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 "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 |
Defines | |
| #define | MISDN_ASTERISK_PVT(ast) 1 |
| #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 const char * | bearer2str (int cap) |
| static enum event_response_e | cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data) |
| 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 void | cl_dequeue_chan (struct chan_list **list, struct chan_list *chan) |
| static void | cl_queue_chan (struct chan_list **list, 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_numplan (int port, int numplan, 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. | |
| static struct chan_list * | find_chan_by_bc (struct chan_list *list, struct misdn_bchannel *bc) |
| static struct chan_list * | find_chan_by_pid (struct chan_list *list, int pid) |
| static struct chan_list * | find_hold_active_call (struct chan_list *list, struct misdn_bchannel *bc) |
| static struct chan_list * | find_hold_call (struct chan_list *list, struct misdn_bchannel *bc) |
| static struct chan_list * | find_hold_call_l3 (struct chan_list *list, unsigned long l3_id) |
| static void | free_robin_list (void) |
| static struct chan_list * | get_chan_by_ast (struct ast_channel *ast) |
| static struct chan_list * | get_chan_by_ast_name (char *name) |
| static struct robin_list * | get_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. | |
| static struct chan_list * | init_chan_list (int orig) |
| static int | load_module (void) |
| 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_check_l2l1 (struct ast_channel *chan, void *data) |
| 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, void *data) |
| static int | misdn_fixup (struct ast_channel *oldast, struct ast_channel *ast) |
| static const char * | misdn_get_ch_state (struct chan_list *p) |
| static int | misdn_hangup (struct ast_channel *ast) |
| static int | misdn_indication (struct ast_channel *ast, int cond, const void *data, size_t datalen) |
| void | misdn_jb_destroy (struct misdn_jb *jb) |
| frees the data and destroys the given jitterbuffer struct | |
| 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. | |
| 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). | |
| struct misdn_jb * | misdn_jb_init (int size, int upper_threshold) |
| allocates the jb-structure and initialize the elements | |
| static int | misdn_l1_task (const void *data) |
| static struct ast_channel * | misdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c) |
| static int | misdn_overlap_dial_task (const void *data) |
| static struct ast_frame * | misdn_read (struct ast_channel *ast) |
| static struct ast_channel * | misdn_request (const char *type, int format, 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, void *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_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 (struct FacParm *fac, struct misdn_bchannel *bc) |
| static struct ast_frame * | process_ast_dsp (struct chan_list *tmp, struct ast_frame *frame) |
| static int | read_config (struct chan_list *ch, int orig) |
| 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 void | 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 int | update_config (struct chan_list *ch, int orig) |
| Updates caller ID information from config. | |
| 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_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
| static struct allowed_bearers | allowed_bearers_array [] |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_cli_entry | chan_misdn_clis [] |
| struct chan_list * | cl_te = NULL |
| Global channel call record list head. | |
| ast_mutex_t | cl_te_lock |
| struct chan_list | dummy_cl |
| static int | g_config_initialized = 0 |
| static int | glob_channel = 0 |
| char | global_tracefile [BUFFERSIZE+1] |
| ast_mutex_t | lock |
| 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_context * | misdn_tasks = NULL |
| the main schedule context for stuff like l1 watcher, overlap dial, ... | |
| 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. | |
| ast_mutex_t | release_lock |
| static struct robin_list * | robin = NULL |
| static struct state_struct | state_array [] |
| static int | tracing = 0 |
the chan_misdn channel driver for Asterisk
Definition in file chan_misdn.c.
| #define MISDN_ASTERISK_PVT | ( | ast | ) | 1 |
Definition at line 490 of file chan_misdn.c.
Referenced by cb_events(), and do_immediate_setup().
| #define MISDN_ASTERISK_TECH_PVT | ( | ast | ) | ast->tech_pvt |
Definition at line 489 of file chan_misdn.c.
Referenced by cb_events(), do_immediate_setup(), misdn_answer(), misdn_call(), misdn_digit_end(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_read(), misdn_set_opt_exec(), misdn_write(), release_chan(), and release_chan_early().
| #define ORG_AST 1 |
Definition at line 133 of file chan_misdn.c.
Referenced by cb_events(), export_aoc_vars(), misdn_call(), misdn_hangup(), misdn_request(), print_bc_info(), read_config(), release_chan(), and release_chan_early().
| #define ORG_MISDN 2 |
Definition at line 134 of file chan_misdn.c.
Referenced by cb_events(), and misdn_indication().
| #define TRANSFER_ON_HELD_CALL_HANGUP 1 |
Definition at line 3767 of file chan_misdn.c.
| enum misdn_chan_state |
| MISDN_NOTHING |
at beginning |
| MISDN_WAITING4DIGS |
when waiting for infos |
| MISDN_EXTCANTMATCH |
when asterisk couldn't match our ext |
| MISDN_INCOMING_SETUP |
for incoming setups |
| MISDN_DIALING |
when pbx_start |
| MISDN_PROGRESS |
we got a progress |
| MISDN_PROCEEDING |
we got a 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 116 of file chan_misdn.c.
00116 { 00117 MISDN_NOTHING=0, /*!< at beginning */ 00118 MISDN_WAITING4DIGS, /*!< when waiting for infos */ 00119 MISDN_EXTCANTMATCH, /*!< when asterisk couldn't match our ext */ 00120 MISDN_INCOMING_SETUP, /*!< for incoming setups*/ 00121 MISDN_DIALING, /*!< when pbx_start */ 00122 MISDN_PROGRESS, /*!< we got a progress */ 00123 MISDN_PROCEEDING, /*!< we got a progress */ 00124 MISDN_CALLING, /*!< when misdn_call is called */ 00125 MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */ 00126 MISDN_ALERTING, /*!< when Alerting */ 00127 MISDN_BUSY, /*!< when BUSY */ 00128 MISDN_CONNECTED, /*!< when connected */ 00129 MISDN_DISCONNECTED, /*!< when connected */ 00130 MISDN_CLEANING, /*!< when hangup from * but we were connected before */ 00131 };
| enum misdn_hold_state |
| 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 136 of file chan_misdn.c.
00136 { 00137 MISDN_HOLD_IDLE, /*!< HOLD not active */ 00138 MISDN_HOLD_ACTIVE, /*!< Call is held */ 00139 MISDN_HOLD_TRANSFER, /*!< Held call is being transferred */ 00140 MISDN_HOLD_DISCONNECT, /*!< Held call is being disconnected */ 00141 };
| static void __reg_module | ( | void | ) | [static] |
Definition at line 6133 of file chan_misdn.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 6133 of file chan_misdn.c.
| static int _misdn_tasks_add_variable | ( | int | timeout, | |
| ast_sched_cb | callback, | |||
| const void * | data, | |||
| int | variable | |||
| ) | [inline, static] |
Definition at line 809 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().
00810 { 00811 int task_id; 00812 00813 if (!misdn_tasks) { 00814 misdn_tasks_init(); 00815 } 00816 task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable); 00817 misdn_tasks_wakeup(); 00818 00819 return task_id; 00820 }
| int add_in_calls | ( | int | port | ) |
Definition at line 4254 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_IN.
Referenced by cb_events().
04255 { 04256 int max_in_calls; 04257 04258 misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 04259 misdn_in_calls[port]++; 04260 04261 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) { 04262 ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port); 04263 return misdn_in_calls[port] - max_in_calls; 04264 } 04265 04266 return 0; 04267 }
| int add_out_calls | ( | int | port | ) |
Definition at line 4269 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_OUT.
Referenced by misdn_call().
04270 { 04271 int max_out_calls; 04272 04273 misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 04274 04275 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) { 04276 ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port); 04277 return (misdn_out_calls[port] + 1) - max_out_calls; 04278 } 04279 04280 misdn_out_calls[port]++; 04281 04282 return 0; 04283 }
| static const char* bearer2str | ( | int | cap | ) | [static] |
Definition at line 607 of file chan_misdn.c.
References ARRAY_LEN, and allowed_bearers::display.
Referenced by cb_events(), print_bc_info(), and print_bearer().
00608 { 00609 unsigned index; 00610 00611 for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) { 00612 if (allowed_bearers_array[index].cap == cap) { 00613 return allowed_bearers_array[index].display; 00614 } 00615 } 00616 00617 return "Unknown Bearer"; 00618 }
| static enum event_response_e cb_events | ( | enum event_e | event, | |
| struct misdn_bchannel * | bc, | |||
| void * | user_data | |||
| ) | [static] |
queue new chan
Sending SETUP_ACK
Supplementary Services
Definition at line 4309 of file chan_misdn.c.
References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, misdn_bchannel::AOCD, misdn_bchannel::AOCD_need_export, misdn_bchannel::AOCDtype, 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_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_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pickup_call(), ast_pickup_ext(), AST_PRES_ALLOWED, AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, AST_PRES_USER_NUMBER_UNSCREENED, ast_queue_control(), ast_queue_frame(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, 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::cad, misdn_bchannel::capability, misdn_bchannel::cause, cb_log, chan, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::chargingUnit, ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), chan_list::context, misdn_bchannel::cpnnumplan, misdn_bchannel::currency, misdn_bchannel::cw, misdn_bchannel::dad, ast_frame::data, ast_frame::datalen, ast_frame::delivery, 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_PORT_ALARM, EVENT_PROCEEDING, EVENT_PROGRESS, 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, chan_list::far_alerting, find_chan_by_bc(), find_hold_active_call(), find_hold_call(), find_hold_call_l3(), ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, hangup_chan(), ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, chan_list::ignore_dtmf, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::info_dad, INFO_PI_INBAND_AVAILABLE, misdn_bchannel::infos_pending, init_chan_list(), misdn_bchannel::keypad, misdn_bchannel::l3_id, chan_list::l3id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, manager_isdn_get_info(), MISDN_ALERTING, MISDN_ASTERISK_PVT, 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_get(), MISDN_CFG_HOLD_ALLOWED, MISDN_CFG_IMMEDIATE, misdn_cfg_is_msn_valid(), MISDN_CFG_REJECT_CAUSE, MISDN_CLEANING, MISDN_CONNECTED, MISDN_DIALING, MISDN_DISCONNECTED, MISDN_EXTCANTMATCH, MISDN_GEN_APPEND_DIGITS2EXTEN, misdn_get_ch_state(), MISDN_HOLD_ACTIVE, MISDN_HOLD_DISCONNECT, MISDN_HOLD_IDLE, misdn_inband_avail(), MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_log_ies(), misdn_lib_port_block(), misdn_lib_send_event(), misdn_new(), MISDN_NOTHING, misdn_overlap_dial_task(), MISDN_PROCEEDING, MISDN_PROGRESS, misdn_tasks_add_variable(), MISDN_WAITING4DIGS, 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::nt, chan_list::nttimeout, misdn_bchannel::oad, 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(), pbx_start_chan(), misdn_bchannel::pid, chan_list::pipe, hold_info::port, misdn_bchannel::port, misdn_bchannel::pres, print_bearer(), print_facility(), misdn_bchannel::progress_indicator, ast_frame::ptr, read_config(), release_chan(), RESPONSE_IGNORE_SETUP, RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE, RESPONSE_OK, RESPONSE_RELEASE_SETUP, ast_channel::rings, ast_frame::samples, misdn_bchannel::screen, 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_channel::tech, misdn_bchannel::tone_cnt, ast_channel::transfercapability, ast_channel_tech::type, update_name(), and wait_for_digits().
Referenced by load_module().
04310 { 04311 int msn_valid; 04312 struct chan_list *held_ch; 04313 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 04314 04315 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 04316 int debuglevel = 1; 04317 if ( event == EVENT_CLEANUP && !user_data) 04318 debuglevel = 5; 04319 04320 chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch ? misdn_get_ch_state(ch) : "none"); 04321 if (debuglevel == 1) { 04322 misdn_lib_log_ies(bc); 04323 chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state)); 04324 } 04325 } 04326 04327 if (!ch) { 04328 switch(event) { 04329 case EVENT_SETUP: 04330 case EVENT_DISCONNECT: 04331 case EVENT_RELEASE: 04332 case EVENT_RELEASE_COMPLETE: 04333 case EVENT_PORT_ALARM: 04334 case EVENT_RETRIEVE: 04335 case EVENT_NEW_BC: 04336 case EVENT_FACILITY: 04337 break; 04338 case EVENT_CLEANUP: 04339 case EVENT_TONE_GENERATE: 04340 case EVENT_BCHAN_DATA: 04341 return -1; 04342 default: 04343 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); 04344 return -1; 04345 } 04346 } 04347 04348 if (ch) { 04349 switch (event) { 04350 case EVENT_TONE_GENERATE: 04351 break; 04352 case EVENT_DISCONNECT: 04353 case EVENT_RELEASE: 04354 case EVENT_RELEASE_COMPLETE: 04355 case EVENT_CLEANUP: 04356 case EVENT_TIMEOUT: 04357 if (!ch->ast) 04358 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)); 04359 break; 04360 default: 04361 if (!ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 04362 if (event != EVENT_BCHAN_DATA) 04363 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 04364 return -1; 04365 } 04366 } 04367 } 04368 04369 04370 switch (event) { 04371 case EVENT_PORT_ALARM: 04372 { 04373 int boa = 0; 04374 misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(boa)); 04375 if (boa) { 04376 cb_log(1, bc->port, " --> blocking\n"); 04377 misdn_lib_port_block(bc->port); 04378 } 04379 } 04380 break; 04381 case EVENT_BCHAN_ACTIVATED: 04382 break; 04383 04384 case EVENT_NEW_CHANNEL: 04385 update_name(ch->ast,bc->port,bc->channel); 04386 break; 04387 04388 case EVENT_NEW_L3ID: 04389 ch->l3id=bc->l3_id; 04390 ch->addr=bc->addr; 04391 break; 04392 04393 case EVENT_NEW_BC: 04394 if (!ch) { 04395 ch = find_hold_call(cl_te,bc); 04396 } 04397 04398 if (!ch) { 04399 ast_log(LOG_WARNING, "NEW_BC without chan_list?\n"); 04400 break; 04401 } 04402 04403 if (bc) 04404 ch->bc = (struct misdn_bchannel *)user_data; 04405 break; 04406 04407 case EVENT_DTMF_TONE: 04408 { 04409 /* sending INFOS as DTMF-Frames :) */ 04410 struct ast_frame fr; 04411 04412 memset(&fr, 0, sizeof(fr)); 04413 fr.frametype = AST_FRAME_DTMF; 04414 fr.subclass = bc->dtmf ; 04415 fr.src = NULL; 04416 fr.data.ptr = NULL; 04417 fr.datalen = 0; 04418 fr.samples = 0; 04419 fr.mallocd = 0; 04420 fr.offset = 0; 04421 fr.delivery = ast_tv(0,0); 04422 04423 if (!ch->ignore_dtmf) { 04424 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 04425 ast_queue_frame(ch->ast, &fr); 04426 } else { 04427 chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf); 04428 } 04429 } 04430 break; 04431 case EVENT_STATUS: 04432 break; 04433 04434 case EVENT_INFORMATION: 04435 { 04436 if ( ch->state != MISDN_CONNECTED ) 04437 stop_indicate(ch); 04438 04439 if (!ch->ast) 04440 break; 04441 04442 if (ch->state == MISDN_WAITING4DIGS ) { 04443 /* Ok, incomplete Setup, waiting till extension exists */ 04444 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 04445 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 04446 ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad)); 04447 } 04448 04449 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1); 04450 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04451 04452 /* Check for Pickup Request first */ 04453 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 04454 if (ast_pickup_call(ch->ast)) { 04455 hangup_chan(ch, bc); 04456 } else { 04457 struct ast_channel *chan = ch->ast; 04458 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04459 ast_setstate(chan, AST_STATE_DOWN); 04460 hangup_chan(ch, bc); 04461 ch->ast = NULL; 04462 break; 04463 } 04464 } 04465 04466 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04467 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04468 ast_log(LOG_WARNING, 04469 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 04470 bc->dad, ch->context, bc->port); 04471 strcpy(ch->ast->exten, "i"); 04472 04473 ch->state = MISDN_DIALING; 04474 start_pbx(ch, bc, ch->ast); 04475 break; 04476 } 04477 04478 ast_log(LOG_WARNING, 04479 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 04480 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04481 bc->dad, ch->context, bc->port); 04482 04483 if (bc->nt) 04484 hanguptone_indicate(ch); 04485 ch->state = MISDN_EXTCANTMATCH; 04486 bc->out_cause = AST_CAUSE_UNALLOCATED; 04487 04488 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04489 break; 04490 } 04491 04492 if (ch->overlap_dial) { 04493 ast_mutex_lock(&ch->overlap_tv_lock); 04494 ch->overlap_tv = ast_tvnow(); 04495 ast_mutex_unlock(&ch->overlap_tv_lock); 04496 if (ch->overlap_dial_task == -1) { 04497 ch->overlap_dial_task = 04498 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04499 } 04500 break; 04501 } 04502 04503 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04504 04505 ch->state = MISDN_DIALING; 04506 start_pbx(ch, bc, ch->ast); 04507 } 04508 } else { 04509 /* sending INFOS as DTMF-Frames :) */ 04510 struct ast_frame fr; 04511 int digits; 04512 04513 memset(&fr, 0, sizeof(fr)); 04514 fr.frametype = AST_FRAME_DTMF; 04515 fr.subclass = bc->info_dad[0] ; 04516 fr.src = NULL; 04517 fr.data.ptr = NULL; 04518 fr.datalen = 0; 04519 fr.samples = 0; 04520 fr.mallocd = 0; 04521 fr.offset = 0; 04522 fr.delivery = ast_tv(0,0); 04523 04524 misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(digits)); 04525 if (ch->state != MISDN_CONNECTED ) { 04526 if (digits) { 04527 strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1); 04528 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04529 ast_cdr_update(ch->ast); 04530 } 04531 04532 ast_queue_frame(ch->ast, &fr); 04533 } 04534 } 04535 } 04536 break; 04537 case EVENT_SETUP: 04538 { 04539 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 04540 struct ast_channel *chan; 04541 int exceed; 04542 int pres, screen; 04543 int ai; 04544 int im; 04545 04546 if (ch) { 04547 switch (ch->state) { 04548 case MISDN_NOTHING: 04549 ch = NULL; 04550 break; 04551 default: 04552 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 04553 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 04554 } 04555 } 04556 04557 msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 04558 if (!bc->nt && ! msn_valid) { 04559 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 04560 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 04561 } 04562 04563 if (bc->cw) { 04564 int cause; 04565 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 04566 misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 04567 bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING; 04568 return RESPONSE_RELEASE_SETUP; 04569 } 04570 04571 print_bearer(bc); 04572 04573 ch = init_chan_list(ORG_MISDN); 04574 04575 if (!ch) { 04576 chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); 04577 return 0; 04578 } 04579 04580 ch->bc = bc; 04581 ch->l3id = bc->l3_id; 04582 ch->addr = bc->addr; 04583 ch->originator = ORG_MISDN; 04584 04585 chan = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel); 04586 if (!chan) { 04587 ast_free(ch); 04588 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04589 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 04590 return 0; 04591 } 04592 04593 ch->ast = chan; 04594 04595 if ((exceed = add_in_calls(bc->port))) { 04596 char tmp[16]; 04597 snprintf(tmp, sizeof(tmp), "%d", exceed); 04598 pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp); 04599 } 04600 04601 read_config(ch, ORG_MISDN); 04602 04603 export_ch(chan, bc, ch); 04604 04605 ch->ast->rings = 1; 04606 ast_setstate(ch->ast, AST_STATE_RINGING); 04607 04608 switch (bc->pres) { 04609 case 1: 04610 pres = AST_PRES_RESTRICTED; 04611 chan_misdn_log(2, bc->port, " --> PRES: Restricted (1)\n"); 04612 break; 04613 case 2: 04614 pres = AST_PRES_UNAVAILABLE; 04615 chan_misdn_log(2, bc->port, " --> PRES: Unavailable (2)\n"); 04616 break; 04617 default: 04618 pres = AST_PRES_ALLOWED; 04619 chan_misdn_log(2, bc->port, " --> PRES: Allowed (%d)\n", bc->pres); 04620 break; 04621 } 04622 04623 switch (bc->screen) { 04624 default: 04625 case 0: 04626 screen = AST_PRES_USER_NUMBER_UNSCREENED; 04627 chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen); 04628 break; 04629 case 1: 04630 screen = AST_PRES_USER_NUMBER_PASSED_SCREEN; 04631 chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n"); 04632 break; 04633 case 2: 04634 screen = AST_PRES_USER_NUMBER_FAILED_SCREEN; 04635 chan_misdn_log(2, bc->port, " --> SCREEN: failed screen (2)\n"); 04636 break; 04637 case 3: 04638 screen = AST_PRES_NETWORK_NUMBER; 04639 chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n"); 04640 break; 04641 } 04642 04643 chan->cid.cid_pres = pres | screen; 04644 04645 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 04646 chan->transfercapability = bc->capability; 04647 04648 switch (bc->capability) { 04649 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 04650 pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL"); 04651 break; 04652 default: 04653 pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH"); 04654 } 04655 04656 /** queue new chan **/ 04657 cl_queue_chan(&cl_te, ch); 04658 04659 if (!strstr(ch->allowed_bearers, "all")) { 04660 int i; 04661 04662 for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) { 04663 if (allowed_bearers_array[i].cap == bc->capability) { 04664 if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) { 04665 /* The bearer capability is allowed */ 04666 if (allowed_bearers_array[i].deprecated) { 04667 chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n", 04668 allowed_bearers_array[i].name); 04669 } 04670 break; 04671 } 04672 } 04673 } /* end for */ 04674 if (i == ARRAY_LEN(allowed_bearers_array)) { 04675 /* We did not find the bearer capability */ 04676 chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n", 04677 bearer2str(bc->capability), bc->capability); 04678 bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 04679 04680 ch->state = MISDN_EXTCANTMATCH; 04681 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 04682 return RESPONSE_OK; 04683 } 04684 } 04685 04686 /* Check for Pickup Request first */ 04687 if (!strcmp(chan->exten, ast_pickup_ext())) { 04688 if (!ch->noautorespond_on_setup) { 04689 int ret;/** Sending SETUP_ACK**/ 04690 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04691 } else { 04692 ch->state = MISDN_INCOMING_SETUP; 04693 } 04694 if (ast_pickup_call(chan)) { 04695 hangup_chan(ch, bc); 04696 } else { 04697 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04698 ast_setstate(chan, AST_STATE_DOWN); 04699 hangup_chan(ch, bc); 04700 ch->ast = NULL; 04701 break; 04702 } 04703 } 04704 04705 /* 04706 * added support for s extension hope it will help those poor cretains 04707 * which haven't overlap dial. 04708 */ 04709 misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 04710 if (ai) { 04711 do_immediate_setup(bc, ch, chan); 04712 break; 04713 } 04714 04715 /* check if we should jump into s when we have no dad */ 04716 misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 04717 if (im && ast_strlen_zero(bc->dad)) { 04718 do_immediate_setup(bc, ch, chan); 04719 break; 04720 } 04721 04722 chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context); 04723 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04724 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04725 ast_log(LOG_WARNING, 04726 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 04727 bc->dad, ch->context, bc->port); 04728 strcpy(ch->ast->exten, "i"); 04729 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 04730 ch->state = MISDN_DIALING; 04731 start_pbx(ch, bc, chan); 04732 break; 04733 } 04734 04735 ast_log(LOG_WARNING, 04736 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 04737 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04738 bc->dad, ch->context, bc->port); 04739 if (bc->nt) 04740 hanguptone_indicate(ch); 04741 04742 ch->state = MISDN_EXTCANTMATCH; 04743 bc->out_cause = AST_CAUSE_UNALLOCATED; 04744 04745 if (bc->nt) 04746 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04747 else 04748 misdn_lib_send_event(bc, EVENT_RELEASE ); 04749 04750 break; 04751 } 04752 04753 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 04754 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 04755 * will be used by Asterisk automatically. */ 04756 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 04757 if (!ch->noautorespond_on_setup) { 04758 ch->state=MISDN_DIALING; 04759 misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04760 } else { 04761 ch->state = MISDN_INCOMING_SETUP; 04762 } 04763 start_pbx(ch, bc, chan); 04764 break; 04765 } 04766 04767 04768 /* 04769 * When we are NT and overlapdial is set and if 04770 * the number is empty, we wait for the ISDN timeout 04771 * instead of our own timer. 04772 */ 04773 if (ch->overlap_dial && bc->nt && !bc->dad[0] ) { 04774 wait_for_digits(ch, bc, chan); 04775 break; 04776 } 04777 04778 /* 04779 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 04780 * Infos with a Interdigit Timeout. 04781 * */ 04782 if (ch->overlap_dial) { 04783 ast_mutex_lock(&ch->overlap_tv_lock); 04784 ch->overlap_tv = ast_tvnow(); 04785 ast_mutex_unlock(&ch->overlap_tv_lock); 04786 04787 wait_for_digits(ch, bc, chan); 04788 if (ch->overlap_dial_task == -1) 04789 ch->overlap_dial_task = 04790 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04791 04792 break; 04793 } 04794 04795 /* If the extension does not exist and we're not TE_PTMP we wait for more digits 04796 * without interdigit timeout. 04797 * */ 04798 if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04799 wait_for_digits(ch, bc, chan); 04800 break; 04801 } 04802 04803 /* 04804 * If the extension exists let's just jump into it. 04805 * */ 04806 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04807 if (bc->need_more_infos) 04808 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04809 else 04810 misdn_lib_send_event(bc, EVENT_PROCEEDING); 04811 04812 ch->state = MISDN_DIALING; 04813 start_pbx(ch, bc, chan); 04814 break; 04815 } 04816 } 04817 break; 04818 04819 case EVENT_SETUP_ACKNOWLEDGE: 04820 { 04821 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04822 04823 if (bc->channel) 04824 update_name(ch->ast,bc->port,bc->channel); 04825 04826 if (!ast_strlen_zero(bc->infos_pending)) { 04827 /* TX Pending Infos */ 04828 strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad) - 1); 04829 04830 if (!ch->ast) 04831 break; 04832 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04833 ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad)); 04834 ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending)); 04835 04836 misdn_lib_send_event(bc, EVENT_INFORMATION); 04837 } 04838 } 04839 break; 04840 case EVENT_PROCEEDING: 04841 { 04842 if (misdn_cap_is_speech(bc->capability) && 04843 misdn_inband_avail(bc) ) { 04844 start_bc_tones(ch); 04845 } 04846 04847 ch->state = MISDN_PROCEEDING; 04848 04849 if (!ch->ast) 04850 break; 04851 04852 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 04853 } 04854 break; 04855 case EVENT_PROGRESS: 04856 04857 if (bc->channel) 04858 update_name(ch->ast, bc->port, bc->channel); 04859 04860 if (!bc->nt ) { 04861 if ( misdn_cap_is_speech(bc->capability) && 04862 misdn_inband_avail(bc) 04863 ) { 04864 start_bc_tones(ch); 04865 } 04866 04867 ch->state = MISDN_PROGRESS; 04868 04869 if (!ch->ast) 04870 break; 04871 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 04872 } 04873 break; 04874 04875 04876 case EVENT_ALERTING: 04877 { 04878 ch->state = MISDN_ALERTING; 04879 04880 if (!ch->ast) 04881 break; 04882 04883 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 04884 ast_setstate(ch->ast, AST_STATE_RINGING); 04885 04886 cb_log(7, bc->port, " --> Set State Ringing\n"); 04887 04888 if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 04889 cb_log(1, bc->port, "Starting Tones, we have inband Data\n"); 04890 start_bc_tones(ch); 04891 } else { 04892 cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n"); 04893 if (ch->far_alerting) { 04894 cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself.."); 04895 start_bc_tones(ch); 04896 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 04897 } 04898 } 04899 } 04900 break; 04901 case EVENT_CONNECT: 04902 { 04903 struct ast_channel *bridged; 04904 04905 /*we answer when we've got our very new L3 ID from the NT stack */ 04906 misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE); 04907 04908 if (!ch->ast) 04909 break; 04910 04911 bridged = ast_bridged_channel(ch->ast); 04912 stop_indicate(ch); 04913 04914 if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) { 04915 struct chan_list *bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged); 04916 04917 chan_misdn_log(1, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad); 04918 if (bridged_ch) { 04919 bridged_ch->bc->cpnnumplan = bc->cpnnumplan; 04920 ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bridged_ch->bc->cad)); 04921 } 04922 } 04923 } 04924 ch->l3id=bc->l3_id; 04925 ch->addr=bc->addr; 04926 04927 start_bc_tones(ch); 04928 04929 ch->state = MISDN_CONNECTED; 04930 04931 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 04932 break; 04933 case EVENT_CONNECT_ACKNOWLEDGE: 04934 { 04935 ch->l3id = bc->l3_id; 04936 ch->addr = bc->addr; 04937 04938 start_bc_tones(ch); 04939 04940 ch->state = MISDN_CONNECTED; 04941 } 04942 break; 04943 case EVENT_DISCONNECT: 04944 /*we might not have an ch->ast ptr here anymore*/ 04945 if (ch) { 04946 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); 04947 if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 04948 /* If there's inband information available (e.g. a 04949 recorded message saying what was wrong with the 04950 dialled number, or perhaps even giving an 04951 alternative number, then play it instead of 04952 immediately releasing the call */ 04953 chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 04954 04955 ch->state = MISDN_DISCONNECTED; 04956 start_bc_tones(ch); 04957 04958 if (ch->ast) { 04959 ch->ast->hangupcause = bc->cause; 04960 if (bc->cause == AST_CAUSE_USER_BUSY) 04961 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 04962 } 04963 ch->need_busy = 0; 04964 break; 04965 } 04966 04967 bc->need_disconnect = 0; 04968 stop_bc_tones(ch); 04969 04970 /* Check for held channel, to implement transfer */ 04971 held_ch = find_hold_call(cl_te, bc); 04972 if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) { 04973 hangup_chan(ch, bc); 04974 } 04975 } else { 04976 held_ch = find_hold_call_l3(cl_te, bc->l3_id); 04977 if (held_ch && held_ch->hold.state == MISDN_HOLD_ACTIVE) { 04978 bc->need_disconnect = 0; 04979 04980 #if defined(TRANSFER_ON_HELD_CALL_HANGUP) 04981 /* 04982 * Some phones disconnect the held call and the active call at the 04983 * same time to do the transfer. Unfortunately, either call could 04984 * be disconnected first. 04985 */ 04986 ch = find_hold_active_call(cl_te, bc); 04987 if (!ch || misdn_attempt_transfer(ch, held_ch)) { 04988 held_ch->hold.state = MISDN_HOLD_DISCONNECT; 04989 hangup_chan(held_ch, bc); 04990 } 04991 #else 04992 hangup_chan(held_ch, bc); 04993 #endif /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */ 04994 } 04995 } 04996 bc->out_cause = -1; 04997 if (bc->need_release) 04998 misdn_lib_send_event(bc, EVENT_RELEASE); 04999 break; 05000 05001 case EVENT_RELEASE: 05002 if (!ch) { 05003 ch = find_hold_call_l3(cl_te, bc->l3_id); 05004 if (!ch) { 05005 chan_misdn_log(1, bc->port, 05006 " --> no Ch, so we've already released. (%s)\n", 05007 manager_isdn_get_info(event)); 05008 return -1; 05009 } 05010 } 05011 05012 bc->need_disconnect = 0; 05013 bc->need_release = 0; 05014 05015 hangup_chan(ch, bc); 05016 release_chan(ch, bc); 05017 break; 05018 case EVENT_RELEASE_COMPLETE: 05019 if (!ch) { 05020 ch = find_hold_call_l3(cl_te, bc->l3_id); 05021 if (!ch) { 05022 chan_misdn_log(1, bc->port, 05023 " --> no Ch, so we've already released. (%s)\n", 05024 manager_isdn_get_info(event)); 05025 break; 05026 } 05027 } 05028 05029 bc->need_disconnect = 0; 05030 bc->need_release = 0; 05031 bc->need_release_complete = 0; 05032 05033 stop_bc_tones(ch); 05034 hangup_chan(ch, bc); 05035 release_chan(ch, bc); 05036 break; 05037 case EVENT_BCHAN_ERROR: 05038 case EVENT_CLEANUP: 05039 { 05040 stop_bc_tones(ch); 05041 05042 switch (ch->state) { 05043 case MISDN_CALLING: 05044 bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 05045 break; 05046 default: 05047 break; 05048 } 05049 05050 hangup_chan(ch, bc); 05051 release_chan(ch, bc); 05052 } 05053 break; 05054 05055 case EVENT_TONE_GENERATE: 05056 { 05057 int tone_len = bc->tone_cnt; 05058 struct ast_channel *ast = ch->ast; 05059 void *tmp; 05060 int res; 05061 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 05062 05063 chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len); 05064 05065 if (!ast) 05066 break; 05067 05068 if (!ast->generator) 05069 break; 05070 05071 tmp = ast->generatordata; 05072 ast->generatordata = NULL; 05073 generate = ast->generator->generate; 05074 05075 if (tone_len < 0 || tone_len > 512 ) { 05076 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len); 05077 tone_len = 128; 05078 } 05079 05080 res = generate(ast, tmp, tone_len, tone_len); 05081 ast->generatordata = tmp; 05082 05083 if (res) { 05084 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 05085 ast_deactivate_generator(ast); 05086 } else { 05087 bc->tone_cnt = 0; 05088 } 05089 } 05090 break; 05091 05092 case EVENT_BCHAN_DATA: 05093 { 05094 if (ch->bc->AOCD_need_export) 05095 export_aoc_vars(ch->originator, ch->ast, ch->bc); 05096 if (!misdn_cap_is_speech(ch->bc->capability)) { 05097 struct ast_frame frame; 05098 /*In Data Modes we queue frames*/ 05099 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 05100 frame.subclass = AST_FORMAT_ALAW; 05101 frame.datalen = bc->bframe_len; 05102 frame.samples = bc->bframe_len; 05103 frame.mallocd = 0; 05104 frame.offset = 0; 05105 frame.delivery = ast_tv(0,0); 05106 frame.src = NULL; 05107 frame.data.ptr = bc->bframe; 05108 05109 if (ch->ast) 05110 ast_queue_frame(ch->ast, &frame); 05111 } else { 05112 fd_set wrfs; 05113 struct timeval tv = { 0, 0 }; 05114 int t; 05115 05116 FD_ZERO(&wrfs); 05117 FD_SET(ch->pipe[1], &wrfs); 05118 05119 t = select(FD_SETSIZE, NULL, &wrfs, NULL, &tv); 05120 05121 if (!t) { 05122 chan_misdn_log(9, bc->port, "Select Timed out\n"); 05123 break; 05124 } 05125 05126 if (t < 0) { 05127 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n", strerror(errno)); 05128 break; 05129 } 05130 05131 if (FD_ISSET(ch->pipe[1], &wrfs)) { 05132 chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len); 05133 if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) { 05134 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno)); 05135 05136 stop_bc_tones(ch); 05137 hangup_chan(ch, bc); 05138 release_chan(ch, bc); 05139 } 05140 } else { 05141 chan_misdn_log(1, bc->port, "Write Pipe full!\n"); 05142 } 05143 } 05144 } 05145 break; 05146 case EVENT_TIMEOUT: 05147 { 05148 if (ch && bc) 05149 chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch)); 05150 05151 switch (ch->state) { 05152 case MISDN_DIALING: 05153 case MISDN_PROGRESS: 05154 if (bc->nt && !ch->nttimeout) 05155 break; 05156 05157 case MISDN_CALLING: 05158 case MISDN_ALERTING: 05159 case MISDN_PROCEEDING: 05160 case MISDN_CALLING_ACKNOWLEDGE: 05161 if (bc->nt) { 05162 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 05163 hanguptone_indicate(ch); 05164 } 05165 05166 bc->out_cause = AST_CAUSE_UNALLOCATED; 05167 misdn_lib_send_event(bc, EVENT_DISCONNECT); 05168 break; 05169 05170 case MISDN_WAITING4DIGS: 05171 if (bc->nt) { 05172 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 05173 bc->out_cause = AST_CAUSE_UNALLOCATED; 05174 hanguptone_indicate(ch); 05175 misdn_lib_send_event(bc, EVENT_DISCONNECT); 05176 } else { 05177 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 05178 misdn_lib_send_event(bc, EVENT_RELEASE); 05179 } 05180 05181 break; 05182 05183 case MISDN_CLEANING: 05184 chan_misdn_log(1,bc->port," --> in state cleaning .. so ignoring, the stack should clean it for us\n"); 05185 break; 05186 05187 default: 05188 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 05189 } 05190 } 05191 break; 05192 05193 05194 /****************************/ 05195 /** Supplementary Services **/ 05196 /****************************/ 05197 case EVENT_RETRIEVE: 05198 if (!ch) { 05199 chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n"); 05200 ch = find_hold_call_l3(cl_te, bc->l3_id); 05201 if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) { 05202 ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n"); 05203 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 05204 break; 05205 } 05206 } 05207 05208 /* remember the channel again */ 05209 ch->bc = bc; 05210 05211 ch->hold.state = MISDN_HOLD_IDLE; 05212 ch->hold.port = 0; 05213 ch->hold.channel = 0; 05214 05215 ast_queue_control(ch->ast, AST_CONTROL_UNHOLD); 05216 05217 if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) { 05218 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n"); 05219 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 05220 } 05221 break; 05222 05223 case EVENT_HOLD: 05224 { 05225 int hold_allowed; 05226 struct ast_channel *bridged; 05227 05228 misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(hold_allowed)); 05229 if (!hold_allowed) { 05230 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 05231 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 05232 break; 05233 } 05234 05235 bridged = ast_bridged_channel(ch->ast); 05236 if (bridged) { 05237 chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type); 05238 ch->l3id = bc->l3_id; 05239 05240 /* forget the channel now */ 05241 ch->bc = NULL; 05242 ch->hold.state = MISDN_HOLD_ACTIVE; 05243 ch->hold.port = bc->port; 05244 ch->hold.channel = bc->channel; 05245 05246 ast_queue_control(ch->ast, AST_CONTROL_HOLD); 05247 05248 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 05249 } else { 05250 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 05251 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 05252 } 05253 } 05254 break; 05255 05256 case EVENT_FACILITY: 05257 print_facility(&(bc->fac_in), bc); 05258 05259 switch (bc->fac_in.Function) { 05260 #ifdef HAVE_MISDN_FAC_RESULT 05261 case Fac_RESULT: 05262 break; 05263 #endif 05264 case Fac_CD: 05265 if (ch) { 05266 struct ast_channel *bridged = ast_bridged_channel(ch->ast); 05267 struct chan_list *ch_br; 05268 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 05269 ch_br = MISDN_ASTERISK_TECH_PVT(bridged); 05270 /*ch->state = MISDN_FACILITY_DEFLECTED;*/ 05271 if (ch_br->bc) { 05272 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) { 05273 ch_br->state = MISDN_DIALING; 05274 if (pbx_start_chan(ch_br) < 0) { 05275 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 05276 } 05277 } 05278 } 05279 } 05280 misdn_lib_send_event(bc, EVENT_DISCONNECT); 05281 } 05282 break; 05283 case Fac_AOCDCurrency: 05284 if (ch) { 05285 bc->AOCDtype = Fac_AOCDCurrency; 05286 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(bc->AOCD.currency)); 05287 bc->AOCD_need_export = 1; 05288 export_aoc_vars(ch->originator, ch->ast, bc); 05289 } 05290 break; 05291 case Fac_AOCDChargingUnit: 05292 if (ch) { 05293 bc->AOCDtype = Fac_AOCDChargingUnit; 05294 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(bc->AOCD.chargingUnit)); 05295 bc->AOCD_need_export = 1; 05296 export_aoc_vars(ch->originator, ch->ast, bc); 05297 } 05298 break; 05299 case Fac_None: 05300 #ifdef HAVE_MISDN_FAC_ERROR 05301 case Fac_ERROR: 05302 #endif 05303 break; 05304 default: 05305 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%d\n", bc->fac_in.Function); 05306 } 05307 05308 break; 05309 05310 case EVENT_RESTART: 05311 05312 if (!bc->dummy) { 05313 stop_bc_tones(ch); 05314 release_chan(ch, bc); 05315 } 05316 break; 05317 05318 default: 05319 chan_misdn_log(1, 0, "Got Unknown Event\n"); 05320 break; 05321 } 05322 05323 return RESPONSE_OK; 05324 }
| int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
| char * | buf, | |||
| int | len | |||
| ) |
Definition at line 5886 of file chan_misdn.c.
References find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().
Referenced by load_module().
05887 { 05888 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 05889 05890 if (ch && ch->jb) { 05891 return misdn_jb_empty(ch->jb, buf, len); 05892 } 05893 05894 return -1; 05895 }
| static void chan_misdn_log | ( | int | level, | |
| int | port, | |||
| char * | tmpl, | |||
| ... | ||||
| ) | [static] |
Definition at line 6069 of file chan_misdn.c.
References ast_console_puts(), ast_log(), ast_strlen_zero(), buf, errno, and LOG_WARNING.
Referenced by cb_events(), cl_queue_chan(), config_jitterbuffer(), debug_numplan(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_chan_by_bc(), find_chan_by_pid(), find_hold_call(), import_ch(), init_chan_list(), load_module(), misdn_answer(), misdn_attempt_transfer(), misdn_bridge(), misdn_call(), misdn_check_l2l1(), misdn_digit_end(), misdn_facility_exec(), 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().
06070 { 06071 va_list ap; 06072 char buf[1024]; 06073 char port_buf[8]; 06074 06075 if (! ((0 <= port) && (port <= max_ports))) { 06076 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 06077 port = 0; 06078 level = -1; 06079 } 06080 06081 snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port); 06082 06083 va_start(ap, tmpl); 06084 vsnprintf(buf, sizeof(buf), tmpl, ap); 06085 va_end(ap); 06086 06087 if (level == -1) 06088 ast_log(LOG_WARNING, "%s", buf); 06089 06090 else if (misdn_debug_only[port] ? 06091 (level == 1 && misdn_debug[port]) || (level == misdn_debug[port]) 06092 : level <= misdn_debug[port]) { 06093 06094 ast_console_puts(port_buf); 06095 ast_console_puts(buf); 06096 } 06097 06098 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 06099 char ctimebuf[30]; 06100 time_t tm = time(NULL); 06101 char *tmp = ctime_r(&tm, ctimebuf), *p; 06102 06103 FILE *fp = fopen(global_tracefile, "a+"); 06104 06105 p = strchr(tmp, '\n'); 06106 if (p) 06107 *p = ':'; 06108 06109 if (!fp) { 06110 ast_console_puts("Error opening Tracefile: [ "); 06111 ast_console_puts(global_tracefile); 06112 ast_console_puts(" ] "); 06113 06114 ast_console_puts(strerror(errno)); 06115 ast_console_puts("\n"); 06116 return ; 06117 } 06118 06119 fputs(tmp, fp); 06120 fputs(" ", fp); 06121 fputs(port_buf, fp); 06122 fputs(" ", fp); 06123 fputs(buf, fp); 06124 06125 fclose(fp); 06126 } 06127 }
Definition at line 3819 of file chan_misdn.c.
References ast_dsp_free(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), chan_list::dsp, chan_list::next, and chan_list::trans.
Referenced by release_chan(), and release_chan_early().
03820 { 03821 struct chan_list *help; 03822 03823 if (chan->dsp) 03824 ast_dsp_free(chan->dsp); 03825 if (chan->trans) 03826 ast_translator_free_path(chan->trans); 03827 03828 ast_mutex_lock(&cl_te_lock); 03829 if (!*list) { 03830 ast_mutex_unlock(&cl_te_lock); 03831 return; 03832 } 03833 03834 if (*list == chan) { 03835 *list = (*list)->next; 03836 ast_mutex_unlock(&cl_te_lock); 03837 return; 03838 } 03839 03840 for (help = *list; help->next; help = help->next) { 03841 if (help->next == chan) { 03842 help->next = help->next->next; 03843 ast_mutex_unlock(&cl_te_lock); 03844 return; 03845 } 03846 } 03847 03848 ast_mutex_unlock(&cl_te_lock); 03849 }
Definition at line 3803 of file chan_misdn.c.
References ast_mutex_lock(), ast_mutex_unlock(), chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::port.
Referenced by cb_events(), and misdn_request().
03804 { 03805 chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan); 03806 03807 ast_mutex_lock(&cl_te_lock); 03808 if (!*list) { 03809 *list = chan; 03810 } else { 03811 struct chan_list *help = *list; 03812 for (; help->next; help = help->next); 03813 help->next = chan; 03814 } 03815 chan->next = NULL; 03816 ast_mutex_unlock(&cl_te_lock); 03817 }
| static char * complete_ch | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 1859 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().
01860 { 01861 return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); 01862 }
| static char * complete_debug_port | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 1864 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().
01865 { 01866 if (a->n) 01867 return NULL; 01868 01869 switch (a->pos) { 01870 case 4: 01871 if (a->word[0] == 'p') 01872 return ast_strdup("port"); 01873 else if (a->word[0] == 'o') 01874 return ast_strdup("only"); 01875 break; 01876 case 6: 01877 if (a->word[0] == 'o') 01878 return ast_strdup("only"); 01879 break; 01880 } 01881 return NULL; 01882 }
| static char * complete_show_config | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 1884 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().
01885 { 01886 char buffer[BUFFERSIZE]; 01887 enum misdn_cfg_elements elem; 01888 int wordlen = strlen(a->word); 01889 int which = 0; 01890 int port = 0; 01891 01892 switch (a->pos) { 01893 case 3: 01894 if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n)) 01895 return ast_strdup("description"); 01896 if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n)) 01897 return ast_strdup("descriptions"); 01898 if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n)) 01899 return ast_strdup("0"); 01900 while ((port = misdn_cfg_get_next_port(port)) != -1) { 01901 snprintf(buffer, sizeof(buffer), "%d", port); 01902 if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) { 01903 return ast_strdup(buffer); 01904 } 01905 } 01906 break; 01907 case 4: 01908 if (strstr(a->line, "description ")) { 01909 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 01910 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) 01911 continue; 01912 misdn_cfg_get_name(elem, buffer, sizeof(buffer)); 01913 if (!wordlen || !strncmp(a->word, buffer, wordlen)) { 01914 if (++which > a->n) 01915 return ast_strdup(buffer); 01916 } 01917 } 01918 } else if (strstr(a->line, "descriptions ")) { 01919 if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n)) 01920 return ast_strdup("general"); 01921 if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n)) 01922 return ast_strdup("ports"); 01923 } 01924 break; 01925 } 01926 return NULL; 01927 }
| static void config_jitterbuffer | ( | struct chan_list * | ch | ) | [static] |
Definition at line 2039 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().
02040 { 02041 struct misdn_bchannel *bc = ch->bc; 02042 int len = ch->jb_len, threshold = ch->jb_upper_threshold; 02043 02044 chan_misdn_log(5, bc->port, "config_jb: Called\n"); 02045 02046 if (! len) { 02047 chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n"); 02048 bc->nojitter=1; 02049 } else { 02050 if (len <= 100 || len > 8000) { 02051 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 02052 len = 1000; 02053 } 02054 02055 if ( threshold > len ) { 02056 chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 02057 } 02058 02059 if ( ch->jb) { 02060 cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n"); 02061 misdn_jb_destroy(ch->jb); 02062 ch->jb = NULL; 02063 } 02064 02065 ch->jb=misdn_jb_init(len, threshold); 02066 02067 if (!ch->jb ) 02068 bc->nojitter = 1; 02069 } 02070 }
| void debug_numplan | ( | int | port, | |
| int | numplan, | |||
| char * | type | |||
| ) |
Definition at line 2073 of file chan_misdn.c.
References chan_misdn_log(), NUMPLAN_INTERNATIONAL, NUMPLAN_NATIONAL, NUMPLAN_SUBSCRIBER, and NUMPLAN_UNKNOWN.
Referenced by read_config().
02074 { 02075 switch (numplan) { 02076 case NUMPLAN_INTERNATIONAL: 02077 chan_misdn_log(2, port, " --> %s: International\n", type); 02078 break; 02079 case NUMPLAN_NATIONAL: 02080 chan_misdn_log(2, port, " --> %s: National\n", type); 02081 break; 02082 case NUMPLAN_SUBSCRIBER: 02083 chan_misdn_log(2, port, " --> %s: Subscriber\n", type); 02084 break; 02085 case NUMPLAN_UNKNOWN: 02086 chan_misdn_log(2, port, " --> %s: Unknown\n", type); 02087 break; 02088 /* Maybe we should cut off the prefix if present ? */ 02089 default: 02090 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 02091 break; 02092 } 02093 }
| static int dialtone_indicate | ( | struct chan_list * | cl | ) | [static] |
AST INDICATIONS END
Definition at line 3274 of file chan_misdn.c.
References chan_list::ast, ast_get_indication_tone(), ast_playtones_start(), chan_list::bc, chan_misdn_log(), 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().
03275 { 03276 const struct tone_zone_sound *ts = NULL; 03277 struct ast_channel *ast = cl->ast; 03278 int nd = 0; 03279 03280 if (!ast) { 03281 chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n"); 03282 return -1; 03283 } 03284 03285 misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 03286 03287 if (nd) { 03288 chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n"); 03289 return 0; 03290 } 03291 03292 chan_misdn_log(3, cl->bc->port, " --> Dial\n"); 03293 ts = ast_get_indication_tone(ast->zone, "dial"); 03294 cl->ts = ts; 03295 03296 if (ts) { 03297 cl->notxtone = 0; 03298 cl->norxtone = 0; 03299 /* This prods us in misdn_write */ 03300 ast_playtones_start(ast, 0, ts->data, 0); 03301 } 03302 03303 return 0; 03304 }
| static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
| struct chan_list * | ch, | |||
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 4077 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(), chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, 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_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_send_event(), chan_list::noautorespond_on_setup, misdn_bchannel::nt, misdn_bchannel::oad, 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, and ast_frame::subclass.
Referenced by cb_events().
04078 { 04079 char *predial; 04080 struct ast_frame fr; 04081 04082 predial = ast_strdupa(ast->exten); 04083 04084 ch->state = MISDN_DIALING; 04085 04086 if (!ch->noautorespond_on_setup) { 04087 if (bc->nt) { 04088 int ret; 04089 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04090 } else { 04091 int ret; 04092 if ( misdn_lib_is_ptp(bc->port)) { 04093 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04094 } else { 04095 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04096 } 04097 } 04098 } else { 04099 ch->state = MISDN_INCOMING_SETUP; 04100 } 04101 04102 chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, ast->cid.cid_num); 04103 04104 strcpy(ast->exten, "s"); 04105 04106 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->oad) || pbx_start_chan(ch) < 0) { 04107 ast = NULL; 04108 bc->out_cause = AST_CAUSE_UNALLOCATED; 04109 hangup_chan(ch, bc); 04110 hanguptone_indicate(ch); 04111 04112 if (bc->nt) 04113 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04114 else 04115 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 04116 } 04117 04118 04119 while (!ast_strlen_zero(predial) ) { 04120 fr.frametype = AST_FRAME_DTMF; 04121 fr.subclass = *predial; 04122 fr.src = NULL; 04123 fr.data.ptr = NULL; 04124 fr.datalen = 0; 04125 fr.samples = 0; 04126 fr.mallocd = 0; 04127 fr.offset = 0; 04128 fr.delivery = ast_tv(0,0); 04129 04130 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 04131 ast_queue_frame(ch->ast, &fr); 04132 } 04133 predial++; 04134 } 04135 }
| static void export_aoc_vars | ( | int | originator, | |
| struct ast_channel * | ast, | |||
| struct misdn_bchannel * | bc | |||
| ) | [static] |
Definition at line 687 of file chan_misdn.c.
References misdn_bchannel::AOCD, misdn_bchannel::AOCD_need_export, misdn_bchannel::AOCDtype, ast_bridged_channel(), buf, misdn_bchannel::chargingUnit, misdn_bchannel::currency, ORG_AST, and pbx_builtin_setvar_helper().
Referenced by cb_events().
00688 { 00689 char buf[128]; 00690 00691 if (!bc->AOCD_need_export || !ast) 00692 return; 00693 00694 if (originator == ORG_AST) { 00695 ast = ast_bridged_channel(ast); 00696 if (!ast) 00697 return; 00698 } 00699 00700 switch (bc->AOCDtype) { 00701 case Fac_AOCDCurrency: 00702 pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency"); 00703 if (bc->AOCD.currency.chargeNotAvailable) 00704 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00705 else { 00706 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00707 if (bc->AOCD.currency.freeOfCharge) 00708 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00709 else { 00710 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00711 if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) { 00712 pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf); 00713 if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) 00714 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00715 } 00716 } 00717 } 00718 break; 00719 case Fac_AOCDChargingUnit: 00720 pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit"); 00721 if (bc->AOCD.chargingUnit.chargeNotAvailable) 00722 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00723 else { 00724 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00725 if (bc->AOCD.chargingUnit.freeOfCharge) 00726 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00727 else { 00728 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00729 if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) { 00730 pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf); 00731 if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) 00732 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00733 } 00734 } 00735 } 00736 break; 00737 default: 00738 break; 00739 } 00740 00741 bc->AOCD_need_export = 0; 00742 }
| 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 4230 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().
04231 { 04232 char tmp[32]; 04233 chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid); 04234 snprintf(tmp, sizeof(tmp), "%d", bc->pid); 04235 pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp); 04236 04237 if (bc->sending_complete) { 04238 snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete); 04239 pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp); 04240 } 04241 04242 if (bc->urate) { 04243 snprintf(tmp, sizeof(tmp), "%d", bc->urate); 04244 pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp); 04245 } 04246 04247 if (bc->uulen) 04248 pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu); 04249 04250 if (!ast_strlen_zero(bc->keypad)) 04251 pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad); 04252 }
| static struct chan_list * find_chan_by_bc | ( | struct chan_list * | list, | |
| struct misdn_bchannel * | bc | |||
| ) | [static, read] |
Definition at line 3713 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), misdn_bchannel::dad, chan_list::next, misdn_bchannel::oad, and misdn_bchannel::port.
Referenced by cb_events(), and chan_misdn_jb_empty().
Definition at line 3725 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::pid.
Referenced by import_ch().
| static struct chan_list* find_hold_active_call | ( | struct chan_list * | list, | |
| struct misdn_bchannel * | bc | |||
| ) | [static, read] |
Definition at line 3783 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_IDLE, MISDN_PROCEEDING, MISDN_PROGRESS, chan_list::next, misdn_bchannel::port, chan_list::state, and hold_info::state.
Referenced by cb_events().
03784 { 03785 for (; list; list = list->next) { 03786 if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port 03787 && list->ast) { 03788 switch (list->state) { 03789 case MISDN_PROCEEDING: 03790 case MISDN_PROGRESS: 03791 case MISDN_ALERTING: 03792 case MISDN_CONNECTED: 03793 return list; 03794 default: 03795 break; 03796 } 03797 } 03798 } 03799 return NULL; 03800 }
| static struct chan_list* find_hold_call | ( | struct chan_list * | list, | |
| struct misdn_bchannel * | bc | |||
| ) | [static, read] |
Definition at line 3737 of file chan_misdn.c.
References chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::dad, chan_list::hold, MISDN_HOLD_ACTIVE, chan_list::next, misdn_bchannel::oad, hold_info::port, misdn_bchannel::port, misdn_bchannel::pri, and hold_info::state.
Referenced by cb_events().
03738 { 03739 struct chan_list *help = list; 03740 03741 if (bc->pri) return NULL; 03742 03743 chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d oad:%s dad:%s\n", bc->channel, bc->oad, bc->dad); 03744 for (;help; help = help->next) { 03745 chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel); 03746 if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port) 03747 return help; 03748 } 03749 chan_misdn_log(6, bc->port, "$$$ find_hold_call: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad); 03750 03751 return NULL; 03752 }
| static struct chan_list* find_hold_call_l3 | ( | struct chan_list * | list, | |
| unsigned long | l3_id | |||
| ) | [static, read] |
Definition at line 3755 of file chan_misdn.c.
References chan_list::hold, chan_list::l3id, MISDN_HOLD_IDLE, chan_list::next, and hold_info::state.
Referenced by cb_events().
| static void free_robin_list | ( | void | ) | [static] |
Definition at line 435 of file chan_misdn.c.
References ast_free, robin_list::group, and robin_list::next.
Referenced by reload_config(), and unload_module().
00436 { 00437 struct robin_list *r; 00438 struct robin_list *next; 00439 00440 for (r = robin, robin = NULL; r; r = next) { 00441 next = r->next; 00442 ast_free(r->group); 00443 ast_free(r); 00444 } 00445 }
| static struct chan_list* get_chan_by_ast | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 564 of file chan_misdn.c.
References chan_list::ast, and chan_list::next.
Referenced by misdn_bridge().
| static struct chan_list* get_chan_by_ast_name | ( | char * | name | ) | [static, read] |
Definition at line 575 of file chan_misdn.c.
References chan_list::ast, 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().
| static struct robin_list* get_robin_position | ( | char * | group | ) | [static, read] |
Definition at line 447 of file chan_misdn.c.
References ast_calloc, ast_free, ast_strdup, robin_list::group, robin_list::next, and robin_list::prev.
Referenced by misdn_request().
00448 { 00449 struct robin_list *new; 00450 struct robin_list *iter = robin; 00451 for (; iter; iter = iter->next) { 00452 if (!strcasecmp(iter->group, group)) { 00453 return iter; 00454 } 00455 } 00456 new = ast_calloc(1, sizeof(*new)); 00457 if (!new) { 00458 return NULL; 00459 } 00460 new->group = ast_strdup(group); 00461 if (!new->group) { 00462 ast_free(new); 00463 return NULL; 00464 } 00465 new->channel = 1; 00466 if (robin) { 00467 new->next = robin; 00468 robin->prev = new; 00469 } 00470 robin = new; 00471 return robin; 00472 }
| static char* handle_cli_misdn_port_block | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1028 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.
01029 { 01030 switch (cmd) { 01031 case CLI_INIT: 01032 e->command = "misdn port block"; 01033 e->usage = 01034 "Usage: misdn port block <port>\n" 01035 " Block the specified port by <port>.\n"; 01036 return NULL; 01037 case CLI_GENERATE: 01038 return NULL; 01039 } 01040 01041 if (a->argc != 4) 01042 return CLI_SHOWUSAGE; 01043 01044 misdn_lib_port_block(atoi(a->argv[3])); 01045 01046 return CLI_SUCCESS; 01047 }
| static char* handle_cli_misdn_port_down | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1133 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.
01134 { 01135 switch (cmd) { 01136 case CLI_INIT: 01137 e->command = "misdn port down"; 01138 e->usage = 01139 "Usage: misdn port down <port>\n" 01140 " Try to deactivate the L1 on the given port.\n"; 01141 return NULL; 01142 case CLI_GENERATE: 01143 return NULL; 01144 } 01145 01146 if (a->argc != 4) 01147 return CLI_SHOWUSAGE; 01148 01149 misdn_lib_get_port_down(atoi(a->argv[3])); 01150 01151 return CLI_SUCCESS; 01152 }
| static char* handle_cli_misdn_port_unblock | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1049 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.
01050 { 01051 switch (cmd) { 01052 case CLI_INIT: 01053 e->command = "misdn port unblock"; 01054 e->usage = 01055 "Usage: misdn port unblock <port>\n" 01056 " Unblock the port specified by <port>.\n"; 01057 return NULL; 01058 case CLI_GENERATE: 01059 return NULL; 01060 } 01061 01062 if (a->argc != 4) 01063 return CLI_SHOWUSAGE; 01064 01065 misdn_lib_port_unblock(atoi(a->argv[3])); 01066 01067 return CLI_SUCCESS; 01068 }
| static char* handle_cli_misdn_port_up | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1112 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.
01113 { 01114 switch (cmd) { 01115 case CLI_INIT: 01116 e->command = "misdn port up"; 01117 e->usage = 01118 "Usage: misdn port up <port>\n" 01119 " Try to establish L1 on the given port.\n"; 01120 return NULL; 01121 case CLI_GENERATE: 01122 return NULL; 01123 } 01124 01125 if (a->argc != 4) 01126 return CLI_SHOWUSAGE; 01127 01128 misdn_lib_get_port_up(atoi(a->argv[3])); 01129 01130 return CLI_SUCCESS; 01131 }
| static char* handle_cli_misdn_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1326 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.
01327 { 01328 switch (cmd) { 01329 case CLI_INIT: 01330 e->command = "misdn reload"; 01331 e->usage = 01332 "Usage: misdn reload\n" 01333 " Reload internal mISDN config, read from the config\n" 01334 " file.\n"; 01335 return NULL; 01336 case CLI_GENERATE: 01337 return NULL; 01338 } 01339 01340 if (a->argc != 2) 01341 return CLI_SHOWUSAGE; 01342 01343 ast_cli(a->fd, "Reloading mISDN configuration\n"); 01344 reload_config(); 01345 return CLI_SUCCESS; 01346 }
| static char* handle_cli_misdn_restart_pid | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1091 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.
01092 { 01093 switch (cmd) { 01094 case CLI_INIT: 01095 e->command = "misdn restart pid"; 01096 e->usage = 01097 "Usage: misdn restart pid <pid>\n" 01098 " Restart the given pid\n"; 01099 return NULL; 01100 case CLI_GENERATE: 01101 return NULL; 01102 } 01103 01104 if (a->argc != 4) 01105 return CLI_SHOWUSAGE; 01106 01107 misdn_lib_pid_restart(atoi(a->argv[3])); 01108 01109 return CLI_SUCCESS; 01110 }
| static char* handle_cli_misdn_restart_port | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1070 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.
01071 { 01072 switch (cmd) { 01073 case CLI_INIT: 01074 e->command = "misdn restart port"; 01075 e->usage = 01076 "Usage: misdn restart port <port>\n" 01077 " Restart the given port.\n"; 01078 return NULL; 01079 case CLI_GENERATE: 01080 return NULL; 01081 } 01082 01083 if (a->argc != 4) 01084 return CLI_SHOWUSAGE; 01085 01086 misdn_lib_port_restart(atoi(a->argv[3])); 01087 01088 return CLI_SUCCESS; 01089 }
| static char* handle_cli_misdn_send_digit | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1728 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, ast_cli(), ast_dtmf_stream(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, get_chan_by_ast_name(), msg, msglen, send_digit_to_chan(), and ast_cli_entry::usage.
01729 { 01730 char *channame; 01731 char *msg; 01732 struct chan_list *tmp; 01733 int i, msglen; 01734 01735 switch (cmd) { 01736 case CLI_INIT: 01737 e->command = "misdn send digit"; 01738 e->usage = 01739 "Usage: misdn send digit <channel> \"<msg>\" \n" 01740 " Send <digit> to <channel> as DTMF Tone\n" 01741 " when channel is a mISDN channel\n"; 01742 return NULL; 01743 case CLI_GENERATE: 01744 return complete_ch(a); 01745 } 01746 01747 if (a->argc != 5) 01748 return CLI_SHOWUSAGE; 01749 01750 channame = a->argv[3]; 01751 msg = a->argv[4]; 01752 msglen = strlen(msg); 01753 01754 ast_cli(a->fd, "Sending %s to %s\n", msg, channame); 01755 01756 tmp = get_chan_by_ast_name(channame); 01757 if (!tmp) { 01758 ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame); 01759 return CLI_SUCCESS; 01760 } 01761 #if 1 01762 for (i = 0; i < msglen; i++) { 01763 ast_cli(a->fd, "Sending: %c\n", msg[i]); 01764 send_digit_to_chan(tmp, msg[i]); 01765 /* res = ast_safe_sleep(tmp->ast, 250); */ 01766 usleep(250000); 01767 /* res = ast_waitfor(tmp->ast,100); */ 01768 } 01769 #else 01770 ast_dtmf_stream(tmp->ast, NULL, msg, 250); 01771 #endif 01772 01773 return CLI_SUCCESS; 01774 }
| static char* handle_cli_misdn_send_display | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1821 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), chan_list::bc, 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(), msg, and ast_cli_entry::usage.
01822 { 01823 char *channame; 01824 char *msg; 01825 struct chan_list *tmp; 01826 01827 switch (cmd) { 01828 case CLI_INIT: 01829 e->command = "misdn send display"; 01830 e->usage = 01831 "Usage: misdn send display <channel> \"<msg>\" \n" 01832 " Send <msg> to <channel> as Display Message\n" 01833 " when channel is a mISDN channel\n"; 01834 return NULL; 01835 case CLI_GENERATE: 01836 return complete_ch(a); 01837 } 01838 01839 if (a->argc != 5) 01840 return CLI_SHOWUSAGE; 01841 01842 channame = a->argv[3]; 01843 msg = a->argv[4]; 01844 01845 ast_cli(a->fd, "Sending %s to %s\n", msg, channame); 01846 tmp = get_chan_by_ast_name(channame); 01847 01848 if (tmp && tmp->bc) { 01849 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); 01850 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 01851 } else { 01852 ast_cli(a->fd, "No such channel %s\n", channame); 01853 return CLI_SUCCESS; 01854 } 01855 01856 return CLI_SUCCESS; 01857 }
| static char* handle_cli_misdn_send_facility | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1608 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_copy_string(), ast_verbose, chan_list::bc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), EVENT_FACILITY, misdn_bchannel::fac_out, get_chan_by_ast_name(), misdn_lib_port_is_nt(), misdn_lib_send_event(), misdn_make_dummy(), and ast_cli_entry::usage.
01609 { 01610 char *channame; 01611 char *nr; 01612 struct chan_list *tmp; 01613 int port; 01614 char *served_nr; 01615 struct misdn_bchannel dummy, *bc=&dummy; 01616 01617 switch (cmd) { 01618 case CLI_INIT: 01619 e->command = "misdn send facility"; 01620 e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n" 01621 "\t type is one of:\n" 01622 "\t - calldeflect\n" 01623 "\t - CFActivate\n" 01624 "\t - CFDeactivate\n"; 01625 01626 return NULL; 01627 case CLI_GENERATE: 01628 return complete_ch(a); 01629 } 01630 01631 if (a->argc < 5) 01632 return CLI_SHOWUSAGE; 01633 01634 if (strstr(a->argv[3], "calldeflect")) { 01635 if (a->argc < 6) { 01636 ast_verbose("calldeflect requires 1 arg: ToNumber\n\n"); 01637 return 0; 01638 } 01639 channame = a->argv[4]; 01640 nr = a->argv[5]; 01641 01642 ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame); 01643 tmp = get_chan_by_ast_name(channame); 01644 if (!tmp) { 01645 ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame); 01646 return 0; 01647 } 01648 01649 if (strlen(nr) >= 15) { 01650 ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame); 01651 return 0; 01652 } 01653 tmp->bc->fac_out.Function = Fac_CD; 01654 ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber)); 01655 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 01656 } else if (strstr(a->argv[3],"CFActivate")) { 01657 if (a->argc < 7) { 01658 ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n"); 01659 return 0; 01660 } 01661 port = atoi(a->argv[4]); 01662 served_nr = a->argv[5]; 01663 nr = a->argv[6]; 01664 01665 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 01666 01667 ast_verbose("Sending CFActivate Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr); 01668 01669 bc->fac_out.Function = Fac_CFActivate; 01670 bc->fac_out.u.CFActivate.BasicService = 0; //All Services 01671 bc->fac_out.u.CFActivate.Procedure = 0; //Unconditional 01672 ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber)); 01673 ast_copy_string((char *)bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber)); 01674 01675 misdn_lib_send_event(bc, EVENT_FACILITY); 01676 } else if (strstr(a->argv[3],"CFDeactivate")) { 01677 if (a->argc < 6) { 01678 ast_verbose("CFDeactivate requires 1 arg: FromNumber\n\n"); 01679 return 0; 01680 } 01681 port = atoi(a->argv[4]); 01682 served_nr = a->argv[5]; 01683 01684 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0); 01685 ast_verbose("Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr); 01686 01687 bc->fac_out.Function = Fac_CFDeactivate; 01688 bc->fac_out.u.CFDeactivate.BasicService = 0; //All Services 01689 bc->fac_out.u.CFDeactivate.Procedure = 0; //Unconditional 01690 01691 ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber)); 01692 misdn_lib_send_event(bc, EVENT_FACILITY); 01693 } 01694 01695 return CLI_SUCCESS; 01696 }
| static char* handle_cli_misdn_send_restart | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1698 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(), and ast_cli_entry::usage.
01699 { 01700 int port; 01701 int channel; 01702 01703 switch (cmd) { 01704 case CLI_INIT: 01705 e->command = "misdn send restart"; 01706 e->usage = 01707 "Usage: misdn send restart [port [channel]]\n" 01708 " Send a restart for every bchannel on the given port.\n"; 01709 return NULL; 01710 case CLI_GENERATE: 01711 return NULL; 01712 } 01713 01714 if (a->argc < 4 || a->argc > 5) 01715 return CLI_SHOWUSAGE; 01716 01717 port = atoi(a->argv[3]); 01718 if (a->argc == 5) { 01719 channel = atoi(a->argv[4]); 01720 misdn_lib_send_restart(port, channel); 01721 } else { 01722 misdn_lib_send_restart(port, -1); 01723 } 01724 01725 return CLI_SUCCESS; 01726 }
| static char* handle_cli_misdn_set_crypt_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1006 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.
01007 { 01008 switch (cmd) { 01009 case CLI_INIT: 01010 e->command = "misdn set crypt debug"; 01011 e->usage = 01012 "Usage: misdn set crypt debug <level>\n" 01013 " Set the crypt debug level of the mISDN channel. Level\n" 01014 " must be 1 or 2.\n"; 01015 return NULL; 01016 case CLI_GENERATE: 01017 return NULL; 01018 } 01019 01020 if (a->argc != 5) 01021 return CLI_SHOWUSAGE; 01022 01023 /* Is this supposed to not do anything? */ 01024 01025 return CLI_SUCCESS; 01026 }
| static char* handle_cli_misdn_set_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 931 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, and ast_cli_entry::usage.
00932 { 00933 int level; 00934 00935 switch (cmd) { 00936 case CLI_INIT: 00937 e->command = "misdn set debug"; 00938 e->usage = 00939 "Usage: misdn set debug <level> [only] | [port <port> [only]]\n" 00940 " Set the debug level of the mISDN channel.\n"; 00941 return NULL; 00942 case CLI_GENERATE: 00943 return complete_debug_port(a); 00944 } 00945 00946 if (a->argc < 4 || a->argc > 7) 00947 return CLI_SHOWUSAGE; 00948 00949 level = atoi(a->argv[3]); 00950 00951 switch (a->argc) { 00952 case 4: 00953 case 5: 00954 { 00955 int i; 00956 int only = 0; 00957 if (a->argc == 5) { 00958 if (strncasecmp(a->argv[4], "only", strlen(a->argv[4]))) 00959 return CLI_SHOWUSAGE; 00960 else 00961 only = 1; 00962 } 00963 00964 for (i = 0; i <= max_ports; i++) { 00965 misdn_debug[i] = level; 00966 misdn_debug_only[i] = only; 00967 } 00968 ast_cli(a->fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":""); 00969 } 00970 break; 00971 case 6: 00972 case 7: 00973 { 00974 int port; 00975 if (strncasecmp(a->argv[4], "port", strlen(a->argv[4]))) 00976 return CLI_SHOWUSAGE; 00977 port = atoi(a->argv[5]); 00978 if (port <= 0 || port > max_ports) { 00979 switch (max_ports) { 00980 case 0: 00981 ast_cli(a->fd, "port number not valid! no ports available so you won't get lucky with any number here...\n"); 00982 break; 00983 case 1: 00984 ast_cli(a->fd, "port number not valid! only port 1 is available.\n"); 00985 break; 00986 default: 00987 ast_cli(a->fd, "port number not valid! only ports 1 to %d are available.\n", max_ports); 00988 } 00989 return 0; 00990 } 00991 if (a->argc == 7) { 00992 if (strncasecmp(a->argv[6], "only", strlen(a->argv[6]))) 00993 return CLI_SHOWUSAGE; 00994 else 00995 misdn_debug_only[port] = 1; 00996 } else 00997 misdn_debug_only[port] = 0; 00998 misdn_debug[port] = level; 00999 ast_cli(a->fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port); 01000 } 01001 } 01002 01003 return CLI_SUCCESS; 01004 }
| static char* handle_cli_misdn_set_tics | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1503 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.
01504 { 01505 switch (cmd) { 01506 case CLI_INIT: 01507 e->command = "misdn set tics"; 01508 e->usage = 01509 "Usage: misdn set tics <value>\n"; 01510 return NULL; 01511 case CLI_GENERATE: 01512 return NULL; 01513 } 01514 01515 if (a->argc != 4) 01516 return CLI_SHOWUSAGE; 01517 01518 MAXTICS = atoi(a->argv[3]); 01519 01520 return CLI_SUCCESS; 01521 }
| static char* handle_cli_misdn_show_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1465 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, chan_list::ast, chan_list::bc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_ch(), ast_cli_args::fd, chan_list::next, print_bc_info(), and ast_cli_entry::usage.
01466 { 01467 struct chan_list *help; 01468 01469 switch (cmd) { 01470 case CLI_INIT: 01471 e->command = "misdn show channel"; 01472 e->usage = 01473 "Usage: misdn show channel <channel>\n" 01474 " Show an internal mISDN channel\n."; 01475 return NULL; 01476 case CLI_GENERATE: 01477 return complete_ch(a); 01478 } 01479 01480 if (a->argc != 4) 01481 return CLI_SHOWUSAGE; 01482 01483 help = cl_te; 01484 01485 for (; help; help = help->next) { 01486 struct misdn_bchannel *bc = help->bc; 01487 struct ast_channel *ast = help->ast; 01488 01489 if (bc && ast) { 01490 if (!strcasecmp(ast->name, a->argv[3])) { 01491 print_bc_info(a->fd, help, bc); 01492 break; 01493 } 01494 } 01495 } 01496 01497 return CLI_SUCCESS; 01498 }
| static char* handle_cli_misdn_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1403 of file chan_misdn.c.
References ast_cli_args::argc, chan_list::ast, ast_cli(), chan_list::bc, hold_info::channel, ast_channel::cid, ast_callerid::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::exten, ast_cli_args::fd, chan_list::hold, chan_list::l3id, misdn_dump_chanlist(), MISDN_HOLD_IDLE, chan_list::next, misdn_bchannel::pid, hold_info::port, print_bc_info(), hold_info::state, and ast_cli_entry::usage.
01404 { 01405 struct chan_list *help; 01406 01407 switch (cmd) { 01408 case CLI_INIT: 01409 e->command = "misdn show channels"; 01410 e->usage = 01411 "Usage: misdn show channels\n" 01412 " Show the internal mISDN channel list\n"; 01413 return NULL; 01414 case CLI_GENERATE: 01415 return NULL; 01416 } 01417 01418 if (a->argc != 3) 01419 return CLI_SHOWUSAGE; 01420 01421 help = cl_te; 01422 01423 ast_cli(a->fd, "Channel List: %p\n", cl_te); 01424 01425 for (; help; help = help->next) { 01426 struct misdn_bchannel *bc = help->bc; 01427 struct ast_channel *ast = help->ast; 01428 if (!ast) { 01429 if (!bc) { 01430 ast_cli(a->fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id); 01431 continue; 01432 } 01433 ast_cli(a->fd, "bc with pid:%d has no Ast Leg\n", bc->pid); 01434 continue; 01435 } 01436 01437 if (misdn_debug[0] > 2) 01438 ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast); 01439 if (bc) { 01440 print_bc_info(a->fd, help, bc); 01441 } else { 01442 if (help->hold.state != MISDN_HOLD_IDLE) { 01443 ast_cli(a->fd, "ITS A HELD CALL BC:\n"); 01444 ast_cli(a->fd, " --> l3_id: %x\n" 01445 " --> dad:%s oad:%s\n" 01446 " --> hold_port: %d\n" 01447 " --> hold_channel: %d\n", 01448 help->l3id, 01449 ast->exten, 01450 ast->cid.cid_num, 01451 help->hold.port, 01452 help->hold.channel 01453 ); 01454 } else { 01455 ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num); 01456 } 01457 } 01458 } 01459 01460 misdn_dump_chanlist(); 01461 01462 return CLI_SUCCESS; 01463 }
| static char* handle_cli_misdn_show_config | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1177 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.
01178 { 01179 char buffer[BUFFERSIZE]; 01180 enum misdn_cfg_elements elem; 01181 int linebreak; 01182 int onlyport = -1; 01183 int ok = 0; 01184 01185 switch (cmd) { 01186 case CLI_INIT: 01187 e->command = "misdn show config"; 01188 e->usage = 01189 "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n" 01190 " Use 0 for <port> to only print the general config.\n"; 01191 return NULL; 01192 case CLI_GENERATE: 01193 return complete_show_config(a); 01194 } 01195 01196 if (a->argc >= 4) { 01197 if (!strcmp(a->argv[3], "description")) { 01198 if (a->argc == 5) { 01199 enum misdn_cfg_elements elem = misdn_cfg_get_elem(a->argv[4]); 01200 if (elem == MISDN_CFG_FIRST) 01201 ast_cli(a->fd, "Unknown element: %s\n", a->argv[4]); 01202 else 01203 show_config_description(a->fd, elem); 01204 return CLI_SUCCESS; 01205 } 01206 return CLI_SHOWUSAGE; 01207 } else if (!strcmp(a->argv[3], "descriptions")) { 01208 if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "general"))) { 01209 for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 01210 show_config_description(a->fd, elem); 01211 ast_cli(a->fd, "\n"); 01212 } 01213 ok = 1; 01214 } 01215 if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "ports"))) { 01216 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) { 01217 show_config_description(a->fd, elem); 01218 ast_cli(a->fd, "\n"); 01219 } 01220 ok = 1; 01221 } 01222 return ok ? CLI_SUCCESS : CLI_SHOWUSAGE; 01223 } else if (!sscanf(a->argv[3], "%5d", &onlyport) || onlyport < 0) { 01224 ast_cli(a->fd, "Unknown option: %s\n", a->argv[3]); 01225 return CLI_SHOWUSAGE; 01226 } 01227 } else if (a->argc == 3 || onlyport == 0) { 01228 ast_cli(a->fd, "mISDN General-Config:\n"); 01229 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) { 01230 misdn_cfg_get_config_string(0, elem, buffer, sizeof(buffer)); 01231 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 01232 } 01233 ast_cli(a->fd, "\n"); 01234 } 01235 01236 if (onlyport < 0) { 01237 int port = misdn_cfg_get_next_port(0); 01238 for (; port > 0; port = misdn_cfg_get_next_port(port)) { 01239 ast_cli(a->fd, "\n[PORT %d]\n", port); 01240 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 01241 misdn_cfg_get_config_string(port, elem, buffer, sizeof(buffer)); 01242 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 01243 } 01244 ast_cli(a->fd, "\n"); 01245 } 01246 } 01247 01248 if (onlyport > 0) { 01249 if (misdn_cfg_is_port_valid(onlyport)) { 01250 ast_cli(a->fd, "[PORT %d]\n", onlyport); 01251 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 01252 misdn_cfg_get_config_string(onlyport, elem, buffer, sizeof(buffer)); 01253 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 01254 } 01255 ast_cli(a->fd, "\n"); 01256 } else { 01257 ast_cli(a->fd, "Port %d is not active!\n", onlyport); 01258 } 01259 } 01260 01261 return CLI_SUCCESS; 01262 }
| static char* handle_cli_misdn_show_port | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1580 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), buf, 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.
01581 { 01582 int port; 01583 char buf[128]; 01584 01585 switch (cmd) { 01586 case CLI_INIT: 01587 e->command = "misdn show port"; 01588 e->usage = 01589 "Usage: misdn show port <port>\n" 01590 " Show detailed information for given port.\n"; 01591 return NULL; 01592 case CLI_GENERATE: 01593 return NULL; 01594 } 01595 01596 if (a->argc != 4) 01597 return CLI_SHOWUSAGE; 01598 01599 port = atoi(a->argv[3]); 01600 01601 ast_cli(a->fd, "BEGIN STACK_LIST:\n"); 01602 get_show_stack_details(port, buf); 01603 ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 01604 01605 return CLI_SUCCESS; 01606 }
| static char* handle_cli_misdn_show_ports_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1552 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.
01553 { 01554 int port; 01555 01556 switch (cmd) { 01557 case CLI_INIT: 01558 e->command = "misdn show ports stats"; 01559 e->usage = 01560 "Usage: misdn show ports stats\n" 01561 " Show mISDNs channel's call statistics per port.\n"; 01562 return NULL; 01563 case CLI_GENERATE: 01564 return NULL; 01565 } 01566 01567 if (a->argc != 4) 01568 return CLI_SHOWUSAGE; 01569 01570 ast_cli(a->fd, "Port\tin_calls\tout_calls\n"); 01571 for (port = misdn_cfg_get_next_port(0); port > 0; 01572 port = misdn_cfg_get_next_port(port)) { 01573 ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]); 01574 } 01575 ast_cli(a->fd, "\n"); 01576 01577 return CLI_SUCCESS; 01578 }
| static char* handle_cli_misdn_show_stacks | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1523 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli(), buf, 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.
01524 { 01525 int port; 01526 01527 switch (cmd) { 01528 case CLI_INIT: 01529 e->command = "misdn show stacks"; 01530 e->usage = 01531 "Usage: misdn show stacks\n" 01532 " Show internal mISDN stack_list.\n"; 01533 return NULL; 01534 case CLI_GENERATE: 01535 return NULL; 01536 } 01537 01538 if (a->argc != 3) 01539 return CLI_SHOWUSAGE; 01540 01541 ast_cli(a->fd, "BEGIN STACK_LIST:\n"); 01542 for (port = misdn_cfg_get_next_port(0); port > 0; 01543 port = misdn_cfg_get_next_port(port)) { 01544 char buf[128]; 01545 get_show_stack_details(port, buf); 01546 ast_cli(a->fd, " %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : ""); 01547 } 01548 01549 return CLI_SUCCESS; 01550 }
| static char* handle_cli_misdn_toggle_echocancel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1776 of file chan_misdn.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), chan_list::bc, 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.
01777 { 01778 char *channame; 01779 struct chan_list *tmp; 01780 01781 switch (cmd) { 01782 case CLI_INIT: 01783 e->command = "misdn toggle echocancel"; 01784 e->usage = 01785 "Usage: misdn toggle echocancel <channel>\n" 01786 " Toggle EchoCancel on mISDN Channel.\n"; 01787 return NULL; 01788 case CLI_GENERATE: 01789 return complete_ch(a); 01790 } 01791 01792 if (a->argc != 4) 01793 return CLI_SHOWUSAGE; 01794 01795 channame = a->argv[3]; 01796 01797 ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame); 01798 01799 tmp = get_chan_by_ast_name(channame); 01800 if (!tmp) { 01801 ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); 01802 return CLI_SUCCESS; 01803 } 01804 01805 tmp->toggle_ec = tmp->toggle_ec ? 0 : 1; 01806 01807 if (tmp->toggle_ec) { 01808 #ifdef MISDN_1_2 01809 update_pipeline_config(tmp->bc); 01810 #else 01811 update_ec_config(tmp->bc); 01812 #endif 01813 manager_ec_enable(tmp->bc); 01814 } else { 01815 manager_ec_disable(tmp->bc); 01816 } 01817 01818 return CLI_SUCCESS; 01819 }
| static void hangup_chan | ( | struct chan_list * | ch, | |
| struct misdn_bchannel * | bc | |||
| ) | [static] |
Definition at line 3866 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(), and start_pbx().
03867 { 03868 int port; 03869 03870 if (!ch) { 03871 cb_log(1, 0, "Cannot hangup chan, no ch\n"); 03872 return; 03873 } 03874 03875 port = bc->port; 03876 cb_log(5, port, "hangup_chan called\n"); 03877 03878 if (ch->need_hangup) { 03879 cb_log(2, port, " --> hangup\n"); 03880 ch->need_hangup = 0; 03881 ch->need_queue_hangup = 0; 03882 if (ch->ast) { 03883 send_cause2ast(ch->ast, bc, ch); 03884 ast_hangup(ch->ast); 03885 } 03886 return; 03887 } 03888 03889 if (!ch->need_queue_hangup) { 03890 cb_log(2, port, " --> No need to queue hangup\n"); 03891 } 03892 03893 ch->need_queue_hangup = 0; 03894 if (ch->ast) { 03895 send_cause2ast(ch->ast, bc, ch); 03896 ast_queue_hangup_with_cause(ch->ast, bc->cause); 03897 cb_log(2, port, " --> queue_hangup\n"); 03898 } else { 03899 cb_log(1, port, "Cannot hangup chan, no ast\n"); 03900 } 03901 }
| static void hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3306 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().
03307 { 03308 misdn_lib_send_tone(cl->bc, TONE_HANGUP); 03309 }
| 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 4196 of file chan_misdn.c.
References ast_copy_string(), ast_log(), chan_misdn_log(), find_chan_by_pid(), misdn_bchannel::keypad, LOG_NOTICE, chan_list::other_ch, chan_list::other_pid, pbx_builtin_getvar_helper(), misdn_bchannel::port, misdn_bchannel::sending_complete, misdn_bchannel::uu, and misdn_bchannel::uulen.
Referenced by misdn_call().
04197 { 04198 const char *tmp; 04199 04200 tmp = pbx_builtin_getvar_helper(chan, "MISDN_PID"); 04201 if (tmp) { 04202 ch->other_pid = atoi(tmp); 04203 chan_misdn_log(3, bc->port, " --> IMPORT_PID: importing pid:%s\n", tmp); 04204 if (ch->other_pid > 0) { 04205 ch->other_ch = find_chan_by_pid(cl_te, ch->other_pid); 04206 if (ch->other_ch) 04207 ch->other_ch->other_ch = ch; 04208 } 04209 } 04210 04211 tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE"); 04212 if (tmp && (atoi(tmp) == 1)) { 04213 bc->sending_complete = 1; 04214 } 04215 04216 tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER"); 04217 if (tmp) { 04218 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 04219 ast_copy_string(bc->uu, tmp, sizeof(bc->uu)); 04220 bc->uulen = strlen(bc->uu); 04221 } 04222 04223 tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD"); 04224 if (tmp) { 04225 ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad)); 04226 } 04227 }
| static struct chan_list* init_chan_list | ( | int | orig | ) | [static, read] |
Definition at line 3350 of file chan_misdn.c.
References ast_calloc, chan_misdn_log(), chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, chan_list::originator, and chan_list::overlap_dial_task.
Referenced by cb_events(), and misdn_request().
03351 { 03352 struct chan_list *cl; 03353 03354 cl = ast_calloc(1, sizeof(*cl)); 03355 if (!cl) { 03356 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 03357 return NULL; 03358 } 03359 03360 cl->originator = orig; 03361 cl->need_queue_hangup = 1; 03362 cl->need_hangup = 1; 03363 cl->need_busy = 1; 03364 cl->overlap_dial_task = -1; 03365 03366 return cl; 03367 }
| static int load_module | ( | void | ) | [static] |
Definition at line 5369 of file chan_misdn.c.
References ast_calloc, ast_channel_register(), ast_cli_register_multiple(), 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, 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().
05370 { 05371 int i, port; 05372 int ntflags = 0, ntkc = 0; 05373 char ports[256] = ""; 05374 char tempbuf[BUFFERSIZE + 1]; 05375 char ntfile[BUFFERSIZE + 1]; 05376 struct misdn_lib_iface iface = { 05377 .cb_event = cb_events, 05378 .cb_log = chan_misdn_log, 05379 .cb_jb_empty = chan_misdn_jb_empty, 05380 }; 05381 05382 max_ports = misdn_lib_maxports_get(); 05383 05384 if (max_ports <= 0) { 05385 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 05386 return AST_MODULE_LOAD_DECLINE; 05387 } 05388 05389 if (misdn_cfg_init(max_ports, 0)) { 05390 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 05391 return AST_MODULE_LOAD_DECLINE; 05392 } 05393 g_config_initialized = 1; 05394 05395 misdn_debug = ast_malloc(sizeof(int) * (max_ports + 1)); 05396 if (!misdn_debug) { 05397 ast_log(LOG_ERROR, "Out of memory for misdn_debug\n"); 05398 return AST_MODULE_LOAD_DECLINE; 05399 } 05400 misdn_ports = ast_malloc(sizeof(int) * (max_ports + 1)); 05401 if (!misdn_ports) { 05402 ast_free(misdn_debug); 05403 ast_log(LOG_ERROR, "Out of memory for misdn_ports\n"); 05404 return AST_MODULE_LOAD_DECLINE; 05405 } 05406 misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(misdn_debug[0])); 05407 for (i = 1; i <= max_ports; i++) { 05408 misdn_debug[i] = misdn_debug[0]; 05409 misdn_ports[i] = i; 05410 } 05411 *misdn_ports = 0; 05412 misdn_debug_only = ast_calloc(max_ports + 1, sizeof(int)); 05413 if (!misdn_debug_only) { 05414 ast_free(misdn_ports); 05415 ast_free(misdn_debug); 05416 ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n"); 05417 return AST_MODULE_LOAD_DECLINE; 05418 } 05419 05420 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, sizeof(tempbuf)); 05421 if (!ast_strlen_zero(tempbuf)) 05422 tracing = 1; 05423 05424 misdn_in_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 05425 if (!misdn_in_calls) { 05426 ast_free(misdn_debug_only); 05427 ast_free(misdn_ports); 05428 ast_free(misdn_debug); 05429 ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n"); 05430 return AST_MODULE_LOAD_DECLINE; 05431 } 05432 misdn_out_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 05433 if (!misdn_out_calls) { 05434 ast_free(misdn_in_calls); 05435 ast_free(misdn_debug_only); 05436 ast_free(misdn_ports); 05437 ast_free(misdn_debug); 05438 ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n"); 05439 return AST_MODULE_LOAD_DECLINE; 05440 } 05441 05442 for (i = 1; i <= max_ports; i++) { 05443 misdn_in_calls[i] = 0; 05444 misdn_out_calls[i] = 0; 05445 } 05446 05447 ast_mutex_init(&cl_te_lock); 05448 ast_mutex_init(&release_lock); 05449 05450 misdn_cfg_update_ptp(); 05451 misdn_cfg_get_ports_string(ports); 05452 05453 if (!ast_strlen_zero(ports)) 05454 chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports); 05455 if (misdn_lib_init(ports, &iface, NULL)) 05456 chan_misdn_log(0, 0, "No te ports initialized\n"); 05457 05458 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(ntflags)); 05459 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, sizeof(ntfile)); 05460 misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(ntkc)); 05461 05462 misdn_lib_nt_keepcalls(ntkc); 05463 misdn_lib_nt_debug_init(ntflags, ntfile); 05464 05465 if (ast_channel_register(&misdn_tech)) { 05466 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 05467 unload_module(); 05468 return AST_MODULE_LOAD_DECLINE; 05469 } 05470 05471 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05472 05473 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 05474 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n" 05475 "Sets mISDN opts. and optargs\n" 05476 "\n" 05477 "The available options are:\n" 05478 " a - Have Asterisk detect DTMF tones on called channel\n" 05479 " c - Make crypted outgoing call, optarg is keyindex\n" 05480 " d - Send display text to called phone, text is the optarg\n" 05481 " e - Perform echo cancelation on this channel,\n" 05482 " takes taps as optarg (32,64,128,256)\n" 05483 " e! - Disable echo cancelation on this channel\n" 05484 " f - Enable fax detection\n" 05485 " h - Make digital outgoing call\n" 05486 " h1 - Make HDLC mode digital outgoing call\n" 05487 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n" 05488 " they will be transported inband.\n" 05489 " jb - Set jitter buffer length, optarg is length\n" 05490 " jt - Set jitter buffer upper threshold, optarg is threshold\n" 05491 " jn - Disable jitter buffer\n" 05492 " n - Disable mISDN DSP on channel.\n" 05493 " Disables: echo cancel, DTMF detection, and volume control.\n" 05494 " p - Caller ID presentation,\n" 05495 " optarg is either 'allowed' or 'restricted'\n" 05496 " s - Send Non-inband DTMF as inband\n" 05497 " vr - Rx gain control, optarg is gain\n" 05498 " vt - Tx gain control, optarg is gain\n" 05499 ); 05500 05501 05502 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 05503 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 05504 "Sends the Facility Message FACILITY_TYPE with \n" 05505 "the given Arguments to the current ISDN Channel\n" 05506 "Supported Facilities are:\n" 05507 "\n" 05508 "type=calldeflect args=Nr where to deflect\n" 05509 ); 05510 05511 05512 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 05513 "misdn_check_l2l1(<port>||g:<groupname>,timeout)" 05514 "Checks if the L2 and L1 are up on either the given <port> or\n" 05515 "on the ports in the group with <groupname>\n" 05516 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 05517 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 05518 "\n" 05519 "This application, ensures the L1/L2 state of the Ports in a group\n" 05520 "it is intended to make the pmp_l1_check option redundant and to\n" 05521 "fix a buggy switch config from your provider\n" 05522 "\n" 05523 "a sample dialplan would look like:\n\n" 05524 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 05525 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 05526 "\n" 05527 ); 05528 05529 05530 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile)); 05531 05532 /* start the l1 watchers */ 05533 05534 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 05535 int l1timeout; 05536 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 05537 if (l1timeout) { 05538 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 05539 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 05540 } 05541 } 05542 05543 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 05544 05545 return 0; 05546 }
| static int misdn_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2492 of file chan_misdn.c.
References chan_list::ast, AST_CAUSE_NETWORK_OUT_OF_ORDER, AST_CAUSE_PROTOCOL_ERROR, ast_copy_string(), ast_log(), ast_queue_hangup_with_cause(), ast_strlen_zero(), ast_true(), chan_list::bc, misdn_bchannel::cad, chan_misdn_log(), misdn_bchannel::crypt_key, misdn_bchannel::dad, EVENT_CONNECT, misdn_bchannel::hdlc, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_lib_send_event(), misdn_bchannel::nodsp, misdn_bchannel::nojitter, pbx_builtin_getvar_helper(), misdn_bchannel::port, start_bc_tones(), chan_list::state, and stop_indicate().
02493 { 02494 struct chan_list *p; 02495 const char *tmp; 02496 02497 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1; 02498 02499 chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n"); 02500 02501 if (!p) { 02502 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 02503 ast_queue_hangup_with_cause(ast, AST_CAUSE_NETWORK_OUT_OF_ORDER); 02504 } 02505 02506 if (!p->bc) { 02507 chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n"); 02508 02509 ast_queue_hangup_with_cause(ast, AST_CAUSE_PROTOCOL_ERROR); 02510 } 02511 02512 tmp = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY"); 02513 if (!ast_strlen_zero(tmp)) { 02514 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 02515 ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key)); 02516 } else { 02517 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 02518 } 02519 02520 tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 02521 if (!ast_strlen_zero(tmp) && ast_true(tmp)) { 02522 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 02523 p->bc->nodsp = 1; 02524 p->bc->hdlc = 0; 02525 p->bc->nojitter = 1; 02526 } 02527 02528 p->state = MISDN_CONNECTED; 02529 stop_indicate(p); 02530 02531 if ( ast_strlen_zero(p->bc->cad) ) { 02532 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n"); 02533 ast_copy_string(p->bc->cad, p->bc->dad, sizeof(p->bc->cad)); 02534 } 02535 02536 misdn_lib_send_event( p->bc, EVENT_CONNECT); 02537 start_bc_tones(p); 02538 02539 return 0; 02540 }
| static int misdn_attempt_transfer | ( | struct chan_list * | active_ch, | |
| struct chan_list * | held_ch | |||
| ) | [static] |
Definition at line 4042 of file chan_misdn.c.
References chan_list::ast, ast_bridged_channel(), ast_channel_masquerade(), AST_CONTROL_UNHOLD, ast_queue_control(), chan_misdn_log(), chan_list::hold, MISDN_ALERTING, MISDN_CONNECTED, MISDN_HOLD_TRANSFER, MISDN_PROCEEDING, MISDN_PROGRESS, hold_info::port, hold_info::state, and chan_list::state.
Referenced by cb_events().
04043 { 04044 int retval; 04045 struct ast_channel *bridged; 04046 04047 switch (active_ch->state) { 04048 case MISDN_PROCEEDING: 04049 case MISDN_PROGRESS: 04050 case MISDN_ALERTING: 04051 case MISDN_CONNECTED: 04052 break; 04053 default: 04054 return -1; 04055 } 04056 04057 bridged = ast_bridged_channel(held_ch->ast); 04058 if (bridged) { 04059 ast_queue_control(held_ch->ast, AST_CONTROL_UNHOLD); 04060 held_ch->hold.state = MISDN_HOLD_TRANSFER; 04061 04062 chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n", 04063 held_ch->ast->name, active_ch->ast->name); 04064 retval = ast_channel_masquerade(active_ch->ast, bridged); 04065 } else { 04066 /* 04067 * Could not transfer. Held channel is not bridged anymore. 04068 * Held party probably got tired of waiting and hung up. 04069 */ 04070 retval = -1; 04071 } 04072 04073 return retval; 04074 }
| 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 3170 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, chan_misdn_log(), ast_channel::exten, f, ast_frame::frametype, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, MISDN_CFG_BRIDGING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_bridge(), misdn_lib_split_bridge(), misdn_bchannel::oad, misdn_bchannel::pid, misdn_bchannel::port, and ast_frame::subclass.
03176 { 03177 struct chan_list *ch1, *ch2; 03178 struct ast_channel *carr[2], *who; 03179 int to = -1; 03180 struct ast_frame *f; 03181 int p1_b, p2_b; 03182 int bridging; 03183 03184 ch1 = get_chan_by_ast(c0); 03185 ch2 = get_chan_by_ast(c1); 03186 03187 carr[0] = c0; 03188 carr[1] = c1; 03189 03190 if (!(ch1 && ch2)) 03191 return -1; 03192 03193 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(p1_b)); 03194 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(p2_b)); 03195 03196 if (! p1_b || ! p2_b) { 03197 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n"); 03198 return AST_BRIDGE_FAILED; 03199 } 03200 03201 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 03202 if (bridging) { 03203 /* trying to make a mISDN_dsp conference */ 03204 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1); 03205 misdn_lib_bridge(ch1->bc, ch2->bc); 03206 } 03207 03208 ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name); 03209 03210 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad); 03211 03212 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_0) ) 03213 ch1->ignore_dtmf = 1; 03214 03215 if (! (flags & AST_BRIDGE_DTMF_CHANNEL_1) ) 03216 ch2->ignore_dtmf = 1; 03217 03218 for (;/*ever*/;) { 03219 to = -1; 03220 who = ast_waitfor_n(carr, 2, &to); 03221 03222 if (!who) { 03223 ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n"); 03224 break; 03225 } 03226 f = ast_read(who); 03227 03228 if (!f || f->frametype == AST_FRAME_CONTROL) { 03229 /* got hangup .. */ 03230 03231 if (!f) 03232 chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n"); 03233 else 03234 chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass); 03235 03236 *fo = f; 03237 *rc = who; 03238 break; 03239 } 03240 03241 if ( f->frametype == AST_FRAME_DTMF ) { 03242 chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass, who->exten); 03243 03244 *fo = f; 03245 *rc = who; 03246 break; 03247 } 03248 03249 #if 0 03250 if (f->frametype == AST_FRAME_VOICE) { 03251 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 03252 03253 continue; 03254 } 03255 #endif 03256 03257 if (who == c0) { 03258 ast_write(c1, f); 03259 } 03260 else { 03261 ast_write(c0, f); 03262 } 03263 } 03264 03265 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1); 03266 03267 misdn_lib_split_bridge(ch1->bc, ch2->bc); 03268 03269 return AST_BRIDGE_COMPLETE; 03270 }
| static int misdn_call | ( | struct ast_channel * | ast, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
we should have l3id after sending setup
Definition at line 2352 of file chan_misdn.c.
References ast_channel::_state, add_out_calls(), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_copy_string(), ast_log(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), ast_transfercapability2str(), chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_callerid::cid_rdnis, ast_channel::context, misdn_bchannel::dad, misdn_bchannel::ec_enable, ENOCHAN, EVENT_SETUP, ext, ast_channel::exten, ast_channel::hangupcause, import_ch(), INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::l3_id, chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_send_event(), misdn_set_opt_exec(), misdn_bchannel::nt, misdn_bchannel::oad, ORG_AST, chan_list::other_ch, pbx_builtin_setvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::rad, S_OR, chan_list::state, stop_bc_tones(), strsep(), ast_channel::transfercapability, and update_config().
02353 { 02354 int port = 0; 02355 int r; 02356 int exceed; 02357 int bridging; 02358 struct chan_list *ch; 02359 struct misdn_bchannel *newbc; 02360 char *opts, *ext; 02361 char *dest_cp; 02362 02363 if (!ast) { 02364 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 02365 return -1; 02366 } 02367 02368 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) { 02369 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02370 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 02371 ast_setstate(ast, AST_STATE_DOWN); 02372 return -1; 02373 } 02374 02375 ch = MISDN_ASTERISK_TECH_PVT(ast); 02376 if (!ch) { 02377 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02378 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 02379 ast_setstate(ast, AST_STATE_DOWN); 02380 return -1; 02381 } 02382 02383 newbc = ch->bc; 02384 if (!newbc) { 02385 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02386 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 02387 ast_setstate(ast, AST_STATE_DOWN); 02388 return -1; 02389 } 02390 02391 /* 02392 * dest is ---v 02393 * Dial(mISDN/g:group_name[/extension[/options]]) 02394 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 02395 * 02396 * The dial extension could be empty if you are using MISDN_KEYPAD 02397 * to control ISDN provider features. 02398 */ 02399 dest_cp = ast_strdupa(dest); 02400 strsep(&dest_cp, "/");/* Discard port/group token */ 02401 ext = strsep(&dest_cp, "/"); 02402 if (!ext) { 02403 ext = ""; 02404 } 02405 opts = dest_cp; 02406 02407 port = newbc->port; 02408 02409 if ((exceed = add_out_calls(port))) { 02410 char tmp[16]; 02411 snprintf(tmp, sizeof(tmp), "%d", exceed); 02412 pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp); 02413 return -1; 02414 } 02415 02416 chan_misdn_log(1, port, "* CALL: %s\n", dest); 02417 02418 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n", ast->exten, ast->name, ast->context); 02419 02420 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n", ast->exten); 02421 if (ast->exten) { 02422 ast_copy_string(ast->exten, ext, sizeof(ast->exten)); 02423 ast_copy_string(newbc->dad, ext, sizeof(newbc->dad)); 02424 } 02425 02426 ast_copy_string(newbc->rad, S_OR(ast->cid.cid_rdnis, ""), sizeof(newbc->rad)); 02427 02428 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n", ast->cid.cid_num); 02429 if (ast_strlen_zero(newbc->oad) && !ast_strlen_zero(ast->cid.cid_num)) { 02430 ast_copy_string(newbc->oad, ast->cid.cid_num, sizeof(newbc->oad)); 02431 } 02432 02433 newbc->capability = ast->transfercapability; 02434 pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability)); 02435 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 02436 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 02437 } 02438 02439 /* update screening and presentation */ 02440 update_config(ch, ORG_AST); 02441 02442 /* fill in some ies from channel vary*/ 02443 import_ch(ast, newbc, ch); 02444 02445 /* Finally The Options Override Everything */ 02446 if (opts) 02447 misdn_set_opt_exec(ast, opts); 02448 else 02449 chan_misdn_log(2, port, "NO OPTS GIVEN\n"); 02450 02451 /*check for bridging*/ 02452 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 02453 if (bridging && ch->other_ch) { 02454 #ifdef MISDN_1_2 02455 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n"); 02456 *ch->bc->pipeline = 0; 02457 *ch->other_ch->bc->pipeline = 0; 02458 #else 02459 chan_misdn_log(1, port, "Disabling EC on both Sides\n"); 02460 ch->bc->ec_enable = 0; 02461 ch->other_ch->bc->ec_enable = 0; 02462 #endif 02463 } 02464 02465 r = misdn_lib_send_event( newbc, EVENT_SETUP ); 02466 02467 /** we should have l3id after sending setup **/ 02468 ch->l3id = newbc->l3_id; 02469 02470 if ( r == -ENOCHAN ) { 02471 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 02472 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1); 02473 ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 02474 ast_setstate(ast, AST_STATE_DOWN); 02475 return -1; 02476 } 02477 02478 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1); 02479 02480 ast_setstate(ast, AST_STATE_DIALING); 02481 ast->hangupcause = AST_CAUSE_NORMAL_CLEARING; 02482 02483 if (newbc->nt) 02484 stop_bc_tones(ch); 02485 02486 ch->state = MISDN_CALLING; 02487 02488 return 0; 02489 }
| static int misdn_check_l2l1 | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 5605 of file chan_misdn.c.
References 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().
05606 { 05607 char *parse; 05608 char group[BUFFERSIZE + 1]; 05609 char *port_str; 05610 int port = 0; 05611 int timeout; 05612 int dowait = 0; 05613 int port_up; 05614 05615 AST_DECLARE_APP_ARGS(args, 05616 AST_APP_ARG(grouppar); 05617 AST_APP_ARG(timeout); 05618 ); 05619 05620 if (ast_strlen_zero((char *)data)) { 05621 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 05622 return -1; 05623 } 05624 05625 parse = ast_strdupa(data); 05626 AST_STANDARD_APP_ARGS(args, parse); 05627 05628 if (args.argc != 2) { 05629 ast_log(LOG_WARNING, "Wrong argument count\n"); 05630 return 0; 05631 } 05632 05633 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 05634 timeout = atoi(args.timeout); 05635 port_str = args.grouppar; 05636 05637 if (port_str[0] == 'g' && port_str[1] == ':' ) { 05638 /* We make a group call lets checkout which ports are in my group */ 05639 port_str += 2; 05640 ast_copy_string(group, port_str, sizeof(group)); 05641 chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group); 05642 05643 for ( port = misdn_cfg_get_next_port(port); 05644 port > 0; 05645 port = misdn_cfg_get_next_port(port)) { 05646 char cfg_group[BUFFERSIZE + 1]; 05647 05648 chan_misdn_log(2, 0, "trying port %d\n", port); 05649 05650 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 05651 05652 if (!strcasecmp(cfg_group, group)) { 05653 port_up = misdn_lib_port_up(port, 1); 05654 05655 if (!port_up) { 05656 chan_misdn_log(2, 0, " --> port '%d'\n", port); 05657 misdn_lib_get_port_up(port); 05658 dowait = 1; 05659 } 05660 } 05661 } 05662 05663 } else { 05664 port = atoi(port_str); 05665 chan_misdn_log(2, 0, "Checking Port: %d\n",port); 05666 port_up = misdn_lib_port_up(port, 1); 05667 if (!port_up) { 05668 misdn_lib_get_port_up(port); 05669 dowait = 1; 05670 } 05671 } 05672 05673 if (dowait) { 05674 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout); 05675 ast_safe_sleep(chan, timeout * 1000); 05676 } 05677 05678 return 0; 05679 }
| static int misdn_digit_begin | ( | struct ast_channel * | chan, | |
| char | digit | |||
| ) | [static] |
Definition at line 2542 of file chan_misdn.c.
| static int misdn_digit_end | ( | struct ast_channel * | ast, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 2548 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_log(), chan_list::bc, buf, chan_misdn_log(), misdn_bchannel::dad, 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(), chan_list::other_ch, misdn_bchannel::port, send_digit_to_chan(), misdn_bchannel::send_dtmf, and chan_list::state.
02549 { 02550 struct chan_list *p; 02551 struct misdn_bchannel *bc; 02552 char buf[2] = { digit, 0 }; 02553 02554 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1; 02555 02556 bc = p->bc; 02557 chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit); 02558 02559 if (!bc) { 02560 ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n"); 02561 return -1; 02562 } 02563 02564 switch (p->state ) { 02565 case MISDN_CALLING: 02566 if (strlen(bc->infos_pending) < sizeof(bc->infos_pending) - 1) 02567 strncat(bc->infos_pending, buf, sizeof(bc->infos_pending) - strlen(bc->infos_pending) - 1); 02568 break; 02569 case MISDN_CALLING_ACKNOWLEDGE: 02570 ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad)); 02571 if (strlen(bc->dad) < sizeof(bc->dad) - 1) 02572 strncat(bc->dad, buf, sizeof(bc->dad) - strlen(bc->dad) - 1); 02573 ast_copy_string(p->ast->exten, bc->dad, sizeof(p->ast->exten)); 02574 misdn_lib_send_event( bc, EVENT_INFORMATION); 02575 break; 02576 default: 02577 /* Do not send Digits in CONNECTED State, when 02578 * the other side is too mISDN. */ 02579 if (p->other_ch ) 02580 return 0; 02581 02582 if ( bc->send_dtmf ) 02583 send_digit_to_chan(p,digit); 02584 break; 02585 } 02586 02587 return 0; 02588 }
| static int misdn_facility_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 5559 of file chan_misdn.c.
References ast_copy_string(), ast_log(), 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, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module().
05560 { 05561 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05562 char *parse, *tok, *tokb; 05563 05564 chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type); 05565 05566 if (strcasecmp(chan->tech->type, "mISDN")) { 05567 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 05568 return -1; 05569 } 05570 05571 if (ast_strlen_zero((char *)data)) { 05572 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05573 return -1; 05574 } 05575 05576 parse = ast_strdupa(data); 05577 tok = strtok_r(parse, "|", &tokb) ; 05578 05579 if (!tok) { 05580 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05581 return -1; 05582 } 05583 05584 if (!strcasecmp(tok, "calldeflect")) { 05585 tok = strtok_r(NULL, "|", &tokb) ; 05586 05587 if (!tok) { 05588 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 05589 } 05590 05591 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) { 05592 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n"); 05593 return 0; 05594 } 05595 ch->bc->fac_out.Function = Fac_CD; 05596 ast_copy_string((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)); 05597 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 05598 } else { 05599 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", tok); 05600 } 05601 05602 return 0; 05603 }
| static int misdn_fixup | ( | struct ast_channel * | oldast, | |
| struct ast_channel * | ast | |||
| ) | [static] |
Definition at line 2591 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.
02592 { 02593 struct chan_list *p; 02594 02595 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1; 02596 02597 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); 02598 02599 p->ast = ast; 02600 02601 return 0; 02602 }
| static const char* misdn_get_ch_state | ( | struct chan_list * | p | ) | [static] |
Definition at line 1286 of file chan_misdn.c.
References chan_list::state, and state_struct::txt.
Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), and print_bc_info().
01287 { 01288 int i; 01289 static char state[8]; 01290 01291 if( !p) return NULL; 01292 01293 for (i = 0; i < sizeof(state_array) / sizeof(struct state_struct); i++) { 01294 if (state_array[i].state == p->state) 01295 return state_array[i].txt; 01296 } 01297 01298 snprintf(state, sizeof(state), "%d", p->state) ; 01299 01300 return state; 01301 }
| static int misdn_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2734 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, AST_CAUSE_NORMAL_CLEARING, ast_copy_string(), ast_debug, ast_log(), AST_STATE_RESERVED, chan_list::bc, misdn_bchannel::cause, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, ast_channel::exten, ast_channel::hangupcause, hanguptone_indicate(), chan_list::hold, 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_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, chan_list::need_busy, misdn_bchannel::need_disconnect, chan_list::need_hangup, chan_list::need_queue_hangup, misdn_bchannel::need_release, misdn_bchannel::nt, ORG_AST, chan_list::originator, misdn_bchannel::out_cause, pbx_builtin_getvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, hold_info::port, misdn_bchannel::progress_indicator, release_chan(), release_chan_early(), start_bc_tones(), chan_list::state, hold_info::state, stop_bc_tones(), misdn_bchannel::uu, misdn_bchannel::uulen, and var.
02735 { 02736 struct chan_list *p; 02737 struct misdn_bchannel *bc; 02738 const char *var; 02739 02740 if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) { 02741 return -1; 02742 } 02743 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 02744 02745 ast_debug(1, "misdn_hangup(%s)\n", ast->name); 02746 02747 if (p->hold.state == MISDN_HOLD_IDLE) { 02748 bc = p->bc; 02749 } else { 02750 p->hold.state = MISDN_HOLD_DISCONNECT; 02751 bc = misdn_lib_find_held_bc(p->hold.port, p->l3id); 02752 if (!bc) { 02753 chan_misdn_log(4, p->hold.port, 02754 "misdn_hangup: Could not find held bc for (%s)\n", ast->name); 02755 release_chan_early(p); 02756 return 0; 02757 } 02758 } 02759 02760 if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) { 02761 /* between request and call */ 02762 ast_debug(1, "State Reserved (or nothing) => chanIsAvail\n"); 02763 release_chan_early(p); 02764 if (bc) { 02765 misdn_lib_release(bc); 02766 } 02767 return 0; 02768 } 02769 if (!bc) { 02770 ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n", 02771 misdn_get_ch_state(p), p->l3id); 02772 release_chan_early(p); 02773 return 0; 02774 } 02775 02776 p->ast = NULL; 02777 p->need_hangup = 0; 02778 p->need_queue_hangup = 0; 02779 p->need_busy = 0; 02780 02781 if (!bc->nt) { 02782 stop_bc_tones(p); 02783 } 02784 02785 bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING; 02786 02787 var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE"); 02788 if (!var) { 02789 var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE"); 02790 } 02791 if (var) { 02792 int tmpcause; 02793 02794 tmpcause = atoi(var); 02795 bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING; 02796 } 02797 02798 var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER"); 02799 if (var) { 02800 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var); 02801 ast_copy_string(bc->uu, var, sizeof(bc->uu)); 02802 bc->uulen = strlen(bc->uu); 02803 } 02804 02805 chan_misdn_log(1, bc->port, 02806 "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n", 02807 bc->pid, 02808 ast->context, 02809 ast->exten, 02810 ast->cid.cid_num, 02811 misdn_get_ch_state(p)); 02812 chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id); 02813 chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause); 02814 chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause); 02815 02816 switch (p->state) { 02817 case MISDN_INCOMING_SETUP: 02818 /* 02819 * This is the only place in misdn_hangup, where we 02820 * can call release_chan, else it might create a lot of trouble. 02821 */ 02822 ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n"); 02823 release_chan(p, bc); 02824 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 02825 return 0; 02826 case MISDN_DIALING: 02827 if (p->hold.state == MISDN_HOLD_IDLE) { 02828 start_bc_tones(p); 02829 hanguptone_indicate(p); 02830 } 02831 02832 p->state = MISDN_CLEANING; 02833 if (bc->need_disconnect) { 02834 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02835 } 02836 break; 02837 case MISDN_CALLING_ACKNOWLEDGE: 02838 if (p->hold.state == MISDN_HOLD_IDLE) { 02839 start_bc_tones(p); 02840 hanguptone_indicate(p); 02841 } 02842 02843 if (bc->need_disconnect) { 02844 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02845 } 02846 break; 02847 02848 case MISDN_CALLING: 02849 case MISDN_ALERTING: 02850 case MISDN_PROGRESS: 02851 case MISDN_PROCEEDING: 02852 if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) { 02853 hanguptone_indicate(p); 02854 } 02855 02856 if (bc->need_disconnect) { 02857 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02858 } 02859 break; 02860 case MISDN_CONNECTED: 02861 /* Alerting or Disconnect */ 02862 if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) { 02863 start_bc_tones(p); 02864 hanguptone_indicate(p); 02865 bc->progress_indicator = INFO_PI_INBAND_AVAILABLE; 02866 } 02867 if (bc->need_disconnect) { 02868 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02869 } 02870 break; 02871 case MISDN_DISCONNECTED: 02872 if (bc->need_release) { 02873 misdn_lib_send_event(bc, EVENT_RELEASE); 02874 } 02875 break; 02876 02877 case MISDN_CLEANING: 02878 return 0; 02879 02880 case MISDN_BUSY: 02881 break; 02882 default: 02883 if (bc->nt) { 02884 bc->out_cause = -1; 02885 if (bc->need_release) { 02886 misdn_lib_send_event(bc, EVENT_RELEASE); 02887 } 02888 } else { 02889 if (bc->need_disconnect) { 02890 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02891 } 02892 } 02893 break; 02894 } 02895 02896 p->state = MISDN_CLEANING; 02897 chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast->name, 02898 misdn_get_ch_state(p)); 02899 02900 return 0; 02901 }
| static int misdn_indication | ( | struct ast_channel * | ast, | |
| int | cond, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 2606 of file chan_misdn.c.
References AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, 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_inband_avail(), misdn_lib_send_event(), chan_list::mohinterpret, misdn_bchannel::nt, ORG_MISDN, chan_list::originator, chan_list::other_ch, misdn_bchannel::out_cause, misdn_bchannel::pid, misdn_bchannel::port, start_bc_tones(), chan_list::state, hold_info::state, and stop_indicate().
02607 { 02608 struct chan_list *p; 02609 02610 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) { 02611 ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n"); 02612 return -1; 02613 } 02614 02615 if (!p->bc) { 02616 if (p->hold.state == MISDN_HOLD_IDLE) { 02617 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond, 02618 ast->name); 02619 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 02620 } else { 02621 chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n", 02622 cond, ast->name); 02623 } 02624 return -1; 02625 } 02626 02627 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n\n", cond, ast->name); 02628 02629 switch (cond) { 02630 case AST_CONTROL_BUSY: 02631 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc ? p->bc->pid : -1); 02632 ast_setstate(ast, AST_STATE_BUSY); 02633 02634 p->bc->out_cause = AST_CAUSE_USER_BUSY; 02635 if (p->state != MISDN_CONNECTED) { 02636 start_bc_tones(p); 02637 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02638 } 02639 return -1; 02640 case AST_CONTROL_RING: 02641 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc ? p->bc->pid : -1); 02642 return -1; 02643 case AST_CONTROL_RINGING: 02644 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1); 02645 switch (p->state) { 02646 case MISDN_ALERTING: 02647 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc ? p->bc->pid : -1); 02648 break; 02649 case MISDN_CONNECTED: 02650 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc ? p->bc->pid : -1); 02651 return -1; 02652 default: 02653 p->state = MISDN_ALERTING; 02654 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1); 02655 misdn_lib_send_event( p->bc, EVENT_ALERTING); 02656 02657 if (p->other_ch && p->other_ch->bc) { 02658 if (misdn_inband_avail(p->other_ch->bc)) { 02659 chan_misdn_log(2, p->bc->port, " --> other End is mISDN and has inband info available\n"); 02660 break; 02661 } 02662 02663 if (!p->other_ch->bc->nt) { 02664 chan_misdn_log(2, p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n"); 02665 break; 02666 } 02667 } 02668 02669 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1); 02670 ast_setstate(ast, AST_STATE_RING); 02671 02672 if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) 02673 chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n"); 02674 else 02675 return -1; 02676 } 02677 break; 02678 case AST_CONTROL_ANSWER: 02679 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc ? p->bc->pid : -1); 02680 start_bc_tones(p); 02681 break; 02682 case AST_CONTROL_TAKEOFFHOOK: 02683 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc ? p->bc->pid : -1); 02684 return -1; 02685 case AST_CONTROL_OFFHOOK: 02686 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc ? p->bc->pid : -1); 02687 return -1; 02688 case AST_CONTROL_FLASH: 02689 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc ? p->bc->pid : -1); 02690 break; 02691 case AST_CONTROL_PROGRESS: 02692 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc ? p->bc->pid : -1); 02693 misdn_lib_send_event( p->bc, EVENT_PROGRESS); 02694 break; 02695 case AST_CONTROL_PROCEEDING: 02696 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc ? p->bc->pid : -1); 02697 misdn_lib_send_event( p->bc, EVENT_PROCEEDING); 02698 break; 02699 case AST_CONTROL_CONGESTION: 02700 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc ? p->bc->pid : -1); 02701 02702 p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION; 02703 start_bc_tones(p); 02704 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02705 02706 if (p->bc->nt) { 02707 hanguptone_indicate(p); 02708 } 02709 break; 02710 case -1 : 02711 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc ? p->bc->pid : -1); 02712 02713 stop_indicate(p); 02714 02715 if (p->state == MISDN_CONNECTED) 02716 start_bc_tones(p); 02717 break; 02718 case AST_CONTROL_HOLD: 02719 ast_moh_start(ast, data, p->mohinterpret); 02720 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc ? p->bc->pid : -1); 02721 break; 02722 case AST_CONTROL_UNHOLD: 02723 ast_moh_stop(ast); 02724 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc ? p->bc->pid : -1); 02725 break; 02726 default: 02727 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc ? p->bc->pid : -1); 02728 return -1; 02729 } 02730 02731 return 0; 02732 }
| void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
frees the data and destroys the given jitterbuffer struct
Definition at line 5946 of file chan_misdn.c.
References ast_free, ast_mutex_destroy(), misdn_jb::mutexjb, misdn_jb::ok, and misdn_jb::samples.
Referenced by config_jitterbuffer(), release_chan(), and release_chan_early().
| 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 6016 of file chan_misdn.c.
References ast_mutex_lock(), ast_mutex_unlock(), chan_misdn_log(), 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().
06017 { 06018 int i, wp, rp, read = 0; 06019 06020 ast_mutex_lock(&jb->mutexjb); 06021 06022 rp = jb->rp; 06023 wp = jb->wp; 06024 06025 if (jb->state_empty) { 06026 for (i = 0; i < len; i++) { 06027 if (wp == rp) { 06028 jb->rp = rp; 06029 jb->state_empty = 0; 06030 06031 ast_mutex_unlock(&jb->mutexjb); 06032 06033 return read; 06034 } else { 06035 if (jb->ok[rp] == 1) { 06036 data[i] = jb->samples[rp]; 06037 jb->ok[rp] = 0; 06038 rp = (rp != jb->size - 1) ? rp + 1 : 0; 06039 read += 1; 06040 } 06041 } 06042 } 06043 06044 if (wp >= rp) 06045 jb->state_buffer = wp - rp; 06046 else 06047 jb->state_buffer = jb->size - rp + wp; 06048 chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 06049 06050 jb->rp = rp; 06051 } else 06052 chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb); 06053 06054 ast_mutex_unlock(&jb->mutexjb); 06055 06056 return read; 06057 }
| 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 5957 of file chan_misdn.c.
References ast_mutex_lock(), ast_mutex_unlock(), misdn_jb::bytes_wrote, chan_misdn_log(), 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().
05958 { 05959 int i, j, rp, wp; 05960 05961 if (!jb || ! data) 05962 return 0; 05963 05964 ast_mutex_lock(&jb->mutexjb); 05965 05966 wp = jb->wp; 05967 rp = jb->rp; 05968 05969 for (i = 0; i < len; i++) { 05970 jb->samples[wp] = data[i]; 05971 jb->ok[wp] = 1; 05972 wp = (wp != jb->size - 1) ? wp + 1 : 0; 05973 05974 if (wp == jb->rp) 05975 jb->state_full = 1; 05976 } 05977 05978 if (wp >= rp) 05979 jb->state_buffer = wp - rp; 05980 else 05981 jb->state_buffer = jb->size - rp + wp; 05982 chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 05983 05984 if (jb->state_full) { 05985 jb->wp = wp; 05986 05987 rp = wp; 05988 for (j = 0; j < jb->upper_threshold; j++) 05989 rp = (rp != 0) ? rp - 1 : jb->size - 1; 05990 jb->rp = rp; 05991 jb->state_full = 0; 05992 jb->state_empty = 1; 05993 05994 ast_mutex_unlock(&jb->mutexjb); 05995 05996 return -1; 05997 } 05998 05999 if (!jb->state_empty) { 06000 jb->bytes_wrote += len; 06001 if (jb->bytes_wrote >= jb->upper_threshold) { 06002 jb->state_empty = 1; 06003 jb->bytes_wrote = 0; 06004 } 06005 } 06006 jb->wp = wp; 06007 06008 ast_mutex_unlock(&jb->mutexjb); 06009 06010 return 0; 06011 }
| struct misdn_jb * misdn_jb_init | ( | int | size, | |
| int | upper_threshold | |||
| ) | [read] |
allocates the jb-structure and initialize the elements
Definition at line 5905 of file chan_misdn.c.
References ast_free, ast_malloc, ast_mutex_init(), misdn_jb::bytes_wrote, chan_misdn_log(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.
Referenced by config_jitterbuffer().
05906 { 05907 int i; 05908 struct misdn_jb *jb; 05909 05910 jb = ast_malloc(sizeof(*jb)); 05911 if (!jb) { 05912 chan_misdn_log(-1, 0, "No free Mem for jb\n"); 05913 return NULL; 05914 } 05915 jb->size = size; 05916 jb->upper_threshold = upper_threshold; 05917 jb->wp = 0; 05918 jb->rp = 0; 05919 jb->state_full = 0; 05920 jb->state_empty = 0; 05921 jb->bytes_wrote = 0; 05922 jb->samples = ast_malloc(size * sizeof(char)); 05923 if (!jb->samples) { 05924 ast_free(jb); 05925 chan_misdn_log(-1, 0, "No free Mem for jb->samples\n"); 05926 return NULL; 05927 } 05928 05929 jb->ok = ast_malloc(size * sizeof(char)); 05930 if (!jb->ok) { 05931 ast_free(jb->samples); 05932 ast_free(jb); 05933 chan_misdn_log(-1, 0, "No free Mem for jb->ok\n"); 05934 return NULL; 05935 } 05936 05937 for (i = 0; i < size; i++) 05938 jb->ok[i] = 0; 05939 05940 ast_mutex_init(&jb->mutexjb); 05941 05942 return jb; 05943 }
| static int misdn_l1_task | ( | const void * | data | ) | [static] |
Definition at line 837 of file chan_misdn.c.
References chan_misdn_log(), and misdn_lib_isdn_l1watcher().
Referenced by load_module().
00838 { 00839 misdn_lib_isdn_l1watcher(*(int *)data); 00840 chan_misdn_log(5, *(int *)data, "L1watcher timeout\n"); 00841 return 1; 00842 }
| static struct ast_channel * misdn_new | ( | struct chan_list * | cl, | |
| int | state, | |||
| char * | exten, | |||
| char * | callerid, | |||
| int | format, | |||
| int | port, | |||
| int | c | |||
| ) | [static, read] |
Definition at line 3642 of file chan_misdn.c.
References ast_callerid_parse(), ast_channel_alloc, ast_channel_set_fd(), ast_copy_string(), ast_jb_configure(), ast_log(), AST_STATE_RING, ast_strdup, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_ani, cid_name, cid_num, ast_channel::exten, LOG_ERROR, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_GEN_BRIDGING, misdn_get_global_jbconf(), misdn_lib_port_is_pri(), ast_channel::nativeformats, chan_list::pipe, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by cb_events(), and misdn_request().
03643 { 03644 struct ast_channel *tmp; 03645 char *cid_name = 0, *cid_num = 0; 03646 int chan_offset = 0; 03647 int tmp_port = misdn_cfg_get_next_port(0); 03648 int bridging; 03649 03650 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03651 if (tmp_port == port) 03652 break; 03653 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03654 } 03655 if (c < 0) 03656 c = 0; 03657 03658 if (callerid) { 03659 ast_callerid_parse(callerid, &cid_name, &cid_num); 03660 } 03661 03662 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++); 03663 if (tmp) { 03664 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n", exten, callerid); 03665 03666 tmp->nativeformats = prefformat; 03667 03668 tmp->readformat = format; 03669 tmp->rawreadformat = format; 03670 tmp->writeformat = format; 03671 tmp->rawwriteformat = format; 03672 03673 tmp->tech_pvt = chlist; 03674 03675 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 03676 03677 if (bridging) 03678 tmp->tech = &misdn_tech; 03679 else 03680 tmp->tech = &misdn_tech_wo_bridge; 03681 03682 tmp->writeformat = format; 03683 tmp->readformat = format; 03684 tmp->priority=1; 03685 03686 if (exten) 03687 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 03688 else 03689 chan_misdn_log(1, 0, "misdn_new: no exten given.\n"); 03690 03691 if (callerid) 03692 /* Don't use ast_set_callerid() here because it will 03693 * generate a needless NewCallerID event */ 03694 tmp->cid.cid_ani = ast_strdup(cid_num); 03695 03696 if (pipe(chlist->pipe) < 0) 03697 ast_log(LOG_ERROR, "Pipe failed\n"); 03698 ast_channel_set_fd(tmp, 0, chlist->pipe[0]); 03699 03700 if (state == AST_STATE_RING) 03701 tmp->rings = 1; 03702 else 03703 tmp->rings = 0; 03704 03705 ast_jb_configure(tmp, misdn_get_global_jbconf()); 03706 } else { 03707 chan_misdn_log(-1, 0, "Unable to allocate channel structure\n"); 03708 } 03709 03710 return tmp; 03711 }
| static int misdn_overlap_dial_task | ( | const void * | data | ) | [static] |
Definition at line 844 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, chan_misdn_log(), chan_list::context, misdn_bchannel::dad, EVENT_DISCONNECT, ast_channel::exten, hanguptone_indicate(), MISDN_CLEANING, MISDN_DIALING, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_bchannel::oad, 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().
00845 { 00846 struct timeval tv_end, tv_now; 00847 int diff; 00848 struct chan_list *ch = (struct chan_list *)data; 00849 00850 chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state); 00851 00852 if (ch->state != MISDN_WAITING4DIGS) { 00853 ch->overlap_dial_task = -1; 00854 return 0; 00855 } 00856 00857 ast_mutex_lock(&ch->overlap_tv_lock); 00858 tv_end = ch->overlap_tv; 00859 ast_mutex_unlock(&ch->overlap_tv_lock); 00860 00861 tv_end.tv_sec += ch->overlap_dial; 00862 tv_now = ast_tvnow(); 00863 00864 diff = ast_tvdiff_ms(tv_end, tv_now); 00865 00866 if (diff <= 100) { 00867 char *dad=ch->bc->dad, sexten[]="s"; 00868 /* if we are 100ms near the timeout, we are satisfied.. */ 00869 stop_indicate(ch); 00870 00871 if (ast_strlen_zero(ch->bc->dad)) { 00872 dad=sexten; 00873 strcpy(ch->ast->exten, sexten); 00874 } 00875 00876 if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) { 00877 ch->state=MISDN_DIALING; 00878 if (pbx_start_chan(ch) < 0) { 00879 chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 00880 goto misdn_overlap_dial_task_disconnect; 00881 } 00882 } else { 00883 misdn_overlap_dial_task_disconnect: 00884 hanguptone_indicate(ch); 00885 ch->bc->out_cause = AST_CAUSE_UNALLOCATED; 00886 ch->state=MISDN_CLEANING; 00887 misdn_lib_send_event(ch->bc, EVENT_DISCONNECT); 00888 } 00889 ch->overlap_dial_task = -1; 00890 return 0; 00891 } else 00892 return diff; 00893 }
| static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 2974 of file chan_misdn.c.
References chan_list::ast_dsp, AST_FORMAT_ALAW, AST_FRAME_VOICE, chan_list::ast_rd_buf, ast_tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), chan_list::bc, chan_misdn_log(), 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.
02975 { 02976 struct chan_list *tmp; 02977 fd_set rrfs; 02978 struct timeval tv; 02979 int len, t; 02980 02981 if (!ast) { 02982 chan_misdn_log(1, 0, "misdn_read called without ast\n"); 02983 return NULL; 02984 } 02985 if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) { 02986 chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n"); 02987 return NULL; 02988 } 02989 02990 if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) { 02991 chan_misdn_log(1, 0, "misdn_read called without bc\n"); 02992 return NULL; 02993 } 02994 02995 tv.tv_sec=0; 02996 tv.tv_usec=20000; 02997 02998 FD_ZERO(&rrfs); 02999 FD_SET(tmp->pipe[0],&rrfs); 03000 03001 t=select(FD_SETSIZE,&rrfs,NULL, NULL,&tv); 03002 03003 if (!t) { 03004 chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n"); 03005 len=160; 03006 } 03007 03008 if (t<0) { 03009 chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n",strerror(errno)); 03010 return NULL; 03011 } 03012 03013 if (FD_ISSET(tmp->pipe[0],&rrfs)) { 03014 len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf)); 03015 03016 if (len<=0) { 03017 /* we hangup here, since our pipe is closed */ 03018 chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n"); 03019 return NULL; 03020 } 03021 03022 } else { 03023 return NULL; 03024 } 03025 03026 tmp->frame.frametype = AST_FRAME_VOICE; 03027 tmp->frame.subclass = AST_FORMAT_ALAW; 03028 tmp->frame.datalen = len; 03029 tmp->frame.samples = len; 03030 tmp->frame.mallocd = 0; 03031 tmp->frame.offset = 0; 03032 tmp->frame.delivery = ast_tv(0,0); 03033 tmp->frame.src = NULL; 03034 tmp->frame.data.ptr = tmp->ast_rd_buf; 03035 03036 if (tmp->faxdetect && !tmp->faxhandled) { 03037 if (tmp->faxdetect_timeout) { 03038 if (ast_tvzero(tmp->faxdetect_tv)) { 03039 tmp->faxdetect_tv = ast_tvnow(); 03040 chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout); 03041 return process_ast_dsp(tmp, &tmp->frame); 03042 } else { 03043 struct timeval tv_now = ast_tvnow(); 03044 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv); 03045 if (diff <= (tmp->faxdetect_timeout * 1000)) { 03046 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n"); 03047 return process_ast_dsp(tmp, &tmp->frame); 03048 } else { 03049 chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n"); 03050 tmp->faxdetect = 0; 03051 return &tmp->frame; 03052 } 03053 } 03054 } else { 03055 chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n"); 03056 return process_ast_dsp(tmp, &tmp->frame); 03057 } 03058 } else { 03059 if (tmp->ast_dsp) 03060 return process_ast_dsp(tmp, &tmp->frame); 03061 else 03062 return &tmp->frame; 03063 } 03064 }
| static struct ast_channel* misdn_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 3369 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_free, ast_log(), AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), chan_list::bc, BUFFERSIZE, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, cl_queue_chan(), misdn_bchannel::dec, ext, get_robin_position(), init_chan_list(), 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_new(), chan_list::need_hangup, ORG_AST, misdn_bchannel::port, robin_list::port, read_config(), and strsep().
03370 { 03371 struct ast_channel *tmp = NULL; 03372 char group[BUFFERSIZE + 1] = ""; 03373 char dial_str[128]; 03374 char *buf2 = ast_strdupa(data); 03375 char *ext; 03376 char *port_str; 03377 char *p = NULL; 03378 int channel = 0; 03379 int port = 0; 03380 struct misdn_bchannel *newbc = NULL; 03381 int dec = 0; 03382 struct chan_list *cl; 03383 03384 snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data); 03385 03386 /* 03387 * data is ---v 03388 * Dial(mISDN/g:group_name[/extension[/options]]) 03389 * Dial(mISDN/port[:preselected_channel][/extension[/options]]) 03390 * 03391 * The dial extension could be empty if you are using MISDN_KEYPAD 03392 * to control ISDN provider features. 03393 */ 03394 port_str = strsep(&buf2, "/"); 03395 if (!ast_strlen_zero(port_str)) { 03396 if (port_str[0] == 'g' && port_str[1] == ':' ) { 03397 /* We make a group call lets checkout which ports are in my group */ 03398 port_str += 2; 03399 ast_copy_string(group, port_str, sizeof(group)); 03400 chan_misdn_log(2, 0, " --> Group Call group: %s\n", group); 03401 } else if ((p = strchr(port_str, ':'))) { 03402 /* we have a preselected channel */ 03403 *p = 0; 03404 channel = atoi(++p); 03405 port = atoi(port_str); 03406 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 03407 } else { 03408 port = atoi(port_str); 03409 } 03410 } else { 03411 ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str); 03412 return NULL; 03413 } 03414 03415 ext = strsep(&buf2, "/"); 03416 if (!ext) { 03417 ext = ""; 03418 } 03419 03420 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { 03421 chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n"); 03422 dec = 1; 03423 } 03424 03425 if (!ast_strlen_zero(group)) { 03426 char cfg_group[BUFFERSIZE + 1]; 03427 struct robin_list *rr = NULL; 03428 03429 /* Group dial */ 03430 03431 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 03432 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); 03433 rr = get_robin_position(group); 03434 } 03435 03436 if (rr) { 03437 int robin_channel = rr->channel; 03438 int port_start; 03439 int next_chan = 1; 03440 03441 do { 03442 port_start = 0; 03443 for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start; 03444 port = misdn_cfg_get_next_port_spin(port)) { 03445 03446 if (!port_start) 03447 port_start = port; 03448 03449 if (port >= port_start) 03450 next_chan = 1; 03451 03452 if (port <= port_start && next_chan) { 03453 int maxbchans=misdn_lib_get_maxchans(port); 03454 if (++robin_channel >= maxbchans) { 03455 robin_channel = 1; 03456 } 03457 next_chan = 0; 03458 } 03459 03460 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 03461 03462 if (!strcasecmp(cfg_group, group)) { 03463 int port_up; 03464 int check; 03465 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check)); 03466 port_up = misdn_lib_port_up(port, check); 03467 03468 if (check && !port_up) 03469 chan_misdn_log(1, port, "L1 is not Up on this Port\n"); 03470 03471 if (check && port_up < 0) { 03472 ast_log(LOG_WARNING, "This port (%d) is blocked\n", port); 03473 } 03474 03475 if (port_up > 0) { 03476 newbc = misdn_lib_get_free_bc(port, robin_channel, 0, 0); 03477 if (newbc) { 03478 chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 03479 if (port_up) 03480 chan_misdn_log(4, port, "portup:%d\n", port_up); 03481 rr->port = newbc->port; 03482 rr->channel = newbc->channel; 03483 break; 03484 } 03485 } 03486 } 03487 } 03488 } while (!newbc && robin_channel != rr->channel); 03489 03490 } else { 03491 for (port = misdn_cfg_get_next_port(0); port > 0; 03492 port = misdn_cfg_get_next_port(port)) { 03493 03494 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 03495 03496 chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port); 03497 if (!strcasecmp(cfg_group, group)) { 03498 int port_up; 03499 int check; 03500 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(check)); 03501 port_up = misdn_lib_port_up(port, check); 03502 03503 chan_misdn_log(4, port, "portup:%d\n", port_up); 03504 03505 if (port_up > 0) { 03506 newbc = misdn_lib_get_free_bc(port, 0, 0, dec); 03507 if (newbc) 03508 break; 03509 } 03510 } 03511 } 03512 } 03513 03514 /* Group dial failed ?*/ 03515 if (!newbc) { 03516 ast_log(LOG_WARNING, 03517 "Could not Dial out on group '%s'.\n" 03518 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 03519 "\tOr there was no free channel on none of the ports\n\n" 03520 , group); 03521 return NULL; 03522 } 03523 } else { 03524 /* 'Normal' Port dial * Port dial */ 03525 if (channel) 03526 chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel); 03527 newbc = misdn_lib_get_free_bc(port, channel, 0, dec); 03528 03529 if (!newbc) { 03530 ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n", port, ext); 03531 return NULL; 03532 } 03533 } 03534 03535 03536 /* create ast_channel and link all the objects together */ 03537 cl = init_chan_list(ORG_AST); 03538 if (!cl) { 03539 ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str); 03540 return NULL; 03541 } 03542 cl->bc = newbc; 03543 03544 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel); 03545 if (!tmp) { 03546 ast_free(cl); 03547 ast_log(LOG_ERROR,"Could not create Asterisk object\n"); 03548 return NULL; 03549 } 03550 03551 cl->ast=tmp; 03552 03553 /* register chan in local list */ 03554 cl_queue_chan(&cl_te, cl) ; 03555 03556 /* fill in the config into the objects */ 03557 read_config(cl, ORG_AST); 03558 03559 /* important */ 03560 cl->need_hangup = 0; 03561 03562 return tmp; 03563 }
| static int misdn_send_text | ( | struct ast_channel * | chan, | |
| const char * | text | |||
| ) | [static] |
Definition at line 3566 of file chan_misdn.c.
References ast_copy_string(), ast_log(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, LOG_WARNING, misdn_lib_send_event(), and ast_channel::tech_pvt.
03567 { 03568 struct chan_list *tmp = chan->tech_pvt; 03569 03570 if (tmp && tmp->bc) { 03571 ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display)); 03572 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 03573 } else { 03574 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 03575 return -1; 03576 } 03577 03578 return 0; 03579 }
| static int misdn_set_opt_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 5681 of file chan_misdn.c.
References ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_strdupa, ast_strlen_zero(), ast_translator_build_path(), 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, 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::pres, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, strsep(), ast_channel::tech, chan_list::trans, misdn_bchannel::txgain, and ast_channel_tech::type.
Referenced by load_module(), and misdn_call().
05682 { 05683 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05684 char *tok, *tokb, *parse; 05685 int keyidx = 0; 05686 int rxgain = 0; 05687 int txgain = 0; 05688 int change_jitter = 0; 05689 05690 if (strcasecmp(chan->tech->type, "mISDN")) { 05691 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n"); 05692 return -1; 05693 } 05694 05695 if (ast_strlen_zero((char *)data)) { 05696 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 05697 return -1; 05698 } 05699 05700 parse = ast_strdupa(data); 05701 for (tok = strtok_r(parse, ":", &tokb); 05702 tok; 05703 tok = strtok_r(NULL, ":", &tokb) ) { 05704 int neglect = 0; 05705 05706 if (tok[0] == '!' ) { 05707 neglect = 1; 05708 tok++; 05709 } 05710 05711 switch(tok[0]) { 05712 05713 case 'd' : 05714 ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display)); 05715 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display); 05716 break; 05717 05718 case 'n': 05719 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 05720 ch->bc->nodsp = 1; 05721 break; 05722 05723 case 'j': 05724 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 05725 tok++; 05726 change_jitter = 1; 05727 05728 switch ( tok[0] ) { 05729 case 'b': 05730 ch->jb_len = atoi(++tok); 05731 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len); 05732 break; 05733 case 't' : 05734 ch->jb_upper_threshold = atoi(++tok); 05735 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold); 05736 break; 05737 case 'n': 05738 ch->bc->nojitter = 1; 05739 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 05740 break; 05741 default: 05742 ch->jb_len = 4000; 05743 ch->jb_upper_threshold = 0; 05744 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len); 05745 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold); 05746 } 05747 break; 05748 case 'v': 05749 tok++; 05750 05751 switch (tok[0]) { 05752 case 'r' : 05753 rxgain = atoi(++tok); 05754 if (rxgain < -8) 05755 rxgain = -8; 05756 if (rxgain > 8) 05757 rxgain = 8; 05758 ch->bc->rxgain = rxgain; 05759 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain); 05760 break; 05761 case 't': 05762 txgain = atoi(++tok); 05763 if (txgain < -8) 05764 txgain = -8; 05765 if (txgain > 8) 05766 txgain = 8; 05767 ch->bc->txgain = txgain; 05768 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain); 05769 break; 05770 } 05771 break; 05772 05773 case 'c': 05774 keyidx = atoi(++tok); 05775 { 05776 char keys[4096]; 05777 char *key = NULL, *tmp = keys; 05778 int i; 05779 misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 05780 05781 for (i = 0; i < keyidx; i++) { 05782 key = strsep(&tmp, ","); 05783 } 05784 05785 if (key) { 05786 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 05787 } 05788 05789 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key); 05790 break; 05791 } 05792 case 'e': 05793 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 05794 05795 if (neglect) { 05796 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 05797 #ifdef MISDN_1_2 05798 *ch->bc->pipeline = 0; 05799 #else 05800 ch->bc->ec_enable = 0; 05801 #endif 05802 } else { 05803 #ifdef MISDN_1_2 05804 update_pipeline_config(ch->bc); 05805 #else 05806 ch->bc->ec_enable = 1; 05807 ch->bc->orig = ch->originator; 05808 tok++; 05809 if (*tok) { 05810 ch->bc->ec_deftaps = atoi(tok); 05811 } 05812 #endif 05813 } 05814 05815 break; 05816 case 'h': 05817 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 05818 05819 if (strlen(tok) > 1 && tok[1] == '1') { 05820 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 05821 if (!ch->bc->hdlc) { 05822 ch->bc->hdlc = 1; 05823 } 05824 } 05825 ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 05826 break; 05827 05828 case 's': 05829 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 05830 ch->bc->send_dtmf = 1; 05831 break; 05832 05833 case 'f': 05834 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 05835 ch->faxdetect = 1; 05836 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 05837 break; 05838 05839 case 'a': 05840 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 05841 ch->ast_dsp = 1; 05842 break; 05843 05844 case 'p': 05845 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]); 05846 /* CRICH: callingpres!!! */ 05847 if (strstr(tok,"allowed")) { 05848 ch->bc->pres = 0; 05849 } else if (strstr(tok, "restricted")) { 05850 ch->bc->pres = 1; 05851 } else if (strstr(tok, "not_screened")) { 05852 chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n"); 05853 ch->bc->pres = 1; 05854 } 05855 break; 05856 case 'i' : 05857 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n"); 05858 ch->ignore_dtmf=1; 05859 break; 05860 default: 05861 break; 05862 } 05863 } 05864 05865 if (change_jitter) 05866 config_jitterbuffer(ch); 05867 05868 if (ch->faxdetect || ch->ast_dsp) { 05869 if (!ch->dsp) 05870 ch->dsp = ast_dsp_new(); 05871 if (ch->dsp) 05872 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT); 05873 if (!ch->trans) 05874 ch->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 05875 } 05876 05877 if (ch->ast_dsp) { 05878 chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 05879 ch->bc->nodsp = 1; 05880 } 05881 05882 return 0; 05883 }
| static int misdn_tasks_add | ( | int | timeout, | |
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 822 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by load_module().
00823 { 00824 return _misdn_tasks_add_variable(timeout, callback, data, 0); 00825 }
| static int misdn_tasks_add_variable | ( | int | timeout, | |
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 827 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by cb_events().
00828 { 00829 return _misdn_tasks_add_variable(timeout, callback, data, 1); 00830 }
| static void misdn_tasks_destroy | ( | void | ) | [static] |
Definition at line 792 of file chan_misdn.c.
References cb_log, chan_misdn_log(), and sched_context_destroy().
Referenced by unload_module().
00793 { 00794 if (misdn_tasks) { 00795 chan_misdn_log(4, 0, "Killing misdn_tasks thread\n"); 00796 if ( pthread_cancel(misdn_tasks_thread) == 0 ) { 00797 cb_log(4, 0, "Joining misdn_tasks thread\n"); 00798 pthread_join(misdn_tasks_thread, NULL); 00799 } 00800 sched_context_destroy(misdn_tasks); 00801 } 00802 }
| static void misdn_tasks_init | ( | void | ) | [static] |
Definition at line 773 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().
00774 { 00775 sem_t blocker; 00776 int i = 5; 00777 00778 if (sem_init(&blocker, 0, 0)) { 00779 perror("chan_misdn: Failed to initialize semaphore!"); 00780 exit(1); 00781 } 00782 00783 chan_misdn_log(4, 0, "Starting misdn_tasks thread\n"); 00784 00785 misdn_tasks = sched_context_create(); 00786 pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker); 00787 00788 while (sem_wait(&blocker) && --i); 00789 sem_destroy(&blocker); 00790 }
| static void misdn_tasks_remove | ( | int | task_id | ) | [static] |
Definition at line 832 of file chan_misdn.c.
References AST_SCHED_DEL.
Referenced by release_chan(), and release_chan_early().
00833 { 00834 AST_SCHED_DEL(misdn_tasks, task_id); 00835 }
| static void* misdn_tasks_thread_func | ( | void * | data | ) | [static] |
Definition at line 749 of file chan_misdn.c.
References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), and sighandler().
Referenced by misdn_tasks_init().
00750 { 00751 int wait; 00752 struct sigaction sa; 00753 00754 sa.sa_handler = sighandler; 00755 sa.sa_flags = SA_NODEFER; 00756 sigemptyset(&sa.sa_mask); 00757 sigaddset(&sa.sa_mask, SIGUSR1); 00758 sigaction(SIGUSR1, &sa, NULL); 00759 00760 sem_post((sem_t *)data); 00761 00762 while (1) { 00763 wait = ast_sched_wait(misdn_tasks); 00764 if (wait < 0) 00765 wait = 8000; 00766 if (poll(NULL, 0, wait) < 0) 00767 chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n"); 00768 ast_sched_runq(misdn_tasks); 00769 } 00770 return NULL; 00771 }
| static void misdn_tasks_wakeup | ( | void | ) | [inline, static] |
Definition at line 804 of file chan_misdn.c.
Referenced by _misdn_tasks_add_variable().
00805 { 00806 pthread_kill(misdn_tasks_thread, SIGUSR1); 00807 }
| static int misdn_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Definition at line 3067 of file chan_misdn.c.
References misdn_bchannel::active, misdn_bchannel::addr, ast_debug, ast_log(), chan_list::bc, misdn_bchannel::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, misdn_bchannel::capability, cb_log, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::hold, 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, misdn_bchannel::port, ast_frame::ptr, ast_frame::samples, ast_frame::src, hold_info::state, ast_frame::subclass, and chan_list::ts.
03068 { 03069 struct chan_list *ch; 03070 int i = 0; 03071 03072 if (!ast || ! (ch = MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 03073 03074 if (ch->hold.state != MISDN_HOLD_IDLE) { 03075 chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n"); 03076 return 0; 03077 } 03078 03079 if (!ch->bc ) { 03080 ast_log(LOG_WARNING, "private but no bc\n"); 03081 return -1; 03082 } 03083 03084 if (ch->notxtone) { 03085 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n"); 03086 return 0; 03087 } 03088 03089 03090 if (!frame->subclass) { 03091 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 03092 return 0; 03093 } 03094 03095 if (!(frame->subclass & prefformat)) { 03096 03097 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass); 03098 return 0; 03099 } 03100 03101 03102 if (!frame->samples ) { 03103 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 03104 03105 if (!strcmp(frame->src,"ast_prod")) { 03106 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch)); 03107 03108 if (ch->ts) { 03109 chan_misdn_log(4, ch->bc->port, "Starting Playtones\n"); 03110 misdn_lib_tone_generator_start(ch->bc); 03111 } 03112 return 0; 03113 } 03114 03115 return -1; 03116 } 03117 03118 if ( ! ch->bc->addr ) { 03119 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 03120 return 0; 03121 } 03122 03123 #ifdef MISDN_DEBUG 03124 { 03125 int i, max = 5 > frame->samples ? frame->samples : 5; 03126 03127 ast_debug(1, "write2mISDN %p %d bytes: ", p, frame->samples); 03128 03129 for (i = 0; i < max ; i++) 03130 ast_debug(1, "%2.2x ", ((char*) frame->data.ptr)[i]); 03131 } 03132 #endif 03133 03134 switch (ch->bc->bc_state) { 03135 case BCHAN_ACTIVATED: 03136 case BCHAN_BRIDGED: 03137 break; 03138 default: 03139 if (!ch->dropped_frame_cnt) 03140 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n", frame->samples, ch->bc->addr, ast->exten, ast->cid.cid_num, misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id); 03141 03142 ch->dropped_frame_cnt++; 03143 if (ch->dropped_frame_cnt > 100) { 03144 ch->dropped_frame_cnt = 0; 03145 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); 03146 } 03147 03148 return 0; 03149 } 03150 03151 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples); 03152 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) { 03153 /* Buffered Transmit (triggered by read from isdn side)*/ 03154 if (misdn_jb_fill(ch->jb, frame->data.ptr, frame->samples) < 0) { 03155 if (ch->bc->active) 03156 cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n"); 03157 } 03158 03159 } else { 03160 /*transmit without jitterbuffer*/ 03161 i = misdn_lib_tx2misdn_frm(ch->bc, frame->data.ptr, frame->samples); 03162 } 03163 03164 return 0; 03165 }
| static int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 3854 of file chan_misdn.c.
References chan_list::ast, ast_pbx_start(), and chan_list::need_hangup.
Referenced by cb_events(), do_immediate_setup(), misdn_overlap_dial_task(), and start_pbx().
03855 { 03856 int ret = ast_pbx_start(ch->ast); 03857 03858 if (ret >= 0) 03859 ch->need_hangup = 0; 03860 else 03861 ch->need_hangup = 1; 03862 03863 return ret; 03864 }
| static void print_bc_info | ( | int | fd, | |
| struct chan_list * | help, | |||
| struct misdn_bchannel * | bc | |||
| ) | [static] |
Definition at line 1348 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(), misdn_bchannel::capability, misdn_bchannel::channel, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, misdn_bchannel::display, misdn_bchannel::ec_enable, ast_channel::exten, misdn_bchannel::holded, misdn_bchannel::l3_id, chan_list::l3id, misdn_get_ch_state(), chan_list::norxtone, chan_list::notxtone, misdn_bchannel::nt, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, and misdn_bchannel::rad.
Referenced by handle_cli_misdn_show_channel(), and handle_cli_misdn_show_channels().
01349 { 01350 struct ast_channel *ast = help->ast; 01351 ast_cli(fd, 01352 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n", 01353 01354 bc->pid, bc->port, bc->channel, 01355 bc->nt ? "NT" : "TE", 01356 help->originator == ORG_AST ? "*" : "I", 01357 ast ? ast->exten : NULL, 01358 ast ? ast->cid.cid_num : NULL, 01359 bc->rad, 01360 ast ? ast->context : NULL, 01361 misdn_get_ch_state(help) 01362 ); 01363 if (misdn_debug[bc->port] > 0) 01364 ast_cli(fd, 01365 " --> astname: %s\n" 01366 " --> ch_l3id: %x\n" 01367 " --> ch_addr: %x\n" 01368 " --> bc_addr: %x\n" 01369 " --> bc_l3id: %x\n" 01370 " --> display: %s\n" 01371 " --> activated: %d\n" 01372 " --> state: %s\n" 01373 " --> capability: %s\n" 01374 #ifdef MISDN_1_2 01375 " --> pipeline: %s\n" 01376 #else 01377 " --> echo_cancel: %d\n" 01378 #endif 01379 " --> notone : rx %d tx:%d\n" 01380 " --> bc_hold: %d\n", 01381 help->ast->name, 01382 help->l3id, 01383 help->addr, 01384 bc->addr, 01385 bc ? bc->l3_id : -1, 01386 bc->display, 01387 01388 bc->active, 01389 bc_state2str(bc->bc_state), 01390 bearer2str(bc->capability), 01391 #ifdef MISDN_1_2 01392 bc->pipeline, 01393 #else 01394 bc->ec_enable, 01395 #endif 01396 01397 help->norxtone, help->notxtone, 01398 bc->holded 01399 ); 01400 01401 }
| static void print_bearer | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 672 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().
00673 { 00674 00675 chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability)); 00676 00677 switch(bc->law) { 00678 case INFO_CODEC_ALAW: 00679 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n"); 00680 break; 00681 case INFO_CODEC_ULAW: 00682 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n"); 00683 break; 00684 } 00685 }
| static void print_facility | ( | struct FacParm * | fac, | |
| struct misdn_bchannel * | bc | |||
| ) | [static] |
Definition at line 621 of file chan_misdn.c.
References chan_misdn_log(), and misdn_bchannel::port.
Referenced by cb_events().
00622 { 00623 switch (fac->Function) { 00624 #ifdef HAVE_MISDN_FAC_RESULT 00625 case Fac_RESULT: 00626 chan_misdn_log(0, bc->port," --> Received RESULT Operation\n"); 00627 break; 00628 #endif 00629 #ifdef HAVE_MISDN_FAC_ERROR 00630 case Fac_ERROR: 00631 chan_misdn_log(0, bc->port," --> Received Error Operation\n"); 00632 chan_misdn_log(0, bc->port," --> Value:%d Error:%s\n",fac->u.ERROR.errorValue, fac->u.ERROR.error); 00633 break; 00634 #endif 00635 case Fac_CD: 00636 chan_misdn_log(1,bc->port," --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber, 00637 fac->u.CDeflection.PresentationAllowed ? "yes" : "no"); 00638 break; 00639 case Fac_AOCDCurrency: 00640 if (fac->u.AOCDcur.chargeNotAvailable) 00641 chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n"); 00642 else if (fac->u.AOCDcur.freeOfCharge) 00643 chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n"); 00644 else if (fac->u.AOCDchu.billingId >= 0) 00645 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n", 00646 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00647 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId); 00648 else 00649 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n", 00650 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00651 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00652 break; 00653 case Fac_AOCDChargingUnit: 00654 if (fac->u.AOCDchu.chargeNotAvailable) 00655 chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n"); 00656 else if (fac->u.AOCDchu.freeOfCharge) 00657 chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n"); 00658 else if (fac->u.AOCDchu.billingId >= 0) 00659 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n", 00660 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId); 00661 else 00662 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n", 00663 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00664 break; 00665 case Fac_None: 00666 default: 00667 chan_misdn_log(1,bc->port," --> unknown facility\n"); 00668 break; 00669 } 00670 }
| static struct ast_frame * process_ast_dsp | ( | struct chan_list * | tmp, | |
| struct ast_frame * | frame | |||
| ) | [static, read] |
Definition at line 2904 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_translate(), ast_verb, chan_list::bc, BUFFERSIZE, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, context, chan_list::dsp, misdn_bchannel::ec_enable, ast_channel::exten, f, chan_list::faxdetect, chan_list::faxhandled, ast_frame::frametype, 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(), pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, ast_frame::subclass, chan_list::trans, and misdn_bchannel::txgain.
Referenced by misdn_read().
02905 { 02906 struct ast_frame *f,*f2; 02907 02908 if (tmp->trans) { 02909 f2 = ast_translate(tmp->trans, frame, 0); 02910 f = ast_dsp_process(tmp->ast, tmp->dsp, f2); 02911 } else { 02912 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n"); 02913 return NULL; 02914 } 02915 02916 if (!f || (f->frametype != AST_FRAME_DTMF)) 02917 return frame; 02918 02919 ast_debug(1, "Detected inband DTMF digit: %c\n", f->subclass); 02920 02921 if (tmp->faxdetect && (f->subclass == 'f')) { 02922 /* Fax tone -- Handle and return NULL */ 02923 if (!tmp->faxhandled) { 02924 struct ast_channel *ast = tmp->ast; 02925 tmp->faxhandled++; 02926 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name); 02927 tmp->bc->rxgain = 0; 02928 isdn_lib_update_rxgain(tmp->bc); 02929 tmp->bc->txgain = 0; 02930 isdn_lib_update_txgain(tmp->bc); 02931 #ifdef MISDN_1_2 02932 *tmp->bc->pipeline = 0; 02933 #else 02934 tmp->bc->ec_enable = 0; 02935 #endif 02936 isdn_lib_update_ec(tmp->bc); 02937 isdn_lib_stop_dtmf(tmp->bc); 02938 switch (tmp->faxdetect) { 02939 case 1: 02940 if (strcmp(ast->exten, "fax")) { 02941 char *context; 02942 char context_tmp[BUFFERSIZE]; 02943 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp)); 02944 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp; 02945 if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) { 02946 ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast->name, context); 02947 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02948 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 02949 if (ast_async_goto(ast, context, "fax", 1)) 02950 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context); 02951 } else 02952 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten); 02953 } else { 02954 ast_debug(1, "Already in a fax extension, not redirecting\n"); 02955 } 02956 break; 02957 case 2: 02958 ast_verb(3, "Not redirecting %s to fax extension, nojump is set.\n", ast->name); 02959 break; 02960 } 02961 } else { 02962 ast_debug(1, "Fax already handled\n"); 02963 } 02964 } 02965 02966 if (tmp->ast_dsp && (f->subclass != 'f')) { 02967 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass); 02968 } 02969 02970 return f; 02971 }
| static int read_config | ( | struct chan_list * | ch, | |
| int | orig | |||
| ) | [static] |
Definition at line 2134 of file chan_misdn.c.
References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, ast_copy_string(), chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_mutex_init(), ast_print_group(), ast_set_callerid(), ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, buf, BUFFERSIZE, ast_channel::callgroup, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_rdnis, config_jitterbuffer(), ast_channel::context, chan_list::context, misdn_bchannel::cpnnumplan, misdn_bchannel::dad, debug_numplan(), misdn_bchannel::dnumplan, 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, 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_CFG_ALLOWED_BEARERS, MISDN_CFG_ASTDTMF, MISDN_CFG_CALLERID, MISDN_CFG_CALLGROUP, MISDN_CFG_CONTEXT, MISDN_CFG_CPNDIALPLAN, MISDN_CFG_DIALPLAN, MISDN_CFG_EARLY_BCONNECT, MISDN_CFG_FAR_ALERTING, MISDN_CFG_FAXDETECT, MISDN_CFG_FAXDETECT_TIMEOUT, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_INCOMING_EARLY_AUDIO, MISDN_CFG_INTERNATPREFIX, MISDN_CFG_JITTERBUFFER, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, MISDN_CFG_LANGUAGE, MISDN_CFG_LOCALDIALPLAN, MISDN_CFG_MUSICCLASS, MISDN_CFG_NATPREFIX, MISDN_CFG_NEED_MORE_INFOS, MISDN_CFG_NOAUTORESPOND_ON_SETUP, MISDN_CFG_NTTIMEOUT, 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_bchannel::need_more_infos, chan_list::noautorespond_on_setup, chan_list::nttimeout, NUMPLAN_INTERNATIONAL, NUMPLAN_NATIONAL, misdn_bchannel::oad, misdn_bchannel::onumplan, ORG_AST, misdn_bchannel::orig_dad, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, ast_channel::pickupgroup, misdn_bchannel::port, prefix, misdn_bchannel::rad, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, misdn_bchannel::te_choose_channel, chan_list::trans, misdn_bchannel::txgain, and update_ec_config().
Referenced by cb_events(), and misdn_request().
02135 { 02136 struct ast_channel *ast; 02137 struct misdn_bchannel *bc; 02138 int port; 02139 int hdlc = 0; 02140 char lang[BUFFERSIZE + 1]; 02141 char faxdetect[BUFFERSIZE + 1]; 02142 char buf[256]; 02143 char buf2[256]; 02144 ast_group_t pg; 02145 ast_group_t cg; 02146 02147 if (!ch) { 02148 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 02149 return -1; 02150 } 02151 02152 ast = ch->ast; 02153 bc = ch->bc; 02154 if (! ast || ! bc) { 02155 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 02156 return -1; 02157 } 02158 02159 port = bc->port; 02160 chan_misdn_log(1, port, "read_config: Getting Config\n"); 02161 02162 misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang)); 02163 ast_string_field_set(ast, language, lang); 02164 02165 misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret)); 02166 02167 misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(bc->txgain)); 02168 misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(bc->rxgain)); 02169 02170 misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(ch->incoming_early_audio)); 02171 02172 misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf)); 02173 02174 misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int)); 02175 02176 if (ch->ast_dsp) { 02177 ch->ignore_dtmf = 1; 02178 } 02179 02180 misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(bc->need_more_infos)); 02181 misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(ch->nttimeout)); 02182 02183 misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(ch->noautorespond_on_setup)); 02184 02185 misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(ch->far_alerting)); 02186 02187 misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, sizeof(ch->allowed_bearers)); 02188 02189 misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect)); 02190 02191 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc)); 02192 02193 if (hdlc) { 02194 switch (bc->capability) { 02195 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 02196 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 02197 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 02198 bc->hdlc = 1; 02199 break; 02200 } 02201 02202 } 02203 /*Initialize new Jitterbuffer*/ 02204 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(ch->jb_len)); 02205 misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(ch->jb_upper_threshold)); 02206 02207 config_jitterbuffer(ch); 02208 02209 misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context)); 02210 02211 ast_copy_string(ast->context, ch->context, sizeof(ast->context)); 02212 02213 #ifdef MISDN_1_2 02214 update_pipeline_config(bc); 02215 #else 02216 update_ec_config(bc); 02217 #endif 02218 02219 misdn_cfg_get(bc->port, MISDN_CFG_EARLY_BCONNECT, &bc->early_bconnect, sizeof(bc->early_bconnect)); 02220 02221 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg)); 02222 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg)); 02223 02224 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg)); 02225 ast->pickupgroup = pg; 02226 ast->callgroup = cg; 02227 02228 if (orig == ORG_AST) { 02229 char callerid[BUFFERSIZE + 1]; 02230 02231 /* ORIGINATOR Asterisk (outgoing call) */ 02232 02233 misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(bc->te_choose_channel)); 02234 02235 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) { 02236 if (strstr(faxdetect, "nojump")) 02237 ch->faxdetect = 2; 02238 else 02239 ch->faxdetect = 1; 02240 } 02241 02242 misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid)); 02243 if ( ! ast_strlen_zero(callerid) ) { 02244 chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid); 02245 ast_copy_string(bc->oad, callerid, sizeof(bc->oad)); 02246 } 02247 02248 misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(bc->dnumplan)); 02249 misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(bc->onumplan)); 02250 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(bc->cpnnumplan)); 02251 debug_numplan(port, bc->dnumplan, "TON"); 02252 debug_numplan(port, bc->onumplan, "LTON"); 02253 debug_numplan(port, bc->cpnnumplan, "CTON"); 02254 02255 ch->overlap_dial = 0; 02256 } else { 02257 /* ORIGINATOR MISDN (incoming call) */ 02258 char prefix[BUFFERSIZE + 1] = ""; 02259 02260 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) { 02261 if (strstr(faxdetect, "nojump")) 02262 ch->faxdetect = 2; 02263 else 02264 ch->faxdetect = 1; 02265 } 02266 02267 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(bc->cpnnumplan)); 02268 debug_numplan(port, bc->cpnnumplan, "CTON"); 02269 02270 switch (bc->onumplan) { 02271 case NUMPLAN_INTERNATIONAL: 02272 misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, sizeof(prefix)); 02273 break; 02274 02275 case NUMPLAN_NATIONAL: 02276 misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, sizeof(prefix)); 02277 break; 02278 default: 02279 break; 02280 } 02281 02282 ast_copy_string(buf, bc->oad, sizeof(buf)); 02283 snprintf(bc->oad, sizeof(bc->oad), "%s%s", prefix, buf); 02284 02285 if (!ast_strlen_zero(bc->dad)) { 02286 ast_copy_string(bc->orig_dad, bc->dad, sizeof(bc->orig_dad)); 02287 } 02288 02289 if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) { 02290 ast_copy_string(bc->dad, bc->keypad, sizeof(bc->dad)); 02291 } 02292 02293 prefix[0] = 0; 02294 02295 switch (bc->dnumplan) { 02296 case NUMPLAN_INTERNATIONAL: 02297 misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, sizeof(prefix)); 02298 break; 02299 case NUMPLAN_NATIONAL: 02300 misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, sizeof(prefix)); 02301 break; 02302 default: 02303 break; 02304 } 02305 02306 ast_copy_string(buf, bc->dad, sizeof(buf)); 02307 snprintf(bc->dad, sizeof(bc->dad), "%s%s", prefix, buf); 02308 02309 if (strcmp(bc->dad, ast->exten)) { 02310 ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten)); 02311 } 02312 02313 ast_set_callerid(ast, bc->oad, NULL, bc->oad); 02314 02315 if ( !ast_strlen_zero(bc->rad) ) { 02316 if (ast->cid.cid_rdnis) 02317 ast_free(ast->cid.cid_rdnis); 02318 ast->cid.cid_rdnis = ast_strdup(bc->rad); 02319 } 02320 02321 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial)); 02322 ast_mutex_init(&ch->overlap_tv_lock); 02323 } /* ORIG MISDN END */ 02324 02325 ch->overlap_dial_task = -1; 02326 02327 if (ch->faxdetect || ch->ast_dsp) { 02328 misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 02329 if (!ch->dsp) 02330 ch->dsp = ast_dsp_new(); 02331 if (ch->dsp) { 02332 if (ch->faxdetect) 02333 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT); 02334 else 02335 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT ); 02336 } 02337 if (!ch->trans) 02338 ch->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 02339 } 02340 02341 /* AOCD initialization */ 02342 bc->AOCDtype = Fac_None; 02343 02344 return 0; 02345 }
| static void release_chan | ( | struct chan_list * | ch, | |
| struct misdn_bchannel * | bc | |||
| ) | [static] |
Definition at line 3914 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_free, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, cl_dequeue_chan(), ast_channel::context, ast_channel::exten, chan_list::jb, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_jb_destroy(), misdn_tasks_remove(), misdn_bchannel::nojitter, ORG_AST, chan_list::originator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, misdn_bchannel::pid, chan_list::pipe, misdn_bchannel::port, and chan_list::state.
Referenced by cb_events(), and misdn_hangup().
03915 { 03916 struct ast_channel *ast; 03917 03918 ch->state = MISDN_CLEANING; 03919 03920 ast_mutex_lock(&release_lock); 03921 03922 cl_dequeue_chan(&cl_te, ch); 03923 03924 chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id); 03925 03926 /* releasing jitterbuffer */ 03927 if (ch->jb) { 03928 misdn_jb_destroy(ch->jb); 03929 ch->jb = NULL; 03930 } else { 03931 if (!bc->nojitter) { 03932 chan_misdn_log(5, bc->port, "Jitterbuffer already destroyed.\n"); 03933 } 03934 } 03935 03936 if (ch->overlap_dial) { 03937 if (ch->overlap_dial_task != -1) { 03938 misdn_tasks_remove(ch->overlap_dial_task); 03939 ch->overlap_dial_task = -1; 03940 } 03941 ast_mutex_destroy(&ch->overlap_tv_lock); 03942 } 03943 03944 if (ch->originator == ORG_AST) { 03945 --misdn_out_calls[bc->port]; 03946 } else { 03947 --misdn_in_calls[bc->port]; 03948 } 03949 03950 close(ch->pipe[0]); 03951 close(ch->pipe[1]); 03952 03953 ast = ch->ast; 03954 if (ast) { 03955 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 03956 chan_misdn_log(1, bc->port, 03957 "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s\n", 03958 bc->pid, 03959 ast->context, 03960 ast->exten, 03961 ast->cid.cid_num); 03962 03963 if (ast->_state != AST_STATE_RESERVED) { 03964 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 03965 ast_setstate(ast, AST_STATE_DOWN); 03966 } 03967 } 03968 03969 ast_free(ch); 03970 03971 ast_mutex_unlock(&release_lock); 03972 }
| static void release_chan_early | ( | struct chan_list * | ch | ) | [static] |
Definition at line 3984 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_free, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, cl_dequeue_chan(), chan_list::hold, chan_list::jb, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, MISDN_HOLD_IDLE, misdn_jb_destroy(), misdn_tasks_remove(), ORG_AST, chan_list::originator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, chan_list::pipe, hold_info::port, hold_info::state, and chan_list::state.
Referenced by misdn_hangup().
03985 { 03986 struct ast_channel *ast; 03987 03988 ch->state = MISDN_CLEANING; 03989 03990 ast_mutex_lock(&release_lock); 03991 03992 cl_dequeue_chan(&cl_te, ch); 03993 03994 /* releasing jitterbuffer */ 03995 if (ch->jb) { 03996 misdn_jb_destroy(ch->jb); 03997 ch->jb = NULL; 03998 } 03999 04000 if (ch->overlap_dial) { 04001 if (ch->overlap_dial_task != -1) { 04002 misdn_tasks_remove(ch->overlap_dial_task); 04003 ch->overlap_dial_task = -1; 04004 } 04005 ast_mutex_destroy(&ch->overlap_tv_lock); 04006 } 04007 04008 if (ch->hold.state != MISDN_HOLD_IDLE) { 04009 if (ch->originator == ORG_AST) { 04010 --misdn_out_calls[ch->hold.port]; 04011 } else { 04012 --misdn_in_calls[ch->hold.port]; 04013 } 04014 } 04015 04016 close(ch->pipe[0]); 04017 close(ch->pipe[1]); 04018 04019 ast = ch->ast; 04020 if (ast) { 04021 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 04022 if (ast->_state != AST_STATE_RESERVED) { 04023 ast_setstate(ast, AST_STATE_DOWN); 04024 } 04025 } 04026 04027 ast_free(ch); 04028 04029 ast_mutex_unlock(&release_lock); 04030 }
| static int reload | ( | void | ) | [static] |
Definition at line 5550 of file chan_misdn.c.
References reload_config().
05551 { 05552 reload_config(); 05553 05554 return 0; 05555 }
| static void reload_config | ( | void | ) | [static] |
Definition at line 1305 of file chan_misdn.c.
References ast_log(), free_robin_list(), LOG_WARNING, 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().
01306 { 01307 int i, cfg_debug; 01308 01309 if (!g_config_initialized) { 01310 ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n"); 01311 return ; 01312 } 01313 01314 free_robin_list(); 01315 misdn_cfg_reload(); 01316 misdn_cfg_update_ptp(); 01317 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile)); 01318 misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(cfg_debug)); 01319 01320 for (i = 0; i <= max_ports; i++) { 01321 misdn_debug[i] = cfg_debug; 01322 misdn_debug_only[i] = 0; 01323 } 01324 }
| static void send_cause2ast | ( | struct ast_channel * | ast, | |
| struct misdn_bchannel * | bc, | |||
| struct chan_list * | ch | |||
| ) | [static] |
Definition at line 4139 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().
04139 { 04140 if (!ast) { 04141 chan_misdn_log(1, 0, "send_cause2ast: No Ast\n"); 04142 return; 04143 } 04144 if (!bc) { 04145 chan_misdn_log(1, 0, "send_cause2ast: No BC\n"); 04146 return; 04147 } 04148 if (!ch) { 04149 chan_misdn_log(1, 0, "send_cause2ast: No Ch\n"); 04150 return; 04151 } 04152 04153 ast->hangupcause = bc->cause; 04154 04155 switch (bc->cause) { 04156 04157 case AST_CAUSE_UNALLOCATED: 04158 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: 04159 case AST_CAUSE_NO_ROUTE_DESTINATION: 04160 case 4: /* Send special information tone */ 04161 case AST_CAUSE_NUMBER_CHANGED: 04162 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 04163 /* Congestion Cases */ 04164 /* 04165 * Not Queueing the Congestion anymore, since we want to hear 04166 * the inband message 04167 * 04168 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1); 04169 ch->state = MISDN_BUSY; 04170 04171 ast_queue_control(ast, AST_CONTROL_CONGESTION); 04172 */ 04173 break; 04174 04175 case AST_CAUSE_CALL_REJECTED: 04176 case AST_CAUSE_USER_BUSY: 04177 ch->state = MISDN_BUSY; 04178 04179 if (!ch->need_busy) { 04180 chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n"); 04181 break; 04182 } 04183 04184 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1); 04185 04186 ast_queue_control(ast, AST_CONTROL_BUSY); 04187 04188 ch->need_busy = 0; 04189 04190 break; 04191 } 04192 }
| static void send_digit_to_chan | ( | struct chan_list * | cl, | |
| char | digit | |||
| ) | [static] |
Definition at line 895 of file chan_misdn.c.
References chan_list::ast, ast_debug, ast_playtones_start(), and chan.
Referenced by handle_cli_misdn_send_digit(), and misdn_digit_end().
00896 { 00897 static const char* dtmf_tones[] = { 00898 "!941+1336/100,!0/100", /* 0 */ 00899 "!697+1209/100,!0/100", /* 1 */ 00900 "!697+1336/100,!0/100", /* 2 */ 00901 "!697+1477/100,!0/100", /* 3 */ 00902 "!770+1209/100,!0/100", /* 4 */ 00903 "!770+1336/100,!0/100", /* 5 */ 00904 "!770+1477/100,!0/100", /* 6 */ 00905 "!852+1209/100,!0/100", /* 7 */ 00906 "!852+1336/100,!0/100", /* 8 */ 00907 "!852+1477/100,!0/100", /* 9 */ 00908 "!697+1633/100,!0/100", /* A */ 00909 "!770+1633/100,!0/100", /* B */ 00910 "!852+1633/100,!0/100", /* C */ 00911 "!941+1633/100,!0/100", /* D */ 00912 "!941+1209/100,!0/100", /* * */ 00913 "!941+1477/100,!0/100" }; /* # */ 00914 struct ast_channel *chan=cl->ast; 00915 00916 if (digit >= '0' && digit <='9') 00917 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0); 00918 else if (digit >= 'A' && digit <= 'D') 00919 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0); 00920 else if (digit == '*') 00921 ast_playtones_start(chan,0,dtmf_tones[14], 0); 00922 else if (digit == '#') 00923 ast_playtones_start(chan,0,dtmf_tones[15], 0); 00924 else { 00925 /* not handled */ 00926 ast_debug(1, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name); 00927 } 00928 }
| static void show_config_description | ( | int | fd, | |
| enum misdn_cfg_elements | elem | |||
| ) | [inline, static] |
Definition at line 1154 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().
01155 { 01156 char section[BUFFERSIZE]; 01157 char name[BUFFERSIZE]; 01158 char desc[BUFFERSIZE]; 01159 char def[BUFFERSIZE]; 01160 char tmp[BUFFERSIZE]; 01161 01162 misdn_cfg_get_name(elem, tmp, sizeof(tmp)); 01163 term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp)); 01164 misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def)); 01165 01166 if (elem < MISDN_CFG_LAST) 01167 term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section)); 01168 else 01169 term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section)); 01170 01171 if (*def) 01172 ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc); 01173 else 01174 ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc); 01175 }
| static void sighandler | ( | int | sig | ) | [static] |
| static int start_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3331 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().
03332 { 03333 misdn_lib_tone_generator_stop(cl->bc); 03334 cl->notxtone = 0; 03335 cl->norxtone = 0; 03336 return 0; 03337 }
| static void start_pbx | ( | struct chan_list * | ch, | |
| struct misdn_bchannel * | bc, | |||
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 4285 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().
04285 { 04286 if (pbx_start_chan(ch) < 0) { 04287 hangup_chan(ch, bc); 04288 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 04289 if (bc->nt) { 04290 hanguptone_indicate(ch); 04291 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 04292 } else 04293 misdn_lib_send_event(bc, EVENT_RELEASE); 04294 } 04295 }
| static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3339 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_call(), and misdn_hangup().
| static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 3311 of file chan_misdn.c.
References chan_list::ast, ast_playtones_stop(), 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().
03312 { 03313 struct ast_channel *ast = cl->ast; 03314 03315 if (!ast) { 03316 chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n"); 03317 return -1; 03318 } 03319 03320 chan_misdn_log(3, cl->bc->port, " --> None\n"); 03321 misdn_lib_tone_generator_stop(cl->bc); 03322 ast_playtones_stop(ast); 03323 03324 cl->ts = NULL; 03325 /*ast_deactivate_generator(ast);*/ 03326 03327 return 0; 03328 }
| static int unload_module | ( | void | ) | [static] |
TE STUFF END
Definition at line 5337 of file chan_misdn.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), 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().
05338 { 05339 /* First, take us out of the channel loop */ 05340 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 05341 05342 misdn_tasks_destroy(); 05343 05344 if (!g_config_initialized) 05345 return 0; 05346 05347 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05348 05349 /* ast_unregister_application("misdn_crypt"); */ 05350 ast_unregister_application("misdn_set_opt"); 05351 ast_unregister_application("misdn_facility"); 05352 ast_unregister_application("misdn_check_l2l1"); 05353 05354 ast_channel_unregister(&misdn_tech); 05355 05356 free_robin_list(); 05357 misdn_cfg_destroy(); 05358 misdn_lib_destroy(); 05359 05360 ast_free(misdn_out_calls); 05361 ast_free(misdn_in_calls); 05362 ast_free(misdn_debug_only); 05363 ast_free(misdn_ports); 05364 ast_free(misdn_debug); 05365 05366 return 0; 05367 }
| static int update_config | ( | struct chan_list * | ch, | |
| int | orig | |||
| ) | [static] |
Updates caller ID information from config.
Definition at line 1954 of file chan_misdn.c.
References chan_list::ast, ast_log(), AST_PRES_NETWORK_NUMBER, AST_PRES_RESTRICTED, AST_PRES_UNAVAILABLE, AST_PRES_USER_NUMBER_FAILED_SCREEN, AST_PRES_USER_NUMBER_PASSED_SCREEN, AST_PRES_USER_NUMBER_UNSCREENED, chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, misdn_bchannel::hdlc, INFO_CAPABILITY_DIGITAL_RESTRICTED, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, LOG_WARNING, misdn_cfg_get(), MISDN_CFG_HDLC, MISDN_CFG_PRES, MISDN_CFG_SCREEN, misdn_bchannel::port, misdn_bchannel::pres, and misdn_bchannel::screen.
Referenced by misdn_call().
01955 { 01956 struct ast_channel *ast; 01957 struct misdn_bchannel *bc; 01958 int port, hdlc = 0; 01959 int pres, screen; 01960 01961 if (!ch) { 01962 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01963 return -1; 01964 } 01965 01966 ast = ch->ast; 01967 bc = ch->bc; 01968 if (! ast || ! bc) { 01969 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01970 return -1; 01971 } 01972 01973 port = bc->port; 01974 01975 chan_misdn_log(7, port, "update_config: Getting Config\n"); 01976 01977 misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01978 01979 if (hdlc) { 01980 switch (bc->capability) { 01981 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01982 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01983 chan_misdn_log(1, bc->port, " --> CONF HDLC\n"); 01984 bc->hdlc = 1; 01985 break; 01986 } 01987 } 01988 01989 misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres)); 01990 misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen)); 01991 chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen); 01992 01993 if (pres < 0 || screen < 0) { 01994 chan_misdn_log(2, port, " --> pres: %x\n", ast->cid.cid_pres); 01995 01996 switch (ast->cid.cid_pres & 0x60) { 01997 case AST_PRES_RESTRICTED: 01998 bc->pres = 1; 01999 chan_misdn_log(2, port, " --> PRES: Restricted (1)\n"); 02000 break; 02001 case AST_PRES_UNAVAILABLE: 02002 bc->pres = 2; 02003 chan_misdn_log(2, port, " --> PRES: Unavailable (2)\n"); 02004 break; 02005 default: 02006 bc->pres = 0; 02007 chan_misdn_log(2, port, " --> PRES: Allowed (0)\n"); 02008 break; 02009 } 02010 02011 switch (ast->cid.cid_pres & 0x3) { 02012 default: 02013 case AST_PRES_USER_NUMBER_UNSCREENED: 02014 bc->screen = 0; 02015 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0)\n"); 02016 break; 02017 case AST_PRES_USER_NUMBER_PASSED_SCREEN: 02018 bc->screen = 1; 02019 chan_misdn_log(2, port, " --> SCREEN: Passed Screen (1)\n"); 02020 break; 02021 case AST_PRES_USER_NUMBER_FAILED_SCREEN: 02022 bc->screen = 2; 02023 chan_misdn_log(2, port, " --> SCREEN: Failed Screen (2)\n"); 02024 break; 02025 case AST_PRES_NETWORK_NUMBER: 02026 bc->screen = 3; 02027 chan_misdn_log(2, port, " --> SCREEN: Network Nr. (3)\n"); 02028 break; 02029 } 02030 } else { 02031 bc->screen = screen; 02032 bc->pres = pres; 02033 } 02034 02035 return 0; 02036 }
| static int update_ec_config | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 2115 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().
02116 { 02117 int ec; 02118 int port = bc->port; 02119 02120 misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec)); 02121 02122 if (ec == 1) { 02123 bc->ec_enable = 1; 02124 } else if (ec > 1) { 02125 bc->ec_enable = 1; 02126 bc->ec_deftaps = ec; 02127 } 02128 02129 return 0; 02130 }
| static void update_name | ( | struct ast_channel * | tmp, | |
| int | port, | |||
| int | c | |||
| ) | [static] |
Definition at line 3621 of file chan_misdn.c.
References ast_change_name(), chan_misdn_log(), misdn_cfg_get_next_port(), and misdn_lib_port_is_pri().
Referenced by cb_events().
03622 { 03623 int chan_offset = 0; 03624 int tmp_port = misdn_cfg_get_next_port(0); 03625 char newname[255]; 03626 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03627 if (tmp_port == port) 03628 break; 03629 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03630 } 03631 if (c < 0) 03632 c = 0; 03633 03634 snprintf(newname, sizeof(newname), "%s/%d-", misdn_type, chan_offset + c); 03635 if (strncmp(tmp->name, newname, strlen(newname))) { 03636 snprintf(newname, sizeof(newname), "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 03637 ast_change_name(tmp, newname); 03638 chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name); 03639 } 03640 }
| static void wait_for_digits | ( | struct chan_list * | ch, | |
| struct misdn_bchannel * | bc, | |||
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 4297 of file chan_misdn.c.
References misdn_bchannel::dad, dialtone_indicate(), EVENT_SETUP_ACKNOWLEDGE, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_bchannel::nt, and chan_list::state.
Referenced by cb_events().
04297 { 04298 ch->state=MISDN_WAITING4DIGS; 04299 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04300 if (bc->nt && !bc->dad[0]) 04301 dialtone_indicate(ch); 04302 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 6133 of file chan_misdn.c.
struct allowed_bearers allowed_bearers_array[] [static] |
Definition at line 596 of file chan_misdn.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 6133 of file chan_misdn.c.
struct ast_cli_entry chan_misdn_clis[] [static] |
Definition at line 1929 of file chan_misdn.c.
Global channel call record list head.
Definition at line 516 of file chan_misdn.c.
Definition at line 517 of file chan_misdn.c.
Definition at line 511 of file chan_misdn.c.
int g_config_initialized = 0 [static] |
Definition at line 77 of file chan_misdn.c.
int glob_channel = 0 [static] |
Definition at line 3619 of file chan_misdn.c.
| char global_tracefile[BUFFERSIZE+1] |
Definition at line 75 of file chan_misdn.c.
Definition at line 1500 of file chan_misdn.c.
int max_ports [static] |
Definition at line 505 of file chan_misdn.c.
| int MAXTICS = 8 |
Definition at line 1501 of file chan_misdn.c.
int* misdn_debug [static] |
Definition at line 503 of file chan_misdn.c.
int* misdn_debug_only [static] |
Definition at line 504 of file chan_misdn.c.
int* misdn_in_calls [static] |
Definition at line 507 of file chan_misdn.c.
int* misdn_out_calls [static] |
Definition at line 508 of file chan_misdn.c.
int* misdn_ports [static] |
Definition at line 479 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 476 of file chan_misdn.c.
pthread_t misdn_tasks_thread [static] |
Definition at line 477 of file chan_misdn.c.
struct ast_channel_tech misdn_tech [static] |
Definition at line 3581 of file chan_misdn.c.
struct ast_channel_tech misdn_tech_wo_bridge [static] |
Definition at line 3600 of file chan_misdn.c.
const char misdn_type[] = "mISDN" [static] |
Definition at line 496 of file chan_misdn.c.
int prefformat = AST_FORMAT_ALAW [static] |
Only alaw and mulaw is allowed for now.
Definition at line 501 of file chan_misdn.c.
Definition at line 114 of file chan_misdn.c.
struct robin_list* robin = NULL [static] |
Definition at line 427 of file chan_misdn.c.
struct state_struct state_array[] [static] |
Definition at line 1269 of file chan_misdn.c.
int tracing = 0 [static] |
Definition at line 498 of file chan_misdn.c.
1.6.1