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