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