#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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct allowed_bearers | allowed_bearers_array [] |
static const 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 5986 of file chan_misdn.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 5986 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 4125 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().
04126 { 04127 int max_in_calls; 04128 04129 misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 04130 misdn_in_calls[port]++; 04131 04132 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) { 04133 ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port); 04134 return misdn_in_calls[port] - max_in_calls; 04135 } 04136 04137 return 0; 04138 }
int add_out_calls | ( | int | port | ) |
Definition at line 4140 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().
04141 { 04142 int max_out_calls; 04143 04144 misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 04145 04146 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) { 04147 ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port); 04148 return (misdn_out_calls[port] + 1) - max_out_calls; 04149 } 04150 04151 misdn_out_calls[port]++; 04152 04153 return 0; 04154 }
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 4180 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, 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().
04181 { 04182 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 04183 04184 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 04185 int debuglevel = 1; 04186 if ( event == EVENT_CLEANUP && !user_data) 04187 debuglevel = 5; 04188 04189 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"); 04190 if (debuglevel == 1) { 04191 misdn_lib_log_ies(bc); 04192 chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state)); 04193 } 04194 } 04195 04196 if (!ch) { 04197 switch(event) { 04198 case EVENT_SETUP: 04199 case EVENT_DISCONNECT: 04200 case EVENT_PORT_ALARM: 04201 case EVENT_RETRIEVE: 04202 case EVENT_NEW_BC: 04203 case EVENT_FACILITY: 04204 break; 04205 case EVENT_RELEASE_COMPLETE: 04206 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); 04207 break; 04208 case EVENT_CLEANUP: 04209 case EVENT_TONE_GENERATE: 04210 case EVENT_BCHAN_DATA: 04211 return -1; 04212 default: 04213 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); 04214 return -1; 04215 } 04216 } 04217 04218 if (ch) { 04219 switch (event) { 04220 case EVENT_TONE_GENERATE: 04221 break; 04222 case EVENT_DISCONNECT: 04223 case EVENT_RELEASE: 04224 case EVENT_RELEASE_COMPLETE: 04225 case EVENT_CLEANUP: 04226 case EVENT_TIMEOUT: 04227 if (!ch->ast) 04228 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)); 04229 break; 04230 default: 04231 if (!ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 04232 if (event != EVENT_BCHAN_DATA) 04233 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 04234 return -1; 04235 } 04236 } 04237 } 04238 04239 04240 switch (event) { 04241 case EVENT_PORT_ALARM: 04242 { 04243 int boa = 0; 04244 misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(boa)); 04245 if (boa) { 04246 cb_log(1, bc->port, " --> blocking\n"); 04247 misdn_lib_port_block(bc->port); 04248 } 04249 } 04250 break; 04251 case EVENT_BCHAN_ACTIVATED: 04252 break; 04253 04254 case EVENT_NEW_CHANNEL: 04255 update_name(ch->ast,bc->port,bc->channel); 04256 break; 04257 04258 case EVENT_NEW_L3ID: 04259 ch->l3id=bc->l3_id; 04260 ch->addr=bc->addr; 04261 break; 04262 04263 case EVENT_NEW_BC: 04264 if (!ch) { 04265 ch = find_holded(cl_te,bc); 04266 } 04267 04268 if (!ch) { 04269 ast_log(LOG_WARNING, "NEW_BC without chan_list?\n"); 04270 break; 04271 } 04272 04273 if (bc) 04274 ch->bc = (struct misdn_bchannel *)user_data; 04275 break; 04276 04277 case EVENT_DTMF_TONE: 04278 { 04279 /* sending INFOS as DTMF-Frames :) */ 04280 struct ast_frame fr = { 0, }; 04281 fr.frametype = AST_FRAME_DTMF; 04282 fr.subclass = bc->dtmf ; 04283 fr.src = NULL; 04284 fr.data = NULL; 04285 fr.datalen = 0; 04286 fr.samples = 0; 04287 fr.mallocd = 0; 04288 fr.offset = 0; 04289 fr.delivery = ast_tv(0,0); 04290 04291 if (!ch->ignore_dtmf) { 04292 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 04293 ast_queue_frame(ch->ast, &fr); 04294 } else { 04295 chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf); 04296 } 04297 } 04298 break; 04299 case EVENT_STATUS: 04300 break; 04301 04302 case EVENT_INFORMATION: 04303 { 04304 if ( ch->state != MISDN_CONNECTED ) 04305 stop_indicate(ch); 04306 04307 if (!ch->ast) 04308 break; 04309 04310 if (ch->state == MISDN_WAITING4DIGS ) { 04311 /* Ok, incomplete Setup, waiting till extension exists */ 04312 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 04313 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 04314 ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad)); 04315 } 04316 04317 strncat(bc->dad,bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1); 04318 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04319 04320 /* Check for Pickup Request first */ 04321 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 04322 if (ast_pickup_call(ch->ast)) { 04323 hangup_chan(ch); 04324 } else { 04325 struct ast_channel *chan = ch->ast; 04326 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04327 ast_setstate(chan, AST_STATE_DOWN); 04328 hangup_chan(ch); 04329 ch->ast = NULL; 04330 break; 04331 } 04332 } 04333 04334 if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04335 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04336 ast_log(LOG_WARNING, 04337 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 04338 bc->dad, ch->context, bc->port); 04339 strcpy(ch->ast->exten, "i"); 04340 04341 ch->state = MISDN_DIALING; 04342 start_pbx(ch, bc, ch->ast); 04343 break; 04344 } 04345 04346 ast_log(LOG_WARNING, 04347 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 04348 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04349 bc->dad, ch->context, 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 = 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, 04609 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n", 04610 bc->dad, ch->context, bc->port); 04611 strcpy(ch->ast->exten, "i"); 04612 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 04613 ch->state = MISDN_DIALING; 04614 start_pbx(ch, bc, chan); 04615 break; 04616 } 04617 04618 ast_log(LOG_WARNING, 04619 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 04620 "\tMaybe you want to add an 'i' extension to catch this case.\n", 04621 bc->dad, ch->context, bc->port); 04622 if (bc->nt) 04623 hanguptone_indicate(ch); 04624 04625 ch->state = MISDN_EXTCANTMATCH; 04626 bc->out_cause = AST_CAUSE_UNALLOCATED; 04627 04628 if (bc->nt) 04629 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04630 else 04631 misdn_lib_send_event(bc, EVENT_RELEASE ); 04632 04633 break; 04634 } 04635 04636 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 04637 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 04638 * will be used by Asterisk automatically. */ 04639 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 04640 if (!ch->noautorespond_on_setup) { 04641 ch->state=MISDN_DIALING; 04642 misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04643 } else { 04644 ch->state = MISDN_INCOMING_SETUP; 04645 } 04646 start_pbx(ch, bc, chan); 04647 break; 04648 } 04649 04650 04651 /* 04652 * When we are NT and overlapdial is set and if 04653 * the number is empty, we wait for the ISDN timeout 04654 * instead of our own timer. 04655 */ 04656 if (ch->overlap_dial && bc->nt && !bc->dad[0] ) { 04657 wait_for_digits(ch, bc, chan); 04658 break; 04659 } 04660 04661 /* 04662 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 04663 * Infos with a Interdigit Timeout. 04664 * */ 04665 if (ch->overlap_dial) { 04666 ast_mutex_lock(&ch->overlap_tv_lock); 04667 ch->overlap_tv = ast_tvnow(); 04668 ast_mutex_unlock(&ch->overlap_tv_lock); 04669 04670 wait_for_digits(ch, bc, chan); 04671 if (ch->overlap_dial_task == -1) 04672 ch->overlap_dial_task = 04673 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04674 04675 break; 04676 } 04677 04678 /* If the extension does not exist and we're not TE_PTMP we wait for more digits 04679 * without interdigit timeout. 04680 * */ 04681 if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04682 wait_for_digits(ch, bc, chan); 04683 break; 04684 } 04685 04686 /* 04687 * If the extension exists let's just jump into it. 04688 * */ 04689 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04690 if (bc->need_more_infos) 04691 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04692 else 04693 misdn_lib_send_event(bc, EVENT_PROCEEDING); 04694 04695 ch->state = MISDN_DIALING; 04696 start_pbx(ch, bc, chan); 04697 break; 04698 } 04699 } 04700 break; 04701 04702 case EVENT_SETUP_ACKNOWLEDGE: 04703 { 04704 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04705 04706 if (bc->channel) 04707 update_name(ch->ast,bc->port,bc->channel); 04708 04709 if (!ast_strlen_zero(bc->infos_pending)) { 04710 /* TX Pending Infos */ 04711 strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad) - 1); 04712 04713 if (!ch->ast) 04714 break; 04715 ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten)); 04716 ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad)); 04717 ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending)); 04718 04719 misdn_lib_send_event(bc, EVENT_INFORMATION); 04720 } 04721 } 04722 break; 04723 case EVENT_PROCEEDING: 04724 { 04725 04726 if (misdn_cap_is_speech(bc->capability) && 04727 misdn_inband_avail(bc) ) { 04728 start_bc_tones(ch); 04729 } 04730 04731 ch->state = MISDN_PROCEEDING; 04732 04733 if (!ch->ast) 04734 break; 04735 04736 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 04737 } 04738 break; 04739 case EVENT_PROGRESS: 04740 04741 if (bc->channel) 04742 update_name(ch->ast, bc->port, bc->channel); 04743 04744 if (!bc->nt ) { 04745 if ( misdn_cap_is_speech(bc->capability) && 04746 misdn_inband_avail(bc) 04747 ) { 04748 start_bc_tones(ch); 04749 } 04750 04751 ch->state = MISDN_PROGRESS; 04752 04753 if (!ch->ast) 04754 break; 04755 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 04756 } 04757 break; 04758 04759 04760 case EVENT_ALERTING: 04761 { 04762 ch->state = MISDN_ALERTING; 04763 04764 if (!ch->ast) 04765 break; 04766 04767 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 04768 ast_setstate(ch->ast, AST_STATE_RINGING); 04769 04770 cb_log(7, bc->port, " --> Set State Ringing\n"); 04771 04772 if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 04773 cb_log(1, bc->port, "Starting Tones, we have inband Data\n"); 04774 start_bc_tones(ch); 04775 } else { 04776 cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n"); 04777 if (ch->far_alerting) { 04778 cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself.."); 04779 start_bc_tones(ch); 04780 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 04781 } 04782 } 04783 } 04784 break; 04785 case EVENT_CONNECT: 04786 { 04787 struct ast_channel *bridged; 04788 04789 /*we answer when we've got our very new L3 ID from the NT stack */ 04790 misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE); 04791 04792 if (!ch->ast) 04793 break; 04794 04795 bridged = ast_bridged_channel(ch->ast); 04796 stop_indicate(ch); 04797 04798 if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) { 04799 struct chan_list *bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged); 04800 04801 chan_misdn_log(1, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad); 04802 if (bridged_ch) { 04803 bridged_ch->bc->cpnnumplan = bc->cpnnumplan; 04804 ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bridged_ch->bc->cad)); 04805 } 04806 } 04807 } 04808 ch->l3id=bc->l3_id; 04809 ch->addr=bc->addr; 04810 04811 start_bc_tones(ch); 04812 04813 ch->state = MISDN_CONNECTED; 04814 04815 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 04816 break; 04817 case EVENT_CONNECT_ACKNOWLEDGE: 04818 { 04819 ch->l3id = bc->l3_id; 04820 ch->addr = bc->addr; 04821 04822 start_bc_tones(ch); 04823 04824 ch->state = MISDN_CONNECTED; 04825 } 04826 break; 04827 case EVENT_DISCONNECT: 04828 /*we might not have an ch->ast ptr here anymore*/ 04829 if (ch) { 04830 struct chan_list *holded_ch = find_holded(cl_te, bc); 04831 04832 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); 04833 if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 04834 /* If there's inband information available (e.g. a 04835 recorded message saying what was wrong with the 04836 dialled number, or perhaps even giving an 04837 alternative number, then play it instead of 04838 immediately releasing the call */ 04839 chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 04840 04841 ch->state = MISDN_DISCONNECTED; 04842 start_bc_tones(ch); 04843 04844 if (ch->ast) { 04845 ch->ast->hangupcause = bc->cause; 04846 if (bc->cause == AST_CAUSE_USER_BUSY) 04847 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 04848 } 04849 ch->need_busy = 0; 04850 break; 04851 } 04852 04853 /*Check for holded channel, to implement transfer*/ 04854 if (holded_ch && holded_ch != ch && ch->ast && ch->state == MISDN_CONNECTED) { 04855 cb_log(1, bc->port, " --> found holded ch\n"); 04856 misdn_transfer_bc(ch, holded_ch) ; 04857 } 04858 04859 bc->need_disconnect = 0; 04860 04861 stop_bc_tones(ch); 04862 hangup_chan(ch); 04863 #if 0 04864 } else { 04865 ch = find_holded_l3(cl_te, bc->l3_id,1); 04866 if (ch) { 04867 hangup_chan(ch); 04868 } 04869 #endif 04870 } 04871 bc->out_cause = -1; 04872 if (bc->need_release) 04873 misdn_lib_send_event(bc, EVENT_RELEASE); 04874 break; 04875 04876 case EVENT_RELEASE: 04877 { 04878 bc->need_disconnect = 0; 04879 bc->need_release = 0; 04880 04881 hangup_chan(ch); 04882 release_chan(bc); 04883 } 04884 break; 04885 case EVENT_RELEASE_COMPLETE: 04886 { 04887 bc->need_disconnect = 0; 04888 bc->need_release = 0; 04889 bc->need_release_complete = 0; 04890 04891 stop_bc_tones(ch); 04892 hangup_chan(ch); 04893 04894 if (ch) 04895 ch->state = MISDN_CLEANING; 04896 04897 release_chan(bc); 04898 } 04899 break; 04900 case EVENT_BCHAN_ERROR: 04901 case EVENT_CLEANUP: 04902 { 04903 stop_bc_tones(ch); 04904 04905 switch (ch->state) { 04906 case MISDN_CALLING: 04907 bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 04908 break; 04909 default: 04910 break; 04911 } 04912 04913 hangup_chan(ch); 04914 release_chan(bc); 04915 } 04916 break; 04917 04918 case EVENT_TONE_GENERATE: 04919 { 04920 int tone_len = bc->tone_cnt; 04921 struct ast_channel *ast = ch->ast; 04922 void *tmp; 04923 int res; 04924 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 04925 04926 chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len); 04927 04928 if (!ast) 04929 break; 04930 04931 if (!ast->generator) 04932 break; 04933 04934 tmp = ast->generatordata; 04935 ast->generatordata = NULL; 04936 generate = ast->generator->generate; 04937 04938 if (tone_len < 0 || tone_len > 512 ) { 04939 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len); 04940 tone_len = 128; 04941 } 04942 04943 res = generate(ast, tmp, tone_len, tone_len); 04944 ast->generatordata = tmp; 04945 04946 if (res) { 04947 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 04948 ast_deactivate_generator(ast); 04949 } else { 04950 bc->tone_cnt = 0; 04951 } 04952 } 04953 break; 04954 04955 case EVENT_BCHAN_DATA: 04956 { 04957 if (ch->bc->AOCD_need_export) 04958 export_aoc_vars(ch->originator, ch->ast, ch->bc); 04959 if (!misdn_cap_is_speech(ch->bc->capability) ) { 04960 struct ast_frame frame; 04961 /*In Data Modes we queue frames*/ 04962 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 04963 frame.subclass = AST_FORMAT_ALAW; 04964 frame.datalen = bc->bframe_len; 04965 frame.samples = bc->bframe_len; 04966 frame.mallocd = 0; 04967 frame.offset = 0; 04968 frame.delivery = ast_tv(0,0); 04969 frame.src = NULL; 04970 frame.data = bc->bframe; 04971 04972 if (ch->ast) 04973 ast_queue_frame(ch->ast, &frame); 04974 } else { 04975 fd_set wrfs; 04976 struct timeval tv = { 0, 0 }; 04977 int t; 04978 04979 FD_ZERO(&wrfs); 04980 FD_SET(ch->pipe[1], &wrfs); 04981 04982 t = select(FD_SETSIZE, NULL, &wrfs, NULL, &tv); 04983 04984 if (!t) { 04985 chan_misdn_log(9, bc->port, "Select Timed out\n"); 04986 break; 04987 } 04988 04989 if (t < 0) { 04990 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n", strerror(errno)); 04991 break; 04992 } 04993 04994 if (FD_ISSET(ch->pipe[1], &wrfs)) { 04995 chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n", bc->bframe_len); 04996 if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) { 04997 chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno)); 04998 04999 stop_bc_tones(ch); 05000 hangup_chan(ch); 05001 release_chan(bc); 05002 } 05003 } else { 05004 chan_misdn_log(1, bc->port, "Write Pipe full!\n"); 05005 } 05006 } 05007 } 05008 break; 05009 case EVENT_TIMEOUT: 05010 { 05011 if (ch && bc) 05012 chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch)); 05013 05014 switch (ch->state) { 05015 case MISDN_DIALING: 05016 case MISDN_PROGRESS: 05017 if (bc->nt && !ch->nttimeout) 05018 break; 05019 05020 case MISDN_CALLING: 05021 case MISDN_ALERTING: 05022 case MISDN_PROCEEDING: 05023 case MISDN_CALLING_ACKNOWLEDGE: 05024 if (bc->nt) { 05025 bc->progress_indicator = 8; 05026 hanguptone_indicate(ch); 05027 } 05028 05029 bc->out_cause = AST_CAUSE_UNALLOCATED; 05030 misdn_lib_send_event(bc, EVENT_DISCONNECT); 05031 break; 05032 05033 case MISDN_WAITING4DIGS: 05034 if (bc->nt) { 05035 bc->progress_indicator = 8; 05036 bc->out_cause = AST_CAUSE_UNALLOCATED; 05037 hanguptone_indicate(ch); 05038 misdn_lib_send_event(bc, EVENT_DISCONNECT); 05039 } else { 05040 bc->out_cause = AST_CAUSE_NORMAL_CLEARING; 05041 misdn_lib_send_event(bc, EVENT_RELEASE); 05042 } 05043 05044 break; 05045 05046 case MISDN_CLEANING: 05047 chan_misdn_log(1,bc->port," --> in state cleaning .. so ignoring, the stack should clean it for us\n"); 05048 break; 05049 05050 default: 05051 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 05052 } 05053 } 05054 break; 05055 05056 05057 /****************************/ 05058 /** Supplementary Services **/ 05059 /****************************/ 05060 case EVENT_RETRIEVE: 05061 { 05062 struct ast_channel *hold_ast; 05063 05064 if (!ch) { 05065 chan_misdn_log(4, bc->port, " --> no CH, searching in holded\n"); 05066 ch = find_holded_l3(cl_te, bc->l3_id, 1); 05067 } 05068 05069 if (!ch) { 05070 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n"); 05071 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 05072 break; 05073 } 05074 05075 /*remember the channel again*/ 05076 ch->bc = bc; 05077 ch->state = MISDN_CONNECTED; 05078 05079 ch->hold_info.port = 0; 05080 ch->hold_info.channel = 0; 05081 05082 hold_ast = ast_bridged_channel(ch->ast); 05083 05084 if (hold_ast) { 05085 ast_moh_stop(hold_ast); 05086 } 05087 05088 if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) { 05089 chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n"); 05090 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 05091 } 05092 } 05093 break; 05094 05095 case EVENT_HOLD: 05096 { 05097 int hold_allowed; 05098 struct ast_channel *bridged = ast_bridged_channel(ch->ast); 05099 05100 misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(hold_allowed)); 05101 05102 if (!hold_allowed) { 05103 05104 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 05105 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 05106 break; 05107 } 05108 05109 if (bridged) { 05110 chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type); 05111 ch->state = MISDN_HOLDED; 05112 ch->l3id = bc->l3_id; 05113 05114 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 05115 05116 /* XXX This should queue an AST_CONTROL_HOLD frame on this channel 05117 * instead of starting moh on the bridged channel directly */ 05118 ast_moh_start(bridged, NULL, NULL); 05119 05120 /*forget the channel now*/ 05121 ch->bc = NULL; 05122 ch->hold_info.port = bc->port; 05123 ch->hold_info.channel = bc->channel; 05124 05125 } else { 05126 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 05127 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 05128 } 05129 } 05130 break; 05131 05132 case EVENT_FACILITY: 05133 print_facility(&(bc->fac_in), bc); 05134 05135 switch (bc->fac_in.Function) { 05136 #ifdef HAVE_MISDN_FAC_RESULT 05137 case Fac_RESULT: 05138 break; 05139 #endif 05140 case Fac_CD: 05141 if (ch) { 05142 struct ast_channel *bridged = ast_bridged_channel(ch->ast); 05143 struct chan_list *ch_br; 05144 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 05145 ch_br = MISDN_ASTERISK_TECH_PVT(bridged); 05146 /*ch->state = MISDN_FACILITY_DEFLECTED;*/ 05147 if (ch_br->bc) { 05148 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) { 05149 ch_br->state = MISDN_DIALING; 05150 if (pbx_start_chan(ch_br) < 0) { 05151 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 05152 } 05153 } 05154 } 05155 } 05156 misdn_lib_send_event(bc, EVENT_DISCONNECT); 05157 } 05158 break; 05159 case Fac_AOCDCurrency: 05160 if (ch) { 05161 bc->AOCDtype = Fac_AOCDCurrency; 05162 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(bc->AOCD.currency)); 05163 bc->AOCD_need_export = 1; 05164 export_aoc_vars(ch->originator, ch->ast, bc); 05165 } 05166 break; 05167 case Fac_AOCDChargingUnit: 05168 if (ch) { 05169 bc->AOCDtype = Fac_AOCDChargingUnit; 05170 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(bc->AOCD.chargingUnit)); 05171 bc->AOCD_need_export = 1; 05172 export_aoc_vars(ch->originator, ch->ast, bc); 05173 } 05174 break; 05175 case Fac_None: 05176 #ifdef HAVE_MISDN_FAC_ERROR 05177 case Fac_ERROR: 05178 #endif 05179 break; 05180 default: 05181 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%d\n", bc->fac_in.Function); 05182 } 05183 05184 break; 05185 05186 case EVENT_RESTART: 05187 05188 if (!bc->dummy) { 05189 stop_bc_tones(ch); 05190 release_chan(bc); 05191 } 05192 break; 05193 05194 default: 05195 chan_misdn_log(1, 0, "Got Unknown Event\n"); 05196 break; 05197 } 05198 05199 return RESPONSE_OK; 05200 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 5737 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().
05738 { 05739 struct chan_list *ch = find_chan_by_bc(cl_te, bc); 05740 05741 if (ch && ch->jb) { 05742 return misdn_jb_empty(ch->jb, buf, len); 05743 } 05744 05745 return -1; 05746 }
static void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 5922 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().
05923 { 05924 va_list ap; 05925 char buf[1024]; 05926 char port_buf[8]; 05927 05928 if (! ((0 <= port) && (port <= max_ports))) { 05929 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 05930 port = 0; 05931 level = -1; 05932 } 05933 05934 snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port); 05935 05936 va_start(ap, tmpl); 05937 vsnprintf(buf, sizeof(buf), tmpl, ap); 05938 va_end(ap); 05939 05940 if (level == -1) 05941 ast_log(LOG_WARNING, "%s", buf); 05942 05943 else if (misdn_debug_only[port] ? 05944 (level == 1 && misdn_debug[port]) || (level == misdn_debug[port]) 05945 : level <= misdn_debug[port]) { 05946 05947 ast_console_puts(port_buf); 05948 ast_console_puts(buf); 05949 } 05950 05951 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 05952 char ctimebuf[30]; 05953 time_t tm = time(NULL); 05954 char *tmp = ctime_r(&tm, ctimebuf), *p; 05955 05956 FILE *fp = fopen(global_tracefile, "a+"); 05957 05958 p = strchr(tmp, '\n'); 05959 if (p) 05960 *p = ':'; 05961 05962 if (!fp) { 05963 ast_console_puts("Error opening Tracefile: [ "); 05964 ast_console_puts(global_tracefile); 05965 ast_console_puts(" ] "); 05966 05967 ast_console_puts(strerror(errno)); 05968 ast_console_puts("\n"); 05969 return ; 05970 } 05971 05972 fputs(tmp, fp); 05973 fputs(" ", fp); 05974 fputs(port_buf, fp); 05975 fputs(" ", fp); 05976 fputs(buf, fp); 05977 05978 fclose(fp); 05979 } 05980 }
Definition at line 3784 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().
03785 { 03786 struct chan_list *help; 03787 03788 if (chan->dsp) 03789 ast_dsp_free(chan->dsp); 03790 if (chan->trans) 03791 ast_translator_free_path(chan->trans); 03792 03793 ast_mutex_lock(&cl_te_lock); 03794 if (!*list) { 03795 ast_mutex_unlock(&cl_te_lock); 03796 return; 03797 } 03798 03799 if (*list == chan) { 03800 *list = (*list)->next; 03801 ast_mutex_unlock(&cl_te_lock); 03802 return; 03803 } 03804 03805 for (help = *list; help->next; help = help->next) { 03806 if (help->next == chan) { 03807 help->next = help->next->next; 03808 ast_mutex_unlock(&cl_te_lock); 03809 return; 03810 } 03811 } 03812 03813 ast_mutex_unlock(&cl_te_lock); 03814 }
Definition at line 3768 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().
03769 { 03770 chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan); 03771 03772 ast_mutex_lock(&cl_te_lock); 03773 if (!*list) { 03774 *list = chan; 03775 } else { 03776 struct chan_list *help = *list; 03777 for (; help->next; help = help->next); 03778 help->next = chan; 03779 } 03780 chan->next = NULL; 03781 ast_mutex_unlock(&cl_te_lock); 03782 }
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 3951 of file chan_misdn.c.
References chan_list::ast, ast_canmatch_extension(), AST_CAUSE_UNALLOCATED, AST_FRAME_DTMF, ast_queue_frame(), ast_strdupa, ast_strlen_zero(), ast_tv(), chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_RELEASE_COMPLETE, EVENT_SETUP_ACKNOWLEDGE, ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_send_event(), chan_list::noautorespond_on_setup, misdn_bchannel::nt, misdn_bchannel::oad, ast_frame::offset, misdn_bchannel::out_cause, pbx_start_chan(), misdn_bchannel::port, ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass.
Referenced by cb_events().
03952 { 03953 char *predial; 03954 struct ast_frame fr; 03955 03956 predial = ast_strdupa(ast->exten); 03957 03958 ch->state = MISDN_DIALING; 03959 03960 if (!ch->noautorespond_on_setup) { 03961 if (bc->nt) { 03962 int ret; 03963 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03964 } else { 03965 int ret; 03966 if ( misdn_lib_is_ptp(bc->port)) { 03967 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03968 } else { 03969 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03970 } 03971 } 03972 } else { 03973 ch->state = MISDN_INCOMING_SETUP; 03974 } 03975 03976 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); 03977 03978 strncpy(ast->exten, "s", 2); 03979 03980 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->oad) || pbx_start_chan(ch) < 0) { 03981 ast = NULL; 03982 bc->out_cause = AST_CAUSE_UNALLOCATED; 03983 hangup_chan(ch); 03984 hanguptone_indicate(ch); 03985 03986 if (bc->nt) 03987 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03988 else 03989 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03990 } 03991 03992 03993 while (!ast_strlen_zero(predial) ) { 03994 fr.frametype = AST_FRAME_DTMF; 03995 fr.subclass = *predial; 03996 fr.src = NULL; 03997 fr.data = NULL; 03998 fr.datalen = 0; 03999 fr.samples = 0; 04000 fr.mallocd = 0; 04001 fr.offset = 0; 04002 fr.delivery = ast_tv(0,0); 04003 04004 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 04005 ast_queue_frame(ch->ast, &fr); 04006 } 04007 predial++; 04008 } 04009 }
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 4101 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().
04102 { 04103 char tmp[32]; 04104 chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid); 04105 snprintf(tmp, sizeof(tmp), "%d", bc->pid); 04106 pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp); 04107 04108 if (bc->sending_complete) { 04109 snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete); 04110 pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp); 04111 } 04112 04113 if (bc->urate) { 04114 snprintf(tmp, sizeof(tmp), "%d", bc->urate); 04115 pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp); 04116 } 04117 04118 if (bc->uulen) 04119 pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu); 04120 04121 if (!ast_strlen_zero(bc->keypad)) 04122 pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad); 04123 }
static struct chan_list * find_chan_by_bc | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3711 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().
03712 { 03713 struct chan_list *help = list; 03714 for (; help; help = help->next) { 03715 if (help->bc == bc) return help; 03716 } 03717 03718 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad); 03719 03720 return NULL; 03721 }
Definition at line 3723 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::pid.
Referenced by import_ch().
03724 { 03725 struct chan_list *help = list; 03726 for (; help; help = help->next) { 03727 if ( help->bc && (help->bc->pid == pid) ) return help; 03728 } 03729 03730 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n", pid); 03731 03732 return NULL; 03733 }
static struct chan_list* find_holded | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 3735 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().
03736 { 03737 struct chan_list *help = list; 03738 03739 if (bc->pri) return NULL; 03740 03741 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n", bc->channel, bc->oad, bc->dad); 03742 for (;help; help = help->next) { 03743 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n", help->state==MISDN_HOLDED, help->hold_info.channel); 03744 if ( (help->state == MISDN_HOLDED) && 03745 (help->hold_info.port == bc->port) ) 03746 return help; 03747 } 03748 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad); 03749 03750 return NULL; 03751 }
static struct chan_list* find_holded_l3 | ( | struct chan_list * | list, | |
unsigned long | l3_id, | |||
int | w | |||
) | [static] |
Definition at line 3754 of file chan_misdn.c.
References chan_list::l3id, MISDN_HOLDED, chan_list::next, and chan_list::state.
Referenced by cb_events().
03755 { 03756 struct chan_list *help = list; 03757 03758 for (; help; help = help->next) { 03759 if ( (help->state == MISDN_HOLDED) && 03760 (help->l3id == l3_id) 03761 ) 03762 return help; 03763 } 03764 03765 return NULL; 03766 }
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 3831 of file chan_misdn.c.
References chan_list::ast, ast_hangup(), ast_queue_hangup(), chan_list::bc, 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().
03832 { 03833 int port = ch ? (ch->bc ? ch->bc->port : 0) : 0; 03834 if (!ch) { 03835 cb_log(1, 0, "Cannot hangup chan, no ch\n"); 03836 return; 03837 } 03838 03839 cb_log(5, port, "hangup_chan called\n"); 03840 03841 if (ch->need_hangup) { 03842 cb_log(2, port, " --> hangup\n"); 03843 send_cause2ast(ch->ast, ch->bc, ch); 03844 ch->need_hangup = 0; 03845 ch->need_queue_hangup = 0; 03846 if (ch->ast) 03847 ast_hangup(ch->ast); 03848 return; 03849 } 03850 03851 if (!ch->need_queue_hangup) { 03852 cb_log(2, port, " --> No need to queue hangup\n"); 03853 } 03854 03855 ch->need_queue_hangup = 0; 03856 if (ch->ast) { 03857 send_cause2ast(ch->ast, ch->bc, ch); 03858 03859 if (ch->ast) 03860 ast_queue_hangup(ch->ast); 03861 cb_log(2, port, " --> queue_hangup\n"); 03862 } else { 03863 cb_log(1, port, "Cannot hangup chan, no ast\n"); 03864 } 03865 }
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 4070 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().
04071 { 04072 const char *tmp = pbx_builtin_getvar_helper(chan, "MISDN_PID"); 04073 if (tmp) { 04074 ch->other_pid = atoi(tmp); 04075 chan_misdn_log(3, bc->port, " --> IMPORT_PID: importing pid:%s\n", tmp); 04076 if (ch->other_pid > 0) { 04077 ch->other_ch = find_chan_by_pid(cl_te, ch->other_pid); 04078 if (ch->other_ch) 04079 ch->other_ch->other_ch = ch; 04080 } 04081 } 04082 04083 tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE"); 04084 if (tmp && (atoi(tmp) == 1)) { 04085 bc->sending_complete = 1; 04086 } 04087 04088 tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER"); 04089 if (tmp) { 04090 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 04091 ast_copy_string(bc->uu, tmp, sizeof(bc->uu)); 04092 bc->uulen = strlen(bc->uu); 04093 } 04094 04095 tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD"); 04096 if (tmp) 04097 ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad)); 04098 }
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 5245 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().
05246 { 05247 int i, port; 05248 int ntflags = 0, ntkc = 0; 05249 char ports[256] = ""; 05250 char tempbuf[BUFFERSIZE + 1]; 05251 char ntfile[BUFFERSIZE + 1]; 05252 struct misdn_lib_iface iface = { 05253 .cb_event = cb_events, 05254 .cb_log = chan_misdn_log, 05255 .cb_jb_empty = chan_misdn_jb_empty, 05256 }; 05257 05258 max_ports = misdn_lib_maxports_get(); 05259 05260 if (max_ports <= 0) { 05261 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 05262 return AST_MODULE_LOAD_DECLINE; 05263 } 05264 05265 if (misdn_cfg_init(max_ports, 0)) { 05266 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 05267 return AST_MODULE_LOAD_DECLINE; 05268 } 05269 g_config_initialized = 1; 05270 05271 misdn_debug = ast_malloc(sizeof(int) * (max_ports + 1)); 05272 if (!misdn_debug) { 05273 ast_log(LOG_ERROR, "Out of memory for misdn_debug\n"); 05274 return AST_MODULE_LOAD_DECLINE; 05275 } 05276 misdn_ports = ast_malloc(sizeof(int) * (max_ports + 1)); 05277 if (!misdn_ports) { 05278 ast_log(LOG_ERROR, "Out of memory for misdn_ports\n"); 05279 return AST_MODULE_LOAD_DECLINE; 05280 } 05281 misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(misdn_debug[0])); 05282 for (i = 1; i <= max_ports; i++) { 05283 misdn_debug[i] = misdn_debug[0]; 05284 misdn_ports[i] = i; 05285 } 05286 *misdn_ports = 0; 05287 misdn_debug_only = ast_calloc(max_ports + 1, sizeof(int)); 05288 05289 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, sizeof(tempbuf)); 05290 if (!ast_strlen_zero(tempbuf)) 05291 tracing = 1; 05292 05293 misdn_in_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 05294 misdn_out_calls = ast_malloc(sizeof(int) * (max_ports + 1)); 05295 05296 for (i = 1; i <= max_ports; i++) { 05297 misdn_in_calls[i] = 0; 05298 misdn_out_calls[i] = 0; 05299 } 05300 05301 ast_mutex_init(&cl_te_lock); 05302 ast_mutex_init(&release_lock); 05303 05304 misdn_cfg_update_ptp(); 05305 misdn_cfg_get_ports_string(ports); 05306 05307 if (!ast_strlen_zero(ports)) 05308 chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports); 05309 if (misdn_lib_init(ports, &iface, NULL)) 05310 chan_misdn_log(0, 0, "No te ports initialized\n"); 05311 05312 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(ntflags)); 05313 misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, sizeof(ntfile)); 05314 misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(ntkc)); 05315 05316 misdn_lib_nt_keepcalls(ntkc); 05317 misdn_lib_nt_debug_init(ntflags, ntfile); 05318 05319 if (ast_channel_register(&misdn_tech)) { 05320 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 05321 unload_module(); 05322 return AST_MODULE_LOAD_DECLINE; 05323 } 05324 05325 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05326 05327 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 05328 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n" 05329 "Sets mISDN opts. and optargs\n" 05330 "\n" 05331 "The available options are:\n" 05332 " a - Have Asterisk detect DTMF tones on called channel\n" 05333 " c - Make crypted outgoing call, optarg is keyindex\n" 05334 " d - Send display text to called phone, text is the optarg\n" 05335 " e - Perform echo cancelation on this channel,\n" 05336 " takes taps as optarg (32,64,128,256)\n" 05337 " e! - Disable echo cancelation on this channel\n" 05338 " f - Enable fax detection\n" 05339 " h - Make digital outgoing call\n" 05340 " h1 - Make HDLC mode digital outgoing call\n" 05341 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n" 05342 " they will be transported inband.\n" 05343 " jb - Set jitter buffer length, optarg is length\n" 05344 " jt - Set jitter buffer upper threshold, optarg is threshold\n" 05345 " jn - Disable jitter buffer\n" 05346 " n - Disable mISDN DSP on channel.\n" 05347 " Disables: echo cancel, DTMF detection, and volume control.\n" 05348 " p - Caller ID presentation,\n" 05349 " optarg is either 'allowed' or 'restricted'\n" 05350 " s - Send Non-inband DTMF as inband\n" 05351 " vr - Rx gain control, optarg is gain\n" 05352 " vt - Tx gain control, optarg is gain\n" 05353 ); 05354 05355 05356 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 05357 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 05358 "Sends the Facility Message FACILITY_TYPE with \n" 05359 "the given Arguments to the current ISDN Channel\n" 05360 "Supported Facilities are:\n" 05361 "\n" 05362 "type=calldeflect args=Nr where to deflect\n" 05363 ); 05364 05365 05366 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 05367 "misdn_check_l2l1(<port>||g:<groupname>,timeout)" 05368 "Checks if the L2 and L1 are up on either the given <port> or\n" 05369 "on the ports in the group with <groupname>\n" 05370 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 05371 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 05372 "\n" 05373 "This application, ensures the L1/L2 state of the Ports in a group\n" 05374 "it is intended to make the pmp_l1_check option redundant and to\n" 05375 "fix a buggy switch config from your provider\n" 05376 "\n" 05377 "a sample dialplan would look like:\n\n" 05378 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 05379 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 05380 "\n" 05381 ); 05382 05383 05384 misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile)); 05385 05386 /* start the l1 watchers */ 05387 05388 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 05389 int l1timeout; 05390 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 05391 if (l1timeout) { 05392 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 05393 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 05394 } 05395 } 05396 05397 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 05398 05399 return 0; 05400 }
static int misdn_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2507 of file chan_misdn.c.
References chan_list::ast, ast_copy_string(), ast_log(), ast_queue_hangup(), 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(ast); 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(ast); 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 5459 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().
05460 { 05461 char *parse; 05462 char group[BUFFERSIZE + 1]; 05463 char *port_str; 05464 int port = 0; 05465 int timeout; 05466 int dowait = 0; 05467 int port_up; 05468 05469 AST_DECLARE_APP_ARGS(args, 05470 AST_APP_ARG(grouppar); 05471 AST_APP_ARG(timeout); 05472 ); 05473 05474 if (ast_strlen_zero((char *)data)) { 05475 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 05476 return -1; 05477 } 05478 05479 parse = ast_strdupa(data); 05480 AST_STANDARD_APP_ARGS(args, parse); 05481 05482 if (args.argc != 2) { 05483 ast_log(LOG_WARNING, "Wrong argument count\n"); 05484 return 0; 05485 } 05486 05487 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 05488 timeout = atoi(args.timeout); 05489 port_str = args.grouppar; 05490 05491 if (port_str[0] == 'g' && port_str[1] == ':' ) { 05492 /* We make a group call lets checkout which ports are in my group */ 05493 port_str += 2; 05494 ast_copy_string(group, port_str, sizeof(group)); 05495 chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group); 05496 05497 for ( port = misdn_cfg_get_next_port(port); 05498 port > 0; 05499 port = misdn_cfg_get_next_port(port)) { 05500 char cfg_group[BUFFERSIZE + 1]; 05501 05502 chan_misdn_log(2, 0, "trying port %d\n", port); 05503 05504 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, sizeof(cfg_group)); 05505 05506 if (!strcasecmp(cfg_group, group)) { 05507 port_up = misdn_lib_port_up(port, 1); 05508 05509 if (!port_up) { 05510 chan_misdn_log(2, 0, " --> port '%d'\n", port); 05511 misdn_lib_get_port_up(port); 05512 dowait = 1; 05513 } 05514 } 05515 } 05516 05517 } else { 05518 port = atoi(port_str); 05519 chan_misdn_log(2, 0, "Checking Port: %d\n",port); 05520 port_up = misdn_lib_port_up(port, 1); 05521 if (!port_up) { 05522 misdn_lib_get_port_up(port); 05523 dowait = 1; 05524 } 05525 } 05526 05527 if (dowait) { 05528 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout); 05529 ast_safe_sleep(chan, timeout * 1000); 05530 } 05531 05532 return 0; 05533 }
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 5413 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().
05414 { 05415 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05416 char *parse, *tok, *tokb; 05417 05418 chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type); 05419 05420 if (strcasecmp(chan->tech->type, "mISDN")) { 05421 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 05422 return -1; 05423 } 05424 05425 if (ast_strlen_zero((char *)data)) { 05426 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05427 return -1; 05428 } 05429 05430 parse = ast_strdupa(data); 05431 tok = strtok_r(parse, "|", &tokb) ; 05432 05433 if (!tok) { 05434 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05435 return -1; 05436 } 05437 05438 if (!strcasecmp(tok, "calldeflect")) { 05439 tok = strtok_r(NULL, "|", &tokb) ; 05440 05441 if (!tok) { 05442 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 05443 } 05444 05445 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) { 05446 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n"); 05447 return 0; 05448 } 05449 ch->bc->fac_out.Function = Fac_CD; 05450 ast_copy_string((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)); 05451 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 05452 } else { 05453 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", tok); 05454 } 05455 05456 return 0; 05457 }
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 p->state = MISDN_CLEANING; 02828 /* This is the only place in misdn_hangup, where we 02829 * can call release_chan, else it might create lot's of trouble 02830 * */ 02831 ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n"); 02832 release_chan(bc); 02833 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); 02834 break; 02835 case MISDN_HOLDED: 02836 case MISDN_DIALING: 02837 start_bc_tones(p); 02838 hanguptone_indicate(p); 02839 02840 p->state=MISDN_CLEANING; 02841 if (bc->need_disconnect) 02842 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02843 break; 02844 case MISDN_CALLING_ACKNOWLEDGE: 02845 start_bc_tones(p); 02846 hanguptone_indicate(p); 02847 02848 if (bc->need_disconnect) 02849 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02850 break; 02851 02852 case MISDN_CALLING: 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 5799 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().
05800 { 05801 ast_mutex_destroy(&jb->mutexjb); 05802 05803 ast_free(jb->ok); 05804 ast_free(jb->samples); 05805 ast_free(jb); 05806 }
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 5869 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().
05870 { 05871 int i, wp, rp, read = 0; 05872 05873 ast_mutex_lock(&jb->mutexjb); 05874 05875 rp = jb->rp; 05876 wp = jb->wp; 05877 05878 if (jb->state_empty) { 05879 for (i = 0; i < len; i++) { 05880 if (wp == rp) { 05881 jb->rp = rp; 05882 jb->state_empty = 0; 05883 05884 ast_mutex_unlock(&jb->mutexjb); 05885 05886 return read; 05887 } else { 05888 if (jb->ok[rp] == 1) { 05889 data[i] = jb->samples[rp]; 05890 jb->ok[rp] = 0; 05891 rp = (rp != jb->size - 1) ? rp + 1 : 0; 05892 read += 1; 05893 } 05894 } 05895 } 05896 05897 if (wp >= rp) 05898 jb->state_buffer = wp - rp; 05899 else 05900 jb->state_buffer = jb->size - rp + wp; 05901 chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 05902 05903 jb->rp = rp; 05904 } else 05905 chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb); 05906 05907 ast_mutex_unlock(&jb->mutexjb); 05908 05909 return read; 05910 }
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 5810 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.
05811 { 05812 int i, j, rp, wp; 05813 05814 if (!jb || ! data) 05815 return 0; 05816 05817 ast_mutex_lock(&jb->mutexjb); 05818 05819 wp = jb->wp; 05820 rp = jb->rp; 05821 05822 for (i = 0; i < len; i++) { 05823 jb->samples[wp] = data[i]; 05824 jb->ok[wp] = 1; 05825 wp = (wp != jb->size - 1) ? wp + 1 : 0; 05826 05827 if (wp == jb->rp) 05828 jb->state_full = 1; 05829 } 05830 05831 if (wp >= rp) 05832 jb->state_buffer = wp - rp; 05833 else 05834 jb->state_buffer = jb->size - rp + wp; 05835 chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb); 05836 05837 if (jb->state_full) { 05838 jb->wp = wp; 05839 05840 rp = wp; 05841 for (j = 0; j < jb->upper_threshold; j++) 05842 rp = rp != 0 ? rp - 1 : jb->size - 1; 05843 jb->rp = rp; 05844 jb->state_full = 0; 05845 jb->state_empty = 1; 05846 05847 ast_mutex_unlock(&jb->mutexjb); 05848 05849 return -1; 05850 } 05851 05852 if (!jb->state_empty) { 05853 jb->bytes_wrote += len; 05854 if (jb->bytes_wrote >= jb->upper_threshold) { 05855 jb->state_empty = 1; 05856 jb->bytes_wrote = 0; 05857 } 05858 } 05859 jb->wp = wp; 05860 05861 ast_mutex_unlock(&jb->mutexjb); 05862 05863 return 0; 05864 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) |
allocates the jb-structure and initialize the elements
Definition at line 5756 of file chan_misdn.c.
References ast_free, ast_malloc, ast_mutex_init(), and chan_misdn_log().
Referenced by config_jitterbuffer().
05757 { 05758 int i; 05759 struct misdn_jb *jb; 05760 05761 jb = ast_malloc(sizeof(*jb)); 05762 if (!jb) { 05763 chan_misdn_log(-1, 0, "No free Mem for jb\n"); 05764 return NULL; 05765 } 05766 jb->size = size; 05767 jb->upper_threshold = upper_threshold; 05768 jb->wp = 0; 05769 jb->rp = 0; 05770 jb->state_full = 0; 05771 jb->state_empty = 0; 05772 jb->bytes_wrote = 0; 05773 jb->samples = ast_malloc(size * sizeof(char)); 05774 05775 if (!jb->samples) { 05776 ast_free(jb); 05777 chan_misdn_log(-1, 0, "No free Mem for jb->samples\n"); 05778 return NULL; 05779 } 05780 05781 jb->ok = ast_malloc(size * sizeof(char)); 05782 05783 if (!jb->ok) { 05784 ast_free(jb->samples); 05785 ast_free(jb); 05786 chan_misdn_log(-1, 0, "No free Mem for jb->ok\n"); 05787 return NULL; 05788 } 05789 05790 for (i = 0; i < size; i++) 05791 jb->ok[i] = 0; 05792 05793 ast_mutex_init(&jb->mutexjb); 05794 05795 return jb; 05796 }
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 3639 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().
03640 { 03641 struct ast_channel *tmp; 03642 char *cid_name = 0, *cid_num = 0; 03643 int chan_offset = 0; 03644 int tmp_port = misdn_cfg_get_next_port(0); 03645 int bridging; 03646 03647 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03648 if (tmp_port == port) 03649 break; 03650 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03651 } 03652 if (c < 0) 03653 c = 0; 03654 03655 if (callerid) 03656 ast_callerid_parse(callerid, &cid_name, &cid_num); 03657 03658 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 03659 03660 if (tmp) { 03661 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n", exten, callerid); 03662 03663 tmp->nativeformats = prefformat; 03664 03665 tmp->readformat = format; 03666 tmp->rawreadformat = format; 03667 tmp->writeformat = format; 03668 tmp->rawwriteformat = format; 03669 03670 tmp->tech_pvt = chlist; 03671 03672 misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging)); 03673 03674 if (bridging) 03675 tmp->tech = &misdn_tech; 03676 else 03677 tmp->tech = &misdn_tech_wo_bridge; 03678 03679 tmp->writeformat = format; 03680 tmp->readformat = format; 03681 tmp->priority=1; 03682 03683 if (exten) 03684 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 03685 else 03686 chan_misdn_log(1, 0, "misdn_new: no exten given.\n"); 03687 03688 if (callerid) 03689 /* Don't use ast_set_callerid() here because it will 03690 * generate a needless NewCallerID event */ 03691 tmp->cid.cid_ani = ast_strdup(cid_num); 03692 03693 if (pipe(chlist->pipe) < 0) 03694 ast_log(LOG_ERROR, "Pipe failed\n"); 03695 03696 ast_channel_set_fd(tmp, 0, chlist->pipe[0]); 03697 03698 if (state == AST_STATE_RING) 03699 tmp->rings = 1; 03700 else 03701 tmp->rings = 0; 03702 03703 ast_jb_configure(tmp, misdn_get_global_jbconf()); 03704 } else { 03705 chan_misdn_log(-1, 0, "Unable to allocate channel structure\n"); 03706 } 03707 03708 return tmp; 03709 }
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::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 = 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 5535 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_DTMF_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().
05536 { 05537 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05538 char *tok, *tokb, *parse; 05539 int keyidx = 0; 05540 int rxgain = 0; 05541 int txgain = 0; 05542 int change_jitter = 0; 05543 05544 if (strcasecmp(chan->tech->type, "mISDN")) { 05545 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n"); 05546 return -1; 05547 } 05548 05549 if (ast_strlen_zero((char *)data)) { 05550 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 05551 return -1; 05552 } 05553 05554 parse = ast_strdupa(data); 05555 for (tok = strtok_r(parse, ":", &tokb); 05556 tok; 05557 tok = strtok_r(NULL, ":", &tokb) ) { 05558 int neglect = 0; 05559 05560 if (tok[0] == '!' ) { 05561 neglect = 1; 05562 tok++; 05563 } 05564 05565 switch(tok[0]) { 05566 05567 case 'd' : 05568 ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display)); 05569 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display); 05570 break; 05571 05572 case 'n': 05573 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 05574 ch->bc->nodsp = 1; 05575 break; 05576 05577 case 'j': 05578 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 05579 tok++; 05580 change_jitter = 1; 05581 05582 switch ( tok[0] ) { 05583 case 'b': 05584 ch->jb_len = atoi(++tok); 05585 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len); 05586 break; 05587 case 't' : 05588 ch->jb_upper_threshold = atoi(++tok); 05589 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold); 05590 break; 05591 case 'n': 05592 ch->bc->nojitter = 1; 05593 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 05594 break; 05595 default: 05596 ch->jb_len = 4000; 05597 ch->jb_upper_threshold = 0; 05598 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len); 05599 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold); 05600 } 05601 break; 05602 case 'v': 05603 tok++; 05604 05605 switch (tok[0]) { 05606 case 'r' : 05607 rxgain = atoi(++tok); 05608 if (rxgain < -8) 05609 rxgain = -8; 05610 if (rxgain > 8) 05611 rxgain = 8; 05612 ch->bc->rxgain = rxgain; 05613 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain); 05614 break; 05615 case 't': 05616 txgain = atoi(++tok); 05617 if (txgain < -8) 05618 txgain = -8; 05619 if (txgain > 8) 05620 txgain = 8; 05621 ch->bc->txgain = txgain; 05622 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain); 05623 break; 05624 } 05625 break; 05626 05627 case 'c': 05628 keyidx = atoi(++tok); 05629 { 05630 char keys[4096]; 05631 char *key = NULL, *tmp = keys; 05632 int i; 05633 misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 05634 05635 for (i = 0; i < keyidx; i++) { 05636 key = strsep(&tmp, ","); 05637 } 05638 05639 if (key) { 05640 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 05641 } 05642 05643 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key); 05644 break; 05645 } 05646 case 'e': 05647 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 05648 05649 if (neglect) { 05650 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 05651 #ifdef MISDN_1_2 05652 *ch->bc->pipeline = 0; 05653 #else 05654 ch->bc->ec_enable = 0; 05655 #endif 05656 } else { 05657 #ifdef MISDN_1_2 05658 update_pipeline_config(ch->bc); 05659 #else 05660 ch->bc->ec_enable = 1; 05661 ch->bc->orig = ch->originator; 05662 tok++; 05663 if (*tok) { 05664 ch->bc->ec_deftaps = atoi(tok); 05665 } 05666 #endif 05667 } 05668 05669 break; 05670 case 'h': 05671 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 05672 05673 if (strlen(tok) > 1 && tok[1] == '1') { 05674 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 05675 if (!ch->bc->hdlc) { 05676 ch->bc->hdlc = 1; 05677 } 05678 } 05679 ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 05680 break; 05681 05682 case 's': 05683 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 05684 ch->bc->send_dtmf = 1; 05685 break; 05686 05687 case 'f': 05688 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 05689 ch->faxdetect = 1; 05690 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 05691 break; 05692 05693 case 'a': 05694 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 05695 ch->ast_dsp = 1; 05696 break; 05697 05698 case 'p': 05699 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]); 05700 /* CRICH: callingpres!!! */ 05701 if (strstr(tok,"allowed")) { 05702 ch->bc->pres = 0; 05703 } else if (strstr(tok, "not_screened")) { 05704 ch->bc->pres = 1; 05705 } 05706 break; 05707 case 'i' : 05708 chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n"); 05709 ch->ignore_dtmf=1; 05710 break; 05711 default: 05712 break; 05713 } 05714 } 05715 05716 if (change_jitter) 05717 config_jitterbuffer(ch); 05718 05719 if (ch->faxdetect || ch->ast_dsp) { 05720 if (!ch->dsp) 05721 ch->dsp = ast_dsp_new(); 05722 if (ch->dsp) 05723 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT); 05724 if (!ch->trans) 05725 ch->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 05726 } 05727 05728 if (ch->ast_dsp) { 05729 chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 05730 ch->bc->nodsp = 1; 05731 } 05732 05733 return 0; 05734 }
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 3937 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().
03938 { 03939 chan_misdn_log(4, 0, "TRANSFERRING %s to %s\n", holded_chan->ast->name, tmp_ch->ast->name); 03940 03941 tmp_ch->state = MISDN_HOLD_DISCONNECT; 03942 03943 ast_moh_stop(ast_bridged_channel(holded_chan->ast)); 03944 03945 holded_chan->state=MISDN_CONNECTED; 03946 /* misdn_lib_transfer(holded_chan->bc); */ 03947 ast_channel_masquerade(holded_chan->ast, ast_bridged_channel(tmp_ch->ast)); 03948 }
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::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)[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, 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, frame->samples); 03178 } 03179 03180 return 0; 03181 }
static int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 3819 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().
03820 { 03821 int ret = ast_pbx_start(ch->ast); 03822 03823 if (ret >= 0) 03824 ch->need_hangup = 0; 03825 else 03826 ch->need_hangup = 1; 03827 03828 return ret; 03829 }
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_DTMF_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_DTMF_DETECT | DSP_FEATURE_FAX_DETECT); 02353 else 02354 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_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 3868 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().
03868 { 03869 struct ast_channel *ast=NULL; 03870 03871 ast_mutex_lock(&release_lock); 03872 { 03873 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03874 if (!ch) { 03875 chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n"); 03876 ast_mutex_unlock(&release_lock); 03877 return; 03878 } 03879 03880 if (ch->ast) { 03881 ast = ch->ast; 03882 } 03883 03884 chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n", bc->l3_id); 03885 03886 /*releasing jitterbuffer*/ 03887 if (ch->jb ) { 03888 misdn_jb_destroy(ch->jb); 03889 ch->jb = NULL; 03890 } else { 03891 if (!bc->nojitter) 03892 chan_misdn_log(5, bc->port, "Jitterbuffer already destroyed.\n"); 03893 } 03894 03895 if (ch->overlap_dial) { 03896 if (ch->overlap_dial_task != -1) { 03897 misdn_tasks_remove(ch->overlap_dial_task); 03898 ch->overlap_dial_task = -1; 03899 } 03900 ast_mutex_destroy(&ch->overlap_tv_lock); 03901 } 03902 03903 if (ch->originator == ORG_AST) { 03904 misdn_out_calls[bc->port]--; 03905 } else { 03906 misdn_in_calls[bc->port]--; 03907 } 03908 03909 if (ch) { 03910 close(ch->pipe[0]); 03911 close(ch->pipe[1]); 03912 03913 if (ast && MISDN_ASTERISK_TECH_PVT(ast)) { 03914 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)); 03915 chan_misdn_log(3, bc->port, " --> * State Down\n"); 03916 MISDN_ASTERISK_TECH_PVT(ast) = NULL; 03917 03918 if (ast->_state != AST_STATE_RESERVED) { 03919 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 03920 ast_setstate(ast, AST_STATE_DOWN); 03921 } 03922 } 03923 03924 ch->state = MISDN_CLEANING; 03925 cl_dequeue_chan(&cl_te, ch); 03926 03927 ast_free(ch); 03928 } else { 03929 /* chan is already cleaned, so exiting */ 03930 } 03931 03932 ast_mutex_unlock(&release_lock); 03933 } 03934 /*** release end **/ 03935 }
static int reload | ( | void | ) | [static] |
Definition at line 5404 of file chan_misdn.c.
References reload_config().
05405 { 05406 reload_config(); 05407 05408 return 0; 05409 }
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 4013 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().
04013 { 04014 if (!ast) { 04015 chan_misdn_log(1, 0, "send_cause2ast: No Ast\n"); 04016 return; 04017 } 04018 if (!bc) { 04019 chan_misdn_log(1, 0, "send_cause2ast: No BC\n"); 04020 return; 04021 } 04022 if (!ch) { 04023 chan_misdn_log(1, 0, "send_cause2ast: No Ch\n"); 04024 return; 04025 } 04026 04027 ast->hangupcause = bc->cause; 04028 04029 switch (bc->cause) { 04030 04031 case 1: /** Congestion Cases **/ 04032 case 2: 04033 case 3: 04034 case 4: 04035 case 22: 04036 case 27: 04037 /* 04038 * Not Queueing the Congestion anymore, since we want to hear 04039 * the inband message 04040 * 04041 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1); 04042 ch->state = MISDN_BUSY; 04043 04044 ast_queue_control(ast, AST_CONTROL_CONGESTION); 04045 */ 04046 break; 04047 04048 case 21: 04049 case 17: /* user busy */ 04050 04051 ch->state = MISDN_BUSY; 04052 04053 if (!ch->need_busy) { 04054 chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n"); 04055 break; 04056 } 04057 04058 chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1); 04059 04060 ast_queue_control(ast, AST_CONTROL_BUSY); 04061 04062 ch->need_busy = 0; 04063 04064 break; 04065 } 04066 }
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 4156 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().
04156 { 04157 if (pbx_start_chan(ch) < 0) { 04158 hangup_chan(ch); 04159 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 04160 if (bc->nt) { 04161 hanguptone_indicate(ch); 04162 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 04163 } else 04164 misdn_lib_send_event(bc, EVENT_RELEASE); 04165 } 04166 }
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 5213 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.
05214 { 05215 /* First, take us out of the channel loop */ 05216 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 05217 05218 misdn_tasks_destroy(); 05219 05220 if (!g_config_initialized) 05221 return 0; 05222 05223 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 05224 05225 /* ast_unregister_application("misdn_crypt"); */ 05226 ast_unregister_application("misdn_set_opt"); 05227 ast_unregister_application("misdn_facility"); 05228 ast_unregister_application("misdn_check_l2l1"); 05229 05230 ast_channel_unregister(&misdn_tech); 05231 05232 free_robin_list(); 05233 misdn_cfg_destroy(); 05234 misdn_lib_destroy(); 05235 05236 if (misdn_debug) 05237 ast_free(misdn_debug); 05238 if (misdn_debug_only) 05239 ast_free(misdn_debug_only); 05240 ast_free(misdn_ports); 05241 05242 return 0; 05243 }
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_string_field_build, chan_misdn_log(), misdn_cfg_get_next_port(), misdn_lib_port_is_pri(), misdn_type, ast_channel::name, and name.
Referenced by cb_events().
03622 { 03623 int chan_offset = 0; 03624 int tmp_port = misdn_cfg_get_next_port(0); 03625 for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) { 03626 if (tmp_port == port) 03627 break; 03628 chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 03629 } 03630 if (c < 0) 03631 c = 0; 03632 03633 ast_string_field_build(tmp, name, "%s/%d-u%d", 03634 misdn_type, chan_offset+c, glob_channel++); 03635 03636 chan_misdn_log(3 , port, " --> updating channel name to [%s]\n", tmp->name); 03637 }
static void wait_for_digits | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 4168 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().
04168 { 04169 ch->state=MISDN_WAITING4DIGS; 04170 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04171 if (bc->nt && !bc->dad[0]) 04172 dialtone_indicate(ch); 04173 }
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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 5986 of file chan_misdn.c.
struct allowed_bearers allowed_bearers_array[] [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 5986 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] |