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