Wed Jan 8 2020 09:50:03

Asterisk developer's documentation


chan_misdn.c File Reference

the chan_misdn channel driver for Asterisk More...

#include "asterisk.h"
#include <pthread.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/file.h>
#include <semaphore.h>
#include <ctype.h>
#include <time.h>
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/io.h"
#include "asterisk/frame.h"
#include "asterisk/translate.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/file.h"
#include "asterisk/callerid.h"
#include "asterisk/indications.h"
#include "asterisk/app.h"
#include "asterisk/features.h"
#include "asterisk/term.h"
#include "asterisk/sched.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/causes.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
#include "asterisk/strings.h"

Go to the source code of this file.

Data Structures

struct  allowed_bearers
 
struct  chan_list
 Channel call record structure. More...
 
struct  hold_info
 
struct  misdn_jb
 
struct  robin_list
 
struct  state_struct
 

Macros

#define chan_list_ref(obj, debug)   (ao2_t_ref((obj), +1, (debug)), (obj))
 
#define chan_list_unref(obj, debug)   (ao2_t_ref((obj), -1, (debug)), NULL)
 
#define MISDN_ASTERISK_TECH_PVT(ast)   ast->tech_pvt
 
#define ORG_AST   1
 
#define ORG_MISDN   2
 
#define TRANSFER_ON_HELD_CALL_HANGUP   1
 

Enumerations

enum  misdn_chan_state {
  MISDN_NOTHING = 0, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, MISDN_INCOMING_SETUP,
  MISDN_DIALING, MISDN_PROGRESS, MISDN_PROCEEDING, MISDN_CALLING,
  MISDN_CALLING_ACKNOWLEDGE, MISDN_ALERTING, MISDN_BUSY, MISDN_CONNECTED,
  MISDN_DISCONNECTED, MISDN_CLEANING
}
 
enum  misdn_hold_state { MISDN_HOLD_IDLE, MISDN_HOLD_ACTIVE, MISDN_HOLD_TRANSFER, MISDN_HOLD_DISCONNECT }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable)
 
int add_in_calls (int port)
 
int add_out_calls (int port)
 
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan (unsigned ast_number_plan)
 
static int ast_to_misdn_pres (int presentation)
 
static enum
mISDN_REDIRECTING_REASON 
ast_to_misdn_reason (const enum AST_REDIRECTING_REASON ast)
 
static int ast_to_misdn_screen (int screening)
 
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton (unsigned ast_number_type)
 
static const char * bearer2str (int cap)
 
static enum event_response_e cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data)
 
static void chan_list_destructor (void *obj)
 
static struct chan_listchan_list_init (int orig)
 
int chan_misdn_jb_empty (struct misdn_bchannel *bc, char *buf, int len)
 
static void chan_misdn_log (int level, int port, char *tmpl,...)
 
static int cl_dequeue_chan (struct chan_list *chan)
 
static void cl_queue_chan (struct chan_list *chan)
 
static char * complete_ch (struct ast_cli_args *a)
 
static char * complete_debug_port (struct ast_cli_args *a)
 
static char * complete_show_config (struct ast_cli_args *a)
 
static void config_jitterbuffer (struct chan_list *ch)
 
void debug_numtype (int port, int numtype, char *type)
 
static int dialtone_indicate (struct chan_list *cl)
 
static void do_immediate_setup (struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
 
static void export_aoc_vars (int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
 
void export_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
 Export parameters to the dialplan environment variables. More...
 
static struct chan_listfind_chan_by_bc (struct misdn_bchannel *bc)
 
static struct chan_listfind_hold_active_call (struct misdn_bchannel *bc)
 
static struct chan_listfind_hold_call (struct misdn_bchannel *bc)
 
static struct chan_listfind_hold_call_l3 (unsigned long l3_id)
 
static void free_robin_list (void)
 
static struct chan_listget_chan_by_ast (struct ast_channel *ast)
 
static struct chan_listget_chan_by_ast_name (const char *name)
 
static struct robin_listget_robin_position (char *group)
 
static char * handle_cli_misdn_port_block (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_port_down (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_port_unblock (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_port_up (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_restart_pid (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_restart_port (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_send_digit (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_send_display (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_send_facility (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_send_restart (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_set_crypt_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_set_tics (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_show_config (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_show_port (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_show_ports_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_show_stacks (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_misdn_toggle_echocancel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void hangup_chan (struct chan_list *ch, struct misdn_bchannel *bc)
 
static void hanguptone_indicate (struct chan_list *cl)
 
void import_ch (struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
 Import parameters from the dialplan environment variables. More...
 
static int load_module (void)
 
static void misdn_add_number_prefix (int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
 
static int misdn_answer (struct ast_channel *ast)
 
static int misdn_attempt_transfer (struct chan_list *active_ch, struct chan_list *held_ch)
 
static enum ast_bridge_result misdn_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
 
static int misdn_call (struct ast_channel *ast, char *dest, int timeout)
 
static int misdn_chan_is_valid (struct chan_list *ch)
 
static int misdn_check_l2l1 (struct ast_channel *chan, const char *data)
 
static void misdn_copy_redirecting_from_ast (struct misdn_bchannel *bc, struct ast_channel *ast)
 
static void misdn_copy_redirecting_to_ast (struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
 
static int misdn_digit_begin (struct ast_channel *chan, char digit)
 
static int misdn_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
 
static int misdn_facility_exec (struct ast_channel *chan, const char *data)
 
static void misdn_facility_ie_handler (enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch)
 
static int misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast)
 
static const char * misdn_get_ch_state (struct chan_list *p)
 
static void misdn_get_connected_line (struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
 
static int misdn_hangup (struct ast_channel *ast)
 
static int misdn_indication (struct ast_channel *ast, int cond, const void *data, size_t datalen)
 
static int misdn_is_msn_valid (int port, const struct misdn_party_dialing *dialed)
 
void misdn_jb_destroy (struct misdn_jb *jb)
 frees the data and destroys the given jitterbuffer struct More...
 
int misdn_jb_empty (struct misdn_jb *jb, char *data, int len)
 gets len bytes out of the jitterbuffer if available, else only the available data is returned and the return value indicates the number of data. More...
 
int misdn_jb_fill (struct misdn_jb *jb, const char *data, int len)
 fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun). More...
 
struct misdn_jbmisdn_jb_init (int size, int upper_threshold)
 allocates the jb-structure and initialize the elements More...
 
static int misdn_l1_task (const void *vdata)
 
static struct ast_channelmisdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c)
 
static int misdn_overlap_dial_task (const void *data)
 
static void misdn_prefix_string (const char *str_prefix, char *str_main, size_t size)
 
static void misdn_queue_connected_line_update (struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
 
static struct ast_framemisdn_read (struct ast_channel *ast)
 
static struct ast_channelmisdn_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
 
static int misdn_send_text (struct ast_channel *chan, const char *text)
 
static int misdn_set_opt_exec (struct ast_channel *chan, const char *data)
 
static int misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data)
 
static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data)
 
static void misdn_tasks_destroy (void)
 
static void misdn_tasks_init (void)
 
static void misdn_tasks_remove (int task_id)
 
static void * misdn_tasks_thread_func (void *data)
 
static void misdn_tasks_wakeup (void)
 
static int misdn_to_ast_plan (enum mISDN_NUMBER_PLAN number_plan)
 
static int misdn_to_ast_pres (int presentation)
 
static enum AST_REDIRECTING_REASON misdn_to_ast_reason (const enum mISDN_REDIRECTING_REASON q931)
 
static int misdn_to_ast_screen (int screening)
 
static int misdn_to_ast_ton (enum mISDN_NUMBER_TYPE number_type)
 
static const char * misdn_to_str_plan (enum mISDN_NUMBER_PLAN number_plan)
 
static const char * misdn_to_str_pres (int presentation)
 
static const char * misdn_to_str_screen (int screening)
 
static const char * misdn_to_str_ton (enum mISDN_NUMBER_TYPE number_type)
 
static void misdn_update_caller_id (struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag)
 
static void misdn_update_connected_line (struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
 
static void misdn_update_redirecting (struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
 
static void misdn_update_remote_party (struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
 
static int misdn_write (struct ast_channel *ast, struct ast_frame *frame)
 
static int pbx_start_chan (struct chan_list *ch)
 
static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
 
static void print_bearer (struct misdn_bchannel *bc)
 
static void print_facility (const struct FacParm *fac, const struct misdn_bchannel *bc)
 
static struct ast_frameprocess_ast_dsp (struct chan_list *tmp, struct ast_frame *frame)
 
static int read_config (struct chan_list *ch)
 
static void release_chan (struct chan_list *ch, struct misdn_bchannel *bc)
 
static void release_chan_early (struct chan_list *ch)
 
static int reload (void)
 
static void reload_config (void)
 
static int send_cause2ast (struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
 
static void send_digit_to_chan (struct chan_list *cl, char digit)
 
static void show_config_description (int fd, enum misdn_cfg_elements elem)
 
static void sighandler (int sig)
 
static int start_bc_tones (struct chan_list *cl)
 
static void start_pbx (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
 
static int stop_bc_tones (struct chan_list *cl)
 
static int stop_indicate (struct chan_list *cl)
 
static int unload_module (void)
 
static void update_config (struct chan_list *ch)
 Updates caller ID information from config. More...
 
static int update_ec_config (struct misdn_bchannel *bc)
 
static void update_name (struct ast_channel *tmp, int port, int c)
 
static void wait_for_digits (struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
 
static struct allowed_bearers allowed_bearers_array []
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry chan_misdn_clis []
 
static struct chan_listcl_te =NULL
 Global channel call record list head. More...
 
static ast_mutex_t cl_te_lock
 
static int g_config_initialized = 0
 
static int glob_channel = 0
 
static char global_tracefile [BUFFERSIZE+1]
 
static int max_ports
 
int MAXTICS = 8
 
static int * misdn_debug
 
static int * misdn_debug_only
 
static int * misdn_in_calls
 
static int * misdn_out_calls
 
static int * misdn_ports
 
static struct sched_contextmisdn_tasks = NULL
 the main schedule context for stuff like l1 watcher, overlap dial, ... More...
 
static pthread_t misdn_tasks_thread
 
static struct ast_channel_tech misdn_tech
 
static struct ast_channel_tech misdn_tech_wo_bridge
 
static const char misdn_type [] = "mISDN"
 
static int prefformat = AST_FORMAT_ALAW
 Only alaw and mulaw is allowed for now. More...
 
static ast_mutex_t release_lock
 
static struct robin_listrobin = NULL
 
static struct state_struct state_array []
 
static int tracing = 0
 

Detailed Description

the chan_misdn channel driver for Asterisk

Author
Christian Richter crich.nosp@m.@ber.nosp@m.onet..nosp@m.com
ExtRef:
MISDN http://www.misdn.org/

Definition in file chan_misdn.c.

Macro Definition Documentation

#define chan_list_ref (   obj,
  debug 
)    (ao2_t_ref((obj), +1, (debug)), (obj))
#define ORG_AST   1

Asterisk created the channel (outgoing call)

Definition at line 315 of file chan_misdn.c.

Referenced by cb_events(), export_aoc_vars(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), release_chan(), and release_chan_early().

#define ORG_MISDN   2

mISDN created the channel (incoming call)

Definition at line 317 of file chan_misdn.c.

Referenced by cb_events(), misdn_get_connected_line(), misdn_indication(), misdn_update_connected_line(), and misdn_update_redirecting().

#define TRANSFER_ON_HELD_CALL_HANGUP   1

Definition at line 8261 of file chan_misdn.c.

Enumeration Type Documentation

Enumerator
MISDN_NOTHING 

at beginning

MISDN_WAITING4DIGS 

when waiting for info

MISDN_EXTCANTMATCH 

when asterisk couldn't match our ext

MISDN_INCOMING_SETUP 

for incoming setup

MISDN_DIALING 

when pbx_start

MISDN_PROGRESS 

we have progress

MISDN_PROCEEDING 

we have progress

MISDN_CALLING 

when misdn_call is called

MISDN_CALLING_ACKNOWLEDGE 

when we get SETUP_ACK

MISDN_ALERTING 

when Alerting

MISDN_BUSY 

when BUSY

MISDN_CONNECTED 

when connected

MISDN_DISCONNECTED 

when connected

MISDN_CLEANING 

when hangup from * but we were connected before

Definition at line 297 of file chan_misdn.c.

297  {
298  MISDN_NOTHING = 0, /*!< at beginning */
299  MISDN_WAITING4DIGS, /*!< when waiting for info */
300  MISDN_EXTCANTMATCH, /*!< when asterisk couldn't match our ext */
301  MISDN_INCOMING_SETUP, /*!< for incoming setup */
302  MISDN_DIALING, /*!< when pbx_start */
303  MISDN_PROGRESS, /*!< we have progress */
304  MISDN_PROCEEDING, /*!< we have progress */
305  MISDN_CALLING, /*!< when misdn_call is called */
306  MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */
307  MISDN_ALERTING, /*!< when Alerting */
308  MISDN_BUSY, /*!< when BUSY */
309  MISDN_CONNECTED, /*!< when connected */
310  MISDN_DISCONNECTED, /*!< when connected */
311  MISDN_CLEANING, /*!< when hangup from * but we were connected before */
312 };
Enumerator
MISDN_HOLD_IDLE 

HOLD not active

MISDN_HOLD_ACTIVE 

Call is held

MISDN_HOLD_TRANSFER 

Held call is being transferred

MISDN_HOLD_DISCONNECT 

Held call is being disconnected

Definition at line 319 of file chan_misdn.c.

319  {
320  MISDN_HOLD_IDLE, /*!< HOLD not active */
321  MISDN_HOLD_ACTIVE, /*!< Call is held */
322  MISDN_HOLD_TRANSFER, /*!< Held call is being transferred */
323  MISDN_HOLD_DISCONNECT, /*!< Held call is being disconnected */
324 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 12695 of file chan_misdn.c.

static void __unreg_module ( void  )
static

Definition at line 12695 of file chan_misdn.c.

static int _misdn_tasks_add_variable ( int  timeout,
ast_sched_cb  callback,
const void *  data,
int  variable 
)
inlinestatic

Definition at line 3560 of file chan_misdn.c.

References ast_sched_add_variable(), misdn_tasks_init(), and misdn_tasks_wakeup().

Referenced by misdn_tasks_add(), and misdn_tasks_add_variable().

3561 {
3562  int task_id;
3563 
3564  if (!misdn_tasks) {
3565  misdn_tasks_init();
3566  }
3567  task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
3569 
3570  return task_id;
3571 }
int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Schedule callback(data) to happen when ms into the future.
Definition: sched.c:406
static struct sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:642
static void misdn_tasks_init(void)
Definition: chan_misdn.c:3523
static void misdn_tasks_wakeup(void)
Definition: chan_misdn.c:3555
int add_in_calls ( int  port)

Definition at line 8802 of file chan_misdn.c.

References ast_log(), LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_IN.

Referenced by cb_events().

8803 {
8804  int max_in_calls;
8805 
8806  misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls));
8807  misdn_in_calls[port]++;
8808 
8809  if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) {
8810  ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port);
8811  return misdn_in_calls[port] - max_in_calls;
8812  }
8813 
8814  return 0;
8815 }
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
static int * misdn_in_calls
Definition: chan_misdn.c:672
int add_out_calls ( int  port)

Definition at line 8817 of file chan_misdn.c.

References ast_log(), LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_OUT.

Referenced by misdn_call().

8818 {
8819  int max_out_calls;
8820 
8821  misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls));
8822 
8823  if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) {
8824  ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port);
8825  return (misdn_out_calls[port] + 1) - max_out_calls;
8826  }
8827 
8828  misdn_out_calls[port]++;
8829 
8830  return 0;
8831 }
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int * misdn_out_calls
Definition: chan_misdn.c:673
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan ( unsigned  ast_number_plan)
static

Definition at line 2014 of file chan_misdn.c.

References NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, and NUMPLAN_UNKNOWN.

Referenced by misdn_call(), misdn_copy_redirecting_from_ast(), and misdn_get_connected_line().

2015 {
2016  enum mISDN_NUMBER_PLAN number_plan;
2017 
2018  switch (ast_number_plan & 0x0F) {
2019  default:
2020  case NUMPLAN_UNKNOWN:
2021  number_plan = NUMPLAN_UNKNOWN;
2022  break;
2023 
2024  case NUMPLAN_ISDN:
2025  number_plan = NUMPLAN_ISDN;
2026  break;
2027 
2028  case NUMPLAN_DATA:
2029  number_plan = NUMPLAN_DATA;
2030  break;
2031 
2032  case NUMPLAN_TELEX:
2033  number_plan = NUMPLAN_TELEX;
2034  break;
2035 
2036  case NUMPLAN_NATIONAL:
2037  number_plan = NUMPLAN_NATIONAL;
2038  break;
2039 
2040  case NUMPLAN_PRIVATE:
2041  number_plan = NUMPLAN_PRIVATE;
2042  break;
2043  }
2044 
2045  return number_plan;
2046 }
mISDN_NUMBER_PLAN
Definition: isdn_lib.h:92
static int ast_to_misdn_pres ( int  presentation)
static

Definition at line 2117 of file chan_misdn.c.

References AST_PRES_ALLOWED, AST_PRES_RESTRICTED, AST_PRES_RESTRICTION, and AST_PRES_UNAVAILABLE.

Referenced by misdn_copy_redirecting_from_ast(), misdn_get_connected_line(), and update_config().

2118 {
2119  switch (presentation & AST_PRES_RESTRICTION) {
2120  default:
2121  case AST_PRES_ALLOWED:
2122  presentation = 0;
2123  break;
2124 
2125  case AST_PRES_RESTRICTED:
2126  presentation = 1;
2127  break;
2128 
2129  case AST_PRES_UNAVAILABLE:
2130  presentation = 2;
2131  break;
2132  }
2133 
2134  return presentation;
2135 }
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
#define AST_PRES_ALLOWED
Definition: callerid.h:324
#define AST_PRES_UNAVAILABLE
Definition: callerid.h:326
static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason ( const enum AST_REDIRECTING_REASON  ast)
static

Definition at line 2246 of file chan_misdn.c.

References ARRAY_LEN, AST_REDIRECTING_REASON_AWAY, AST_REDIRECTING_REASON_CALL_FWD_DTE, AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_DO_NOT_DISTURB, AST_REDIRECTING_REASON_FOLLOW_ME, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_OUT_OF_ORDER, AST_REDIRECTING_REASON_TIME_OF_DAY, AST_REDIRECTING_REASON_UNAVAILABLE, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, AST_REDIRECTING_REASON_USER_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD, mISDN_REDIRECTING_REASON_CALL_FWD_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD_DTE, mISDN_REDIRECTING_REASON_DEFLECTION, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_OUT_OF_ORDER, and mISDN_REDIRECTING_REASON_UNKNOWN.

Referenced by misdn_copy_redirecting_from_ast().

2247 {
2248  unsigned index;
2249 
2250  static const struct misdn_reasons {
2251  enum AST_REDIRECTING_REASON ast;
2252  enum mISDN_REDIRECTING_REASON q931;
2253  } misdn_reason_table[] = {
2254  /* *INDENT-OFF* */
2267  /* *INDENT-ON* */
2268  };
2269 
2270  for (index = 0; index < ARRAY_LEN(misdn_reason_table); ++index) {
2271  if (misdn_reason_table[index].ast == ast) {
2272  return misdn_reason_table[index].q931;
2273  }
2274  }
2276 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
mISDN_REDIRECTING_REASON
Q.931 encoded redirecting reason.
Definition: isdn_lib.h:197
AST_REDIRECTING_REASON
redirecting reason codes.
Definition: callerid.h:390
static int ast_to_misdn_screen ( int  screening)
static

Definition at line 2214 of file chan_misdn.c.

References AST_PRES_NETWORK_NUMBER, AST_PRES_NUMBER_TYPE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.

Referenced by misdn_copy_redirecting_from_ast(), misdn_get_connected_line(), and update_config().

2215 {
2216  switch (screening & AST_PRES_NUMBER_TYPE) {
2217  default:
2219  screening = 0;
2220  break;
2221 
2223  screening = 1;
2224  break;
2225 
2227  screening = 2;
2228  break;
2229 
2231  screening = 3;
2232  break;
2233  }
2234 
2235  return screening;
2236 }
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:320
#define AST_PRES_NETWORK_NUMBER
Definition: callerid.h:321
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_PRES_NUMBER_TYPE
Definition: callerid.h:317
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:319
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton ( unsigned  ast_number_type)
static

Definition at line 1888 of file chan_misdn.c.

References NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.

Referenced by misdn_call(), misdn_copy_redirecting_from_ast(), and misdn_get_connected_line().

1889 {
1890  enum mISDN_NUMBER_TYPE number_type;
1891 
1892  switch ((ast_number_type >> 4) & 0x07) {
1893  default:
1894  case NUMTYPE_UNKNOWN:
1895  number_type = NUMTYPE_UNKNOWN;
1896  break;
1897 
1898  case NUMTYPE_INTERNATIONAL:
1899  number_type = NUMTYPE_INTERNATIONAL;
1900  break;
1901 
1902  case NUMTYPE_NATIONAL:
1903  number_type = NUMTYPE_NATIONAL;
1904  break;
1905 
1907  number_type = NUMTYPE_NETWORK_SPECIFIC;
1908  break;
1909 
1910  case NUMTYPE_SUBSCRIBER:
1911  number_type = NUMTYPE_SUBSCRIBER;
1912  break;
1913 
1914  case NUMTYPE_ABBREVIATED:
1915  number_type = NUMTYPE_ABBREVIATED;
1916  break;
1917  }
1918 
1919  return number_type;
1920 }
mISDN_NUMBER_TYPE
Definition: isdn_lib.h:101
static const char* bearer2str ( int  cap)
static

Definition at line 2345 of file chan_misdn.c.

References ARRAY_LEN, and allowed_bearers::display.

Referenced by cb_events(), print_bc_info(), and print_bearer().

2346 {
2347  unsigned index;
2348 
2349  for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) {
2350  if (allowed_bearers_array[index].cap == cap) {
2351  return allowed_bearers_array[index].display;
2352  }
2353  }
2354 
2355  return "Unknown Bearer";
2356 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct allowed_bearers allowed_bearers_array[]
Definition: chan_misdn.c:2334
static enum event_response_e cb_events ( enum event_e  event,
struct misdn_bchannel bc,
void *  user_data 
)
static

queue new chan

Supplementary Services

Definition at line 9859 of file chan_misdn.c.

References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, ao2_ref, misdn_bchannel::AOCD_need_export, ARRAY_LEN, chan_list::ast, ast_bridged_channel(), ast_canmatch_extension(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_cdr_update(), ast_channel_lock, ast_channel_queue_redirecting_update(), ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_copy_string(), ast_deactivate_generator(), ast_exists_extension(), AST_FORMAT_ALAW, AST_FRAME_DTMF, AST_FRAME_VOICE, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pickup_call(), ast_pickup_ext(), ast_poll, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_queue_frame(), ast_set_callerid(), ast_setstate(), AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdup, ast_strlen_zero(), ast_transfercapability2str(), ast_tv(), ast_tvnow(), chan_list::bc, misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::bframe, misdn_bchannel::bframe_len, misdn_bchannel::caller, ast_channel::caller, misdn_bchannel::capability, misdn_bchannel::cause, cb_log, chan_list_init(), chan_list_unref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, cl_queue_chan(), ast_frame_subclass::codec, misdn_bchannel::connected, chan_list::context, misdn_bchannel::cw, ast_frame::data, ast_frame::datalen, ast_frame::delivery, misdn_bchannel::dialed, do_immediate_setup(), misdn_bchannel::dtmf, misdn_bchannel::dummy, errno, EVENT_ALERTING, EVENT_BCHAN_ACTIVATED, EVENT_BCHAN_DATA, EVENT_BCHAN_ERROR, EVENT_CLEANUP, EVENT_CONNECT, EVENT_CONNECT_ACKNOWLEDGE, EVENT_DISCONNECT, EVENT_DTMF_TONE, EVENT_FACILITY, EVENT_HOLD, EVENT_HOLD_ACKNOWLEDGE, EVENT_HOLD_REJECT, EVENT_INFORMATION, EVENT_NEW_BC, EVENT_NEW_CHANNEL, EVENT_NEW_L3ID, EVENT_NOTIFY, EVENT_PORT_ALARM, EVENT_PROCEEDING, EVENT_PROGRESS, EVENT_REGISTER, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_RESTART, EVENT_RETRIEVE, EVENT_RETRIEVE_ACKNOWLEDGE, EVENT_RETRIEVE_REJECT, EVENT_SETUP, EVENT_SETUP_ACKNOWLEDGE, EVENT_STATUS, EVENT_TIMEOUT, EVENT_TONE_GENERATE, export_aoc_vars(), export_ch(), ast_channel::exten, misdn_bchannel::fac_in, misdn_bchannel::fac_out, chan_list::far_alerting, find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), ast_frame::frametype, misdn_party_redirecting::from, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, hangup_chan(), ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, ast_party_caller::id, chan_list::ignore_dtmf, misdn_bchannel::incoming_cid_tag, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::info_dad, INFO_PI_INBAND_AVAILABLE, misdn_bchannel::infos_pending, ast_frame_subclass::integer, misdn_bchannel::keypad, misdn_bchannel::l3_id, chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_isdn_get_info(), misdn_add_number_prefix(), MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, misdn_attempt_transfer(), MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_cap_is_speech(), MISDN_CFG_ALARM_BLOCK, MISDN_CFG_ALWAYS_IMMEDIATE, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, misdn_cfg_get(), MISDN_CFG_HOLD_ALLOWED, MISDN_CFG_IMMEDIATE, MISDN_CFG_REJECT_CAUSE, MISDN_CLEANING, MISDN_CONNECTED, misdn_copy_redirecting_to_ast(), MISDN_DIALING, MISDN_DISCONNECTED, MISDN_EXTCANTMATCH, misdn_facility_ie_handler(), MISDN_GEN_APPEND_DIGITS2EXTEN, misdn_get_ch_state(), MISDN_HOLD_ACTIVE, MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, misdn_inband_avail(), MISDN_INCOMING_SETUP, misdn_is_msn_valid(), misdn_lib_is_ptp(), misdn_lib_log_ies(), misdn_lib_port_block(), misdn_lib_send_event(), misdn_new(), MISDN_NOTHING, mISDN_NOTIFY_CODE_CALL_IS_DIVERTING, mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING, mISDN_NOTIFY_CODE_DIVERSION_ACTIVATED, mISDN_NOTIFY_CODE_INVALID, misdn_overlap_dial_task(), MISDN_PROCEEDING, MISDN_PROGRESS, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_UNKNOWN, misdn_tasks_add_variable(), misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), misdn_to_str_plan(), misdn_to_str_pres(), misdn_to_str_screen(), misdn_to_str_ton(), misdn_update_remote_party(), MISDN_WAITING4DIGS, misdn_party_id::name, allowed_bearers::name, chan_list::need_busy, misdn_bchannel::need_disconnect, misdn_bchannel::need_more_infos, misdn_bchannel::need_release, misdn_bchannel::need_release_complete, chan_list::noautorespond_on_setup, misdn_bchannel::notify_description_code, misdn_bchannel::nt, chan_list::nttimeout, misdn_party_dialing::number, ast_party_id::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_frame::offset, ORG_AST, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_builtin_setvar_helper(), misdn_bchannel::pid, chan_list::pipe, ast_party_number::plan, hold_info::port, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, print_bearer(), misdn_bchannel::progress_indicator, ast_frame::ptr, read_config(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, ast_channel::redirecting, release_chan(), RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, ast_channel::rings, ast_frame::samples, misdn_party_id::screening, misdn_bchannel::sending_complete, ast_frame::src, start_bc_tones(), start_pbx(), hold_info::state, chan_list::state, stop_bc_tones(), stop_indicate(), ast_frame::subclass, ast_party_id::tag, ast_channel::tech, misdn_party_redirecting::to, ast_party_redirecting::to, misdn_party_redirecting::to_changed, misdn_bchannel::tone_cnt, ast_channel::transfercapability, ast_channel_tech::type, update_name(), and wait_for_digits().

Referenced by load_module().

9860 {
9861 #if defined(AST_MISDN_ENHANCEMENTS)
9862  struct misdn_cc_record *cc_record;
9863 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
9864  struct chan_list *held_ch;
9865  struct chan_list *ch = find_chan_by_bc(bc);
9866 
9867  if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) {
9868  int debuglevel = 1;
9869 
9870  /* Debug Only Non-Bchan */
9871  if (event == EVENT_CLEANUP && !user_data) {
9872  debuglevel = 5;
9873  }
9874 
9875  chan_misdn_log(debuglevel, bc->port,
9876  "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n",
9877  manager_isdn_get_info(event),
9878  bc->caller.name,
9879  bc->caller.number,
9880  bc->dialed.number,
9881  bc->pid,
9882  ch ? misdn_get_ch_state(ch) : "none");
9883  if (debuglevel == 1) {
9884  misdn_lib_log_ies(bc);
9885  chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state));
9886  }
9887  }
9888 
9889  if (!ch) {
9890  switch(event) {
9891  case EVENT_SETUP:
9892  case EVENT_DISCONNECT:
9893  case EVENT_RELEASE:
9895  case EVENT_PORT_ALARM:
9896  case EVENT_RETRIEVE:
9897  case EVENT_NEW_BC:
9898  case EVENT_FACILITY:
9899  case EVENT_REGISTER:
9900  break;
9901  case EVENT_CLEANUP:
9902  case EVENT_TONE_GENERATE:
9903  case EVENT_BCHAN_DATA:
9904  return -1;
9905  default:
9906  chan_misdn_log(1, bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n", bc->l3_id, bc, manager_isdn_get_info(event), bc->port, bc->channel);
9907  return -1;
9908  }
9909  } else {
9910  switch (event) {
9911  case EVENT_TONE_GENERATE:
9912  break;
9913  case EVENT_DISCONNECT:
9914  case EVENT_RELEASE:
9916  case EVENT_CLEANUP:
9917  case EVENT_TIMEOUT:
9918  if (!ch->ast) {
9919  chan_misdn_log(3, bc->port, "ast_hangup already called, so we have no ast ptr anymore in event(%s)\n", manager_isdn_get_info(event));
9920  }
9921  break;
9922  default:
9923  if (!ch->ast || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
9924  if (event != EVENT_BCHAN_DATA) {
9925  ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
9926  }
9927  chan_list_unref(ch, "No Ast or Ast private pointer");
9928  return -1;
9929  }
9930  break;
9931  }
9932  }
9933 
9934 
9935  switch (event) {
9936  case EVENT_PORT_ALARM:
9937  {
9938  int boa = 0;
9939  misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(boa));
9940  if (boa) {
9941  cb_log(1, bc->port, " --> blocking\n");
9943  }
9944  }
9945  break;
9946  case EVENT_BCHAN_ACTIVATED:
9947  break;
9948 
9949  case EVENT_NEW_CHANNEL:
9950  update_name(ch->ast,bc->port,bc->channel);
9951  break;
9952 
9953  case EVENT_NEW_L3ID:
9954  ch->l3id=bc->l3_id;
9955  ch->addr=bc->addr;
9956  break;
9957 
9958  case EVENT_NEW_BC:
9959  if (!ch) {
9960  ch = find_hold_call(bc);
9961  }
9962 
9963  if (!ch) {
9964  ast_log(LOG_WARNING, "NEW_BC without chan_list?\n");
9965  break;
9966  }
9967 
9968  if (bc) {
9969  ch->bc = (struct misdn_bchannel *) user_data;
9970  }
9971  break;
9972 
9973  case EVENT_DTMF_TONE:
9974  {
9975  /* sending INFOS as DTMF-Frames :) */
9976  struct ast_frame fr;
9977 
9978  memset(&fr, 0, sizeof(fr));
9979  fr.frametype = AST_FRAME_DTMF;
9980  fr.subclass.integer = bc->dtmf ;
9981  fr.src = NULL;
9982  fr.data.ptr = NULL;
9983  fr.datalen = 0;
9984  fr.samples = 0;
9985  fr.mallocd = 0;
9986  fr.offset = 0;
9987  fr.delivery = ast_tv(0,0);
9988 
9989  if (!ch->ignore_dtmf) {
9990  chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
9991  ast_queue_frame(ch->ast, &fr);
9992  } else {
9993  chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf);
9994  }
9995  break;
9996  }
9997  case EVENT_STATUS:
9998  break;
9999 
10000  case EVENT_INFORMATION:
10001  if (ch->state != MISDN_CONNECTED) {
10002  stop_indicate(ch);
10003  }
10004 
10005  if (!ch->ast) {
10006  break;
10007  }
10008 
10009  if (ch->state == MISDN_WAITING4DIGS) {
10010  /* Ok, incomplete Setup, waiting till extension exists */
10011  if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
10012  chan_misdn_log(1, bc->port, " --> using keypad as info\n");
10013  ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad));
10014  }
10015 
10016  strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
10017  ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten));
10018 
10019  /* Check for Pickup Request first */
10020  if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
10021  if (ast_pickup_call(ch->ast)) {
10022  hangup_chan(ch, bc);
10023  } else {
10025  hangup_chan(ch, bc);
10026  ch->ast = NULL;
10027  break;
10028  }
10029  }
10030 
10031  if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10032  if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
10034  "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10035  bc->dialed.number, ch->context, bc->port);
10036  pbx_builtin_setvar_helper(ch->ast, "INVALID_EXTEN", bc->dialed.number);
10037  strcpy(ch->ast->exten, "i");
10038  ch->state = MISDN_DIALING;
10039  start_pbx(ch, bc, ch->ast);
10040  break;
10041  }
10042 
10044  "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
10045  "\tMaybe you want to add an 'i' extension to catch this case.\n",
10046  bc->dialed.number, ch->context, bc->port);
10047 
10048  if (bc->nt) {
10049  hanguptone_indicate(ch);
10050  }
10051  ch->state = MISDN_EXTCANTMATCH;
10053 
10055  break;
10056  }
10057 
10058  if (ch->overlap_dial) {
10060  ch->overlap_tv = ast_tvnow();
10062  if (ch->overlap_dial_task == -1) {
10063  ch->overlap_dial_task =
10065  }
10066  break;
10067  }
10068 
10069  if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10070  ch->state = MISDN_DIALING;
10071  start_pbx(ch, bc, ch->ast);
10072  }
10073  } else {
10074  /* sending INFOS as DTMF-Frames :) */
10075  struct ast_frame fr;
10076  int digits;
10077 
10078  memset(&fr, 0, sizeof(fr));
10079  fr.frametype = AST_FRAME_DTMF;
10080  fr.subclass.integer = bc->info_dad[0] ;
10081  fr.src = NULL;
10082  fr.data.ptr = NULL;
10083  fr.datalen = 0;
10084  fr.samples = 0;
10085  fr.mallocd = 0;
10086  fr.offset = 0;
10087  fr.delivery = ast_tv(0,0);
10088 
10089  misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(digits));
10090  if (ch->state != MISDN_CONNECTED) {
10091  if (digits) {
10092  strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
10093  ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten));
10094  ast_cdr_update(ch->ast);
10095  }
10096 
10097  ast_queue_frame(ch->ast, &fr);
10098  }
10099  }
10100  break;
10101  case EVENT_SETUP:
10102  {
10103  struct ast_channel *chan;
10104  int exceed;
10105  int ai;
10106  int im;
10107  int append_msn = 0;
10108 
10109  if (ch) {
10110  switch (ch->state) {
10111  case MISDN_NOTHING:
10112  chan_list_unref(ch, "Ignore found ch. Is it for an outgoing call?");
10113  ch = NULL;
10114  break;
10115  default:
10116  chan_list_unref(ch, "Already have a call.");
10117  chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
10118  return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */
10119  }
10120  }
10121 
10122  if (!bc->nt && !misdn_is_msn_valid(bc->port, &bc->dialed)) {
10123  chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
10124  return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */
10125  }
10126 
10127  if (bc->cw) {
10128  int cause;
10129  chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
10130  misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
10131  bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING;
10132  return RESPONSE_RELEASE_SETUP;
10133  }
10134 
10135  print_bearer(bc);
10136 
10137  ch = chan_list_init(ORG_MISDN);
10138  if (!ch) {
10139  chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
10140  return RESPONSE_RELEASE_SETUP;
10141  }
10142 
10143  ch->bc = bc;
10144  ch->l3id = bc->l3_id;
10145  ch->addr = bc->addr;
10146 
10147  chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, NULL, bc->port, bc->channel);
10148  if (!chan) {
10149  chan_list_unref(ch, "Failed to create a new channel");
10150  ast_log(LOG_ERROR, "cb_events: misdn_new failed!\n");
10151  return RESPONSE_RELEASE_SETUP;
10152  }
10153 
10154  if ((exceed = add_in_calls(bc->port))) {
10155  char tmp[16];
10156  snprintf(tmp, sizeof(tmp), "%d", exceed);
10157  pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp);
10158  }
10159 
10160  read_config(ch);
10161 
10162  export_ch(chan, bc, ch);
10163 
10164  ch->ast->rings = 1;
10166 
10167  /* Update asterisk channel caller information */
10168  chan_misdn_log(2, bc->port, " --> TON: %s(%d)\n", misdn_to_str_ton(bc->caller.number_type), bc->caller.number_type);
10169  chan_misdn_log(2, bc->port, " --> PLAN: %s(%d)\n", misdn_to_str_plan(bc->caller.number_plan), bc->caller.number_plan);
10172 
10173  chan_misdn_log(2, bc->port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
10174  chan_misdn_log(2, bc->port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
10177 
10178  ast_set_callerid(chan, bc->caller.number, NULL, bc->caller.number);
10179 
10180  misdn_cfg_get(bc->port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn));
10181  if (append_msn) {
10182  strncat(bc->incoming_cid_tag, "_", sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1);
10183  strncat(bc->incoming_cid_tag, bc->dialed.number, sizeof(bc->incoming_cid_tag) - strlen(bc->incoming_cid_tag) - 1);
10184  }
10185 
10186  ast_channel_lock(chan);
10187  chan->caller.id.tag = ast_strdup(bc->incoming_cid_tag);
10188  ast_channel_unlock(chan);
10189 
10190  if (!ast_strlen_zero(bc->redirecting.from.number)) {
10191  /* Add configured prefix to redirecting.from.number */
10193 
10194  /* Update asterisk channel redirecting information */
10196  }
10197 
10198  pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
10199  chan->transfercapability = bc->capability;
10200 
10201  switch (bc->capability) {
10203  pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL");
10204  break;
10205  default:
10206  pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH");
10207  break;
10208  }
10209 
10210  if (!strstr(ch->allowed_bearers, "all")) {
10211  int i;
10212 
10213  for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) {
10214  if (allowed_bearers_array[i].cap == bc->capability) {
10215  if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) {
10216  /* The bearer capability is allowed */
10217  if (allowed_bearers_array[i].deprecated) {
10218  chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n",
10220  }
10221  break;
10222  }
10223  }
10224  }
10225  if (i == ARRAY_LEN(allowed_bearers_array)) {
10226  /* We did not find the bearer capability */
10227  chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n",
10228  bearer2str(bc->capability), bc->capability);
10229 
10230  ch->state = MISDN_EXTCANTMATCH;
10231  chan_list_unref(ch, "BC not allowed, releasing call");
10233  return RESPONSE_RELEASE_SETUP;
10234  }
10235  }
10236 
10237  /** queue new chan **/
10238  cl_queue_chan(ch);
10239 
10240  if (bc->fac_in.Function != Fac_None) {
10241  misdn_facility_ie_handler(event, bc, ch);
10242  }
10243 
10244  /* Check for Pickup Request first */
10245  if (!strcmp(chan->exten, ast_pickup_ext())) {
10246  if (!ch->noautorespond_on_setup) {
10247  /* Sending SETUP_ACK */
10249  } else {
10251  }
10252  if (ast_pickup_call(chan)) {
10253  hangup_chan(ch, bc);
10254  } else {
10256  hangup_chan(ch, bc);
10257  ch->ast = NULL;
10258  break;
10259  }
10260  }
10261 
10262  /*
10263  * added support for s extension hope it will help those poor cretains
10264  * which haven't overlap dial.
10265  */
10266  misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
10267  if (ai) {
10268  do_immediate_setup(bc, ch, chan);
10269  break;
10270  }
10271 
10272  /* check if we should jump into s when we have no dialed.number */
10273  misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
10274  if (im && ast_strlen_zero(bc->dialed.number)) {
10275  do_immediate_setup(bc, ch, chan);
10276  break;
10277  }
10278 
10279  chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context);
10280  if (!ast_canmatch_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10281  if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->caller.number)) {
10283  "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10284  bc->dialed.number, ch->context, bc->port);
10285  pbx_builtin_setvar_helper(ch->ast, "INVALID_EXTEN", bc->dialed.number);
10286  strcpy(ch->ast->exten, "i");
10288  ch->state = MISDN_DIALING;
10289  start_pbx(ch, bc, chan);
10290  break;
10291  }
10292 
10294  "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
10295  "\tMaybe you want to add an 'i' extension to catch this case.\n",
10296  bc->dialed.number, ch->context, bc->port);
10297  if (bc->nt) {
10298  hanguptone_indicate(ch);
10299  }
10300 
10301  ch->state = MISDN_EXTCANTMATCH;
10303 
10305  break;
10306  }
10307 
10308  /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely
10309  * jump into the dialplan, when the dialed extension does not exist, the 's' extension
10310  * will be used by Asterisk automatically. */
10311  if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
10312  if (!ch->noautorespond_on_setup) {
10313  ch->state=MISDN_DIALING;
10315  } else {
10317  }
10318  start_pbx(ch, bc, chan);
10319  break;
10320  }
10321 
10322 
10323  /*
10324  * When we are NT and overlapdial is set and if
10325  * the number is empty, we wait for the ISDN timeout
10326  * instead of our own timer.
10327  */
10328  if (ch->overlap_dial && bc->nt && !bc->dialed.number[0]) {
10329  wait_for_digits(ch, bc, chan);
10330  break;
10331  }
10332 
10333  /*
10334  * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more
10335  * Infos with a Interdigit Timeout.
10336  * */
10337  if (ch->overlap_dial) {
10339  ch->overlap_tv = ast_tvnow();
10341 
10342  wait_for_digits(ch, bc, chan);
10343  if (ch->overlap_dial_task == -1) {
10344  ch->overlap_dial_task =
10346  }
10347  break;
10348  }
10349 
10350  /* If the extension does not exist and we're not TE_PTMP we wait for more digits
10351  * without interdigit timeout.
10352  * */
10353  if (!ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10354  wait_for_digits(ch, bc, chan);
10355  break;
10356  }
10357 
10358  /*
10359  * If the extension exists let's just jump into it.
10360  * */
10361  if (ast_exists_extension(ch->ast, ch->context, bc->dialed.number, 1, bc->caller.number)) {
10363  ch->state = MISDN_DIALING;
10364  start_pbx(ch, bc, chan);
10365  break;
10366  }
10367  break;
10368  }
10369 #if defined(AST_MISDN_ENHANCEMENTS)
10370  case EVENT_REGISTER:
10371  if (bc->fac_in.Function != Fac_None) {
10372  misdn_facility_ie_handler(event, bc, ch);
10373  }
10374  /*
10375  * Shut down this connection immediately.
10376  * The current design of chan_misdn data structures
10377  * does not allow the proper handling of inbound call records
10378  * without an assigned B channel. Therefore, we cannot
10379  * be the CCBS User-B party in a point-to-point setup.
10380  */
10381  bc->fac_out.Function = Fac_None;
10384  break;
10385 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10388 
10389  if (bc->channel) {
10390  update_name(ch->ast,bc->port,bc->channel);
10391  }
10392 
10393  if (bc->fac_in.Function != Fac_None) {
10394  misdn_facility_ie_handler(event, bc, ch);
10395  }
10396 
10397  if (!ast_strlen_zero(bc->infos_pending)) {
10398  /* TX Pending Infos */
10399  strncat(bc->dialed.number, bc->infos_pending, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
10400 
10401  if (!ch->ast) {
10402  break;
10403  }
10404  ast_copy_string(ch->ast->exten, bc->dialed.number, sizeof(ch->ast->exten));
10405  ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
10406  ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending));
10407 
10409  }
10410  break;
10411  case EVENT_PROCEEDING:
10412  if (misdn_cap_is_speech(bc->capability) &&
10413  misdn_inband_avail(bc)) {
10414  start_bc_tones(ch);
10415  }
10416 
10417  ch->state = MISDN_PROCEEDING;
10418 
10419  if (bc->fac_in.Function != Fac_None) {
10420  misdn_facility_ie_handler(event, bc, ch);
10421  }
10422 
10423  if (!ch->ast) {
10424  break;
10425  }
10426 
10428  break;
10429  case EVENT_PROGRESS:
10430  if (bc->channel) {
10431  update_name(ch->ast, bc->port, bc->channel);
10432  }
10433 
10434  if (bc->fac_in.Function != Fac_None) {
10435  misdn_facility_ie_handler(event, bc, ch);
10436  }
10437 
10438  if (!bc->nt) {
10439  if (misdn_cap_is_speech(bc->capability) &&
10440  misdn_inband_avail(bc)) {
10441  start_bc_tones(ch);
10442  }
10443 
10444  ch->state = MISDN_PROGRESS;
10445 
10446  if (!ch->ast) {
10447  break;
10448  }
10450  }
10451  break;
10452  case EVENT_ALERTING:
10453  ch->state = MISDN_ALERTING;
10454 
10455  if (!ch->ast) {
10456  break;
10457  }
10458 
10459  if (bc->fac_in.Function != Fac_None) {
10460  misdn_facility_ie_handler(event, bc, ch);
10461  }
10462 
10465 
10466  cb_log(7, bc->port, " --> Set State Ringing\n");
10467 
10469  cb_log(1, bc->port, "Starting Tones, we have inband Data\n");
10470  start_bc_tones(ch);
10471  } else {
10472  cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n");
10473  if (ch->far_alerting) {
10474  cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself..");
10475  start_bc_tones(ch);
10476  /*tone_indicate(ch, TONE_FAR_ALERTING);*/
10477  }
10478  }
10479  break;
10480  case EVENT_CONNECT:
10481  if (bc->fac_in.Function != Fac_None) {
10482  misdn_facility_ie_handler(event, bc, ch);
10483  }
10484 #if defined(AST_MISDN_ENHANCEMENTS)
10485  if (bc->div_leg_3_rx_wanted) {
10486  bc->div_leg_3_rx_wanted = 0;
10487 
10488  if (ch->ast) {
10492  }
10493  }
10494 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10495 
10496  /* we answer when we've got our very new L3 ID from the NT stack */
10498 
10499  if (!ch->ast) {
10500  break;
10501  }
10502 
10503  stop_indicate(ch);
10504 
10505 #if defined(AST_MISDN_ENHANCEMENTS)
10506  if (ch->record_id != -1) {
10507  /*
10508  * We will delete the associated call completion
10509  * record since we now have a completed call.
10510  * We will not wait/depend on the network to tell
10511  * us to delete it.
10512  */
10513  AST_LIST_LOCK(&misdn_cc_records_db);
10514  cc_record = misdn_cc_find_by_id(ch->record_id);
10515  if (cc_record) {
10516  if (cc_record->ptp && cc_record->mode.ptp.bc) {
10517  /* Close the call-completion signaling link */
10518  cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
10519  cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
10520  misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
10521  }
10522  misdn_cc_delete(cc_record);
10523  }
10524  AST_LIST_UNLOCK(&misdn_cc_records_db);
10525  ch->record_id = -1;
10526  if (ch->peer) {
10527  misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, "");
10528 
10529  ao2_ref(ch->peer, -1);
10530  ch->peer = NULL;
10531  }
10532  }
10533 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10534 
10535  if (!ast_strlen_zero(bc->connected.number)) {
10536  /* Add configured prefix to connected.number */
10538 
10539  /* Update the connected line information on the other channel */
10541  }
10542 
10543  ch->l3id = bc->l3_id;
10544  ch->addr = bc->addr;
10545 
10546  start_bc_tones(ch);
10547 
10548  ch->state = MISDN_CONNECTED;
10549 
10551  break;
10553  ch->l3id = bc->l3_id;
10554  ch->addr = bc->addr;
10555 
10556  start_bc_tones(ch);
10557 
10558  ch->state = MISDN_CONNECTED;
10559  break;
10560  case EVENT_DISCONNECT:
10561  /* we might not have an ch->ast ptr here anymore */
10562  if (ch) {
10563  if (bc->fac_in.Function != Fac_None) {
10564  misdn_facility_ie_handler(event, bc, ch);
10565  }
10566 
10567  chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->originator, bc->nt, misdn_inband_avail(bc), ch->state);
10568  if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
10569  /* If there's inband information available (e.g. a
10570  recorded message saying what was wrong with the
10571  dialled number, or perhaps even giving an
10572  alternative number, then play it instead of
10573  immediately releasing the call */
10574  chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
10575 
10576  ch->state = MISDN_DISCONNECTED;
10577  start_bc_tones(ch);
10578 
10579  if (ch->ast) {
10580  ch->ast->hangupcause = bc->cause;
10581  if (bc->cause == AST_CAUSE_USER_BUSY) {
10583  }
10584  }
10585  ch->need_busy = 0;
10586  break;
10587  }
10588 
10589  bc->need_disconnect = 0;
10590  stop_bc_tones(ch);
10591 
10592  /* Check for held channel, to implement transfer */
10593  held_ch = find_hold_call(bc);
10594  if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) {
10595  hangup_chan(ch, bc);
10596  }
10597  } else {
10598  held_ch = find_hold_call_l3(bc->l3_id);
10599  if (held_ch) {
10600  if (bc->fac_in.Function != Fac_None) {
10601  misdn_facility_ie_handler(event, bc, held_ch);
10602  }
10603 
10604  if (held_ch->hold.state == MISDN_HOLD_ACTIVE) {
10605  bc->need_disconnect = 0;
10606 
10607 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
10608  /*
10609  * Some phones disconnect the held call and the active call at the
10610  * same time to do the transfer. Unfortunately, either call could
10611  * be disconnected first.
10612  */
10613  ch = find_hold_active_call(bc);
10614  if (!ch || misdn_attempt_transfer(ch, held_ch)) {
10615  held_ch->hold.state = MISDN_HOLD_DISCONNECT;
10616  hangup_chan(held_ch, bc);
10617  }
10618 #else
10619  hangup_chan(held_ch, bc);
10620 #endif /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */
10621  }
10622  }
10623  }
10624  if (held_ch) {
10625  chan_list_unref(held_ch, "Done with held call");
10626  }
10627  bc->out_cause = -1;
10628  if (bc->need_release) {
10630  }
10631  break;
10632  case EVENT_RELEASE:
10633  if (!ch) {
10634  ch = find_hold_call_l3(bc->l3_id);
10635  if (!ch) {
10636  chan_misdn_log(1, bc->port,
10637  " --> no Ch, so we've already released. (%s)\n",
10638  manager_isdn_get_info(event));
10639  return -1;
10640  }
10641  }
10642  if (bc->fac_in.Function != Fac_None) {
10643  misdn_facility_ie_handler(event, bc, ch);
10644  }
10645 
10646  bc->need_disconnect = 0;
10647  bc->need_release = 0;
10648 
10649  hangup_chan(ch, bc);
10650  release_chan(ch, bc);
10651  break;
10653  if (!ch) {
10654  ch = find_hold_call_l3(bc->l3_id);
10655  }
10656 
10657  bc->need_disconnect = 0;
10658  bc->need_release = 0;
10659  bc->need_release_complete = 0;
10660 
10661  if (ch) {
10662  if (bc->fac_in.Function != Fac_None) {
10663  misdn_facility_ie_handler(event, bc, ch);
10664  }
10665 
10666  stop_bc_tones(ch);
10667  hangup_chan(ch, bc);
10668  release_chan(ch, bc);
10669  } else {
10670 #if defined(AST_MISDN_ENHANCEMENTS)
10671  /*
10672  * A call-completion signaling link established with
10673  * REGISTER does not have a struct chan_list record
10674  * associated with it.
10675  */
10676  AST_LIST_LOCK(&misdn_cc_records_db);
10677  cc_record = misdn_cc_find_by_bc(bc);
10678  if (cc_record) {
10679  /* The call-completion signaling link is closed. */
10680  misdn_cc_delete(cc_record);
10681  }
10682  AST_LIST_UNLOCK(&misdn_cc_records_db);
10683 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
10684 
10685  chan_misdn_log(1, bc->port,
10686  " --> no Ch, so we've already released. (%s)\n",
10687  manager_isdn_get_info(event));
10688  }
10689  break;
10690  case EVENT_BCHAN_ERROR:
10691  case EVENT_CLEANUP:
10692  stop_bc_tones(ch);
10693 
10694  switch (ch->state) {
10695  case MISDN_CALLING:
10697  break;
10698  default:
10699  break;
10700  }
10701 
10702  hangup_chan(ch, bc);
10703  release_chan(ch, bc);
10704  break;
10705  case EVENT_TONE_GENERATE:
10706  {
10707  int tone_len = bc->tone_cnt;
10708  struct ast_channel *ast = ch->ast;
10709  void *tmp;
10710  int res;
10711  int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
10712 
10713  chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len);
10714 
10715  if (!ast) {
10716  break;
10717  }
10718 
10719  if (!ast->generator) {
10720  break;
10721  }
10722 
10723  tmp = ast->generatordata;
10724  ast->generatordata = NULL;
10725  generate = ast->generator->generate;
10726 
10727  if (tone_len < 0 || tone_len > 512) {
10728  ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len);
10729  tone_len = 128;
10730  }
10731 
10732  res = generate(ast, tmp, tone_len, tone_len);
10733  ast->generatordata = tmp;
10734 
10735  if (res) {
10736  ast_log(LOG_WARNING, "Auto-deactivating generator\n");
10738  } else {
10739  bc->tone_cnt = 0;
10740  }
10741  break;
10742  }
10743  case EVENT_BCHAN_DATA:
10744  if (ch->bc->AOCD_need_export) {
10745  export_aoc_vars(ch->originator, ch->ast, ch->bc);
10746  }
10747  if (!misdn_cap_is_speech(ch->bc->capability)) {
10748  struct ast_frame frame;
10749 
10750  /* In Data Modes we queue frames */
10751  memset(&frame, 0, sizeof(frame));
10752  frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */
10753  frame.subclass.codec = AST_FORMAT_ALAW;
10754  frame.datalen = bc->bframe_len;
10755  frame.samples = bc->bframe_len;
10756  frame.mallocd = 0;
10757  frame.offset = 0;
10758  frame.delivery = ast_tv(0, 0);
10759  frame.src = NULL;
10760  frame.data.ptr = bc->bframe;
10761 
10762  if (ch->ast) {
10763  ast_queue_frame(ch->ast, &frame);
10764  }
10765  } else {
10766  struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT };
10767  int t;
10768 
10769  t = ast_poll(&pfd, 1, 0);
10770 
10771  if (t < 0) {
10772  chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno));
10773  break;
10774  }
10775  if (!t) {
10776  chan_misdn_log(9, bc->port, "poll() timed out\n");
10777  break;
10778  }
10779 
10780  if (pfd.revents & POLLOUT) {
10781  chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len);
10782  if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) {
10783  chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno));
10784 
10785  stop_bc_tones(ch);
10786  hangup_chan(ch, bc);
10787  release_chan(ch, bc);
10788  }
10789  } else {
10790  chan_misdn_log(1, bc->port, "Write Pipe full!\n");
10791  }
10792  }
10793  break;
10794  case EVENT_TIMEOUT:
10795  if (ch && bc) {
10796  chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch));
10797  }
10798 
10799  switch (ch->state) {
10800  case MISDN_DIALING:
10801  case MISDN_PROGRESS:
10802  if (bc->nt && !ch->nttimeout) {
10803  break;
10804  }
10805  /* fall-through */
10806  case MISDN_CALLING:
10807  case MISDN_ALERTING:
10808  case MISDN_PROCEEDING:
10810  if (bc->nt) {
10812  hanguptone_indicate(ch);
10813  }
10814 
10817  break;
10818  case MISDN_WAITING4DIGS:
10819  if (bc->nt) {
10822  hanguptone_indicate(ch);
10824  } else {
10827  }
10828  break;
10829  case MISDN_CLEANING:
10830  chan_misdn_log(1, bc->port, " --> in state cleaning .. so ignoring, the stack should clean it for us\n");
10831  break;
10832  default:
10834  break;
10835  }
10836  break;
10837 
10838  /****************************/
10839  /** Supplementary Services **/
10840  /****************************/
10841  case EVENT_RETRIEVE:
10842  if (!ch) {
10843  chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n");
10844  ch = find_hold_call_l3(bc->l3_id);
10845  if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) {
10846  ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n");
10848  break;
10849  }
10850  }
10851 
10852  /* remember the channel again */
10853  ch->bc = bc;
10854 
10855  ch->hold.state = MISDN_HOLD_IDLE;
10856  ch->hold.port = 0;
10857  ch->hold.channel = 0;
10858 
10860 
10862  chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
10864  }
10865  break;
10866  case EVENT_HOLD:
10867  {
10868  int hold_allowed;
10869  struct ast_channel *bridged;
10870 
10871  misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(hold_allowed));
10872  if (!hold_allowed) {
10873  chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
10875  break;
10876  }
10877 
10878  bridged = ast_bridged_channel(ch->ast);
10879  if (bridged) {
10880  chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type);
10881  ch->l3id = bc->l3_id;
10882 
10883  /* forget the channel now */
10884  ch->bc = NULL;
10886  ch->hold.port = bc->port;
10887  ch->hold.channel = bc->channel;
10888 
10890 
10892  } else {
10894  chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
10895  }
10896  break;
10897  }
10898  case EVENT_NOTIFY:
10899  if (bc->redirecting.to_changed) {
10900  /* Add configured prefix to redirecting.to.number */
10902  bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
10903  }
10904  switch (bc->notify_description_code) {
10906  /* Ignore for now. */
10907  bc->redirecting.to_changed = 0;
10908  break;
10910  if (!bc->redirecting.to_changed) {
10911  break;
10912  }
10913  bc->redirecting.to_changed = 0;
10914  if (!ch || !ch->ast) {
10915  break;
10916  }
10917  switch (ch->state) {
10918  case MISDN_ALERTING:
10919  /* Call is deflecting after we have seen an ALERTING message */
10921  break;
10922  default:
10923  /* Call is deflecting for call forwarding unconditional or busy reason. */
10925  break;
10926  }
10929  break;
10931  /*
10932  * It would be preferable to update the connected line information
10933  * only when the message callStatus is active. However, the
10934  * optional redirection number may not be present in the active
10935  * message if an alerting message were received earlier.
10936  *
10937  * The consequences if we wind up sending two updates is benign.
10938  * The other end will think that it got transferred twice.
10939  */
10940  if (!bc->redirecting.to_changed) {
10941  break;
10942  }
10943  bc->redirecting.to_changed = 0;
10944  if (!ch || !ch->ast) {
10945  break;
10946  }
10949  bc->incoming_cid_tag);
10950  break;
10952  if (!bc->redirecting.to_changed) {
10953  break;
10954  }
10955  bc->redirecting.to_changed = 0;
10956  if (!ch || !ch->ast) {
10957  break;
10958  }
10961  break;
10962  default:
10963  bc->redirecting.to_changed = 0;
10964  chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n",
10966  break;
10967  }
10969  break;
10970  case EVENT_FACILITY:
10971  if (bc->fac_in.Function == Fac_None) {
10972  /* This is a FACILITY message so we MUST have a facility ie */
10973  chan_misdn_log(0, bc->port," --> Missing facility ie or unknown facility ie contents.\n");
10974  } else {
10975  misdn_facility_ie_handler(event, bc, ch);
10976  }
10977 
10978  /* In case it came in on a FACILITY message and we did not handle it. */
10979  bc->redirecting.to_changed = 0;
10981  break;
10982  case EVENT_RESTART:
10983  if (!bc->dummy) {
10984  stop_bc_tones(ch);
10985  release_chan(ch, bc);
10986  }
10987  break;
10988  default:
10989  chan_misdn_log(1, 0, "Got Unknown Event\n");
10990  break;
10991  }
10992 
10993  if (ch) {
10994  chan_list_unref(ch, "cb_event complete OK");
10995  }
10996  return RESPONSE_OK;
10997 }
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:374
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7051
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7660
static struct chan_list * find_hold_call(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8210
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7655
const char *const type
Definition: channel.h:508
static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
Definition: chan_misdn.c:8847
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
Definition: causes.h:134
static const char * misdn_to_str_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1804
int rings
Definition: channel.h:840
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
static int read_config(struct chan_list *ch)
Definition: chan_misdn.c:5891
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:1972
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
#define ast_strdup(a)
Definition: astmm.h:109
int addr
From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid() ...
Definition: chan_misdn.c:519
int tone_cnt
Number of tone samples to generate.
Definition: isdn_lib.h:544
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
Definition: chan_misdn.c:410
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
Definition: chan_misdn.c:8546
int dummy
TRUE if this is a dummy BC record.
Definition: isdn_lib.h:361
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:416
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2089
static void cl_queue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8304
int bframe_len
B channel speech sample data buffer size.
Definition: isdn_lib.h:435
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * manager_isdn_get_info(enum event_e event)
Definition: isdn_lib.c:4324
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
int cw
TRUE if call waiting.
Definition: isdn_lib.h:426
#define AST_FRAME_DTMF
Definition: frame.h:128
static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8422
struct ast_generator * generator
Definition: channel.h:747
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
B channel control structure.
Definition: isdn_lib.h:324
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4071
static struct chan_list * find_hold_active_call(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8278
static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
Definition: chan_misdn.c:6368
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
Definition: chan_misdn.c:8833
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
#define ast_mutex_lock(a)
Definition: lock.h:155
unsigned short transfercapability
Definition: channel.h:863
static const char * misdn_to_str_pres(int presentation)
Definition: chan_misdn.c:2056
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
Definition: isdn_lib.h:521
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
Definition: features.c:7380
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
Definition: chan_misdn.c:525
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static const char * misdn_to_str_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:1930
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:5415
static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
Definition: chan_misdn.c:8617
int misdn_cap_is_speech(int cap)
Definition: isdn_lib.c:436
static int misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data)
Definition: chan_misdn.c:3578
static int misdn_is_msn_valid(int port, const struct misdn_party_dialing *dialed)
Definition: chan_misdn.c:9846
struct timeval overlap_tv
Overlap timer start time. Timer restarted for every digit received.
Definition: chan_misdn.c:575
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
static int stop_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7689
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int misdn_inband_avail(struct misdn_bchannel *bc)
Definition: isdn_lib.c:444
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1846
int misdn_lib_port_block(int port)
Definition: isdn_lib.c:91
int need_release_complete
TRUE if RELEASE_COMPLETE needs to be sent to clear a call.
Definition: isdn_lib.h:392
#define AST_FORMAT_ALAW
Definition: frame.h:248
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:565
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static const char * misdn_to_str_screen(int screening)
Definition: chan_misdn.c:2145
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
void misdn_lib_log_ies(struct misdn_bchannel *bc)
Definition: isdn_lib.c:3431
char infos_pending[MISDN_MAX_NUMBER_LEN]
Collected digits to go into info_dad[] while waiting for a SETUP_ACKNOWLEDGE to come in...
Definition: isdn_lib.h:653
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
static struct chan_list * find_chan_by_bc(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8186
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
char * bc_state2str(enum bchannel_state state)
Definition: isdn_lib.c:617
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int far_alerting
TRUE if we must do the ringback tones.
Definition: chan_misdn.c:542
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
int ast_cdr_update(struct ast_channel *chan)
Update CDR on a channel.
Definition: cdr.c:1083
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:334
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Export parameters to the dialplan environment variables.
Definition: chan_misdn.c:8769
char allowed_bearers[BUFFERSIZE+1]
The &quot;allowed_bearers&quot; string read in from /etc/asterisk/misdn.conf.
Definition: chan_misdn.c:353
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
static const char * bearer2str(int cap)
Definition: chan_misdn.c:2345
#define LOG_ERROR
Definition: logger.h:155
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3396
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
static struct chan_list * find_hold_call_l3(unsigned long l3_id)
Definition: chan_misdn.c:8244
static void misdn_update_remote_party(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
Definition: chan_misdn.c:6145
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int misdn_overlap_dial_task(const void *data)
Definition: chan_misdn.c:3597
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int add_in_calls(int port)
Definition: chan_misdn.c:8802
#define LOG_NOTICE
Definition: logger.h:133
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:570
#define ORG_MISDN
Definition: chan_misdn.c:317
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int errno
static struct allowed_bearers allowed_bearers_array[]
Definition: chan_misdn.c:2334
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
Definition: isdn_lib.h:429
Channel call record structure.
Definition: chan_misdn.c:349
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:513
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
static struct chan_list * chan_list_init(int orig)
Definition: chan_misdn.c:7748
int channel
Original B channel number the HELD call was using.
Definition: chan_misdn.c:340
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8374
int(* generate)(struct ast_channel *chan, void *data, int len, int samples)
Definition: channel.h:186
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
static void print_bearer(struct misdn_bchannel *bc)
Definition: chan_misdn.c:3327
static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
Definition: chan_misdn.c:3430
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
char * tag
User-set &quot;tag&quot;.
Definition: channel.h:304
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:3107
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
int need_release
TRUE if RELEASE needs to be sent to clear a call.
Definition: isdn_lib.h:389
int need_more_infos
TRUE if we send SETUP_ACKNOWLEDGE on incoming calls anyway (instead of PROCEEDING).
Definition: isdn_lib.h:465
int dtmf
Last decoded DTMF digit from mISDN driver.
Definition: isdn_lib.h:452
enum bchannel_state bc_state
Current B Channel state.
Definition: isdn_lib.h:547
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7681
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
int need_disconnect
TRUE if DISCONNECT needs to be sent to clear a call.
Definition: isdn_lib.h:386
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Definition: channel.c:1041
Data structure associated with a single frame of data.
Definition: frame.h:142
int progress_indicator
Progress Indicator IE progress description field. Used to determine if there is an inband audio messa...
Definition: isdn_lib.h:492
int hangupcause
Definition: channel.h:849
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
#define ORG_AST
Definition: chan_misdn.c:315
char * bframe
B channel speech sample data buffer.
Definition: isdn_lib.h:432
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
Definition: channel.c:9605
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
char info_dad[MISDN_MAX_NUMBER_LEN]
Current overlap dialing digits to/from INFORMATION messages.
Definition: isdn_lib.h:650
static void update_name(struct ast_channel *tmp, int port, int c)
Definition: chan_misdn.c:8087
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2182
struct ast_channel_tech * tech
Definition: channel.h:743
struct FacParm fac_in
Inbound FACILITY message function type and contents.
Definition: isdn_lib.h:507
static struct ast_channel * misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c)
Definition: chan_misdn.c:8111
void * generatordata
Definition: channel.h:746
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:560
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
const char * ast_pickup_ext(void)
Determine system call pickup extension.
Definition: features.c:849
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
Definition: chan_misdn.c:385
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch)
Definition: chan_misdn.c:9051
#define ast_mutex_unlock(a)
Definition: lock.h:156
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
int nttimeout
TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
Definition: chan_misdn.c:548
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void chan_list_destructor ( void *  obj)
static

Definition at line 7709 of file chan_misdn.c.

References ao2_ref, ast_dsp_free(), ast_mutex_destroy, chan_list::dsp, chan_list::jb, misdn_jb_destroy(), misdn_tasks_remove(), chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, and chan_list::pipe.

Referenced by chan_list_init().

7710 {
7711  struct chan_list *ch = obj;
7712 
7713 #if defined(AST_MISDN_ENHANCEMENTS)
7714  if (ch->peer) {
7715  ao2_ref(ch->peer, -1);
7716  ch->peer = NULL;
7717  }
7718 #endif /* AST_MISDN_ENHANCEMENTS */
7719 
7720  if (ch->dsp) {
7721  ast_dsp_free(ch->dsp);
7722  ch->dsp = NULL;
7723  }
7724 
7725  /* releasing jitterbuffer */
7726  if (ch->jb) {
7727  misdn_jb_destroy(ch->jb);
7728  ch->jb = NULL;
7729  }
7730 
7731  if (ch->overlap_dial) {
7732  if (ch->overlap_dial_task != -1) {
7734  ch->overlap_dial_task = -1;
7735  }
7737  }
7738 
7739  if (-1 < ch->pipe[0]) {
7740  close(ch->pipe[0]);
7741  }
7742  if (-1 < ch->pipe[1]) {
7743  close(ch->pipe[1]);
7744  }
7745 }
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:482
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1650
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:416
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:475
void misdn_jb_destroy(struct misdn_jb *jb)
frees the data and destroys the given jitterbuffer struct
Definition: chan_misdn.c:12497
static void misdn_tasks_remove(int task_id)
Definition: chan_misdn.c:3583
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:565
#define ao2_ref(o, delta)
Definition: astobj2.h:472
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:570
Channel call record structure.
Definition: chan_misdn.c:349
#define ast_mutex_destroy(a)
Definition: lock.h:154
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:560
static struct chan_list* chan_list_init ( int  orig)
static

Returns a reference to the new chan_list.

Definition at line 7748 of file chan_misdn.c.

References ao2_alloc, chan_list_destructor(), chan_misdn_log(), chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, chan_list::originator, chan_list::overlap_dial_task, and chan_list::pipe.

Referenced by cb_events(), and misdn_request().

7749 {
7750  struct chan_list *cl;
7751 
7752  cl = ao2_alloc(sizeof(*cl), chan_list_destructor);
7753  if (!cl) {
7754  chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
7755  return NULL;
7756  }
7757 
7758  cl->originator = orig;
7759  cl->need_queue_hangup = 1;
7760  cl->need_hangup = 1;
7761  cl->need_busy = 1;
7762  cl->overlap_dial_task = -1;
7763 #if defined(AST_MISDN_ENHANCEMENTS)
7764  cl->record_id = -1;
7765 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7766  cl->pipe[0] = -1;
7767  cl->pipe[1] = -1;
7768 
7769  return cl;
7770 }
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:374
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:369
int need_queue_hangup
TRUE if a hangup needs to be queued.
Definition: chan_misdn.c:364
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:416
static void chan_list_destructor(void *obj)
Definition: chan_misdn.c:7709
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:565
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
Channel call record structure.
Definition: chan_misdn.c:349
int chan_misdn_jb_empty ( struct misdn_bchannel bc,
char *  buf,
int  len 
)

Definition at line 12432 of file chan_misdn.c.

References chan_list_unref, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().

Referenced by load_module().

12433 {
12434  struct chan_list *ch;
12435  int res;
12436 
12437  ch = find_chan_by_bc(bc);
12438  if (!ch) {
12439  return 0;
12440  }
12441 
12442  if (ch->jb) {
12443  res = misdn_jb_empty(ch->jb, buf, len);
12444  } else {
12445  res = 0;
12446  }
12447  chan_list_unref(ch, "Done emptying jb");
12448 
12449  return res;
12450 }
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:475
static struct chan_list * find_chan_by_bc(struct misdn_bchannel *bc)
Definition: chan_misdn.c:8186
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the...
Definition: chan_misdn.c:12574
static void chan_misdn_log ( int  level,
int  port,
char *  tmpl,
  ... 
)
static

Definition at line 12626 of file chan_misdn.c.

References ast_log(), ast_strlen_zero(), ast_verbose(), errno, and LOG_WARNING.

Referenced by cb_events(), chan_list_init(), cl_queue_chan(), config_jitterbuffer(), debug_numtype(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_chan_by_bc(), find_hold_call(), load_module(), misdn_answer(), misdn_attempt_transfer(), misdn_bridge(), misdn_call(), misdn_check_l2l1(), misdn_digit_end(), misdn_facility_exec(), misdn_facility_ie_handler(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_empty(), misdn_jb_fill(), misdn_jb_init(), misdn_l1_task(), misdn_new(), misdn_overlap_dial_task(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_tasks_destroy(), misdn_tasks_init(), misdn_tasks_thread_func(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), start_pbx(), stop_indicate(), update_config(), and update_name().

12627 {
12628  va_list ap;
12629  char buf[1024];
12630  char port_buf[8];
12631 
12632  if (!(0 <= port && port <= max_ports)) {
12633  ast_log(LOG_WARNING, "chan_misdn_log called with out-of-range port number! (%d)\n", port);
12634  port = 0;
12635  level = -1;
12636  } else if (!(level == -1
12637  || (misdn_debug_only[port]
12638  ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12639  : level <= misdn_debug[port])
12640  || (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)))) {
12641  /*
12642  * We are not going to print anything so lets not
12643  * go to all the work of generating a string.
12644  */
12645  return;
12646  }
12647 
12648  snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port);
12649  va_start(ap, tmpl);
12650  vsnprintf(buf, sizeof(buf), tmpl, ap);
12651  va_end(ap);
12652 
12653  if (level == -1) {
12654  ast_log(LOG_WARNING, "%s", buf);
12655  } else if (misdn_debug_only[port]
12656  ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12657  : level <= misdn_debug[port]) {
12658  ast_verbose("%s%s", port_buf, buf);
12659  }
12660 
12661  if (level <= misdn_debug[0] && !ast_strlen_zero(global_tracefile)) {
12662  char ctimebuf[30];
12663  time_t tm;
12664  char *tmp;
12665  char *p;
12666  FILE *fp;
12667 
12668  fp = fopen(global_tracefile, "a+");
12669  if (!fp) {
12670  ast_verbose("Error opening Tracefile: [ %s ] %s\n", global_tracefile, strerror(errno));
12671  return;
12672  }
12673 
12674  tm = time(NULL);
12675  tmp = ctime_r(&tm, ctimebuf);
12676  p = strchr(tmp, '\n');
12677  if (p) {
12678  *p = ':';
12679  }
12680  fputs(tmp, fp);
12681  fputs(" ", fp);
12682  fputs(port_buf, fp);
12683  fputs(" ", fp);
12684  fputs(buf, fp);
12685 
12686  fclose(fp);
12687  }
12688 }
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static int * misdn_debug_only
Definition: chan_misdn.c:669
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int max_ports
Definition: chan_misdn.c:670
static char global_tracefile[BUFFERSIZE+1]
Definition: chan_misdn.c:99
static int * misdn_debug
Definition: chan_misdn.c:668
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static int cl_dequeue_chan ( struct chan_list chan)
static

Definition at line 8325 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list_unref, and chan_list::next.

Referenced by release_chan(), and release_chan_early().

8326 {
8327  int found_it;
8328  struct chan_list *help;
8329 
8331  if (!cl_te) {
8332  /* List is empty. */
8334  return 0;
8335  }
8336 
8337  if (cl_te == chan) {
8338  /* What we want is the head of the list. */
8339  cl_te = cl_te->next;
8341  chan_list_unref(chan, "Removed chan_list from list head");
8342  return 1;
8343  }
8344 
8345  found_it = 0;
8346  for (help = cl_te; help->next; help = help->next) {
8347  if (help->next == chan) {
8348  /* Found it in the list. */
8349  help->next = help->next->next;
8350  found_it = 1;
8351  break;
8352  }
8353  }
8354 
8356  if (found_it) {
8357  chan_list_unref(chan, "Removed chan_list from list");
8358  }
8359  return found_it;
8360 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void cl_queue_chan ( struct chan_list chan)
static

Definition at line 8304 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, chan_misdn_log(), chan_list::next, and misdn_bchannel::port.

Referenced by cb_events(), and misdn_request().

8305 {
8306  chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan);
8307 
8308  chan_list_ref(chan, "Adding chan_list to list");
8310  chan->next = NULL;
8311  if (!cl_te) {
8312  /* List is empty, make head of list. */
8313  cl_te = chan;
8314  } else {
8315  struct chan_list *help;
8316 
8317  /* Put at end of list. */
8318  for (help = cl_te; help->next; help = help->next) {
8319  }
8320  help->next = chan;
8321  }
8323 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char * complete_ch ( struct ast_cli_args a)
static

Definition at line 5623 of file chan_misdn.c.

References ast_complete_channels(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, and ast_cli_args::word.

Referenced by handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), handle_cli_misdn_show_channel(), and handle_cli_misdn_toggle_echocancel().

5624 {
5625  return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
5626 }
const char * line
Definition: cli.h:156
const int n
Definition: cli.h:159
const char * word
Definition: cli.h:157
const int pos
Definition: cli.h:158
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: cli.c:1547
static char * complete_debug_port ( struct ast_cli_args a)
static

Definition at line 5628 of file chan_misdn.c.

References ast_strdup, ast_cli_args::n, ast_cli_args::pos, and ast_cli_args::word.

Referenced by handle_cli_misdn_set_debug().

5629 {
5630  if (a->n) {
5631  return NULL;
5632  }
5633 
5634  switch (a->pos) {
5635  case 4:
5636  if (a->word[0] == 'p') {
5637  return ast_strdup("port");
5638  } else if (a->word[0] == 'o') {
5639  return ast_strdup("only");
5640  }
5641  break;
5642  case 6:
5643  if (a->word[0] == 'o') {
5644  return ast_strdup("only");
5645  }
5646  break;
5647  }
5648  return NULL;
5649 }
#define ast_strdup(a)
Definition: astmm.h:109
const int n
Definition: cli.h:159
const char * word
Definition: cli.h:157
const int pos
Definition: cli.h:158
static char * complete_show_config ( struct ast_cli_args a)
static

Definition at line 5651 of file chan_misdn.c.

References ast_strdup, BUFFERSIZE, ast_cli_args::line, MISDN_CFG_FIRST, misdn_cfg_get_name(), misdn_cfg_get_next_port(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, ast_cli_args::n, ast_cli_args::pos, and ast_cli_args::word.

Referenced by handle_cli_misdn_show_config().

5652 {
5653  char buffer[BUFFERSIZE];
5654  enum misdn_cfg_elements elem;
5655  int wordlen = strlen(a->word);
5656  int which = 0;
5657  int port = 0;
5658 
5659  switch (a->pos) {
5660  case 3:
5661  if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n)) {
5662  return ast_strdup("description");
5663  }
5664  if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n)) {
5665  return ast_strdup("descriptions");
5666  }
5667  if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n)) {
5668  return ast_strdup("0");
5669  }
5670  while ((port = misdn_cfg_get_next_port(port)) != -1) {
5671  snprintf(buffer, sizeof(buffer), "%d", port);
5672  if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) {
5673  return ast_strdup(buffer);
5674  }
5675  }
5676  break;
5677  case 4:
5678  if (strstr(a->line, "description ")) {
5679  for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
5680  if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) {
5681  continue;
5682  }
5683  misdn_cfg_get_name(elem, buffer, sizeof(buffer));
5684  if (!wordlen || !strncmp(a->word, buffer, wordlen)) {
5685  if (++which > a->n) {
5686  return ast_strdup(buffer);
5687  }
5688  }
5689  }
5690  } else if (strstr(a->line, "descriptions ")) {
5691  if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n)) {
5692  return ast_strdup("general");
5693  }
5694  if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n)) {
5695  return ast_strdup("ports");
5696  }
5697  }
5698  break;
5699  }
5700  return NULL;
5701 }
#define ast_strdup(a)
Definition: astmm.h:109
misdn_cfg_elements
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
const char * line
Definition: cli.h:156
#define BUFFERSIZE
void misdn_cfg_get_name(enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:637
const int n
Definition: cli.h:159
const char * word
Definition: cli.h:157
const int pos
Definition: cli.h:158
static void config_jitterbuffer ( struct chan_list ch)
static

Definition at line 5786 of file chan_misdn.c.

References chan_list::bc, cb_log, chan_misdn_log(), chan_list::jb, chan_list::jb_len, chan_list::jb_upper_threshold, len(), misdn_jb_destroy(), misdn_jb_init(), misdn_bchannel::nojitter, and misdn_bchannel::port.

Referenced by misdn_set_opt_exec(), and read_config().

5787 {
5788  struct misdn_bchannel *bc = ch->bc;
5789  int len = ch->jb_len;
5790  int threshold = ch->jb_upper_threshold;
5791 
5792  chan_misdn_log(5, bc->port, "config_jb: Called\n");
5793 
5794  if (!len) {
5795  chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n");
5796  bc->nojitter = 1;
5797  } else {
5798  if (len <= 100 || len > 8000) {
5799  chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
5800  len = 1000;
5801  }
5802 
5803  if (threshold > len) {
5804  chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
5805  }
5806 
5807  if (ch->jb) {
5808  cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n");
5809  misdn_jb_destroy(ch->jb);
5810  ch->jb = NULL;
5811  }
5812 
5813  ch->jb = misdn_jb_init(len, threshold);
5814 
5815  if (!ch->jb) {
5816  bc->nojitter = 1;
5817  }
5818  }
5819 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int jb_len
Jitterbuffer length.
Definition: chan_misdn.c:462
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:475
void misdn_jb_destroy(struct misdn_jb *jb)
frees the data and destroys the given jitterbuffer struct
Definition: chan_misdn.c:12497
int jb_upper_threshold
Jitterbuffer upper threshold.
Definition: chan_misdn.c:468
B channel control structure.
Definition: isdn_lib.h:324
threshold
Definition: dsp.h:62
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
struct misdn_jb * misdn_jb_init(int size, int upper_threshold)
allocates the jb-structure and initialize the elements
Definition: chan_misdn.c:12460
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
void debug_numtype ( int  port,
int  numtype,
char *  type 
)

Definition at line 5822 of file chan_misdn.c.

References chan_misdn_log(), NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.

Referenced by misdn_call(), misdn_get_connected_line(), and read_config().

5823 {
5824  switch (numtype) {
5825  case NUMTYPE_UNKNOWN:
5826  chan_misdn_log(2, port, " --> %s: Unknown\n", type);
5827  break;
5828  case NUMTYPE_INTERNATIONAL:
5829  chan_misdn_log(2, port, " --> %s: International\n", type);
5830  break;
5831  case NUMTYPE_NATIONAL:
5832  chan_misdn_log(2, port, " --> %s: National\n", type);
5833  break;
5835  chan_misdn_log(2, port, " --> %s: Network Specific\n", type);
5836  break;
5837  case NUMTYPE_SUBSCRIBER:
5838  chan_misdn_log(2, port, " --> %s: Subscriber\n", type);
5839  break;
5840  case NUMTYPE_ABBREVIATED:
5841  chan_misdn_log(2, port, " --> %s: Abbreviated\n", type);
5842  break;
5843  /* Maybe we should cut off the prefix if present ? */
5844  default:
5845  chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
5846  break;
5847  }
5848 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char type[]
Definition: chan_nbs.c:57
static int dialtone_indicate ( struct chan_list cl)
static

AST INDICATIONS END

Definition at line 7624 of file chan_misdn.c.

References chan_list::ast, ast_get_indication_tone(), ast_playtones_start(), chan_list::bc, chan_misdn_log(), ast_tone_zone_sound::data, misdn_cfg_get(), MISDN_CFG_NODIALTONE, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::port, chan_list::ts, and ast_channel::zone.

Referenced by wait_for_digits().

7625 {
7626  struct ast_channel *ast = cl->ast;
7627  int nd = 0;
7628 
7629  if (!ast) {
7630  chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n");
7631  return -1;
7632  }
7633 
7634  misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
7635 
7636  if (nd) {
7637  chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n");
7638  return 0;
7639  }
7640 
7641  chan_misdn_log(3, cl->bc->port, " --> Dial\n");
7642 
7643  cl->ts = ast_get_indication_tone(ast->zone, "dial");
7644 
7645  if (cl->ts) {
7646  cl->notxtone = 0;
7647  cl->norxtone = 0;
7648  /* This prods us in misdn_write */
7649  ast_playtones_start(ast, 0, cl->ts->data, 0);
7650  }
7651 
7652  return 0;
7653 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_tone_zone * zone
Definition: channel.h:767
int norxtone
Definition: chan_misdn.c:387
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:392
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
Definition: indications.c:473
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
Definition: chan_misdn.c:554
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:319
const char * data
Description of a tone.
Definition: indications.h:53
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static void do_immediate_setup ( struct misdn_bchannel bc,
struct chan_list ch,
struct ast_channel ast 
)
static

Definition at line 8617 of file chan_misdn.c.

References chan_list::ast, ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_FRAME_DTMF, ast_queue_frame(), ast_strdupa, ast_strlen_zero(), ast_tv(), misdn_bchannel::caller, ast_channel::caller, chan_misdn_log(), ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_RELEASE_COMPLETE, EVENT_SETUP_ACKNOWLEDGE, ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), ast_party_caller::id, ast_frame_subclass::integer, ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_send_event(), ast_party_id::name, chan_list::noautorespond_on_setup, misdn_bchannel::nt, ast_party_id::number, misdn_party_id::number, ast_frame::offset, misdn_bchannel::out_cause, pbx_start_chan(), misdn_bchannel::port, ast_frame::ptr, ast_frame::samples, ast_frame::src, chan_list::state, ast_party_name::str, ast_party_number::str, ast_frame::subclass, ast_party_name::valid, and ast_party_number::valid.

Referenced by cb_events().

8618 {
8619  char *predial;
8620  struct ast_frame fr;
8621 
8622  predial = ast_strdupa(ast->exten);
8623 
8624  ch->state = MISDN_DIALING;
8625 
8626  if (!ch->noautorespond_on_setup) {
8627  if (bc->nt) {
8629  } else {
8630  if (misdn_lib_is_ptp(bc->port)) {
8632  } else {
8634  }
8635  }
8636  } else {
8638  }
8639 
8640  chan_misdn_log(1, bc->port,
8641  "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n",
8642  ast->context,
8643  ast->exten,
8644  (ast->caller.id.name.valid && ast->caller.id.name.str)
8645  ? ast->caller.id.name.str : "",
8646  (ast->caller.id.number.valid && ast->caller.id.number.str)
8647  ? ast->caller.id.number.str : "");
8648 
8649  strcpy(ast->exten, "s");
8650 
8651  if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->caller.number) || pbx_start_chan(ch) < 0) {
8652  ast = NULL;
8654  hangup_chan(ch, bc);
8655  hanguptone_indicate(ch);
8656 
8658  }
8659 
8660 
8661  while (!ast_strlen_zero(predial)) {
8662  fr.frametype = AST_FRAME_DTMF;
8663  fr.subclass.integer = *predial;
8664  fr.src = NULL;
8665  fr.data.ptr = NULL;
8666  fr.datalen = 0;
8667  fr.samples = 0;
8668  fr.mallocd = 0;
8669  fr.offset = 0;
8670  fr.delivery = ast_tv(0,0);
8671 
8672  if (ch->ast && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
8673  ast_queue_frame(ch->ast, &fr);
8674  }
8675  predial++;
8676  }
8677 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7655
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static int pbx_start_chan(struct chan_list *ch)
Definition: chan_misdn.c:8365
#define AST_FRAME_DTMF
Definition: frame.h:128
char * str
Subscriber name (Malloced)
Definition: channel.h:214
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:5415
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8374
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
Data structure associated with a single frame of data.
Definition: frame.h:142
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
Definition: chan_misdn.c:385
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void export_aoc_vars ( int  originator,
struct ast_channel ast,
struct misdn_bchannel bc 
)
static

Definition at line 3430 of file chan_misdn.c.

References misdn_bchannel::AOCD, misdn_bchannel::AOCD_need_export, misdn_bchannel::AOCDtype, ast_bridged_channel(), misdn_bchannel::chargingUnit, misdn_bchannel::currency, ORG_AST, and pbx_builtin_setvar_helper().

Referenced by cb_events(), and misdn_facility_ie_handler().

3431 {
3432  char buf[128];
3433 
3434  if (!bc->AOCD_need_export || !ast) {
3435  return;
3436  }
3437 
3438  if (originator == ORG_AST) {
3439  ast = ast_bridged_channel(ast);
3440  if (!ast) {
3441  return;
3442  }
3443  }
3444 
3445  switch (bc->AOCDtype) {
3446  case Fac_AOCDCurrency:
3447  pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency");
3448  if (bc->AOCD.currency.chargeNotAvailable) {
3449  pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
3450  } else {
3451  pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
3452  if (bc->AOCD.currency.freeOfCharge) {
3453  pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
3454  } else {
3455  pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
3456  if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {
3457  pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf);
3458  if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) {
3459  pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
3460  }
3461  }
3462  }
3463  }
3464  break;
3465  case Fac_AOCDChargingUnit:
3466  pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit");
3467  if (bc->AOCD.chargingUnit.chargeNotAvailable) {
3468  pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
3469  } else {
3470  pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
3471  if (bc->AOCD.chargingUnit.freeOfCharge) {
3472  pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
3473  } else {
3474  pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
3475  if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {
3476  pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf);
3477  if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) {
3478  pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
3479  }
3480  }
3481  }
3482  }
3483  break;
3484  default:
3485  break;
3486  }
3487 
3488  bc->AOCD_need_export = 0;
3489 }
enum FacFunction AOCDtype
Definition: isdn_lib.h:515
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
Definition: isdn_lib.h:521
struct FacAOCDCurrency currency
Definition: isdn_lib.h:517
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define ORG_AST
Definition: chan_misdn.c:315
union misdn_bchannel::@126 AOCD
struct FacAOCDChargingUnit chargingUnit
Definition: isdn_lib.h:518
void export_ch ( struct ast_channel chan,
struct misdn_bchannel bc,
struct chan_list ch 
)

Export parameters to the dialplan environment variables.

Definition at line 8769 of file chan_misdn.c.

References ast_strlen_zero(), chan_misdn_log(), misdn_bchannel::keypad, pbx_builtin_setvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::sending_complete, misdn_bchannel::urate, misdn_bchannel::uu, and misdn_bchannel::uulen.

Referenced by cb_events().

8770 {
8771  char tmp[32];
8772 
8773  /*
8774  * The only use for MISDN_PID is if there is a problem and you
8775  * have to use the "misdn restart pid" CLI command. Otherwise,
8776  * the pid is not used by anyone. The internal use of MISDN_PID
8777  * has been deleted.
8778  */
8779  chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid);
8780  snprintf(tmp, sizeof(tmp), "%d", bc->pid);
8781  pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp);
8782 
8783  if (bc->sending_complete) {
8784  snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete);
8785  pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp);
8786  }
8787 
8788  if (bc->urate) {
8789  snprintf(tmp, sizeof(tmp), "%d", bc->urate);
8790  pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp);
8791  }
8792 
8793  if (bc->uulen) {
8794  pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu);
8795  }
8796 
8797  if (!ast_strlen_zero(bc->keypad)) {
8798  pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad);
8799  }
8800 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
int uulen
User-User information string length in uu[].
Definition: isdn_lib.h:666
char uu[256]
User-User information string.
Definition: isdn_lib.h:663
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int urate
Q.931 Bearer Capability IE Layer 1 User Rate field.
Definition: isdn_lib.h:629
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
static struct chan_list* find_chan_by_bc ( struct misdn_bchannel bc)
static

Returns a reference to the found chan_list.

Definition at line 8186 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list::bc, misdn_bchannel::caller, chan_list_ref, chan_misdn_log(), misdn_bchannel::dialed, misdn_party_id::name, chan_list::next, misdn_party_dialing::number, misdn_party_id::number, and misdn_bchannel::port.

Referenced by cb_events(), and chan_misdn_jb_empty().

8187 {
8188  struct chan_list *help;
8189 
8191  for (help = cl_te; help; help = help->next) {
8192  if (help->bc == bc) {
8193  chan_list_ref(help, "Found chan_list by bc");
8195  return help;
8196  }
8197  }
8199 
8200  chan_misdn_log(6, bc->port,
8201  "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8202  bc->dialed.number,
8203  bc->caller.name,
8204  bc->caller.number);
8205 
8206  return NULL;
8207 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct chan_list* find_hold_active_call ( struct misdn_bchannel bc)
static

Definition at line 8278 of file chan_misdn.c.

References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list::bc, chan_list_ref, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_IDLE, MISDN_PROCEEDING, MISDN_PROGRESS, chan_list::next, misdn_bchannel::port, hold_info::state, and chan_list::state.

Referenced by cb_events().

8279 {
8280  struct chan_list *list;
8281 
8283  for (list = cl_te; list; list = list->next) {
8284  if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port
8285  && list->ast) {
8286  switch (list->state) {
8287  case MISDN_PROCEEDING:
8288  case MISDN_PROGRESS:
8289  case MISDN_ALERTING:
8290  case MISDN_CONNECTED:
8291  chan_list_ref(list, "Found chan_list hold active call");
8293  return list;
8294  default:
8295  break;
8296  }
8297  }
8298  }
8300  return NULL;
8301 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct chan_list* find_hold_call ( struct misdn_bchannel bc)
static

Returns a reference to the found chan_list.

Definition at line 8210 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, misdn_bchannel::caller, chan_list_ref, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::dialed, chan_list::hold, MISDN_HOLD_ACTIVE, misdn_party_id::name, chan_list::next, misdn_party_dialing::number, misdn_party_id::number, hold_info::port, misdn_bchannel::port, misdn_bchannel::pri, and hold_info::state.

Referenced by cb_events().

8211 {
8212  struct chan_list *help;
8213 
8214  if (bc->pri) {
8215  return NULL;
8216  }
8217 
8218  chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d dialed:%s caller:\"%s\" <%s>\n",
8219  bc->channel,
8220  bc->dialed.number,
8221  bc->caller.name,
8222  bc->caller.number);
8224  for (help = cl_te; help; help = help->next) {
8225  chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel);
8226  if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port) {
8227  chan_list_ref(help, "Found chan_list hold call");
8229  return help;
8230  }
8231  }
8233  chan_misdn_log(6, bc->port,
8234  "$$$ find_hold_call: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8235  bc->dialed.number,
8236  bc->caller.name,
8237  bc->caller.number);
8238 
8239  return NULL;
8240 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
int pri
TRUE if ISDN-PRI (ISDN-BRI otherwise)
Definition: isdn_lib.h:367
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:334
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
int channel
Original B channel number the HELD call was using.
Definition: chan_misdn.c:340
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct chan_list* find_hold_call_l3 ( unsigned long  l3_id)
static

Returns a reference to the found chan_list.

Definition at line 8244 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_list_ref, chan_list::hold, chan_list::l3id, MISDN_HOLD_IDLE, chan_list::next, and hold_info::state.

Referenced by cb_events().

8245 {
8246  struct chan_list *help;
8247 
8249  for (help = cl_te; help; help = help->next) {
8250  if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id) {
8251  chan_list_ref(help, "Found chan_list hold call l3");
8253  return help;
8254  }
8255  }
8257 
8258  return NULL;
8259 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
Channel call record structure.
Definition: chan_misdn.c:349
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:513
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void free_robin_list ( void  )
static

Definition at line 601 of file chan_misdn.c.

References ast_free, robin_list::group, and robin_list::next.

Referenced by reload_config(), and unload_module().

602 {
603  struct robin_list *r;
604  struct robin_list *next;
605 
606  for (r = robin, robin = NULL; r; r = next) {
607  next = r->next;
608  ast_free(r->group);
609  ast_free(r);
610  }
611 }
struct robin_list * next
Definition: chan_misdn.c:595
static struct robin_list * robin
Definition: chan_misdn.c:598
char * group
Definition: chan_misdn.c:592
#define ast_free(a)
Definition: astmm.h:97
static struct chan_list* get_chan_by_ast ( struct ast_channel ast)
static

Returns a reference to the found chan_list.

Definition at line 740 of file chan_misdn.c.

References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list_ref, and chan_list::next.

Referenced by misdn_bridge().

741 {
742  struct chan_list *tmp;
743 
745  for (tmp = cl_te; tmp; tmp = tmp->next) {
746  if (tmp->ast == ast) {
747  chan_list_ref(tmp, "Found chan_list by ast");
749  return tmp;
750  }
751  }
753 
754  return NULL;
755 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct chan_list* get_chan_by_ast_name ( const char *  name)
static

Returns a reference to the found chan_list.

Definition at line 758 of file chan_misdn.c.

References chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list_ref, ast_channel::name, and chan_list::next.

Referenced by handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_send_facility(), and handle_cli_misdn_toggle_echocancel().

759 {
760  struct chan_list *tmp;
761 
763  for (tmp = cl_te; tmp; tmp = tmp->next) {
764  if (tmp->ast && strcmp(tmp->ast->name, name) == 0) {
765  chan_list_ref(tmp, "Found chan_list by ast name");
767  return tmp;
768  }
769  }
771 
772  return NULL;
773 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
const ast_string_field name
Definition: channel.h:787
static const char name[]
Channel call record structure.
Definition: chan_misdn.c:349
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct robin_list* get_robin_position ( char *  group)
static

Definition at line 613 of file chan_misdn.c.

References ast_calloc, ast_free, ast_strdup, robin_list::group, robin_list::next, robin_list::prev, and robin.

Referenced by misdn_request().

614 {
615  struct robin_list *new;
616  struct robin_list *iter = robin;
617  for (; iter; iter = iter->next) {
618  if (!strcasecmp(iter->group, group)) {
619  return iter;
620  }
621  }
622  new = ast_calloc(1, sizeof(*new));
623  if (!new) {
624  return NULL;
625  }
626  new->group = ast_strdup(group);
627  if (!new->group) {
628  ast_free(new);
629  return NULL;
630  }
631  new->channel = 1;
632  if (robin) {
633  new->next = robin;
634  robin->prev = new;
635  }
636  robin = new;
637  return robin;
638 }
#define ast_strdup(a)
Definition: astmm.h:109
struct robin_list * next
Definition: chan_misdn.c:595
static struct robin_list * robin
Definition: chan_misdn.c:598
struct robin_list * prev
Definition: chan_misdn.c:596
char * group
Definition: chan_misdn.c:592
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
static char* handle_cli_misdn_port_block ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3799 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_port_block(), and ast_cli_entry::usage.

3800 {
3801  switch (cmd) {
3802  case CLI_INIT:
3803  e->command = "misdn port block";
3804  e->usage =
3805  "Usage: misdn port block <port>\n"
3806  " Block the specified port by <port>.\n";
3807  return NULL;
3808  case CLI_GENERATE:
3809  return NULL;
3810  }
3811 
3812  if (a->argc != 4) {
3813  return CLI_SHOWUSAGE;
3814  }
3815 
3816  misdn_lib_port_block(atoi(a->argv[3]));
3817 
3818  return CLI_SUCCESS;
3819 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
int misdn_lib_port_block(int port)
Definition: isdn_lib.c:91
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_port_down ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3909 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_get_port_down(), and ast_cli_entry::usage.

3910 {
3911  switch (cmd) {
3912  case CLI_INIT:
3913  e->command = "misdn port down";
3914  e->usage =
3915  "Usage: misdn port down <port>\n"
3916  " Try to deactivate the L1 on the given port.\n";
3917  return NULL;
3918  case CLI_GENERATE:
3919  return NULL;
3920  }
3921 
3922  if (a->argc != 4) {
3923  return CLI_SHOWUSAGE;
3924  }
3925 
3926  misdn_lib_get_port_down(atoi(a->argv[3]));
3927 
3928  return CLI_SUCCESS;
3929 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
int misdn_lib_get_port_down(int port)
Definition: isdn_lib.c:1805
static char* handle_cli_misdn_port_unblock ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3821 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_port_unblock(), and ast_cli_entry::usage.

3822 {
3823  switch (cmd) {
3824  case CLI_INIT:
3825  e->command = "misdn port unblock";
3826  e->usage =
3827  "Usage: misdn port unblock <port>\n"
3828  " Unblock the port specified by <port>.\n";
3829  return NULL;
3830  case CLI_GENERATE:
3831  return NULL;
3832  }
3833 
3834  if (a->argc != 4) {
3835  return CLI_SHOWUSAGE;
3836  }
3837 
3838  misdn_lib_port_unblock(atoi(a->argv[3]));
3839 
3840  return CLI_SUCCESS;
3841 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
int misdn_lib_port_unblock(int port)
Definition: isdn_lib.c:104
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_port_up ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3887 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_get_port_up(), and ast_cli_entry::usage.

3888 {
3889  switch (cmd) {
3890  case CLI_INIT:
3891  e->command = "misdn port up";
3892  e->usage =
3893  "Usage: misdn port up <port>\n"
3894  " Try to establish L1 on the given port.\n";
3895  return NULL;
3896  case CLI_GENERATE:
3897  return NULL;
3898  }
3899 
3900  if (a->argc != 4) {
3901  return CLI_SHOWUSAGE;
3902  }
3903 
3904  misdn_lib_get_port_up(atoi(a->argv[3]));
3905 
3906  return CLI_SUCCESS;
3907 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
int misdn_lib_get_port_up(int port)
Definition: isdn_lib.c:1781
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4113 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, reload_config(), and ast_cli_entry::usage.

4114 {
4115  switch (cmd) {
4116  case CLI_INIT:
4117  e->command = "misdn reload";
4118  e->usage =
4119  "Usage: misdn reload\n"
4120  " Reload internal mISDN config, read from the config\n"
4121  " file.\n";
4122  return NULL;
4123  case CLI_GENERATE:
4124  return NULL;
4125  }
4126 
4127  if (a->argc != 2) {
4128  return CLI_SHOWUSAGE;
4129  }
4130 
4131  ast_cli(a->fd, "Reloading mISDN configuration\n");
4132  reload_config();
4133  return CLI_SUCCESS;
4134 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
static void reload_config(void)
Definition: chan_misdn.c:4092
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_restart_pid ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3865 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_pid_restart(), and ast_cli_entry::usage.

3866 {
3867  switch (cmd) {
3868  case CLI_INIT:
3869  e->command = "misdn restart pid";
3870  e->usage =
3871  "Usage: misdn restart pid <pid>\n"
3872  " Restart the given pid\n";
3873  return NULL;
3874  case CLI_GENERATE:
3875  return NULL;
3876  }
3877 
3878  if (a->argc != 4) {
3879  return CLI_SHOWUSAGE;
3880  }
3881 
3882  misdn_lib_pid_restart(atoi(a->argv[3]));
3883 
3884  return CLI_SUCCESS;
3885 }
int misdn_lib_pid_restart(int pid)
Definition: isdn_lib.c:3932
const int argc
Definition: cli.h:154
Definition: cli.h:146
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_restart_port ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3843 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_port_restart(), and ast_cli_entry::usage.

3844 {
3845  switch (cmd) {
3846  case CLI_INIT:
3847  e->command = "misdn restart port";
3848  e->usage =
3849  "Usage: misdn restart port <port>\n"
3850  " Restart the given port.\n";
3851  return NULL;
3852  case CLI_GENERATE:
3853  return NULL;
3854  }
3855 
3856  if (a->argc != 4) {
3857  return CLI_SHOWUSAGE;
3858  }
3859 
3860  misdn_lib_port_restart(atoi(a->argv[3]));
3861 
3862  return CLI_SUCCESS;
3863 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
int misdn_lib_port_restart(int port)
Definition: isdn_lib.c:3982
static char* handle_cli_misdn_send_digit ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5478 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_cli(), ast_dtmf_stream(), chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, get_chan_by_ast_name(), send_digit_to_chan(), and ast_cli_entry::usage.

5479 {
5480  const char *channame;
5481  const char *msg;
5482  struct chan_list *tmp;
5483  int i, msglen;
5484 
5485  switch (cmd) {
5486  case CLI_INIT:
5487  e->command = "misdn send digit";
5488  e->usage =
5489  "Usage: misdn send digit <channel> \"<msg>\" \n"
5490  " Send <digit> to <channel> as DTMF Tone\n"
5491  " when channel is a mISDN channel\n";
5492  return NULL;
5493  case CLI_GENERATE:
5494  return complete_ch(a);
5495  }
5496 
5497  if (a->argc != 5) {
5498  return CLI_SHOWUSAGE;
5499  }
5500 
5501  channame = a->argv[3];
5502  msg = a->argv[4];
5503  msglen = strlen(msg);
5504 
5505  ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
5506 
5507  tmp = get_chan_by_ast_name(channame);
5508  if (!tmp) {
5509  ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
5510  return CLI_SUCCESS;
5511  }
5512 #if 1
5513  for (i = 0; i < msglen; i++) {
5514  if (!tmp->ast) {
5515  break;
5516  }
5517  ast_cli(a->fd, "Sending: %c\n", msg[i]);
5518  send_digit_to_chan(tmp, msg[i]);
5519  /* res = ast_safe_sleep(tmp->ast, 250); */
5520  usleep(250000);
5521  /* res = ast_waitfor(tmp->ast,100); */
5522  }
5523 #else
5524  if (tmp->ast) {
5525  ast_dtmf_stream(tmp->ast, NULL, msg, 250);
5526  }
5527 #endif
5528  chan_list_unref(tmp, "Digit(s) sent");
5529 
5530  return CLI_SUCCESS;
5531 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:758
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5623
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
Channel call record structure.
Definition: chan_misdn.c:349
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static void send_digit_to_chan(struct chan_list *cl, char digit)
Definition: chan_misdn.c:3650
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send DTMF to a channel.
Definition: app.c:501
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
static char* handle_cli_misdn_send_display ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5580 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), chan_list::bc, chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), misdn_bchannel::display, EVENT_INFORMATION, ast_cli_args::fd, get_chan_by_ast_name(), misdn_lib_send_event(), and ast_cli_entry::usage.

5581 {
5582  const char *channame;
5583  const char *msg;
5584  struct chan_list *tmp;
5585 
5586  switch (cmd) {
5587  case CLI_INIT:
5588  e->command = "misdn send display";
5589  e->usage =
5590  "Usage: misdn send display <channel> \"<msg>\" \n"
5591  " Send <msg> to <channel> as Display Message\n"
5592  " when channel is a mISDN channel\n";
5593  return NULL;
5594  case CLI_GENERATE:
5595  return complete_ch(a);
5596  }
5597 
5598  if (a->argc != 5) {
5599  return CLI_SHOWUSAGE;
5600  }
5601 
5602  channame = a->argv[3];
5603  msg = a->argv[4];
5604 
5605  ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
5606 
5607  tmp = get_chan_by_ast_name(channame);
5608  if (tmp && tmp->bc) {
5609  ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
5611  chan_list_unref(tmp, "Done sending display");
5612  } else {
5613  if (tmp) {
5614  chan_list_unref(tmp, "Display failed");
5615  }
5616  ast_cli(a->fd, "No such channel %s\n", channame);
5617  return CLI_SUCCESS;
5618  }
5619 
5620  return CLI_SUCCESS;
5621 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:758
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5623
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
Channel call record structure.
Definition: chan_misdn.c:349
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
static char* handle_cli_misdn_send_facility ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5152 of file chan_misdn.c.

References ao2_lock, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_copy_string(), ast_verbose(), chan_list::bc, chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), dummy(), EVENT_FACILITY, EVENT_REGISTER, misdn_bchannel::fac_out, get_chan_by_ast_name(), misdn_lib_port_is_nt(), misdn_lib_send_event(), misdn_make_dummy(), print_facility(), and ast_cli_entry::usage.

5153 {
5154  const char *channame;
5155  const char *nr;
5156  struct chan_list *tmp;
5157  int port;
5158  const char *served_nr;
5159  struct misdn_bchannel dummy, *bc=&dummy;
5160  unsigned max_len;
5161 
5162  switch (cmd) {
5163  case CLI_INIT:
5164  e->command = "misdn send facility";
5165  e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n"
5166  "\t type is one of:\n"
5167  "\t - calldeflect\n"
5168 #if defined(AST_MISDN_ENHANCEMENTS)
5169  "\t - callrerouting\n"
5170 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
5171  "\t - CFActivate\n"
5172  "\t - CFDeactivate\n";
5173 
5174  return NULL;
5175  case CLI_GENERATE:
5176  return complete_ch(a);
5177  }
5178 
5179  if (a->argc < 5) {
5180  return CLI_SHOWUSAGE;
5181  }
5182 
5183  if (strstr(a->argv[3], "calldeflect")) {
5184  if (a->argc < 6) {
5185  ast_verbose("calldeflect requires 1 arg: ToNumber\n\n");
5186  return 0;
5187  }
5188  channame = a->argv[4];
5189  nr = a->argv[5];
5190 
5191  ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame);
5192  tmp = get_chan_by_ast_name(channame);
5193  if (!tmp) {
5194  ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5195  return 0;
5196  }
5197  ao2_lock(tmp);
5198 
5199 #if defined(AST_MISDN_ENHANCEMENTS)
5200  max_len = sizeof(tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
5201  if (max_len < strlen(nr)) {
5202  ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5203  nr, channame, max_len);
5204  ao2_unlock(tmp);
5205  chan_list_unref(tmp, "Number too long");
5206  return 0;
5207  }
5208  tmp->bc->fac_out.Function = Fac_CallDeflection;
5209  tmp->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
5210  tmp->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
5211  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
5212  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
5213  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */
5214  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(nr);
5215  strcpy((char *) tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, nr);
5216  tmp->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
5217 
5218 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
5219 
5220  max_len = sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1;
5221  if (max_len < strlen(nr)) {
5222  ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5223  nr, channame, max_len);
5224  ao2_unlock(tmp);
5225  chan_list_unref(tmp, "Number too long");
5226  return 0;
5227  }
5228  tmp->bc->fac_out.Function = Fac_CD;
5229  tmp->bc->fac_out.u.CDeflection.PresentationAllowed = 0;
5230  //tmp->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0;
5231  strcpy((char *) tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr);
5232 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
5233 
5234  /* Send message */
5235  print_facility(&tmp->bc->fac_out, tmp->bc);
5236  ao2_unlock(tmp);
5238  chan_list_unref(tmp, "Send facility complete");
5239 #if defined(AST_MISDN_ENHANCEMENTS)
5240  } else if (strstr(a->argv[3], "callrerouteing") || strstr(a->argv[3], "callrerouting")) {
5241  if (a->argc < 6) {
5242  ast_verbose("callrerouting requires 1 arg: ToNumber\n\n");
5243  return 0;
5244  }
5245  channame = a->argv[4];
5246  nr = a->argv[5];
5247 
5248  ast_verbose("Sending Callrerouting (%s) to %s\n", nr, channame);
5249  tmp = get_chan_by_ast_name(channame);
5250  if (!tmp) {
5251  ast_verbose("Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5252  return 0;
5253  }
5254  ao2_lock(tmp);
5255 
5256  max_len = sizeof(tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
5257  if (max_len < strlen(nr)) {
5258  ast_verbose("Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5259  nr, channame, max_len);
5260  ao2_unlock(tmp);
5261  chan_list_unref(tmp, "Number too long");
5262  return 0;
5263  }
5264  tmp->bc->fac_out.Function = Fac_CallRerouteing;
5265  tmp->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
5266  tmp->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
5267 
5268  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */
5269  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
5270 
5271  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */
5272  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(nr);
5273  strcpy((char *) tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, nr);
5274  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
5275 
5276  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
5277 
5278  /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */
5279  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
5280  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
5281  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
5282  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
5283  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
5284  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
5285  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
5286 
5287  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */
5288  tmp->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */
5289 
5290  /* Send message */
5291  print_facility(&tmp->bc->fac_out, tmp->bc);
5292  ao2_unlock(tmp);
5294  chan_list_unref(tmp, "Send facility complete");
5295 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
5296  } else if (strstr(a->argv[3], "CFActivate")) {
5297  if (a->argc < 7) {
5298  ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
5299  return 0;
5300  }
5301  port = atoi(a->argv[4]);
5302  served_nr = a->argv[5];
5303  nr = a->argv[6];
5304 
5305  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5306 
5307  ast_verbose("Sending CFActivate Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
5308 
5309 #if defined(AST_MISDN_ENHANCEMENTS)
5310  bc->fac_out.Function = Fac_ActivationDiversion;
5311  bc->fac_out.u.ActivationDiversion.InvokeID = ++misdn_invoke_id;
5312  bc->fac_out.u.ActivationDiversion.ComponentType = FacComponent_Invoke;
5313  bc->fac_out.u.ActivationDiversion.Component.Invoke.BasicService = 0;/* allServices */
5314  bc->fac_out.u.ActivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */
5315  ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number,
5316  served_nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number));
5317  bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5318  strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number);
5319  bc->fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */
5320  ast_copy_string((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number,
5321  nr, sizeof(bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number));
5322  bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber =
5323  strlen((char *) bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number);
5324  bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 0;/* unknown */
5325  bc->fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Subaddress.Length = 0;
5326 
5327 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
5328 
5329  bc->fac_out.Function = Fac_CFActivate;
5330  bc->fac_out.u.CFActivate.BasicService = 0; /* All Services */
5331  bc->fac_out.u.CFActivate.Procedure = 0; /* Unconditional */
5332  ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
5333  ast_copy_string((char *) bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber));
5334 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
5335 
5336  /* Send message */
5337  print_facility(&bc->fac_out, bc);
5339  } else if (strstr(a->argv[3], "CFDeactivate")) {
5340  if (a->argc < 6) {
5341  ast_verbose("CFDeactivate requires 1 arg: FromNumber\n\n");
5342  return 0;
5343  }
5344  port = atoi(a->argv[4]);
5345  served_nr = a->argv[5];
5346 
5347  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5348  ast_verbose("Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr);
5349 
5350 #if defined(AST_MISDN_ENHANCEMENTS)
5351  bc->fac_out.Function = Fac_DeactivationDiversion;
5352  bc->fac_out.u.DeactivationDiversion.InvokeID = ++misdn_invoke_id;
5353  bc->fac_out.u.DeactivationDiversion.ComponentType = FacComponent_Invoke;
5354  bc->fac_out.u.DeactivationDiversion.Component.Invoke.BasicService = 0;/* allServices */
5355  bc->fac_out.u.DeactivationDiversion.Component.Invoke.Procedure = 0;/* cfu (Call Forward Unconditional) */
5356  ast_copy_string((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number,
5357  served_nr, sizeof(bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number));
5358  bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5359  strlen((char *) bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number);
5360  bc->fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Type = 0;/* unknown */
5361 
5362 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
5363 
5364  bc->fac_out.Function = Fac_CFDeactivate;
5365  bc->fac_out.u.CFDeactivate.BasicService = 0; /* All Services */
5366  bc->fac_out.u.CFDeactivate.Procedure = 0; /* Unconditional */
5367  ast_copy_string((char *) bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
5368 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
5369 
5370  /* Send message */
5371  print_facility(&bc->fac_out, bc);
5373 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES)
5374  } else if (strstr(a->argv[3], "test")) {
5375  int msg_number;
5376 
5377  if (a->argc < 5) {
5378  ast_verbose("test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n");
5379  return 0;
5380  }
5381  port = atoi(a->argv[4]);
5382 
5383  channame = a->argv[4];
5384  tmp = get_chan_by_ast_name(channame);
5385  if (tmp) {
5386  /* We are going to send this FACILITY message out on an existing connection */
5387  msg_number = atoi(a->argv[5]);
5388  if (msg_number < ARRAY_LEN(Fac_Msgs)) {
5389  ao2_lock(tmp);
5390  tmp->bc->fac_out = Fac_Msgs[msg_number];
5391 
5392  /* Send message */
5393  print_facility(&tmp->bc->fac_out, tmp->bc);
5394  ao2_unlock(tmp);
5396  } else {
5397  ast_verbose("test <channel-name> <msg#>\n\n");
5398  }
5399  chan_list_unref(tmp, "Facility test done");
5400  } else if (a->argc < 6) {
5401  for (msg_number = 0; msg_number < ARRAY_LEN(Fac_Msgs); ++msg_number) {
5402  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5403  bc->fac_out = Fac_Msgs[msg_number];
5404 
5405  /* Send message */
5406  print_facility(&bc->fac_out, bc);
5408  sleep(1);
5409  }
5410  } else {
5411  msg_number = atoi(a->argv[5]);
5412  if (msg_number < ARRAY_LEN(Fac_Msgs)) {
5413  misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
5414  bc->fac_out = Fac_Msgs[msg_number];
5415 
5416  /* Send message */
5417  print_facility(&bc->fac_out, bc);
5419  } else {
5420  ast_verbose("test <port> [<msg#>]\n\n");
5421  }
5422  }
5423  } else if (strstr(a->argv[3], "register")) {
5424  if (a->argc < 5) {
5425  ast_verbose("register <port>\n\n");
5426  return 0;
5427  }
5428  port = atoi(a->argv[4]);
5429 
5430  bc = misdn_lib_get_register_bc(port);
5431  if (!bc) {
5432  ast_verbose("Could not allocate REGISTER bc struct\n\n");
5433  return 0;
5434  }
5435  bc->fac_out = Fac_Msgs[45];
5436 
5437  /* Send message */
5438  print_facility(&bc->fac_out, bc);
5440 #endif /* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */
5441  }
5442 
5443  return CLI_SUCCESS;
5444 }
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
const int argc
Definition: cli.h:154
static void dummy(char *unused,...)
Definition: chan_unistim.c:188
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
Definition: isdn_lib.c:77
B channel control structure.
Definition: isdn_lib.h:324
Definition: cli.h:146
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:758
#define ao2_unlock(a)
Definition: astobj2.h:497
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2734
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5623
#define ao2_lock(a)
Definition: astobj2.h:488
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
Channel call record structure.
Definition: chan_misdn.c:349
int misdn_lib_port_is_nt(int port)
Definition: isdn_lib.c:65
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
static char* handle_cli_misdn_send_restart ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5446 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, misdn_bchannel::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, misdn_lib_send_restart(), misdn_bchannel::port, and ast_cli_entry::usage.

5447 {
5448  int port;
5449  int channel;
5450 
5451  switch (cmd) {
5452  case CLI_INIT:
5453  e->command = "misdn send restart";
5454  e->usage =
5455  "Usage: misdn send restart [port [channel]]\n"
5456  " Send a restart for every bchannel on the given port.\n";
5457  return NULL;
5458  case CLI_GENERATE:
5459  return NULL;
5460  }
5461 
5462  if (a->argc < 4 || a->argc > 5) {
5463  return CLI_SHOWUSAGE;
5464  }
5465 
5466  port = atoi(a->argv[3]);
5467 
5468  if (a->argc == 5) {
5469  channel = atoi(a->argv[4]);
5470  misdn_lib_send_restart(port, channel);
5471  } else {
5472  misdn_lib_send_restart(port, -1);
5473  }
5474 
5475  return CLI_SUCCESS;
5476 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
int misdn_lib_send_restart(int port, int channel)
Definition: isdn_lib.c:3943
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
char * command
Definition: cli.h:180
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_set_crypt_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3776 of file chan_misdn.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.

3777 {
3778  switch (cmd) {
3779  case CLI_INIT:
3780  e->command = "misdn set crypt debug";
3781  e->usage =
3782  "Usage: misdn set crypt debug <level>\n"
3783  " Set the crypt debug level of the mISDN channel. Level\n"
3784  " must be 1 or 2.\n";
3785  return NULL;
3786  case CLI_GENERATE:
3787  return NULL;
3788  }
3789 
3790  if (a->argc != 5) {
3791  return CLI_SHOWUSAGE;
3792  }
3793 
3794  /* XXX Is this supposed to not do anything? XXX */
3795 
3796  return CLI_SUCCESS;
3797 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3689 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_debug_port(), ast_cli_args::fd, max_ports, and ast_cli_entry::usage.

3690 {
3691  int level;
3692 
3693  switch (cmd) {
3694  case CLI_INIT:
3695  e->command = "misdn set debug [on|off]";
3696  e->usage =
3697  "Usage: misdn set debug {on|off|<level>} [only] | [port <port> [only]]\n"
3698  " Set the debug level of the mISDN channel.\n";
3699  return NULL;
3700  case CLI_GENERATE:
3701  return complete_debug_port(a);
3702  }
3703 
3704  if (a->argc < 4 || a->argc > 7) {
3705  return CLI_SHOWUSAGE;
3706  }
3707 
3708  if (!strcasecmp(a->argv[3], "on")) {
3709  level = 1;
3710  } else if (!strcasecmp(a->argv[3], "off")) {
3711  level = 0;
3712  } else if (isdigit(a->argv[3][0])) {
3713  level = atoi(a->argv[3]);
3714  } else {
3715  return CLI_SHOWUSAGE;
3716  }
3717 
3718  switch (a->argc) {
3719  case 4:
3720  case 5:
3721  {
3722  int i;
3723  int only = 0;
3724  if (a->argc == 5) {
3725  if (strncasecmp(a->argv[4], "only", strlen(a->argv[4]))) {
3726  return CLI_SHOWUSAGE;
3727  } else {
3728  only = 1;
3729  }
3730  }
3731 
3732  for (i = 0; i <= max_ports; i++) {
3733  misdn_debug[i] = level;
3734  misdn_debug_only[i] = only;
3735  }
3736  ast_cli(a->fd, "changing debug level for all ports to %d%s\n", misdn_debug[0], only ? " (only)" : "");
3737  }
3738  break;
3739  case 6:
3740  case 7:
3741  {
3742  int port;
3743  if (strncasecmp(a->argv[4], "port", strlen(a->argv[4])))
3744  return CLI_SHOWUSAGE;
3745  port = atoi(a->argv[5]);
3746  if (port <= 0 || port > max_ports) {
3747  switch (max_ports) {
3748  case 0:
3749  ast_cli(a->fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
3750  break;
3751  case 1:
3752  ast_cli(a->fd, "port number not valid! only port 1 is available.\n");
3753  break;
3754  default:
3755  ast_cli(a->fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
3756  }
3757  return 0;
3758  }
3759  if (a->argc == 7) {
3760  if (strncasecmp(a->argv[6], "only", strlen(a->argv[6]))) {
3761  return CLI_SHOWUSAGE;
3762  } else {
3763  misdn_debug_only[port] = 1;
3764  }
3765  } else {
3766  misdn_debug_only[port] = 0;
3767  }
3768  misdn_debug[port] = level;
3769  ast_cli(a->fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port] ? " (only)" : "", port);
3770  }
3771  }
3772 
3773  return CLI_SUCCESS;
3774 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static int * misdn_debug_only
Definition: chan_misdn.c:669
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
static int max_ports
Definition: chan_misdn.c:670
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int * misdn_debug
Definition: chan_misdn.c:668
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char * complete_debug_port(struct ast_cli_args *a)
Definition: chan_misdn.c:5628
static char* handle_cli_misdn_set_tics ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4308 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.

4309 {
4310  switch (cmd) {
4311  case CLI_INIT:
4312  e->command = "misdn set tics";
4313  e->usage =
4314  "Usage: misdn set tics <value>\n";
4315  return NULL;
4316  case CLI_GENERATE:
4317  return NULL;
4318  }
4319 
4320  if (a->argc != 4) {
4321  return CLI_SHOWUSAGE;
4322  }
4323 
4324  /* XXX Wow, this does... a whole lot of nothing... XXX */
4325  MAXTICS = atoi(a->argv[3]);
4326 
4327  return CLI_SUCCESS;
4328 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
int MAXTICS
Definition: chan_misdn.c:584
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_show_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4272 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_mutex_lock, ast_mutex_unlock, chan_list::bc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, ast_channel::name, chan_list::next, print_bc_info(), and ast_cli_entry::usage.

4273 {
4274  struct chan_list *help;
4275 
4276  switch (cmd) {
4277  case CLI_INIT:
4278  e->command = "misdn show channel";
4279  e->usage =
4280  "Usage: misdn show channel <channel>\n"
4281  " Show an internal mISDN channel\n.";
4282  return NULL;
4283  case CLI_GENERATE:
4284  return complete_ch(a);
4285  }
4286 
4287  if (a->argc != 4) {
4288  return CLI_SHOWUSAGE;
4289  }
4290 
4292  for (help = cl_te; help; help = help->next) {
4293  struct misdn_bchannel *bc = help->bc;
4294  struct ast_channel *ast = help->ast;
4295 
4296  if (bc && ast) {
4297  if (!strcasecmp(ast->name, a->argv[3])) {
4298  print_bc_info(a->fd, help, bc);
4299  break;
4300  }
4301  }
4302  }
4304 
4305  return CLI_SUCCESS;
4306 }
Main Channel structure associated with a channel.
Definition: channel.h:742
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
const int argc
Definition: cli.h:154
B channel control structure.
Definition: isdn_lib.h:324
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5623
const int fd
Definition: cli.h:153
static void print_bc_info(int fd, struct chan_list *help, struct misdn_bchannel *bc)
Definition: chan_misdn.c:4136
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
const ast_string_field name
Definition: channel.h:787
char * command
Definition: cli.h:180
Channel call record structure.
Definition: chan_misdn.c:349
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_cli_misdn_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4199 of file chan_misdn.c.

References ast_cli_args::argc, chan_list::ast, ast_cli(), ast_mutex_lock, ast_mutex_unlock, chan_list::bc, ast_channel::caller, hold_info::channel, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::exten, ast_cli_args::fd, chan_list::hold, ast_party_caller::id, chan_list::l3id, misdn_dump_chanlist(), MISDN_HOLD_IDLE, ast_party_id::name, chan_list::next, ast_party_id::number, misdn_bchannel::pid, hold_info::port, print_bc_info(), S_COR, hold_info::state, ast_party_name::str, ast_party_number::str, ast_cli_entry::usage, ast_party_name::valid, and ast_party_number::valid.

4200 {
4201  struct chan_list *help;
4202 
4203  switch (cmd) {
4204  case CLI_INIT:
4205  e->command = "misdn show channels";
4206  e->usage =
4207  "Usage: misdn show channels\n"
4208  " Show the internal mISDN channel list\n";
4209  return NULL;
4210  case CLI_GENERATE:
4211  return NULL;
4212  }
4213 
4214  if (a->argc != 3) {
4215  return CLI_SHOWUSAGE;
4216  }
4217 
4218  ast_cli(a->fd, "Channel List: %p\n", cl_te);
4219 
4220  /*
4221  * Walking the list and dumping the channel information could
4222  * take awhile. With the list locked for the duration, the
4223  * channel driver cannot process signaling messages. However,
4224  * since this is a CLI command it should not be run very often.
4225  */
4227  for (help = cl_te; help; help = help->next) {
4228  struct misdn_bchannel *bc = help->bc;
4229  struct ast_channel *ast = help->ast;
4230  if (!ast) {
4231  if (!bc) {
4232  ast_cli(a->fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id);
4233  continue;
4234  }
4235  ast_cli(a->fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
4236  }
4237 
4238  if (misdn_debug[0] > 2) {
4239  ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast);
4240  }
4241  if (bc) {
4242  print_bc_info(a->fd, help, bc);
4243  } else {
4244  if (help->hold.state != MISDN_HOLD_IDLE) {
4245  ast_cli(a->fd, "ITS A HELD CALL BC:\n");
4246  ast_cli(a->fd, " --> l3_id: %x\n"
4247  " --> dialed:%s\n"
4248  " --> caller:\"%s\" <%s>\n"
4249  " --> hold_port: %d\n"
4250  " --> hold_channel: %d\n",
4251  help->l3id,
4252  ast->exten,
4253  S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""),
4254  S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
4255  help->hold.port,
4256  help->hold.channel
4257  );
4258  } else {
4259  ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n",
4260  ast->exten,
4261  S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""));
4262  }
4263  }
4264  }
4266 
4268 
4269  return CLI_SUCCESS;
4270 }
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
void misdn_dump_chanlist(void)
Definition: isdn_lib.c:483
const int argc
Definition: cli.h:154
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
B channel control structure.
Definition: isdn_lib.h:324
Definition: cli.h:146
char * str
Subscriber name (Malloced)
Definition: channel.h:214
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
const int fd
Definition: cli.h:153
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:334
static void print_bc_info(int fd, struct chan_list *help, struct misdn_bchannel *bc)
Definition: chan_misdn.c:4136
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int * misdn_debug
Definition: chan_misdn.c:668
char * command
Definition: cli.h:180
Channel call record structure.
Definition: chan_misdn.c:349
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:513
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
int channel
Original B channel number the HELD call was using.
Definition: chan_misdn.c:340
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static char* handle_cli_misdn_show_config ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3956 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), BUFFERSIZE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_show_config(), ast_cli_args::fd, MISDN_CFG_FIRST, misdn_cfg_get_config_string(), misdn_cfg_get_elem(), misdn_cfg_get_next_port(), misdn_cfg_is_port_valid(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, show_config_description(), and ast_cli_entry::usage.

3957 {
3958  char buffer[BUFFERSIZE];
3959  enum misdn_cfg_elements elem;
3960  int linebreak;
3961  int onlyport = -1;
3962  int ok = 0;
3963 
3964  switch (cmd) {
3965  case CLI_INIT:
3966  e->command = "misdn show config";
3967  e->usage =
3968  "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
3969  " Use 0 for <port> to only print the general config.\n";
3970  return NULL;
3971  case CLI_GENERATE:
3972  return complete_show_config(a);
3973  }
3974 
3975  if (a->argc >= 4) {
3976  if (!strcmp(a->argv[3], "description")) {
3977  if (a->argc == 5) {
3978  enum misdn_cfg_elements elem = misdn_cfg_get_elem(a->argv[4]);
3979  if (elem == MISDN_CFG_FIRST) {
3980  ast_cli(a->fd, "Unknown element: %s\n", a->argv[4]);
3981  } else {
3982  show_config_description(a->fd, elem);
3983  }
3984  return CLI_SUCCESS;
3985  }
3986  return CLI_SHOWUSAGE;
3987  } else if (!strcmp(a->argv[3], "descriptions")) {
3988  if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "general"))) {
3989  for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
3990  show_config_description(a->fd, elem);
3991  ast_cli(a->fd, "\n");
3992  }
3993  ok = 1;
3994  }
3995  if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "ports"))) {
3996  for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
3997  show_config_description(a->fd, elem);
3998  ast_cli(a->fd, "\n");
3999  }
4000  ok = 1;
4001  }
4002  return ok ? CLI_SUCCESS : CLI_SHOWUSAGE;
4003  } else if (!sscanf(a->argv[3], "%5d", &onlyport) || onlyport < 0) {
4004  ast_cli(a->fd, "Unknown option: %s\n", a->argv[3]);
4005  return CLI_SHOWUSAGE;
4006  }
4007  }
4008 
4009  if (a->argc == 3 || onlyport == 0) {
4010  ast_cli(a->fd, "mISDN General-Config:\n");
4011  for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
4012  misdn_cfg_get_config_string(0, elem, buffer, sizeof(buffer));
4013  ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
4014  }
4015  ast_cli(a->fd, "\n");
4016  }
4017 
4018  if (onlyport < 0) {
4019  int port = misdn_cfg_get_next_port(0);
4020 
4021  for (; port > 0; port = misdn_cfg_get_next_port(port)) {
4022  ast_cli(a->fd, "\n[PORT %d]\n", port);
4023  for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
4024  misdn_cfg_get_config_string(port, elem, buffer, sizeof(buffer));
4025  ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
4026  }
4027  ast_cli(a->fd, "\n");
4028  }
4029  }
4030 
4031  if (onlyport > 0) {
4032  if (misdn_cfg_is_port_valid(onlyport)) {
4033  ast_cli(a->fd, "[PORT %d]\n", onlyport);
4034  for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
4035  misdn_cfg_get_config_string(onlyport, elem, buffer, sizeof(buffer));
4036  ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
4037  }
4038  ast_cli(a->fd, "\n");
4039  } else {
4040  ast_cli(a->fd, "Port %d is not active!\n", onlyport);
4041  }
4042  }
4043 
4044  return CLI_SUCCESS;
4045 }
enum misdn_cfg_elements misdn_cfg_get_elem(const char *name)
Definition: misdn_config.c:616
const int argc
Definition: cli.h:154
misdn_cfg_elements
Definition: cli.h:146
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define BUFFERSIZE
static void show_config_description(int fd, enum misdn_cfg_elements elem)
Definition: chan_misdn.c:3931
const int fd
Definition: cli.h:153
static char * complete_show_config(struct ast_cli_args *a)
Definition: chan_misdn.c:5651
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
void misdn_cfg_get_config_string(int port, enum misdn_cfg_elements elem, char *buf, int bufsize)
Definition: misdn_config.c:787
int misdn_cfg_is_port_valid(int port)
Definition: misdn_config.c:719
static char* handle_cli_misdn_show_port ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4390 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_show_stack_details(), and ast_cli_entry::usage.

4391 {
4392  int port;
4393  char buf[128];
4394 
4395  switch (cmd) {
4396  case CLI_INIT:
4397  e->command = "misdn show port";
4398  e->usage =
4399  "Usage: misdn show port <port>\n"
4400  " Show detailed information for given port.\n";
4401  return NULL;
4402  case CLI_GENERATE:
4403  return NULL;
4404  }
4405 
4406  if (a->argc != 4) {
4407  return CLI_SHOWUSAGE;
4408  }
4409 
4410  port = atoi(a->argv[3]);
4411 
4412  ast_cli(a->fd, "BEGIN STACK_LIST:\n");
4413  get_show_stack_details(port, buf);
4414  ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
4415 
4416  return CLI_SUCCESS;
4417 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static int * misdn_debug_only
Definition: chan_misdn.c:669
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
void get_show_stack_details(int port, char *buf)
Definition: isdn_lib.c:168
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int * misdn_debug
Definition: chan_misdn.c:668
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_show_ports_stats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4361 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, misdn_cfg_get_next_port(), and ast_cli_entry::usage.

4362 {
4363  int port;
4364 
4365  switch (cmd) {
4366  case CLI_INIT:
4367  e->command = "misdn show ports stats";
4368  e->usage =
4369  "Usage: misdn show ports stats\n"
4370  " Show mISDNs channel's call statistics per port.\n";
4371  return NULL;
4372  case CLI_GENERATE:
4373  return NULL;
4374  }
4375 
4376  if (a->argc != 4) {
4377  return CLI_SHOWUSAGE;
4378  }
4379 
4380  ast_cli(a->fd, "Port\tin_calls\tout_calls\n");
4381  for (port = misdn_cfg_get_next_port(0); port > 0;
4382  port = misdn_cfg_get_next_port(port)) {
4383  ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
4384  }
4385  ast_cli(a->fd, "\n");
4386 
4387  return CLI_SUCCESS;
4388 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
static int * misdn_out_calls
Definition: chan_misdn.c:673
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int * misdn_in_calls
Definition: chan_misdn.c:672
static char* handle_cli_misdn_show_stacks ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4330 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_show_stack_details(), misdn_cfg_get_next_port(), and ast_cli_entry::usage.

4331 {
4332  int port;
4333 
4334  switch (cmd) {
4335  case CLI_INIT:
4336  e->command = "misdn show stacks";
4337  e->usage =
4338  "Usage: misdn show stacks\n"
4339  " Show internal mISDN stack_list.\n";
4340  return NULL;
4341  case CLI_GENERATE:
4342  return NULL;
4343  }
4344 
4345  if (a->argc != 3) {
4346  return CLI_SHOWUSAGE;
4347  }
4348 
4349  ast_cli(a->fd, "BEGIN STACK_LIST:\n");
4350  for (port = misdn_cfg_get_next_port(0); port > 0;
4351  port = misdn_cfg_get_next_port(port)) {
4352  char buf[128];
4353 
4354  get_show_stack_details(port, buf);
4355  ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
4356  }
4357 
4358  return CLI_SUCCESS;
4359 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
static int * misdn_debug_only
Definition: chan_misdn.c:669
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
void get_show_stack_details(int port, char *buf)
Definition: isdn_lib.c:168
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int * misdn_debug
Definition: chan_misdn.c:668
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_misdn_toggle_echocancel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5533 of file chan_misdn.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), chan_list::bc, chan_list_unref, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, get_chan_by_ast_name(), manager_ec_disable(), manager_ec_enable(), chan_list::toggle_ec, update_ec_config(), and ast_cli_entry::usage.

5534 {
5535  const char *channame;
5536  struct chan_list *tmp;
5537 
5538  switch (cmd) {
5539  case CLI_INIT:
5540  e->command = "misdn toggle echocancel";
5541  e->usage =
5542  "Usage: misdn toggle echocancel <channel>\n"
5543  " Toggle EchoCancel on mISDN Channel.\n";
5544  return NULL;
5545  case CLI_GENERATE:
5546  return complete_ch(a);
5547  }
5548 
5549  if (a->argc != 4) {
5550  return CLI_SHOWUSAGE;
5551  }
5552 
5553  channame = a->argv[3];
5554 
5555  ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame);
5556 
5557  tmp = get_chan_by_ast_name(channame);
5558  if (!tmp) {
5559  ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
5560  return CLI_SUCCESS;
5561  }
5562 
5563  tmp->toggle_ec = tmp->toggle_ec ? 0 : 1;
5564 
5565  if (tmp->toggle_ec) {
5566 #ifdef MISDN_1_2
5567  update_pipeline_config(tmp->bc);
5568 #else
5569  update_ec_config(tmp->bc);
5570 #endif
5571  manager_ec_enable(tmp->bc);
5572  } else {
5573  manager_ec_disable(tmp->bc);
5574  }
5575  chan_list_unref(tmp, "Done toggling echo cancel");
5576 
5577  return CLI_SUCCESS;
5578 }
void manager_ec_enable(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4628
const int argc
Definition: cli.h:154
Definition: cli.h:146
static struct chan_list * get_chan_by_ast_name(const char *name)
Definition: chan_misdn.c:758
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
void manager_ec_disable(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4677
static char * complete_ch(struct ast_cli_args *a)
Definition: chan_misdn.c:5623
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
Channel call record structure.
Definition: chan_misdn.c:349
static int update_ec_config(struct misdn_bchannel *bc)
Definition: chan_misdn.c:5872
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
int toggle_ec
TRUE if echo canceller is enabled. Value is toggled.
Definition: chan_misdn.c:397
static void hangup_chan ( struct chan_list ch,
struct misdn_bchannel bc 
)
static

Definition at line 8374 of file chan_misdn.c.

References chan_list::ast, ast_hangup(), ast_queue_hangup_with_cause(), misdn_bchannel::cause, cb_log, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::port, and send_cause2ast().

Referenced by cb_events(), do_immediate_setup(), local_hangup(), and start_pbx().

8375 {
8376  int port = bc->port;
8377 
8378  if (!ch) {
8379  cb_log(1, port, "Cannot hangup chan, no ch\n");
8380  return;
8381  }
8382 
8383  cb_log(5, port, "hangup_chan called\n");
8384 
8385  if (ch->need_hangup) {
8386  cb_log(2, port, " --> hangup\n");
8387  ch->need_hangup = 0;
8388  ch->need_queue_hangup = 0;
8389  if (ch->ast && send_cause2ast(ch->ast, bc, ch)) {
8390  ast_hangup(ch->ast);
8391  }
8392  return;
8393  }
8394 
8395  if (!ch->need_queue_hangup) {
8396  cb_log(2, port, " --> No need to queue hangup\n");
8397  return;
8398  }
8399 
8400  ch->need_queue_hangup = 0;
8401  if (ch->ast) {
8402  if (send_cause2ast(ch->ast, bc, ch)) {
8404  cb_log(2, port, " --> queue_hangup\n");
8405  }
8406  } else {
8407  cb_log(1, port, "Cannot hangup chan, no ast\n");
8408  }
8409 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:369
int need_queue_hangup
TRUE if a hangup needs to be queued.
Definition: chan_misdn.c:364
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1581
static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
Definition: chan_misdn.c:8683
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
static void hanguptone_indicate ( struct chan_list cl)
static

Definition at line 7655 of file chan_misdn.c.

References chan_list::bc, misdn_lib_send_tone(), and TONE_HANGUP.

Referenced by cb_events(), do_immediate_setup(), misdn_hangup(), misdn_indication(), misdn_overlap_dial_task(), and start_pbx().

7656 {
7658 }
void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone)
Definition: isdn_lib.c:4596
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
void import_ch ( struct ast_channel chan,
struct misdn_bchannel bc,
struct chan_list ch 
)

Import parameters from the dialplan environment variables.

Definition at line 8744 of file chan_misdn.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), misdn_bchannel::keypad, LOG_NOTICE, pbx_builtin_getvar_helper(), misdn_bchannel::sending_complete, misdn_bchannel::uu, and misdn_bchannel::uulen.

Referenced by misdn_call().

8745 {
8746  const char *tmp;
8747 
8748  ast_channel_lock(chan);
8749  tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE");
8750  if (tmp && (atoi(tmp) == 1)) {
8751  bc->sending_complete = 1;
8752  }
8753 
8754  tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER");
8755  if (tmp) {
8756  ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
8757  ast_copy_string(bc->uu, tmp, sizeof(bc->uu));
8758  bc->uulen = strlen(bc->uu);
8759  }
8760 
8761  tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD");
8762  if (tmp) {
8763  ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad));
8764  }
8765  ast_channel_unlock(chan);
8766 }
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
#define ast_channel_lock(chan)
Definition: channel.h:2466
int uulen
User-User information string length in uu[].
Definition: isdn_lib.h:666
char uu[256]
User-User information string.
Definition: isdn_lib.h:663
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int load_module ( void  )
static

Definition at line 11179 of file chan_misdn.c.

References ast_calloc, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_free, ast_log(), ast_malloc, AST_MODULE_LOAD_DECLINE, ast_mutex_init, ast_register_application, ast_strlen_zero(), BUFFERSIZE, misdn_lib_iface::cb_event, cb_events(), chan_misdn_jb_empty(), chan_misdn_log(), LOG_ERROR, max_ports, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), MISDN_CFG_L1_TIMEOUT, misdn_cfg_update_ptp(), misdn_check_l2l1(), misdn_facility_exec(), MISDN_GEN_DEBUG, MISDN_GEN_NTDEBUGFILE, MISDN_GEN_NTDEBUGFLAGS, MISDN_GEN_NTKEEPCALLS, MISDN_GEN_TRACEFILE, misdn_l1_task(), misdn_lib_init(), misdn_lib_maxports_get(), misdn_lib_nt_debug_init(), misdn_lib_nt_keepcalls(), misdn_set_opt_exec(), misdn_tasks_add(), and unload_module().

11180 {
11181  int i, port;
11182  int ntflags = 0, ntkc = 0;
11183  char ports[256] = "";
11184  char tempbuf[BUFFERSIZE + 1];
11185  char ntfile[BUFFERSIZE + 1];
11186  struct misdn_lib_iface iface = {
11187  .cb_event = cb_events,
11188  .cb_log = chan_misdn_log,
11189  .cb_jb_empty = chan_misdn_jb_empty,
11190  };
11191 
11193 
11194  if (max_ports <= 0) {
11195  ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
11196  return AST_MODULE_LOAD_DECLINE;
11197  }
11198 
11199  if (misdn_cfg_init(max_ports, 0)) {
11200  ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
11201  return AST_MODULE_LOAD_DECLINE;
11202  }
11204 
11205 #if defined(AST_MISDN_ENHANCEMENTS)
11206  misdn_cc_init();
11207 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11208 
11209  misdn_debug = ast_malloc(sizeof(int) * (max_ports + 1));
11210  if (!misdn_debug) {
11211  ast_log(LOG_ERROR, "Out of memory for misdn_debug\n");
11212  return AST_MODULE_LOAD_DECLINE;
11213  }
11214  misdn_ports = ast_malloc(sizeof(int) * (max_ports + 1));
11215  if (!misdn_ports) {
11217  ast_log(LOG_ERROR, "Out of memory for misdn_ports\n");
11218  return AST_MODULE_LOAD_DECLINE;
11219  }
11221  for (i = 1; i <= max_ports; i++) {
11222  misdn_debug[i] = misdn_debug[0];
11223  misdn_ports[i] = i;
11224  }
11225  *misdn_ports = 0;
11226  misdn_debug_only = ast_calloc(max_ports + 1, sizeof(int));
11227  if (!misdn_debug_only) {
11230  ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n");
11231  return AST_MODULE_LOAD_DECLINE;
11232  }
11233 
11234  misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, sizeof(tempbuf));
11235  if (!ast_strlen_zero(tempbuf)) {
11236  tracing = 1;
11237  }
11238 
11239  misdn_in_calls = ast_malloc(sizeof(int) * (max_ports + 1));
11240  if (!misdn_in_calls) {
11244  ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n");
11245  return AST_MODULE_LOAD_DECLINE;
11246  }
11247  misdn_out_calls = ast_malloc(sizeof(int) * (max_ports + 1));
11248  if (!misdn_out_calls) {
11253  ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n");
11254  return AST_MODULE_LOAD_DECLINE;
11255  }
11256 
11257  for (i = 1; i <= max_ports; i++) {
11258  misdn_in_calls[i] = 0;
11259  misdn_out_calls[i] = 0;
11260  }
11261 
11264 
11267 
11268  if (!ast_strlen_zero(ports)) {
11269  chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports);
11270  }
11271  if (misdn_lib_init(ports, &iface, NULL)) {
11272  chan_misdn_log(0, 0, "No te ports initialized\n");
11273  }
11274 
11275  misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(ntflags));
11276  misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, sizeof(ntfile));
11277  misdn_cfg_get(0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(ntkc));
11278 
11279  misdn_lib_nt_keepcalls(ntkc);
11280  misdn_lib_nt_debug_init(ntflags, ntfile);
11281 
11283  ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
11284  unload_module();
11285  return AST_MODULE_LOAD_DECLINE;
11286  }
11287 
11289 
11290  ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
11291  "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n"
11292  "Sets mISDN opts. and optargs\n"
11293  "\n"
11294  "The available options are:\n"
11295  " a - Have Asterisk detect DTMF tones on called channel\n"
11296  " c - Make crypted outgoing call, optarg is keyindex\n"
11297  " d - Send display text to called phone, text is the optarg\n"
11298  " e - Perform echo cancellation on this channel,\n"
11299  " takes taps as optarg (32,64,128,256)\n"
11300  " e! - Disable echo cancellation on this channel\n"
11301  " f - Enable fax detection\n"
11302  " h - Make digital outgoing call\n"
11303  " h1 - Make HDLC mode digital outgoing call\n"
11304  " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n"
11305  " they will be transported inband.\n"
11306  " jb - Set jitter buffer length, optarg is length\n"
11307  " jt - Set jitter buffer upper threshold, optarg is threshold\n"
11308  " jn - Disable jitter buffer\n"
11309  " n - Disable mISDN DSP on channel.\n"
11310  " Disables: echo cancel, DTMF detection, and volume control.\n"
11311  " p - Caller ID presentation,\n"
11312  " optarg is either 'allowed' or 'restricted'\n"
11313  " s - Send Non-inband DTMF as inband\n"
11314  " vr - Rx gain control, optarg is gain\n"
11315  " vt - Tx gain control, optarg is gain\n"
11316  );
11317 
11318 
11319  ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
11320  "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
11321  "Sends the Facility Message FACILITY_TYPE with \n"
11322  "the given Arguments to the current ISDN Channel\n"
11323  "Supported Facilities are:\n"
11324  "\n"
11325  "type=calldeflect args=Nr where to deflect\n"
11326 #if defined(AST_MISDN_ENHANCEMENTS)
11327  "type=callrerouting args=Nr where to deflect\n"
11328 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11329  );
11330 
11331 
11332  ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1",
11333  "misdn_check_l2l1(<port>||g:<groupname>,timeout)\n"
11334  "Checks if the L2 and L1 are up on either the given <port> or\n"
11335  "on the ports in the group with <groupname>\n"
11336  "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
11337  "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
11338  "\n"
11339  "This application, ensures the L1/L2 state of the Ports in a group\n"
11340  "it is intended to make the pmp_l1_check option redundant and to\n"
11341  "fix a buggy switch config from your provider\n"
11342  "\n"
11343  "a sample dialplan would look like:\n\n"
11344  "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
11345  "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
11346  );
11347 
11348 #if defined(AST_MISDN_ENHANCEMENTS)
11349  ast_register_application(misdn_command_name, misdn_command_exec, misdn_command_name,
11350  "misdn_command(<command>[,<options>])\n"
11351  "The following commands are defined:\n"
11352  "cc-initialize\n"
11353  " Setup mISDN support for call completion\n"
11354  " Must call before doing any Dial() involving call completion.\n"
11355  "ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11356  " Request Call Completion No Reply activation\n"
11357  "ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11358  " Request Call Completion Busy Subscriber activation\n"
11359  "cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n"
11360  " Set the dialplan location to notify when User-B is available but User-A is busy.\n"
11361  " Setting this dialplan location is optional.\n"
11362  "cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>\n"
11363  " Set the busy status of call completion User-A\n"
11364  "cc-deactivate,${MISDN_CC_RECORD_ID}\n"
11365  " Deactivate the identified call completion request\n"
11366  "\n"
11367  "MISDN_CC_RECORD_ID is set when Dial() returns and call completion is possible\n"
11368  "MISDN_CC_STATUS is set to ACTIVATED or ERROR after the call completion\n"
11369  "activation request.\n"
11370  "MISDN_ERROR_MSG is set to a descriptive message on error.\n"
11371  );
11372 
11373  ast_custom_function_register(&misdn_cc_function);
11374 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11375 
11377 
11378  /* start the l1 watchers */
11379 
11380  for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) {
11381  int l1timeout;
11382  misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout));
11383  if (l1timeout) {
11384  chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
11385  misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]);
11386  }
11387  }
11388 
11389  chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n");
11390 
11391  return 0;
11392 }
int misdn_lib_maxports_get(void)
Definition: isdn_lib.c:4094
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_data)
Definition: isdn_lib.c:4143
void misdn_lib_nt_debug_init(int flags, char *file)
Definition: isdn_lib.c:4124
int misdn_cfg_init(int this_max_ports, int reload)
descriptor for a cli entry.
Definition: cli.h:165
static int misdn_tasks_add(int timeout, ast_sched_cb callback, const void *data)
Definition: chan_misdn.c:3573
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:907
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
static int * misdn_debug_only
Definition: chan_misdn.c:669
int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len)
Definition: chan_misdn.c:12432
#define BUFFERSIZE
static int misdn_l1_task(const void *vdata)
Definition: chan_misdn.c:3588
static ast_mutex_t release_lock
Definition: chan_misdn.c:295
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_cli_entry chan_misdn_clis[]
Definition: chan_misdn.c:5703
#define ast_register_application(app, execute, synopsis, description)
Register an application.
Definition: module.h:421
static int max_ports
Definition: chan_misdn.c:670
static char global_tracefile[BUFFERSIZE+1]
Definition: chan_misdn.c:99
void misdn_lib_nt_keepcalls(int kc)
Definition: isdn_lib.c:4112
#define LOG_ERROR
Definition: logger.h:155
static int misdn_check_l2l1(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12149
static int tracing
Definition: chan_misdn.c:663
static int * misdn_debug
Definition: chan_misdn.c:668
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char misdn_type[]
Definition: chan_misdn.c:661
static struct ast_channel_tech misdn_tech
Definition: chan_misdn.c:8047
static int unload_module(void)
Definition: chan_misdn.c:11138
#define ast_free(a)
Definition: astmm.h:97
static int * misdn_ports
Definition: chan_misdn.c:645
void misdn_cfg_update_ptp(void)
static int * misdn_out_calls
Definition: chan_misdn.c:673
enum event_response_e(* cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data)
Definition: isdn_lib.h:729
static int g_config_initialized
Definition: chan_misdn.c:101
void misdn_cfg_get_ports_string(char *ports)
Generate a comma separated list of all active ports.
Definition: misdn_config.c:761
#define ast_calloc(a, b)
Definition: astmm.h:82
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static int * misdn_in_calls
Definition: chan_misdn.c:672
#define ast_mutex_init(pmutex)
Definition: lock.h:152
static int misdn_facility_exec(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12026
#define ast_malloc(a)
Definition: astmm.h:91
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12223
static enum event_response_e cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
Definition: chan_misdn.c:9859
static void misdn_add_number_prefix ( int  port,
enum mISDN_NUMBER_TYPE  number_type,
char *  number,
size_t  size 
)
static

Definition at line 3396 of file chan_misdn.c.

References misdn_cfg_get(), MISDN_CFG_TON_PREFIX_ABBREVIATED, MISDN_CFG_TON_PREFIX_INTERNATIONAL, MISDN_CFG_TON_PREFIX_NATIONAL, MISDN_CFG_TON_PREFIX_NETWORK_SPECIFIC, MISDN_CFG_TON_PREFIX_SUBSCRIBER, MISDN_CFG_TON_PREFIX_UNKNOWN, MISDN_MAX_NUMBER_LEN, misdn_prefix_string(), NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.

Referenced by cb_events(), misdn_facility_ie_handler(), misdn_is_msn_valid(), and read_config().

3397 {
3398  enum misdn_cfg_elements type_prefix;
3399  char num_prefix[MISDN_MAX_NUMBER_LEN];
3400 
3401  /* Get prefix string. */
3402  switch (number_type) {
3403  case NUMTYPE_UNKNOWN:
3404  type_prefix = MISDN_CFG_TON_PREFIX_UNKNOWN;
3405  break;
3406  case NUMTYPE_INTERNATIONAL:
3407  type_prefix = MISDN_CFG_TON_PREFIX_INTERNATIONAL;
3408  break;
3409  case NUMTYPE_NATIONAL:
3410  type_prefix = MISDN_CFG_TON_PREFIX_NATIONAL;
3411  break;
3414  break;
3415  case NUMTYPE_SUBSCRIBER:
3416  type_prefix = MISDN_CFG_TON_PREFIX_SUBSCRIBER;
3417  break;
3418  case NUMTYPE_ABBREVIATED:
3419  type_prefix = MISDN_CFG_TON_PREFIX_ABBREVIATED;
3420  break;
3421  default:
3422  /* Type-of-number does not have a prefix that can be added. */
3423  return;
3424  }
3425  misdn_cfg_get(port, type_prefix, num_prefix, sizeof(num_prefix));
3426 
3427  misdn_prefix_string(num_prefix, number, size);
3428 }
misdn_cfg_elements
Number structure.
Definition: app_followme.c:109
#define MISDN_MAX_NUMBER_LEN
Definition: isdn_lib.h:246
static void misdn_prefix_string(const char *str_prefix, char *str_main, size_t size)
Definition: chan_misdn.c:3353
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
static int misdn_answer ( struct ast_channel ast)
static

Definition at line 6753 of file chan_misdn.c.

References AST_CAUSE_NETWORK_OUT_OF_ORDER, AST_CAUSE_PROTOCOL_ERROR, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_queue_hangup_with_cause(), ast_strlen_zero(), ast_true(), chan_list::bc, chan_misdn_log(), misdn_bchannel::connected, misdn_bchannel::crypt_key, misdn_bchannel::dialed, EVENT_CONNECT, misdn_bchannel::fac_out, misdn_bchannel::hdlc, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_lib_send_event(), misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_party_dialing::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_dialing::number_plan, misdn_party_id::number_type, misdn_party_dialing::number_type, misdn_bchannel::outgoing_colp, pbx_builtin_getvar_helper(), misdn_bchannel::port, misdn_party_id::presentation, misdn_bchannel::presentation, print_facility(), misdn_party_id::screening, start_bc_tones(), chan_list::state, and stop_indicate().

6754 {
6755  struct chan_list *p;
6756  const char *tmp;
6757 
6758  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6759  return -1;
6760  }
6761 
6762  chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n");
6763 
6764  if (!p) {
6765  ast_log(LOG_WARNING, " --> Channel not connected ??\n");
6767  }
6768 
6769  if (!p->bc) {
6770  chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n");
6771 
6773  }
6774 
6775  ast_channel_lock(ast);
6776  tmp = pbx_builtin_getvar_helper(ast, "CRYPT_KEY");
6777  if (!ast_strlen_zero(tmp)) {
6778  chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
6779  ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key));
6780  } else {
6781  chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
6782  }
6783 
6784  tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
6785  if (!ast_strlen_zero(tmp) && ast_true(tmp)) {
6786  chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
6787  p->bc->nodsp = 1;
6788  p->bc->hdlc = 0;
6789  p->bc->nojitter = 1;
6790  }
6791  ast_channel_unlock(ast);
6792 
6793  p->state = MISDN_CONNECTED;
6794  stop_indicate(p);
6795 
6796  if (ast_strlen_zero(p->bc->connected.number)) {
6797  chan_misdn_log(2,p->bc->port," --> empty connected number using dialed number\n");
6799 
6800  /*
6801  * Use the misdn_set_opt() application to set the presentation
6802  * before we answer or you can use the CONECTEDLINE() function
6803  * to set everything before using the Answer() application.
6804  */
6806  p->bc->connected.screening = 0; /* unscreened */
6809  }
6810 
6811  switch (p->bc->outgoing_colp) {
6812  case 1:/* restricted */
6813  case 2:/* blocked */
6814  p->bc->connected.presentation = 1;/* restricted */
6815  break;
6816  default:
6817  break;
6818  }
6819 
6820 #if defined(AST_MISDN_ENHANCEMENTS)
6821  if (p->bc->div_leg_3_tx_pending) {
6822  p->bc->div_leg_3_tx_pending = 0;
6823 
6824  /* Send DivertingLegInformation3 */
6825  p->bc->fac_out.Function = Fac_DivertingLegInformation3;
6826  p->bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6827  p->bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6828  (p->bc->connected.presentation == 0) ? 1 : 0;
6829  print_facility(&p->bc->fac_out, p->bc);
6830  }
6831 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6833  start_bc_tones(p);
6834 
6835  return 0;
6836 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
#define AST_CAUSE_PROTOCOL_ERROR
Definition: causes.h:144
#define ast_channel_lock(chan)
Definition: channel.h:2466
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7660
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int nodsp
TRUE if we will not use jollys dsp.
Definition: isdn_lib.h:474
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:600
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
Definition: causes.h:120
#define LOG_WARNING
Definition: logger.h:144
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
char crypt_key[255]
Blowfish encryption key string (secret)
Definition: isdn_lib.h:529
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1581
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2734
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
#define ast_channel_unlock(chan)
Definition: channel.h:2467
Channel call record structure.
Definition: chan_misdn.c:349
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7681
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:263
static int misdn_attempt_transfer ( struct chan_list active_ch,
struct chan_list held_ch 
)
static

Definition at line 8546 of file chan_misdn.c.

References ao2_ref, chan_list::ast, ast_bridged_channel(), ast_channel_lock, ast_channel_transfer_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), chan_misdn_log(), CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::connected, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_TRANSFER, MISDN_PROCEEDING, MISDN_PROGRESS, ast_channel::name, hold_info::port, hold_info::state, and chan_list::state.

Referenced by cb_events().

8547 {
8548  int retval;
8549  struct ast_channel *target;
8550  struct ast_channel *transferee;
8551  struct ast_party_connected_line target_colp;
8552  struct ast_party_connected_line transferee_colp;
8553 
8554  switch (active_ch->state) {
8555  case MISDN_PROCEEDING:
8556  case MISDN_PROGRESS:
8557  case MISDN_ALERTING:
8558  case MISDN_CONNECTED:
8559  break;
8560  default:
8561  return -1;
8562  }
8563 
8564  ast_channel_lock(held_ch->ast);
8565  while (ast_channel_trylock(active_ch->ast)) {
8566  CHANNEL_DEADLOCK_AVOIDANCE(held_ch->ast);
8567  }
8568 
8569  transferee = ast_bridged_channel(held_ch->ast);
8570  if (!transferee) {
8571  /*
8572  * Could not transfer. Held channel is not bridged anymore.
8573  * Held party probably got tired of waiting and hung up.
8574  */
8575  ast_channel_unlock(held_ch->ast);
8576  ast_channel_unlock(active_ch->ast);
8577  return -1;
8578  }
8579 
8580  target = active_ch->ast;
8581  chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n",
8582  held_ch->ast->name, target->name);
8583 
8584  ast_party_connected_line_init(&target_colp);
8585  ast_party_connected_line_copy(&target_colp, &target->connected);
8586  ast_party_connected_line_init(&transferee_colp);
8587  ast_party_connected_line_copy(&transferee_colp, &held_ch->ast->connected);
8588  held_ch->hold.state = MISDN_HOLD_TRANSFER;
8589 
8590  /*
8591  * Before starting a masquerade, all channel and pvt locks must
8592  * be unlocked. Any recursive channel locks held before
8593  * ast_channel_transfer_masquerade() invalidates deadlock
8594  * avoidance. Since we are unlocking both the pvt and its owner
8595  * channel it is possible for "target" and "transferee" to be
8596  * destroyed by their pbx threads. To prevent this we must give
8597  * "target" and "transferee" a reference before any unlocking
8598  * takes place.
8599  */
8600  ao2_ref(target, +1);
8601  ao2_ref(transferee, +1);
8602  ast_channel_unlock(held_ch->ast);
8603  ast_channel_unlock(active_ch->ast);
8604 
8605  /* Setup transfer masquerade. */
8606  retval = ast_channel_transfer_masquerade(target, &target_colp, 0,
8607  transferee, &transferee_colp, 1);
8608 
8609  ast_party_connected_line_free(&target_colp);
8610  ast_party_connected_line_free(&transferee_colp);
8611  ao2_ref(target, -1);
8612  ao2_ref(transferee, -1);
8613  return retval;
8614 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2308
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2353
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
#define ao2_ref(o, delta)
Definition: astobj2.h:472
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:334
int ast_channel_transfer_masquerade(struct ast_channel *target_chan, const struct ast_party_connected_line *target_id, int target_held, struct ast_channel *transferee_chan, const struct ast_party_connected_line *transferee_id, int transferee_held)
Setup a masquerade to transfer a call.
Definition: channel.c:6184
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
Connected Line/Party information.
Definition: channel.h:401
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:480
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
Definition: channel.c:2316
#define ast_channel_trylock(chan)
Definition: channel.h:2468
static enum ast_bridge_result misdn_bridge ( struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
int  timeoutms 
)
static

Definition at line 7511 of file chan_misdn.c.

References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_log(), ast_read(), ast_verb, ast_waitfor_n(), ast_write(), chan_list::bc, misdn_bchannel::caller, chan_list_unref, chan_misdn_log(), ast_channel::exten, f, ast_frame::frametype, get_chan_by_ast(), chan_list::ignore_dtmf, ast_frame_subclass::integer, LOG_NOTICE, MISDN_CFG_BRIDGING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_bridge(), misdn_lib_split_bridge(), misdn_party_id::name, ast_channel::name, misdn_party_id::number, misdn_bchannel::pid, misdn_bchannel::port, and ast_frame::subclass.

7516 {
7517  struct chan_list *ch1, *ch2;
7518  struct ast_channel *carr[2], *who;
7519  int to = -1;
7520  struct ast_frame *f;
7521  int p1_b, p2_b;
7522  int bridging;
7523 
7524  ch1 = get_chan_by_ast(c0);
7525  if (!ch1) {
7526  return -1;
7527  }
7528  ch2 = get_chan_by_ast(c1);
7529  if (!ch2) {
7530  chan_list_unref(ch1, "Failed to find ch2");
7531  return -1;
7532  }
7533 
7534  carr[0] = c0;
7535  carr[1] = c1;
7536 
7537  misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(p1_b));
7538  misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(p2_b));
7539 
7540  if (! p1_b || ! p2_b) {
7541  ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
7542  chan_list_unref(ch1, "Bridge fallback ch1");
7543  chan_list_unref(ch2, "Bridge fallback ch2");
7544  return AST_BRIDGE_FAILED;
7545  }
7546 
7547  misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
7548  if (bridging) {
7549  /* trying to make a mISDN_dsp conference */
7550  chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1);
7551  misdn_lib_bridge(ch1->bc, ch2->bc);
7552  }
7553 
7554  ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name);
7555 
7556  chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between \"%s\" <%s> and \"%s\" <%s>\n",
7557  ch1->bc->caller.name,
7558  ch1->bc->caller.number,
7559  ch2->bc->caller.name,
7560  ch2->bc->caller.number);
7561 
7562  if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
7563  ch1->ignore_dtmf = 1;
7564  }
7565 
7566  if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1)) {
7567  ch2->ignore_dtmf = 1;
7568  }
7569 
7570  for (;/*ever*/;) {
7571  to = -1;
7572  who = ast_waitfor_n(carr, 2, &to);
7573 
7574  if (!who) {
7575  ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n");
7576  break;
7577  }
7578  f = ast_read(who);
7579 
7580  if (!f || f->frametype == AST_FRAME_CONTROL) {
7581  /* got hangup .. */
7582 
7583  if (!f) {
7584  chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n");
7585  } else {
7586  chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass.integer);
7587  }
7588 
7589  *fo = f;
7590  *rc = who;
7591  break;
7592  }
7593 
7594  if (f->frametype == AST_FRAME_DTMF) {
7595  chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass.integer, who->exten);
7596 
7597  *fo = f;
7598  *rc = who;
7599  break;
7600  }
7601 
7602 #if 0
7603  if (f->frametype == AST_FRAME_VOICE) {
7604  chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
7605 
7606  continue;
7607  }
7608 #endif
7609 
7610  ast_write((who == c0) ? c1 : c0, f);
7611  }
7612 
7613  chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1);
7614 
7615  misdn_lib_split_bridge(ch1->bc, ch2->bc);
7616 
7617  chan_list_unref(ch1, "Bridge complete ch1");
7618  chan_list_unref(ch2, "Bridge complete ch2");
7619  return AST_BRIDGE_COMPLETE;
7620 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
Definition: channel.c:3534
union ast_frame_subclass subclass
Definition: frame.h:146
Main Channel structure associated with a channel.
Definition: channel.h:742
static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
Definition: chan_misdn.c:740
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
Definition: chan_misdn.c:410
#define AST_FRAME_DTMF
Definition: frame.h:128
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
#define ast_verb(level,...)
Definition: logger.h:243
void misdn_lib_split_bridge(struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
Definition: isdn_lib.c:4751
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
Definition: channel.h:1934
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define LOG_NOTICE
Definition: logger.h:133
unsigned int flags
Definition: frame.h:166
static struct ast_format f[]
Definition: format_g726.c:181
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:4916
Channel call record structure.
Definition: chan_misdn.c:349
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
void misdn_lib_bridge(struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
Definition: isdn_lib.c:4728
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Definition: channel.h:1932
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static int misdn_call ( struct ast_channel ast,
char *  dest,
int  timeout 
)
static

we should have l3id after sending setup

Definition at line 6485 of file chan_misdn.c.

References ast_channel::_state, add_out_calls(), args, AST_APP_ARG, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_to_misdn_plan(), ast_to_misdn_ton(), ast_transfercapability2str(), chan_list::bc, misdn_bchannel::caller, ast_channel::caller, misdn_bchannel::capability, chan_misdn_log(), ast_channel::connected, ast_channel::context, misdn_party_redirecting::count, debug_numtype(), misdn_bchannel::dialed, ENOCHAN, EVENT_SETUP, ext, ast_channel::exten, misdn_bchannel::fac_out, misdn_party_redirecting::from, ast_channel::hangupcause, misdn_bchannel::hdlc, ast_party_caller::id, ast_party_connected_line::id, import_ch(), misdn_bchannel::incoming_cid_tag, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::l3_id, chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, misdn_cfg_get(), MISDN_CFG_LOCALDIALPLAN, misdn_copy_redirecting_from_ast(), misdn_lib_is_ptp(), misdn_lib_send_event(), misdn_set_opt_exec(), ast_party_id::name, misdn_party_id::name, ast_channel::name, misdn_bchannel::nt, misdn_party_dialing::number, ast_party_id::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_ISDN, NUMTYPE_UNKNOWN, misdn_bchannel::outgoing_colp, pbx_builtin_setvar_helper(), misdn_bchannel::pid, ast_party_number::plan, misdn_bchannel::port, misdn_party_id::presentation, misdn_bchannel::presentation, print_facility(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_bchannel::sending_complete, misdn_bchannel::set_presentation, chan_list::state, stop_bc_tones(), ast_party_name::str, ast_party_number::str, ast_party_id::tag, ast_channel::transfercapability, update_config(), ast_party_name::valid, and ast_party_number::valid.

6486 {
6487  int port = 0;
6488  int r;
6489  int exceed;
6490  int number_type;
6491  struct chan_list *ch;
6492  struct misdn_bchannel *newbc;
6493  char *dest_cp;
6494  int append_msn = 0;
6495 
6497  AST_APP_ARG(intf); /* The interface token is discarded. */
6498  AST_APP_ARG(ext); /* extension token */
6499  AST_APP_ARG(opts); /* options token */
6500  );
6501 
6502  if (!ast) {
6503  ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
6504  return -1;
6505  }
6506 
6507  if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest) {
6508  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
6511  return -1;
6512  }
6513 
6514  ch = MISDN_ASTERISK_TECH_PVT(ast);
6515  if (!ch) {
6516  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, chan_list *ch==NULL\n", ast->name);
6519  return -1;
6520  }
6521 
6522  newbc = ch->bc;
6523  if (!newbc) {
6524  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, newbc==NULL\n", ast->name);
6527  return -1;
6528  }
6529 
6530  port = newbc->port;
6531 
6532 #if defined(AST_MISDN_ENHANCEMENTS)
6533  if ((ch->peer = misdn_cc_caller_get(ast))) {
6534  chan_misdn_log(3, port, " --> Found CC caller data, peer:%s\n",
6535  ch->peer->chan ? "available" : "NULL");
6536  }
6537 
6538  if (ch->record_id != -1) {
6539  struct misdn_cc_record *cc_record;
6540 
6541  /* This is a call completion retry call */
6542  AST_LIST_LOCK(&misdn_cc_records_db);
6543  cc_record = misdn_cc_find_by_id(ch->record_id);
6544  if (!cc_record) {
6545  AST_LIST_UNLOCK(&misdn_cc_records_db);
6546  ast_log(LOG_WARNING, " --> ! misdn_call called on %s, cc_record==NULL\n", ast->name);
6549  return -1;
6550  }
6551 
6552  /* Setup calling parameters to retry the call. */
6553  newbc->dialed = cc_record->redial.dialed;
6554  newbc->caller = cc_record->redial.caller;
6555  memset(&newbc->redirecting, 0, sizeof(newbc->redirecting));
6556  newbc->capability = cc_record->redial.capability;
6557  newbc->hdlc = cc_record->redial.hdlc;
6558  newbc->sending_complete = 1;
6559 
6560  if (cc_record->ptp) {
6561  newbc->fac_out.Function = Fac_CCBS_T_Call;
6562  newbc->fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id;
6563  } else {
6564  newbc->fac_out.Function = Fac_CCBSCall;
6565  newbc->fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id;
6566  newbc->fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id;
6567  }
6568  AST_LIST_UNLOCK(&misdn_cc_records_db);
6569 
6570  ast_copy_string(ast->exten, newbc->dialed.number, sizeof(ast->exten));
6571 
6572  chan_misdn_log(1, port, "* Call completion to: %s\n", newbc->dialed.number);
6573  chan_misdn_log(2, port, " --> * tech:%s context:%s\n", ast->name, ast->context);
6574  } else
6575 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6576  {
6577  /*
6578  * dest is ---v
6579  * Dial(mISDN/g:group_name[/extension[/options]])
6580  * Dial(mISDN/port[:preselected_channel][/extension[/options]])
6581  *
6582  * The dial extension could be empty if you are using MISDN_KEYPAD
6583  * to control ISDN provider features.
6584  */
6585  dest_cp = ast_strdupa(dest);
6586  AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
6587  if (!args.ext) {
6588  args.ext = "";
6589  }
6590 
6591  chan_misdn_log(1, port, "* CALL: %s\n", dest);
6592  chan_misdn_log(2, port, " --> * dialed:%s tech:%s context:%s\n", args.ext, ast->name, ast->context);
6593 
6594  ast_copy_string(ast->exten, args.ext, sizeof(ast->exten));
6595  ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number));
6596 
6597  if (ast_strlen_zero(newbc->caller.name)
6598  && ast->connected.id.name.valid
6599  && !ast_strlen_zero(ast->connected.id.name.str)) {
6600  ast_copy_string(newbc->caller.name, ast->connected.id.name.str, sizeof(newbc->caller.name));
6601  chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
6602  }
6603  if (ast_strlen_zero(newbc->caller.number)
6604  && ast->connected.id.number.valid
6605  && !ast_strlen_zero(ast->connected.id.number.str)) {
6606  ast_copy_string(newbc->caller.number, ast->connected.id.number.str, sizeof(newbc->caller.number));
6607  chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
6608  }
6609 
6610  misdn_cfg_get(port, MISDN_CFG_APPEND_MSN_TO_CALLERID_TAG, &append_msn, sizeof(append_msn));
6611  if (append_msn) {
6612  strncat(newbc->incoming_cid_tag, "_", sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1);
6613  strncat(newbc->incoming_cid_tag, newbc->caller.number, sizeof(newbc->incoming_cid_tag) - strlen(newbc->incoming_cid_tag) - 1);
6614  }
6615 
6616  ast->caller.id.tag = ast_strdup(newbc->incoming_cid_tag);
6617 
6618  misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
6619  if (number_type < 0) {
6620  if (ast->connected.id.number.valid) {
6623  } else {
6625  newbc->caller.number_plan = NUMPLAN_ISDN;
6626  }
6627  } else {
6628  /* Force us to send in SETUP message */
6629  newbc->caller.number_type = number_type;
6630  newbc->caller.number_plan = NUMPLAN_ISDN;
6631  }
6632  debug_numtype(port, newbc->caller.number_type, "LTON");
6633 
6634  newbc->capability = ast->transfercapability;
6635  pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability));
6637  chan_misdn_log(2, port, " --> * Call with flag Digital\n");
6638  }
6639 
6640  /* update caller screening and presentation */
6641  update_config(ch);
6642 
6643  /* fill in some ies from channel dialplan variables */
6644  import_ch(ast, newbc, ch);
6645 
6646  /* Finally The Options Override Everything */
6647  if (!ast_strlen_zero(args.opts)) {
6648  misdn_set_opt_exec(ast, args.opts);
6649  } else {
6650  chan_misdn_log(2, port, "NO OPTS GIVEN\n");
6651  }
6652  if (newbc->set_presentation) {
6653  newbc->caller.presentation = newbc->presentation;
6654  }
6655 
6656  misdn_copy_redirecting_from_ast(newbc, ast);
6657  switch (newbc->outgoing_colp) {
6658  case 1:/* restricted */
6659  case 2:/* blocked */
6660  newbc->redirecting.from.presentation = 1;/* restricted */
6661  break;
6662  default:
6663  break;
6664  }
6665 #if defined(AST_MISDN_ENHANCEMENTS)
6666  if (newbc->redirecting.from.number[0] && misdn_lib_is_ptp(port)) {
6667  if (newbc->redirecting.count < 1) {
6668  newbc->redirecting.count = 1;
6669  }
6670 
6671  /* Create DivertingLegInformation2 facility */
6672  newbc->fac_out.Function = Fac_DivertingLegInformation2;
6673  newbc->fac_out.u.DivertingLegInformation2.InvokeID = ++misdn_invoke_id;
6674  newbc->fac_out.u.DivertingLegInformation2.DivertingPresent = 1;
6675  misdn_PresentedNumberUnscreened_fill(
6676  &newbc->fac_out.u.DivertingLegInformation2.Diverting,
6677  &newbc->redirecting.from);
6678  switch (newbc->outgoing_colp) {
6679  case 2:/* blocked */
6680  /* Block the number going out */
6681  newbc->fac_out.u.DivertingLegInformation2.Diverting.Type = 1;/* presentationRestricted */
6682 
6683  /* Don't tell about any previous diversions or why for that matter. */
6684  newbc->fac_out.u.DivertingLegInformation2.DiversionCounter = 1;
6685  newbc->fac_out.u.DivertingLegInformation2.DiversionReason = 0;/* unknown */
6686  break;
6687  default:
6688  newbc->fac_out.u.DivertingLegInformation2.DiversionCounter =
6689  newbc->redirecting.count;
6690  newbc->fac_out.u.DivertingLegInformation2.DiversionReason =
6691  misdn_to_diversion_reason(newbc->redirecting.reason);
6692  break;
6693  }
6694  newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0;
6695  if (1 < newbc->fac_out.u.DivertingLegInformation2.DiversionCounter) {
6696  newbc->fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1;
6697  newbc->fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;/* numberNotAvailableDueToInterworking */
6698  }
6699 
6700  /*
6701  * Expect a DivertingLegInformation3 to update the COLR of the
6702  * redirecting-to party we are attempting to call now.
6703  */
6704  newbc->div_leg_3_rx_wanted = 1;
6705  }
6706 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6707  }
6708 
6709  exceed = add_out_calls(port);
6710  if (exceed != 0) {
6711  char tmp[16];
6712 
6713  snprintf(tmp, sizeof(tmp), "%d", exceed);
6714  pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp);
6717  return -1;
6718  }
6719 
6720 #if defined(AST_MISDN_ENHANCEMENTS)
6721  if (newbc->fac_out.Function != Fac_None) {
6722  print_facility(&newbc->fac_out, newbc);
6723  }
6724 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6725  r = misdn_lib_send_event(newbc, EVENT_SETUP);
6726 
6727  /** we should have l3id after sending setup **/
6728  ch->l3id = newbc->l3_id;
6729 
6730  if (r == -ENOCHAN) {
6731  chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
6732  chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1);
6735  return -1;
6736  }
6737 
6738  chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1);
6739 
6742 
6743  if (newbc->nt) {
6744  stop_bc_tones(ch);
6745  }
6746 
6747  ch->state = MISDN_CALLING;
6748 
6749  return 0;
6750 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
void debug_numtype(int port, int numtype, char *type)
Definition: chan_misdn.c:5822
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
static void update_config(struct chan_list *ch)
Updates caller ID information from config.
Definition: chan_misdn.c:5730
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
#define ast_strdup(a)
Definition: astmm.h:109
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:121
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:600
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int add_out_calls(int port)
Definition: chan_misdn.c:8817
B channel control structure.
Definition: isdn_lib.h:324
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Definition: isdn_lib.h:470
char * str
Subscriber name (Malloced)
Definition: channel.h:214
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
unsigned short transfercapability
Definition: channel.h:863
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Definition: causes.h:119
void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Import parameters from the dialplan environment variables.
Definition: chan_misdn.c:8744
const char * ext
Definition: http.c:112
static int stop_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7689
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2734
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int set_presentation
TRUE if the user set the presentation restriction code.
Definition: isdn_lib.h:603
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
Definition: chan_misdn.c:6316
Channel call record structure.
Definition: chan_misdn.c:349
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
Definition: chan_misdn.c:1888
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:513
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
char * tag
User-set &quot;tag&quot;.
Definition: channel.h:304
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Definition: channel.c:1041
int hangupcause
Definition: channel.h:849
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
Definition: chan_misdn.c:12223
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
Definition: chan_misdn.c:2014
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int misdn_chan_is_valid ( struct chan_list ch)
static

Definition at line 723 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, and chan_list::next.

Referenced by misdn_hangup().

724 {
725  struct chan_list *list;
726 
728  for (list = cl_te; list; list = list->next) {
729  if (list == ch) {
731  return 1;
732  }
733  }
735 
736  return 0;
737 }
struct chan_list * next
Next channel call record in the list.
Definition: chan_misdn.c:580
#define ast_mutex_lock(a)
Definition: lock.h:155
static struct chan_list * cl_te
Global channel call record list head.
Definition: chan_misdn.c:678
Channel call record structure.
Definition: chan_misdn.c:349
static ast_mutex_t cl_te_lock
Definition: chan_misdn.c:679
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int misdn_check_l2l1 ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 12149 of file chan_misdn.c.

References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_safe_sleep(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), BUFFERSIZE, chan_misdn_log(), LOG_WARNING, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_CFG_GROUPNAME, misdn_lib_get_port_up(), misdn_lib_port_up(), and parse().

Referenced by load_module().

12150 {
12151  char *parse;
12152  char group[BUFFERSIZE + 1];
12153  char *port_str;
12154  int port = 0;
12155  int timeout;
12156  int dowait = 0;
12157  int port_up;
12158 
12160  AST_APP_ARG(grouppar);
12161  AST_APP_ARG(timeout);
12162  );
12163 
12164  if (ast_strlen_zero((char *) data)) {
12165  ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
12166  return -1;
12167  }
12168 
12169  parse = ast_strdupa(data);
12170  AST_STANDARD_APP_ARGS(args, parse);
12171 
12172  if (args.argc != 2) {
12173  ast_log(LOG_WARNING, "Wrong argument count\n");
12174  return 0;
12175  }
12176 
12177  /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/
12178  timeout = atoi(args.timeout);
12179  port_str = args.grouppar;
12180 
12181  if (port_str[0] == 'g' && port_str[1] == ':') {
12182  /* We make a group call lets checkout which ports are in my group */
12183  port_str += 2;
12184  ast_copy_string(group, port_str, sizeof(group));
12185  chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group);
12186 
12187  for (port = misdn_cfg_get_next_port(port);
12188  port > 0;
12189  port = misdn_cfg_get_next_port(port)) {
12190  char cfg_group[BUFFERSIZE + 1];
12191 
12192  chan_misdn_log(2, 0, "trying port %d\n", port);
12193 
12194  misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
12195 
12196  if (!strcasecmp(cfg_group, group)) {
12197  port_up = misdn_lib_port_up(port, 1);
12198  if (!port_up) {
12199  chan_misdn_log(2, 0, " --> port '%d'\n", port);
12200  misdn_lib_get_port_up(port);
12201  dowait = 1;
12202  }
12203  }
12204  }
12205  } else {
12206  port = atoi(port_str);
12207  chan_misdn_log(2, 0, "Checking Port: %d\n", port);
12208  port_up = misdn_lib_port_up(port, 1);
12209  if (!port_up) {
12210  misdn_lib_get_port_up(port);
12211  dowait = 1;
12212  }
12213  }
12214 
12215  if (dowait) {
12216  chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout);
12217  ast_safe_sleep(chan, timeout * 1000);
12218  }
12219 
12220  return 0;
12221 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1916
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
#define BUFFERSIZE
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int misdn_lib_get_port_up(int port)
Definition: isdn_lib.c:1781
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
int misdn_lib_port_up(int port, int check)
Definition: isdn_lib.c:1821
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static void misdn_copy_redirecting_from_ast ( struct misdn_bchannel bc,
struct ast_channel ast 
)
static

Definition at line 6316 of file chan_misdn.c.

References ast_copy_string(), ast_to_misdn_plan(), ast_to_misdn_pres(), ast_to_misdn_reason(), ast_to_misdn_screen(), ast_to_misdn_ton(), misdn_party_redirecting::count, ast_party_redirecting::count, misdn_party_redirecting::from, ast_party_redirecting::from, ast_party_id::name, misdn_party_id::name, ast_party_id::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, ast_party_number::plan, ast_party_number::presentation, misdn_party_id::presentation, misdn_party_redirecting::reason, ast_party_redirecting::reason, misdn_bchannel::redirecting, ast_channel::redirecting, S_COR, S_OR, misdn_party_id::screening, ast_party_name::str, ast_party_number::str, misdn_party_redirecting::to, ast_party_redirecting::to, ast_party_name::valid, and ast_party_number::valid.

Referenced by misdn_call(), and misdn_update_redirecting().

6317 {
6320  sizeof(bc->redirecting.from.name));
6321  if (ast->redirecting.from.number.valid) {
6323  sizeof(bc->redirecting.from.number));
6328  } else {
6329  bc->redirecting.from.number[0] = '\0';
6330  bc->redirecting.from.presentation = 0;/* Allowed */
6331  bc->redirecting.from.screening = 0;/* Unscreened */
6334  }
6335 
6337  S_COR(ast->redirecting.to.name.valid, ast->redirecting.to.name.str, ""),
6338  sizeof(bc->redirecting.to.name));
6339  if (ast->redirecting.to.number.valid) {
6341  sizeof(bc->redirecting.to.number));
6346  } else {
6347  bc->redirecting.to.number[0] = '\0';
6348  bc->redirecting.to.presentation = 0;/* Allowed */
6349  bc->redirecting.to.screening = 0;/* Unscreened */
6352  }
6353 
6355  bc->redirecting.count = ast->redirecting.count;
6356 }
static int ast_to_misdn_pres(int presentation)
Definition: chan_misdn.c:2117
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
static int ast_to_misdn_screen(int screening)
Definition: chan_misdn.c:2214
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
Definition: chan_misdn.c:1888
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
int count
Number of times the call was redirected.
Definition: channel.h:455
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
int reason
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:458
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason(const enum AST_REDIRECTING_REASON ast)
Definition: chan_misdn.c:2246
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
Definition: chan_misdn.c:2014
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void misdn_copy_redirecting_to_ast ( struct ast_channel ast,
const struct misdn_party_redirecting redirect,
char *  tag 
)
static

Definition at line 6368 of file chan_misdn.c.

References ast_channel_set_redirecting(), ast_party_redirecting_set_init(), misdn_party_redirecting::count, ast_party_redirecting::count, misdn_party_redirecting::from, ast_party_redirecting::from, ast_set_party_redirecting::from, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_reason(), misdn_to_ast_screen(), misdn_to_ast_ton(), ast_party_id::number, misdn_party_id::number, ast_set_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, ast_party_number::presentation, misdn_party_id::presentation, misdn_party_redirecting::reason, ast_party_redirecting::reason, ast_channel::redirecting, misdn_party_id::screening, ast_party_number::str, ast_party_id::tag, misdn_party_redirecting::to, ast_party_redirecting::to, ast_set_party_redirecting::to, and ast_party_number::valid.

Referenced by cb_events(), and misdn_facility_ie_handler().

6369 {
6370  struct ast_party_redirecting redirecting;
6372 
6373  ast_party_redirecting_set_init(&redirecting, &ast->redirecting);
6374  memset(&update_redirecting, 0, sizeof(update_redirecting));
6375 
6376  update_redirecting.from.number = 1;
6377  redirecting.from.number.valid = 1;
6378  redirecting.from.number.str = (char *) redirect->from.number;
6379  redirecting.from.number.plan =
6380  misdn_to_ast_ton(redirect->from.number_type)
6381  | misdn_to_ast_plan(redirect->from.number_plan);
6382  redirecting.from.number.presentation =
6384  | misdn_to_ast_screen(redirect->from.screening);
6385  redirecting.from.tag = tag;
6386 
6387  update_redirecting.to.number = 1;
6388  redirecting.to.number.valid = 1;
6389  redirecting.to.number.str = (char *) redirect->to.number;
6390  redirecting.to.number.plan =
6391  misdn_to_ast_ton(redirect->to.number_type)
6392  | misdn_to_ast_plan(redirect->to.number_plan);
6393  redirecting.to.number.presentation =
6394  misdn_to_ast_pres(redirect->to.presentation)
6395  | misdn_to_ast_screen(redirect->to.screening);
6396  redirecting.to.tag = tag;
6397 
6398  redirecting.reason = misdn_to_ast_reason(redirect->reason);
6399  redirecting.count = redirect->count;
6400 
6401  ast_channel_set_redirecting(ast, &redirecting, &update_redirecting);
6402 }
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:1972
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2089
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1846
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
Definition: channel.c:9111
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:447
static enum AST_REDIRECTING_REASON misdn_to_ast_reason(const enum mISDN_REDIRECTING_REASON q931)
Definition: chan_misdn.c:2286
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:465
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
Definition: channel.c:2380
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen)
Send a provisional response indicating that a call was redirected.
Definition: chan_sip.c:13487
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2182
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316
static int misdn_digit_begin ( struct ast_channel chan,
char  digit 
)
static

Definition at line 6838 of file chan_misdn.c.

6839 {
6840  /* XXX Modify this callback to support Asterisk controlling the length of DTMF */
6841  return 0;
6842 }
static int misdn_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)
static

Definition at line 6844 of file chan_misdn.c.

References chan_list::ast, ast_copy_string(), ast_log(), chan_list::bc, chan_misdn_log(), misdn_bchannel::dialed, EVENT_INFORMATION, ast_channel::exten, misdn_bchannel::info_dad, misdn_bchannel::infos_pending, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_lib_send_event(), misdn_party_dialing::number, misdn_bchannel::port, send_digit_to_chan(), misdn_bchannel::send_dtmf, and chan_list::state.

6845 {
6846  struct chan_list *p;
6847  struct misdn_bchannel *bc;
6848  char buf[2] = { digit, 0 };
6849 
6850  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6851  return -1;
6852  }
6853 
6854  bc = p->bc;
6855  chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit);
6856 
6857  if (!bc) {
6858  ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n");
6859  return -1;
6860  }
6861 
6862  switch (p->state) {
6863  case MISDN_CALLING:
6864  if (strlen(bc->infos_pending) < sizeof(bc->infos_pending) - 1) {
6865  strncat(bc->infos_pending, buf, sizeof(bc->infos_pending) - strlen(bc->infos_pending) - 1);
6866  }
6867  break;
6869  ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad));
6870  if (strlen(bc->dialed.number) < sizeof(bc->dialed.number) - 1) {
6871  strncat(bc->dialed.number, buf, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
6872  }
6873  ast_copy_string(p->ast->exten, bc->dialed.number, sizeof(p->ast->exten));
6875  break;
6876  default:
6877  if (bc->send_dtmf) {
6878  send_digit_to_chan(p, digit);
6879  }
6880  break;
6881  }
6882 
6883  return 0;
6884 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
#define LOG_WARNING
Definition: logger.h:144
B channel control structure.
Definition: isdn_lib.h:324
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
char infos_pending[MISDN_MAX_NUMBER_LEN]
Collected digits to go into info_dad[] while waiting for a SETUP_ACKNOWLEDGE to come in...
Definition: isdn_lib.h:653
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
Definition: isdn_lib.h:457
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
Channel call record structure.
Definition: chan_misdn.c:349
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
static void send_digit_to_chan(struct chan_list *cl, char digit)
Definition: chan_misdn.c:3650
char info_dad[MISDN_MAX_NUMBER_LEN]
Current overlap dialing digits to/from INFORMATION messages.
Definition: isdn_lib.h:650
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static int misdn_facility_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 12026 of file chan_misdn.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), chan_list::bc, chan_misdn_log(), EVENT_FACILITY, misdn_bchannel::fac_out, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_lib_send_event(), parse(), misdn_bchannel::port, print_facility(), ast_channel::tech, and ast_channel_tech::type.

Referenced by load_module().

12027 {
12028  struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
12029  char *parse;
12030  unsigned max_len;
12031 
12033  AST_APP_ARG(facility_type);
12034  AST_APP_ARG(arg)[99];
12035  );
12036 
12037  chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type);
12038 
12039  if (strcasecmp(chan->tech->type, misdn_type)) {
12040  ast_log(LOG_WARNING, "misdn_facility only makes sense with %s channels!\n", misdn_type);
12041  return -1;
12042  }
12043 
12044  if (ast_strlen_zero((char *) data)) {
12045  ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n");
12046  return -1;
12047  }
12048 
12049  parse = ast_strdupa(data);
12050  AST_STANDARD_APP_ARGS(args, parse);
12051 
12052  if (ast_strlen_zero(args.facility_type)) {
12053  ast_log(LOG_WARNING, "misdn_facility requires arguments: facility_type[,<args>]\n");
12054  return -1;
12055  }
12056 
12057  if (!strcasecmp(args.facility_type, "calldeflect")) {
12058  if (ast_strlen_zero(args.arg[0])) {
12059  ast_log(LOG_WARNING, "Facility: Call Deflection requires an argument: Number\n");
12060  }
12061 
12062 #if defined(AST_MISDN_ENHANCEMENTS)
12063  max_len = sizeof(ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
12064  if (max_len < strlen(args.arg[0])) {
12066  "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12067  max_len);
12068  return 0;
12069  }
12070  ch->bc->fac_out.Function = Fac_CallDeflection;
12071  ch->bc->fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
12072  ch->bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
12073  ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
12074  ch->bc->fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
12075  ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;/* unknown */
12076  ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(args.arg[0]);
12077  strcpy((char *) ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, args.arg[0]);
12078  ch->bc->fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
12079 
12080 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
12081 
12082  max_len = sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1;
12083  if (max_len < strlen(args.arg[0])) {
12085  "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12086  max_len);
12087  return 0;
12088  }
12089  ch->bc->fac_out.Function = Fac_CD;
12090  ch->bc->fac_out.u.CDeflection.PresentationAllowed = 0;
12091  //ch->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0;
12092  strcpy((char *) ch->bc->fac_out.u.CDeflection.DeflectedToNumber, args.arg[0]);
12093 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
12094 
12095  /* Send message */
12096  print_facility(&ch->bc->fac_out, ch->bc);
12098 #if defined(AST_MISDN_ENHANCEMENTS)
12099  } else if (!strcasecmp(args.facility_type, "callrerouteing")
12100  || !strcasecmp(args.facility_type, "callrerouting")) {
12101  if (ast_strlen_zero(args.arg[0])) {
12102  ast_log(LOG_WARNING, "Facility: Call rerouting requires an argument: Number\n");
12103  }
12104 
12105  max_len = sizeof(ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
12106  if (max_len < strlen(args.arg[0])) {
12108  "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12109  max_len);
12110  return 0;
12111  }
12112  ch->bc->fac_out.Function = Fac_CallRerouteing;
12113  ch->bc->fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
12114  ch->bc->fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
12115 
12116  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;/* unknown */
12117  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
12118 
12119  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;/* unknown */
12120  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(args.arg[0]);
12121  strcpy((char *) ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, args.arg[0]);
12122  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
12123 
12124  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
12125 
12126  /* 0x90 0x90 0xa3 3.1 kHz audio, circuit mode, 64kbit/sec, level1/a-Law */
12127  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
12128  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
12129  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
12130  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
12131  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
12132  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
12133  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
12134 
12135  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;/* presentationRestricted */
12136  ch->bc->fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;/* no notification to caller */
12137 
12138  /* Send message */
12139  print_facility(&ch->bc->fac_out, ch->bc);
12141 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
12142  } else {
12143  chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", args.facility_type);
12144  }
12145 
12146  return 0;
12147 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
const char *const type
Definition: channel.h:508
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2734
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char misdn_type[]
Definition: chan_misdn.c:661
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
Channel call record structure.
Definition: chan_misdn.c:349
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
struct ast_channel_tech * tech
Definition: channel.h:743
static void misdn_facility_ie_handler ( enum event_e  event,
struct misdn_bchannel bc,
struct chan_list ch 
)
static

Definition at line 9051 of file chan_misdn.c.

References misdn_bchannel::AOCD, misdn_bchannel::AOCD_need_export, misdn_bchannel::AOCDtype, chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_channel_queue_redirecting_update(), AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER, AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING, AST_CONTROL_BUSY, ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PRES_ALLOWED, AST_PRES_RESTRICTED, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_string_field_set, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), misdn_bchannel::chargingUnit, misdn_party_redirecting::count, misdn_bchannel::currency, misdn_bchannel::dialed, EVENT_ALERTING, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, EVENT_SETUP, export_aoc_vars(), misdn_bchannel::fac_in, misdn_bchannel::fac_out, misdn_party_redirecting::from, misdn_bchannel::hdlc, misdn_bchannel::incoming_cid_tag, misdn_add_number_prefix(), misdn_copy_redirecting_to_ast(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING, mISDN_NOTIFY_CODE_INVALID, mISDN_REDIRECTING_REASON_DEFLECTION, misdn_update_remote_party(), misdn_party_id::name, misdn_bchannel::notify_description_code, misdn_party_dialing::number, ast_party_id::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_dialing::number_plan, misdn_party_id::number_type, misdn_party_dialing::number_type, NUMPLAN_ISDN, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, chan_list::originator, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, print_facility(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, ast_channel::redirecting, misdn_party_id::screening, misdn_party_redirecting::to, ast_party_redirecting::to, and misdn_party_redirecting::to_changed.

Referenced by cb_events().

9052 {
9053 #if defined(AST_MISDN_ENHANCEMENTS)
9054  const char *diagnostic_msg;
9055  struct misdn_cc_record *cc_record;
9056  char buf[32];
9057  struct misdn_party_id party_id;
9058  long new_record_id;
9059 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
9060 
9061  print_facility(&bc->fac_in, bc);
9062  switch (bc->fac_in.Function) {
9063 #if defined(AST_MISDN_ENHANCEMENTS)
9064  case Fac_ActivationDiversion:
9065  switch (bc->fac_in.u.ActivationDiversion.ComponentType) {
9066  case FacComponent_Result:
9067  /* Positive ACK to activation */
9068  /* We don't handle this yet */
9069  break;
9070  default:
9071  chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n",
9072  bc->fac_in.Function);
9073  break;
9074  }
9075  break;
9076  case Fac_DeactivationDiversion:
9077  switch (bc->fac_in.u.DeactivationDiversion.ComponentType) {
9078  case FacComponent_Result:
9079  /* Positive ACK to deactivation */
9080  /* We don't handle this yet */
9081  break;
9082  default:
9083  chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n",
9084  bc->fac_in.Function);
9085  break;
9086  }
9087  break;
9088  case Fac_ActivationStatusNotificationDiv:
9089  /* Sent to other MSN numbers on the line when a user activates call forwarding. */
9090  /* Sent in the first call control message of an outgoing call from the served user. */
9091  /* We do not have anything to do for this message. */
9092  break;
9093  case Fac_DeactivationStatusNotificationDiv:
9094  /* Sent to other MSN numbers on the line when a user deactivates call forwarding. */
9095  /* We do not have anything to do for this message. */
9096  break;
9097 #if 0 /* We don't handle this yet */
9098  case Fac_InterrogationDiversion:
9099  /* We don't handle this yet */
9100  break;
9101  case Fac_InterrogateServedUserNumbers:
9102  /* We don't handle this yet */
9103  break;
9104 #endif /* We don't handle this yet */
9105  case Fac_DiversionInformation:
9106  /* Sent to the served user when a call is forwarded. */
9107  /* We do not have anything to do for this message. */
9108  break;
9109  case Fac_CallDeflection:
9110  if (ch && ch->ast) {
9111  switch (bc->fac_in.u.CallDeflection.ComponentType) {
9112  case FacComponent_Invoke:
9114  sizeof(bc->redirecting.from.number));
9115  bc->redirecting.from.name[0] = 0;
9118  bc->redirecting.from.screening = 0;/* Unscreened */
9119  if (bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
9121  bc->fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser
9122  ? 0 /* Allowed */ : 1 /* Restricted */;
9123  } else {
9124  bc->redirecting.from.presentation = 0;/* Allowed */
9125  }
9126 
9127  /* Add configured prefix to the call deflection number */
9128  memset(&party_id, 0, sizeof(party_id));
9129  misdn_PartyNumber_extract(&party_id,
9130  &bc->fac_in.u.CallDeflection.Component.Invoke.Deflection.Party);
9131  misdn_add_number_prefix(bc->port, party_id.number_type,
9132  party_id.number, sizeof(party_id.number));
9133  //party_id.presentation = 0;/* Allowed */
9134  //party_id.screening = 0;/* Unscreened */
9135  bc->redirecting.to = party_id;
9136 
9137  ++bc->redirecting.count;
9139 
9141  ast_string_field_set(ch->ast, call_forward, bc->redirecting.to.number);
9142 
9143  /* Send back positive ACK */
9144 #if 1
9145  /*
9146  * Since there are no return result arguments it must be a
9147  * generic result message. ETSI 300-196
9148  */
9149  bc->fac_out.Function = Fac_RESULT;
9150  bc->fac_out.u.RESULT.InvokeID = bc->fac_in.u.CallDeflection.InvokeID;
9151 #else
9152  bc->fac_out.Function = Fac_CallDeflection;
9153  bc->fac_out.u.CallDeflection.InvokeID = bc->fac_in.u.CallDeflection.InvokeID;
9154  bc->fac_out.u.CallDeflection.ComponentType = FacComponent_Result;
9155 #endif
9156  print_facility(&bc->fac_out, bc);
9158 
9159  /* This line is BUSY to further attempts by this dialing attempt. */
9161  break;
9162 
9163  case FacComponent_Result:
9164  /* Positive ACK to call deflection */
9165  /*
9166  * Sent in DISCONNECT or FACILITY message depending upon network option.
9167  * It is in the FACILITY message if the call is still offered to the user
9168  * while trying to alert the deflected to party.
9169  */
9170  /* Ignore the ACK */
9171  break;
9172 
9173  default:
9174  break;
9175  }
9176  }
9177  break;
9178 #if 0 /* We don't handle this yet */
9179  case Fac_CallRerouteing:
9180  /* Private-Public ISDN interworking message */
9181  /* We don't handle this yet */
9182  break;
9183 #endif /* We don't handle this yet */
9184  case Fac_DivertingLegInformation1:
9185  /* Private-Public ISDN interworking message */
9186  bc->div_leg_3_rx_wanted = 0;
9187  if (ch && ch->ast) {
9188  bc->redirecting.reason =
9189  diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation1.DiversionReason);
9190  if (bc->fac_in.u.DivertingLegInformation1.DivertedToPresent) {
9191  misdn_PresentedNumberUnscreened_extract(&bc->redirecting.to,
9192  &bc->fac_in.u.DivertingLegInformation1.DivertedTo);
9193 
9194  /* Add configured prefix to redirecting.to.number */
9196  bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
9197  } else {
9198  bc->redirecting.to.number[0] = '\0';
9201  bc->redirecting.to.presentation = 1;/* restricted */
9202  bc->redirecting.to.screening = 0;/* unscreened */
9203  }
9205  bc->div_leg_3_rx_wanted = 1;
9206  }
9207  break;
9208  case Fac_DivertingLegInformation2:
9209  /* Private-Public ISDN interworking message */
9210  switch (event) {
9211  case EVENT_SETUP:
9212  /* Comes in on a SETUP with redirecting.from information */
9213  bc->div_leg_3_tx_pending = 1;
9214  if (ch && ch->ast) {
9215  /*
9216  * Setup the redirecting.to informtion so we can identify
9217  * if the user wants to manually supply the COLR for this
9218  * redirected to number if further redirects could happen.
9219  *
9220  * All the user needs to do is set the REDIRECTING(to-pres)
9221  * to the COLR and REDIRECTING(to-num) = ${EXTEN} to be safe
9222  * after determining that the incoming call was redirected by
9223  * checking if there is a REDIRECTING(from-num).
9224  */
9226  sizeof(bc->redirecting.to.number));
9229  bc->redirecting.to.presentation = 1;/* restricted */
9230  bc->redirecting.to.screening = 0;/* unscreened */
9231 
9232  bc->redirecting.reason =
9233  diversion_reason_to_misdn(bc->fac_in.u.DivertingLegInformation2.DiversionReason);
9234  bc->redirecting.count = bc->fac_in.u.DivertingLegInformation2.DiversionCounter;
9235  if (bc->fac_in.u.DivertingLegInformation2.DivertingPresent) {
9236  /* This information is redundant if there was a redirecting ie in the SETUP. */
9237  misdn_PresentedNumberUnscreened_extract(&bc->redirecting.from,
9238  &bc->fac_in.u.DivertingLegInformation2.Diverting);
9239 
9240  /* Add configured prefix to redirecting.from.number */
9242  bc->redirecting.from.number, sizeof(bc->redirecting.from.number));
9243  }
9244 #if 0
9245  if (bc->fac_in.u.DivertingLegInformation2.OriginalCalledPresent) {
9246  /* We have no place to put the OriginalCalled number */
9247  }
9248 #endif
9250  }
9251  break;
9252  default:
9253  chan_misdn_log(0, bc->port," --> Expected in a SETUP message: facility type:0x%04X\n",
9254  bc->fac_in.Function);
9255  break;
9256  }
9257  break;
9258  case Fac_DivertingLegInformation3:
9259  /* Private-Public ISDN interworking message */
9260  if (bc->div_leg_3_rx_wanted) {
9261  bc->div_leg_3_rx_wanted = 0;
9262 
9263  if (ch && ch->ast) {
9265  bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
9269  }
9270  }
9271  break;
9272 
9273 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
9274 
9275  case Fac_CD:
9276  if (ch && ch->ast) {
9278  sizeof(bc->redirecting.from.number));
9279  bc->redirecting.from.name[0] = 0;
9282  bc->redirecting.from.screening = 0;/* Unscreened */
9284  bc->fac_in.u.CDeflection.PresentationAllowed
9285  ? 0 /* Allowed */ : 1 /* Restricted */;
9286 
9288  (char *) bc->fac_in.u.CDeflection.DeflectedToNumber,
9289  sizeof(bc->redirecting.to.number));
9290  bc->redirecting.to.name[0] = 0;
9293  bc->redirecting.to.presentation = 0;/* Allowed */
9294  bc->redirecting.to.screening = 0;/* Unscreened */
9295 
9296  ++bc->redirecting.count;
9298 
9300  ast_string_field_set(ch->ast, call_forward, bc->redirecting.to.number);
9301 
9303 
9304  /* This line is BUSY to further attempts by this dialing attempt. */
9306  }
9307  break;
9308 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
9309  case Fac_AOCDCurrency:
9310  if (ch && ch->ast) {
9311  bc->AOCDtype = Fac_AOCDCurrency;
9312  memcpy(&bc->AOCD.currency, &bc->fac_in.u.AOCDcur, sizeof(bc->AOCD.currency));
9313  bc->AOCD_need_export = 1;
9314  export_aoc_vars(ch->originator, ch->ast, bc);
9315  }
9316  break;
9317  case Fac_AOCDChargingUnit:
9318  if (ch && ch->ast) {
9319  bc->AOCDtype = Fac_AOCDChargingUnit;
9320  memcpy(&bc->AOCD.chargingUnit, &bc->fac_in.u.AOCDchu, sizeof(bc->AOCD.chargingUnit));
9321  bc->AOCD_need_export = 1;
9322  export_aoc_vars(ch->originator, ch->ast, bc);
9323  }
9324  break;
9325 #if defined(AST_MISDN_ENHANCEMENTS)
9326  case Fac_ERROR:
9327  diagnostic_msg = misdn_to_str_error_code(bc->fac_in.u.ERROR.errorValue);
9328  chan_misdn_log(1, bc->port, " --> Facility error code: %s\n", diagnostic_msg);
9329  switch (event) {
9330  case EVENT_DISCONNECT:
9331  case EVENT_RELEASE:
9333  /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
9334  if (ch && ch->peer) {
9335  misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9336  }
9337  break;
9338  default:
9339  break;
9340  }
9341  AST_LIST_LOCK(&misdn_cc_records_db);
9342  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.ERROR.invokeId);
9343  if (cc_record) {
9344  cc_record->outstanding_message = 0;
9345  cc_record->error_code = bc->fac_in.u.ERROR.errorValue;
9346  }
9347  AST_LIST_UNLOCK(&misdn_cc_records_db);
9348  break;
9349  case Fac_REJECT:
9350  diagnostic_msg = misdn_to_str_reject_code(bc->fac_in.u.REJECT.Code);
9351  chan_misdn_log(1, bc->port, " --> Facility reject code: %s\n", diagnostic_msg);
9352  switch (event) {
9353  case EVENT_DISCONNECT:
9354  case EVENT_RELEASE:
9356  /* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
9357  if (ch && ch->peer) {
9358  misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9359  }
9360  break;
9361  default:
9362  break;
9363  }
9364  if (bc->fac_in.u.REJECT.InvokeIDPresent) {
9365  AST_LIST_LOCK(&misdn_cc_records_db);
9366  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.REJECT.InvokeID);
9367  if (cc_record) {
9368  cc_record->outstanding_message = 0;
9369  cc_record->reject_code = bc->fac_in.u.REJECT.Code;
9370  }
9371  AST_LIST_UNLOCK(&misdn_cc_records_db);
9372  }
9373  break;
9374  case Fac_RESULT:
9375  AST_LIST_LOCK(&misdn_cc_records_db);
9376  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.RESULT.InvokeID);
9377  if (cc_record) {
9378  cc_record->outstanding_message = 0;
9379  }
9380  AST_LIST_UNLOCK(&misdn_cc_records_db);
9381  break;
9382 #if 0 /* We don't handle this yet */
9383  case Fac_EctExecute:
9384  /* We don't handle this yet */
9385  break;
9386  case Fac_ExplicitEctExecute:
9387  /* We don't handle this yet */
9388  break;
9389  case Fac_EctLinkIdRequest:
9390  /* We don't handle this yet */
9391  break;
9392 #endif /* We don't handle this yet */
9393  case Fac_SubaddressTransfer:
9394  /* We do not have anything to do for this message since we do not handle subaddreses. */
9395  break;
9396  case Fac_RequestSubaddress:
9397  /*
9398  * We do not have anything to do for this message since we do not handle subaddreses.
9399  * However, we do care about some other ie's that should be present.
9400  */
9401  if (bc->redirecting.to_changed) {
9402  /* Add configured prefix to redirecting.to.number */
9404  bc->redirecting.to.number, sizeof(bc->redirecting.to.number));
9405  }
9406  switch (bc->notify_description_code) {
9408  /* Notify ie was not present. */
9409  bc->redirecting.to_changed = 0;
9410  break;
9412  /*
9413  * It would be preferable to update the connected line information
9414  * only when the message callStatus is active. However, the
9415  * optional redirection number may not be present in the active
9416  * message if an alerting message were received earlier.
9417  *
9418  * The consequences if we wind up sending two updates is benign.
9419  * The other end will think that it got transferred twice.
9420  */
9421  if (!bc->redirecting.to_changed) {
9422  break;
9423  }
9424  bc->redirecting.to_changed = 0;
9425  if (!ch || !ch->ast) {
9426  break;
9427  }
9430  bc->incoming_cid_tag);
9431  break;
9433  if (!bc->redirecting.to_changed) {
9434  break;
9435  }
9436  bc->redirecting.to_changed = 0;
9437  if (!ch || !ch->ast) {
9438  break;
9439  }
9442  break;
9443  default:
9444  bc->redirecting.to_changed = 0;
9445  chan_misdn_log(0, bc->port," --> not yet handled: notify code:0x%02X\n",
9447  break;
9448  }
9450  break;
9451  case Fac_EctInform:
9452  /* Private-Public ISDN interworking message */
9453  if (ch && ch->ast && bc->fac_in.u.EctInform.RedirectionPresent) {
9454  /* Add configured prefix to the redirection number */
9455  memset(&party_id, 0, sizeof(party_id));
9456  misdn_PresentedNumberUnscreened_extract(&party_id,
9457  &bc->fac_in.u.EctInform.Redirection);
9458  misdn_add_number_prefix(bc->port, party_id.number_type,
9459  party_id.number, sizeof(party_id.number));
9460 
9461  /*
9462  * It would be preferable to update the connected line information
9463  * only when the message callStatus is active. However, the
9464  * optional redirection number may not be present in the active
9465  * message if an alerting message were received earlier.
9466  *
9467  * The consequences if we wind up sending two updates is benign.
9468  * The other end will think that it got transferred twice.
9469  */
9470  misdn_update_remote_party(ch->ast, &party_id,
9471  (bc->fac_in.u.EctInform.Status == 0 /* alerting */)
9474  bc->incoming_cid_tag);
9475  }
9476  break;
9477 #if 0 /* We don't handle this yet */
9478  case Fac_EctLoopTest:
9479  /* The use of this message is unclear on how it works to detect loops. */
9480  /* We don't handle this yet */
9481  break;
9482 #endif /* We don't handle this yet */
9483  case Fac_CallInfoRetain:
9484  switch (event) {
9485  case EVENT_ALERTING:
9486  case EVENT_DISCONNECT:
9487  /* CCBS/CCNR is available */
9488  if (ch && ch->peer) {
9489  AST_LIST_LOCK(&misdn_cc_records_db);
9490  if (ch->record_id == -1) {
9491  cc_record = misdn_cc_new();
9492  } else {
9493  /*
9494  * We are doing a call-completion attempt
9495  * or the switch is sending us extra call-completion
9496  * availability indications (erroneously?).
9497  *
9498  * Assume that the network request retention option
9499  * is not on and that the current call-completion
9500  * request is disabled.
9501  */
9502  cc_record = misdn_cc_find_by_id(ch->record_id);
9503  if (cc_record) {
9504  if (cc_record->ptp && cc_record->mode.ptp.bc) {
9505  /*
9506  * What? We are getting mixed messages from the
9507  * switch. We are currently setup for
9508  * point-to-point. Now we are switching to
9509  * point-to-multipoint.
9510  *
9511  * Close the call-completion signaling link
9512  */
9513  cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9514  cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
9515  misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
9516  }
9517 
9518  /*
9519  * Resetup the existing record for a possible new
9520  * call-completion request.
9521  */
9522  new_record_id = misdn_cc_record_id_new();
9523  if (new_record_id < 0) {
9524  /* Looks like we must keep the old id anyway. */
9525  } else {
9526  cc_record->record_id = new_record_id;
9527  ch->record_id = new_record_id;
9528  }
9529  cc_record->ptp = 0;
9530  cc_record->port = bc->port;
9531  memset(&cc_record->mode, 0, sizeof(cc_record->mode));
9532  cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
9533  cc_record->invoke_id = ++misdn_invoke_id;
9534  cc_record->activated = 0;
9535  cc_record->outstanding_message = 0;
9536  cc_record->activation_requested = 0;
9537  cc_record->error_code = FacError_None;
9538  cc_record->reject_code = FacReject_None;
9539  memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
9540  memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
9541  cc_record->time_created = time(NULL);
9542 
9543  cc_record = NULL;
9544  } else {
9545  /*
9546  * Where did the record go? We will have to recapture
9547  * the call setup information. Unfortunately, some
9548  * setup information may have been changed.
9549  */
9550  ch->record_id = -1;
9551  cc_record = misdn_cc_new();
9552  }
9553  }
9554  if (cc_record) {
9555  ch->record_id = cc_record->record_id;
9556  cc_record->ptp = 0;
9557  cc_record->port = bc->port;
9558  cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
9559 
9560  /* Record call information for possible call-completion attempt. */
9561  cc_record->redial.caller = bc->caller;
9562  cc_record->redial.dialed = bc->dialed;
9563  cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9564  cc_record->redial.capability = bc->capability;
9565  cc_record->redial.hdlc = bc->hdlc;
9566  }
9567  AST_LIST_UNLOCK(&misdn_cc_records_db);
9568 
9569  /* Set MISDN_CC_RECORD_ID in original channel */
9570  if (ch->record_id != -1) {
9571  snprintf(buf, sizeof(buf), "%ld", ch->record_id);
9572  } else {
9573  buf[0] = 0;
9574  }
9575  misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9576  }
9577  break;
9578  default:
9579  chan_misdn_log(0, bc->port,
9580  " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9581  bc->fac_in.Function);
9582  break;
9583  }
9584  break;
9585  case Fac_CCBS_T_Call:
9586  case Fac_CCBSCall:
9587  switch (event) {
9588  case EVENT_SETUP:
9589  /*
9590  * This is a call completion retry call.
9591  * If we had anything to do we would do it here.
9592  */
9593  break;
9594  default:
9595  chan_misdn_log(0, bc->port, " --> Expected in a SETUP message: facility type:0x%04X\n",
9596  bc->fac_in.Function);
9597  break;
9598  }
9599  break;
9600  case Fac_CCBSDeactivate:
9601  switch (bc->fac_in.u.CCBSDeactivate.ComponentType) {
9602  case FacComponent_Result:
9603  AST_LIST_LOCK(&misdn_cc_records_db);
9604  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSDeactivate.InvokeID);
9605  if (cc_record) {
9606  cc_record->outstanding_message = 0;
9607  }
9608  AST_LIST_UNLOCK(&misdn_cc_records_db);
9609  break;
9610 
9611  default:
9612  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9613  bc->fac_in.Function);
9614  break;
9615  }
9616  break;
9617  case Fac_CCBSErase:
9618  AST_LIST_LOCK(&misdn_cc_records_db);
9619  cc_record = misdn_cc_find_by_reference(bc->port, bc->fac_in.u.CCBSErase.CCBSReference);
9620  if (cc_record) {
9621  misdn_cc_delete(cc_record);
9622  }
9623  AST_LIST_UNLOCK(&misdn_cc_records_db);
9624  break;
9625  case Fac_CCBSRemoteUserFree:
9626  misdn_cc_handle_remote_user_free(bc->port, &bc->fac_in);
9627  break;
9628  case Fac_CCBSBFree:
9629  misdn_cc_handle_b_free(bc->port, &bc->fac_in);
9630  break;
9631  case Fac_CCBSStatusRequest:
9632  misdn_cc_handle_ccbs_status_request(bc->port, &bc->fac_in);
9633  break;
9634  case Fac_EraseCallLinkageID:
9635  AST_LIST_LOCK(&misdn_cc_records_db);
9636  cc_record = misdn_cc_find_by_linkage(bc->port,
9637  bc->fac_in.u.EraseCallLinkageID.CallLinkageID);
9638  if (cc_record && !cc_record->activation_requested) {
9639  /*
9640  * The T-RETENTION timer expired before we requested
9641  * call completion activation. Call completion is no
9642  * longer available.
9643  */
9644  misdn_cc_delete(cc_record);
9645  }
9646  AST_LIST_UNLOCK(&misdn_cc_records_db);
9647  break;
9648  case Fac_CCBSStopAlerting:
9649  /* We do not have anything to do for this message. */
9650  break;
9651  case Fac_CCBSRequest:
9652  case Fac_CCNRRequest:
9653  switch (bc->fac_in.u.CCBSRequest.ComponentType) {
9654  case FacComponent_Result:
9655  AST_LIST_LOCK(&misdn_cc_records_db);
9656  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSRequest.InvokeID);
9657  if (cc_record && !cc_record->ptp) {
9658  cc_record->outstanding_message = 0;
9659  cc_record->activated = 1;
9660  cc_record->mode.ptmp.recall_mode = bc->fac_in.u.CCBSRequest.Component.Result.RecallMode;
9661  cc_record->mode.ptmp.reference_id = bc->fac_in.u.CCBSRequest.Component.Result.CCBSReference;
9662  }
9663  AST_LIST_UNLOCK(&misdn_cc_records_db);
9664  break;
9665 
9666  default:
9667  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9668  bc->fac_in.Function);
9669  break;
9670  }
9671  break;
9672 #if 0 /* We don't handle this yet */
9673  case Fac_CCBSInterrogate:
9674  case Fac_CCNRInterrogate:
9675  /* We don't handle this yet */
9676  break;
9677  case Fac_StatusRequest:
9678  /* We don't handle this yet */
9679  break;
9680 #endif /* We don't handle this yet */
9681 #if 0 /* We don't handle this yet */
9682  case Fac_CCBS_T_Suspend:
9683  case Fac_CCBS_T_Resume:
9684  /* We don't handle this yet */
9685  break;
9686 #endif /* We don't handle this yet */
9687  case Fac_CCBS_T_RemoteUserFree:
9688  misdn_cc_handle_T_remote_user_free(bc);
9689  break;
9690  case Fac_CCBS_T_Available:
9691  switch (event) {
9692  case EVENT_ALERTING:
9693  case EVENT_DISCONNECT:
9694  /* CCBS-T/CCNR-T is available */
9695  if (ch && ch->peer) {
9696  int set_id = 1;
9697 
9698  AST_LIST_LOCK(&misdn_cc_records_db);
9699  if (ch->record_id == -1) {
9700  cc_record = misdn_cc_new();
9701  } else {
9702  /*
9703  * We are doing a call-completion attempt
9704  * or the switch is sending us extra call-completion
9705  * availability indications (erroneously?).
9706  */
9707  cc_record = misdn_cc_find_by_id(ch->record_id);
9708  if (cc_record) {
9709  if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) {
9710  /*
9711  * Call-completion is still activated.
9712  * The user does not have to request it again.
9713  */
9714  chan_misdn_log(1, bc->port, " --> Call-completion request retention option is enabled\n");
9715 
9716  set_id = 0;
9717  } else {
9718  if (cc_record->ptp && cc_record->mode.ptp.bc) {
9719  /*
9720  * The network request retention option
9721  * is not on and the current call-completion
9722  * request is to be disabled.
9723  *
9724  * We should get here only if EVENT_DISCONNECT
9725  *
9726  * Close the call-completion signaling link
9727  */
9728  cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9729  cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
9730  misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
9731  }
9732 
9733  /*
9734  * Resetup the existing record for a possible new
9735  * call-completion request.
9736  */
9737  new_record_id = misdn_cc_record_id_new();
9738  if (new_record_id < 0) {
9739  /* Looks like we must keep the old id anyway. */
9740  } else {
9741  cc_record->record_id = new_record_id;
9742  ch->record_id = new_record_id;
9743  }
9744  cc_record->ptp = 1;
9745  cc_record->port = bc->port;
9746  memset(&cc_record->mode, 0, sizeof(cc_record->mode));
9747  cc_record->invoke_id = ++misdn_invoke_id;
9748  cc_record->activated = 0;
9749  cc_record->outstanding_message = 0;
9750  cc_record->activation_requested = 0;
9751  cc_record->error_code = FacError_None;
9752  cc_record->reject_code = FacReject_None;
9753  memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
9754  memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
9755  cc_record->time_created = time(NULL);
9756  }
9757  cc_record = NULL;
9758  } else {
9759  /*
9760  * Where did the record go? We will have to recapture
9761  * the call setup information. Unfortunately, some
9762  * setup information may have been changed.
9763  */
9764  ch->record_id = -1;
9765  cc_record = misdn_cc_new();
9766  }
9767  }
9768  if (cc_record) {
9769  ch->record_id = cc_record->record_id;
9770  cc_record->ptp = 1;
9771  cc_record->port = bc->port;
9772 
9773  /* Record call information for possible call-completion attempt. */
9774  cc_record->redial.caller = bc->caller;
9775  cc_record->redial.dialed = bc->dialed;
9776  cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9777  cc_record->redial.capability = bc->capability;
9778  cc_record->redial.hdlc = bc->hdlc;
9779  }
9780  AST_LIST_UNLOCK(&misdn_cc_records_db);
9781 
9782  /* Set MISDN_CC_RECORD_ID in original channel */
9783  if (ch->record_id != -1 && set_id) {
9784  snprintf(buf, sizeof(buf), "%ld", ch->record_id);
9785  } else {
9786  buf[0] = 0;
9787  }
9788  misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9789  }
9790  break;
9791  default:
9792  chan_misdn_log(0, bc->port,
9793  " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9794  bc->fac_in.Function);
9795  break;
9796  }
9797  break;
9798  case Fac_CCBS_T_Request:
9799  case Fac_CCNR_T_Request:
9800  switch (bc->fac_in.u.CCBS_T_Request.ComponentType) {
9801  case FacComponent_Result:
9802  AST_LIST_LOCK(&misdn_cc_records_db);
9803  cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBS_T_Request.InvokeID);
9804  if (cc_record && cc_record->ptp) {
9805  cc_record->outstanding_message = 0;
9806  cc_record->activated = 1;
9807  cc_record->mode.ptp.retention_enabled =
9808  cc_record->mode.ptp.requested_retention
9809  ? bc->fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported
9810  ? 1 : 0
9811  : 0;
9812  }
9813  AST_LIST_UNLOCK(&misdn_cc_records_db);
9814  break;
9815 
9816  case FacComponent_Invoke:
9817  /* We cannot be User-B in ptp mode. */
9818  default:
9819  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9820  bc->fac_in.Function);
9821  break;
9822  }
9823  break;
9824 
9825 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
9826  case Fac_None:
9827  break;
9828  default:
9829  chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
9830  bc->fac_in.Function);
9831  break;
9832  }
9833 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
enum FacFunction AOCDtype
Definition: isdn_lib.h:515
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
Connected-Line/Calling/Redirecting ID info struct.
Definition: isdn_lib.h:273
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
Definition: chan_misdn.c:6368
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
Definition: isdn_lib.h:521
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2734
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
struct FacAOCDCurrency currency
Definition: isdn_lib.h:517
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3396
static void misdn_update_remote_party(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
Definition: chan_misdn.c:6145
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
Definition: chan_misdn.c:3430
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
#define AST_PRES_ALLOWED
Definition: callerid.h:324
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
Definition: channel.c:9605
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
union misdn_bchannel::@126 AOCD
struct FacParm fac_in
Inbound FACILITY message function type and contents.
Definition: isdn_lib.h:507
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
struct FacAOCDChargingUnit chargingUnit
Definition: isdn_lib.h:518
int count
Number of times the call has been redirected.
Definition: isdn_lib.h:316
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:263
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int misdn_fixup ( struct ast_channel oldast,
struct ast_channel ast 
)
static

Definition at line 6887 of file chan_misdn.c.

References chan_list::ast, chan_list::bc, chan_misdn_log(), chan_list::l3id, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), and misdn_bchannel::port.

6888 {
6889  struct chan_list *p;
6890 
6891  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6892  return -1;
6893  }
6894 
6895  chan_misdn_log(1, p->bc ? p->bc->port : 0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
6896 
6897  p->ast = ast;
6898 
6899  return 0;
6900 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4071
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
Channel call record structure.
Definition: chan_misdn.c:349
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:513
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static const char* misdn_get_ch_state ( struct chan_list p)
static

Definition at line 4071 of file chan_misdn.c.

References ARRAY_LEN, chan_list::state, state, and state_struct::txt.

Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), and print_bc_info().

4072 {
4073  int i;
4074  static char state[8];
4075 
4076  if (!p) {
4077  return NULL;
4078  }
4079 
4080  for (i = 0; i < ARRAY_LEN(state_array); i++) {
4081  if (state_array[i].state == p->state) {
4082  return state_array[i].txt;
4083  }
4084  }
4085 
4086  snprintf(state, sizeof(state), "%d", p->state) ;
4087 
4088  return state;
4089 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char txt[255]
Definition: chan_misdn.c:4049
static struct state_struct state_array[]
Definition: chan_misdn.c:4052
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
static void misdn_get_connected_line ( struct ast_channel ast,
struct misdn_bchannel bc,
int  originator 
)
static

Definition at line 6161 of file chan_misdn.c.

References ast_copy_string(), ast_to_misdn_plan(), ast_to_misdn_pres(), ast_to_misdn_screen(), ast_to_misdn_ton(), misdn_bchannel::caller, misdn_bchannel::connected, ast_channel::connected, debug_numtype(), ast_party_connected_line::id, MISDN_CFG_CPNDIALPLAN, misdn_cfg_get(), MISDN_CFG_LOCALDIALPLAN, ast_party_id::name, misdn_party_id::name, ast_party_id::number, misdn_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, NUMPLAN_ISDN, NUMPLAN_UNKNOWN, NUMTYPE_UNKNOWN, ORG_MISDN, ast_party_number::plan, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, S_COR, S_OR, misdn_party_id::screening, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by misdn_update_connected_line().

6162 {
6163  int number_type;
6164 
6165  if (originator == ORG_MISDN) {
6166  /* ORIGINATOR MISDN (incoming call) */
6167 
6169  S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
6170  sizeof(bc->connected.name));
6171  if (ast->connected.id.number.valid) {
6173  sizeof(bc->connected.number));
6178  } else {
6179  bc->connected.number[0] = '\0';
6180  bc->connected.presentation = 0;/* Allowed */
6181  bc->connected.screening = 0;/* Unscreened */
6184  }
6185 
6186  misdn_cfg_get(bc->port, MISDN_CFG_CPNDIALPLAN, &number_type, sizeof(number_type));
6187  if (0 <= number_type) {
6188  /* Force us to send in CONNECT message */
6189  bc->connected.number_type = number_type;
6191  }
6192  debug_numtype(bc->port, bc->connected.number_type, "CTON");
6193  } else {
6194  /* ORIGINATOR Asterisk (outgoing call) */
6195 
6197  S_COR(ast->connected.id.name.valid, ast->connected.id.name.str, ""),
6198  sizeof(bc->caller.name));
6199  if (ast->connected.id.number.valid) {
6201  sizeof(bc->caller.number));
6206  } else {
6207  bc->caller.number[0] = '\0';
6208  bc->caller.presentation = 0;/* Allowed */
6209  bc->caller.screening = 0;/* Unscreened */
6212  }
6213 
6214  misdn_cfg_get(bc->port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
6215  if (0 <= number_type) {
6216  /* Force us to send in SETUP message */
6217  bc->caller.number_type = number_type;
6219  }
6220  debug_numtype(bc->port, bc->caller.number_type, "LTON");
6221  }
6222 }
static int ast_to_misdn_pres(int presentation)
Definition: chan_misdn.c:2117
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
void debug_numtype(int port, int numtype, char *type)
Definition: chan_misdn.c:5822
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
char * str
Subscriber name (Malloced)
Definition: channel.h:214
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
static int ast_to_misdn_screen(int screening)
Definition: chan_misdn.c:2214
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:317
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
Definition: chan_misdn.c:1888
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
Definition: chan_misdn.c:2014
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int misdn_hangup ( struct ast_channel ast)
static

Definition at line 7043 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_copy_string(), ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_RESERVED, chan_list::bc, ast_channel::caller, misdn_bchannel::cause, chan_list_unref, chan_misdn_log(), ast_channel::context, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, ast_channel::exten, ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, ast_party_caller::id, INFO_PI_INBAND_AVAILABLE, chan_list::l3id, LOG_NOTICE, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_BUSY, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, misdn_chan_is_valid(), MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, misdn_get_ch_state(), MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, MISDN_INCOMING_SETUP, misdn_lib_find_held_bc(), misdn_lib_release(), misdn_lib_send_event(), MISDN_NOTHING, MISDN_PROCEEDING, MISDN_PROGRESS, ast_party_id::name, ast_channel::name, chan_list::need_busy, misdn_bchannel::need_disconnect, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::need_release, misdn_bchannel::nt, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_getvar_helper(), misdn_bchannel::pid, hold_info::port, misdn_bchannel::port, misdn_bchannel::progress_indicator, release_chan(), release_chan_early(), start_bc_tones(), hold_info::state, chan_list::state, stop_bc_tones(), ast_party_name::str, ast_party_number::str, misdn_bchannel::uu, misdn_bchannel::uulen, ast_party_name::valid, ast_party_number::valid, and var.

7044 {
7045  struct chan_list *p;
7046  struct misdn_bchannel *bc;
7047  const char *var;
7048 
7049  if (!ast) {
7050  return -1;
7051  }
7052 
7053  ast_debug(1, "misdn_hangup(%s)\n", ast->name);
7054 
7055  /* Take the ast_channel's tech_pvt reference. */
7057  p = MISDN_ASTERISK_TECH_PVT(ast);
7058  if (!p) {
7060  return -1;
7061  }
7062  MISDN_ASTERISK_TECH_PVT(ast) = NULL;
7063 
7064  if (!misdn_chan_is_valid(p)) {
7066  chan_list_unref(p, "Release ast_channel reference. Was not active?");
7067  return 0;
7068  }
7069 
7070  if (p->hold.state == MISDN_HOLD_IDLE) {
7071  bc = p->bc;
7072  } else {
7074  bc = misdn_lib_find_held_bc(p->hold.port, p->l3id);
7075  if (!bc) {
7076  chan_misdn_log(4, p->hold.port,
7077  "misdn_hangup: Could not find held bc for (%s)\n", ast->name);
7078  release_chan_early(p);
7080  chan_list_unref(p, "Release ast_channel reference");
7081  return 0;
7082  }
7083  }
7084 
7085  if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) {
7086  /* between request and call */
7087  ast_debug(1, "State Reserved (or nothing) => chanIsAvail\n");
7088  release_chan_early(p);
7089  if (bc) {
7090  misdn_lib_release(bc);
7091  }
7093  chan_list_unref(p, "Release ast_channel reference");
7094  return 0;
7095  }
7096  if (!bc) {
7097  ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n",
7098  misdn_get_ch_state(p), p->l3id);
7099  release_chan_early(p);
7101  chan_list_unref(p, "Release ast_channel reference");
7102  return 0;
7103  }
7104 
7105  p->ast = NULL;
7106  p->need_hangup = 0;
7107  p->need_queue_hangup = 0;
7108  p->need_busy = 0;
7109 
7110  if (!bc->nt) {
7111  stop_bc_tones(p);
7112  }
7113 
7115 
7116  /* Channel lock is already held when we are called. */
7117  //ast_channel_lock(ast);
7118  var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE");
7119  if (!var) {
7120  var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE");
7121  }
7122  if (var) {
7123  int tmpcause;
7124 
7125  tmpcause = atoi(var);
7126  bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING;
7127  }
7128 
7129  var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER");
7130  if (var) {
7131  ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var);
7132  ast_copy_string(bc->uu, var, sizeof(bc->uu));
7133  bc->uulen = strlen(bc->uu);
7134  }
7135  //ast_channel_unlock(ast);
7136 
7137  chan_misdn_log(1, bc->port,
7138  "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n",
7139  bc->pid,
7140  ast->context,
7141  ast->exten,
7142  (ast->caller.id.name.valid && ast->caller.id.name.str)
7143  ? ast->caller.id.name.str : "",
7144  (ast->caller.id.number.valid && ast->caller.id.number.str)
7145  ? ast->caller.id.number.str : "",
7146  misdn_get_ch_state(p));
7147  chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
7148  chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
7149  chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause);
7150 
7151  switch (p->state) {
7152  case MISDN_INCOMING_SETUP:
7153  /*
7154  * This is the only place in misdn_hangup, where we
7155  * can call release_chan, else it might create a lot of trouble.
7156  */
7157  ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n");
7158  release_chan(p, bc);
7161  chan_list_unref(p, "Release ast_channel reference");
7162  return 0;
7163  case MISDN_DIALING:
7164  if (p->hold.state == MISDN_HOLD_IDLE) {
7165  start_bc_tones(p);
7167  }
7168 
7169  if (bc->need_disconnect) {
7171  }
7172  break;
7174  if (p->hold.state == MISDN_HOLD_IDLE) {
7175  start_bc_tones(p);
7177  }
7178 
7179  if (bc->need_disconnect) {
7181  }
7182  break;
7183 
7184  case MISDN_CALLING:
7185  case MISDN_ALERTING:
7186  case MISDN_PROGRESS:
7187  case MISDN_PROCEEDING:
7188  if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) {
7190  }
7191 
7192  if (bc->need_disconnect) {
7194  }
7195  break;
7196  case MISDN_CONNECTED:
7197  /* Alerting or Disconnect */
7198  if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) {
7199  start_bc_tones(p);
7202  }
7203  if (bc->need_disconnect) {
7205  }
7206  break;
7207  case MISDN_DISCONNECTED:
7208  if (bc->need_release) {
7210  }
7211  break;
7212 
7213  case MISDN_CLEANING:
7215  chan_list_unref(p, "Release ast_channel reference");
7216  return 0;
7217 
7218  case MISDN_BUSY:
7219  break;
7220  default:
7221  if (bc->nt) {
7222  bc->out_cause = -1;
7223  if (bc->need_release) {
7225  }
7226  } else {
7227  if (bc->need_disconnect) {
7229  }
7230  }
7231  break;
7232  }
7233 
7234  p->state = MISDN_CLEANING;
7235  chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast->name,
7236  misdn_get_ch_state(p));
7237 
7239  chan_list_unref(p, "Release ast_channel reference");
7240  return 0;
7241 }
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:374
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7655
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:369
int need_queue_hangup
TRUE if a hangup needs to be queued.
Definition: chan_misdn.c:364
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
int uulen
User-User information string length in uu[].
Definition: isdn_lib.h:666
char uu[256]
User-User information string.
Definition: isdn_lib.h:663
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static void release_chan_early(struct chan_list *ch)
Definition: chan_misdn.c:8488
#define LOG_WARNING
Definition: logger.h:144
static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8422
#define var
Definition: ast_expr2f.c:606
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
B channel control structure.
Definition: isdn_lib.h:324
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4071
char * str
Subscriber name (Malloced)
Definition: channel.h:214
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
#define ast_mutex_lock(a)
Definition: lock.h:155
struct misdn_bchannel * misdn_lib_find_held_bc(int port, int l3_id)
Find a held call&#39;s B channel record.
Definition: isdn_lib.c:4580
static int misdn_chan_is_valid(struct chan_list *ch)
Definition: chan_misdn.c:723
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
static int stop_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7689
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static ast_mutex_t release_lock
Definition: chan_misdn.c:295
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
void misdn_lib_release(struct misdn_bchannel *bc)
Definition: isdn_lib.c:1759
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:334
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define LOG_NOTICE
Definition: logger.h:133
Channel call record structure.
Definition: chan_misdn.c:349
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:513
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
int need_release
TRUE if RELEASE needs to be sent to clear a call.
Definition: isdn_lib.h:389
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7681
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int need_disconnect
TRUE if DISCONNECT needs to be sent to clear a call.
Definition: isdn_lib.h:386
int progress_indicator
Progress Indicator IE progress description field. Used to determine if there is an inband audio messa...
Definition: isdn_lib.h:492
int hangupcause
Definition: channel.h:849
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
#define ORG_AST
Definition: chan_misdn.c:315
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int misdn_indication ( struct ast_channel ast,
int  cond,
const void *  data,
size_t  datalen 
)
static

Definition at line 6904 of file chan_misdn.c.

References AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_STATE_BUSY, AST_STATE_RING, chan_list::bc, chan_misdn_log(), EVENT_ALERTING, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_PROGRESS, hanguptone_indicate(), chan_list::hold, chan_list::incoming_early_audio, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, MISDN_HOLD_IDLE, misdn_lib_send_event(), misdn_update_connected_line(), misdn_update_redirecting(), chan_list::mohinterpret, ast_channel::name, misdn_bchannel::nt, ORG_MISDN, chan_list::originator, misdn_bchannel::out_cause, chan_list::overlap_dial, misdn_bchannel::pid, misdn_bchannel::port, start_bc_tones(), hold_info::state, chan_list::state, and stop_indicate().

6905 {
6906  struct chan_list *p;
6907 
6908  if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
6909  ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n");
6910  return -1;
6911  }
6912 
6913  if (!p->bc) {
6914  if (p->hold.state == MISDN_HOLD_IDLE) {
6915  chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond,
6916  ast->name);
6917  ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
6918  } else {
6919  chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n",
6920  cond, ast->name);
6921  }
6922  return -1;
6923  }
6924 
6925  chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n", cond, ast->name);
6926 
6927  switch (cond) {
6928  case AST_CONTROL_BUSY:
6929  chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc->pid);
6931 
6933  if (p->state != MISDN_CONNECTED) {
6934  start_bc_tones(p);
6936  }
6937  return -1;
6938  case AST_CONTROL_RING:
6939  chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc->pid);
6940  return -1;
6941  case AST_CONTROL_RINGING:
6942  chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc->pid);
6943  switch (p->state) {
6944  case MISDN_ALERTING:
6945  chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc->pid);
6946  break;
6947  case MISDN_CONNECTED:
6948  chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc->pid);
6949  return -1;
6950  default:
6951  p->state = MISDN_ALERTING;
6952  chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid);
6954 
6955  chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc->pid);
6957 
6958  if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) {
6959  chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n");
6960  } else {
6961  return -1;
6962  }
6963  }
6964  break;
6965  case AST_CONTROL_ANSWER:
6966  chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc->pid);
6967  start_bc_tones(p);
6968  break;
6970  chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc->pid);
6971  return -1;
6972  case AST_CONTROL_OFFHOOK:
6973  chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc->pid);
6974  return -1;
6975  case AST_CONTROL_FLASH:
6976  chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc->pid);
6977  break;
6978  case AST_CONTROL_PROGRESS:
6979  chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc->pid);
6981  break;
6983  chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc->pid);
6985  break;
6987  chan_misdn_log(1, p->bc->port, " --> *\tincomplete pid:%d\n", p->bc->pid);
6988  if (!p->overlap_dial) {
6989  /* Overlapped dialing not enabled - send hangup */
6991  start_bc_tones(p);
6993 
6994  if (p->bc->nt) {
6996  }
6997  }
6998  break;
7000  chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid);
7001 
7003  start_bc_tones(p);
7005 
7006  if (p->bc->nt) {
7008  }
7009  break;
7010  case -1 :
7011  chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc->pid);
7012 
7013  stop_indicate(p);
7014 
7015  if (p->state == MISDN_CONNECTED) {
7016  start_bc_tones(p);
7017  }
7018  break;
7019  case AST_CONTROL_HOLD:
7020  ast_moh_start(ast, data, p->mohinterpret);
7021  chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc->pid);
7022  break;
7023  case AST_CONTROL_UNHOLD:
7024  ast_moh_stop(ast);
7025  chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc->pid);
7026  break;
7028  chan_misdn_log(1, p->bc->port, "* IND :\tconnected line update pid:%d\n", p->bc->pid);
7030  break;
7032  chan_misdn_log(1, p->bc->port, "* IND :\tredirecting info update pid:%d\n", p->bc->pid);
7033  misdn_update_redirecting(ast, p->bc, p->originator);
7034  break;
7035  default:
7036  chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc->pid);
7037  return -1;
7038  }
7039 
7040  return 0;
7041 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7660
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7655
static void misdn_update_redirecting(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
Definition: chan_misdn.c:6414
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:122
#define LOG_WARNING
Definition: logger.h:144
static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
Definition: chan_misdn.c:6234
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for this call.
Definition: chan_misdn.c:531
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:115
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
ast_cond_t cond
Definition: app_meetme.c:963
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
const ast_string_field name
Definition: channel.h:787
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:8040
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int incoming_early_audio
TRUE if you want to send Tone Indications to an incoming ISDN channel on a TE Port.
Definition: chan_misdn.c:404
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:317
Channel call record structure.
Definition: chan_misdn.c:349
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
static int start_bc_tones(struct chan_list *cl)
Definition: chan_misdn.c:7681
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:560
static int misdn_is_msn_valid ( int  port,
const struct misdn_party_dialing dialed 
)
static

Definition at line 9846 of file chan_misdn.c.

References ast_copy_string(), misdn_add_number_prefix(), misdn_cfg_is_msn_valid(), misdn_party_dialing::number, and misdn_party_dialing::number_type.

Referenced by cb_events().

9847 {
9848  char number[sizeof(dialed->number)];
9849 
9850  ast_copy_string(number, dialed->number, sizeof(number));
9851  misdn_add_number_prefix(port, dialed->number_type, number, sizeof(number));
9852  return misdn_cfg_is_msn_valid(port, number);
9853 }
int misdn_cfg_is_msn_valid(int port, char *msn)
Definition: misdn_config.c:694
Number structure.
Definition: app_followme.c:109
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3396
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void misdn_jb_destroy ( struct misdn_jb jb)

frees the data and destroys the given jitterbuffer struct

Definition at line 12497 of file chan_misdn.c.

References ast_free, ast_mutex_destroy, misdn_jb::mutexjb, misdn_jb::ok, and misdn_jb::samples.

Referenced by chan_list_destructor(), and config_jitterbuffer().

12498 {
12499  ast_mutex_destroy(&jb->mutexjb);
12500 
12501  ast_free(jb->ok);
12502  ast_free(jb->samples);
12503  ast_free(jb);
12504 }
ast_mutex_t mutexjb
Definition: chan_misdn.c:112
char * ok
Definition: chan_misdn.c:106
char * samples
Definition: chan_misdn.c:106
#define ast_free(a)
Definition: astmm.h:97
#define ast_mutex_destroy(a)
Definition: lock.h:154
int misdn_jb_empty ( struct misdn_jb jb,
char *  data,
int  len 
)

gets len bytes out of the jitterbuffer if available, else only the available data is returned and the return value indicates the number of data.

Definition at line 12574 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, chan_misdn_log(), len(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_buffer, misdn_jb::state_empty, and misdn_jb::wp.

Referenced by chan_misdn_jb_empty().

12575 {
12576  int i;
12577  int wp;
12578  int rp;
12579  int read = 0;
12580 
12581  ast_mutex_lock(&jb->mutexjb);
12582 
12583  rp = jb->rp;
12584  wp = jb->wp;
12585 
12586  if (jb->state_empty) {
12587  for (i = 0; i < len; i++) {
12588  if (wp == rp) {
12589  jb->rp = rp;
12590  jb->state_empty = 0;
12591 
12592  ast_mutex_unlock(&jb->mutexjb);
12593 
12594  return read;
12595  } else {
12596  if (jb->ok[rp] == 1) {
12597  data[i] = jb->samples[rp];
12598  jb->ok[rp] = 0;
12599  rp = (rp != jb->size - 1) ? rp + 1 : 0;
12600  read += 1;
12601  }
12602  }
12603  }
12604 
12605  if (wp >= rp) {
12606  jb->state_buffer = wp - rp;
12607  } else {
12608  jb->state_buffer = jb->size - rp + wp;
12609  }
12610  chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
12611 
12612  jb->rp = rp;
12613  } else {
12614  chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb);
12615  }
12616 
12617  ast_mutex_unlock(&jb->mutexjb);
12618 
12619  return read;
12620 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
ast_mutex_t mutexjb
Definition: chan_misdn.c:112
char * ok
Definition: chan_misdn.c:106
int size
Definition: chan_misdn.c:104
int state_buffer
Definition: chan_misdn.c:110
#define ast_mutex_lock(a)
Definition: lock.h:155
char * samples
Definition: chan_misdn.c:106
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_mutex_unlock(a)
Definition: lock.h:156
int state_empty
Definition: chan_misdn.c:108
int misdn_jb_fill ( struct misdn_jb jb,
const char *  data,
int  len 
)

fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun).

Definition at line 12508 of file chan_misdn.c.

References ast_mutex_lock, ast_mutex_unlock, misdn_jb::bytes_wrote, chan_misdn_log(), len(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_buffer, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.

Referenced by misdn_write().

12509 {
12510  int i;
12511  int j;
12512  int rp;
12513  int wp;
12514 
12515  if (!jb || ! data) {
12516  return 0;
12517  }
12518 
12519  ast_mutex_lock(&jb->mutexjb);
12520 
12521  wp = jb->wp;
12522  rp = jb->rp;
12523 
12524  for (i = 0; i < len; i++) {
12525  jb->samples[wp] = data[i];
12526  jb->ok[wp] = 1;
12527  wp = (wp != jb->size - 1) ? wp + 1 : 0;
12528 
12529  if (wp == jb->rp) {
12530  jb->state_full = 1;
12531  }
12532  }
12533 
12534  if (wp >= rp) {
12535  jb->state_buffer = wp - rp;
12536  } else {
12537  jb->state_buffer = jb->size - rp + wp;
12538  }
12539  chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
12540 
12541  if (jb->state_full) {
12542  jb->wp = wp;
12543 
12544  rp = wp;
12545  for (j = 0; j < jb->upper_threshold; j++) {
12546  rp = (rp != 0) ? rp - 1 : jb->size - 1;
12547  }
12548  jb->rp = rp;
12549  jb->state_full = 0;
12550  jb->state_empty = 1;
12551 
12552  ast_mutex_unlock(&jb->mutexjb);
12553 
12554  return -1;
12555  }
12556 
12557  if (!jb->state_empty) {
12558  jb->bytes_wrote += len;
12559  if (jb->bytes_wrote >= jb->upper_threshold) {
12560  jb->state_empty = 1;
12561  jb->bytes_wrote = 0;
12562  }
12563  }
12564  jb->wp = wp;
12565 
12566  ast_mutex_unlock(&jb->mutexjb);
12567 
12568  return 0;
12569 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
ast_mutex_t mutexjb
Definition: chan_misdn.c:112
char * ok
Definition: chan_misdn.c:106
int size
Definition: chan_misdn.c:104
int state_buffer
Definition: chan_misdn.c:110
#define ast_mutex_lock(a)
Definition: lock.h:155
char * samples
Definition: chan_misdn.c:106
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int upper_threshold
Definition: chan_misdn.c:105
int state_full
Definition: chan_misdn.c:109
int bytes_wrote
Definition: chan_misdn.c:111
#define ast_mutex_unlock(a)
Definition: lock.h:156
int state_empty
Definition: chan_misdn.c:108
struct misdn_jb * misdn_jb_init ( int  size,
int  upper_threshold 
)

allocates the jb-structure and initialize the elements

Definition at line 12460 of file chan_misdn.c.

References ast_calloc, ast_free, ast_mutex_init, chan_misdn_log(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::samples, misdn_jb::size, and misdn_jb::upper_threshold.

Referenced by config_jitterbuffer().

12461 {
12462  struct misdn_jb *jb;
12463 
12464  jb = ast_calloc(1, sizeof(*jb));
12465  if (!jb) {
12466  chan_misdn_log(-1, 0, "No free Mem for jb\n");
12467  return NULL;
12468  }
12469  jb->size = size;
12471  //jb->wp = 0;
12472  //jb->rp = 0;
12473  //jb->state_full = 0;
12474  //jb->state_empty = 0;
12475  //jb->bytes_wrote = 0;
12476  jb->samples = ast_calloc(size, sizeof(*jb->samples));
12477  if (!jb->samples) {
12478  ast_free(jb);
12479  chan_misdn_log(-1, 0, "No free Mem for jb->samples\n");
12480  return NULL;
12481  }
12482 
12483  jb->ok = ast_calloc(size, sizeof(*jb->ok));
12484  if (!jb->ok) {
12485  ast_free(jb->samples);
12486  ast_free(jb);
12487  chan_misdn_log(-1, 0, "No free Mem for jb->ok\n");
12488  return NULL;
12489  }
12490 
12491  ast_mutex_init(&jb->mutexjb);
12492 
12493  return jb;
12494 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
ast_mutex_t mutexjb
Definition: chan_misdn.c:112
char * ok
Definition: chan_misdn.c:106
int size
Definition: chan_misdn.c:104
char * samples
Definition: chan_misdn.c:106
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
int upper_threshold
Definition: chan_misdn.c:105
#define ast_mutex_init(pmutex)
Definition: lock.h:152
static int misdn_l1_task ( const void *  vdata)
static

Definition at line 3588 of file chan_misdn.c.

References chan_misdn_log(), and misdn_lib_isdn_l1watcher().

Referenced by load_module().

3589 {
3590  const int *data = vdata;
3591 
3592  misdn_lib_isdn_l1watcher(*data);
3593  chan_misdn_log(5, *data, "L1watcher timeout\n");
3594  return 1;
3595 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
void misdn_lib_isdn_l1watcher(int port)
Definition: isdn_lib.c:3049
static struct ast_channel * misdn_new ( struct chan_list cl,
int  state,
char *  exten,
char *  callerid,
int  format,
const char *  linkedid,
int  port,
int  c 
)
static

Definition at line 8111 of file chan_misdn.c.

References ast_party_caller::ani, chan_list::ast, ast_callerid_parse(), ast_channel_alloc(), ast_channel_set_fd(), ast_copy_string(), ast_jb_configure(), ast_log(), AST_STATE_RING, ast_strdup, ast_strlen_zero(), ast_channel::caller, chan_list_ref, chan_misdn_log(), cid_name, cid_num, ast_channel::exten, format, LOG_ERROR, MISDN_ASTERISK_TECH_PVT, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_GEN_BRIDGING, misdn_get_global_jbconf(), misdn_lib_port_is_pri(), misdn_tech_wo_bridge, ast_channel::nativeformats, ast_party_id::number, chan_list::pipe, prefformat, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, ast_party_number::str, ast_channel::tech, ast_party_number::valid, and ast_channel::writeformat.

Referenced by cb_events(), and misdn_request().

8112 {
8113  struct ast_channel *tmp;
8114  char *cid_name = NULL;
8115  char *cid_num = NULL;
8116  int chan_offset = 0;
8117  int tmp_port = misdn_cfg_get_next_port(0);
8118  int bridging;
8119 
8120  for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
8121  if (tmp_port == port) {
8122  break;
8123  }
8124  chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
8125  }
8126  if (c < 0) {
8127  c = 0;
8128  }
8129 
8130  if (callerid) {
8131  ast_callerid_parse(callerid, &cid_name, &cid_num);
8132  }
8133 
8134  tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", linkedid, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
8135  if (tmp) {
8136  chan_misdn_log(2, port, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
8137 
8138  tmp->nativeformats = prefformat;
8139 
8140  tmp->readformat = format;
8141  tmp->rawreadformat = format;
8142  tmp->writeformat = format;
8143  tmp->rawwriteformat = format;
8144 
8145  /* Link the channel and private together */
8146  chan_list_ref(chlist, "Give a reference to ast_channel");
8147  MISDN_ASTERISK_TECH_PVT(tmp) = chlist;
8148  chlist->ast = tmp;
8149 
8150  misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
8151  tmp->tech = bridging ? &misdn_tech : &misdn_tech_wo_bridge;
8152 
8153  tmp->writeformat = format;
8154  tmp->readformat = format;
8155  tmp->priority = 1;
8156 
8157  if (exten) {
8158  ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
8159  } else {
8160  chan_misdn_log(1, 0, "misdn_new: no exten given.\n");
8161  }
8162 
8163  if (!ast_strlen_zero(cid_num)) {
8164  /* Don't use ast_set_callerid() here because it will
8165  * generate a needless NewCallerID event */
8166  tmp->caller.ani.number.valid = 1;
8167  tmp->caller.ani.number.str = ast_strdup(cid_num);
8168  }
8169 
8170  if (pipe(chlist->pipe) < 0) {
8171  ast_log(LOG_ERROR, "Pipe failed\n");
8172  }
8173  ast_channel_set_fd(tmp, 0, chlist->pipe[0]);
8174 
8175  tmp->rings = (state == AST_STATE_RING) ? 1 : 0;
8176 
8178  } else {
8179  chan_misdn_log(-1, 0, "Unable to allocate channel structure\n");
8180  }
8181 
8182  return tmp;
8183 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int rings
Definition: channel.h:840
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
#define ast_strdup(a)
Definition: astmm.h:109
format_t writeformat
Definition: channel.h:854
format_t rawwriteformat
Definition: channel.h:856
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
format_t nativeformats
Definition: channel.h:852
const ast_string_field linkedid
Definition: channel.h:787
format_t rawreadformat
Definition: channel.h:855
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:157
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
struct ast_jb_conf * misdn_get_global_jbconf()
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_channel_tech misdn_tech_wo_bridge
Definition: chan_misdn.c:8066
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int glob_channel
Definition: chan_misdn.c:8085
static const char misdn_type[]
Definition: chan_misdn.c:661
static struct ast_channel_tech misdn_tech
Definition: chan_misdn.c:8047
#define chan_list_ref(obj, debug)
Definition: chan_misdn.c:343
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2631
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:158
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:616
format_t readformat
Definition: channel.h:853
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int misdn_lib_port_is_pri(int port)
Definition: isdn_lib.c:53
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
static int prefformat
Only alaw and mulaw is allowed for now.
Definition: chan_misdn.c:666
static snd_pcm_format_t format
Definition: chan_alsa.c:93
struct ast_channel_tech * tech
Definition: channel.h:743
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int misdn_overlap_dial_task ( const void *  data)
static

Definition at line 3597 of file chan_misdn.c.

References chan_list::ast, AST_CAUSE_UNALLOCATED, ast_exists_extension(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), chan_list::bc, misdn_bchannel::caller, chan_misdn_log(), chan_list::context, misdn_bchannel::dialed, EVENT_DISCONNECT, ast_channel::exten, hanguptone_indicate(), MISDN_CLEANING, MISDN_DIALING, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_party_dialing::number, misdn_party_id::number, misdn_bchannel::out_cause, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv, chan_list::overlap_tv_lock, pbx_start_chan(), misdn_bchannel::port, chan_list::state, and stop_indicate().

Referenced by cb_events().

3598 {
3599  struct timeval tv_end, tv_now;
3600  int diff;
3601  struct chan_list *ch = (struct chan_list *) data;
3602  char *dad;
3603 
3604  chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
3605 
3606  if (ch->state != MISDN_WAITING4DIGS) {
3607  ch->overlap_dial_task = -1;
3608  return 0;
3609  }
3610 
3612  tv_end = ch->overlap_tv;
3614 
3615  tv_end.tv_sec += ch->overlap_dial;
3616  tv_now = ast_tvnow();
3617 
3618  diff = ast_tvdiff_ms(tv_end, tv_now);
3619  if (100 < diff) {
3620  return diff;
3621  }
3622 
3623  /* if we are 100ms near the timeout, we are satisfied.. */
3624  stop_indicate(ch);
3625 
3626  if (ast_strlen_zero(ch->bc->dialed.number)) {
3627  dad = "s";
3628  strcpy(ch->ast->exten, dad);
3629  } else {
3630  dad = ch->bc->dialed.number;
3631  }
3632 
3633  if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->caller.number)) {
3634  ch->state = MISDN_DIALING;
3635  if (pbx_start_chan(ch) < 0) {
3636  chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
3637  goto misdn_overlap_dial_task_disconnect;
3638  }
3639  } else {
3640 misdn_overlap_dial_task_disconnect:
3641  hanguptone_indicate(ch);
3643  ch->state = MISDN_CLEANING;
3645  }
3646  ch->overlap_dial_task = -1;
3647  return 0;
3648 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static int stop_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7660
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7655
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
static int pbx_start_chan(struct chan_list *ch)
Definition: chan_misdn.c:8365
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
Definition: chan_misdn.c:525
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
struct timeval overlap_tv
Overlap timer start time. Timer restarted for every digit received.
Definition: chan_misdn.c:575
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:565
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:570
Channel call record structure.
Definition: chan_misdn.c:349
int out_cause
Q.931 Cause for disconnection code (sent)
Definition: isdn_lib.h:677
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:560
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void misdn_prefix_string ( const char *  str_prefix,
char *  str_main,
size_t  size 
)
static

Definition at line 3353 of file chan_misdn.c.

Referenced by misdn_add_number_prefix().

3354 {
3355  size_t len_over;
3356  size_t len_total;
3357  size_t len_main;
3358  size_t len_prefix;
3359 
3360  len_prefix = strlen(str_prefix);
3361  if (!len_prefix) {
3362  /* There is no prefix to prepend. */
3363  return;
3364  }
3365  len_main = strlen(str_main);
3366  len_total = len_prefix + len_main;
3367  if (size <= len_total) {
3368  /* We need to truncate since the buffer is too small. */
3369  len_over = len_total + 1 - size;
3370  if (len_over <= len_main) {
3371  len_main -= len_over;
3372  } else {
3373  len_over -= len_main;
3374  len_main = 0;
3375  len_prefix -= len_over;
3376  }
3377  }
3378  if (len_main) {
3379  memmove(str_main + len_prefix, str_main, len_main);
3380  }
3381  memcpy(str_main, str_prefix, len_prefix);
3382  str_main[len_prefix + len_main] = '\0';
3383 }
static void misdn_queue_connected_line_update ( struct ast_channel ast,
const struct misdn_party_id id,
enum AST_CONNECTED_LINE_UPDATE_SOURCE  source,
char *  cid_tag 
)
static

Definition at line 6077 of file chan_misdn.c.

References ast_channel_queue_connected_line_update(), ast_party_connected_line_init(), ast_party_connected_line::id, ast_set_party_connected_line::id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), ast_party_id::number, misdn_party_id::number, ast_set_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, ast_party_number::presentation, misdn_party_id::presentation, misdn_party_id::screening, ast_party_connected_line::source, ast_party_number::str, ast_party_id::tag, and ast_party_number::valid.

Referenced by misdn_update_remote_party().

6078 {
6080  struct ast_set_party_connected_line update_connected;
6081 
6083  memset(&update_connected, 0, sizeof(update_connected));
6084  update_connected.id.number = 1;
6085  connected.id.number.valid = 1;
6086  connected.id.number.str = (char *) id->number;
6087  connected.id.number.plan = misdn_to_ast_ton(id->number_type)
6089  connected.id.number.presentation = misdn_to_ast_pres(id->presentation)
6091  connected.id.tag = cid_tag;
6092  connected.source = source;
6093  ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
6094 }
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2308
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:1972
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2089
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
Definition: channel.c:9098
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1846
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
Connected Line/Party information.
Definition: channel.h:401
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:431
static int connected
Definition: cdr_pgsql.c:57
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2182
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
static struct ast_frame* misdn_read ( struct ast_channel ast)
static

Definition at line 7319 of file chan_misdn.c.

References chan_list::ast_dsp, AST_FORMAT_ALAW, AST_FRAME_VOICE, ast_poll, chan_list::ast_rd_buf, ast_tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chan_list::bc, chan_misdn_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, chan_list::faxdetect, chan_list::faxdetect_timeout, chan_list::faxdetect_tv, chan_list::faxhandled, chan_list::frame, ast_frame::frametype, chan_list::hold, len(), ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, MISDN_HOLD_IDLE, ast_frame::offset, chan_list::pipe, misdn_bchannel::port, process_ast_dsp(), ast_frame::ptr, ast_frame::samples, ast_frame::src, hold_info::state, and ast_frame::subclass.

7320 {
7321  struct chan_list *tmp;
7322  int len, t;
7323  struct pollfd pfd = { .fd = -1, .events = POLLIN };
7324 
7325  if (!ast) {
7326  chan_misdn_log(1, 0, "misdn_read called without ast\n");
7327  return NULL;
7328  }
7329  if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
7330  chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n");
7331  return NULL;
7332  }
7333 
7334  if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) {
7335  chan_misdn_log(1, 0, "misdn_read called without bc\n");
7336  return NULL;
7337  }
7338 
7339  pfd.fd = tmp->pipe[0];
7340  t = ast_poll(&pfd, 1, 20);
7341 
7342  if (t < 0) {
7343  chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno));
7344  return NULL;
7345  }
7346 
7347  if (!t) {
7348  chan_misdn_log(3, tmp->bc->port, "poll() timed out\n");
7349  len = 160;
7350  } else if (pfd.revents & POLLIN) {
7351  len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
7352 
7353  if (len <= 0) {
7354  /* we hangup here, since our pipe is closed */
7355  chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
7356  return NULL;
7357  }
7358  } else {
7359  return NULL;
7360  }
7361 
7364  tmp->frame.datalen = len;
7365  tmp->frame.samples = len;
7366  tmp->frame.mallocd = 0;
7367  tmp->frame.offset = 0;
7368  tmp->frame.delivery = ast_tv(0, 0);
7369  tmp->frame.src = NULL;
7370  tmp->frame.data.ptr = tmp->ast_rd_buf;
7371 
7372  if (tmp->faxdetect && !tmp->faxhandled) {
7373  if (tmp->faxdetect_timeout) {
7374  if (ast_tvzero(tmp->faxdetect_tv)) {
7375  tmp->faxdetect_tv = ast_tvnow();
7376  chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
7377  return process_ast_dsp(tmp, &tmp->frame);
7378  } else {
7379  struct timeval tv_now = ast_tvnow();
7380  int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
7381  if (diff <= (tmp->faxdetect_timeout * 1000)) {
7382  chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n");
7383  return process_ast_dsp(tmp, &tmp->frame);
7384  } else {
7385  chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n");
7386  tmp->faxdetect = 0;
7387  return &tmp->frame;
7388  }
7389  }
7390  } else {
7391  chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n");
7392  return process_ast_dsp(tmp, &tmp->frame);
7393  }
7394  } else {
7395  if (tmp->ast_dsp) {
7396  return process_ast_dsp(tmp, &tmp->frame);
7397  } else {
7398  return &tmp->frame;
7399  }
7400  }
7401 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:456
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
union ast_frame_subclass subclass
Definition: frame.h:146
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:433
char ast_rd_buf[4096]
Read buffer for inbound audio from pipe[0].
Definition: chan_misdn.c:421
int offset
Definition: frame.h:156
void * ptr
Definition: frame.h:160
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
Definition: chan_misdn.c:416
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
Definition: chan_misdn.c:440
struct ast_frame frame
Inbound audio frame returned by misdn_read().
Definition: chan_misdn.c:426
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
format_t codec
Definition: frame.h:137
static struct ast_frame * process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
Definition: chan_misdn.c:7244
const char * src
Definition: frame.h:158
#define AST_FORMAT_ALAW
Definition: frame.h:248
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
int datalen
Definition: frame.h:148
struct timeval faxdetect_tv
Starting time of fax detection with timeout when nonzero.
Definition: chan_misdn.c:445
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int errno
Channel call record structure.
Definition: chan_misdn.c:349
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
struct timeval delivery
Definition: frame.h:162
int mallocd
Definition: frame.h:152
int faxhandled
TRUE if a fax has been detected.
Definition: chan_misdn.c:450
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
enum ast_frame_type frametype
Definition: frame.h:144
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
union ast_frame::@172 data
int samples
Definition: frame.h:150
static struct ast_channel* misdn_request ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  cause 
)
static

Definition at line 7772 of file chan_misdn.c.

References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), chan_list::bc, BUFFERSIZE, chan_list_init(), chan_list_unref, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, cl_queue_chan(), misdn_bchannel::dec, ext, get_robin_position(), ast_channel::linkedid, LOG_ERROR, LOG_WARNING, METHOD_ROUND_ROBIN, METHOD_STANDARD_DEC, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), MISDN_CFG_GROUPNAME, misdn_cfg_is_group_method(), MISDN_CFG_PMP_L1_CHECK, misdn_lib_get_free_bc(), misdn_lib_get_maxchans(), misdn_lib_port_up(), misdn_lib_release(), misdn_new(), chan_list::need_hangup, ORG_AST, misdn_bchannel::port, robin_list::port, and read_config().

7773 {
7774  struct ast_channel *ast;
7775  char group[BUFFERSIZE + 1] = "";
7776  char dial_str[128];
7777  char *dest_cp;
7778  char *p = NULL;
7779  int channel = 0;
7780  int port = 0;
7781  struct misdn_bchannel *newbc = NULL;
7782  int dec = 0;
7783 #if defined(AST_MISDN_ENHANCEMENTS)
7784  int cc_retry_call = 0; /* TRUE if this is a call completion retry call */
7785  long record_id = -1;
7786  struct misdn_cc_record *cc_record;
7787  const char *err_msg;
7788 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7789  struct chan_list *cl;
7790 
7792  AST_APP_ARG(intf); /* interface token */
7793  AST_APP_ARG(ext); /* extension token */
7794  AST_APP_ARG(opts); /* options token */
7795  );
7796 
7797  snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data);
7798 
7799  /*
7800  * data is ---v
7801  * Dial(mISDN/g:group_name[/extension[/options]])
7802  * Dial(mISDN/port[:preselected_channel][/extension[/options]])
7803  * Dial(mISDN/cc/cc-record-id)
7804  *
7805  * The dial extension could be empty if you are using MISDN_KEYPAD
7806  * to control ISDN provider features.
7807  */
7808  dest_cp = ast_strdupa(data);
7809  AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
7810  if (!args.ext) {
7811  args.ext = "";
7812  }
7813 
7814  if (!ast_strlen_zero(args.intf)) {
7815  if (args.intf[0] == 'g' && args.intf[1] == ':') {
7816  /* We make a group call lets checkout which ports are in my group */
7817  args.intf += 2;
7818  ast_copy_string(group, args.intf, sizeof(group));
7819  chan_misdn_log(2, 0, " --> Group Call group: %s\n", group);
7820 #if defined(AST_MISDN_ENHANCEMENTS)
7821  } else if (strcmp(args.intf, "cc") == 0) {
7822  cc_retry_call = 1;
7823 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7824  } else if ((p = strchr(args.intf, ':'))) {
7825  /* we have a preselected channel */
7826  *p++ = 0;
7827  channel = atoi(p);
7828  port = atoi(args.intf);
7829  chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
7830  } else {
7831  port = atoi(args.intf);
7832  }
7833  } else {
7834  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
7835  return NULL;
7836  }
7837 
7838 #if defined(AST_MISDN_ENHANCEMENTS)
7839  if (cc_retry_call) {
7840  if (ast_strlen_zero(args.ext)) {
7841  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT cc-record-id, check extensions.conf\n", dial_str);
7842  return NULL;
7843  }
7844  if (!isdigit(*args.ext)) {
7845  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str);
7846  return NULL;
7847  }
7848  record_id = atol(args.ext);
7849 
7850  AST_LIST_LOCK(&misdn_cc_records_db);
7851  cc_record = misdn_cc_find_by_id(record_id);
7852  if (!cc_record) {
7853  AST_LIST_UNLOCK(&misdn_cc_records_db);
7854  err_msg = misdn_cc_record_not_found;
7855  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg);
7856  return NULL;
7857  }
7858  if (!cc_record->activated) {
7859  AST_LIST_UNLOCK(&misdn_cc_records_db);
7860  err_msg = "Call completion has not been activated";
7861  ast_log(LOG_WARNING, " --> ! IND : Dial(%s) %s.\n", dial_str, err_msg);
7862  return NULL;
7863  }
7864  port = cc_record->port;
7865  AST_LIST_UNLOCK(&misdn_cc_records_db);
7866  }
7867 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
7868 
7870  chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n");
7871  dec = 1;
7872  }
7873 
7874  if (!ast_strlen_zero(group)) {
7875  char cfg_group[BUFFERSIZE + 1];
7876  struct robin_list *rr = NULL;
7877 
7878  /* Group dial */
7879 
7881  chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n");
7882  rr = get_robin_position(group);
7883  }
7884 
7885  if (rr) {
7886  int port_start;
7887  int bchan_start;
7888  int port_up;
7889  int check;
7890  int maxbchans;
7891  int wraped = 0;
7892 
7893  if (!rr->port) {
7895  }
7896 
7897  if (!rr->channel) {
7898  rr->channel = 1;
7899  }
7900 
7901  bchan_start = rr->channel;
7902  port_start = rr->port;
7903  do {
7904  misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
7905  if (strcasecmp(cfg_group, group)) {
7906  wraped = 1;
7908  rr->channel = 1;
7909  continue;
7910  }
7911 
7912  misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check));
7913  port_up = misdn_lib_port_up(rr->port, check);
7914 
7915  if (!port_up) {
7916  chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n");
7918  rr->channel = 1;
7919  } else if (port_up < 0) {
7920  ast_log(LOG_WARNING, "This port (%d) is blocked\n", rr->port);
7922  rr->channel = 1;
7923  } else {
7924  chan_misdn_log(4, rr->port, "portup\n");
7925  maxbchans = misdn_lib_get_maxchans(rr->port);
7926 
7927  for (;rr->channel <= maxbchans;rr->channel++) {
7928  /* ive come full circle and can stop now */
7929  if (wraped && (rr->port == port_start) && (rr->channel == bchan_start)) {
7930  break;
7931  }
7932 
7933  chan_misdn_log(4, rr->port, "Checking channel %d\n", rr->channel);
7934 
7935  if ((newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0))) {
7936  chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
7937  rr->channel++;
7938  break;
7939  }
7940  }
7941  if (wraped && (rr->port == port_start) && (rr->channel <= bchan_start)) {
7942  break;
7943  } else if (!newbc || (rr->channel == maxbchans)) {
7945  rr->channel = 1;
7946  }
7947 
7948  }
7949  wraped = 1;
7950  } while (!newbc && (rr->port > 0));
7951  } else {
7952  for (port = misdn_cfg_get_next_port(0); port > 0;
7953  port = misdn_cfg_get_next_port(port)) {
7954  misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group));
7955 
7956  chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port);
7957  if (!strcasecmp(cfg_group, group)) {
7958  int port_up;
7959  int check;
7960 
7961  misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check));
7962  port_up = misdn_lib_port_up(port, check);
7963 
7964  chan_misdn_log(4, port, "portup:%d\n", port_up);
7965 
7966  if (port_up > 0) {
7967  newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
7968  if (newbc) {
7969  break;
7970  }
7971  }
7972  }
7973  }
7974  }
7975 
7976  /* Group dial failed ?*/
7977  if (!newbc) {
7979  "Could not Dial out on group '%s'.\n"
7980  "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
7981  "\tOr there was no free channel on none of the ports\n\n",
7982  group);
7983  return NULL;
7984  }
7985  } else {
7986  /* 'Normal' Port dial * Port dial */
7987  if (channel) {
7988  chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel);
7989  }
7990  newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
7991  if (!newbc) {
7992  ast_log(LOG_WARNING, "Could not create channel on port:%d for Dial(%s)\n", port, dial_str);
7993  return NULL;
7994  }
7995  }
7996 
7997  /* create ast_channel and link all the objects together */
7998  cl = chan_list_init(ORG_AST);
7999  if (!cl) {
8000  misdn_lib_release(newbc);
8001  ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str);
8002  return NULL;
8003  }
8004  cl->bc = newbc;
8005 
8006  ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, requestor ? requestor->linkedid : NULL, port, channel);
8007  if (!ast) {
8008  chan_list_unref(cl, "Failed to create a new channel");
8009  misdn_lib_release(newbc);
8010  ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
8011  return NULL;
8012  }
8013 
8014 #if defined(AST_MISDN_ENHANCEMENTS)
8015  cl->record_id = record_id;
8016 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
8017 
8018  /* register chan in local list */
8019  cl_queue_chan(cl);
8020 
8021  /* fill in the config into the objects */
8022  read_config(cl);
8023 
8024  /* important */
8025  cl->need_hangup = 0;
8026 
8027  chan_list_unref(cl, "Successful misdn_request()");
8028  return ast;
8029 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int read_config(struct chan_list *ch)
Definition: chan_misdn.c:5891
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:369
static void cl_queue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8304
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
B channel control structure.
Definition: isdn_lib.h:324
int misdn_cfg_is_group_method(char *group, enum misdn_cfg_method meth)
Definition: misdn_config.c:726
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
const ast_string_field linkedid
Definition: channel.h:787
const char * ext
Definition: http.c:112
int misdn_lib_get_maxchans(int port)
Definition: isdn_lib.c:137
#define BUFFERSIZE
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void misdn_lib_release(struct misdn_bchannel *bc)
Definition: isdn_lib.c:1759
int dec
TRUE if allocate higher B channels first.
Definition: isdn_lib.h:395
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int misdn_cfg_get_next_port_spin(int port)
Definition: misdn_config.c:909
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char misdn_type[]
Definition: chan_misdn.c:661
struct misdn_bchannel * misdn_lib_get_free_bc(int port, int channel, int inout, int dec)
Definition: isdn_lib.c:3205
Channel call record structure.
Definition: chan_misdn.c:349
int misdn_lib_port_up(int port, int check)
Definition: isdn_lib.c:1821
static struct chan_list * chan_list_init(int orig)
Definition: chan_misdn.c:7748
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
#define ORG_AST
Definition: chan_misdn.c:315
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
static struct robin_list * get_robin_position(char *group)
Definition: chan_misdn.c:613
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static struct ast_channel * misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, int format, const char *linkedid, int port, int c)
Definition: chan_misdn.c:8111
static int misdn_send_text ( struct ast_channel chan,
const char *  text 
)
static

Definition at line 8032 of file chan_misdn.c.

References ast_copy_string(), ast_log(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, and misdn_lib_send_event().

8033 {
8034  struct chan_list *tmp = MISDN_ASTERISK_TECH_PVT(chan);
8035 
8036  if (tmp && tmp->bc) {
8037  ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display));
8039  } else {
8040  ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
8041  return -1;
8042  }
8043 
8044  return 0;
8045 }
#define LOG_WARNING
Definition: logger.h:144
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
char * text
Definition: app_queue.c:1091
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Channel call record structure.
Definition: chan_misdn.c:349
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static int misdn_set_opt_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 12223 of file chan_misdn.c.

References ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_strdupa, ast_strlen_zero(), chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), config_jitterbuffer(), misdn_bchannel::crypt_key, misdn_bchannel::display, chan_list::dsp, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, chan_list::ignore_dtmf, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, keys, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_GEN_CRYPT_KEYS, misdn_bchannel::nodsp, misdn_bchannel::nojitter, misdn_bchannel::orig, chan_list::originator, parse(), misdn_bchannel::port, misdn_bchannel::presentation, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::set_presentation, strsep(), ast_channel::tech, misdn_bchannel::txgain, and ast_channel_tech::type.

Referenced by load_module(), and misdn_call().

12224 {
12225  struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
12226  char *tok;
12227  char *tokb;
12228  char *parse;
12229  int keyidx = 0;
12230  int rxgain = 0;
12231  int txgain = 0;
12232  int change_jitter = 0;
12233 
12234  if (strcasecmp(chan->tech->type, misdn_type)) {
12235  ast_log(LOG_WARNING, "misdn_set_opt makes sense only with %s channels!\n", misdn_type);
12236  return -1;
12237  }
12238 
12239  if (ast_strlen_zero((char *) data)) {
12240  ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
12241  return -1;
12242  }
12243 
12244  parse = ast_strdupa(data);
12245  for (tok = strtok_r(parse, ":", &tokb);
12246  tok;
12247  tok = strtok_r(NULL, ":", &tokb)) {
12248  int neglect = 0;
12249 
12250  if (tok[0] == '!') {
12251  neglect = 1;
12252  tok++;
12253  }
12254 
12255  switch(tok[0]) {
12256  case 'd' :
12257  ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display));
12258  chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display);
12259  break;
12260  case 'n':
12261  chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
12262  ch->bc->nodsp = 1;
12263  break;
12264  case 'j':
12265  chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
12266  tok++;
12267  change_jitter = 1;
12268 
12269  switch (tok[0]) {
12270  case 'b':
12271  ch->jb_len = atoi(++tok);
12272  chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len);
12273  break;
12274  case 't' :
12275  ch->jb_upper_threshold = atoi(++tok);
12276  chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold);
12277  break;
12278  case 'n':
12279  ch->bc->nojitter = 1;
12280  chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
12281  break;
12282  default:
12283  ch->jb_len = 4000;
12284  ch->jb_upper_threshold = 0;
12285  chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len);
12286  chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold);
12287  break;
12288  }
12289  break;
12290  case 'v':
12291  tok++;
12292 
12293  switch (tok[0]) {
12294  case 'r' :
12295  rxgain = atoi(++tok);
12296  if (rxgain < -8) {
12297  rxgain = -8;
12298  }
12299  if (rxgain > 8) {
12300  rxgain = 8;
12301  }
12302  ch->bc->rxgain = rxgain;
12303  chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain);
12304  break;
12305  case 't':
12306  txgain = atoi(++tok);
12307  if (txgain < -8) {
12308  txgain = -8;
12309  }
12310  if (txgain > 8) {
12311  txgain = 8;
12312  }
12313  ch->bc->txgain = txgain;
12314  chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain);
12315  break;
12316  }
12317  break;
12318  case 'c':
12319  keyidx = atoi(++tok);
12320  {
12321  char keys[4096];
12322  char *key = NULL;
12323  char *tmp = keys;
12324  int i;
12325 
12326  misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys));
12327 
12328  for (i = 0; i < keyidx; i++) {
12329  key = strsep(&tmp, ",");
12330  }
12331 
12332  if (key) {
12333  ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key));
12334  }
12335 
12336  chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key);
12337  break;
12338  }
12339  case 'e':
12340  chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
12341 
12342  if (neglect) {
12343  chan_misdn_log(1, ch->bc->port, " --> disabled\n");
12344 #ifdef MISDN_1_2
12345  *ch->bc->pipeline = 0;
12346 #else
12347  ch->bc->ec_enable = 0;
12348 #endif
12349  } else {
12350 #ifdef MISDN_1_2
12351  update_pipeline_config(ch->bc);
12352 #else
12353  ch->bc->ec_enable = 1;
12354  ch->bc->orig = ch->originator;
12355  tok++;
12356  if (*tok) {
12357  ch->bc->ec_deftaps = atoi(tok);
12358  }
12359 #endif
12360  }
12361  break;
12362  case 'h':
12363  chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
12364 
12365  if (strlen(tok) > 1 && tok[1] == '1') {
12366  chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
12367  if (!ch->bc->hdlc) {
12368  ch->bc->hdlc = 1;
12369  }
12370  }
12372  break;
12373  case 's':
12374  chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
12375  ch->bc->send_dtmf = 1;
12376  break;
12377  case 'f':
12378  chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
12379  ch->faxdetect = 1;
12381  break;
12382  case 'a':
12383  chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
12384  ch->ast_dsp = 1;
12385  break;
12386  case 'p':
12387  chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]);
12388  /* CRICH: callingpres!!! */
12389  if (strstr(tok, "allowed")) {
12390  ch->bc->presentation = 0;
12391  ch->bc->set_presentation = 1;
12392  } else if (strstr(tok, "restricted")) {
12393  ch->bc->presentation = 1;
12394  ch->bc->set_presentation = 1;
12395  } else if (strstr(tok, "not_screened")) {
12396  chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n");
12397  ch->bc->presentation = 1;
12398  ch->bc->set_presentation = 1;
12399  }
12400  break;
12401  case 'i' :
12402  chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n");
12403  ch->ignore_dtmf = 1;
12404  break;
12405  default:
12406  break;
12407  }
12408  }
12409 
12410  if (change_jitter) {
12411  config_jitterbuffer(ch);
12412  }
12413 
12414  if (ch->faxdetect || ch->ast_dsp) {
12415  if (!ch->dsp) {
12416  ch->dsp = ast_dsp_new();
12417  }
12418  if (ch->dsp) {
12420  }
12421  }
12422 
12423  if (ch->ast_dsp) {
12424  chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
12425  ch->bc->nodsp = 1;
12426  }
12427 
12428  return 0;
12429 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:456
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int jb_len
Jitterbuffer length.
Definition: chan_misdn.c:462
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:433
const char *const type
Definition: channel.h:508
char * strsep(char **str, const char *delims)
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:482
int nodsp
TRUE if we will not use jollys dsp.
Definition: isdn_lib.h:474
int txgain
Tx gain setting (range -8 to 8)
Definition: isdn_lib.h:708
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
Definition: chan_misdn.c:410
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:600
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
#define LOG_WARNING
Definition: logger.h:144
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
Definition: chan_misdn.c:440
struct ast_dsp * ast_dsp_new(void)
Definition: dsp.c:1607
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int jb_upper_threshold
Jitterbuffer upper threshold.
Definition: chan_misdn.c:468
static void config_jitterbuffer(struct chan_list *ch)
Definition: chan_misdn.c:5786
char crypt_key[255]
Blowfish encryption key string (secret)
Definition: isdn_lib.h:529
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
int set_presentation
TRUE if the user set the presentation restriction code.
Definition: isdn_lib.h:603
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
int rxgain
Rx gain setting (range -8 to 8)
Definition: isdn_lib.h:714
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
Definition: isdn_lib.h:457
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static const char misdn_type[]
Definition: chan_misdn.c:661
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1642
Channel call record structure.
Definition: chan_misdn.c:349
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
int ec_deftaps
Number of taps in the echo cancellor when enabled.
Definition: isdn_lib.h:693
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static struct keys keys
struct ast_channel_tech * tech
Definition: channel.h:743
int orig
Who originated the call (ORG_AST, ORG_MISDN)
Definition: isdn_lib.h:702
static int misdn_tasks_add ( int  timeout,
ast_sched_cb  callback,
const void *  data 
)
static

Definition at line 3573 of file chan_misdn.c.

References _misdn_tasks_add_variable().

Referenced by load_module().

3574 {
3575  return _misdn_tasks_add_variable(timeout, callback, data, 0);
3576 }
static int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
Definition: chan_misdn.c:3560
static int misdn_tasks_add_variable ( int  timeout,
ast_sched_cb  callback,
const void *  data 
)
static

Definition at line 3578 of file chan_misdn.c.

References _misdn_tasks_add_variable().

Referenced by cb_events().

3579 {
3580  return _misdn_tasks_add_variable(timeout, callback, data, 1);
3581 }
static int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
Definition: chan_misdn.c:3560
static void misdn_tasks_destroy ( void  )
static

Definition at line 3543 of file chan_misdn.c.

References cb_log, chan_misdn_log(), and sched_context_destroy().

Referenced by unload_module().

3544 {
3545  if (misdn_tasks) {
3546  chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
3547  if (pthread_cancel(misdn_tasks_thread) == 0) {
3548  cb_log(4, 0, "Joining misdn_tasks thread\n");
3549  pthread_join(misdn_tasks_thread, NULL);
3550  }
3552  }
3553 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static struct sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:642
static pthread_t misdn_tasks_thread
Definition: chan_misdn.c:643
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free&#39;s) the given sched_context structure
Definition: sched.c:267
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
static void misdn_tasks_init ( void  )
static

Definition at line 3523 of file chan_misdn.c.

References chan_misdn_log(), misdn_tasks_thread_func(), pthread_create, and sched_context_create().

Referenced by _misdn_tasks_add_variable().

3524 {
3525  sem_t blocker;
3526  int i = 5;
3527 
3528  if (sem_init(&blocker, 0, 0)) {
3529  perror("chan_misdn: Failed to initialize semaphore!");
3530  exit(1);
3531  }
3532 
3533  chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
3534 
3537 
3538  while (sem_wait(&blocker) && --i) {
3539  }
3540  sem_destroy(&blocker);
3541 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static struct sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:642
static pthread_t misdn_tasks_thread
Definition: chan_misdn.c:643
static void * misdn_tasks_thread_func(void *data)
Definition: chan_misdn.c:3497
#define pthread_create
Definition: lock.h:573
struct sched_context * sched_context_create(void)
New schedule context.
Definition: sched.c:246
static void misdn_tasks_remove ( int  task_id)
static

Definition at line 3583 of file chan_misdn.c.

References AST_SCHED_DEL.

Referenced by chan_list_destructor().

3584 {
3585  AST_SCHED_DEL(misdn_tasks, task_id);
3586 }
static struct sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:642
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
static void* misdn_tasks_thread_func ( void *  data)
static

Definition at line 3497 of file chan_misdn.c.

References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), and sighandler().

Referenced by misdn_tasks_init().

3498 {
3499  int wait;
3500  struct sigaction sa;
3501 
3502  sa.sa_handler = sighandler;
3503  sa.sa_flags = SA_NODEFER;
3504  sigemptyset(&sa.sa_mask);
3505  sigaddset(&sa.sa_mask, SIGUSR1);
3506  sigaction(SIGUSR1, &sa, NULL);
3507 
3508  sem_post((sem_t *)data);
3509 
3510  while (1) {
3511  wait = ast_sched_wait(misdn_tasks);
3512  if (wait < 0) {
3513  wait = 8000;
3514  }
3515  if (poll(NULL, 0, wait) < 0) {
3516  chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
3517  }
3519  }
3520  return NULL;
3521 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static struct sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
Definition: chan_misdn.c:642
static void sighandler(int sig)
Definition: chan_misdn.c:3493
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
Definition: sched.c:334
static void misdn_tasks_wakeup ( void  )
inlinestatic

Definition at line 3555 of file chan_misdn.c.

Referenced by _misdn_tasks_add_variable().

3556 {
3557  pthread_kill(misdn_tasks_thread, SIGUSR1);
3558 }
static pthread_t misdn_tasks_thread
Definition: chan_misdn.c:643
static int misdn_to_ast_plan ( enum mISDN_NUMBER_PLAN  number_plan)
static

Definition at line 1972 of file chan_misdn.c.

References NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, and NUMPLAN_UNKNOWN.

Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().

1973 {
1974  int ast_number_plan;
1975 
1976  switch (number_plan) {
1977  default:
1978  case NUMPLAN_UNKNOWN:
1979  ast_number_plan = NUMPLAN_UNKNOWN;
1980  break;
1981 
1982  case NUMPLAN_ISDN:
1983  ast_number_plan = NUMPLAN_ISDN;
1984  break;
1985 
1986  case NUMPLAN_DATA:
1987  ast_number_plan = NUMPLAN_DATA;
1988  break;
1989 
1990  case NUMPLAN_TELEX:
1991  ast_number_plan = NUMPLAN_TELEX;
1992  break;
1993 
1994  case NUMPLAN_NATIONAL:
1995  ast_number_plan = NUMPLAN_NATIONAL;
1996  break;
1997 
1998  case NUMPLAN_PRIVATE:
1999  ast_number_plan = NUMPLAN_PRIVATE;
2000  break;
2001  }
2002 
2003  return ast_number_plan;
2004 }
static int misdn_to_ast_pres ( int  presentation)
static

Definition at line 2089 of file chan_misdn.c.

References AST_PRES_ALLOWED, AST_PRES_RESTRICTED, and AST_PRES_UNAVAILABLE.

Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().

2090 {
2091  switch (presentation) {
2092  default:
2093  case 0:
2094  presentation = AST_PRES_ALLOWED;
2095  break;
2096 
2097  case 1:
2098  presentation = AST_PRES_RESTRICTED;
2099  break;
2100 
2101  case 2:
2102  presentation = AST_PRES_UNAVAILABLE;
2103  break;
2104  }
2105 
2106  return presentation;
2107 }
#define AST_PRES_RESTRICTED
Definition: callerid.h:325
#define AST_PRES_ALLOWED
Definition: callerid.h:324
#define AST_PRES_UNAVAILABLE
Definition: callerid.h:326
static enum AST_REDIRECTING_REASON misdn_to_ast_reason ( const enum mISDN_REDIRECTING_REASON  q931)
static

Definition at line 2286 of file chan_misdn.c.

References AST_REDIRECTING_REASON_CALL_FWD_DTE, AST_REDIRECTING_REASON_DEFLECTION, AST_REDIRECTING_REASON_NO_ANSWER, AST_REDIRECTING_REASON_OUT_OF_ORDER, AST_REDIRECTING_REASON_UNCONDITIONAL, AST_REDIRECTING_REASON_UNKNOWN, AST_REDIRECTING_REASON_USER_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD, mISDN_REDIRECTING_REASON_CALL_FWD_BUSY, mISDN_REDIRECTING_REASON_CALL_FWD_DTE, mISDN_REDIRECTING_REASON_DEFLECTION, mISDN_REDIRECTING_REASON_NO_REPLY, mISDN_REDIRECTING_REASON_OUT_OF_ORDER, and mISDN_REDIRECTING_REASON_UNKNOWN.

Referenced by misdn_copy_redirecting_to_ast().

2287 {
2288  enum AST_REDIRECTING_REASON ast;
2289 
2290  switch (q931) {
2291  default:
2294  break;
2295 
2298  break;
2299 
2302  break;
2303 
2306  break;
2307 
2310  break;
2311 
2314  break;
2315 
2318  break;
2319  }
2320 
2321  return ast;
2322 }
AST_REDIRECTING_REASON
redirecting reason codes.
Definition: callerid.h:390
static int misdn_to_ast_screen ( int  screening)
static

Definition at line 2182 of file chan_misdn.c.

References AST_PRES_NETWORK_NUMBER, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, and AST_PRES_USER_NUMBER_UNSCREENED.

Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().

2183 {
2184  switch (screening) {
2185  default:
2186  case 0:
2187  screening = AST_PRES_USER_NUMBER_UNSCREENED;
2188  break;
2189 
2190  case 1:
2192  break;
2193 
2194  case 2:
2196  break;
2197 
2198  case 3:
2199  screening = AST_PRES_NETWORK_NUMBER;
2200  break;
2201  }
2202 
2203  return screening;
2204 }
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
Definition: callerid.h:320
#define AST_PRES_NETWORK_NUMBER
Definition: callerid.h:321
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition: callerid.h:318
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition: callerid.h:319
static int misdn_to_ast_ton ( enum mISDN_NUMBER_TYPE  number_type)
static

Definition at line 1846 of file chan_misdn.c.

References NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, and NUMTYPE_UNKNOWN.

Referenced by cb_events(), misdn_copy_redirecting_to_ast(), misdn_queue_connected_line_update(), and misdn_update_caller_id().

1847 {
1848  int ast_number_type;
1849 
1850  switch (number_type) {
1851  default:
1852  case NUMTYPE_UNKNOWN:
1853  ast_number_type = NUMTYPE_UNKNOWN << 4;
1854  break;
1855 
1856  case NUMTYPE_INTERNATIONAL:
1857  ast_number_type = NUMTYPE_INTERNATIONAL << 4;
1858  break;
1859 
1860  case NUMTYPE_NATIONAL:
1861  ast_number_type = NUMTYPE_NATIONAL << 4;
1862  break;
1863 
1865  ast_number_type = NUMTYPE_NETWORK_SPECIFIC << 4;
1866  break;
1867 
1868  case NUMTYPE_SUBSCRIBER:
1869  ast_number_type = NUMTYPE_SUBSCRIBER << 4;
1870  break;
1871 
1872  case NUMTYPE_ABBREVIATED:
1873  ast_number_type = NUMTYPE_ABBREVIATED << 4;
1874  break;
1875  }
1876 
1877  return ast_number_type;
1878 }
static const char* misdn_to_str_plan ( enum mISDN_NUMBER_PLAN  number_plan)
static

Definition at line 1930 of file chan_misdn.c.

References NUMPLAN_DATA, NUMPLAN_ISDN, NUMPLAN_NATIONAL, NUMPLAN_PRIVATE, NUMPLAN_TELEX, NUMPLAN_UNKNOWN, and str.

Referenced by cb_events().

1931 {
1932  const char *str;
1933 
1934  switch (number_plan) {
1935  default:
1936  case NUMPLAN_UNKNOWN:
1937  str = "Unknown";
1938  break;
1939 
1940  case NUMPLAN_ISDN:
1941  str = "ISDN";
1942  break;
1943 
1944  case NUMPLAN_DATA:
1945  str = "Data";
1946  break;
1947 
1948  case NUMPLAN_TELEX:
1949  str = "Telex";
1950  break;
1951 
1952  case NUMPLAN_NATIONAL:
1953  str = "National";
1954  break;
1955 
1956  case NUMPLAN_PRIVATE:
1957  str = "Private";
1958  break;
1959  }
1960 
1961  return str;
1962 }
const char * str
Definition: app_jack.c:144
static const char* misdn_to_str_pres ( int  presentation)
static

Definition at line 2056 of file chan_misdn.c.

References str.

Referenced by cb_events(), and update_config().

2057 {
2058  const char *str;
2059 
2060  switch (presentation) {
2061  case 0:
2062  str = "Allowed";
2063  break;
2064 
2065  case 1:
2066  str = "Restricted";
2067  break;
2068 
2069  case 2:
2070  str = "Unavailable";
2071  break;
2072 
2073  default:
2074  str = "Unknown";
2075  break;
2076  }
2077 
2078  return str;
2079 }
const char * str
Definition: app_jack.c:144
static const char* misdn_to_str_screen ( int  screening)
static

Definition at line 2145 of file chan_misdn.c.

References str.

Referenced by cb_events(), and update_config().

2146 {
2147  const char *str;
2148 
2149  switch (screening) {
2150  case 0:
2151  str = "Unscreened";
2152  break;
2153 
2154  case 1:
2155  str = "Passed Screen";
2156  break;
2157 
2158  case 2:
2159  str = "Failed Screen";
2160  break;
2161 
2162  case 3:
2163  str = "Network Number";
2164  break;
2165 
2166  default:
2167  str = "Unknown";
2168  break;
2169  }
2170 
2171  return str;
2172 }
const char * str
Definition: app_jack.c:144
static const char* misdn_to_str_ton ( enum mISDN_NUMBER_TYPE  number_type)
static

Definition at line 1804 of file chan_misdn.c.

References NUMTYPE_ABBREVIATED, NUMTYPE_INTERNATIONAL, NUMTYPE_NATIONAL, NUMTYPE_NETWORK_SPECIFIC, NUMTYPE_SUBSCRIBER, NUMTYPE_UNKNOWN, and str.

Referenced by cb_events().

1805 {
1806  const char *str;
1807 
1808  switch (number_type) {
1809  default:
1810  case NUMTYPE_UNKNOWN:
1811  str = "Unknown";
1812  break;
1813 
1814  case NUMTYPE_INTERNATIONAL:
1815  str = "International";
1816  break;
1817 
1818  case NUMTYPE_NATIONAL:
1819  str = "National";
1820  break;
1821 
1823  str = "Network Specific";
1824  break;
1825 
1826  case NUMTYPE_SUBSCRIBER:
1827  str = "Subscriber";
1828  break;
1829 
1830  case NUMTYPE_ABBREVIATED:
1831  str = "Abbreviated";
1832  break;
1833  }
1834 
1835  return str;
1836 }
const char * str
Definition: app_jack.c:144
static void misdn_update_caller_id ( struct ast_channel ast,
const struct misdn_party_id id,
char *  cid_tag 
)
static

Definition at line 6106 of file chan_misdn.c.

References ast_party_caller::ani, ast_set_party_caller::ani, ast_channel_lock, ast_channel_set_caller_event(), ast_channel_unlock, ast_party_caller_set_init(), ast_channel::caller, ast_party_caller::id, ast_set_party_caller::id, misdn_to_ast_plan(), misdn_to_ast_pres(), misdn_to_ast_screen(), misdn_to_ast_ton(), ast_party_id::number, misdn_party_id::number, ast_set_party_id::number, misdn_party_id::number_plan, misdn_party_id::number_type, ast_party_number::plan, ast_party_number::presentation, misdn_party_id::presentation, misdn_party_id::screening, ast_party_number::str, ast_party_id::tag, and ast_party_number::valid.

Referenced by misdn_update_remote_party().

6107 {
6108  struct ast_party_caller caller;
6109  struct ast_set_party_caller update_caller;
6110 
6111  memset(&update_caller, 0, sizeof(update_caller));
6112  update_caller.id.number = 1;
6113  update_caller.ani.number = 1;
6114 
6115  ast_channel_lock(ast);
6116  ast_party_caller_set_init(&caller, &ast->caller);
6117 
6118  caller.id.number.valid = 1;
6119  caller.id.number.str = (char *) id->number;
6120  caller.id.number.plan = misdn_to_ast_ton(id->number_type)
6122  caller.id.number.presentation = misdn_to_ast_pres(id->presentation)
6124 
6125  caller.ani.number = caller.id.number;
6126 
6127  caller.id.tag = cid_tag;
6128  caller.ani.tag = cid_tag;
6129 
6130  ast_channel_set_caller_event(ast, &caller, &update_caller);
6131  ast_channel_unlock(ast);
6132 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7091
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
Definition: chan_misdn.c:1972
static int misdn_to_ast_pres(int presentation)
Definition: chan_misdn.c:2089
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
Indicate what information in ast_party_caller should be set.
Definition: channel.h:387
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
Definition: chan_misdn.c:1846
Caller Party information.
Definition: channel.h:368
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:2288
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
static int misdn_to_ast_screen(int screening)
Definition: chan_misdn.c:2182
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:288
static void misdn_update_connected_line ( struct ast_channel ast,
struct misdn_bchannel bc,
int  originator 
)
static

Definition at line 6234 of file chan_misdn.c.

References misdn_bchannel::caller, misdn_bchannel::connected, EVENT_FACILITY, EVENT_NOTIFY, misdn_bchannel::fac_out, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_get_connected_line(), misdn_lib_is_ptp(), misdn_lib_port_is_nt(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_TRANSFER_ACTIVE, misdn_bchannel::notify_description_code, ORG_MISDN, misdn_bchannel::outgoing_colp, misdn_bchannel::port, misdn_party_id::presentation, print_facility(), misdn_bchannel::redirecting, chan_list::state, misdn_party_redirecting::to, and misdn_party_redirecting::to_changed.

Referenced by misdn_indication().

6235 {
6236  struct chan_list *ch;
6237 
6239  if (originator == ORG_MISDN) {
6240  bc->redirecting.to = bc->connected;
6241  } else {
6242  bc->redirecting.to = bc->caller;
6243  }
6244  switch (bc->outgoing_colp) {
6245  case 1:/* restricted */
6246  bc->redirecting.to.presentation = 1;/* restricted */
6247  break;
6248  case 2:/* blocked */
6249  /* Don't tell the remote party that the call was transferred. */
6250  return;
6251  default:
6252  break;
6253  }
6254 
6255  ch = MISDN_ASTERISK_TECH_PVT(ast);
6256  if (ch->state == MISDN_CONNECTED
6257  || originator != ORG_MISDN) {
6258  int is_ptmp;
6259 
6260  is_ptmp = !misdn_lib_is_ptp(bc->port);
6261  if (is_ptmp) {
6262  /*
6263  * We should not send these messages to the network if we are
6264  * the CPE side since phones do not transfer calls within
6265  * themselves. Well... If you consider handing the handset to
6266  * someone else a transfer then how is the network to know?
6267  */
6268  if (!misdn_lib_port_is_nt(bc->port)) {
6269  return;
6270  }
6271  if (ch->state != MISDN_CONNECTED) {
6272  /* Send NOTIFY(Nie(transfer-active), RDNie(redirecting.to data)) */
6273  bc->redirecting.to_changed = 1;
6276 #if defined(AST_MISDN_ENHANCEMENTS)
6277  } else {
6278  /* Send FACILITY(Fie(RequestSubaddress), Nie(transfer-active), RDNie(redirecting.to data)) */
6279  bc->redirecting.to_changed = 1;
6281  bc->fac_out.Function = Fac_RequestSubaddress;
6282  bc->fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id;
6283 
6284  /* Send message */
6285  print_facility(&bc->fac_out, bc);
6287 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6288  }
6289 #if defined(AST_MISDN_ENHANCEMENTS)
6290  } else {
6291  /* Send FACILITY(Fie(EctInform(transfer-active, redirecting.to data))) */
6292  bc->fac_out.Function = Fac_EctInform;
6293  bc->fac_out.u.EctInform.InvokeID = ++misdn_invoke_id;
6294  bc->fac_out.u.EctInform.Status = 1;/* active */
6295  bc->fac_out.u.EctInform.RedirectionPresent = 1;/* Must be present when status is active */
6296  misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.EctInform.Redirection,
6297  &bc->redirecting.to);
6298 
6299  /* Send message */
6300  print_facility(&bc->fac_out, bc);
6302 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6303  }
6304  }
6305 }
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2734
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
Definition: isdn_lib.h:353
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:317
Channel call record structure.
Definition: chan_misdn.c:349
int misdn_lib_port_is_nt(int port)
Definition: isdn_lib.c:65
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
Definition: chan_misdn.c:6161
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
static void misdn_update_redirecting ( struct ast_channel ast,
struct misdn_bchannel bc,
int  originator 
)
static

Definition at line 6414 of file chan_misdn.c.

References EVENT_FACILITY, EVENT_NOTIFY, ast_channel::exten, misdn_bchannel::fac_out, match(), misdn_copy_redirecting_from_ast(), misdn_lib_is_ptp(), misdn_lib_port_is_nt(), misdn_lib_send_event(), mISDN_NOTIFY_CODE_CALL_IS_DIVERTING, misdn_bchannel::notify_description_code, misdn_party_id::number, ORG_MISDN, misdn_bchannel::outgoing_colp, misdn_bchannel::port, misdn_party_id::presentation, print_facility(), misdn_party_redirecting::reason, misdn_bchannel::redirecting, misdn_party_redirecting::to, and misdn_party_redirecting::to_changed.

Referenced by misdn_indication().

6415 {
6416  int is_ptmp;
6417 
6419  switch (bc->outgoing_colp) {
6420  case 1:/* restricted */
6421  bc->redirecting.to.presentation = 1;/* restricted */
6422  break;
6423  case 2:/* blocked */
6424  /* Don't tell the remote party that the call was redirected. */
6425  return;
6426  default:
6427  break;
6428  }
6429 
6430  if (originator != ORG_MISDN) {
6431  return;
6432  }
6433 
6434  is_ptmp = !misdn_lib_is_ptp(bc->port);
6435  if (is_ptmp) {
6436  /*
6437  * We should not send these messages to the network if we are
6438  * the CPE side since phones do not redirect calls within
6439  * themselves. Well... If you consider someone else picking up
6440  * the handset a redirection then how is the network to know?
6441  */
6442  if (!misdn_lib_port_is_nt(bc->port)) {
6443  return;
6444  }
6445  /* Send NOTIFY(call-is-diverting, redirecting.to data) */
6446  bc->redirecting.to_changed = 1;
6449 #if defined(AST_MISDN_ENHANCEMENTS)
6450  } else {
6451  int match; /* TRUE if the dialed number matches the redirecting to number */
6452 
6453  match = (strcmp(ast->exten, bc->redirecting.to.number) == 0) ? 1 : 0;
6454  if (!bc->div_leg_3_tx_pending
6455  || !match) {
6456  /* Send DivertingLegInformation1 */
6457  bc->fac_out.Function = Fac_DivertingLegInformation1;
6458  bc->fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id;
6459  bc->fac_out.u.DivertingLegInformation1.DiversionReason =
6460  misdn_to_diversion_reason(bc->redirecting.reason);
6461  bc->fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;/* notificationWithDivertedToNr */
6462  bc->fac_out.u.DivertingLegInformation1.DivertedToPresent = 1;
6463  misdn_PresentedNumberUnscreened_fill(&bc->fac_out.u.DivertingLegInformation1.DivertedTo, &bc->redirecting.to);
6464  print_facility(&bc->fac_out, bc);
6466  }
6467  bc->div_leg_3_tx_pending = 0;
6468 
6469  /* Send DivertingLegInformation3 */
6470  bc->fac_out.Function = Fac_DivertingLegInformation3;
6471  bc->fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6472  bc->fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6473  bc->redirecting.to.presentation == 0 ? 1 : 0;
6474  print_facility(&bc->fac_out, bc);
6476 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
6477  }
6478 }
struct FacParm fac_out
Outbound FACILITY message function type and contents.
Definition: isdn_lib.h:512
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
Definition: chan_misdn.c:2734
int misdn_lib_is_ptp(int port)
Definition: isdn_lib.c:128
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ORG_MISDN
Definition: chan_misdn.c:317
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
Definition: chan_misdn.c:6316
int misdn_lib_port_is_nt(int port)
Definition: isdn_lib.c:65
int to_changed
TRUE if the redirecting.to information has changed.
Definition: isdn_lib.h:319
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
Definition: isdn_lib.h:313
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
Definition: isdn_lib.h:606
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2069
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static void misdn_update_remote_party ( struct ast_channel ast,
const struct misdn_party_id id,
enum AST_CONNECTED_LINE_UPDATE_SOURCE  source,
char *  cid_tag 
)
static

Definition at line 6145 of file chan_misdn.c.

References misdn_queue_connected_line_update(), and misdn_update_caller_id().

Referenced by cb_events(), and misdn_facility_ie_handler().

6146 {
6147  misdn_update_caller_id(ast, id, cid_tag);
6148  misdn_queue_connected_line_update(ast, id, source, cid_tag);
6149 }
static void misdn_update_caller_id(struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag)
Definition: chan_misdn.c:6106
static void misdn_queue_connected_line_update(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
Definition: chan_misdn.c:6077
static int misdn_write ( struct ast_channel ast,
struct ast_frame frame 
)
static

Definition at line 7404 of file chan_misdn.c.

References misdn_bchannel::active, misdn_bchannel::addr, ast_debug, ast_getformatname(), ast_log(), chan_list::bc, misdn_bchannel::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, ast_channel::caller, misdn_bchannel::capability, cb_log, chan_misdn_log(), ast_frame_subclass::codec, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::hold, ast_party_caller::id, chan_list::jb, misdn_bchannel::l3_id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_cap_is_speech(), misdn_get_ch_state(), MISDN_HOLD_IDLE, misdn_jb_fill(), misdn_lib_tone_generator_start(), misdn_lib_tx2misdn_frm(), misdn_bchannel::nojitter, chan_list::notxtone, ast_party_id::number, misdn_bchannel::port, ast_frame::ptr, S_COR, ast_frame::samples, ast_frame::src, hold_info::state, ast_party_number::str, ast_frame::subclass, chan_list::ts, and ast_party_number::valid.

7405 {
7406  struct chan_list *ch;
7407 
7408  if (!ast || !(ch = MISDN_ASTERISK_TECH_PVT(ast))) {
7409  return -1;
7410  }
7411 
7412  if (ch->hold.state != MISDN_HOLD_IDLE) {
7413  chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n");
7414  return 0;
7415  }
7416 
7417  if (!ch->bc) {
7418  ast_log(LOG_WARNING, "private but no bc\n");
7419  return -1;
7420  }
7421 
7422  if (ch->notxtone) {
7423  chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n");
7424  return 0;
7425  }
7426 
7427 
7428  if (!frame->subclass.codec) {
7429  chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
7430  return 0;
7431  }
7432 
7433  if (!(frame->subclass.codec & prefformat)) {
7434  chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(frame->subclass.codec));
7435  return 0;
7436  }
7437 
7438 
7439  if (!frame->samples) {
7440  chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
7441 
7442  if (!strcmp(frame->src,"ast_prod")) {
7443  chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch));
7444 
7445  if (ch->ts) {
7446  chan_misdn_log(4, ch->bc->port, "Starting Playtones\n");
7448  }
7449  return 0;
7450  }
7451 
7452  return -1;
7453  }
7454 
7455  if (!ch->bc->addr) {
7456  chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
7457  return 0;
7458  }
7459 
7460 #ifdef MISDN_DEBUG
7461  {
7462  int i;
7463  int max = 5 > frame->samples ? frame->samples : 5;
7464 
7465  ast_debug(1, "write2mISDN %p %d bytes: ", p, frame->samples);
7466 
7467  for (i = 0; i < max; i++) {
7468  ast_debug(1, "%2.2x ", ((char *) frame->data.ptr)[i]);
7469  }
7470  }
7471 #endif
7472 
7473  switch (ch->bc->bc_state) {
7474  case BCHAN_ACTIVATED:
7475  case BCHAN_BRIDGED:
7476  break;
7477  default:
7478  if (!ch->dropped_frame_cnt) {
7479  chan_misdn_log(5, ch->bc->port,
7480  "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",
7481  frame->samples, ch->bc->addr, ast->exten,
7482  S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""),
7483  misdn_get_ch_state(ch), ch->bc->bc_state, ch->bc->l3_id);
7484  }
7485 
7486  if (++ch->dropped_frame_cnt > 100) {
7487  ch->dropped_frame_cnt = 0;
7488  chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x dropped > 100 frames!\n", frame->samples, ch->bc->addr);
7489  }
7490 
7491  return 0;
7492  }
7493 
7494  chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples);
7495  if (!ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability)) {
7496  /* Buffered Transmit (triggered by read from isdn side)*/
7497  if (misdn_jb_fill(ch->jb, frame->data.ptr, frame->samples) < 0) {
7498  if (ch->bc->active) {
7499  cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n");
7500  }
7501  }
7502 
7503  } else {
7504  /* transmit without jitterbuffer */
7505  misdn_lib_tx2misdn_frm(ch->bc, frame->data.ptr, frame->samples);
7506  }
7507 
7508  return 0;
7509 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
union ast_frame_subclass subclass
Definition: frame.h:146
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
struct misdn_jb * jb
Allocated jitterbuffer controller.
Definition: chan_misdn.c:475
int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
fills the jitterbuffer with len data returns &lt; 0 if there was an error (buffer overrun).
Definition: chan_misdn.c:12508
void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
Definition: isdn_lib.c:2271
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4071
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
format_t codec
Definition: frame.h:137
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:392
int misdn_cap_is_speech(int cap)
Definition: isdn_lib.c:436
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * src
Definition: frame.h:158
int dropped_frame_cnt
Number of outgoing audio frames dropped since last debug gripe message.
Definition: chan_misdn.c:536
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int nojitter
TRUE if we will not use the jitter buffer system.
Definition: isdn_lib.h:477
int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len)
Definition: isdn_lib.c:4382
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
Definition: isdn_lib.h:429
int active
Seems to have been intended for something to do with the jitter buffer.
Definition: isdn_lib.h:537
Channel call record structure.
Definition: chan_misdn.c:349
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
Definition: chan_misdn.c:554
enum bchannel_state bc_state
Current B Channel state.
Definition: isdn_lib.h:547
static int prefformat
Only alaw and mulaw is allowed for now.
Definition: chan_misdn.c:666
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
union ast_frame::@172 data
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
int samples
Definition: frame.h:150
void(* cb_log)(int level, int port, char *tmpl,...)
Definition: isdn_lib.c:32
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int pbx_start_chan ( struct chan_list ch)
static

Channel Queue End

Definition at line 8365 of file chan_misdn.c.

References chan_list::ast, ast_pbx_start(), and chan_list::need_hangup.

Referenced by do_immediate_setup(), misdn_overlap_dial_task(), and start_pbx().

8366 {
8367  int ret = ast_pbx_start(ch->ast);
8368 
8369  ch->need_hangup = (ret >= 0) ? 0 : 1;
8370 
8371  return ret;
8372 }
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
Definition: chan_misdn.c:369
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static void print_bc_info ( int  fd,
struct chan_list help,
struct misdn_bchannel bc 
)
static

Definition at line 4136 of file chan_misdn.c.

References misdn_bchannel::active, misdn_bchannel::addr, chan_list::addr, chan_list::ast, ast_cli(), misdn_bchannel::bc_state, bc_state2str(), bearer2str(), ast_channel::caller, misdn_bchannel::capability, misdn_bchannel::channel, ast_channel::context, misdn_bchannel::display, misdn_bchannel::ec_enable, ast_channel::exten, misdn_party_redirecting::from, misdn_bchannel::holded, ast_party_caller::id, misdn_bchannel::l3_id, chan_list::l3id, misdn_get_ch_state(), ast_party_id::name, misdn_party_id::name, ast_channel::name, chan_list::norxtone, chan_list::notxtone, misdn_bchannel::nt, ast_party_id::number, misdn_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::redirecting, ast_party_name::str, ast_party_number::str, misdn_party_redirecting::to, ast_party_name::valid, and ast_party_number::valid.

Referenced by handle_cli_misdn_show_channel(), and handle_cli_misdn_show_channels().

4137 {
4138  struct ast_channel *ast = help->ast;
4139 
4140  ast_cli(fd,
4141  "* Pid:%d Port:%d Ch:%d Mode:%s Orig:%s dialed:%s\n"
4142  " --> caller:\"%s\" <%s>\n"
4143  " --> redirecting-from:\"%s\" <%s>\n"
4144  " --> redirecting-to:\"%s\" <%s>\n"
4145  " --> context:%s state:%s\n",
4146  bc->pid,
4147  bc->port,
4148  bc->channel,
4149  bc->nt ? "NT" : "TE",
4150  help->originator == ORG_AST ? "*" : "I",
4151  ast ? ast->exten : "",
4152  (ast && ast->caller.id.name.valid && ast->caller.id.name.str)
4153  ? ast->caller.id.name.str : "",
4154  (ast && ast->caller.id.number.valid && ast->caller.id.number.str)
4155  ? ast->caller.id.number.str : "",
4156  bc->redirecting.from.name,
4157  bc->redirecting.from.number,
4158  bc->redirecting.to.name,
4159  bc->redirecting.to.number,
4160  ast ? ast->context : "",
4161  misdn_get_ch_state(help));
4162  if (misdn_debug[bc->port] > 0) {
4163  ast_cli(fd,
4164  " --> astname: %s\n"
4165  " --> ch_l3id: %x\n"
4166  " --> ch_addr: %x\n"
4167  " --> bc_addr: %x\n"
4168  " --> bc_l3id: %x\n"
4169  " --> display: %s\n"
4170  " --> activated: %d\n"
4171  " --> state: %s\n"
4172  " --> capability: %s\n"
4173 #ifdef MISDN_1_2
4174  " --> pipeline: %s\n"
4175 #else
4176  " --> echo_cancel: %d\n"
4177 #endif
4178  " --> notone : rx %d tx:%d\n"
4179  " --> bc_hold: %d\n",
4180  ast ? ast->name : "",
4181  help->l3id,
4182  help->addr,
4183  bc->addr,
4184  bc->l3_id,
4185  bc->display,
4186  bc->active,
4187  bc_state2str(bc->bc_state),
4188  bearer2str(bc->capability),
4189 #ifdef MISDN_1_2
4190  bc->pipeline,
4191 #else
4192  bc->ec_enable,
4193 #endif
4194  help->norxtone, help->notxtone,
4195  bc->holded);
4196  }
4197 }
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int addr
From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid() ...
Definition: chan_misdn.c:519
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
int norxtone
Definition: chan_misdn.c:387
static const char * misdn_get_ch_state(struct chan_list *p)
Definition: chan_misdn.c:4071
char * str
Subscriber name (Malloced)
Definition: channel.h:214
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
Definition: isdn_lib.h:310
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:392
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
char display[84]
Display message that can be displayed by the user phone.
Definition: isdn_lib.h:642
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
int holded
TRUE if this channel is on hold.
Definition: isdn_lib.h:556
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
char * bc_state2str(enum bchannel_state state)
Definition: isdn_lib.c:617
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: isdn_lib.h:307
static const char * bearer2str(int cap)
Definition: chan_misdn.c:2345
static int * misdn_debug
Definition: chan_misdn.c:668
const ast_string_field name
Definition: channel.h:787
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
Definition: isdn_lib.h:358
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
Definition: isdn_lib.h:429
int active
Seems to have been intended for something to do with the jitter buffer.
Definition: isdn_lib.h:537
unsigned int l3id
From associated B channel: Layer 3 process ID.
Definition: chan_misdn.c:513
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Definition: isdn_lib.h:411
enum bchannel_state bc_state
Current B Channel state.
Definition: isdn_lib.h:547
#define ORG_AST
Definition: chan_misdn.c:315
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void print_bearer ( struct misdn_bchannel bc)
static

Definition at line 3327 of file chan_misdn.c.

References bearer2str(), misdn_bchannel::capability, chan_misdn_log(), INFO_CODEC_ALAW, INFO_CODEC_ULAW, misdn_bchannel::law, and misdn_bchannel::port.

Referenced by cb_events().

3328 {
3329  chan_misdn_log(2, bc->port, " --> Bearer: %s\n", bearer2str(bc->capability));
3330 
3331  switch(bc->law) {
3332  case INFO_CODEC_ALAW:
3333  chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
3334  break;
3335  case INFO_CODEC_ULAW:
3336  chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
3337  break;
3338  }
3339 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
static const char * bearer2str(int cap)
Definition: chan_misdn.c:2345
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
int law
Companding ALaw/uLaw encoding (INFO_CODEC_ALAW / INFO_CODEC_ULAW)
Definition: isdn_lib.h:612
static void print_facility ( const struct FacParm *  fac,
const struct misdn_bchannel bc 
)
static

Definition at line 2734 of file chan_misdn.c.

References chan_misdn_log(), and misdn_bchannel::port.

Referenced by handle_cli_misdn_send_facility(), misdn_answer(), misdn_call(), misdn_facility_exec(), misdn_facility_ie_handler(), misdn_update_connected_line(), and misdn_update_redirecting().

2735 {
2736 #if defined(AST_MISDN_ENHANCEMENTS)
2737  unsigned Index;
2738 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
2739 
2740  switch (fac->Function) {
2741 #if defined(AST_MISDN_ENHANCEMENTS)
2742  case Fac_ActivationDiversion:
2743  chan_misdn_log(1, bc->port, " --> ActivationDiversion: InvokeID:%d\n",
2744  fac->u.ActivationDiversion.InvokeID);
2745  switch (fac->u.ActivationDiversion.ComponentType) {
2746  case FacComponent_Invoke:
2747  chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n",
2748  fac->u.ActivationDiversion.Component.Invoke.Procedure,
2749  fac->u.ActivationDiversion.Component.Invoke.BasicService);
2750  chan_misdn_log(1, bc->port, " --> ForwardedTo:\n");
2751  print_facility_Address(3, &fac->u.ActivationDiversion.Component.Invoke.ForwardedTo, bc);
2752  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2753  print_facility_ServedUserNr(3, &fac->u.ActivationDiversion.Component.Invoke.ServedUser, bc);
2754  break;
2755  case FacComponent_Result:
2756  chan_misdn_log(1, bc->port, " --> Result\n");
2757  break;
2758  default:
2759  break;
2760  }
2761  break;
2762  case Fac_DeactivationDiversion:
2763  chan_misdn_log(1, bc->port, " --> DeactivationDiversion: InvokeID:%d\n",
2764  fac->u.DeactivationDiversion.InvokeID);
2765  switch (fac->u.DeactivationDiversion.ComponentType) {
2766  case FacComponent_Invoke:
2767  chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n",
2768  fac->u.DeactivationDiversion.Component.Invoke.Procedure,
2769  fac->u.DeactivationDiversion.Component.Invoke.BasicService);
2770  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2771  print_facility_ServedUserNr(3, &fac->u.DeactivationDiversion.Component.Invoke.ServedUser, bc);
2772  break;
2773  case FacComponent_Result:
2774  chan_misdn_log(1, bc->port, " --> Result\n");
2775  break;
2776  default:
2777  break;
2778  }
2779  break;
2780  case Fac_ActivationStatusNotificationDiv:
2781  chan_misdn_log(1, bc->port, " --> ActivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2782  fac->u.ActivationStatusNotificationDiv.InvokeID,
2783  fac->u.ActivationStatusNotificationDiv.Procedure,
2784  fac->u.ActivationStatusNotificationDiv.BasicService);
2785  chan_misdn_log(1, bc->port, " --> ForwardedTo:\n");
2786  print_facility_Address(2, &fac->u.ActivationStatusNotificationDiv.ForwardedTo, bc);
2787  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2788  print_facility_ServedUserNr(2, &fac->u.ActivationStatusNotificationDiv.ServedUser, bc);
2789  break;
2790  case Fac_DeactivationStatusNotificationDiv:
2791  chan_misdn_log(1, bc->port, " --> DeactivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2792  fac->u.DeactivationStatusNotificationDiv.InvokeID,
2793  fac->u.DeactivationStatusNotificationDiv.Procedure,
2794  fac->u.DeactivationStatusNotificationDiv.BasicService);
2795  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2796  print_facility_ServedUserNr(2, &fac->u.DeactivationStatusNotificationDiv.ServedUser, bc);
2797  break;
2798  case Fac_InterrogationDiversion:
2799  chan_misdn_log(1, bc->port, " --> InterrogationDiversion: InvokeID:%d\n",
2800  fac->u.InterrogationDiversion.InvokeID);
2801  switch (fac->u.InterrogationDiversion.ComponentType) {
2802  case FacComponent_Invoke:
2803  chan_misdn_log(1, bc->port, " --> Invoke: Procedure:%d BasicService:%d\n",
2804  fac->u.InterrogationDiversion.Component.Invoke.Procedure,
2805  fac->u.InterrogationDiversion.Component.Invoke.BasicService);
2806  chan_misdn_log(1, bc->port, " --> ServedUserNr:\n");
2807  print_facility_ServedUserNr(3, &fac->u.InterrogationDiversion.Component.Invoke.ServedUser, bc);
2808  break;
2809  case FacComponent_Result:
2810  chan_misdn_log(1, bc->port, " --> Result:\n");
2811  if (fac->u.InterrogationDiversion.Component.Result.NumRecords) {
2812  for (Index = 0; Index < fac->u.InterrogationDiversion.Component.Result.NumRecords; ++Index) {
2813  chan_misdn_log(1, bc->port, " --> IntResult[%d]:\n", Index);
2814  print_facility_IntResult(3, &fac->u.InterrogationDiversion.Component.Result.List[Index], bc);
2815  }
2816  }
2817  break;
2818  default:
2819  break;
2820  }
2821  break;
2822  case Fac_DiversionInformation:
2823  chan_misdn_log(1, bc->port, " --> DiversionInformation: InvokeID:%d Reason:%d BasicService:%d\n",
2824  fac->u.DiversionInformation.InvokeID,
2825  fac->u.DiversionInformation.DiversionReason,
2826  fac->u.DiversionInformation.BasicService);
2827  if (fac->u.DiversionInformation.ServedUserSubaddress.Length) {
2828  chan_misdn_log(1, bc->port, " --> ServedUserSubaddress:\n");
2829  print_facility_Subaddress(2, &fac->u.DiversionInformation.ServedUserSubaddress, bc);
2830  }
2831  if (fac->u.DiversionInformation.CallingAddressPresent) {
2832  chan_misdn_log(1, bc->port, " --> CallingAddress:\n");
2833  print_facility_PresentedAddressScreened(2, &fac->u.DiversionInformation.CallingAddress, bc);
2834  }
2835  if (fac->u.DiversionInformation.OriginalCalledPresent) {
2836  chan_misdn_log(1, bc->port, " --> OriginalCalledNr:\n");
2837  print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.OriginalCalled, bc);
2838  }
2839  if (fac->u.DiversionInformation.LastDivertingPresent) {
2840  chan_misdn_log(1, bc->port, " --> LastDivertingNr:\n");
2841  print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.LastDiverting, bc);
2842  }
2843  if (fac->u.DiversionInformation.LastDivertingReasonPresent) {
2844  chan_misdn_log(1, bc->port, " --> LastDivertingReason:%d\n", fac->u.DiversionInformation.LastDivertingReason);
2845  }
2846  if (fac->u.DiversionInformation.UserInfo.Length) {
2847  chan_misdn_log(1, bc->port, " --> UserInfo Length:%d\n", fac->u.DiversionInformation.UserInfo.Length);
2848  }
2849  break;
2850  case Fac_CallDeflection:
2851  chan_misdn_log(1, bc->port, " --> CallDeflection: InvokeID:%d\n",
2852  fac->u.CallDeflection.InvokeID);
2853  switch (fac->u.CallDeflection.ComponentType) {
2854  case FacComponent_Invoke:
2855  chan_misdn_log(1, bc->port, " --> Invoke:\n");
2856  if (fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
2857  chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n",
2858  fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser);
2859  }
2860  chan_misdn_log(1, bc->port, " --> DeflectionAddress:\n");
2861  print_facility_Address(3, &fac->u.CallDeflection.Component.Invoke.Deflection, bc);
2862  break;
2863  case FacComponent_Result:
2864  chan_misdn_log(1, bc->port, " --> Result\n");
2865  break;
2866  default:
2867  break;
2868  }
2869  break;
2870  case Fac_CallRerouteing:
2871  chan_misdn_log(1, bc->port, " --> CallRerouteing: InvokeID:%d\n",
2872  fac->u.CallRerouteing.InvokeID);
2873  switch (fac->u.CallRerouteing.ComponentType) {
2874  case FacComponent_Invoke:
2875  chan_misdn_log(1, bc->port, " --> Invoke: Reason:%d Counter:%d\n",
2876  fac->u.CallRerouteing.Component.Invoke.ReroutingReason,
2877  fac->u.CallRerouteing.Component.Invoke.ReroutingCounter);
2878  chan_misdn_log(1, bc->port, " --> CalledAddress:\n");
2879  print_facility_Address(3, &fac->u.CallRerouteing.Component.Invoke.CalledAddress, bc);
2880  print_facility_Q931_Bc_Hlc_Llc_Uu(2, &fac->u.CallRerouteing.Component.Invoke.Q931ie, bc);
2881  chan_misdn_log(1, bc->port, " --> LastReroutingNr:\n");
2882  print_facility_PresentedNumberUnscreened(3, &fac->u.CallRerouteing.Component.Invoke.LastRerouting, bc);
2883  chan_misdn_log(1, bc->port, " --> SubscriptionOption:%d\n",
2884  fac->u.CallRerouteing.Component.Invoke.SubscriptionOption);
2885  if (fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length) {
2886  chan_misdn_log(1, bc->port, " --> CallingParty:\n");
2887  print_facility_Subaddress(3, &fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress, bc);
2888  }
2889  break;
2890  case FacComponent_Result:
2891  chan_misdn_log(1, bc->port, " --> Result\n");
2892  break;
2893  default:
2894  break;
2895  }
2896  break;
2897  case Fac_InterrogateServedUserNumbers:
2898  chan_misdn_log(1, bc->port, " --> InterrogateServedUserNumbers: InvokeID:%d\n",
2899  fac->u.InterrogateServedUserNumbers.InvokeID);
2900  switch (fac->u.InterrogateServedUserNumbers.ComponentType) {
2901  case FacComponent_Invoke:
2902  chan_misdn_log(1, bc->port, " --> Invoke\n");
2903  break;
2904  case FacComponent_Result:
2905  chan_misdn_log(1, bc->port, " --> Result:\n");
2906  if (fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords) {
2907  for (Index = 0; Index < fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords; ++Index) {
2908  chan_misdn_log(1, bc->port, " --> ServedUserNr[%d]:\n", Index);
2909  print_facility_PartyNumber(3, &fac->u.InterrogateServedUserNumbers.Component.Result.List[Index], bc);
2910  }
2911  }
2912  break;
2913  default:
2914  break;
2915  }
2916  break;
2917  case Fac_DivertingLegInformation1:
2918  chan_misdn_log(1, bc->port, " --> DivertingLegInformation1: InvokeID:%d Reason:%d SubscriptionOption:%d\n",
2919  fac->u.DivertingLegInformation1.InvokeID,
2920  fac->u.DivertingLegInformation1.DiversionReason,
2921  fac->u.DivertingLegInformation1.SubscriptionOption);
2922  if (fac->u.DivertingLegInformation1.DivertedToPresent) {
2923  chan_misdn_log(1, bc->port, " --> DivertedToNr:\n");
2924  print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation1.DivertedTo, bc);
2925  }
2926  break;
2927  case Fac_DivertingLegInformation2:
2928  chan_misdn_log(1, bc->port, " --> DivertingLegInformation2: InvokeID:%d Reason:%d Count:%d\n",
2929  fac->u.DivertingLegInformation2.InvokeID,
2930  fac->u.DivertingLegInformation2.DiversionReason,
2931  fac->u.DivertingLegInformation2.DiversionCounter);
2932  if (fac->u.DivertingLegInformation2.DivertingPresent) {
2933  chan_misdn_log(1, bc->port, " --> DivertingNr:\n");
2934  print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.Diverting, bc);
2935  }
2936  if (fac->u.DivertingLegInformation2.OriginalCalledPresent) {
2937  chan_misdn_log(1, bc->port, " --> OriginalCalledNr:\n");
2938  print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.OriginalCalled, bc);
2939  }
2940  break;
2941  case Fac_DivertingLegInformation3:
2942  chan_misdn_log(1, bc->port, " --> DivertingLegInformation3: InvokeID:%d PresentationAllowed:%d\n",
2943  fac->u.DivertingLegInformation3.InvokeID,
2944  fac->u.DivertingLegInformation3.PresentationAllowedIndicator);
2945  break;
2946 
2947 #else /* !defined(AST_MISDN_ENHANCEMENTS) */
2948 
2949  case Fac_CD:
2950  chan_misdn_log(1, bc->port, " --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
2951  fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
2952  break;
2953 #endif /* !defined(AST_MISDN_ENHANCEMENTS) */
2954  case Fac_AOCDCurrency:
2955  if (fac->u.AOCDcur.chargeNotAvailable) {
2956  chan_misdn_log(1, bc->port, " --> AOCD currency: charge not available\n");
2957  } else if (fac->u.AOCDcur.freeOfCharge) {
2958  chan_misdn_log(1, bc->port, " --> AOCD currency: free of charge\n");
2959  } else if (fac->u.AOCDchu.billingId >= 0) {
2960  chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
2961  fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2962  (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
2963  } else {
2964  chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
2965  fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2966  (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
2967  }
2968  break;
2969  case Fac_AOCDChargingUnit:
2970  if (fac->u.AOCDchu.chargeNotAvailable) {
2971  chan_misdn_log(1, bc->port, " --> AOCD charging unit: charge not available\n");
2972  } else if (fac->u.AOCDchu.freeOfCharge) {
2973  chan_misdn_log(1, bc->port, " --> AOCD charging unit: free of charge\n");
2974  } else if (fac->u.AOCDchu.billingId >= 0) {
2975  chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
2976  fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
2977  } else {
2978  chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
2979  fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
2980  }
2981  break;
2982 #if defined(AST_MISDN_ENHANCEMENTS)
2983  case Fac_ERROR:
2984  chan_misdn_log(1, bc->port, " --> ERROR: InvokeID:%d, Code:0x%02x\n",
2985  fac->u.ERROR.invokeId, fac->u.ERROR.errorValue);
2986  break;
2987  case Fac_RESULT:
2988  chan_misdn_log(1, bc->port, " --> RESULT: InvokeID:%d\n",
2989  fac->u.RESULT.InvokeID);
2990  break;
2991  case Fac_REJECT:
2992  if (fac->u.REJECT.InvokeIDPresent) {
2993  chan_misdn_log(1, bc->port, " --> REJECT: InvokeID:%d, Code:0x%02x\n",
2994  fac->u.REJECT.InvokeID, fac->u.REJECT.Code);
2995  } else {
2996  chan_misdn_log(1, bc->port, " --> REJECT: Code:0x%02x\n",
2997  fac->u.REJECT.Code);
2998  }
2999  break;
3000  case Fac_EctExecute:
3001  chan_misdn_log(1, bc->port, " --> EctExecute: InvokeID:%d\n",
3002  fac->u.EctExecute.InvokeID);
3003  break;
3004  case Fac_ExplicitEctExecute:
3005  chan_misdn_log(1, bc->port, " --> ExplicitEctExecute: InvokeID:%d LinkID:%d\n",
3006  fac->u.ExplicitEctExecute.InvokeID,
3007  fac->u.ExplicitEctExecute.LinkID);
3008  break;
3009  case Fac_RequestSubaddress:
3010  chan_misdn_log(1, bc->port, " --> RequestSubaddress: InvokeID:%d\n",
3011  fac->u.RequestSubaddress.InvokeID);
3012  break;
3013  case Fac_SubaddressTransfer:
3014  chan_misdn_log(1, bc->port, " --> SubaddressTransfer: InvokeID:%d\n",
3015  fac->u.SubaddressTransfer.InvokeID);
3016  print_facility_Subaddress(1, &fac->u.SubaddressTransfer.Subaddress, bc);
3017  break;
3018  case Fac_EctLinkIdRequest:
3019  chan_misdn_log(1, bc->port, " --> EctLinkIdRequest: InvokeID:%d\n",
3020  fac->u.EctLinkIdRequest.InvokeID);
3021  switch (fac->u.EctLinkIdRequest.ComponentType) {
3022  case FacComponent_Invoke:
3023  chan_misdn_log(1, bc->port, " --> Invoke\n");
3024  break;
3025  case FacComponent_Result:
3026  chan_misdn_log(1, bc->port, " --> Result: LinkID:%d\n",
3027  fac->u.EctLinkIdRequest.Component.Result.LinkID);
3028  break;
3029  default:
3030  break;
3031  }
3032  break;
3033  case Fac_EctInform:
3034  chan_misdn_log(1, bc->port, " --> EctInform: InvokeID:%d Status:%d\n",
3035  fac->u.EctInform.InvokeID,
3036  fac->u.EctInform.Status);
3037  if (fac->u.EctInform.RedirectionPresent) {
3038  chan_misdn_log(1, bc->port, " --> Redirection Number\n");
3039  print_facility_PresentedNumberUnscreened(2, &fac->u.EctInform.Redirection, bc);
3040  }
3041  break;
3042  case Fac_EctLoopTest:
3043  chan_misdn_log(1, bc->port, " --> EctLoopTest: InvokeID:%d\n",
3044  fac->u.EctLoopTest.InvokeID);
3045  switch (fac->u.EctLoopTest.ComponentType) {
3046  case FacComponent_Invoke:
3047  chan_misdn_log(1, bc->port, " --> Invoke: CallTransferID:%d\n",
3048  fac->u.EctLoopTest.Component.Invoke.CallTransferID);
3049  break;
3050  case FacComponent_Result:
3051  chan_misdn_log(1, bc->port, " --> Result: LoopResult:%d\n",
3052  fac->u.EctLoopTest.Component.Result.LoopResult);
3053  break;
3054  default:
3055  break;
3056  }
3057  break;
3058  case Fac_StatusRequest:
3059  chan_misdn_log(1, bc->port, " --> StatusRequest: InvokeID:%d\n",
3060  fac->u.StatusRequest.InvokeID);
3061  switch (fac->u.StatusRequest.ComponentType) {
3062  case FacComponent_Invoke:
3063  chan_misdn_log(1, bc->port, " --> Invoke: Compatibility:%d\n",
3064  fac->u.StatusRequest.Component.Invoke.CompatibilityMode);
3065  break;
3066  case FacComponent_Result:
3067  chan_misdn_log(1, bc->port, " --> Result: Status:%d\n",
3068  fac->u.StatusRequest.Component.Result.Status);
3069  break;
3070  default:
3071  break;
3072  }
3073  break;
3074  case Fac_CallInfoRetain:
3075  chan_misdn_log(1, bc->port, " --> CallInfoRetain: InvokeID:%d, LinkageID:%d\n",
3076  fac->u.CallInfoRetain.InvokeID, fac->u.CallInfoRetain.CallLinkageID);
3077  break;
3078  case Fac_CCBSDeactivate:
3079  chan_misdn_log(1, bc->port, " --> CCBSDeactivate: InvokeID:%d\n",
3080  fac->u.CCBSDeactivate.InvokeID);
3081  switch (fac->u.CCBSDeactivate.ComponentType) {
3082  case FacComponent_Invoke:
3083  chan_misdn_log(1, bc->port, " --> Invoke: CCBSReference:%d\n",
3084  fac->u.CCBSDeactivate.Component.Invoke.CCBSReference);
3085  break;
3086  case FacComponent_Result:
3087  chan_misdn_log(1, bc->port, " --> Result\n");
3088  break;
3089  default:
3090  break;
3091  }
3092  break;
3093  case Fac_CCBSErase:
3094  chan_misdn_log(1, bc->port, " --> CCBSErase: InvokeID:%d, CCBSReference:%d RecallMode:%d, Reason:%d\n",
3095  fac->u.CCBSErase.InvokeID, fac->u.CCBSErase.CCBSReference,
3096  fac->u.CCBSErase.RecallMode, fac->u.CCBSErase.Reason);
3097  chan_misdn_log(1, bc->port, " --> AddressOfB\n");
3098  print_facility_Address(2, &fac->u.CCBSErase.AddressOfB, bc);
3099  print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSErase.Q931ie, bc);
3100  break;
3101  case Fac_CCBSRemoteUserFree:
3102  chan_misdn_log(1, bc->port, " --> CCBSRemoteUserFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3103  fac->u.CCBSRemoteUserFree.InvokeID, fac->u.CCBSRemoteUserFree.CCBSReference,
3104  fac->u.CCBSRemoteUserFree.RecallMode);
3105  chan_misdn_log(1, bc->port, " --> AddressOfB\n");
3106  print_facility_Address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc);
3107  print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSRemoteUserFree.Q931ie, bc);
3108  break;
3109  case Fac_CCBSCall:
3110  chan_misdn_log(1, bc->port, " --> CCBSCall: InvokeID:%d, CCBSReference:%d\n",
3111  fac->u.CCBSCall.InvokeID, fac->u.CCBSCall.CCBSReference);
3112  break;
3113  case Fac_CCBSStatusRequest:
3114  chan_misdn_log(1, bc->port, " --> CCBSStatusRequest: InvokeID:%d\n",
3115  fac->u.CCBSStatusRequest.InvokeID);
3116  switch (fac->u.CCBSStatusRequest.ComponentType) {
3117  case FacComponent_Invoke:
3118  chan_misdn_log(1, bc->port, " --> Invoke: CCBSReference:%d RecallMode:%d\n",
3119  fac->u.CCBSStatusRequest.Component.Invoke.CCBSReference,
3120  fac->u.CCBSStatusRequest.Component.Invoke.RecallMode);
3121  print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBSStatusRequest.Component.Invoke.Q931ie, bc);
3122  break;
3123  case FacComponent_Result:
3124  chan_misdn_log(1, bc->port, " --> Result: Free:%d\n",
3125  fac->u.CCBSStatusRequest.Component.Result.Free);
3126  break;
3127  default:
3128  break;
3129  }
3130  break;
3131  case Fac_CCBSBFree:
3132  chan_misdn_log(1, bc->port, " --> CCBSBFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3133  fac->u.CCBSBFree.InvokeID, fac->u.CCBSBFree.CCBSReference,
3134  fac->u.CCBSBFree.RecallMode);
3135  chan_misdn_log(1, bc->port, " --> AddressOfB\n");
3136  print_facility_Address(2, &fac->u.CCBSBFree.AddressOfB, bc);
3137  print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSBFree.Q931ie, bc);
3138  break;
3139  case Fac_EraseCallLinkageID:
3140  chan_misdn_log(1, bc->port, " --> EraseCallLinkageID: InvokeID:%d, LinkageID:%d\n",
3141  fac->u.EraseCallLinkageID.InvokeID, fac->u.EraseCallLinkageID.CallLinkageID);
3142  break;
3143  case Fac_CCBSStopAlerting:
3144  chan_misdn_log(1, bc->port, " --> CCBSStopAlerting: InvokeID:%d, CCBSReference:%d\n",
3145  fac->u.CCBSStopAlerting.InvokeID, fac->u.CCBSStopAlerting.CCBSReference);
3146  break;
3147  case Fac_CCBSRequest:
3148  chan_misdn_log(1, bc->port, " --> CCBSRequest: InvokeID:%d\n",
3149  fac->u.CCBSRequest.InvokeID);
3150  switch (fac->u.CCBSRequest.ComponentType) {
3151  case FacComponent_Invoke:
3152  chan_misdn_log(1, bc->port, " --> Invoke: LinkageID:%d\n",
3153  fac->u.CCBSRequest.Component.Invoke.CallLinkageID);
3154  break;
3155  case FacComponent_Result:
3156  chan_misdn_log(1, bc->port, " --> Result: CCBSReference:%d RecallMode:%d\n",
3157  fac->u.CCBSRequest.Component.Result.CCBSReference,
3158  fac->u.CCBSRequest.Component.Result.RecallMode);
3159  break;
3160  default:
3161  break;
3162  }
3163  break;
3164  case Fac_CCBSInterrogate:
3165  chan_misdn_log(1, bc->port, " --> CCBSInterrogate: InvokeID:%d\n",
3166  fac->u.CCBSInterrogate.InvokeID);
3167  switch (fac->u.CCBSInterrogate.ComponentType) {
3168  case FacComponent_Invoke:
3169  chan_misdn_log(1, bc->port, " --> Invoke\n");
3170  if (fac->u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent) {
3171  chan_misdn_log(1, bc->port, " --> CCBSReference:%d\n",
3172  fac->u.CCBSInterrogate.Component.Invoke.CCBSReference);
3173  }
3174  if (fac->u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3175  chan_misdn_log(1, bc->port, " --> AParty\n");
3176  print_facility_PartyNumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc);
3177  }
3178  break;
3179  case FacComponent_Result:
3180  chan_misdn_log(1, bc->port, " --> Result: RecallMode:%d\n",
3181  fac->u.CCBSInterrogate.Component.Result.RecallMode);
3182  if (fac->u.CCBSInterrogate.Component.Result.NumRecords) {
3183  for (Index = 0; Index < fac->u.CCBSInterrogate.Component.Result.NumRecords; ++Index) {
3184  chan_misdn_log(1, bc->port, " --> CallDetails[%d]:\n", Index);
3185  print_facility_CallInformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc);
3186  }
3187  }
3188  break;
3189  default:
3190  break;
3191  }
3192  break;
3193  case Fac_CCNRRequest:
3194  chan_misdn_log(1, bc->port, " --> CCNRRequest: InvokeID:%d\n",
3195  fac->u.CCNRRequest.InvokeID);
3196  switch (fac->u.CCNRRequest.ComponentType) {
3197  case FacComponent_Invoke:
3198  chan_misdn_log(1, bc->port, " --> Invoke: LinkageID:%d\n",
3199  fac->u.CCNRRequest.Component.Invoke.CallLinkageID);
3200  break;
3201  case FacComponent_Result:
3202  chan_misdn_log(1, bc->port, " --> Result: CCBSReference:%d RecallMode:%d\n",
3203  fac->u.CCNRRequest.Component.Result.CCBSReference,
3204  fac->u.CCNRRequest.Component.Result.RecallMode);
3205  break;
3206  default:
3207  break;
3208  }
3209  break;
3210  case Fac_CCNRInterrogate:
3211  chan_misdn_log(1, bc->port, " --> CCNRInterrogate: InvokeID:%d\n",
3212  fac->u.CCNRInterrogate.InvokeID);
3213  switch (fac->u.CCNRInterrogate.ComponentType) {
3214  case FacComponent_Invoke:
3215  chan_misdn_log(1, bc->port, " --> Invoke\n");
3216  if (fac->u.CCNRInterrogate.Component.Invoke.CCBSReferencePresent) {
3217  chan_misdn_log(1, bc->port, " --> CCBSReference:%d\n",
3218  fac->u.CCNRInterrogate.Component.Invoke.CCBSReference);
3219  }
3220  if (fac->u.CCNRInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3221  chan_misdn_log(1, bc->port, " --> AParty\n");
3222  print_facility_PartyNumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc);
3223  }
3224  break;
3225  case FacComponent_Result:
3226  chan_misdn_log(1, bc->port, " --> Result: RecallMode:%d\n",
3227  fac->u.CCNRInterrogate.Component.Result.RecallMode);
3228  if (fac->u.CCNRInterrogate.Component.Result.NumRecords) {
3229  for (Index = 0; Index < fac->u.CCNRInterrogate.Component.Result.NumRecords; ++Index) {
3230  chan_misdn_log(1, bc->port, " --> CallDetails[%d]:\n", Index);
3231  print_facility_CallInformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc);
3232  }
3233  }
3234  break;
3235  default:
3236  break;
3237  }
3238  break;
3239  case Fac_CCBS_T_Call:
3240  chan_misdn_log(1, bc->port, " --> CCBS_T_Call: InvokeID:%d\n",
3241  fac->u.CCBS_T_Call.InvokeID);
3242  break;
3243  case Fac_CCBS_T_Suspend:
3244  chan_misdn_log(1, bc->port, " --> CCBS_T_Suspend: InvokeID:%d\n",
3245  fac->u.CCBS_T_Suspend.InvokeID);
3246  break;
3247  case Fac_CCBS_T_Resume:
3248  chan_misdn_log(1, bc->port, " --> CCBS_T_Resume: InvokeID:%d\n",
3249  fac->u.CCBS_T_Resume.InvokeID);
3250  break;
3251  case Fac_CCBS_T_RemoteUserFree:
3252  chan_misdn_log(1, bc->port, " --> CCBS_T_RemoteUserFree: InvokeID:%d\n",
3253  fac->u.CCBS_T_RemoteUserFree.InvokeID);
3254  break;
3255  case Fac_CCBS_T_Available:
3256  chan_misdn_log(1, bc->port, " --> CCBS_T_Available: InvokeID:%d\n",
3257  fac->u.CCBS_T_Available.InvokeID);
3258  break;
3259  case Fac_CCBS_T_Request:
3260  chan_misdn_log(1, bc->port, " --> CCBS_T_Request: InvokeID:%d\n",
3261  fac->u.CCBS_T_Request.InvokeID);
3262  switch (fac->u.CCBS_T_Request.ComponentType) {
3263  case FacComponent_Invoke:
3264  chan_misdn_log(1, bc->port, " --> Invoke\n");
3265  chan_misdn_log(1, bc->port, " --> DestinationAddress:\n");
3266  print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Destination, bc);
3267  print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBS_T_Request.Component.Invoke.Q931ie, bc);
3268  if (fac->u.CCBS_T_Request.Component.Invoke.RetentionSupported) {
3269  chan_misdn_log(1, bc->port, " --> RetentionSupported:1\n");
3270  }
3271  if (fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3272  chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n",
3273  fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator);
3274  }
3275  if (fac->u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3276  chan_misdn_log(1, bc->port, " --> OriginatingAddress:\n");
3277  print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Originating, bc);
3278  }
3279  break;
3280  case FacComponent_Result:
3281  chan_misdn_log(1, bc->port, " --> Result: RetentionSupported:%d\n",
3282  fac->u.CCBS_T_Request.Component.Result.RetentionSupported);
3283  break;
3284  default:
3285  break;
3286  }
3287  break;
3288  case Fac_CCNR_T_Request:
3289  chan_misdn_log(1, bc->port, " --> CCNR_T_Request: InvokeID:%d\n",
3290  fac->u.CCNR_T_Request.InvokeID);
3291  switch (fac->u.CCNR_T_Request.ComponentType) {
3292  case FacComponent_Invoke:
3293  chan_misdn_log(1, bc->port, " --> Invoke\n");
3294  chan_misdn_log(1, bc->port, " --> DestinationAddress:\n");
3295  print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Destination, bc);
3296  print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCNR_T_Request.Component.Invoke.Q931ie, bc);
3297  if (fac->u.CCNR_T_Request.Component.Invoke.RetentionSupported) {
3298  chan_misdn_log(1, bc->port, " --> RetentionSupported:1\n");
3299  }
3300  if (fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3301  chan_misdn_log(1, bc->port, " --> PresentationAllowed:%d\n",
3302  fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicator);
3303  }
3304  if (fac->u.CCNR_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3305  chan_misdn_log(1, bc->port, " --> OriginatingAddress:\n");
3306  print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Originating, bc);
3307  }
3308  break;
3309  case FacComponent_Result:
3310  chan_misdn_log(1, bc->port, " --> Result: RetentionSupported:%d\n",
3311  fac->u.CCNR_T_Request.Component.Result.RetentionSupported);
3312  break;
3313  default:
3314  break;
3315  }
3316  break;
3317 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
3318  case Fac_None:
3319  /* No facility so print nothing */
3320  break;
3321  default:
3322  chan_misdn_log(1, bc->port, " --> unknown facility\n");
3323  break;
3324  }
3325 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static struct ast_frame * process_ast_dsp ( struct chan_list tmp,
struct ast_frame frame 
)
static

Definition at line 7244 of file chan_misdn.c.

References chan_list::ast, ast_async_goto(), ast_debug, chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, ast_log(), ast_strlen_zero(), ast_verb, chan_list::bc, BUFFERSIZE, ast_channel::caller, chan_misdn_log(), context, ast_channel::context, chan_list::dsp, misdn_bchannel::ec_enable, ast_channel::exten, f, chan_list::faxdetect, chan_list::faxhandled, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, isdn_lib_stop_dtmf(), isdn_lib_update_ec(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, MISDN_CFG_FAXDETECT_CONTEXT, misdn_cfg_get(), ast_channel::name, ast_party_id::number, pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, S_COR, ast_party_number::str, ast_frame::subclass, misdn_bchannel::txgain, and ast_party_number::valid.

Referenced by misdn_read().

7245 {
7246  struct ast_frame *f;
7247 
7248  if (tmp->dsp) {
7249  f = ast_dsp_process(tmp->ast, tmp->dsp, frame);
7250  } else {
7251  chan_misdn_log(0, tmp->bc->port, "No DSP-Path found\n");
7252  return NULL;
7253  }
7254 
7255  if (!f || (f->frametype != AST_FRAME_DTMF)) {
7256  return f;
7257  }
7258 
7259  ast_debug(1, "Detected inband DTMF digit: %c\n", f->subclass.integer);
7260 
7261  if (tmp->faxdetect && (f->subclass.integer == 'f')) {
7262  /* Fax tone -- Handle and return NULL */
7263  if (!tmp->faxhandled) {
7264  struct ast_channel *ast = tmp->ast;
7265  tmp->faxhandled++;
7266  chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name);
7267  tmp->bc->rxgain = 0;
7268  isdn_lib_update_rxgain(tmp->bc);
7269  tmp->bc->txgain = 0;
7270  isdn_lib_update_txgain(tmp->bc);
7271 #ifdef MISDN_1_2
7272  *tmp->bc->pipeline = 0;
7273 #else
7274  tmp->bc->ec_enable = 0;
7275 #endif
7276  isdn_lib_update_ec(tmp->bc);
7277  isdn_lib_stop_dtmf(tmp->bc);
7278  switch (tmp->faxdetect) {
7279  case 1:
7280  if (strcmp(ast->exten, "fax")) {
7281  char *context;
7282  char context_tmp[BUFFERSIZE];
7283  misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
7284  context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
7285  if (ast_exists_extension(ast, context, "fax", 1,
7286  S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
7287  ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
7288  /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
7289  pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
7290  if (ast_async_goto(ast, context, "fax", 1)) {
7291  ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
7292  }
7293  } else {
7294  ast_log(LOG_NOTICE, "Fax detected but no fax extension, context:%s exten:%s\n", context, ast->exten);
7295  }
7296  } else {
7297  ast_debug(1, "Already in a fax extension, not redirecting\n");
7298  }
7299  break;
7300  case 2:
7301  ast_verb(3, "Not redirecting %s to fax extension, nojump is set.\n", ast->name);
7302  break;
7303  default:
7304  break;
7305  }
7306  } else {
7307  ast_debug(1, "Fax already handled\n");
7308  }
7309  }
7310 
7311  if (tmp->ast_dsp && (f->subclass.integer != 'f')) {
7312  chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass.integer);
7313  }
7314 
7315  return f;
7316 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:456
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
union ast_frame_subclass subclass
Definition: frame.h:146
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1392
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:433
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:482
int txgain
Tx gain setting (range -8 to 8)
Definition: isdn_lib.h:708
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
#define AST_FRAME_DTMF
Definition: frame.h:128
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
void isdn_lib_update_rxgain(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4440
#define ast_verb(level,...)
Definition: logger.h:243
void isdn_lib_update_txgain(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4445
void isdn_lib_update_ec(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4450
#define BUFFERSIZE
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int rxgain
Rx gain setting (range -8 to 8)
Definition: isdn_lib.h:714
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define LOG_NOTICE
Definition: logger.h:133
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
static struct ast_format f[]
Definition: format_g726.c:181
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
int faxhandled
TRUE if a fax has been detected.
Definition: chan_misdn.c:450
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:8731
void isdn_lib_stop_dtmf(struct misdn_bchannel *bc)
Definition: isdn_lib.c:4462
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int read_config ( struct chan_list ch)
static

Definition at line 5891 of file chan_misdn.c.

References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, ast_callerid_parse(), ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_init, ast_print_group(), ast_string_field_set, ast_strlen_zero(), chan_list::bc, buf2, BUFFERSIZE, misdn_bchannel::caller, ast_channel::callgroup, misdn_bchannel::capability, chan_misdn_log(), cid_name, cid_num, config_jitterbuffer(), chan_list::context, ast_channel::context, debug_numtype(), misdn_bchannel::dialed, misdn_bchannel::display_connected, misdn_bchannel::display_setup, chan_list::dsp, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::early_bconnect, ast_channel::exten, chan_list::far_alerting, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, chan_list::ignore_dtmf, misdn_bchannel::incoming_cid_tag, chan_list::incoming_early_audio, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, misdn_bchannel::keypad, language, LOG_WARNING, misdn_add_number_prefix(), MISDN_CFG_ALLOWED_BEARERS, MISDN_CFG_ASTDTMF, MISDN_CFG_CALLERID, MISDN_CFG_CALLGROUP, MISDN_CFG_CONTEXT, MISDN_CFG_DIALPLAN, MISDN_CFG_DISPLAY_CONNECTED, MISDN_CFG_DISPLAY_SETUP, MISDN_CFG_EARLY_BCONNECT, MISDN_CFG_FAR_ALERTING, MISDN_CFG_FAXDETECT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_INCOMING_CALLERID_TAG, MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CFG_JITTERBUFFER, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CFG_LANGUAGE, MISDN_CFG_MUSICCLASS, MISDN_CFG_NEED_MORE_INFOS, MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CFG_NTTIMEOUT, MISDN_CFG_OUTGOING_COLP, MISDN_CFG_OVERLAP_DIAL, MISDN_CFG_PICKUPGROUP, MISDN_CFG_RXGAIN, MISDN_CFG_SENDDTMF, MISDN_CFG_TE_CHOOSE_CHANNEL, MISDN_CFG_TXGAIN, chan_list::mohinterpret, misdn_party_id::name, misdn_bchannel::need_more_infos, chan_list::noautorespond_on_setup, chan_list::nttimeout, misdn_party_dialing::number, misdn_party_id::number, misdn_party_dialing::number_plan, misdn_party_id::number_type, misdn_party_dialing::number_type, NUMPLAN_ISDN, ORG_AST, chan_list::originator, misdn_bchannel::outgoing_colp, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, ast_channel::pickupgroup, misdn_bchannel::port, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::te_choose_channel, misdn_bchannel::txgain, and update_ec_config().

Referenced by cb_events(), and misdn_request().

5892 {
5893  struct ast_channel *ast;
5894  struct misdn_bchannel *bc;
5895  int port;
5896  int hdlc = 0;
5897  char lang[BUFFERSIZE + 1];
5898  char faxdetect[BUFFERSIZE + 1];
5899  char buf[256];
5900  char buf2[256];
5901  ast_group_t pg;
5902  ast_group_t cg;
5903 
5904  if (!ch) {
5905  ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
5906  return -1;
5907  }
5908 
5909  ast = ch->ast;
5910  bc = ch->bc;
5911  if (! ast || ! bc) {
5912  ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
5913  return -1;
5914  }
5915 
5916  port = bc->port;
5917  chan_misdn_log(1, port, "read_config: Getting Config\n");
5918 
5919  misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang));
5920  ast_string_field_set(ast, language, lang);
5921 
5923 
5924  misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(bc->txgain));
5925  misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(bc->rxgain));
5926 
5928 
5929  misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf));
5930 
5931  misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
5932  if (ch->ast_dsp) {
5933  ch->ignore_dtmf = 1;
5934  }
5935 
5937  misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(ch->nttimeout));
5938 
5940 
5942 
5944 
5945  misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect));
5946 
5947  misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc));
5948  if (hdlc) {
5949  switch (bc->capability) {
5952  chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
5953  bc->hdlc = 1;
5954  break;
5955  }
5956 
5957  }
5958  /*Initialize new Jitterbuffer*/
5959  misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(ch->jb_len));
5961 
5962  config_jitterbuffer(ch);
5963 
5964  misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
5965 
5966  ast_copy_string(ast->context, ch->context, sizeof(ast->context));
5967 
5968 #ifdef MISDN_1_2
5969  update_pipeline_config(bc);
5970 #else
5971  update_ec_config(bc);
5972 #endif
5973 
5975 
5979 
5980  misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
5981  misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
5982  chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
5983  ast->pickupgroup = pg;
5984  ast->callgroup = cg;
5985 
5986  if (ch->originator == ORG_AST) {
5987  char callerid[BUFFERSIZE + 1];
5988 
5989  /* ORIGINATOR Asterisk (outgoing call) */
5990 
5992 
5993  if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
5994  ch->faxdetect = strstr(faxdetect, "nojump") ? 2 : 1;
5995  }
5996 
5997  misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid));
5998  if (!ast_strlen_zero(callerid)) {
5999  char *cid_name = NULL;
6000  char *cid_num = NULL;
6001 
6002  ast_callerid_parse(callerid, &cid_name, &cid_num);
6003  if (cid_name) {
6004  ast_copy_string(bc->caller.name, cid_name, sizeof(bc->caller.name));
6005  } else {
6006  bc->caller.name[0] = '\0';
6007  }
6008  if (cid_num) {
6009  ast_copy_string(bc->caller.number, cid_num, sizeof(bc->caller.number));
6010  } else {
6011  bc->caller.number[0] = '\0';
6012  }
6013  chan_misdn_log(1, port, " --> * Setting caller to \"%s\" <%s>\n", bc->caller.name, bc->caller.number);
6014  }
6015 
6018  debug_numtype(port, bc->dialed.number_type, "TON");
6019 
6020  ch->overlap_dial = 0;
6021  } else {
6022  /* ORIGINATOR MISDN (incoming call) */
6023 
6024  if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
6025  ch->faxdetect = (strstr(faxdetect, "nojump")) ? 2 : 1;
6026  }
6027 
6028  /* Add configured prefix to caller.number */
6030 
6031  if (ast_strlen_zero(bc->dialed.number) && !ast_strlen_zero(bc->keypad)) {
6032  ast_copy_string(bc->dialed.number, bc->keypad, sizeof(bc->dialed.number));
6033  }
6034 
6035  /* Add configured prefix to dialed.number */
6037 
6038  ast_copy_string(ast->exten, bc->dialed.number, sizeof(ast->exten));
6039 
6042  } /* ORIG MISDN END */
6043 
6045  if (!ast_strlen_zero(bc->incoming_cid_tag)) {
6046  chan_misdn_log(1, port, " --> * Setting incoming caller id tag to \"%s\"\n", bc->incoming_cid_tag);
6047  }
6048  ch->overlap_dial_task = -1;
6049 
6050  if (ch->faxdetect || ch->ast_dsp) {
6052  if (!ch->dsp) {
6053  ch->dsp = ast_dsp_new();
6054  }
6055  if (ch->dsp) {
6057  }
6058  }
6059 
6060  /* AOCD initialization */
6061  bc->AOCDtype = Fac_None;
6062 
6063  return 0;
6064 }
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
Definition: chan_misdn.c:456
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
unsigned long long ast_group_t
Definition: channel.h:175
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Definition: isdn_lib.h:647
int display_setup
Put a display ie in the SETUP message.
Definition: isdn_lib.h:585
Main Channel structure associated with a channel.
Definition: channel.h:742
int jb_len
Jitterbuffer length.
Definition: chan_misdn.c:462
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
Definition: chan_misdn.c:433
void debug_numtype(int port, int numtype, char *type)
Definition: chan_misdn.c:5822
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
Definition: isdn_lib.h:298
struct ast_dsp * dsp
Allocated DSP controller.
Definition: chan_misdn.c:482
int txgain
Tx gain setting (range -8 to 8)
Definition: isdn_lib.h:708
enum FacFunction AOCDtype
Definition: isdn_lib.h:515
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
Definition: chan_misdn.c:410
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
Definition: isdn_lib.h:348
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
Definition: chan_misdn.c:440
struct ast_dsp * ast_dsp_new(void)
Definition: dsp.c:1607
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
int jb_upper_threshold
Jitterbuffer upper threshold.
Definition: chan_misdn.c:468
B channel control structure.
Definition: isdn_lib.h:324
int outgoing_colp
Select what to do with outgoing COLP information.
Definition: isdn_lib.h:594
static void config_jitterbuffer(struct chan_list *ch)
Definition: chan_misdn.c:5786
static struct ast_threadstorage buf2
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
Definition: chan_misdn.c:525
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for this call.
Definition: chan_misdn.c:531
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:157
ast_group_t pickupgroup
Definition: channel.h:819
ast_group_t callgroup
Definition: channel.h:818
char * ast_print_group(char *buf, int buflen, ast_group_t group)
print call- and pickup groups into buffer
Definition: channel.c:8236
#define BUFFERSIZE
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
Definition: chan_misdn.c:565
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
Definition: isdn_lib.h:285
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int display_connected
Put a display ie in the CONNECT message.
Definition: isdn_lib.h:573
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:108
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
Definition: isdn_lib.h:295
int rxgain
Rx gain setting (range -8 to 8)
Definition: isdn_lib.h:714
int far_alerting
TRUE if we must do the ringback tones.
Definition: chan_misdn.c:542
char allowed_bearers[BUFFERSIZE+1]
The &quot;allowed_bearers&quot; string read in from /etc/asterisk/misdn.conf.
Definition: chan_misdn.c:353
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
Definition: isdn_lib.h:260
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
Definition: chan_misdn.c:3396
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
Definition: isdn_lib.h:457
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int incoming_early_audio
TRUE if you want to send Tone Indications to an incoming ISDN channel on a TE Port.
Definition: chan_misdn.c:404
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
Definition: chan_misdn.c:570
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1642
static int update_ec_config(struct misdn_bchannel *bc)
Definition: chan_misdn.c:5872
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:158
int need_more_infos
TRUE if we send SETUP_ACKNOWLEDGE on incoming calls anyway (instead of PROCEEDING).
Definition: isdn_lib.h:465
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
#define ORG_AST
Definition: chan_misdn.c:315
#define ast_mutex_init(pmutex)
Definition: lock.h:152
int te_choose_channel
TRUE if the TE side should choose the B channel to use.
Definition: isdn_lib.h:444
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
Definition: chan_misdn.c:560
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
Definition: chan_misdn.c:385
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
Definition: isdn_lib.h:263
int early_bconnect
TRUE if the call progress indicators can indicate an inband audio message for the user to listen to...
Definition: isdn_lib.h:449
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
int nttimeout
TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
Definition: chan_misdn.c:548
static void release_chan ( struct chan_list ch,
struct misdn_bchannel bc 
)
static

Definition at line 8422 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_channel::caller, chan_list_unref, chan_misdn_log(), cl_dequeue_chan(), ast_channel::context, DEADLOCK_AVOIDANCE, ast_channel::exten, ast_party_caller::id, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, ast_party_id::name, ast_party_id::number, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, S_COR, chan_list::state, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by cb_events(), and misdn_hangup().

8423 {
8424  struct ast_channel *ast;
8425 
8426  chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id);
8427 
8429  for (;;) {
8430  ast = ch->ast;
8431  if (!ast || !ast_channel_trylock(ast)) {
8432  break;
8433  }
8435  }
8436  if (!cl_dequeue_chan(ch)) {
8437  /* Someone already released it. */
8438  if (ast) {
8439  ast_channel_unlock(ast);
8440  }
8442  return;
8443  }
8444  ch->state = MISDN_CLEANING;
8445  ch->ast = NULL;
8446  if (ast) {
8447  struct chan_list *ast_ch;
8448 
8449  ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
8450  MISDN_ASTERISK_TECH_PVT(ast) = NULL;
8451  chan_misdn_log(1, bc->port,
8452  "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n",
8453  bc->pid,
8454  ast->context,
8455  ast->exten,
8456  S_COR(ast->caller.id.name.valid, ast->caller.id.name.str, ""),
8457  S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, ""));
8458 
8459  if (ast->_state != AST_STATE_RESERVED) {
8460  chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
8462  }
8463  ast_channel_unlock(ast);
8464  if (ast_ch) {
8465  chan_list_unref(ast_ch, "Release ast_channel reference.");
8466  }
8467  }
8468 
8469  if (ch->originator == ORG_AST) {
8470  --misdn_out_calls[bc->port];
8471  } else {
8472  --misdn_in_calls[bc->port];
8473  }
8474 
8476 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:485
static int cl_dequeue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8325
char * str
Subscriber name (Malloced)
Definition: channel.h:214
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static ast_mutex_t release_lock
Definition: chan_misdn.c:295
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
enum ast_channel_state _state
Definition: channel.h:839
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define ast_channel_unlock(chan)
Definition: channel.h:2467
Channel call record structure.
Definition: chan_misdn.c:349
static int * misdn_out_calls
Definition: chan_misdn.c:673
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
#define ORG_AST
Definition: chan_misdn.c:315
static int * misdn_in_calls
Definition: chan_misdn.c:672
#define ast_channel_trylock(chan)
Definition: channel.h:2468
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int l3_id
Layer 3 process ID.
Definition: isdn_lib.h:399
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void release_chan_early ( struct chan_list ch)
static

Definition at line 8488 of file chan_misdn.c.

References ast_channel::_state, chan_list::ast, ast_channel_trylock, ast_channel_unlock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_list_unref, cl_dequeue_chan(), DEADLOCK_AVOIDANCE, chan_list::hold, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, MISDN_HOLD_IDLE, ORG_AST, chan_list::originator, hold_info::port, hold_info::state, and chan_list::state.

Referenced by misdn_hangup().

8489 {
8490  struct ast_channel *ast;
8491 
8493  for (;;) {
8494  ast = ch->ast;
8495  if (!ast || !ast_channel_trylock(ast)) {
8496  break;
8497  }
8499  }
8500  if (!cl_dequeue_chan(ch)) {
8501  /* Someone already released it. */
8502  if (ast) {
8503  ast_channel_unlock(ast);
8504  }
8506  return;
8507  }
8508  ch->state = MISDN_CLEANING;
8509  ch->ast = NULL;
8510  if (ast) {
8511  struct chan_list *ast_ch;
8512 
8513  ast_ch = MISDN_ASTERISK_TECH_PVT(ast);
8514  MISDN_ASTERISK_TECH_PVT(ast) = NULL;
8515 
8516  if (ast->_state != AST_STATE_RESERVED) {
8518  }
8519  ast_channel_unlock(ast);
8520  if (ast_ch) {
8521  chan_list_unref(ast_ch, "Release ast_channel reference.");
8522  }
8523  }
8524 
8525  if (ch->hold.state != MISDN_HOLD_IDLE) {
8526  if (ch->originator == ORG_AST) {
8527  --misdn_out_calls[ch->hold.port];
8528  } else {
8529  --misdn_in_calls[ch->hold.port];
8530  }
8531  }
8532 
8534 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:485
static int cl_dequeue_chan(struct chan_list *chan)
Definition: chan_misdn.c:8325
struct hold_info hold
HELD channel call information.
Definition: chan_misdn.c:507
#define MISDN_ASTERISK_TECH_PVT(ast)
Definition: chan_misdn.c:655
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static ast_mutex_t release_lock
Definition: chan_misdn.c:295
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
Definition: chan_misdn.c:334
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
Definition: chan_misdn.c:379
enum ast_channel_state _state
Definition: channel.h:839
#define ast_channel_unlock(chan)
Definition: channel.h:2467
Channel call record structure.
Definition: chan_misdn.c:349
static int * misdn_out_calls
Definition: chan_misdn.c:673
enum misdn_hold_state state
Call HOLD state.
Definition: chan_misdn.c:329
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
#define ORG_AST
Definition: chan_misdn.c:315
static int * misdn_in_calls
Definition: chan_misdn.c:672
#define ast_channel_trylock(chan)
Definition: channel.h:2468
#define chan_list_unref(obj, debug)
Definition: chan_misdn.c:344
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int reload ( void  )
static

Definition at line 11396 of file chan_misdn.c.

References reload_config().

11397 {
11398  reload_config();
11399 
11400  return 0;
11401 }
static void reload_config(void)
Definition: chan_misdn.c:4092
static void reload_config ( void  )
static

Definition at line 4092 of file chan_misdn.c.

References ast_log(), free_robin_list(), LOG_WARNING, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), MISDN_GEN_DEBUG, and MISDN_GEN_TRACEFILE.

Referenced by handle_cli_misdn_reload(), and reload().

4093 {
4094  int i, cfg_debug;
4095 
4096  if (!g_config_initialized) {
4097  ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
4098  return ;
4099  }
4100 
4101  free_robin_list();
4102  misdn_cfg_reload();
4105  misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(cfg_debug));
4106 
4107  for (i = 0; i <= max_ports; i++) {
4108  misdn_debug[i] = cfg_debug;
4109  misdn_debug_only[i] = 0;
4110  }
4111 }
#define LOG_WARNING
Definition: logger.h:144
void misdn_cfg_reload(void)
static int * misdn_debug_only
Definition: chan_misdn.c:669
static int max_ports
Definition: chan_misdn.c:670
static char global_tracefile[BUFFERSIZE+1]
Definition: chan_misdn.c:99
static void free_robin_list(void)
Definition: chan_misdn.c:601
static int * misdn_debug
Definition: chan_misdn.c:668
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void misdn_cfg_update_ptp(void)
static int g_config_initialized
Definition: chan_misdn.c:101
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
static int send_cause2ast ( struct ast_channel ast,
struct misdn_bchannel bc,
struct chan_list ch 
)
static
Return values
-1if can hangup after calling.
0if cannot hangup after calling.

Definition at line 8683 of file chan_misdn.c.

References AST_CAUSE_CALL_REJECTED, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, AST_CONTROL_BUSY, ast_queue_control(), misdn_bchannel::cause, chan_misdn_log(), ast_channel::hangupcause, MISDN_BUSY, chan_list::need_busy, misdn_bchannel::pid, misdn_bchannel::port, and chan_list::state.

Referenced by hangup_chan().

8684 {
8685  int can_hangup;
8686 
8687  if (!ast) {
8688  chan_misdn_log(1, 0, "send_cause2ast: No Ast\n");
8689  return 0;
8690  }
8691  if (!bc) {
8692  chan_misdn_log(1, 0, "send_cause2ast: No BC\n");
8693  return 0;
8694  }
8695  if (!ch) {
8696  chan_misdn_log(1, 0, "send_cause2ast: No Ch\n");
8697  return 0;
8698  }
8699 
8700  ast->hangupcause = bc->cause;
8701 
8702  can_hangup = -1;
8703  switch (bc->cause) {
8704  case AST_CAUSE_UNALLOCATED:
8707  case 4: /* Send special information tone */
8710  /* Congestion Cases */
8711  /*
8712  * Not Queueing the Congestion anymore, since we want to hear
8713  * the inband message
8714  *
8715  chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1);
8716  ch->state = MISDN_BUSY;
8717 
8718  ast_queue_control(ast, AST_CONTROL_CONGESTION);
8719  */
8720  break;
8721 
8723  case AST_CAUSE_USER_BUSY:
8724  ch->state = MISDN_BUSY;
8725 
8726  if (!ch->need_busy) {
8727  chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n");
8728  break;
8729  }
8730  ch->need_busy = 0;
8731 
8732  chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1);
8734 
8735  /* The BUSY is likely to cause a hangup or the user needs to hear it. */
8736  can_hangup = 0;
8737  break;
8738  }
8739  return can_hangup;
8740 }
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
Definition: chan_misdn.c:374
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
Definition: causes.h:98
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
int pid
B channel process ID (1-5000)
Definition: isdn_lib.h:402
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
#define AST_CAUSE_NUMBER_CHANGED
Definition: causes.h:111
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int hangupcause
Definition: channel.h:849
int cause
Q.931 Cause for disconnection code (received)
Definition: isdn_lib.h:671
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
static void send_digit_to_chan ( struct chan_list cl,
char  digit 
)
static

Definition at line 3650 of file chan_misdn.c.

References chan_list::ast, ast_debug, ast_playtones_start(), and ast_channel::name.

Referenced by handle_cli_misdn_send_digit(), and misdn_digit_end().

3651 {
3652  static const char * const dtmf_tones[] = {
3653 /* *INDENT-OFF* */
3654  "!941+1336/100,!0/100", /* 0 */
3655  "!697+1209/100,!0/100", /* 1 */
3656  "!697+1336/100,!0/100", /* 2 */
3657  "!697+1477/100,!0/100", /* 3 */
3658  "!770+1209/100,!0/100", /* 4 */
3659  "!770+1336/100,!0/100", /* 5 */
3660  "!770+1477/100,!0/100", /* 6 */
3661  "!852+1209/100,!0/100", /* 7 */
3662  "!852+1336/100,!0/100", /* 8 */
3663  "!852+1477/100,!0/100", /* 9 */
3664  "!697+1633/100,!0/100", /* A */
3665  "!770+1633/100,!0/100", /* B */
3666  "!852+1633/100,!0/100", /* C */
3667  "!941+1633/100,!0/100", /* D */
3668  "!941+1209/100,!0/100", /* * */
3669  "!941+1477/100,!0/100", /* # */
3670 /* *INDENT-ON* */
3671  };
3672  struct ast_channel *chan = cl->ast;
3673 
3674  if (digit >= '0' && digit <='9') {
3675  ast_playtones_start(chan, 0, dtmf_tones[digit - '0'], 0);
3676  } else if (digit >= 'A' && digit <= 'D') {
3677  ast_playtones_start(chan, 0, dtmf_tones[digit - 'A' + 10], 0);
3678  } else if (digit == '*') {
3679  ast_playtones_start(chan, 0, dtmf_tones[14], 0);
3680  } else if (digit == '#') {
3681  ast_playtones_start(chan, 0, dtmf_tones[15], 0);
3682  } else {
3683  /* not handled */
3684  ast_debug(1, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
3685  }
3686 }
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const ast_string_field name
Definition: channel.h:787
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
Definition: indications.c:319
static void show_config_description ( int  fd,
enum misdn_cfg_elements  elem 
)
inlinestatic

Definition at line 3931 of file chan_misdn.c.

References ast_cli(), BUFFERSIZE, COLOR_BRWHITE, COLOR_YELLOW, desc, misdn_cfg_get_desc(), misdn_cfg_get_name(), MISDN_CFG_LAST, name, and term_color().

Referenced by handle_cli_misdn_show_config().

3932 {
3933  char section[BUFFERSIZE];
3934  char name[BUFFERSIZE];
3935  char desc[BUFFERSIZE];
3936  char def[BUFFERSIZE];
3937  char tmp[BUFFERSIZE];
3938 
3939  misdn_cfg_get_name(elem, tmp, sizeof(tmp));
3940  term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));
3941  misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));
3942 
3943  if (elem < MISDN_CFG_LAST) {
3944  term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));
3945  } else {
3946  term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));
3947  }
3948 
3949  if (*def) {
3950  ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc);
3951  } else {
3952  ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
3953  }
3954 }
#define COLOR_YELLOW
Definition: term.h:54
#define COLOR_BRWHITE
Definition: term.h:62
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define BUFFERSIZE
void misdn_cfg_get_name(enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:637
void misdn_cfg_get_desc(enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default)
Definition: misdn_config.c:663
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
static const char desc[]
Definition: cdr_radius.c:85
static const char name[]
static void sighandler ( int  sig)
static

Definition at line 3493 of file chan_misdn.c.

Referenced by misdn_tasks_thread_func().

3494 {
3495 }
static int start_bc_tones ( struct chan_list cl)
static

Definition at line 7681 of file chan_misdn.c.

References chan_list::bc, misdn_lib_tone_generator_stop(), chan_list::norxtone, and chan_list::notxtone.

Referenced by cb_events(), misdn_answer(), misdn_hangup(), and misdn_indication().

7682 {
7684  cl->notxtone = 0;
7685  cl->norxtone = 0;
7686  return 0;
7687 }
int norxtone
Definition: chan_misdn.c:387
void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
Definition: isdn_lib.c:2276
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:392
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static void start_pbx ( struct chan_list ch,
struct misdn_bchannel bc,
struct ast_channel chan 
)
static

Definition at line 8833 of file chan_misdn.c.

References chan_misdn_log(), EVENT_RELEASE, EVENT_RELEASE_COMPLETE, hangup_chan(), hanguptone_indicate(), misdn_lib_send_event(), misdn_bchannel::nt, pbx_start_chan(), and misdn_bchannel::port.

Referenced by cb_events().

8834 {
8835  if (pbx_start_chan(ch) < 0) {
8836  hangup_chan(ch, bc);
8837  chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
8838  if (bc->nt) {
8839  hanguptone_indicate(ch);
8841  } else {
8843  }
8844  }
8845 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static void hanguptone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7655
static int pbx_start_chan(struct chan_list *ch)
Definition: chan_misdn.c:8365
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8374
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523
static int stop_bc_tones ( struct chan_list cl)
static

Definition at line 7689 of file chan_misdn.c.

References chan_list::norxtone, and chan_list::notxtone.

Referenced by cb_events(), misdn_call(), and misdn_hangup().

7690 {
7691  if (!cl) {
7692  return -1;
7693  }
7694 
7695  cl->notxtone = 1;
7696  cl->norxtone = 1;
7697 
7698  return 0;
7699 }
int norxtone
Definition: chan_misdn.c:387
int notxtone
TRUE if we are not to generate tones (Playtones)
Definition: chan_misdn.c:392
static int stop_indicate ( struct chan_list cl)
static

Definition at line 7660 of file chan_misdn.c.

References chan_list::ast, ast_playtones_stop(), ast_tone_zone_sound_unref(), chan_list::bc, chan_misdn_log(), misdn_lib_tone_generator_stop(), misdn_bchannel::port, and chan_list::ts.

Referenced by cb_events(), misdn_answer(), misdn_indication(), and misdn_overlap_dial_task().

7661 {
7662  struct ast_channel *ast = cl->ast;
7663 
7664  if (!ast) {
7665  chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n");
7666  return -1;
7667  }
7668 
7669  chan_misdn_log(3, cl->bc->port, " --> None\n");
7671  ast_playtones_stop(ast);
7672 
7673  if (cl->ts) {
7674  cl->ts = ast_tone_zone_sound_unref(cl->ts);
7675  }
7676 
7677  return 0;
7678 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
Main Channel structure associated with a channel.
Definition: channel.h:742
void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
Definition: isdn_lib.c:2276
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
Definition: indications.c:411
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:226
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
Definition: chan_misdn.c:554
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
static int unload_module ( void  )
static

TE STUFF END

Definition at line 11138 of file chan_misdn.c.

References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free, ast_log(), ast_unregister_application(), free_robin_list(), LOG_VERBOSE, misdn_cfg_destroy(), misdn_lib_destroy(), and misdn_tasks_destroy().

Referenced by load_module().

11139 {
11140  /* First, take us out of the channel loop */
11141  ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
11142 
11144 
11145  if (!g_config_initialized) {
11146  return 0;
11147  }
11148 
11150 
11151  /* ast_unregister_application("misdn_crypt"); */
11152  ast_unregister_application("misdn_set_opt");
11153  ast_unregister_application("misdn_facility");
11154  ast_unregister_application("misdn_check_l2l1");
11155 #if defined(AST_MISDN_ENHANCEMENTS)
11156  ast_unregister_application(misdn_command_name);
11157  ast_custom_function_unregister(&misdn_cc_function);
11158 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11159 
11161 
11162  free_robin_list();
11165 
11171 
11172 #if defined(AST_MISDN_ENHANCEMENTS)
11173  misdn_cc_destroy();
11174 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
11175 
11176  return 0;
11177 }
void misdn_cfg_destroy(void)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:938
descriptor for a cli entry.
Definition: cli.h:165
static int * misdn_debug_only
Definition: chan_misdn.c:669
void misdn_lib_destroy(void)
Definition: isdn_lib.c:4285
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static void misdn_tasks_destroy(void)
Definition: chan_misdn.c:3543
static struct ast_cli_entry chan_misdn_clis[]
Definition: chan_misdn.c:5703
static void free_robin_list(void)
Definition: chan_misdn.c:601
static int * misdn_debug
Definition: chan_misdn.c:668
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_channel_tech misdn_tech
Definition: chan_misdn.c:8047
#define ast_free(a)
Definition: astmm.h:97
static int * misdn_ports
Definition: chan_misdn.c:645
static int * misdn_out_calls
Definition: chan_misdn.c:673
static int g_config_initialized
Definition: chan_misdn.c:101
#define LOG_VERBOSE
Definition: logger.h:166
static int * misdn_in_calls
Definition: chan_misdn.c:672
static void update_config ( struct chan_list ch)
static

Updates caller ID information from config.

Definition at line 5730 of file chan_misdn.c.

References chan_list::ast, ast_log(), ast_to_misdn_pres(), ast_to_misdn_screen(), chan_list::bc, misdn_bchannel::caller, misdn_bchannel::capability, chan_misdn_log(), ast_channel::connected, misdn_bchannel::hdlc, ast_party_connected_line::id, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, LOG_WARNING, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_PRES, MISDN_CFG_SCREEN, misdn_to_str_pres(), misdn_to_str_screen(), ast_party_id::number, misdn_bchannel::port, ast_party_number::presentation, misdn_party_id::presentation, and misdn_party_id::screening.

Referenced by misdn_call().

5731 {
5732  struct ast_channel *ast;
5733  struct misdn_bchannel *bc;
5734  int port;
5735  int hdlc = 0;
5736  int pres;
5737  int screen;
5738 
5739  if (!ch) {
5740  ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
5741  return;
5742  }
5743 
5744  ast = ch->ast;
5745  bc = ch->bc;
5746  if (! ast || ! bc) {
5747  ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
5748  return;
5749  }
5750 
5751  port = bc->port;
5752 
5753  chan_misdn_log(7, port, "update_config: Getting Config\n");
5754 
5755  misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
5756  if (hdlc) {
5757  switch (bc->capability) {
5760  chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
5761  bc->hdlc = 1;
5762  break;
5763  }
5764  }
5765 
5766 
5767  misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres));
5768  misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen));
5769  chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
5770 
5771  if (pres < 0 || screen < 0) {
5772  chan_misdn_log(2, port, " --> pres: %x\n", ast->connected.id.number.presentation);
5773 
5775  chan_misdn_log(2, port, " --> PRES: %s(%d)\n", misdn_to_str_pres(bc->caller.presentation), bc->caller.presentation);
5776 
5778  chan_misdn_log(2, port, " --> SCREEN: %s(%d)\n", misdn_to_str_screen(bc->caller.screening), bc->caller.screening);
5779  } else {
5780  bc->caller.screening = screen;
5781  bc->caller.presentation = pres;
5782  }
5783 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
static int ast_to_misdn_pres(int presentation)
Definition: chan_misdn.c:2117
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define LOG_WARNING
Definition: logger.h:144
int hdlc
TRUE if call made in digital HDLC mode.
Definition: isdn_lib.h:635
B channel control structure.
Definition: isdn_lib.h:324
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
Definition: isdn_lib.h:277
int capability
SETUP message bearer capability field code value.
Definition: isdn_lib.h:609
static const char * misdn_to_str_pres(int presentation)
Definition: chan_misdn.c:2056
struct ast_channel * ast
Associated Asterisk channel structure.
Definition: chan_misdn.c:487
static const char * misdn_to_str_screen(int screening)
Definition: chan_misdn.c:2145
struct misdn_party_id caller
Originating/Caller ID information struct.
Definition: isdn_lib.h:343
static int ast_to_misdn_screen(int screening)
Definition: chan_misdn.c:2214
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
struct misdn_bchannel * bc
Associated B channel structure.
Definition: chan_misdn.c:492
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
Definition: isdn_lib.h:282
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int update_ec_config ( struct misdn_bchannel bc)
static

Definition at line 5872 of file chan_misdn.c.

References misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, MISDN_CFG_ECHOCANCEL, misdn_cfg_get(), and misdn_bchannel::port.

Referenced by handle_cli_misdn_toggle_echocancel(), and read_config().

5873 {
5874  int ec;
5875  int port = bc->port;
5876 
5877  misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec));
5878 
5879  if (ec == 1) {
5880  bc->ec_enable = 1;
5881  } else if (ec > 1) {
5882  bc->ec_enable = 1;
5883  bc->ec_deftaps = ec;
5884  }
5885 
5886  return 0;
5887 }
int ec_enable
TRUE if the echo cancellor is enabled.
Definition: isdn_lib.h:688
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
Definition: misdn_config.c:562
int ec_deftaps
Number of taps in the echo cancellor when enabled.
Definition: isdn_lib.h:693
static void update_name ( struct ast_channel tmp,
int  port,
int  c 
)
static

Definition at line 8087 of file chan_misdn.c.

References ast_change_name(), chan_misdn_log(), misdn_cfg_get_next_port(), misdn_lib_port_is_pri(), and ast_channel::name.

Referenced by cb_events().

8088 {
8089  int chan_offset = 0;
8090  int tmp_port = misdn_cfg_get_next_port(0);
8091  char newname[255];
8092 
8093  for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
8094  if (tmp_port == port) {
8095  break;
8096  }
8097  chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
8098  }
8099  if (c < 0) {
8100  c = 0;
8101  }
8102 
8103  snprintf(newname, sizeof(newname), "%s/%d-", misdn_type, chan_offset + c);
8104  if (strncmp(tmp->name, newname, strlen(newname))) {
8105  snprintf(newname, sizeof(newname), "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
8106  ast_change_name(tmp, newname);
8107  chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name);
8108  }
8109 }
static void chan_misdn_log(int level, int port, char *tmpl,...)
Definition: chan_misdn.c:12626
int misdn_cfg_get_next_port(int port)
Definition: misdn_config.c:892
void ast_change_name(struct ast_channel *chan, const char *newname)
Change channel name.
Definition: channel.c:6229
const ast_string_field name
Definition: channel.h:787
int port
Logical Layer 1 port associated with this B channel.
Definition: isdn_lib.h:370
static int glob_channel
Definition: chan_misdn.c:8085
static const char misdn_type[]
Definition: chan_misdn.c:661
int misdn_lib_port_is_pri(int port)
Definition: isdn_lib.c:53
static void wait_for_digits ( struct chan_list ch,
struct misdn_bchannel bc,
struct ast_channel chan 
)
static

Definition at line 8847 of file chan_misdn.c.

References misdn_bchannel::dialed, dialtone_indicate(), EVENT_SETUP_ACKNOWLEDGE, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_bchannel::nt, misdn_party_dialing::number, and chan_list::state.

Referenced by cb_events().

8848 {
8849  ch->state = MISDN_WAITING4DIGS;
8851  if (bc->nt && !bc->dialed.number[0]) {
8852  dialtone_indicate(ch);
8853  }
8854 }
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
Definition: isdn_lib.h:266
int nt
TRUE if NT side of protocol (TE otherwise)
Definition: isdn_lib.h:364
enum misdn_chan_state state
State of the channel.
Definition: chan_misdn.c:358
struct misdn_party_dialing dialed
Dialed/Called information struct.
Definition: isdn_lib.h:337
static int dialtone_indicate(struct chan_list *cl)
Definition: chan_misdn.c:7624
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
Definition: isdn_lib.c:3523

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Channel driver for mISDN Support (BRI/PRI)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
static

Definition at line 12695 of file chan_misdn.c.

struct allowed_bearers allowed_bearers_array[]
static

Definition at line 2334 of file chan_misdn.c.

Definition at line 12695 of file chan_misdn.c.

struct ast_cli_entry chan_misdn_clis[]
static

Definition at line 5703 of file chan_misdn.c.

struct chan_list* cl_te =NULL
static

Global channel call record list head.

Definition at line 678 of file chan_misdn.c.

ast_mutex_t cl_te_lock
static

Definition at line 679 of file chan_misdn.c.

int g_config_initialized = 0
static

Definition at line 101 of file chan_misdn.c.

int glob_channel = 0
static

Definition at line 8085 of file chan_misdn.c.

char global_tracefile[BUFFERSIZE+1]
static
Note
To use the CCBS/CCNR supplementary service feature and other supplementary services using FACILITY messages requires a modified version of mISDN.
The latest modified mISDN v1.1.x based version is available at: http://svn.digium.com/svn/thirdparty/mISDN/trunk http://svn.digium.com/svn/thirdparty/mISDNuser/trunk
Taged versions of the modified mISDN code are available under: http://svn.digium.com/svn/thirdparty/mISDN/tags http://svn.digium.com/svn/thirdparty/mISDNuser/tags

Definition at line 99 of file chan_misdn.c.

int max_ports
static

Definition at line 670 of file chan_misdn.c.

Referenced by handle_cli_misdn_set_debug(), load_module(), and reload_config().

int MAXTICS = 8

Definition at line 584 of file chan_misdn.c.

int* misdn_debug
static

Definition at line 668 of file chan_misdn.c.

int* misdn_debug_only
static

Definition at line 669 of file chan_misdn.c.

int* misdn_in_calls
static

Definition at line 672 of file chan_misdn.c.

int* misdn_out_calls
static

Definition at line 673 of file chan_misdn.c.

int* misdn_ports
static

Definition at line 645 of file chan_misdn.c.

struct sched_context* misdn_tasks = NULL
static

the main schedule context for stuff like l1 watcher, overlap dial, ...

Definition at line 642 of file chan_misdn.c.

pthread_t misdn_tasks_thread
static

Definition at line 643 of file chan_misdn.c.

struct ast_channel_tech misdn_tech
static

Definition at line 8047 of file chan_misdn.c.

struct ast_channel_tech misdn_tech_wo_bridge
static

Definition at line 8066 of file chan_misdn.c.

Referenced by misdn_new().

const char misdn_type[] = "mISDN"
static

Definition at line 661 of file chan_misdn.c.

int prefformat = AST_FORMAT_ALAW
static

Only alaw and mulaw is allowed for now.

Definition at line 666 of file chan_misdn.c.

Referenced by misdn_new().

ast_mutex_t release_lock
static

Definition at line 295 of file chan_misdn.c.

struct robin_list* robin = NULL
static

Definition at line 598 of file chan_misdn.c.

Referenced by get_robin_position().

struct state_struct state_array[]
static

Definition at line 4052 of file chan_misdn.c.

int tracing = 0
static

Definition at line 663 of file chan_misdn.c.