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