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