#include "asterisk.h"
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.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/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.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 "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 |
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 int | _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data, int variable) |
int | add_in_calls (int port) |
int | add_out_calls (int port) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Channel driver for mISDN Support (BRI/PRI)",.load=load_module,.unload=unload_module,.reload=reload,) | |
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 (const char *line, const char *word, int pos, int state) |
static char * | complete_ch_helper (const char *line, const char *word, int pos, int state, int rpos) |
static char * | complete_debug_port (const char *line, const char *word, int pos, int state) |
static char * | complete_show_config (const char *line, const char *word, int pos, int state) |
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) |
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 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) |
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 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) |
int | misdn_jb_empty (struct misdn_jb *jb, char *data, int len) |
int | misdn_jb_fill (struct misdn_jb *jb, const char *data, int len) |
struct misdn_jb * | misdn_jb_init (int size, int upper_threshold) |
static int | misdn_l1_task (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 (void *data) |
static int | misdn_port_block (int fd, int argc, char *argv[]) |
static int | misdn_port_down (int fd, int argc, char *argv[]) |
static int | misdn_port_unblock (int fd, int argc, char *argv[]) |
static int | misdn_port_up (int fd, int argc, char *argv[]) |
static struct ast_frame * | misdn_read (struct ast_channel *ast) |
static int | misdn_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | misdn_request (const char *type, int format, void *data, int *cause) |
static int | misdn_restart_pid (int fd, int argc, char *argv[]) |
static int | misdn_restart_port (int fd, int argc, char *argv[]) |
static int | misdn_send_cd (int fd, int argc, char *argv[]) |
static int | misdn_send_digit (int fd, int argc, char *argv[]) |
static int | misdn_send_display (int fd, int argc, char *argv[]) |
static int | misdn_send_restart (int fd, int argc, char *argv[]) |
static int | misdn_send_text (struct ast_channel *chan, const char *text) |
static int | misdn_set_crypt_debug (int fd, int argc, char *argv[]) |
static int | misdn_set_debug (int fd, int argc, char *argv[]) |
static int | misdn_set_opt_exec (struct ast_channel *chan, void *data) |
static int | misdn_set_tics (int fd, int argc, char *argv[]) |
static int | misdn_show_cl (int fd, int argc, char *argv[]) |
static int | misdn_show_cls (int fd, int argc, char *argv[]) |
static int | misdn_show_config (int fd, int argc, char *argv[]) |
static int | misdn_show_port (int fd, int argc, char *argv[]) |
static int | misdn_show_ports_stats (int fd, int argc, char *argv[]) |
static int | misdn_show_stacks (int fd, int argc, char *argv[]) |
static int | misdn_tasks_add (int timeout, ast_sched_cb callback, void *data) |
static int | misdn_tasks_add_variable (int timeout, ast_sched_cb callback, void *data) |
static void | misdn_tasks_destroy (void) |
static void | misdn_tasks_init (void) |
static void | misdn_tasks_remove (int task_id) |
static void * | misdn_tasks_thread_func (void *data) |
static void | misdn_tasks_wakeup (void) |
static int | misdn_toggle_echocancel (int fd, int argc, char *argv[]) |
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) |
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 | |
struct allowed_bearers | allowed_bearers_array [] |
static struct ast_cli_entry | chan_misdn_clis [] |
struct chan_list * | cl_te = NULL |
ast_mutex_t | cl_te_lock |
struct chan_list | dummy_cl |
static int | g_config_initialized = 0 |
static int | glob_channel = 0 |
char | global_tracefile [BUFFERSIZE+1] |
ast_mutex_t | lock |
static int | max_ports |
int | MAXTICS = 8 |
static int * | misdn_debug |
static int * | misdn_debug_only |
static int * | misdn_in_calls |
static int * | misdn_out_calls |
static int * | misdn_ports |
static struct sched_context * | misdn_tasks = NULL |
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 |
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 295 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 143 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 |
MISDN_NOTHING | at beginning |
MISDN_WAITING4DIGS | when waiting for infos |
MISDN_EXTCANTMATCH | when asterisk couldnt match our ext |
MISDN_INCOMING_SETUP | for incoming setups |
MISDN_DIALING | when pbx_start |
MISDN_PROGRESS | we got a progress |
MISDN_PROCEEDING | we got a progress |
MISDN_CALLING | when misdn_call is called |
MISDN_CALLING_ACKNOWLEDGE | when we get SETUP_ACK |
MISDN_ALERTING | when Alerting |
MISDN_BUSY | when BUSY |
MISDN_CONNECTED | when connected |
MISDN_PRECONNECTED | when connected |
MISDN_DISCONNECTED | when connected |
MISDN_RELEASED | when connected |
MISDN_BRIDGED | when bridged |
MISDN_CLEANING | when hangup from * but we were connected before |
MISDN_HUNGUP_FROM_MISDN | when DISCONNECT/RELEASE/REL_COMP cam from misdn |
MISDN_HUNGUP_FROM_AST | when DISCONNECT/RELEASE/REL_COMP came out of |
MISDN_HOLDED | if this chan is holded |
MISDN_HOLD_DISCONNECT | if this chan is holded |
Definition at line 117 of file chan_misdn.c.
00117 { 00118 MISDN_NOTHING=0, /*!< at beginning */ 00119 MISDN_WAITING4DIGS, /*!< when waiting for infos */ 00120 MISDN_EXTCANTMATCH, /*!< when asterisk couldnt match our ext */ 00121 MISDN_INCOMING_SETUP, /*!< for incoming setups*/ 00122 MISDN_DIALING, /*!< when pbx_start */ 00123 MISDN_PROGRESS, /*!< we got a progress */ 00124 MISDN_PROCEEDING, /*!< we got a progress */ 00125 MISDN_CALLING, /*!< when misdn_call is called */ 00126 MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */ 00127 MISDN_ALERTING, /*!< when Alerting */ 00128 MISDN_BUSY, /*!< when BUSY */ 00129 MISDN_CONNECTED, /*!< when connected */ 00130 MISDN_PRECONNECTED, /*!< when connected */ 00131 MISDN_DISCONNECTED, /*!< when connected */ 00132 MISDN_RELEASED, /*!< when connected */ 00133 MISDN_BRIDGED, /*!< when bridged */ 00134 MISDN_CLEANING, /*!< when hangup from * but we were connected before */ 00135 MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP cam from misdn */ 00136 MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */ 00137 /* misdn_hangup */ 00138 MISDN_HOLDED, /*!< if this chan is holded */ 00139 MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */ 00140 00141 };
static int _misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
void * | data, | |||
int | variable | |||
) | [inline, static] |
Definition at line 615 of file chan_misdn.c.
References ast_sched_add_variable(), misdn_tasks_init(), and misdn_tasks_wakeup().
Referenced by misdn_tasks_add(), and misdn_tasks_add_variable().
00616 { 00617 int task_id; 00618 00619 if (!misdn_tasks) { 00620 misdn_tasks_init(); 00621 } 00622 task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable); 00623 misdn_tasks_wakeup(); 00624 00625 return task_id; 00626 }
int add_in_calls | ( | int | port | ) |
Definition at line 3789 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_IN.
Referenced by cb_events().
03790 { 03791 int max_in_calls; 03792 03793 misdn_cfg_get( port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls)); 03794 misdn_in_calls[port]++; 03795 03796 if (max_in_calls >=0 && max_in_calls<misdn_in_calls[port]) { 03797 ast_log(LOG_NOTICE,"Marking Incoming Call on port[%d]\n",port); 03798 return misdn_in_calls[port]-max_in_calls; 03799 } 03800 03801 return 0; 03802 }
int add_out_calls | ( | int | port | ) |
Definition at line 3804 of file chan_misdn.c.
References ast_log(), LOG_NOTICE, misdn_cfg_get(), and MISDN_CFG_MAX_OUT.
Referenced by misdn_call().
03805 { 03806 int max_out_calls; 03807 03808 misdn_cfg_get( port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls)); 03809 03810 03811 if (max_out_calls >=0 && max_out_calls<=misdn_out_calls[port]) { 03812 ast_log(LOG_NOTICE,"Rejecting Outgoing Call on port[%d]\n",port); 03813 return (misdn_out_calls[port]+1)-max_out_calls; 03814 } 03815 03816 misdn_out_calls[port]++; 03817 03818 return 0; 03819 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Channel driver for mISDN Support (BRI/PRI)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
static char* bearer2str | ( | int | cap | ) | [static] |
Definition at line 409 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 misdn_lib_log_ies(), print_bc_info(), and print_bearer().
00409 { 00410 static char *bearers[]={ 00411 "Speech", 00412 "Audio 3.1k", 00413 "Unres Digital", 00414 "Res Digital", 00415 "Video", 00416 "Unknown Bearer" 00417 }; 00418 00419 switch (cap) { 00420 case INFO_CAPABILITY_SPEECH: 00421 return bearers[0]; 00422 break; 00423 case INFO_CAPABILITY_AUDIO_3_1K: 00424 return bearers[1]; 00425 break; 00426 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 00427 return bearers[2]; 00428 break; 00429 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 00430 return bearers[3]; 00431 break; 00432 case INFO_CAPABILITY_VIDEO: 00433 return bearers[4]; 00434 break; 00435 default: 00436 return bearers[5]; 00437 break; 00438 } 00439 }
static enum event_response_e cb_events | ( | enum event_e | event, | |
struct misdn_bchannel * | bc, | |||
void * | user_data | |||
) | [static] |
queue new chan
Sending SETUP_ACK
Suplementary Services
Definition at line 3845 of file chan_misdn.c.
References add_in_calls(), misdn_bchannel::addr, chan_list::addr, chan_list::allowed_bearers, misdn_bchannel::AOCD, misdn_bchannel::AOCDtype, chan_list::ast, ast_bridged_channel(), ast_canmatch_extension(), ast_cdr_update(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, 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(), chan_list::bc, misdn_bchannel::bc_state, bc_state2str(), misdn_bchannel::bframe, misdn_bchannel::bframe_len, misdn_bchannel::cad, misdn_bchannel::capability, misdn_bchannel::cause, cb_log, chan_misdn_log(), hold_info::channel, misdn_bchannel::channel, misdn_bchannel::chargingUnit, ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), chan_list::context, misdn_bchannel::cpnnumplan, misdn_bchannel::currency, misdn_bchannel::cw, misdn_bchannel::dad, ast_frame::data, ast_frame::datalen, ast_frame::delivery, do_immediate_setup(), misdn_bchannel::dtmf, misdn_bchannel::dummy, 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, t, ast_channel::tech, misdn_bchannel::tone_cnt, ast_channel::transfercapability, ast_channel_tech::type, update_name(), and wait_for_digits().
Referenced by load_module().
03846 { 03847 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03848 03849 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 03850 int debuglevel=1; 03851 if ( event==EVENT_CLEANUP && !user_data) 03852 debuglevel=5; 03853 03854 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"); 03855 if (debuglevel==1) { 03856 misdn_lib_log_ies(bc); 03857 chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state)); 03858 } 03859 } 03860 03861 if (!ch) { 03862 switch(event) { 03863 case EVENT_SETUP: 03864 case EVENT_DISCONNECT: 03865 case EVENT_PORT_ALARM: 03866 case EVENT_RETRIEVE: 03867 case EVENT_NEW_BC: 03868 case EVENT_FACILITY: 03869 break; 03870 case EVENT_RELEASE_COMPLETE: 03871 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); 03872 break; 03873 case EVENT_CLEANUP: 03874 case EVENT_TONE_GENERATE: 03875 case EVENT_BCHAN_DATA: 03876 return -1; 03877 03878 default: 03879 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); 03880 return -1; 03881 } 03882 } 03883 03884 if (ch ) { 03885 switch (event) { 03886 case EVENT_TONE_GENERATE: 03887 break; 03888 case EVENT_DISCONNECT: 03889 case EVENT_RELEASE: 03890 case EVENT_RELEASE_COMPLETE: 03891 case EVENT_CLEANUP: 03892 case EVENT_TIMEOUT: 03893 if (!ch->ast) 03894 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)); 03895 break; 03896 default: 03897 if ( !ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03898 if (event!=EVENT_BCHAN_DATA) 03899 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 03900 return -1; 03901 } 03902 } 03903 } 03904 03905 03906 switch (event) { 03907 case EVENT_PORT_ALARM: 03908 { 03909 int boa=0; 03910 misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int)); 03911 if (boa) { 03912 cb_log(1,bc->port," --> blocking\n"); 03913 misdn_lib_port_block(bc->port); 03914 } 03915 } 03916 break; 03917 case EVENT_BCHAN_ACTIVATED: 03918 break; 03919 03920 case EVENT_NEW_CHANNEL: 03921 update_name(ch->ast,bc->port,bc->channel); 03922 break; 03923 03924 case EVENT_NEW_L3ID: 03925 ch->l3id=bc->l3_id; 03926 ch->addr=bc->addr; 03927 break; 03928 03929 case EVENT_NEW_BC: 03930 if (!ch) { 03931 ch=find_holded(cl_te,bc); 03932 } 03933 03934 if (!ch) { 03935 ast_log(LOG_WARNING,"NEW_BC without chan_list?\n"); 03936 break; 03937 } 03938 03939 if (bc) 03940 ch->bc=(struct misdn_bchannel*)user_data; 03941 break; 03942 03943 case EVENT_DTMF_TONE: 03944 { 03945 /* sending INFOS as DTMF-Frames :) */ 03946 struct ast_frame fr; 03947 memset(&fr, 0 , sizeof(fr)); 03948 fr.frametype = AST_FRAME_DTMF; 03949 fr.subclass = bc->dtmf ; 03950 fr.src=NULL; 03951 fr.data = NULL ; 03952 fr.datalen = 0; 03953 fr.samples = 0 ; 03954 fr.mallocd =0 ; 03955 fr.offset= 0 ; 03956 fr.delivery= ast_tv(0,0) ; 03957 03958 if (!ch->ignore_dtmf) { 03959 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 03960 ast_queue_frame(ch->ast, &fr); 03961 } else { 03962 chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf); 03963 } 03964 } 03965 break; 03966 case EVENT_STATUS: 03967 break; 03968 03969 case EVENT_INFORMATION: 03970 { 03971 int l; 03972 03973 if ( ch->state != MISDN_CONNECTED ) 03974 stop_indicate(ch); 03975 03976 if (!ch->ast) break; 03977 03978 if (ch->state == MISDN_WAITING4DIGS ) { 03979 /* Ok, incomplete Setup, waiting till extension exists */ 03980 if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) { 03981 chan_misdn_log(1, bc->port, " --> using keypad as info\n"); 03982 strcpy(bc->info_dad,bc->keypad); 03983 } 03984 03985 l = sizeof(bc->dad); 03986 strncat(bc->dad,bc->info_dad, l); 03987 bc->dad[l-1] = 0; 03988 03989 l = sizeof(ch->ast->exten); 03990 strncpy(ch->ast->exten, bc->dad, l); 03991 ch->ast->exten[l-1] = 0; 03992 03993 /* Check for Pickup Request first */ 03994 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 03995 if (ast_pickup_call(ch->ast)) { 03996 hangup_chan(ch); 03997 } else { 03998 struct ast_channel *chan=ch->ast; 03999 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04000 ast_setstate(chan, AST_STATE_DOWN); 04001 hangup_chan(ch); 04002 ch->ast=NULL; 04003 break; 04004 } 04005 } 04006 04007 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04008 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04009 ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port); 04010 strcpy(ch->ast->exten, "i"); 04011 04012 ch->state = MISDN_DIALING; 04013 start_pbx(ch, bc, ch->ast); 04014 break; 04015 } 04016 04017 ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)." 04018 "maybe you want to add an 'i' extension to catch this case.\n", 04019 bc->port); 04020 04021 if (bc->nt) 04022 hanguptone_indicate(ch); 04023 ch->state=MISDN_EXTCANTMATCH; 04024 bc->out_cause=1; 04025 04026 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 04027 break; 04028 } 04029 04030 if (ch->overlap_dial) { 04031 ast_mutex_lock(&ch->overlap_tv_lock); 04032 ch->overlap_tv = ast_tvnow(); 04033 ast_mutex_unlock(&ch->overlap_tv_lock); 04034 if (ch->overlap_dial_task == -1) { 04035 ch->overlap_dial_task = 04036 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04037 } 04038 break; 04039 } 04040 04041 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04042 04043 ch->state = MISDN_DIALING; 04044 start_pbx(ch, bc, ch->ast); 04045 } 04046 } else { 04047 /* sending INFOS as DTMF-Frames :) */ 04048 struct ast_frame fr; 04049 fr.frametype = AST_FRAME_DTMF; 04050 fr.subclass = bc->info_dad[0] ; 04051 fr.src=NULL; 04052 fr.data = NULL ; 04053 fr.datalen = 0; 04054 fr.samples = 0 ; 04055 fr.mallocd =0 ; 04056 fr.offset= 0 ; 04057 fr.delivery= ast_tv(0,0) ; 04058 04059 04060 int digits; 04061 misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int)); 04062 if (ch->state != MISDN_CONNECTED ) { 04063 if (digits) { 04064 int l = sizeof(bc->dad); 04065 strncat(bc->dad,bc->info_dad, l); 04066 bc->dad[l-1] = 0; 04067 l = sizeof(ch->ast->exten); 04068 strncpy(ch->ast->exten, bc->dad, l); 04069 ch->ast->exten[l-1] = 0; 04070 04071 ast_cdr_update(ch->ast); 04072 } 04073 04074 ast_queue_frame(ch->ast, &fr); 04075 } 04076 } 04077 } 04078 break; 04079 case EVENT_SETUP: 04080 { 04081 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 04082 if (ch) { 04083 switch (ch->state) { 04084 case MISDN_NOTHING: 04085 ch=NULL; 04086 break; 04087 default: 04088 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 04089 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 04090 } 04091 } 04092 } 04093 04094 int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 04095 if (!bc->nt && ! msn_valid) { 04096 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 04097 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 04098 } 04099 04100 04101 if (bc->cw) { 04102 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 04103 int cause; 04104 misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 04105 bc->out_cause=cause?cause:16; 04106 return RESPONSE_RELEASE_SETUP; 04107 } 04108 04109 print_bearer(bc); 04110 04111 { 04112 int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 04113 if (!bc->nt && ! msn_valid) { 04114 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 04115 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 04116 } 04117 04118 if (bc->cw) { 04119 chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n"); 04120 int cause; 04121 misdn_cfg_get( bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause)); 04122 bc->out_cause=cause?cause:16; 04123 return RESPONSE_RELEASE_SETUP; 04124 } 04125 04126 print_bearer(bc); 04127 04128 struct chan_list *ch=init_chan_list(ORG_MISDN); 04129 struct ast_channel *chan; 04130 int exceed; 04131 04132 if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;} 04133 04134 ch->bc = bc; 04135 ch->l3id=bc->l3_id; 04136 ch->addr=bc->addr; 04137 ch->originator = ORG_MISDN; 04138 04139 chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel); 04140 04141 if (!chan) { 04142 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04143 ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 04144 return 0; 04145 } 04146 04147 ch->ast = chan; 04148 04149 if ((exceed=add_in_calls(bc->port))) { 04150 char tmp[16]; 04151 sprintf(tmp,"%d",exceed); 04152 pbx_builtin_setvar_helper(chan,"MAX_OVERFLOW",tmp); 04153 } 04154 04155 read_config(ch, ORG_MISDN); 04156 04157 export_ch(chan, bc, ch); 04158 04159 ch->ast->rings=1; 04160 ast_setstate(ch->ast, AST_STATE_RINGING); 04161 04162 int pres,screen; 04163 04164 switch (bc->pres) { 04165 case 1: 04166 pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n"); 04167 break; 04168 case 2: 04169 pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n"); 04170 break; 04171 default: 04172 pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres); 04173 } 04174 04175 switch (bc->screen) { 04176 case 0: 04177 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n"); 04178 break; 04179 case 1: 04180 screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n"); 04181 break; 04182 case 2: 04183 screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n"); 04184 break; 04185 case 3: 04186 screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n"); 04187 break; 04188 default: 04189 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen); 04190 } 04191 04192 chan->cid.cid_pres=pres+screen; 04193 04194 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 04195 chan->transfercapability=bc->capability; 04196 04197 switch (bc->capability) { 04198 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 04199 pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL"); 04200 break; 04201 default: 04202 pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH"); 04203 } 04204 04205 /** queue new chan **/ 04206 cl_queue_chan(&cl_te, ch) ; 04207 04208 if (!strstr(ch->allowed_bearers,"all")) { 04209 int i; 04210 for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) { 04211 if (allowed_bearers_array[i].cap == bc->capability) { 04212 if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) { 04213 chan_misdn_log(0,bc->port,"Bearer Not allowed\b"); 04214 bc->out_cause=88; 04215 04216 ch->state=MISDN_EXTCANTMATCH; 04217 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04218 return RESPONSE_OK; 04219 } 04220 } 04221 04222 } 04223 } 04224 04225 /* Check for Pickup Request first */ 04226 if (!strcmp(chan->exten, ast_pickup_ext())) { 04227 if (!ch->noautorespond_on_setup) { 04228 int ret;/** Sending SETUP_ACK**/ 04229 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04230 } else { 04231 ch->state = MISDN_INCOMING_SETUP; 04232 } 04233 if (ast_pickup_call(chan)) { 04234 hangup_chan(ch); 04235 } else { 04236 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04237 ast_setstate(chan, AST_STATE_DOWN); 04238 hangup_chan(ch); 04239 ch->ast=NULL; 04240 break; 04241 } 04242 } 04243 04244 /* 04245 added support for s extension hope it will help those poor cretains 04246 which haven't overlap dial. 04247 */ 04248 int ai; 04249 misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 04250 if ( ai ) { 04251 do_immediate_setup(bc, ch , chan); 04252 break; 04253 } 04254 04255 /* check if we should jump into s when we have no dad */ 04256 int im; 04257 misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 04258 if ( im && ast_strlen_zero(bc->dad) ) { 04259 do_immediate_setup(bc, ch , chan); 04260 break; 04261 } 04262 04263 chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context); 04264 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04265 if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) { 04266 ast_log(LOG_WARNING, "Extension can never match, So jumping to 'i' extension. port(%d)\n",bc->port); 04267 strcpy(ch->ast->exten, "i"); 04268 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE); 04269 ch->state=MISDN_DIALING; 04270 start_pbx(ch, bc, chan); 04271 break; 04272 } 04273 04274 ast_log(LOG_WARNING, "Extension can never match, so disconnecting on port(%d)." 04275 "maybe you want to add an 'i' extension to catch this case.\n", 04276 bc->port); 04277 if (bc->nt) 04278 hanguptone_indicate(ch); 04279 04280 ch->state=MISDN_EXTCANTMATCH; 04281 bc->out_cause=1; 04282 04283 if (bc->nt) 04284 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 04285 else 04286 misdn_lib_send_event(bc, EVENT_RELEASE ); 04287 04288 break; 04289 } 04290 04291 /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 04292 * jump into the dialplan, when the dialed extension does not exist, the 's' extension 04293 * will be used by Asterisk automatically. */ 04294 if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) { 04295 if (!ch->noautorespond_on_setup) { 04296 ch->state=MISDN_DIALING; 04297 misdn_lib_send_event(bc, EVENT_PROCEEDING ); 04298 } else { 04299 ch->state = MISDN_INCOMING_SETUP; 04300 } 04301 start_pbx(ch, bc, chan); 04302 break; 04303 } 04304 04305 /* 04306 * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 04307 * Infos with a Interdigit Timeout. 04308 * */ 04309 if (ch->overlap_dial) { 04310 ast_mutex_lock(&ch->overlap_tv_lock); 04311 ch->overlap_tv = ast_tvnow(); 04312 ast_mutex_unlock(&ch->overlap_tv_lock); 04313 04314 if (ch->overlap_dial_task == -1) 04315 ch->overlap_dial_task = 04316 misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch); 04317 04318 wait_for_digits(ch, bc, chan); 04319 break; 04320 } 04321 04322 /* If the extension does not exist and we're not TE_PTMP we wait for more digis 04323 * without interdigit timeout. 04324 * */ 04325 if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04326 wait_for_digits(ch, bc, chan); 04327 break; 04328 } 04329 04330 /* 04331 * If the extension exists let's just jump into it. 04332 * */ 04333 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 04334 if (bc->need_more_infos) 04335 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 04336 else 04337 misdn_lib_send_event(bc, EVENT_PROCEEDING); 04338 04339 ch->state=MISDN_DIALING; 04340 start_pbx(ch, bc, chan); 04341 break; 04342 } 04343 } 04344 break; 04345 04346 case EVENT_SETUP_ACKNOWLEDGE: 04347 { 04348 ch->state = MISDN_CALLING_ACKNOWLEDGE; 04349 04350 if (bc->channel) 04351 update_name(ch->ast,bc->port,bc->channel); 04352 04353 if (!ast_strlen_zero(bc->infos_pending)) { 04354 /* TX Pending Infos */ 04355 04356 { 04357 int l = sizeof(bc->dad); 04358 strncat(bc->dad,bc->infos_pending, l - strlen(bc->dad)); 04359 bc->dad[l-1] = 0; 04360 } 04361 04362 if (!ch->ast) break; 04363 { 04364 int l = sizeof(ch->ast->exten); 04365 strncpy(ch->ast->exten, bc->dad, l); 04366 ch->ast->exten[l-1] = 0; 04367 } 04368 { 04369 int l = sizeof(bc->info_dad); 04370 strncpy(bc->info_dad, bc->infos_pending, l); 04371 bc->info_dad[l-1] = 0; 04372 } 04373 strncpy(bc->infos_pending,"", 1); 04374 04375 misdn_lib_send_event(bc, EVENT_INFORMATION); 04376 } 04377 } 04378 break; 04379 case EVENT_PROCEEDING: 04380 { 04381 if (bc->channel) 04382 update_name(ch->ast,bc->port,bc->channel); 04383 04384 if ( misdn_cap_is_speech(bc->capability) && 04385 misdn_inband_avail(bc) ) { 04386 start_bc_tones(ch); 04387 } 04388 04389 ch->state = MISDN_PROCEEDING; 04390 04391 if (!ch->ast) break; 04392 04393 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 04394 } 04395 break; 04396 case EVENT_PROGRESS: 04397 if (bc->channel) 04398 update_name(ch->ast,bc->port,bc->channel); 04399 04400 if (!bc->nt ) { 04401 if ( misdn_cap_is_speech(bc->capability) && 04402 misdn_inband_avail(bc) 04403 ) { 04404 start_bc_tones(ch); 04405 } 04406 04407 ch->state=MISDN_PROGRESS; 04408 04409 if (!ch->ast) break; 04410 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 04411 } 04412 break; 04413 04414 04415 case EVENT_ALERTING: 04416 { 04417 if (bc->channel) 04418 update_name(ch->ast,bc->port,bc->channel); 04419 04420 ch->state = MISDN_ALERTING; 04421 04422 if (!ch->ast) break; 04423 04424 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 04425 ast_setstate(ch->ast, AST_STATE_RINGING); 04426 04427 cb_log(7,bc->port," --> Set State Ringing\n"); 04428 04429 if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 04430 cb_log(1,bc->port,"Starting Tones, we have inband Data\n"); 04431 start_bc_tones(ch); 04432 } else { 04433 cb_log(3,bc->port," --> We have no inband Data, the other end must create ringing\n"); 04434 if (ch->far_alerting) { 04435 cb_log(1,bc->port," --> The other end can not do ringing eh ?.. we must do all ourself.."); 04436 start_bc_tones(ch); 04437 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 04438 } 04439 } 04440 } 04441 break; 04442 case EVENT_CONNECT: 04443 { 04444 /*we answer when we've got our very new L3 ID from the NT stack */ 04445 misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE); 04446 04447 if (!ch->ast) break; 04448 04449 struct ast_channel *bridged=ast_bridged_channel(ch->ast); 04450 stop_indicate(ch); 04451 04452 if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) { 04453 struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged); 04454 04455 chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad); 04456 if (bridged_ch) { 04457 bridged_ch->bc->cpnnumplan=bc->cpnnumplan; 04458 ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad)); 04459 } 04460 } 04461 } 04462 04463 /* notice that we don't break here!*/ 04464 case EVENT_CONNECT_ACKNOWLEDGE: 04465 { 04466 ch->l3id=bc->l3_id; 04467 ch->addr=bc->addr; 04468 04469 start_bc_tones(ch); 04470 04471 ch->state = MISDN_CONNECTED; 04472 04473 if (!ch->ast) break; 04474 04475 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 04476 } 04477 break; 04478 case EVENT_DISCONNECT: 04479 /*we might not have an ch->ast ptr here anymore*/ 04480 if (ch) { 04481 struct chan_list *holded_ch=find_holded(cl_te, bc); 04482 04483 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); 04484 if ( ch->originator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 04485 /* If there's inband information available (e.g. a 04486 recorded message saying what was wrong with the 04487 dialled number, or perhaps even giving an 04488 alternative number, then play it instead of 04489 immediately releasing the call */ 04490 chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 04491 04492 ch->state=MISDN_DISCONNECTED; 04493 start_bc_tones(ch); 04494 04495 if (ch->ast) { 04496 ch->ast->hangupcause=bc->cause; 04497 if (bc->cause == 17) 04498 ast_queue_control(ch->ast, AST_CONTROL_BUSY); 04499 } 04500 ch->need_busy=0; 04501 break; 04502 } 04503 04504 /*Check for holded channel, to implement transfer*/ 04505 if ( holded_ch && 04506 holded_ch != ch && 04507 ch->ast && 04508 ch->state == MISDN_CONNECTED ) { 04509 cb_log(1,bc->port," --> found holded ch\n"); 04510 misdn_transfer_bc(ch, holded_ch) ; 04511 } 04512 04513 bc->need_disconnect=0; 04514 04515 stop_bc_tones(ch); 04516 hangup_chan(ch); 04517 } else { 04518 /* ch=find_holded_l3(cl_te, bc->l3_id,1); 04519 if (ch) { 04520 hangup_chan(ch); 04521 } 04522 */ 04523 } 04524 bc->out_cause=-1; 04525 if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE); 04526 break; 04527 04528 case EVENT_RELEASE: 04529 { 04530 bc->need_disconnect=0; 04531 bc->need_release=0; 04532 04533 hangup_chan(ch); 04534 release_chan(bc); 04535 04536 if (bc->need_release_complete) 04537 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04538 } 04539 break; 04540 case EVENT_RELEASE_COMPLETE: 04541 { 04542 bc->need_disconnect=0; 04543 bc->need_release=0; 04544 bc->need_release_complete=0; 04545 04546 stop_bc_tones(ch); 04547 hangup_chan(ch); 04548 04549 if(ch) 04550 ch->state=MISDN_CLEANING; 04551 04552 release_chan(bc); 04553 } 04554 break; 04555 case EVENT_BCHAN_ERROR: 04556 case EVENT_CLEANUP: 04557 { 04558 stop_bc_tones(ch); 04559 04560 switch(ch->state) { 04561 case MISDN_CALLING: 04562 bc->cause=27; /* Destination out of order */ 04563 break; 04564 default: 04565 break; 04566 } 04567 04568 hangup_chan(ch); 04569 release_chan(bc); 04570 } 04571 break; 04572 04573 case EVENT_TONE_GENERATE: 04574 { 04575 int tone_len=bc->tone_cnt; 04576 struct ast_channel *ast=ch->ast; 04577 void *tmp; 04578 int res; 04579 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 04580 04581 chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n"); 04582 04583 if (!ast) break; 04584 04585 if (!ast->generator) break; 04586 04587 04588 04589 tmp = ast->generatordata; 04590 ast->generatordata = NULL; 04591 generate = ast->generator->generate; 04592 04593 if (tone_len <0 || tone_len > 512 ) { 04594 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len); 04595 tone_len=128; 04596 } 04597 04598 res = generate(ast, tmp, tone_len, tone_len); 04599 ast->generatordata = tmp; 04600 04601 if (res) { 04602 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 04603 ast_deactivate_generator(ast); 04604 } else { 04605 bc->tone_cnt=0; 04606 } 04607 } 04608 break; 04609 04610 case EVENT_BCHAN_DATA: 04611 { 04612 if ( !misdn_cap_is_speech(ch->bc->capability) ) { 04613 struct ast_frame frame; 04614 /*In Data Modes we queue frames*/ 04615 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 04616 frame.subclass = AST_FORMAT_ALAW; 04617 frame.datalen = bc->bframe_len; 04618 frame.samples = bc->bframe_len ; 04619 frame.mallocd =0 ; 04620 frame.offset= 0 ; 04621 frame.delivery= ast_tv(0,0) ; 04622 frame.src = NULL; 04623 frame.data = bc->bframe ; 04624 04625 if (ch->ast) 04626 ast_queue_frame(ch->ast,&frame); 04627 } else { 04628 fd_set wrfs; 04629 struct timeval tv; 04630 tv.tv_sec=0; 04631 tv.tv_usec=0; 04632 04633 04634 FD_ZERO(&wrfs); 04635 FD_SET(ch->pipe[1],&wrfs); 04636 04637 int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv); 04638 04639 if (!t) { 04640 chan_misdn_log(9, bc->port, "Select Timed out\n"); 04641 break; 04642 } 04643 04644 if (t<0) { 04645 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno)); 04646 break; 04647 } 04648 04649 if (FD_ISSET(ch->pipe[1],&wrfs)) { 04650 chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len); 04651 int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len); 04652 04653 if (ret<=0) { 04654 chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n",strerror(errno)); 04655 04656 stop_bc_tones(ch); 04657 hangup_chan(ch); 04658 release_chan(bc); 04659 } 04660 } else { 04661 chan_misdn_log(1, bc->port, "Wripe Pipe full!\n"); 04662 } 04663 } 04664 } 04665 break; 04666 case EVENT_TIMEOUT: 04667 { 04668 if (ch && bc) 04669 chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch)); 04670 04671 switch (ch->state) { 04672 case MISDN_DIALING: 04673 case MISDN_PROGRESS: 04674 if (bc->nt && !ch->nttimeout) break; 04675 04676 case MISDN_CALLING: 04677 case MISDN_ALERTING: 04678 case MISDN_PROCEEDING: 04679 case MISDN_CALLING_ACKNOWLEDGE: 04680 if (bc->nt) { 04681 bc->progress_indicator=8; 04682 hanguptone_indicate(ch); 04683 } 04684 04685 bc->out_cause=1; 04686 misdn_lib_send_event(bc,EVENT_DISCONNECT); 04687 break; 04688 04689 case MISDN_WAITING4DIGS: 04690 if (bc->nt) { 04691 bc->progress_indicator=8; 04692 bc->out_cause=1; 04693 hanguptone_indicate(ch); 04694 misdn_lib_send_event(bc,EVENT_DISCONNECT); 04695 } else { 04696 bc->out_cause=16; 04697 misdn_lib_send_event(bc,EVENT_RELEASE); 04698 } 04699 04700 break; 04701 04702 04703 case MISDN_CLEANING: 04704 chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n"); 04705 break; 04706 04707 default: 04708 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 04709 } 04710 } 04711 break; 04712 04713 04714 /***************************/ 04715 /** Suplementary Services **/ 04716 /***************************/ 04717 case EVENT_RETRIEVE: 04718 { 04719 if (!ch) { 04720 chan_misdn_log(4, bc->port, " --> no CH, searching in holded"); 04721 ch=find_holded_l3(cl_te, bc->l3_id,1); 04722 } 04723 04724 if (!ch) { 04725 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n"); 04726 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04727 break; 04728 } 04729 04730 /*remember the channel again*/ 04731 ch->bc=bc; 04732 ch->state = MISDN_CONNECTED; 04733 04734 ch->hold_info.port=0; 04735 ch->hold_info.channel=0; 04736 04737 struct ast_channel *hold_ast=ast_bridged_channel(ch->ast); 04738 04739 if (hold_ast) { 04740 ast_moh_stop(hold_ast); 04741 } 04742 04743 if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) 04744 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 04745 } 04746 break; 04747 04748 case EVENT_HOLD: 04749 { 04750 int hold_allowed; 04751 misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int)); 04752 04753 if (!hold_allowed) { 04754 04755 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 04756 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04757 break; 04758 } 04759 04760 struct ast_channel *bridged=ast_bridged_channel(ch->ast); 04761 04762 if (bridged) { 04763 chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type); 04764 ch->state = MISDN_HOLDED; 04765 ch->l3id = bc->l3_id; 04766 04767 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 04768 04769 /* XXX This should queue an AST_CONTROL_HOLD frame on this channel 04770 * instead of starting moh on the bridged channel directly */ 04771 ast_moh_start(bridged, NULL, NULL); 04772 04773 /*forget the channel now*/ 04774 ch->bc=NULL; 04775 ch->hold_info.port=bc->port; 04776 ch->hold_info.channel=bc->channel; 04777 04778 } else { 04779 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 04780 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 04781 } 04782 } 04783 break; 04784 04785 case EVENT_FACILITY: 04786 if (!ch) { 04787 /* This may come from a call we don't know nothing about, so we ignore it. */ 04788 chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n"); 04789 break; 04790 } 04791 04792 print_facility(&(bc->fac_in), bc); 04793 04794 switch (bc->fac_in.Function) { 04795 case Fac_CD: 04796 { 04797 struct ast_channel *bridged=ast_bridged_channel(ch->ast); 04798 struct chan_list *ch_br; 04799 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 04800 ch_br=MISDN_ASTERISK_TECH_PVT(bridged); 04801 /*ch->state=MISDN_FACILITY_DEFLECTED;*/ 04802 if (ch_br->bc) { 04803 if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) { 04804 ch_br->state=MISDN_DIALING; 04805 if (pbx_start_chan(ch_br) < 0) { 04806 chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 04807 } 04808 } 04809 } 04810 04811 } 04812 misdn_lib_send_event(bc, EVENT_DISCONNECT); 04813 } 04814 break; 04815 case Fac_AOCDCurrency: 04816 bc->AOCDtype = Fac_AOCDCurrency; 04817 memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency)); 04818 export_aoc_vars(ch->originator, ch->ast, bc); 04819 break; 04820 case Fac_AOCDChargingUnit: 04821 bc->AOCDtype = Fac_AOCDChargingUnit; 04822 memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit)); 04823 export_aoc_vars(ch->originator, ch->ast, bc); 04824 break; 04825 default: 04826 chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_in.Function); 04827 } 04828 04829 break; 04830 04831 case EVENT_RESTART: 04832 04833 if (!bc->dummy) { 04834 stop_bc_tones(ch); 04835 release_chan(bc); 04836 } 04837 04838 break; 04839 04840 default: 04841 chan_misdn_log(1,0, "Got Unknown Event\n"); 04842 break; 04843 } 04844 04845 return RESPONSE_OK; 04846 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 5373 of file chan_misdn.c.
References find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().
Referenced by load_module().
05374 { 05375 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 05376 05377 if (ch && ch->jb) { 05378 return misdn_jb_empty(ch->jb, buf, len); 05379 } 05380 05381 return -1; 05382 }
void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 5558 of file chan_misdn.c.
References ast_console_puts(), ast_log(), ast_strlen_zero(), and LOG_WARNING.
Referenced by cb_events(), cl_queue_chan(), config_jitterbuffer(), debug_numplan(), dialtone_indicate(), do_immediate_setup(), export_ch(), find_chan_by_bc(), find_chan_by_pid(), find_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().
05559 { 05560 if (! ((0 <= port) && (port <= max_ports))) { 05561 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 05562 port=0; 05563 level=-1; 05564 } 05565 05566 va_list ap; 05567 char buf[1024]; 05568 char port_buf[8]; 05569 sprintf(port_buf,"P[%2d] ",port); 05570 05571 va_start(ap, tmpl); 05572 vsnprintf( buf, 1023, tmpl, ap ); 05573 va_end(ap); 05574 05575 if (level == -1) 05576 ast_log(LOG_WARNING, buf); 05577 05578 else if (misdn_debug_only[port] ? 05579 (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) 05580 : level <= misdn_debug[port]) { 05581 05582 ast_console_puts(port_buf); 05583 ast_console_puts(buf); 05584 } 05585 05586 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 05587 time_t tm = time(NULL); 05588 char *tmp=ctime(&tm),*p; 05589 05590 FILE *fp= fopen(global_tracefile, "a+"); 05591 05592 p=strchr(tmp,'\n'); 05593 if (p) *p=':'; 05594 05595 if (!fp) { 05596 ast_console_puts("Error opening Tracefile: [ "); 05597 ast_console_puts(global_tracefile); 05598 ast_console_puts(" ] "); 05599 05600 ast_console_puts(strerror(errno)); 05601 ast_console_puts("\n"); 05602 return ; 05603 } 05604 05605 fputs(tmp,fp); 05606 fputs(" ", fp); 05607 fputs(port_buf,fp); 05608 fputs(" ", fp); 05609 fputs(buf, fp); 05610 05611 fclose(fp); 05612 } 05613 }
Definition at line 3435 of file chan_misdn.c.
References ast_dsp_free(), ast_mutex_lock(), ast_mutex_unlock(), ast_translator_free_path(), chan_list::dsp, chan_list::next, and chan_list::trans.
Referenced by misdn_hangup(), and release_chan().
03436 { 03437 if (chan->dsp) 03438 ast_dsp_free(chan->dsp); 03439 if (chan->trans) 03440 ast_translator_free_path(chan->trans); 03441 03442 03443 03444 ast_mutex_lock(&cl_te_lock); 03445 if (!*list) { 03446 ast_mutex_unlock(&cl_te_lock); 03447 return; 03448 } 03449 03450 if (*list == chan) { 03451 *list=(*list)->next; 03452 ast_mutex_unlock(&cl_te_lock); 03453 return ; 03454 } 03455 03456 { 03457 struct chan_list *help=*list; 03458 for (;help->next; help=help->next) { 03459 if (help->next == chan) { 03460 help->next=help->next->next; 03461 ast_mutex_unlock(&cl_te_lock); 03462 return; 03463 } 03464 } 03465 } 03466 03467 ast_mutex_unlock(&cl_te_lock); 03468 }
Definition at line 3419 of file chan_misdn.c.
References ast_mutex_lock(), ast_mutex_unlock(), chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::port.
Referenced by cb_events(), and misdn_request().
03420 { 03421 chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan); 03422 03423 ast_mutex_lock(&cl_te_lock); 03424 if (!*list) { 03425 *list = chan; 03426 } else { 03427 struct chan_list *help=*list; 03428 for (;help->next; help=help->next); 03429 help->next=chan; 03430 } 03431 chan->next=NULL; 03432 ast_mutex_unlock(&cl_te_lock); 03433 }
static char* complete_ch | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1421 of file chan_misdn.c.
References complete_ch_helper().
01422 { 01423 return complete_ch_helper(line, word, pos, state, 3); 01424 }
static char* complete_ch_helper | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) | [static] |
Definition at line 1397 of file chan_misdn.c.
References ast_channel_walk_locked(), ast_mutex_unlock(), ast_channel::lock, and strdup.
Referenced by complete_ch().
01398 { 01399 struct ast_channel *c; 01400 int which=0; 01401 char *ret; 01402 if (pos != rpos) 01403 return NULL; 01404 c = ast_channel_walk_locked(NULL); 01405 while(c) { 01406 if (!strncasecmp(word, c->name, strlen(word))) { 01407 if (++which > state) 01408 break; 01409 } 01410 ast_mutex_unlock(&c->lock); 01411 c = ast_channel_walk_locked(c); 01412 } 01413 if (c) { 01414 ret = strdup(c->name); 01415 ast_mutex_unlock(&c->lock); 01416 } else 01417 ret = NULL; 01418 return ret; 01419 }
static char* complete_debug_port | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1426 of file chan_misdn.c.
References strdup.
01427 { 01428 if (state) 01429 return NULL; 01430 01431 switch (pos) { 01432 case 4: if (*word == 'p') 01433 return strdup("port"); 01434 else if (*word == 'o') 01435 return strdup("only"); 01436 break; 01437 case 6: if (*word == 'o') 01438 return strdup("only"); 01439 break; 01440 } 01441 return NULL; 01442 }
static char* complete_show_config | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1444 of file chan_misdn.c.
References BUFFERSIZE, MISDN_CFG_FIRST, misdn_cfg_get_name(), misdn_cfg_get_next_port(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, and strdup.
01445 { 01446 char buffer[BUFFERSIZE]; 01447 enum misdn_cfg_elements elem; 01448 int wordlen = strlen(word); 01449 int which = 0; 01450 int port = 0; 01451 01452 switch (pos) { 01453 case 3: if ((!strncmp(word, "description", wordlen)) && (++which > state)) 01454 return strdup("description"); 01455 if ((!strncmp(word, "descriptions", wordlen)) && (++which > state)) 01456 return strdup("descriptions"); 01457 if ((!strncmp(word, "0", wordlen)) && (++which > state)) 01458 return strdup("0"); 01459 while ((port = misdn_cfg_get_next_port(port)) != -1) { 01460 snprintf(buffer, sizeof(buffer), "%d", port); 01461 if ((!strncmp(word, buffer, wordlen)) && (++which > state)) { 01462 return strdup(buffer); 01463 } 01464 } 01465 break; 01466 case 4: 01467 if (strstr(line, "description ")) { 01468 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 01469 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) 01470 continue; 01471 misdn_cfg_get_name(elem, buffer, BUFFERSIZE); 01472 if (!wordlen || !strncmp(word, buffer, wordlen)) { 01473 if (++which > state) 01474 return strdup(buffer); 01475 } 01476 } 01477 } else if (strstr(line, "descriptions ")) { 01478 if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state)) 01479 return strdup("general"); 01480 if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state)) 01481 return strdup("ports"); 01482 } 01483 break; 01484 } 01485 return NULL; 01486 }
static void config_jitterbuffer | ( | struct chan_list * | ch | ) | [static] |
Definition at line 1639 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().
01640 { 01641 struct misdn_bchannel *bc=ch->bc; 01642 int len=ch->jb_len, threshold=ch->jb_upper_threshold; 01643 01644 chan_misdn_log(5,bc->port, "config_jb: Called\n"); 01645 01646 if ( ! len ) { 01647 chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n"); 01648 bc->nojitter=1; 01649 } else { 01650 01651 if (len <=100 || len > 8000) { 01652 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 01653 len=1000; 01654 } 01655 01656 if ( threshold > len ) { 01657 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 01658 } 01659 01660 if ( ch->jb) { 01661 cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n"); 01662 misdn_jb_destroy(ch->jb); 01663 ch->jb=NULL; 01664 } 01665 01666 ch->jb=misdn_jb_init(len, threshold); 01667 01668 if (!ch->jb ) 01669 bc->nojitter=1; 01670 } 01671 }
void debug_numplan | ( | int | port, | |
int | numplan, | |||
char * | type | |||
) |
Definition at line 1674 of file chan_misdn.c.
References chan_misdn_log(), NUMPLAN_INTERNATIONAL, NUMPLAN_NATIONAL, NUMPLAN_SUBSCRIBER, and NUMPLAN_UNKNOWN.
Referenced by read_config().
01675 { 01676 switch (numplan) { 01677 case NUMPLAN_INTERNATIONAL: 01678 chan_misdn_log(2, port, " --> %s: International\n",type); 01679 break; 01680 case NUMPLAN_NATIONAL: 01681 chan_misdn_log(2, port, " --> %s: National\n",type); 01682 break; 01683 case NUMPLAN_SUBSCRIBER: 01684 chan_misdn_log(2, port, " --> %s: Subscriber\n",type); 01685 break; 01686 case NUMPLAN_UNKNOWN: 01687 chan_misdn_log(2, port, " --> %s: Unknown\n",type); 01688 break; 01689 /* Maybe we should cut off the prefix if present ? */ 01690 default: 01691 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 01692 break; 01693 } 01694 }
static int dialtone_indicate | ( | struct chan_list * | cl | ) | [static] |
AST INDICATIONS END
Definition at line 2927 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().
02928 { 02929 const struct tone_zone_sound *ts= NULL; 02930 struct ast_channel *ast=cl->ast; 02931 02932 if (!ast) { 02933 chan_misdn_log(0,cl->bc->port,"No Ast in dialtone_indicate\n"); 02934 return -1; 02935 } 02936 02937 int nd=0; 02938 misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 02939 02940 if (nd) { 02941 chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n"); 02942 return 0; 02943 } 02944 02945 chan_misdn_log(3,cl->bc->port," --> Dial\n"); 02946 ts=ast_get_indication_tone(ast->zone,"dial"); 02947 cl->ts=ts; 02948 02949 if (ts) { 02950 cl->notxtone=0; 02951 cl->norxtone=0; 02952 /* This prods us in misdn_write */ 02953 ast_playtones_start(ast,0, ts->data, 0); 02954 } 02955 02956 return 0; 02957 }
static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
struct chan_list * | ch, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 3609 of file chan_misdn.c.
References chan_list::ast, AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_frame::data, ast_frame::datalen, ast_frame::delivery, EVENT_DISCONNECT, EVENT_PROCEEDING, EVENT_RELEASE_COMPLETE, EVENT_SETUP_ACKNOWLEDGE, ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, MISDN_INCOMING_SETUP, misdn_lib_is_ptp(), misdn_lib_send_event(), chan_list::noautorespond_on_setup, misdn_bchannel::nt, ast_frame::offset, pbx_start_chan(), misdn_bchannel::port, ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass.
Referenced by cb_events().
03610 { 03611 char predial[256]=""; 03612 char *p = predial; 03613 03614 struct ast_frame fr; 03615 03616 strncpy(predial, ast->exten, sizeof(predial) -1 ); 03617 03618 ch->state=MISDN_DIALING; 03619 03620 if (!ch->noautorespond_on_setup) { 03621 if (bc->nt) { 03622 int ret; 03623 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03624 } else { 03625 int ret; 03626 if ( misdn_lib_is_ptp(bc->port)) { 03627 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03628 } else { 03629 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03630 } 03631 } 03632 } else { 03633 ch->state = MISDN_INCOMING_SETUP; 03634 } 03635 03636 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); 03637 03638 strncpy(ast->exten,"s", 2); 03639 03640 if (pbx_start_chan(ch)<0) { 03641 ast=NULL; 03642 hangup_chan(ch); 03643 hanguptone_indicate(ch); 03644 03645 if (bc->nt) 03646 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03647 else 03648 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03649 } 03650 03651 03652 while (!ast_strlen_zero(p) ) { 03653 fr.frametype = AST_FRAME_DTMF; 03654 fr.subclass = *p ; 03655 fr.src=NULL; 03656 fr.data = NULL ; 03657 fr.datalen = 0; 03658 fr.samples = 0 ; 03659 fr.mallocd =0 ; 03660 fr.offset= 0 ; 03661 fr.delivery= ast_tv(0,0) ; 03662 03663 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03664 ast_queue_frame(ch->ast, &fr); 03665 } 03666 p++; 03667 } 03668 }
static void export_aoc_vars | ( | int | originator, | |
struct ast_channel * | ast, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 495 of file chan_misdn.c.
References misdn_bchannel::AOCD, misdn_bchannel::AOCDtype, ast_bridged_channel(), misdn_bchannel::chargingUnit, misdn_bchannel::currency, ORG_AST, and pbx_builtin_setvar_helper().
Referenced by cb_events().
00496 { 00497 char buf[128]; 00498 00499 if (!ast) 00500 return; 00501 00502 if (originator == ORG_AST) { 00503 ast = ast_bridged_channel(ast); 00504 if (!ast) 00505 return; 00506 } 00507 00508 switch (bc->AOCDtype) { 00509 case Fac_AOCDCurrency: 00510 pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency"); 00511 if (bc->AOCD.currency.chargeNotAvailable) 00512 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00513 else { 00514 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00515 if (bc->AOCD.currency.freeOfCharge) 00516 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00517 else { 00518 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00519 if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) { 00520 pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf); 00521 if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) 00522 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00523 } 00524 } 00525 } 00526 break; 00527 case Fac_AOCDChargingUnit: 00528 pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit"); 00529 if (bc->AOCD.chargingUnit.chargeNotAvailable) 00530 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no"); 00531 else { 00532 pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes"); 00533 if (bc->AOCD.chargingUnit.freeOfCharge) 00534 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes"); 00535 else { 00536 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no"); 00537 if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) { 00538 pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf); 00539 if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) 00540 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf); 00541 } 00542 } 00543 } 00544 break; 00545 default: 00546 break; 00547 } 00548 }
void export_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Definition at line 3764 of file chan_misdn.c.
References 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().
03765 { 03766 char tmp[32]; 03767 chan_misdn_log(3,bc->port," --> EXPORT_PID: pid:%d\n",bc->pid); 03768 sprintf(tmp,"%d",bc->pid); 03769 pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp); 03770 03771 if (bc->sending_complete) { 03772 sprintf(tmp,"%d",bc->sending_complete); 03773 pbx_builtin_setvar_helper(chan,"MISDN_ADDRESS_COMPLETE",tmp); 03774 } 03775 03776 if (bc->urate) { 03777 sprintf(tmp,"%d",bc->urate); 03778 pbx_builtin_setvar_helper(chan,"MISDN_URATE",tmp); 03779 } 03780 03781 if (bc->uulen) { 03782 pbx_builtin_setvar_helper(chan,"MISDN_USERUSER",bc->uu); 03783 } 03784 03785 if (bc->keypad[0]) 03786 pbx_builtin_setvar_helper(chan,"MISDN_KEYPAD",bc->keypad); 03787 }
static struct chan_list * find_chan_by_bc | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static, read] |
Definition at line 3361 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().
03362 { 03363 struct chan_list *help=list; 03364 for (;help; help=help->next) { 03365 if (help->bc == bc) return help; 03366 } 03367 03368 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 03369 03370 return NULL; 03371 }
Definition at line 3373 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), chan_list::next, and misdn_bchannel::pid.
Referenced by import_ch().
03374 { 03375 struct chan_list *help=list; 03376 for (;help; help=help->next) { 03377 if ( help->bc && (help->bc->pid == pid) ) return help; 03378 } 03379 03380 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid); 03381 03382 return NULL; 03383 }
static struct chan_list* find_holded | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static, read] |
Definition at line 3385 of file chan_misdn.c.
References 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().
03386 { 03387 struct chan_list *help=list; 03388 03389 if (bc->pri) return NULL; 03390 03391 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad); 03392 for (;help; help=help->next) { 03393 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel); 03394 if ( (help->state == MISDN_HOLDED) && 03395 (help->hold_info.port == bc->port) ) 03396 return help; 03397 } 03398 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 03399 03400 return NULL; 03401 }
static struct chan_list* find_holded_l3 | ( | struct chan_list * | list, | |
unsigned long | l3_id, | |||
int | w | |||
) | [static, read] |
Definition at line 3404 of file chan_misdn.c.
References chan_list::l3id, MISDN_HOLDED, chan_list::next, and chan_list::state.
Referenced by cb_events().
03406 { 03407 struct chan_list *help=list; 03408 03409 for (;help; help=help->next) { 03410 if ( (help->state == MISDN_HOLDED) && 03411 (help->l3id == l3_id) 03412 ) 03413 return help; 03414 } 03415 03416 return NULL; 03417 }
static void free_robin_list | ( | void | ) | [static] |
Definition at line 256 of file chan_misdn.c.
References free_robin_list_r().
Referenced by reload_config(), and unload_module().
00257 { 00258 free_robin_list_r(robin); 00259 robin = NULL; 00260 }
static void free_robin_list_r | ( | struct robin_list * | r | ) | [inline, static] |
Definition at line 247 of file chan_misdn.c.
References free, robin_list::group, and robin_list::next.
Referenced by free_robin_list().
00248 { 00249 if (r) { 00250 if (r->next) free_robin_list_r(r->next); 00251 if (r->group) free(r->group); 00252 free(r); 00253 } 00254 }
static struct chan_list* get_chan_by_ast | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 371 of file chan_misdn.c.
References chan_list::ast, and chan_list::next.
Referenced by misdn_bridge().
00372 { 00373 struct chan_list *tmp; 00374 00375 for (tmp=cl_te; tmp; tmp = tmp->next) { 00376 if ( tmp->ast == ast ) return tmp; 00377 } 00378 00379 return NULL; 00380 }
static struct chan_list* get_chan_by_ast_name | ( | char * | name | ) | [static, read] |
Definition at line 382 of file chan_misdn.c.
References chan_list::ast, and chan_list::next.
Referenced by misdn_send_cd(), misdn_send_digit(), misdn_send_display(), and misdn_toggle_echocancel().
00383 { 00384 struct chan_list *tmp; 00385 00386 for (tmp=cl_te; tmp; tmp = tmp->next) { 00387 if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp; 00388 } 00389 00390 return NULL; 00391 }
static struct robin_list* get_robin_position | ( | char * | group | ) | [static, read] |
Definition at line 262 of file chan_misdn.c.
References calloc, robin_list::group, robin_list::next, robin_list::prev, and strndup.
Referenced by misdn_request().
00263 { 00264 struct robin_list *iter = robin; 00265 for (; iter; iter = iter->next) { 00266 if (!strcasecmp(iter->group, group)) 00267 return iter; 00268 } 00269 struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list)); 00270 new->group = strndup(group, strlen(group)); 00271 new->channel = 1; 00272 if (robin) { 00273 new->next = robin; 00274 robin->prev = new; 00275 } 00276 robin = new; 00277 return robin; 00278 }
static void hangup_chan | ( | struct chan_list * | ch | ) | [static] |
Definition at line 3485 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().
03486 { 03487 int port=ch?ch->bc?ch->bc->port:0:0; 03488 if (!ch) { 03489 cb_log(1,0,"Cannot hangup chan, no ch\n"); 03490 return; 03491 } 03492 03493 cb_log(5,port,"hangup_chan called\n"); 03494 03495 if (ch->need_hangup) 03496 { 03497 cb_log(2,port," --> hangup\n"); 03498 send_cause2ast(ch->ast,ch->bc,ch); 03499 ch->need_hangup=0; 03500 ch->need_queue_hangup=0; 03501 if (ch->ast) 03502 ast_hangup(ch->ast); 03503 return; 03504 } 03505 03506 if (!ch->need_queue_hangup) { 03507 cb_log(2,port," --> No need to queue hangup\n"); 03508 } 03509 03510 ch->need_queue_hangup=0; 03511 if (ch->ast) { 03512 send_cause2ast(ch->ast,ch->bc,ch); 03513 03514 if (ch->ast) 03515 ast_queue_hangup(ch->ast); 03516 cb_log(2,port," --> queue_hangup\n"); 03517 } else { 03518 cb_log(1,port,"Cannot hangup chan, no ast\n"); 03519 } 03520 }
static int hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2959 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().
02960 { 02961 misdn_lib_send_tone(cl->bc,TONE_HANGUP); 02962 return 0; 02963 }
void import_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Definition at line 3730 of file chan_misdn.c.
References ast_log(), chan_misdn_log(), find_chan_by_pid(), misdn_bchannel::keypad, LOG_NOTICE, chan_list::other_ch, chan_list::other_pid, pbx_builtin_getvar_helper(), misdn_bchannel::port, misdn_bchannel::sending_complete, misdn_bchannel::uu, and misdn_bchannel::uulen.
Referenced by misdn_call().
03731 { 03732 const char *tmp; 03733 tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID"); 03734 if (tmp) { 03735 ch->other_pid=atoi(tmp); 03736 chan_misdn_log(3,bc->port," --> IMPORT_PID: importing pid:%s\n",tmp); 03737 if (ch->other_pid >0) { 03738 ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid); 03739 if (ch->other_ch) ch->other_ch->other_ch=ch; 03740 } 03741 } 03742 03743 tmp=pbx_builtin_getvar_helper(chan,"MISDN_ADDRESS_COMPLETE"); 03744 if (tmp && (atoi(tmp) == 1)) { 03745 bc->sending_complete=1; 03746 } 03747 03748 tmp=pbx_builtin_getvar_helper(chan,"MISDN_USERUSER"); 03749 if (tmp) { 03750 ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp); 03751 strcpy(bc->uu, tmp); 03752 bc->uulen=strlen(bc->uu); 03753 } 03754 03755 tmp=pbx_builtin_getvar_helper(chan,"MISDN_KEYPAD"); 03756 if (tmp) { 03757 strncpy(bc->keypad,tmp,sizeof(bc->keypad)); 03758 bc->keypad[sizeof(bc->keypad)-1]=0; 03759 } 03760 03761 03762 }
static struct chan_list* init_chan_list | ( | int | orig | ) | [static, read] |
Definition at line 3004 of file chan_misdn.c.
References chan_misdn_log(), malloc, chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, chan_list::originator, and chan_list::overlap_dial_task.
Referenced by cb_events(), and misdn_request().
03005 { 03006 struct chan_list *cl=malloc(sizeof(struct chan_list)); 03007 03008 if (!cl) { 03009 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 03010 return NULL; 03011 } 03012 03013 memset(cl,0,sizeof(struct chan_list)); 03014 03015 cl->originator=orig; 03016 cl->need_queue_hangup=1; 03017 cl->need_hangup=1; 03018 cl->need_busy=1; 03019 cl->overlap_dial_task=-1; 03020 03021 return cl; 03022 03023 }
static int load_module | ( | void | ) | [static] |
Definition at line 4891 of file chan_misdn.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_log(), AST_MODULE_LOAD_DECLINE, ast_mutex_init(), ast_register_application(), BUFFERSIZE, calloc, misdn_lib_iface::cb_event, cb_events(), chan_misdn_jb_empty(), chan_misdn_log(), LOG_ERROR, malloc, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), MISDN_CFG_L1_TIMEOUT, misdn_cfg_update_ptp(), misdn_check_l2l1(), misdn_facility_exec(), MISDN_GEN_DEBUG, MISDN_GEN_NTDEBUGFILE, MISDN_GEN_NTDEBUGFLAGS, MISDN_GEN_TRACEFILE, misdn_l1_task(), misdn_lib_init(), misdn_lib_maxports_get(), misdn_lib_nt_debug_init(), misdn_set_opt_exec(), misdn_tasks_add(), and unload_module().
04892 { 04893 int i, port; 04894 04895 char ports[256]=""; 04896 04897 max_ports=misdn_lib_maxports_get(); 04898 04899 if (max_ports<=0) { 04900 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 04901 return AST_MODULE_LOAD_DECLINE; 04902 } 04903 04904 if (misdn_cfg_init(max_ports)) { 04905 ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n"); 04906 return AST_MODULE_LOAD_DECLINE; 04907 } 04908 g_config_initialized=1; 04909 04910 misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1)); 04911 misdn_ports = (int *)malloc(sizeof(int) * (max_ports+1)); 04912 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int)); 04913 for (i = 1; i <= max_ports; i++) { 04914 misdn_debug[i] = misdn_debug[0]; 04915 misdn_ports[i] = i; 04916 } 04917 *misdn_ports = 0; 04918 misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int)); 04919 04920 { 04921 char tempbuf[BUFFERSIZE+1]; 04922 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE); 04923 if (strlen(tempbuf)) 04924 tracing = 1; 04925 } 04926 04927 misdn_in_calls = (int *)malloc(sizeof(int) * (max_ports+1)); 04928 misdn_out_calls = (int *)malloc(sizeof(int) * (max_ports+1)); 04929 04930 for (i=1; i <= max_ports; i++) { 04931 misdn_in_calls[i]=0; 04932 misdn_out_calls[i]=0; 04933 } 04934 04935 ast_mutex_init(&cl_te_lock); 04936 ast_mutex_init(&release_lock); 04937 04938 misdn_cfg_update_ptp(); 04939 misdn_cfg_get_ports_string(ports); 04940 04941 if (strlen(ports)) 04942 chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports); 04943 04944 { 04945 struct misdn_lib_iface iface = { 04946 .cb_event = cb_events, 04947 .cb_log = chan_misdn_log, 04948 .cb_jb_empty = chan_misdn_jb_empty, 04949 }; 04950 04951 if (misdn_lib_init(ports, &iface, NULL)) 04952 chan_misdn_log(0, 0, "No te ports initialized\n"); 04953 04954 int ntflags=0; 04955 char ntfile[BUFFERSIZE+1]; 04956 04957 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int)); 04958 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE); 04959 04960 misdn_lib_nt_debug_init(ntflags,ntfile); 04961 04962 } 04963 04964 { 04965 if (ast_channel_register(&misdn_tech)) { 04966 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 04967 unload_module(); 04968 return -1; 04969 } 04970 } 04971 04972 ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 04973 04974 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 04975 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n" 04976 "Sets mISDN opts. and optargs\n" 04977 "\n" 04978 "The available options are:\n" 04979 " d - Send display text on called phone, text is the optparam\n" 04980 " n - don't detect dtmf tones on called channel\n" 04981 " h - make digital outgoing call\n" 04982 " c - make crypted outgoing call, param is keyindex\n" 04983 " e - perform echo cancelation on this channel,\n" 04984 " takes taps as arguments (32,64,128,256)\n" 04985 " s - send Non Inband DTMF as inband\n" 04986 " vr - rxgain control\n" 04987 " vt - txgain control\n" 04988 ); 04989 04990 04991 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 04992 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 04993 "Sends the Facility Message FACILITY_TYPE with \n" 04994 "the given Arguments to the current ISDN Channel\n" 04995 "Supported Facilities are:\n" 04996 "\n" 04997 "type=calldeflect args=Nr where to deflect\n" 04998 ); 04999 05000 05001 ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1", 05002 "misdn_check_l2l1(<port>||g:<groupname>,timeout)" 05003 "Checks if the L2 and L1 are up on either the given <port> or\n" 05004 "on the ports in the group with <groupname>\n" 05005 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 05006 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 05007 "\n" 05008 "This application, ensures the L1/L2 state of the Ports in a group\n" 05009 "it is intended to make the pmp_l1_check option redundant and to\n" 05010 "fix a buggy switch config from your provider\n" 05011 "\n" 05012 "a sample dialplan would look like:\n\n" 05013 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 05014 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 05015 "\n" 05016 ); 05017 05018 05019 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 05020 05021 /* start the l1 watchers */ 05022 05023 for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) { 05024 int l1timeout; 05025 misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout)); 05026 if (l1timeout) { 05027 chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout); 05028 misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]); 05029 } 05030 } 05031 05032 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n"); 05033 05034 return 0; 05035 }
static int misdn_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2128 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_queue_hangup(), ast_strlen_zero(), 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().
02129 { 02130 struct chan_list *p; 02131 02132 02133 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02134 02135 chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n"); 02136 02137 if (!p) { 02138 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 02139 ast_queue_hangup(ast); 02140 } 02141 02142 if (!p->bc) { 02143 chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n"); 02144 02145 ast_queue_hangup(ast); 02146 } 02147 02148 { 02149 const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY"); 02150 02151 if (tmp_key ) { 02152 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 02153 { 02154 int l = sizeof(p->bc->crypt_key); 02155 strncpy(p->bc->crypt_key,tmp_key, l); 02156 p->bc->crypt_key[l-1] = 0; 02157 } 02158 } else { 02159 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 02160 } 02161 02162 } 02163 02164 { 02165 const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 02166 if (nodsp) { 02167 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 02168 p->bc->nodsp=1; 02169 p->bc->hdlc=0; 02170 p->bc->nojitter=1; 02171 } 02172 } 02173 02174 p->state = MISDN_CONNECTED; 02175 stop_indicate(p); 02176 02177 if ( ast_strlen_zero(p->bc->cad) ) { 02178 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n"); 02179 ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad)); 02180 } 02181 02182 misdn_lib_send_event( p->bc, EVENT_CONNECT); 02183 start_bc_tones(p); 02184 02185 return 0; 02186 }
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 2817 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_verbose(), ast_waitfor_n(), ast_write(), chan_list::bc, chan_misdn_log(), ast_channel::exten, f, ast_frame::frametype, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, MISDN_CFG_BRIDGING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_bridge(), misdn_lib_split_bridge(), misdn_bchannel::oad, option_verbose, misdn_bchannel::pid, misdn_bchannel::port, ast_frame::subclass, and VERBOSE_PREFIX_3.
02823 { 02824 struct chan_list *ch1,*ch2; 02825 struct ast_channel *carr[2], *who; 02826 int to=-1; 02827 struct ast_frame *f; 02828 02829 ch1=get_chan_by_ast(c0); 02830 ch2=get_chan_by_ast(c1); 02831 02832 carr[0]=c0; 02833 carr[1]=c1; 02834 02835 if (ch1 && ch2 ) ; 02836 else 02837 return -1; 02838 02839 int p1_b, p2_b; 02840 02841 misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int)); 02842 misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int)); 02843 02844 if ( ! p1_b || ! p2_b) { 02845 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n"); 02846 return AST_BRIDGE_FAILED; 02847 } 02848 02849 int bridging; 02850 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 02851 if (bridging) { 02852 /* trying to make a mISDN_dsp conference */ 02853 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1); 02854 misdn_lib_bridge(ch1->bc,ch2->bc); 02855 } 02856 02857 if (option_verbose > 2) 02858 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 02859 02860 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad); 02861 02862 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) ) 02863 ch1->ignore_dtmf=1; 02864 02865 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) ) 02866 ch2->ignore_dtmf=1; 02867 02868 while(1) { 02869 to=-1; 02870 who = ast_waitfor_n(carr, 2, &to); 02871 02872 if (!who) { 02873 ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n"); 02874 break; 02875 } 02876 f = ast_read(who); 02877 02878 if (!f || f->frametype == AST_FRAME_CONTROL) { 02879 /* got hangup .. */ 02880 02881 if (!f) 02882 chan_misdn_log(4,ch1->bc->port,"Read Null Frame\n"); 02883 else 02884 chan_misdn_log(4,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass); 02885 02886 *fo=f; 02887 *rc=who; 02888 02889 break; 02890 } 02891 02892 if ( f->frametype == AST_FRAME_DTMF ) { 02893 chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten); 02894 02895 *fo=f; 02896 *rc=who; 02897 break; 02898 } 02899 02900 #if 0 02901 if (f->frametype == AST_FRAME_VOICE) { 02902 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 02903 02904 continue; 02905 } 02906 #endif 02907 02908 if (who == c0) { 02909 ast_write(c1,f); 02910 } 02911 else { 02912 ast_write(c0,f); 02913 } 02914 02915 } 02916 02917 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 02918 02919 misdn_lib_split_bridge(ch1->bc,ch2->bc); 02920 02921 02922 return AST_BRIDGE_COMPLETE; 02923 }
static int misdn_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
we should have l3id after sending setup
Definition at line 1971 of file chan_misdn.c.
References ast_channel::_state, add_out_calls(), ast_log(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_callerid::cid_rdnis, ast_channel::context, misdn_bchannel::dad, misdn_bchannel::ec_enable, ENOCHAN, EVENT_SETUP, ext, ast_channel::exten, ast_channel::hangupcause, import_ch(), INFO_CAPABILITY_DIGITAL_UNRESTRICTED, misdn_bchannel::l3_id, chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, misdn_cfg_get(), MISDN_GEN_BRIDGING, misdn_lib_send_event(), misdn_set_opt_exec(), misdn_bchannel::nt, misdn_bchannel::oad, ORG_AST, chan_list::other_ch, pbx_builtin_setvar_helper(), misdn_bchannel::pid, misdn_bchannel::port, misdn_bchannel::rad, chan_list::state, stop_bc_tones(), strsep(), ast_channel::transfercapability, and update_config().
01972 { 01973 int port=0; 01974 int r; 01975 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 01976 struct misdn_bchannel *newbc; 01977 char *opts=NULL, *ext; 01978 char dest_cp[256]; 01979 01980 { 01981 strncpy(dest_cp,dest,sizeof(dest_cp)-1); 01982 dest_cp[sizeof(dest_cp)]=0; 01983 01984 ext=dest_cp; 01985 strsep(&ext,"/"); 01986 if (ext) { 01987 opts=ext; 01988 strsep(&opts,"/"); 01989 } else { 01990 ast_log(LOG_WARNING, "Malformed dialstring\n"); 01991 return -1; 01992 } 01993 } 01994 01995 if (!ast) { 01996 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 01997 return -1; 01998 } 01999 02000 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) { 02001 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02002 ast->hangupcause=41; 02003 ast_setstate(ast, AST_STATE_DOWN); 02004 return -1; 02005 } 02006 02007 if (!ch) { 02008 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02009 ast->hangupcause=41; 02010 ast_setstate(ast, AST_STATE_DOWN); 02011 return -1; 02012 } 02013 02014 newbc=ch->bc; 02015 02016 if (!newbc) { 02017 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 02018 ast->hangupcause=41; 02019 ast_setstate(ast, AST_STATE_DOWN); 02020 return -1; 02021 } 02022 02023 port=newbc->port; 02024 02025 02026 int exceed; 02027 if ((exceed=add_out_calls(port))) { 02028 char tmp[16]; 02029 sprintf(tmp,"%d",exceed); 02030 pbx_builtin_setvar_helper(ast,"MAX_OVERFLOW",tmp); 02031 return -1; 02032 } 02033 02034 chan_misdn_log(1, port, "* CALL: %s\n",dest); 02035 02036 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context); 02037 02038 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten); 02039 if (ast->exten) { 02040 int l = sizeof(newbc->dad); 02041 strncpy(ast->exten,ext,sizeof(ast->exten)); 02042 02043 strncpy(newbc->dad,ext,l); 02044 02045 newbc->dad[l-1] = 0; 02046 } 02047 02048 if (ast->cid.cid_rdnis) 02049 strcpy(newbc->rad, ast->cid.cid_rdnis); 02050 else 02051 newbc->rad[0]=0; 02052 02053 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",ast->cid.cid_num); 02054 if (ast_strlen_zero(newbc->oad) && ast->cid.cid_num ) { 02055 02056 if (ast->cid.cid_num) { 02057 int l = sizeof(newbc->oad); 02058 strncpy(newbc->oad,ast->cid.cid_num, l); 02059 newbc->oad[l-1] = 0; 02060 } 02061 } 02062 02063 { 02064 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 02065 if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;} 02066 02067 newbc->capability=ast->transfercapability; 02068 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability)); 02069 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 02070 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 02071 } 02072 02073 02074 /* update screening and presentation */ 02075 update_config(ch,ORG_AST); 02076 02077 /* fill in some ies from channel vary*/ 02078 import_ch(ast, newbc, ch); 02079 02080 /* Finally The Options Override Everything */ 02081 if (opts) 02082 misdn_set_opt_exec(ast,opts); 02083 else 02084 chan_misdn_log(2,port,"NO OPTS GIVEN\n"); 02085 02086 /*check for bridging*/ 02087 int bridging; 02088 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 02089 if (bridging && ch->other_ch) { 02090 #ifdef MISDN_1_2 02091 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n"); 02092 *ch->bc->pipeline=0; 02093 *ch->other_ch->bc->pipeline=0; 02094 #else 02095 chan_misdn_log(1, port, "Disabling EC on both Sides\n"); 02096 ch->bc->ec_enable=0; 02097 ch->other_ch->bc->ec_enable=0; 02098 #endif 02099 } 02100 02101 r=misdn_lib_send_event( newbc, EVENT_SETUP ); 02102 02103 /** we should have l3id after sending setup **/ 02104 ch->l3id=newbc->l3_id; 02105 } 02106 02107 if ( r == -ENOCHAN ) { 02108 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 02109 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1); 02110 ast->hangupcause=34; 02111 ast_setstate(ast, AST_STATE_DOWN); 02112 return -1; 02113 } 02114 02115 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1); 02116 02117 ast_setstate(ast, AST_STATE_DIALING); 02118 ast->hangupcause=16; 02119 02120 if (newbc->nt) stop_bc_tones(ch); 02121 02122 ch->state=MISDN_CALLING; 02123 02124 return 0; 02125 }
static int misdn_check_l2l1 | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5094 of file chan_misdn.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), BUFFERSIZE, chan_misdn_log(), group, LOG_WARNING, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_CFG_GROUPNAME, misdn_lib_get_port_up(), and misdn_lib_port_up().
Referenced by load_module().
05095 { 05096 AST_DECLARE_APP_ARGS(args, 05097 AST_APP_ARG(grouppar); 05098 AST_APP_ARG(timeout); 05099 ); 05100 05101 if (ast_strlen_zero((char *)data)) { 05102 ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n"); 05103 return -1; 05104 } 05105 05106 AST_STANDARD_APP_ARGS(args, data); 05107 05108 if (args.argc != 2) { 05109 ast_log(LOG_WARNING, "Wrong argument count\n"); 05110 return 0; 05111 } 05112 05113 /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/ 05114 char group[BUFFERSIZE+1]; 05115 char *port_str; 05116 05117 int port=0; 05118 int timeout=atoi(args.timeout); 05119 int dowait=0; 05120 05121 port_str=args.grouppar; 05122 05123 int port_up; 05124 if (port_str[0]=='g' && port_str[1]==':' ) { 05125 /* We make a group call lets checkout which ports are in my group */ 05126 port_str += 2; 05127 strncpy(group, port_str, BUFFERSIZE); 05128 group[BUFFERSIZE-1] = 0; 05129 chan_misdn_log(2, 0, "Checking Ports in group: %s\n",group); 05130 05131 for ( port = misdn_cfg_get_next_port(port); 05132 port > 0; 05133 port = misdn_cfg_get_next_port(port)) { 05134 05135 chan_misdn_log(2,0,"trying port %d\n",port); 05136 05137 char cfg_group[BUFFERSIZE+1]; 05138 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 05139 05140 if (!strcasecmp(cfg_group, group)) { 05141 port_up = misdn_lib_port_up(port, 1); 05142 05143 if (!port_up) { 05144 chan_misdn_log(2, 0, " --> port '%d'\n", port); 05145 misdn_lib_get_port_up(port); 05146 dowait=1; 05147 } 05148 } 05149 } 05150 05151 } else { 05152 port = atoi(port_str); 05153 chan_misdn_log(2, 0, "Checking Port: %d\n",port); 05154 port_up = misdn_lib_port_up(port, 1); 05155 if (!port_up) { 05156 misdn_lib_get_port_up(port); 05157 dowait=1; 05158 } 05159 05160 } 05161 05162 if (dowait) { 05163 chan_misdn_log(2, 0, "Waiting for '%d' seconds\n",timeout); 05164 sleep(timeout); 05165 } 05166 05167 return 0; 05168 }
static int misdn_digit_begin | ( | struct ast_channel * | chan, | |
char | digit | |||
) | [static] |
Definition at line 2188 of file chan_misdn.c.
02189 { 02190 /* XXX Modify this callback to support Asterisk controlling the length of DTMF */ 02191 return 0; 02192 }
static int misdn_digit_end | ( | struct ast_channel * | ast, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2194 of file chan_misdn.c.
References chan_list::ast, ast_log(), chan_list::bc, 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.
02195 { 02196 struct chan_list *p; 02197 02198 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1; 02199 02200 struct misdn_bchannel *bc=p->bc; 02201 chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit); 02202 02203 if (!bc) { 02204 ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n"); 02205 return -1; 02206 } 02207 02208 switch (p->state ) { 02209 case MISDN_CALLING: 02210 { 02211 02212 char buf[8]; 02213 buf[0]=digit; 02214 buf[1]=0; 02215 02216 int l = sizeof(bc->infos_pending); 02217 strncat(bc->infos_pending,buf,l); 02218 bc->infos_pending[l-1] = 0; 02219 } 02220 break; 02221 case MISDN_CALLING_ACKNOWLEDGE: 02222 { 02223 bc->info_dad[0]=digit; 02224 bc->info_dad[1]=0; 02225 02226 { 02227 int l = sizeof(bc->dad); 02228 strncat(bc->dad,bc->info_dad, l - strlen(bc->dad)); 02229 bc->dad[l-1] = 0; 02230 } 02231 { 02232 int l = sizeof(p->ast->exten); 02233 strncpy(p->ast->exten, bc->dad, l); 02234 p->ast->exten[l-1] = 0; 02235 } 02236 02237 misdn_lib_send_event( bc, EVENT_INFORMATION); 02238 } 02239 break; 02240 02241 default: 02242 /* Do not send Digits in CONNECTED State, when 02243 * the other side is too mISDN. */ 02244 if (p->other_ch ) 02245 return 0; 02246 02247 if ( bc->send_dtmf ) 02248 send_digit_to_chan(p,digit); 02249 break; 02250 } 02251 02252 return 0; 02253 }
static int misdn_facility_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5048 of file chan_misdn.c.
References ast_log(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), EVENT_FACILITY, misdn_bchannel::fac_out, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_lib_send_event(), misdn_bchannel::port, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module().
05049 { 05050 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05051 char *tok, *tokb; 05052 05053 chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type); 05054 05055 if (strcasecmp(chan->tech->type,"mISDN")) { 05056 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 05057 return -1; 05058 } 05059 05060 if (ast_strlen_zero((char *)data)) { 05061 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05062 return -1; 05063 } 05064 05065 tok=strtok_r((char*)data,"|", &tokb) ; 05066 05067 if (!tok) { 05068 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 05069 return -1; 05070 } 05071 05072 if (!strcasecmp(tok,"calldeflect")) { 05073 tok=strtok_r(NULL,"|", &tokb) ; 05074 05075 if (!tok) { 05076 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 05077 } 05078 05079 if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) { 05080 ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n"); 05081 return 0; 05082 } 05083 ch->bc->fac_out.Function = Fac_CD; 05084 strncpy((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)); 05085 misdn_lib_send_event(ch->bc, EVENT_FACILITY); 05086 } else { 05087 chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n",tok); 05088 } 05089 05090 return 0; 05091 05092 }
static int misdn_fixup | ( | struct ast_channel * | oldast, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 2256 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.
02257 { 02258 struct chan_list *p; 02259 02260 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1; 02261 02262 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); 02263 02264 p->ast = ast ; 02265 02266 return 0; 02267 }
static char* misdn_get_ch_state | ( | struct chan_list * | p | ) | [static] |
Definition at line 1014 of file chan_misdn.c.
References chan_list::state, and state_struct::txt.
Referenced by cb_events(), misdn_fixup(), misdn_hangup(), misdn_write(), print_bc_info(), and release_chan().
01015 { 01016 int i; 01017 static char state[8]; 01018 01019 if( !p) return NULL; 01020 01021 for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) { 01022 if ( state_array[i].state == p->state) return state_array[i].txt; 01023 } 01024 01025 sprintf(state,"%d",p->state) ; 01026 01027 return state; 01028 }
static int misdn_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2403 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, 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(), ast_channel::context, EVENT_DISCONNECT, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, ast_channel::exten, free, ast_channel::hangupcause, hanguptone_indicate(), chan_list::l3id, LOG_DEBUG, 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, chan_list::need_busy, misdn_bchannel::need_disconnect, chan_list::need_hangup, chan_list::need_queue_hangup, 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, misdn_bchannel::progress_indicator, release_chan(), start_bc_tones(), chan_list::state, and stop_bc_tones().
02404 { 02405 struct chan_list *p; 02406 struct misdn_bchannel *bc=NULL; 02407 02408 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name); 02409 02410 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1; 02411 02412 if (!p) { 02413 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n"); 02414 return 0 ; 02415 } 02416 02417 bc=p->bc; 02418 02419 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 02420 p->ast=NULL; 02421 02422 if (ast->_state == AST_STATE_RESERVED || 02423 p->state == MISDN_NOTHING || 02424 p->state == MISDN_HOLDED || 02425 p->state == MISDN_HOLD_DISCONNECT ) { 02426 02427 CLEAN_CH: 02428 /* between request and call */ 02429 ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n"); 02430 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 02431 02432 ast_mutex_lock(&release_lock); 02433 cl_dequeue_chan(&cl_te, p); 02434 close(p->pipe[0]); 02435 close(p->pipe[1]); 02436 free(p); 02437 ast_mutex_unlock(&release_lock); 02438 02439 if (bc) 02440 misdn_lib_release(bc); 02441 02442 return 0; 02443 } 02444 02445 if (!bc) { 02446 ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id); 02447 goto CLEAN_CH; 02448 } 02449 02450 02451 p->need_hangup=0; 02452 p->need_queue_hangup=0; 02453 p->need_busy=0; 02454 02455 02456 if (!p->bc->nt) 02457 stop_bc_tones(p); 02458 02459 02460 { 02461 const char *varcause=NULL; 02462 bc->out_cause=ast->hangupcause?ast->hangupcause:16; 02463 02464 if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) || 02465 (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) { 02466 int tmpcause=atoi(varcause); 02467 bc->out_cause=tmpcause?tmpcause:16; 02468 } 02469 02470 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)); 02471 chan_misdn_log(3, bc->port, " --> l3id:%x\n",p->l3id); 02472 chan_misdn_log(3, bc->port, " --> cause:%d\n",bc->cause); 02473 chan_misdn_log(2, bc->port, " --> out_cause:%d\n",bc->out_cause); 02474 chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p)); 02475 02476 switch (p->state) { 02477 case MISDN_CALLING: 02478 case MISDN_INCOMING_SETUP: 02479 /* This is the only place in misdn_hangup, where we 02480 * can call release_chan, else it might create lot's of trouble 02481 * */ 02482 ast_log(LOG_NOTICE, "release channel, in CALLING/INCOMING_SETUP state.. no other events happened\n"); 02483 release_chan(bc); 02484 02485 p->state=MISDN_CLEANING; 02486 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); 02487 break; 02488 case MISDN_HOLDED: 02489 case MISDN_DIALING: 02490 start_bc_tones(p); 02491 hanguptone_indicate(p); 02492 02493 if (bc->need_disconnect) 02494 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02495 break; 02496 02497 case MISDN_CALLING_ACKNOWLEDGE: 02498 start_bc_tones(p); 02499 hanguptone_indicate(p); 02500 02501 if (bc->need_disconnect) 02502 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02503 break; 02504 02505 case MISDN_ALERTING: 02506 case MISDN_PROGRESS: 02507 case MISDN_PROCEEDING: 02508 if (p->originator != ORG_AST) 02509 hanguptone_indicate(p); 02510 02511 /*p->state=MISDN_CLEANING;*/ 02512 if (bc->need_disconnect) 02513 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02514 break; 02515 case MISDN_CONNECTED: 02516 case MISDN_PRECONNECTED: 02517 /* Alerting or Disconect */ 02518 if (p->bc->nt) { 02519 start_bc_tones(p); 02520 hanguptone_indicate(p); 02521 p->bc->progress_indicator=8; 02522 } 02523 if (bc->need_disconnect) 02524 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02525 02526 /*p->state=MISDN_CLEANING;*/ 02527 break; 02528 case MISDN_DISCONNECTED: 02529 misdn_lib_send_event( bc, EVENT_RELEASE); 02530 p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ 02531 break; 02532 02533 case MISDN_RELEASED: 02534 case MISDN_CLEANING: 02535 p->state=MISDN_CLEANING; 02536 break; 02537 02538 case MISDN_BUSY: 02539 break; 02540 02541 case MISDN_HOLD_DISCONNECT: 02542 /* need to send release here */ 02543 chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause); 02544 chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause); 02545 02546 bc->out_cause=-1; 02547 misdn_lib_send_event(bc,EVENT_RELEASE); 02548 p->state=MISDN_CLEANING; 02549 break; 02550 default: 02551 if (bc->nt) { 02552 bc->out_cause=-1; 02553 misdn_lib_send_event(bc, EVENT_RELEASE); 02554 p->state=MISDN_CLEANING; 02555 } else { 02556 if (bc->need_disconnect) 02557 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02558 } 02559 } 02560 02561 p->state=MISDN_CLEANING; 02562 02563 } 02564 02565 02566 chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p)); 02567 02568 return 0; 02569 }
static int misdn_indication | ( | struct ast_channel * | ast, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 2271 of file chan_misdn.c.
References 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_RINGING, 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(), 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().
02272 { 02273 struct chan_list *p; 02274 02275 02276 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) { 02277 ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n"); 02278 return -1; 02279 } 02280 02281 if (!p->bc ) { 02282 chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten); 02283 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 02284 return -1; 02285 } 02286 02287 chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten); 02288 02289 switch (cond) { 02290 case AST_CONTROL_BUSY: 02291 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n",p->bc?p->bc->pid:-1); 02292 ast_setstate(ast,AST_STATE_BUSY); 02293 02294 p->bc->out_cause=17; 02295 if (p->state != MISDN_CONNECTED) { 02296 start_bc_tones(p); 02297 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02298 } else { 02299 chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name); 02300 } 02301 return -1; 02302 break; 02303 case AST_CONTROL_RING: 02304 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n",p->bc?p->bc->pid:-1); 02305 return -1; 02306 break; 02307 02308 case AST_CONTROL_RINGING: 02309 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1); 02310 switch (p->state) { 02311 case MISDN_ALERTING: 02312 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1); 02313 break; 02314 case MISDN_CONNECTED: 02315 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); 02316 return -1; 02317 break; 02318 default: 02319 p->state=MISDN_ALERTING; 02320 chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1); 02321 misdn_lib_send_event( p->bc, EVENT_ALERTING); 02322 02323 if (p->other_ch && p->other_ch->bc) { 02324 if (misdn_inband_avail(p->other_ch->bc)) { 02325 chan_misdn_log(2,p->bc->port, " --> other End is mISDN and has inband info available\n"); 02326 break; 02327 } 02328 02329 if (!p->other_ch->bc->nt) { 02330 chan_misdn_log(2,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n"); 02331 break; 02332 } 02333 } 02334 02335 chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1); 02336 ast_setstate(ast,AST_STATE_RINGING); 02337 02338 if ( !p->bc->nt && (p->originator==ORG_MISDN) && !p->incoming_early_audio ) 02339 chan_misdn_log(2,p->bc->port, " --> incoming_early_audio off\n"); 02340 else 02341 return -1; 02342 } 02343 break; 02344 case AST_CONTROL_ANSWER: 02345 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1); 02346 start_bc_tones(p); 02347 break; 02348 case AST_CONTROL_TAKEOFFHOOK: 02349 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1); 02350 return -1; 02351 break; 02352 case AST_CONTROL_OFFHOOK: 02353 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1); 02354 return -1; 02355 break; 02356 case AST_CONTROL_FLASH: 02357 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1); 02358 break; 02359 case AST_CONTROL_PROGRESS: 02360 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1); 02361 misdn_lib_send_event( p->bc, EVENT_PROGRESS); 02362 break; 02363 case AST_CONTROL_PROCEEDING: 02364 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1); 02365 misdn_lib_send_event( p->bc, EVENT_PROCEEDING); 02366 break; 02367 case AST_CONTROL_CONGESTION: 02368 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1); 02369 02370 p->bc->out_cause=42; 02371 start_bc_tones(p); 02372 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 02373 02374 if (p->bc->nt) { 02375 hanguptone_indicate(p); 02376 } 02377 break; 02378 case -1 : 02379 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1); 02380 02381 stop_indicate(p); 02382 02383 if (p->state == MISDN_CONNECTED) 02384 start_bc_tones(p); 02385 02386 break; 02387 02388 case AST_CONTROL_HOLD: 02389 ast_moh_start(ast,data,ast->musicclass); 02390 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1); 02391 break; 02392 case AST_CONTROL_UNHOLD: 02393 ast_moh_stop(ast); 02394 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1); 02395 break; 02396 default: 02397 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1); 02398 } 02399 02400 return 0; 02401 }
void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
Definition at line 5426 of file chan_misdn.c.
References ast_mutex_destroy(), free, misdn_jb::mutexjb, and misdn_jb::samples.
Referenced by config_jitterbuffer(), and release_chan().
05427 { 05428 ast_mutex_destroy(&jb->mutexjb); 05429 05430 free(jb->samples); 05431 free(jb); 05432 }
int misdn_jb_empty | ( | struct misdn_jb * | jb, | |
char * | data, | |||
int | len | |||
) |
Definition at line 5498 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().
05499 { 05500 int i, wp, rp, read=0; 05501 05502 ast_mutex_lock (&jb->mutexjb); 05503 05504 rp=jb->rp; 05505 wp=jb->wp; 05506 05507 if(jb->state_empty) 05508 { 05509 for(i=0; i<len; i++) 05510 { 05511 if(wp==rp) 05512 { 05513 jb->rp=rp; 05514 jb->state_empty=0; 05515 05516 ast_mutex_unlock (&jb->mutexjb); 05517 05518 return read; 05519 } 05520 else 05521 { 05522 if(jb->ok[rp]==1) 05523 { 05524 data[i]=jb->samples[rp]; 05525 jb->ok[rp]=0; 05526 rp=(rp!=jb->size-1 ? rp+1 : 0); 05527 read+=1; 05528 } 05529 } 05530 } 05531 05532 if(wp >= rp) 05533 jb->state_buffer=wp-rp; 05534 else 05535 jb->state_buffer= jb->size-rp+wp; 05536 chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 05537 05538 jb->rp=rp; 05539 } 05540 else 05541 chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb); 05542 05543 ast_mutex_unlock (&jb->mutexjb); 05544 05545 return read; 05546 }
int misdn_jb_fill | ( | struct misdn_jb * | jb, | |
const char * | data, | |||
int | len | |||
) |
Definition at line 5436 of file chan_misdn.c.
References ast_mutex_lock(), ast_mutex_unlock(), misdn_jb::bytes_wrote, chan_misdn_log(), misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_buffer, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.
Referenced by misdn_write().
05437 { 05438 int i, j, rp, wp; 05439 05440 if (!jb || ! data) return 0; 05441 05442 ast_mutex_lock (&jb->mutexjb); 05443 05444 wp=jb->wp; 05445 rp=jb->rp; 05446 05447 for(i=0; i<len; i++) 05448 { 05449 jb->samples[wp]=data[i]; 05450 jb->ok[wp]=1; 05451 wp = (wp!=jb->size-1 ? wp+1 : 0); 05452 05453 if(wp==jb->rp) 05454 jb->state_full=1; 05455 } 05456 05457 if(wp>=rp) 05458 jb->state_buffer=wp-rp; 05459 else 05460 jb->state_buffer= jb->size-rp+wp; 05461 chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 05462 05463 if(jb->state_full) 05464 { 05465 jb->wp=wp; 05466 05467 rp=wp; 05468 for(j=0; j<jb->upper_threshold; j++) 05469 rp = (rp!=0 ? rp-1 : jb->size-1); 05470 jb->rp=rp; 05471 jb->state_full=0; 05472 jb->state_empty=1; 05473 05474 ast_mutex_unlock (&jb->mutexjb); 05475 05476 return -1; 05477 } 05478 05479 if(!jb->state_empty) 05480 { 05481 jb->bytes_wrote+=len; 05482 if(jb->bytes_wrote>=jb->upper_threshold) 05483 { 05484 jb->state_empty=1; 05485 jb->bytes_wrote=0; 05486 } 05487 } 05488 jb->wp=wp; 05489 05490 ast_mutex_unlock (&jb->mutexjb); 05491 05492 return 0; 05493 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) | [read] |
Definition at line 5392 of file chan_misdn.c.
References ast_mutex_init(), misdn_jb::bytes_wrote, chan_misdn_log(), malloc, misdn_jb::mutexjb, misdn_jb::ok, misdn_jb::rp, misdn_jb::samples, misdn_jb::size, misdn_jb::state_empty, misdn_jb::state_full, misdn_jb::upper_threshold, and misdn_jb::wp.
Referenced by config_jitterbuffer().
05393 { 05394 int i; 05395 struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb)); 05396 jb->size = size; 05397 jb->upper_threshold = upper_threshold; 05398 jb->wp = 0; 05399 jb->rp = 0; 05400 jb->state_full = 0; 05401 jb->state_empty = 0; 05402 jb->bytes_wrote = 0; 05403 jb->samples = (char *)malloc(size*sizeof(char)); 05404 05405 if (!jb->samples) { 05406 chan_misdn_log(-1,0,"No free Mem for jb->samples\n"); 05407 return NULL; 05408 } 05409 05410 jb->ok = (char *)malloc(size*sizeof(char)); 05411 05412 if (!jb->ok) { 05413 chan_misdn_log(-1,0,"No free Mem for jb->ok\n"); 05414 return NULL; 05415 } 05416 05417 for(i=0; i<size; i++) 05418 jb->ok[i]=0; 05419 05420 ast_mutex_init(&jb->mutexjb); 05421 05422 return jb; 05423 }
static int misdn_l1_task | ( | void * | data | ) | [static] |
Definition at line 643 of file chan_misdn.c.
References chan_misdn_log(), and misdn_lib_isdn_l1watcher().
Referenced by load_module().
00644 { 00645 misdn_lib_isdn_l1watcher(*(int *)data); 00646 chan_misdn_log(5, *(int *)data, "L1watcher timeout\n"); 00647 return 1; 00648 }
static struct ast_channel * misdn_new | ( | struct chan_list * | cl, | |
int | state, | |||
char * | exten, | |||
char * | callerid, | |||
int | format, | |||
int | port, | |||
int | c | |||
) | [static, read] |
Definition at line 3281 of file chan_misdn.c.
References ast_callerid_parse(), ast_channel_alloc(), AST_STATE_RING, ast_strdup, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, cid_name, ast_callerid::cid_num, cid_num, ast_channel::exten, ast_channel::fds, misdn_cfg_get(), misdn_cfg_get_next_port(), MISDN_GEN_BRIDGING, misdn_lib_port_is_pri(), ast_channel::nativeformats, chan_list::pipe, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by cb_events(), and misdn_request().
03282 { 03283 struct ast_channel *tmp; 03284 char *cid_name = 0, *cid_num = 0; 03285 int chan_offset=0; 03286 int tmp_port = misdn_cfg_get_next_port(0); 03287 03288 for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) { 03289 if (tmp_port == port) break; 03290 chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2; 03291 } 03292 if (c<0) c=0; 03293 03294 03295 if (callerid) 03296 ast_callerid_parse(callerid, &cid_name, &cid_num); 03297 03298 tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); 03299 03300 if (tmp) { 03301 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid); 03302 03303 tmp->nativeformats = prefformat; 03304 03305 tmp->readformat = format; 03306 tmp->rawreadformat = format; 03307 tmp->writeformat = format; 03308 tmp->rawwriteformat = format; 03309 03310 tmp->tech_pvt = chlist; 03311 03312 int bridging; 03313 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 03314 03315 if (bridging) 03316 tmp->tech = &misdn_tech; 03317 else 03318 tmp->tech = &misdn_tech_wo_bridge; 03319 03320 tmp->writeformat = format; 03321 tmp->readformat = format; 03322 tmp->priority=1; 03323 03324 if (exten) 03325 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 03326 else 03327 chan_misdn_log(1,0,"misdn_new: no exten given.\n"); 03328 03329 if (callerid) { 03330 char *cid_name, *cid_num; 03331 03332 ast_callerid_parse(callerid, &cid_name, &cid_num); 03333 /* Don't use ast_set_callerid() here because it will 03334 * generate a needless NewCallerID event */ 03335 tmp->cid.cid_num = ast_strdup(cid_num); 03336 tmp->cid.cid_ani = ast_strdup(cid_num); 03337 tmp->cid.cid_name = ast_strdup(cid_name); 03338 } 03339 03340 { 03341 if (pipe(chlist->pipe)<0) 03342 perror("Pipe failed\n"); 03343 03344 tmp->fds[0]=chlist->pipe[0]; 03345 03346 } 03347 03348 if (state == AST_STATE_RING) 03349 tmp->rings = 1; 03350 else 03351 tmp->rings = 0; 03352 03353 03354 } else { 03355 chan_misdn_log(-1,0,"Unable to allocate channel structure\n"); 03356 } 03357 03358 return tmp; 03359 }
static int misdn_overlap_dial_task | ( | void * | data | ) | [static] |
Definition at line 650 of file chan_misdn.c.
References chan_list::ast, ast_exists_extension(), ast_mutex_lock(), ast_mutex_unlock(), chan_list::bc, chan_misdn_log(), chan_list::context, misdn_bchannel::dad, EVENT_RELEASE, EVENT_RELEASE_COMPLETE, hanguptone_indicate(), MISDN_DIALING, misdn_lib_send_event(), MISDN_WAITING4DIGS, misdn_bchannel::nt, misdn_bchannel::oad, 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().
00651 { 00652 struct timeval tv_end, tv_now; 00653 int diff; 00654 struct chan_list *ch = (struct chan_list *)data; 00655 00656 chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state); 00657 00658 if (ch->state != MISDN_WAITING4DIGS) { 00659 ch->overlap_dial_task = -1; 00660 return 0; 00661 } 00662 00663 ast_mutex_lock(&ch->overlap_tv_lock); 00664 tv_end = ch->overlap_tv; 00665 ast_mutex_unlock(&ch->overlap_tv_lock); 00666 00667 tv_end.tv_sec += ch->overlap_dial; 00668 tv_now = ast_tvnow(); 00669 00670 diff = ast_tvdiff_ms(tv_end, tv_now); 00671 00672 if (diff <= 100) { 00673 /* if we are 100ms near the timeout, we are satisfied.. */ 00674 stop_indicate(ch); 00675 if (ast_exists_extension(ch->ast, ch->context, ch->bc->dad, 1, ch->bc->oad)) { 00676 ch->state=MISDN_DIALING; 00677 if (pbx_start_chan(ch) < 0) { 00678 chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n"); 00679 goto misdn_overlap_dial_task_disconnect; 00680 } 00681 } else { 00682 misdn_overlap_dial_task_disconnect: 00683 hanguptone_indicate(ch); 00684 if (ch->bc->nt) 00685 misdn_lib_send_event(ch->bc, EVENT_RELEASE_COMPLETE ); 00686 else 00687 misdn_lib_send_event(ch->bc, EVENT_RELEASE); 00688 } 00689 ch->overlap_dial_task = -1; 00690 return 0; 00691 } else 00692 return diff; 00693 }
static int misdn_port_block | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 797 of file chan_misdn.c.
References misdn_lib_port_block(), and RESULT_SHOWUSAGE.
00798 { 00799 int port; 00800 00801 if (argc != 4) 00802 return RESULT_SHOWUSAGE; 00803 00804 port = atoi(argv[3]); 00805 00806 misdn_lib_port_block(port); 00807 00808 return 0; 00809 }
static int misdn_port_down | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 868 of file chan_misdn.c.
References misdn_lib_get_port_down(), and RESULT_SHOWUSAGE.
00869 { 00870 int port; 00871 00872 if (argc != 4) 00873 return RESULT_SHOWUSAGE; 00874 00875 port = atoi(argv[3]); 00876 00877 misdn_lib_get_port_down(port); 00878 00879 return 0; 00880 }
static int misdn_port_unblock | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 811 of file chan_misdn.c.
References misdn_lib_port_unblock(), and RESULT_SHOWUSAGE.
00812 { 00813 int port; 00814 00815 if (argc != 4) 00816 return RESULT_SHOWUSAGE; 00817 00818 port = atoi(argv[3]); 00819 00820 misdn_lib_port_unblock(port); 00821 00822 return 0; 00823 }
static int misdn_port_up | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 854 of file chan_misdn.c.
References misdn_lib_get_port_up(), and RESULT_SHOWUSAGE.
00855 { 00856 int port; 00857 00858 if (argc != 4) 00859 return RESULT_SHOWUSAGE; 00860 00861 port = atoi(argv[3]); 00862 00863 misdn_lib_get_port_up(port); 00864 00865 return 0; 00866 }
static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | [static, read] |
Definition at line 2642 of file chan_misdn.c.
References chan_list::ast_dsp, AST_FORMAT_ALAW, AST_FRAME_VOICE, chan_list::ast_rd_buf, chan_list::bc, chan_misdn_log(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, 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.
02643 { 02644 struct chan_list *tmp; 02645 int len; 02646 02647 if (!ast) { 02648 chan_misdn_log(1,0,"misdn_read called without ast\n"); 02649 return NULL; 02650 } 02651 if (!(tmp=MISDN_ASTERISK_TECH_PVT(ast))) { 02652 chan_misdn_log(1,0,"misdn_read called without ast->pvt\n"); 02653 return NULL; 02654 } 02655 02656 if (!tmp->bc && !(tmp->state==MISDN_HOLDED)) { 02657 chan_misdn_log(1,0,"misdn_read called without bc\n"); 02658 return NULL; 02659 } 02660 02661 len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf)); 02662 02663 if (len<=0) { 02664 /* we hangup here, since our pipe is closed */ 02665 chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n"); 02666 return NULL; 02667 } 02668 02669 tmp->frame.frametype = AST_FRAME_VOICE; 02670 tmp->frame.subclass = AST_FORMAT_ALAW; 02671 tmp->frame.datalen = len; 02672 tmp->frame.samples = len; 02673 tmp->frame.mallocd = 0; 02674 tmp->frame.offset = 0; 02675 tmp->frame.delivery= ast_tv(0,0) ; 02676 tmp->frame.src = NULL; 02677 tmp->frame.data = tmp->ast_rd_buf; 02678 02679 if (tmp->faxdetect && !tmp->faxhandled) { 02680 if (tmp->faxdetect_timeout) { 02681 if (ast_tvzero(tmp->faxdetect_tv)) { 02682 tmp->faxdetect_tv = ast_tvnow(); 02683 chan_misdn_log(2,tmp->bc->port,"faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout); 02684 return process_ast_dsp(tmp, &tmp->frame); 02685 } else { 02686 struct timeval tv_now = ast_tvnow(); 02687 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv); 02688 if (diff <= (tmp->faxdetect_timeout * 1000)) { 02689 chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ...\n"); 02690 return process_ast_dsp(tmp, &tmp->frame); 02691 } else { 02692 chan_misdn_log(2,tmp->bc->port,"faxdetect: stopping detection (time ran out) ...\n"); 02693 tmp->faxdetect = 0; 02694 return &tmp->frame; 02695 } 02696 } 02697 } else { 02698 chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ... (no timeout)\n"); 02699 return process_ast_dsp(tmp, &tmp->frame); 02700 } 02701 } else { 02702 if (tmp->ast_dsp) 02703 return process_ast_dsp(tmp, &tmp->frame); 02704 else 02705 return &tmp->frame; 02706 } 02707 }
static int misdn_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1053 of file chan_misdn.c.
References ast_cli(), and reload_config().
01054 { 01055 ast_cli(fd, "Reloading mISDN Config\n"); 01056 reload_config(); 01057 return 0; 01058 }
static struct ast_channel* misdn_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 3025 of file chan_misdn.c.
References chan_list::ast, ast_log(), AST_STATE_RESERVED, ast_strlen_zero(), chan_list::bc, BUFFERSIZE, chan_misdn_log(), misdn_bchannel::channel, robin_list::channel, cl_queue_chan(), misdn_bchannel::dec, ext, get_robin_position(), group, init_chan_list(), LOG_ERROR, LOG_WARNING, METHOD_ROUND_ROBIN, METHOD_STANDARD_DEC, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), MISDN_CFG_GROUPNAME, misdn_cfg_is_group_method(), MISDN_CFG_PMP_L1_CHECK, misdn_lib_get_free_bc(), misdn_lib_get_maxchans(), misdn_lib_port_up(), misdn_new(), chan_list::need_hangup, ORG_AST, misdn_bchannel::port, robin_list::port, and read_config().
03027 { 03028 struct ast_channel *tmp = NULL; 03029 char group[BUFFERSIZE+1]=""; 03030 char buf[128]; 03031 char buf2[128], *ext=NULL, *port_str; 03032 char *tokb=NULL, *p=NULL; 03033 int channel=0, port=0; 03034 struct misdn_bchannel *newbc = NULL; 03035 int dec=0; 03036 03037 struct chan_list *cl=init_chan_list(ORG_AST); 03038 03039 sprintf(buf,"%s/%s",misdn_type,(char*)data); 03040 ast_copy_string(buf2,data, 128); 03041 03042 port_str=strtok_r(buf2,"/", &tokb); 03043 03044 ext=strtok_r(NULL,"/", &tokb); 03045 03046 if (port_str) { 03047 if (port_str[0]=='g' && port_str[1]==':' ) { 03048 /* We make a group call lets checkout which ports are in my group */ 03049 port_str += 2; 03050 strncpy(group, port_str, BUFFERSIZE); 03051 group[127] = 0; 03052 chan_misdn_log(2, 0, " --> Group Call group: %s\n",group); 03053 } 03054 else if ((p = strchr(port_str, ':'))) { 03055 /* we have a preselected channel */ 03056 *p = 0; 03057 channel = atoi(++p); 03058 port = atoi(port_str); 03059 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 03060 } 03061 else { 03062 port = atoi(port_str); 03063 } 03064 } else { 03065 ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext); 03066 return NULL; 03067 } 03068 03069 if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) { 03070 chan_misdn_log(4, port, " --> STARTING STANDARDDEC...\n"); 03071 dec=1; 03072 } 03073 03074 if (!ast_strlen_zero(group)) { 03075 03076 char cfg_group[BUFFERSIZE+1]; 03077 struct robin_list *rr = NULL; 03078 03079 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 03080 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n"); 03081 rr = get_robin_position(group); 03082 } 03083 03084 03085 if (rr) { 03086 int robin_channel = rr->channel; 03087 int port_start; 03088 int next_chan = 1; 03089 03090 do { 03091 port_start = 0; 03092 for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start; 03093 port = misdn_cfg_get_next_port_spin(port)) { 03094 03095 if (!port_start) 03096 port_start = port; 03097 03098 if (port >= port_start) 03099 next_chan = 1; 03100 03101 if (port <= port_start && next_chan) { 03102 int maxbchans=misdn_lib_get_maxchans(port); 03103 if (++robin_channel >= maxbchans) { 03104 robin_channel = 1; 03105 } 03106 next_chan = 0; 03107 } 03108 03109 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03110 03111 if (!strcasecmp(cfg_group, group)) { 03112 int port_up; 03113 int check; 03114 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03115 port_up = misdn_lib_port_up(port, check); 03116 03117 if (check && !port_up) 03118 chan_misdn_log(1,port,"L1 is not Up on this Port\n"); 03119 03120 if (check && port_up<0) { 03121 ast_log(LOG_WARNING,"This port (%d) is blocked\n", port); 03122 } 03123 03124 03125 if ( port_up>0 ) { 03126 newbc = misdn_lib_get_free_bc(port, robin_channel,0, 0); 03127 if (newbc) { 03128 chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 03129 if (port_up) 03130 chan_misdn_log(4, port, "portup:%d\n", port_up); 03131 rr->port = newbc->port; 03132 rr->channel = newbc->channel; 03133 break; 03134 } 03135 } 03136 } 03137 } 03138 } while (!newbc && robin_channel != rr->channel); 03139 03140 } else { 03141 for (port=misdn_cfg_get_next_port(0); port > 0; 03142 port=misdn_cfg_get_next_port(port)) { 03143 03144 misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 03145 03146 chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port); 03147 if (!strcasecmp(cfg_group, group)) { 03148 int port_up; 03149 int check; 03150 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 03151 port_up = misdn_lib_port_up(port, check); 03152 03153 chan_misdn_log(4, port, "portup:%d\n", port_up); 03154 03155 if ( port_up>0 ) { 03156 newbc = misdn_lib_get_free_bc(port, 0, 0, dec); 03157 if (newbc) 03158 break; 03159 } 03160 } 03161 } 03162 } 03163 03164 /* Group dial failed ?*/ 03165 if (!newbc) { 03166 ast_log(LOG_WARNING, 03167 "Could not Dial out on group '%s'.\n" 03168 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 03169 "\tOr there was no free channel on none of the ports\n\n" 03170 , group); 03171 return NULL; 03172 } 03173 } else { /* 'Normal' Port dial * Port dial */ 03174 if (channel) 03175 chan_misdn_log(1, port," --> preselected_channel: %d\n",channel); 03176 newbc = misdn_lib_get_free_bc(port, channel, 0, dec); 03177 03178 if (!newbc) { 03179 ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n",port,ext); 03180 return NULL; 03181 } 03182 } 03183 03184 03185 /* create ast_channel and link all the objects together */ 03186 cl->bc=newbc; 03187 03188 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel); 03189 if (!tmp) { 03190 ast_log(LOG_ERROR,"Could not create Asterisk object\n"); 03191 return NULL; 03192 } 03193 03194 cl->ast=tmp; 03195 03196 /* register chan in local list */ 03197 cl_queue_chan(&cl_te, cl) ; 03198 03199 /* fill in the config into the objects */ 03200 read_config(cl, ORG_AST); 03201 03202 /* important */ 03203 cl->need_hangup=0; 03204 03205 return tmp; 03206 }
static int misdn_restart_pid | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 840 of file chan_misdn.c.
References misdn_lib_pid_restart(), and RESULT_SHOWUSAGE.
00841 { 00842 int pid; 00843 00844 if (argc != 4) 00845 return RESULT_SHOWUSAGE; 00846 00847 pid = atoi(argv[3]); 00848 00849 misdn_lib_pid_restart(pid); 00850 00851 return 0; 00852 }
static int misdn_restart_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 826 of file chan_misdn.c.
References misdn_lib_port_restart(), and RESULT_SHOWUSAGE.
00827 { 00828 int port; 00829 00830 if (argc != 4) 00831 return RESULT_SHOWUSAGE; 00832 00833 port = atoi(argv[3]); 00834 00835 misdn_lib_port_restart(port); 00836 00837 return 0; 00838 }
static int misdn_send_cd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1240 of file chan_misdn.c.
References ast_cli(), chan_list::bc, EVENT_FACILITY, misdn_bchannel::fac_out, get_chan_by_ast_name(), misdn_lib_send_event(), and RESULT_SHOWUSAGE.
01241 { 01242 char *channame; 01243 char *nr; 01244 01245 if (argc != 5) 01246 return RESULT_SHOWUSAGE; 01247 01248 channame = argv[3]; 01249 nr = argv[4]; 01250 01251 ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame); 01252 01253 { 01254 struct chan_list *tmp=get_chan_by_ast_name(channame); 01255 01256 if (!tmp) { 01257 ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame); 01258 return 0; 01259 } else { 01260 if (strlen(nr) >= 15) { 01261 ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame); 01262 return 0; 01263 } 01264 tmp->bc->fac_out.Function = Fac_CD; 01265 strncpy((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber)); 01266 misdn_lib_send_event(tmp->bc, EVENT_FACILITY); 01267 } 01268 } 01269 01270 return 0; 01271 }
static int misdn_send_digit | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1292 of file chan_misdn.c.
References chan_list::ast, ast_cli(), ast_dtmf_stream(), get_chan_by_ast_name(), RESULT_SHOWUSAGE, and send_digit_to_chan().
01293 { 01294 char *channame; 01295 char *msg; 01296 01297 if (argc != 5) 01298 return RESULT_SHOWUSAGE; 01299 01300 channame = argv[3]; 01301 msg = argv[4]; 01302 01303 ast_cli(fd, "Sending %s to %s\n",msg, channame); 01304 01305 { 01306 struct chan_list *tmp=get_chan_by_ast_name(channame); 01307 01308 if (!tmp) { 01309 ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame); 01310 return 0; 01311 } else { 01312 #if 1 01313 int i; 01314 int msglen = strlen(msg); 01315 for (i=0; i<msglen; i++) { 01316 ast_cli(fd, "Sending: %c\n",msg[i]); 01317 send_digit_to_chan(tmp, msg[i]); 01318 /* res = ast_safe_sleep(tmp->ast, 250); */ 01319 usleep(250000); 01320 /* res = ast_waitfor(tmp->ast,100); */ 01321 } 01322 #else 01323 int res; 01324 res = ast_dtmf_stream(tmp->ast,NULL,msg,250); 01325 #endif 01326 } 01327 } 01328 01329 return 0; 01330 }
static int misdn_send_display | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1369 of file chan_misdn.c.
References ast_cli(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, get_chan_by_ast_name(), misdn_lib_send_event(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01370 { 01371 char *channame; 01372 char *msg; 01373 01374 if (argc != 5) 01375 return RESULT_SHOWUSAGE; 01376 01377 channame = argv[3]; 01378 msg = argv[4]; 01379 01380 ast_cli(fd, "Sending %s to %s\n",msg, channame); 01381 { 01382 struct chan_list *tmp; 01383 tmp=get_chan_by_ast_name(channame); 01384 01385 if (tmp && tmp->bc) { 01386 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); 01387 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 01388 } else { 01389 ast_cli(fd,"No such channel %s\n",channame); 01390 return RESULT_FAILURE; 01391 } 01392 } 01393 01394 return RESULT_SUCCESS ; 01395 }
static int misdn_send_restart | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1273 of file chan_misdn.c.
References misdn_lib_send_restart(), and RESULT_SHOWUSAGE.
01274 { 01275 int port; 01276 int channel; 01277 01278 if ( (argc < 4) || (argc > 5) ) 01279 return RESULT_SHOWUSAGE; 01280 01281 port = atoi(argv[3]); 01282 01283 if (argc==5) { 01284 channel = atoi(argv[4]); 01285 misdn_lib_send_restart(port, channel); 01286 } else 01287 misdn_lib_send_restart(port, -1 ); 01288 01289 return 0; 01290 }
static int misdn_send_text | ( | struct ast_channel * | chan, | |
const char * | text | |||
) | [static] |
Definition at line 3209 of file chan_misdn.c.
References ast_log(), chan_list::bc, misdn_bchannel::display, EVENT_INFORMATION, LOG_WARNING, misdn_lib_send_event(), and ast_channel::tech_pvt.
03210 { 03211 struct chan_list *tmp=chan->tech_pvt; 03212 03213 if (tmp && tmp->bc) { 03214 ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display)); 03215 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 03216 } else { 03217 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 03218 return -1; 03219 } 03220 03221 return 0; 03222 }
static int misdn_set_crypt_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 789 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00790 { 00791 if (argc != 5) return RESULT_SHOWUSAGE; 00792 00793 return 0; 00794 }
static int misdn_set_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 732 of file chan_misdn.c.
References ast_cli(), and RESULT_SHOWUSAGE.
00733 { 00734 if (argc != 4 && argc != 5 && argc != 6 && argc != 7) 00735 return RESULT_SHOWUSAGE; 00736 00737 int level = atoi(argv[3]); 00738 00739 switch (argc) { 00740 case 4: 00741 case 5: { 00742 int only = 0; 00743 if (argc == 5) { 00744 if (strncasecmp(argv[4], "only", strlen(argv[4]))) 00745 return RESULT_SHOWUSAGE; 00746 else 00747 only = 1; 00748 } 00749 int i; 00750 for (i=0; i<=max_ports; i++) { 00751 misdn_debug[i] = level; 00752 misdn_debug_only[i] = only; 00753 } 00754 ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":""); 00755 } 00756 break; 00757 case 6: 00758 case 7: { 00759 if (strncasecmp(argv[4], "port", strlen(argv[4]))) 00760 return RESULT_SHOWUSAGE; 00761 int port = atoi(argv[5]); 00762 if (port <= 0 || port > max_ports) { 00763 switch (max_ports) { 00764 case 0: 00765 ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n"); 00766 break; 00767 case 1: 00768 ast_cli(fd, "port number not valid! only port 1 is availble.\n"); 00769 break; 00770 default: 00771 ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports); 00772 } 00773 return 0; 00774 } 00775 if (argc == 7) { 00776 if (strncasecmp(argv[6], "only", strlen(argv[6]))) 00777 return RESULT_SHOWUSAGE; 00778 else 00779 misdn_debug_only[port] = 1; 00780 } else 00781 misdn_debug_only[port] = 0; 00782 misdn_debug[port] = level; 00783 ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port); 00784 } 00785 } 00786 return 0; 00787 }
static int misdn_set_opt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 5170 of file chan_misdn.c.
References chan_list::ast_dsp, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, misdn_bchannel::capability, chan_misdn_log(), config_jitterbuffer(), misdn_bchannel::crypt_key, misdn_bchannel::display, chan_list::dsp, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, misdn_bchannel::ec_deftaps, misdn_bchannel::ec_enable, chan_list::faxdetect, chan_list::faxdetect_timeout, misdn_bchannel::hdlc, INFO_CAPABILITY_DIGITAL_UNRESTRICTED, chan_list::jb_len, chan_list::jb_upper_threshold, key(), keys, 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, misdn_bchannel::port, misdn_bchannel::pres, misdn_bchannel::rxgain, misdn_bchannel::send_dtmf, strsep(), ast_channel::tech, chan_list::trans, misdn_bchannel::txgain, and ast_channel_tech::type.
Referenced by load_module(), and misdn_call().
05171 { 05172 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 05173 char *tok,*tokb; 05174 int keyidx=0; 05175 int rxgain=0; 05176 int txgain=0; 05177 int change_jitter=0; 05178 05179 if (strcasecmp(chan->tech->type,"mISDN")) { 05180 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n"); 05181 return -1; 05182 } 05183 05184 if (ast_strlen_zero((char *)data)) { 05185 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 05186 return -1; 05187 } 05188 05189 for (tok=strtok_r((char*)data, ":",&tokb); 05190 tok; 05191 tok=strtok_r(NULL,":",&tokb) ) { 05192 int neglect=0; 05193 05194 if (tok[0] == '!' ) { 05195 neglect=1; 05196 tok++; 05197 } 05198 05199 switch(tok[0]) { 05200 05201 case 'd' : 05202 ast_copy_string(ch->bc->display,++tok,84); 05203 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display); 05204 break; 05205 05206 case 'n': 05207 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 05208 ch->bc->nodsp=1; 05209 break; 05210 05211 case 'j': 05212 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 05213 tok++; 05214 change_jitter=1; 05215 05216 switch ( tok[0] ) { 05217 case 'b' : 05218 ch->jb_len=atoi(++tok); 05219 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len); 05220 break; 05221 case 't' : 05222 ch->jb_upper_threshold=atoi(++tok); 05223 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold); 05224 break; 05225 05226 case 'n': 05227 ch->bc->nojitter=1; 05228 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 05229 break; 05230 05231 default: 05232 ch->jb_len=4000; 05233 ch->jb_upper_threshold=0; 05234 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len); 05235 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold); 05236 } 05237 05238 break; 05239 05240 case 'v': 05241 tok++; 05242 05243 switch ( tok[0] ) { 05244 case 'r' : 05245 rxgain=atoi(++tok); 05246 if (rxgain<-8) rxgain=-8; 05247 if (rxgain>8) rxgain=8; 05248 ch->bc->rxgain=rxgain; 05249 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain); 05250 break; 05251 case 't': 05252 txgain=atoi(++tok); 05253 if (txgain<-8) txgain=-8; 05254 if (txgain>8) txgain=8; 05255 ch->bc->txgain=txgain; 05256 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain); 05257 break; 05258 } 05259 break; 05260 05261 case 'c': 05262 keyidx=atoi(++tok); 05263 05264 char keys[4096]; 05265 char *key=NULL, *tmp; 05266 int i; 05267 misdn_cfg_get( 0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys)); 05268 05269 tmp=keys; 05270 05271 for (i=0; i<keyidx; i++) { 05272 key=strsep(&tmp,","); 05273 } 05274 05275 if (key) { 05276 ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key)); 05277 } 05278 05279 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",ch->bc->crypt_key); 05280 break; 05281 05282 case 'e': 05283 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 05284 05285 if (neglect) { 05286 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 05287 #ifdef MISDN_1_2 05288 *ch->bc->pipeline=0; 05289 #else 05290 ch->bc->ec_enable=0; 05291 #endif 05292 } else { 05293 #ifdef MISDN_1_2 05294 update_pipeline_config(ch->bc); 05295 #else 05296 ch->bc->ec_enable=1; 05297 ch->bc->orig=ch->originator; 05298 tok++; 05299 if (*tok) { 05300 ch->bc->ec_deftaps=atoi(tok); 05301 } 05302 #endif 05303 } 05304 05305 break; 05306 05307 case 'h': 05308 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 05309 05310 if (strlen(tok) > 1 && tok[1]=='1') { 05311 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 05312 if (!ch->bc->hdlc) { 05313 ch->bc->hdlc=1; 05314 } 05315 } 05316 ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 05317 break; 05318 05319 case 's': 05320 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 05321 ch->bc->send_dtmf=1; 05322 break; 05323 05324 case 'f': 05325 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 05326 ch->faxdetect=1; 05327 misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 05328 break; 05329 05330 case 'a': 05331 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 05332 ch->ast_dsp=1; 05333 break; 05334 05335 case 'p': 05336 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]); 05337 /* CRICH: callingpres!!! */ 05338 if (strstr(tok,"allowed") ) { 05339 ch->bc->pres=0; 05340 } else if (strstr(tok,"not_screened")) { 05341 ch->bc->pres=1; 05342 } 05343 05344 05345 break; 05346 05347 05348 default: 05349 break; 05350 } 05351 } 05352 05353 if (change_jitter) 05354 config_jitterbuffer(ch); 05355 05356 05357 if (ch->faxdetect || ch->ast_dsp) { 05358 if (!ch->dsp) ch->dsp = ast_dsp_new(); 05359 if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT); 05360 if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 05361 } 05362 05363 if (ch->ast_dsp) { 05364 chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 05365 ch->bc->nodsp=1; 05366 ch->bc->nojitter=1; 05367 } 05368 05369 return 0; 05370 }
static int misdn_set_tics | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1177 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
01178 { 01179 if (argc != 4) 01180 return RESULT_SHOWUSAGE; 01181 01182 MAXTICS=atoi(argv[3]); 01183 01184 return 0; 01185 }
static int misdn_show_cl | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1151 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, chan_list::next, print_bc_info(), and RESULT_SHOWUSAGE.
01152 { 01153 struct chan_list *help=cl_te; 01154 01155 if (argc != 4) 01156 return RESULT_SHOWUSAGE; 01157 01158 for (;help; help=help->next) { 01159 struct misdn_bchannel *bc=help->bc; 01160 struct ast_channel *ast=help->ast; 01161 01162 if (bc && ast) { 01163 if (!strcasecmp(ast->name,argv[3])) { 01164 print_bc_info(fd, help, bc); 01165 break; 01166 } 01167 } 01168 } 01169 01170 01171 return 0; 01172 }
static int misdn_show_cls | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1115 of file chan_misdn.c.
References chan_list::ast, ast_cli(), chan_list::bc, hold_info::channel, ast_channel::cid, ast_callerid::cid_num, ast_channel::exten, chan_list::hold_info, chan_list::l3id, misdn_dump_chanlist(), MISDN_HOLDED, chan_list::next, hold_info::port, print_bc_info(), and chan_list::state.
01116 { 01117 struct chan_list *help=cl_te; 01118 01119 ast_cli(fd,"Chan List: %p\n",cl_te); 01120 01121 for (;help; help=help->next) { 01122 struct misdn_bchannel *bc=help->bc; 01123 struct ast_channel *ast=help->ast; 01124 if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast); 01125 if (bc) { 01126 print_bc_info(fd, help, bc); 01127 } else { 01128 if (help->state == MISDN_HOLDED) { 01129 ast_cli(fd, "ITS A HOLDED BC:\n"); 01130 ast_cli(fd, " --> l3_id: %x\n" 01131 " --> dad:%s oad:%s\n" 01132 " --> hold_port: %d\n" 01133 " --> hold_channel: %d\n" 01134 01135 ,help->l3id 01136 ,ast->exten 01137 ,ast->cid.cid_num 01138 ,help->hold_info.port 01139 ,help->hold_info.channel 01140 ); 01141 } else { 01142 ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num); 01143 } 01144 } 01145 } 01146 01147 misdn_dump_chanlist(); 01148 return 0; 01149 }
static int misdn_show_config | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 905 of file chan_misdn.c.
References ast_cli(), BUFFERSIZE, MISDN_CFG_FIRST, misdn_cfg_get_config_string(), misdn_cfg_get_elem(), misdn_cfg_get_next_port(), misdn_cfg_is_port_valid(), MISDN_CFG_LAST, MISDN_GEN_FIRST, MISDN_GEN_LAST, RESULT_SHOWUSAGE, and show_config_description().
00906 { 00907 char buffer[BUFFERSIZE]; 00908 enum misdn_cfg_elements elem; 00909 int linebreak; 00910 int onlyport = -1; 00911 int ok = 0; 00912 00913 if (argc >= 4) { 00914 if (!strcmp(argv[3], "description")) { 00915 if (argc == 5) { 00916 enum misdn_cfg_elements elem = misdn_cfg_get_elem (argv[4]); 00917 if (elem == MISDN_CFG_FIRST) 00918 ast_cli(fd, "Unknown element: %s\n", argv[4]); 00919 else 00920 show_config_description(fd, elem); 00921 return 0; 00922 } 00923 return RESULT_SHOWUSAGE; 00924 } 00925 if (!strcmp(argv[3], "descriptions")) { 00926 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) { 00927 for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) { 00928 show_config_description(fd, elem); 00929 ast_cli(fd, "\n"); 00930 } 00931 ok = 1; 00932 } 00933 if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) { 00934 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) { 00935 show_config_description(fd, elem); 00936 ast_cli(fd, "\n"); 00937 } 00938 ok = 1; 00939 } 00940 return ok ? 0 : RESULT_SHOWUSAGE; 00941 } 00942 if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) { 00943 ast_cli(fd, "Unknown option: %s\n", argv[3]); 00944 return RESULT_SHOWUSAGE; 00945 } 00946 } 00947 00948 if (argc == 3 || onlyport == 0) { 00949 ast_cli(fd,"Misdn General-Config: \n"); 00950 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) { 00951 misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE); 00952 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00953 } 00954 ast_cli(fd, "\n"); 00955 } 00956 00957 if (onlyport < 0) { 00958 int port = misdn_cfg_get_next_port(0); 00959 for (; port > 0; port = misdn_cfg_get_next_port(port)) { 00960 ast_cli(fd, "\n[PORT %d]\n", port); 00961 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 00962 misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE); 00963 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00964 } 00965 ast_cli(fd, "\n"); 00966 } 00967 } 00968 00969 if (onlyport > 0) { 00970 if (misdn_cfg_is_port_valid(onlyport)) { 00971 ast_cli(fd, "[PORT %d]\n", onlyport); 00972 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 00973 misdn_cfg_get_config_string(onlyport, elem, buffer, BUFFERSIZE); 00974 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00975 } 00976 ast_cli(fd, "\n"); 00977 } else { 00978 ast_cli(fd, "Port %d is not active!\n", onlyport); 00979 } 00980 } 00981 return 0; 00982 }
static int misdn_show_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1221 of file chan_misdn.c.
References ast_cli(), get_show_stack_details(), and RESULT_SHOWUSAGE.
01222 { 01223 int port; 01224 01225 if (argc != 4) 01226 return RESULT_SHOWUSAGE; 01227 01228 port = atoi(argv[3]); 01229 01230 ast_cli(fd, "BEGIN STACK_LIST:\n"); 01231 01232 char buf[128]; 01233 get_show_stack_details(port,buf); 01234 ast_cli(fd," %s Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); 01235 01236 01237 return 0; 01238 }
static int misdn_show_ports_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1204 of file chan_misdn.c.
References ast_cli(), and misdn_cfg_get_next_port().
01205 { 01206 int port; 01207 01208 ast_cli(fd, "Port\tin_calls\tout_calls\n"); 01209 01210 for (port=misdn_cfg_get_next_port(0); port > 0; 01211 port=misdn_cfg_get_next_port(port)) { 01212 ast_cli(fd,"%d\t%d\t\t%d\n",port,misdn_in_calls[port],misdn_out_calls[port]); 01213 } 01214 ast_cli(fd,"\n"); 01215 01216 return 0; 01217 01218 }
static int misdn_show_stacks | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1187 of file chan_misdn.c.
References ast_cli(), get_show_stack_details(), and misdn_cfg_get_next_port().
01188 { 01189 int port; 01190 01191 ast_cli(fd, "BEGIN STACK_LIST:\n"); 01192 01193 for (port=misdn_cfg_get_next_port(0); port > 0; 01194 port=misdn_cfg_get_next_port(port)) { 01195 char buf[128]; 01196 get_show_stack_details(port,buf); 01197 ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); 01198 } 01199 01200 return 0; 01201 }
static int misdn_tasks_add | ( | int | timeout, | |
ast_sched_cb | callback, | |||
void * | data | |||
) | [static] |
Definition at line 628 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by load_module().
00629 { 00630 return _misdn_tasks_add_variable(timeout, callback, data, 0); 00631 }
static int misdn_tasks_add_variable | ( | int | timeout, | |
ast_sched_cb | callback, | |||
void * | data | |||
) | [static] |
Definition at line 633 of file chan_misdn.c.
References _misdn_tasks_add_variable().
Referenced by cb_events().
00634 { 00635 return _misdn_tasks_add_variable(timeout, callback, data, 1); 00636 }
static void misdn_tasks_destroy | ( | void | ) | [static] |
Definition at line 598 of file chan_misdn.c.
References cb_log, chan_misdn_log(), and sched_context_destroy().
Referenced by unload_module().
00599 { 00600 if (misdn_tasks) { 00601 chan_misdn_log(4, 0, "Killing misdn_tasks thread\n"); 00602 if ( pthread_cancel(misdn_tasks_thread) == 0 ) { 00603 cb_log(4, 0, "Joining misdn_tasks thread\n"); 00604 pthread_join(misdn_tasks_thread, NULL); 00605 } 00606 sched_context_destroy(misdn_tasks); 00607 } 00608 }
static void misdn_tasks_init | ( | void | ) | [static] |
Definition at line 579 of file chan_misdn.c.
References chan_misdn_log(), misdn_tasks_thread_func(), pthread_create, and sched_context_create().
Referenced by _misdn_tasks_add_variable().
00580 { 00581 sem_t blocker; 00582 int i = 5; 00583 00584 if (sem_init(&blocker, 0, 0)) { 00585 perror("chan_misdn: Failed to initialize semaphore!"); 00586 exit(1); 00587 } 00588 00589 chan_misdn_log(4, 0, "Starting misdn_tasks thread\n"); 00590 00591 misdn_tasks = sched_context_create(); 00592 pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker); 00593 00594 while (sem_wait(&blocker) && --i); 00595 sem_destroy(&blocker); 00596 }
static void misdn_tasks_remove | ( | int | task_id | ) | [static] |
Definition at line 638 of file chan_misdn.c.
References ast_sched_del().
Referenced by release_chan().
00639 { 00640 ast_sched_del(misdn_tasks, task_id); 00641 }
static void* misdn_tasks_thread_func | ( | void * | data | ) | [static] |
Definition at line 555 of file chan_misdn.c.
References ast_sched_runq(), ast_sched_wait(), chan_misdn_log(), poll(), and sighandler().
Referenced by misdn_tasks_init().
00556 { 00557 int wait; 00558 struct sigaction sa; 00559 00560 sa.sa_handler = sighandler; 00561 sa.sa_flags = SA_NODEFER; 00562 sigemptyset(&sa.sa_mask); 00563 sigaddset(&sa.sa_mask, SIGUSR1); 00564 sigaction(SIGUSR1, &sa, NULL); 00565 00566 sem_post((sem_t *)data); 00567 00568 while (1) { 00569 wait = ast_sched_wait(misdn_tasks); 00570 if (wait < 0) 00571 wait = 8000; 00572 if (poll(NULL, 0, wait) < 0) 00573 chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n"); 00574 ast_sched_runq(misdn_tasks); 00575 } 00576 return NULL; 00577 }
static void misdn_tasks_wakeup | ( | void | ) | [inline, static] |
Definition at line 610 of file chan_misdn.c.
Referenced by _misdn_tasks_add_variable().
00611 { 00612 pthread_kill(misdn_tasks_thread, SIGUSR1); 00613 }
static int misdn_toggle_echocancel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1332 of file chan_misdn.c.
References ast_cli(), chan_list::bc, get_chan_by_ast_name(), manager_ec_disable(), manager_ec_enable(), RESULT_SHOWUSAGE, chan_list::toggle_ec, and update_ec_config().
01333 { 01334 char *channame; 01335 01336 if (argc != 4) 01337 return RESULT_SHOWUSAGE; 01338 01339 channame = argv[3]; 01340 01341 ast_cli(fd, "Toggling EchoCancel on %s\n", channame); 01342 01343 { 01344 struct chan_list *tmp=get_chan_by_ast_name(channame); 01345 01346 if (!tmp) { 01347 ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); 01348 return 0; 01349 } else { 01350 01351 tmp->toggle_ec=tmp->toggle_ec?0:1; 01352 01353 if (tmp->toggle_ec) { 01354 #ifdef MISDN_1_2 01355 update_pipeline_config(tmp->bc); 01356 #else 01357 update_ec_config(tmp->bc); 01358 #endif 01359 manager_ec_enable(tmp->bc); 01360 } else { 01361 manager_ec_disable(tmp->bc); 01362 } 01363 } 01364 } 01365 01366 return 0; 01367 }
static void misdn_transfer_bc | ( | struct chan_list * | tmp_ch, | |
struct chan_list * | holded_chan | |||
) | [static] |
Definition at line 3595 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, and chan_list::state.
Referenced by cb_events().
03596 { 03597 chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name); 03598 03599 tmp_ch->state=MISDN_HOLD_DISCONNECT; 03600 03601 ast_moh_stop(ast_bridged_channel(holded_chan->ast)); 03602 03603 holded_chan->state=MISDN_CONNECTED; 03604 //misdn_lib_transfer(holded_chan->bc); 03605 ast_channel_masquerade(holded_chan->ast, ast_bridged_channel(tmp_ch->ast)); 03606 }
static int misdn_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2710 of file chan_misdn.c.
References misdn_bchannel::active, misdn_bchannel::addr, ast_log(), chan_list::bc, misdn_bchannel::bc_state, BCHAN_ACTIVATED, BCHAN_BRIDGED, misdn_bchannel::capability, cb_log, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::jb, misdn_bchannel::l3_id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_cap_is_speech(), misdn_get_ch_state(), MISDN_HOLDED, misdn_jb_fill(), misdn_lib_tone_generator_start(), misdn_lib_tx2misdn_frm(), misdn_bchannel::nojitter, chan_list::notxtone, misdn_bchannel::port, ast_frame::samples, ast_frame::src, chan_list::state, ast_frame::subclass, and chan_list::ts.
02711 { 02712 struct chan_list *ch; 02713 int i = 0; 02714 02715 if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02716 02717 if (ch->state == MISDN_HOLDED) { 02718 chan_misdn_log(7, 0, "misdn_write: Returning because holded\n"); 02719 return 0; 02720 } 02721 02722 if (!ch->bc ) { 02723 ast_log(LOG_WARNING, "private but no bc\n"); 02724 return -1; 02725 } 02726 02727 if (ch->notxtone) { 02728 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxone\n"); 02729 return 0; 02730 } 02731 02732 02733 if ( !frame->subclass) { 02734 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 02735 return 0; 02736 } 02737 02738 if ( !(frame->subclass & prefformat)) { 02739 02740 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass); 02741 return 0; 02742 } 02743 02744 02745 if ( !frame->samples ) { 02746 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 02747 02748 if (!strcmp(frame->src,"ast_prod")) { 02749 chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch)); 02750 02751 if (ch->ts) { 02752 chan_misdn_log(4,ch->bc->port,"Starting Playtones\n"); 02753 misdn_lib_tone_generator_start(ch->bc); 02754 } 02755 return 0; 02756 } 02757 02758 return -1; 02759 } 02760 02761 if ( ! ch->bc->addr ) { 02762 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 02763 return 0; 02764 } 02765 02766 #if MISDN_DEBUG 02767 { 02768 int i, max=5>frame->samples?frame->samples:5; 02769 02770 printf("write2mISDN %p %d bytes: ", p, frame->samples); 02771 02772 for (i=0; i< max ; i++) printf("%2.2x ",((char*) frame->data)[i]); 02773 printf ("\n"); 02774 } 02775 #endif 02776 02777 02778 switch (ch->bc->bc_state) { 02779 case BCHAN_ACTIVATED: 02780 case BCHAN_BRIDGED: 02781 break; 02782 default: 02783 if (!ch->dropped_frame_cnt) 02784 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %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); 02785 02786 ch->dropped_frame_cnt++; 02787 if (ch->dropped_frame_cnt > 100) { 02788 ch->dropped_frame_cnt=0; 02789 chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x dropped > 100 frames!\n",frame->samples,ch->bc->addr); 02790 02791 } 02792 02793 return 0; 02794 } 02795 02796 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples); 02797 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) { 02798 /* Buffered Transmit (triggert by read from isdn side)*/ 02799 if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) { 02800 if (ch->bc->active) 02801 cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n"); 02802 } 02803 02804 } else { 02805 /*transmit without jitterbuffer*/ 02806 i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples); 02807 } 02808 02809 02810 02811 return 0; 02812 }
int pbx_start_chan | ( | struct chan_list * | ch | ) | [static] |
Channel Queue End
Definition at line 3473 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().
03474 { 03475 int ret=ast_pbx_start(ch->ast); 03476 03477 if (ret>=0) 03478 ch->need_hangup=0; 03479 else 03480 ch->need_hangup=1; 03481 03482 return ret; 03483 }
static void print_bc_info | ( | int | fd, | |
struct chan_list * | help, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 1060 of file chan_misdn.c.
References misdn_bchannel::active, misdn_bchannel::addr, chan_list::addr, chan_list::ast, ast_cli(), misdn_bchannel::bc_state, bc_state2str(), bearer2str(), misdn_bchannel::capability, misdn_bchannel::channel, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, misdn_bchannel::display, misdn_bchannel::ec_enable, ast_channel::exten, misdn_bchannel::holded, misdn_bchannel::l3_id, chan_list::l3id, misdn_get_ch_state(), chan_list::norxtone, chan_list::notxtone, misdn_bchannel::nt, ORG_AST, chan_list::originator, misdn_bchannel::pid, misdn_bchannel::port, and misdn_bchannel::rad.
Referenced by misdn_show_cl(), and misdn_show_cls().
01061 { 01062 struct ast_channel *ast=help->ast; 01063 ast_cli(fd, 01064 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n", 01065 01066 bc->pid, bc->port, bc->channel, 01067 bc->nt?"NT":"TE", 01068 help->originator == ORG_AST?"*":"I", 01069 ast?ast->exten:NULL, 01070 ast?ast->cid.cid_num:NULL, 01071 bc->rad, 01072 ast?ast->context:NULL, 01073 misdn_get_ch_state(help) 01074 ); 01075 if (misdn_debug[bc->port] > 0) 01076 ast_cli(fd, 01077 " --> astname: %s\n" 01078 " --> ch_l3id: %x\n" 01079 " --> ch_addr: %x\n" 01080 " --> bc_addr: %x\n" 01081 " --> bc_l3id: %x\n" 01082 " --> display: %s\n" 01083 " --> activated: %d\n" 01084 " --> state: %s\n" 01085 " --> capability: %s\n" 01086 #ifdef MISDN_1_2 01087 " --> pipeline: %s\n" 01088 #else 01089 " --> echo_cancel: %d\n" 01090 #endif 01091 " --> notone : rx %d tx:%d\n" 01092 " --> bc_hold: %d\n", 01093 help->ast->name, 01094 help->l3id, 01095 help->addr, 01096 bc->addr, 01097 bc?bc->l3_id:-1, 01098 bc->display, 01099 01100 bc->active, 01101 bc_state2str(bc->bc_state), 01102 bearer2str(bc->capability), 01103 #ifdef MISDN_1_2 01104 bc->pipeline, 01105 #else 01106 bc->ec_enable, 01107 #endif 01108 01109 help->norxtone,help->notxtone, 01110 bc->holded 01111 ); 01112 01113 }
static void print_bearer | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 480 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().
00481 { 00482 00483 chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability)); 00484 00485 switch(bc->law) { 00486 case INFO_CODEC_ALAW: 00487 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n"); 00488 break; 00489 case INFO_CODEC_ULAW: 00490 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n"); 00491 break; 00492 } 00493 }
static void print_facility | ( | struct FacParm * | fac, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 442 of file chan_misdn.c.
References chan_misdn_log(), and misdn_bchannel::port.
Referenced by cb_events().
00443 { 00444 switch (fac->Function) { 00445 case Fac_CD: 00446 chan_misdn_log(1,bc->port," --> calldeflect to: %s, screened: %s\n", fac->u.CDeflection.DeflectedToNumber, 00447 fac->u.CDeflection.PresentationAllowed ? "yes" : "no"); 00448 break; 00449 case Fac_AOCDCurrency: 00450 if (fac->u.AOCDcur.chargeNotAvailable) 00451 chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n"); 00452 else if (fac->u.AOCDcur.freeOfCharge) 00453 chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n"); 00454 else if (fac->u.AOCDchu.billingId >= 0) 00455 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d billingId:%d\n", 00456 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00457 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId); 00458 else 00459 chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d\n", 00460 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier, 00461 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00462 break; 00463 case Fac_AOCDChargingUnit: 00464 if (fac->u.AOCDchu.chargeNotAvailable) 00465 chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n"); 00466 else if (fac->u.AOCDchu.freeOfCharge) 00467 chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n"); 00468 else if (fac->u.AOCDchu.billingId >= 0) 00469 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n", 00470 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId); 00471 else 00472 chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n", 00473 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total"); 00474 break; 00475 default: 00476 chan_misdn_log(1,bc->port," --> unknown\n"); 00477 } 00478 }
static struct ast_frame * process_ast_dsp | ( | struct chan_list * | tmp, | |
struct ast_frame * | frame | |||
) | [static, read] |
Definition at line 2572 of file chan_misdn.c.
References chan_list::ast, ast_async_goto(), chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, ast_log(), ast_strlen_zero(), ast_translate(), ast_verbose(), chan_list::bc, BUFFERSIZE, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, context, chan_list::dsp, misdn_bchannel::ec_enable, ast_channel::exten, f, chan_list::faxdetect, chan_list::faxhandled, ast_frame::frametype, isdn_lib_stop_dtmf(), isdn_lib_update_ec(), isdn_lib_update_rxgain(), isdn_lib_update_txgain(), LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, MISDN_CFG_FAXDETECT_CONTEXT, misdn_cfg_get(), option_verbose, pbx_builtin_setvar_helper(), misdn_bchannel::port, misdn_bchannel::rxgain, ast_frame::subclass, chan_list::trans, misdn_bchannel::txgain, and VERBOSE_PREFIX_3.
Referenced by misdn_read().
02573 { 02574 struct ast_frame *f,*f2; 02575 02576 if (tmp->trans) { 02577 f2 = ast_translate(tmp->trans, frame, 0); 02578 f = ast_dsp_process(tmp->ast, tmp->dsp, f2); 02579 } else { 02580 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n"); 02581 return NULL; 02582 } 02583 02584 02585 if (!f || (f->frametype != AST_FRAME_DTMF)) 02586 return frame; 02587 02588 ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass); 02589 02590 if (tmp->faxdetect && (f->subclass == 'f')) { 02591 /* Fax tone -- Handle and return NULL */ 02592 if (!tmp->faxhandled) { 02593 struct ast_channel *ast = tmp->ast; 02594 tmp->faxhandled++; 02595 chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name); 02596 tmp->bc->rxgain = 0; 02597 isdn_lib_update_rxgain(tmp->bc); 02598 tmp->bc->txgain = 0; 02599 isdn_lib_update_txgain(tmp->bc); 02600 #ifdef MISDN_1_2 02601 *tmp->bc->pipeline = 0; 02602 #else 02603 tmp->bc->ec_enable = 0; 02604 #endif 02605 isdn_lib_update_ec(tmp->bc); 02606 isdn_lib_stop_dtmf(tmp->bc); 02607 switch (tmp->faxdetect) { 02608 case 1: 02609 if (strcmp(ast->exten, "fax")) { 02610 char *context; 02611 char context_tmp[BUFFERSIZE]; 02612 misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp)); 02613 context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp; 02614 if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) { 02615 if (option_verbose > 2) 02616 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context); 02617 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02618 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 02619 if (ast_async_goto(ast, context, "fax", 1)) 02620 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context); 02621 } else 02622 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten); 02623 } else 02624 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 02625 break; 02626 case 2: 02627 ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name); 02628 break; 02629 } 02630 } else 02631 ast_log(LOG_DEBUG, "Fax already handled\n"); 02632 } 02633 02634 if (tmp->ast_dsp && (f->subclass != 'f')) { 02635 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass); 02636 } 02637 02638 return frame; 02639 }
static int read_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
ORIGINATOR MISDN
Definition at line 1737 of file chan_misdn.c.
References chan_list::allowed_bearers, misdn_bchannel::AOCDtype, chan_list::ast, ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, ast_log(), ast_mutex_init(), ast_print_group(), ast_set_callerid(), ast_string_field_set, ast_strlen_zero(), ast_translator_build_path(), chan_list::bc, 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, free, misdn_bchannel::hdlc, 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_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, musicclass, 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, strdup, misdn_bchannel::te_choose_channel, chan_list::trans, misdn_bchannel::txgain, and update_ec_config().
Referenced by cb_events(), and misdn_request().
01737 { 01738 01739 if (!ch) { 01740 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01741 return -1; 01742 } 01743 01744 struct ast_channel *ast=ch->ast; 01745 struct misdn_bchannel *bc=ch->bc; 01746 if (! ast || ! bc ) { 01747 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01748 return -1; 01749 } 01750 01751 int port=bc->port; 01752 01753 chan_misdn_log(1,port,"read_config: Getting Config\n"); 01754 01755 char lang[BUFFERSIZE+1]; 01756 01757 01758 misdn_cfg_get( port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE); 01759 ast_string_field_set(ast, language, lang); 01760 01761 char localmusicclass[BUFFERSIZE+1]; 01762 01763 misdn_cfg_get( port, MISDN_CFG_MUSICCLASS, localmusicclass, BUFFERSIZE); 01764 ast_string_field_set(ast, musicclass, localmusicclass); 01765 01766 01767 misdn_cfg_get( port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int)); 01768 misdn_cfg_get( port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int)); 01769 01770 misdn_cfg_get( port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int)); 01771 01772 misdn_cfg_get( port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int)); 01773 01774 misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int)); 01775 misdn_cfg_get( port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(int)); 01776 01777 misdn_cfg_get( port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(int)); 01778 01779 misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int)); 01780 01781 misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE); 01782 01783 char faxdetect[BUFFERSIZE+1]; 01784 misdn_cfg_get( port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE); 01785 01786 int hdlc=0; 01787 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01788 01789 if (hdlc) { 01790 switch (bc->capability) { 01791 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01792 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01793 chan_misdn_log(1,bc->port," --> CONF HDLC\n"); 01794 bc->hdlc=1; 01795 break; 01796 } 01797 01798 } 01799 /*Initialize new Jitterbuffer*/ 01800 { 01801 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int)); 01802 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int)); 01803 01804 config_jitterbuffer(ch); 01805 } 01806 01807 misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context)); 01808 01809 ast_copy_string (ast->context,ch->context,sizeof(ast->context)); 01810 01811 #ifdef MISDN_1_2 01812 update_pipeline_config(bc); 01813 #else 01814 update_ec_config(bc); 01815 #endif 01816 01817 { 01818 int eb3; 01819 01820 misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int)); 01821 bc->early_bconnect=eb3; 01822 } 01823 01824 port=bc->port; 01825 01826 { 01827 char buf[256]; 01828 ast_group_t pg,cg; 01829 01830 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg)); 01831 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg)); 01832 01833 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg)); 01834 ast->pickupgroup=pg; 01835 ast->callgroup=cg; 01836 } 01837 01838 if ( orig == ORG_AST) { 01839 misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int)); 01840 01841 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) { 01842 if (strstr(faxdetect, "nojump")) 01843 ch->faxdetect=2; 01844 else 01845 ch->faxdetect=1; 01846 } 01847 01848 { 01849 char callerid[BUFFERSIZE+1]; 01850 misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE); 01851 if ( ! ast_strlen_zero(callerid) ) { 01852 chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid); 01853 { 01854 int l = sizeof(bc->oad); 01855 strncpy(bc->oad,callerid, l); 01856 bc->oad[l-1] = 0; 01857 } 01858 01859 } 01860 01861 01862 misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int)); 01863 misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int)); 01864 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 01865 debug_numplan(port, bc->dnumplan,"TON"); 01866 debug_numplan(port, bc->onumplan,"LTON"); 01867 debug_numplan(port, bc->cpnnumplan,"CTON"); 01868 } 01869 01870 ch->overlap_dial = 0; 01871 } else { /** ORIGINATOR MISDN **/ 01872 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) { 01873 if (strstr(faxdetect, "nojump")) 01874 ch->faxdetect=2; 01875 else 01876 ch->faxdetect=1; 01877 } 01878 01879 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 01880 debug_numplan(port, bc->cpnnumplan,"CTON"); 01881 01882 char prefix[BUFFERSIZE+1]=""; 01883 switch( bc->onumplan ) { 01884 case NUMPLAN_INTERNATIONAL: 01885 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 01886 break; 01887 01888 case NUMPLAN_NATIONAL: 01889 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 01890 break; 01891 default: 01892 break; 01893 } 01894 01895 { 01896 int l = strlen(prefix) + strlen(bc->oad); 01897 char tmp[l+1]; 01898 strcpy(tmp,prefix); 01899 strcat(tmp,bc->oad); 01900 strcpy(bc->oad,tmp); 01901 } 01902 01903 if (!ast_strlen_zero(bc->dad)) { 01904 ast_copy_string(bc->orig_dad,bc->dad, sizeof(bc->orig_dad)); 01905 } 01906 01907 if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) { 01908 ast_copy_string(bc->dad,bc->keypad, sizeof(bc->dad)); 01909 } 01910 01911 prefix[0] = 0; 01912 01913 switch( bc->dnumplan ) { 01914 case NUMPLAN_INTERNATIONAL: 01915 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 01916 break; 01917 case NUMPLAN_NATIONAL: 01918 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 01919 break; 01920 default: 01921 break; 01922 } 01923 01924 { 01925 int l = strlen(prefix) + strlen(bc->dad); 01926 char tmp[l+1]; 01927 strcpy(tmp,prefix); 01928 strcat(tmp,bc->dad); 01929 strcpy(bc->dad,tmp); 01930 } 01931 01932 if ( strcmp(bc->dad,ast->exten)) { 01933 ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten)); 01934 } 01935 01936 ast_set_callerid(ast, bc->oad, NULL, bc->oad); 01937 01938 if ( !ast_strlen_zero(bc->rad) ) { 01939 if (ast->cid.cid_rdnis) 01940 free(ast->cid.cid_rdnis); 01941 ast->cid.cid_rdnis = strdup(bc->rad); 01942 } 01943 01944 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial)); 01945 ast_mutex_init(&ch->overlap_tv_lock); 01946 } /* ORIG MISDN END */ 01947 01948 ch->overlap_dial_task = -1; 01949 01950 if (ch->faxdetect) { 01951 misdn_cfg_get( port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout)); 01952 if (!ch->dsp) 01953 ch->dsp = ast_dsp_new(); 01954 if (ch->dsp) 01955 ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT); 01956 if (!ch->trans) 01957 ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 01958 } 01959 01960 /* AOCD initialization */ 01961 bc->AOCDtype = Fac_None; 01962 01963 return 0; 01964 }
static void release_chan | ( | struct misdn_bchannel * | bc | ) | [static] |
Isdn asks us to release channel, pendant to misdn_hangup
Definition at line 3523 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, cl_dequeue_chan(), ast_channel::context, ast_channel::exten, find_chan_by_bc(), free, chan_list::jb, misdn_bchannel::l3_id, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_get_ch_state(), misdn_jb_destroy(), misdn_tasks_remove(), misdn_bchannel::nojitter, ORG_AST, chan_list::originator, chan_list::overlap_dial, chan_list::overlap_dial_task, chan_list::overlap_tv_lock, misdn_bchannel::pid, chan_list::pipe, misdn_bchannel::port, and chan_list::state.
Referenced by cb_events(), and misdn_hangup().
03523 { 03524 struct ast_channel *ast=NULL; 03525 03526 ast_mutex_lock(&release_lock); 03527 { 03528 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03529 if (!ch) { 03530 chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n"); 03531 ast_mutex_unlock(&release_lock); 03532 return; 03533 } 03534 03535 if (ch->ast) { 03536 ast=ch->ast; 03537 } 03538 03539 chan_misdn_log(5, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id); 03540 03541 /*releaseing jitterbuffer*/ 03542 if (ch->jb ) { 03543 misdn_jb_destroy(ch->jb); 03544 ch->jb=NULL; 03545 } else { 03546 if (!bc->nojitter) 03547 chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n"); 03548 } 03549 03550 if (ch->overlap_dial) { 03551 if (ch->overlap_dial_task != -1) { 03552 misdn_tasks_remove(ch->overlap_dial_task); 03553 ch->overlap_dial_task = -1; 03554 } 03555 ast_mutex_destroy(&ch->overlap_tv_lock); 03556 } 03557 03558 if (ch->originator == ORG_AST) { 03559 misdn_out_calls[bc->port]--; 03560 } else { 03561 misdn_in_calls[bc->port]--; 03562 } 03563 03564 if (ch) { 03565 03566 close(ch->pipe[0]); 03567 close(ch->pipe[1]); 03568 03569 03570 if (ast && MISDN_ASTERISK_TECH_PVT(ast)) { 03571 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)); 03572 chan_misdn_log(3, bc->port, " --> * State Down\n"); 03573 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 03574 03575 03576 if (ast->_state != AST_STATE_RESERVED) { 03577 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 03578 ast_setstate(ast, AST_STATE_DOWN); 03579 } 03580 } 03581 03582 ch->state=MISDN_CLEANING; 03583 cl_dequeue_chan(&cl_te, ch); 03584 03585 free(ch); 03586 } else { 03587 /* chan is already cleaned, so exiting */ 03588 } 03589 } 03590 03591 ast_mutex_unlock(&release_lock); 03592 }
static int reload | ( | void | ) | [static] |
Definition at line 5039 of file chan_misdn.c.
References reload_config().
05040 { 05041 reload_config(); 05042 05043 return 0; 05044 }
static void reload_config | ( | void | ) | [static] |
Definition at line 1032 of file chan_misdn.c.
References ast_log(), BUFFERSIZE, free_robin_list(), LOG_WARNING, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), MISDN_GEN_DEBUG, and MISDN_GEN_TRACEFILE.
01033 { 01034 int i, cfg_debug; 01035 01036 if (!g_config_initialized) { 01037 ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n"); 01038 return ; 01039 } 01040 01041 free_robin_list(); 01042 misdn_cfg_reload(); 01043 misdn_cfg_update_ptp(); 01044 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 01045 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int)); 01046 01047 for (i = 0; i <= max_ports; i++) { 01048 misdn_debug[i] = cfg_debug; 01049 misdn_debug_only[i] = 0; 01050 } 01051 }
static void send_cause2ast | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) | [static] |
Congestion Cases
Definition at line 3672 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().
03672 { 03673 if (!ast) { 03674 chan_misdn_log(1,0,"send_cause2ast: No Ast\n"); 03675 return; 03676 } 03677 if (!bc) { 03678 chan_misdn_log(1,0,"send_cause2ast: No BC\n"); 03679 return; 03680 } 03681 if (!ch) { 03682 chan_misdn_log(1,0,"send_cause2ast: No Ch\n"); 03683 return; 03684 } 03685 03686 ast->hangupcause=bc->cause; 03687 03688 switch ( bc->cause) { 03689 03690 case 1: /** Congestion Cases **/ 03691 case 2: 03692 case 3: 03693 case 4: 03694 case 22: 03695 case 27: 03696 /* 03697 * Not Queueing the Congestion anymore, since we want to hear 03698 * the inband message 03699 * 03700 chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1); 03701 ch->state=MISDN_BUSY; 03702 03703 ast_queue_control(ast, AST_CONTROL_CONGESTION); 03704 */ 03705 break; 03706 03707 case 21: 03708 case 17: /* user busy */ 03709 03710 ch->state=MISDN_BUSY; 03711 03712 if (!ch->need_busy) { 03713 chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n"); 03714 break; 03715 } 03716 03717 chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1); 03718 03719 ast_queue_control(ast, AST_CONTROL_BUSY); 03720 03721 ch->need_busy=0; 03722 03723 break; 03724 } 03725 }
static void send_digit_to_chan | ( | struct chan_list * | cl, | |
char | digit | |||
) | [static] |
Definition at line 695 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_playtones_start(), and LOG_DEBUG.
Referenced by misdn_digit_end(), and misdn_send_digit().
00696 { 00697 static const char* dtmf_tones[] = { 00698 "!941+1336/100,!0/100", /* 0 */ 00699 "!697+1209/100,!0/100", /* 1 */ 00700 "!697+1336/100,!0/100", /* 2 */ 00701 "!697+1477/100,!0/100", /* 3 */ 00702 "!770+1209/100,!0/100", /* 4 */ 00703 "!770+1336/100,!0/100", /* 5 */ 00704 "!770+1477/100,!0/100", /* 6 */ 00705 "!852+1209/100,!0/100", /* 7 */ 00706 "!852+1336/100,!0/100", /* 8 */ 00707 "!852+1477/100,!0/100", /* 9 */ 00708 "!697+1633/100,!0/100", /* A */ 00709 "!770+1633/100,!0/100", /* B */ 00710 "!852+1633/100,!0/100", /* C */ 00711 "!941+1633/100,!0/100", /* D */ 00712 "!941+1209/100,!0/100", /* * */ 00713 "!941+1477/100,!0/100" }; /* # */ 00714 struct ast_channel *chan=cl->ast; 00715 00716 if (digit >= '0' && digit <='9') 00717 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0); 00718 else if (digit >= 'A' && digit <= 'D') 00719 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0); 00720 else if (digit == '*') 00721 ast_playtones_start(chan,0,dtmf_tones[14], 0); 00722 else if (digit == '#') 00723 ast_playtones_start(chan,0,dtmf_tones[15], 0); 00724 else { 00725 /* not handled */ 00726 ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name); 00727 00728 00729 } 00730 }
static void show_config_description | ( | int | fd, | |
enum misdn_cfg_elements | elem | |||
) | [inline, static] |
Definition at line 882 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 misdn_show_config().
00883 { 00884 char section[BUFFERSIZE]; 00885 char name[BUFFERSIZE]; 00886 char desc[BUFFERSIZE]; 00887 char def[BUFFERSIZE]; 00888 char tmp[BUFFERSIZE]; 00889 00890 misdn_cfg_get_name(elem, tmp, sizeof(tmp)); 00891 term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp)); 00892 misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def)); 00893 00894 if (elem < MISDN_CFG_LAST) 00895 term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section)); 00896 else 00897 term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section)); 00898 00899 if (*def) 00900 ast_cli(fd, "[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc); 00901 else 00902 ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc); 00903 }
static void sighandler | ( | int | sig | ) | [static] |
static int start_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2985 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().
02986 { 02987 misdn_lib_tone_generator_stop(cl->bc); 02988 cl->notxtone=0; 02989 cl->norxtone=0; 02990 return 0; 02991 }
static void start_pbx | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3821 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().
03821 { 03822 if (pbx_start_chan(ch)<0) { 03823 hangup_chan(ch); 03824 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 03825 if (bc->nt) { 03826 hanguptone_indicate(ch); 03827 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03828 } else 03829 misdn_lib_send_event(bc, EVENT_RELEASE); 03830 } 03831 }
static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2993 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by cb_events(), misdn_call(), and misdn_hangup().
02994 { 02995 if (!cl) return -1; 02996 02997 cl->notxtone=1; 02998 cl->norxtone=1; 02999 03000 return 0; 03001 }
static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2965 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().
02966 { 02967 struct ast_channel *ast=cl->ast; 02968 02969 if (!ast) { 02970 chan_misdn_log(0,cl->bc->port,"No Ast in stop_indicate\n"); 02971 return -1; 02972 } 02973 02974 chan_misdn_log(3,cl->bc->port," --> None\n"); 02975 misdn_lib_tone_generator_stop(cl->bc); 02976 ast_playtones_stop(ast); 02977 02978 cl->ts=NULL; 02979 /*ast_deactivate_generator(ast);*/ 02980 02981 return 0; 02982 }
static int unload_module | ( | void | ) | [static] |
TE STUFF END
Definition at line 4859 of file chan_misdn.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_log(), ast_unregister_application(), free, free_robin_list(), LOG_VERBOSE, misdn_cfg_destroy(), misdn_lib_destroy(), and misdn_tasks_destroy().
04860 { 04861 /* First, take us out of the channel loop */ 04862 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 04863 04864 misdn_tasks_destroy(); 04865 04866 if (!g_config_initialized) return 0; 04867 04868 ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry)); 04869 04870 /* ast_unregister_application("misdn_crypt"); */ 04871 ast_unregister_application("misdn_set_opt"); 04872 ast_unregister_application("misdn_facility"); 04873 ast_unregister_application("misdn_check_l2l1"); 04874 04875 ast_channel_unregister(&misdn_tech); 04876 04877 04878 free_robin_list(); 04879 misdn_cfg_destroy(); 04880 misdn_lib_destroy(); 04881 04882 if (misdn_debug) 04883 free(misdn_debug); 04884 if (misdn_debug_only) 04885 free(misdn_debug_only); 04886 free(misdn_ports); 04887 04888 return 0; 04889 }
static int update_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
Definition at line 1539 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().
01540 { 01541 if (!ch) { 01542 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01543 return -1; 01544 } 01545 01546 struct ast_channel *ast=ch->ast; 01547 struct misdn_bchannel *bc=ch->bc; 01548 if (! ast || ! bc ) { 01549 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01550 return -1; 01551 } 01552 01553 int port=bc->port; 01554 01555 chan_misdn_log(7,port,"update_config: Getting Config\n"); 01556 01557 int hdlc=0; 01558 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01559 01560 if (hdlc) { 01561 switch (bc->capability) { 01562 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01563 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01564 chan_misdn_log(1,bc->port," --> CONF HDLC\n"); 01565 bc->hdlc=1; 01566 break; 01567 } 01568 01569 } 01570 01571 01572 int pres, screen; 01573 01574 misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int)); 01575 misdn_cfg_get( port, MISDN_CFG_SCREEN, &screen, sizeof(int)); 01576 chan_misdn_log(2,port," --> pres: %d screen: %d\n",pres, screen); 01577 01578 if ( (pres + screen) < 0 ) { 01579 01580 chan_misdn_log(2,port," --> pres: %x\n", ast->cid.cid_pres); 01581 01582 switch (ast->cid.cid_pres & 0x60){ 01583 01584 case AST_PRES_RESTRICTED: 01585 bc->pres=1; 01586 chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n"); 01587 break; 01588 01589 01590 case AST_PRES_UNAVAILABLE: 01591 bc->pres=2; 01592 chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n"); 01593 break; 01594 01595 default: 01596 bc->pres=0; 01597 chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n"); 01598 } 01599 01600 switch (ast->cid.cid_pres & 0x3){ 01601 01602 case AST_PRES_USER_NUMBER_UNSCREENED: 01603 bc->screen=0; 01604 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n"); 01605 break; 01606 01607 case AST_PRES_USER_NUMBER_PASSED_SCREEN: 01608 bc->screen=1; 01609 chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n"); 01610 break; 01611 case AST_PRES_USER_NUMBER_FAILED_SCREEN: 01612 bc->screen=2; 01613 chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n"); 01614 break; 01615 01616 case AST_PRES_NETWORK_NUMBER: 01617 bc->screen=3; 01618 chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n"); 01619 break; 01620 01621 default: 01622 bc->screen=0; 01623 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n"); 01624 } 01625 01626 01627 } else { 01628 bc->screen=screen; 01629 bc->pres=pres; 01630 } 01631 01632 return 0; 01633 01634 }
static int update_ec_config | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 1718 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 misdn_toggle_echocancel(), and read_config().
01719 { 01720 int ec; 01721 int port=bc->port; 01722 01723 misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int)); 01724 01725 if (ec == 1 ) { 01726 bc->ec_enable=1; 01727 } else if ( ec > 1 ) { 01728 bc->ec_enable=1; 01729 bc->ec_deftaps=ec; 01730 } 01731 01732 return 0; 01733 }
static void update_name | ( | struct ast_channel * | tmp, | |
int | port, | |||
int | c | |||
) | [static] |
Definition at line 3264 of file chan_misdn.c.
References ast_string_field_build, chan_misdn_log(), misdn_cfg_get_next_port(), misdn_lib_port_is_pri(), and name.
Referenced by cb_events().
03265 { 03266 int chan_offset=0; 03267 int tmp_port = misdn_cfg_get_next_port(0); 03268 for (; tmp_port > 0; tmp_port=misdn_cfg_get_next_port(tmp_port)) { 03269 if (tmp_port == port) break; 03270 chan_offset+=misdn_lib_port_is_pri(tmp_port)?30:2; 03271 } 03272 if (c<0) c=0; 03273 03274 ast_string_field_build(tmp, name, "%s/%d-u%d", 03275 misdn_type, chan_offset+c, glob_channel++); 03276 03277 chan_misdn_log(3,port," --> updating channel name to [%s]\n",tmp->name); 03278 03279 }
static void wait_for_digits | ( | struct chan_list * | ch, | |
struct misdn_bchannel * | bc, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 3833 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().
03833 { 03834 ch->state=MISDN_WAITING4DIGS; 03835 misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03836 if (bc->nt && !bc->dad[0]) 03837 dialtone_indicate(ch); 03838 }
struct allowed_bearers allowed_bearers_array[] |
Definition at line 401 of file chan_misdn.c.
struct ast_cli_entry chan_misdn_clis[] [static] |
Definition at line 1488 of file chan_misdn.c.
Definition at line 319 of file chan_misdn.c.
Definition at line 320 of file chan_misdn.c.
Definition at line 317 of file chan_misdn.c.
int g_config_initialized = 0 [static] |
Definition at line 81 of file chan_misdn.c.
int glob_channel = 0 [static] |
Definition at line 3262 of file chan_misdn.c.
char global_tracefile[BUFFERSIZE+1] |
Definition at line 79 of file chan_misdn.c.
Definition at line 1174 of file chan_misdn.c.
Referenced by load_config(), load_module(), load_rpt_vars(), rpt_master(), unload_module(), zap_show_channel(), zap_show_channels(), and zt_request().
int max_ports [static] |
Definition at line 311 of file chan_misdn.c.
int MAXTICS = 8 |
Definition at line 1175 of file chan_misdn.c.
int* misdn_debug [static] |
Definition at line 309 of file chan_misdn.c.
int* misdn_debug_only [static] |
Definition at line 310 of file chan_misdn.c.
int* misdn_in_calls [static] |
Definition at line 313 of file chan_misdn.c.
int* misdn_out_calls [static] |
Definition at line 314 of file chan_misdn.c.
int* misdn_ports [static] |
Definition at line 285 of file chan_misdn.c.
struct sched_context* misdn_tasks = NULL [static] |
Definition at line 282 of file chan_misdn.c.
pthread_t misdn_tasks_thread [static] |
Definition at line 283 of file chan_misdn.c.
struct ast_channel_tech misdn_tech [static] |
Definition at line 3224 of file chan_misdn.c.
struct ast_channel_tech misdn_tech_wo_bridge [static] |
Definition at line 3243 of file chan_misdn.c.
const char misdn_type[] = "mISDN" [static] |
Definition at line 302 of file chan_misdn.c.
int prefformat = AST_FORMAT_ALAW [static] |
Definition at line 307 of file chan_misdn.c.
Definition at line 115 of file chan_misdn.c.
struct robin_list* robin = NULL [static] |
Definition at line 239 of file chan_misdn.c.
struct state_struct state_array[] [static] |
Definition at line 989 of file chan_misdn.c.
int tracing = 0 [static] |
Definition at line 304 of file chan_misdn.c.