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