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