#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 <sys/file.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 <chan_misdn_config.h>
#include <isdn_lib.h>
#include <asterisk/strings.h>
Go to the source code of this file.
Data Structures | |
struct | allowed_bearers |
struct | chan_list |
struct | misdn_jb |
struct | robin_list |
struct | state_struct |
Defines | |
#define | AST_BRIDGED_P(ast) ast_bridged_channel(ast) |
#define | AST_CID_P(ast) ast->cid.cid_num |
#define | AST_DESTROY_CFG ast_config_destroy |
#define | AST_LOAD_CFG ast_config_load |
#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, MISDN_WAITING4DIGS, MISDN_EXTCANTMATCH, 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 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 (char *line, char *word, int pos, int state) |
static char * | complete_ch_helper (char *line, char *word, int pos, int state, int rpos) |
static char * | complete_debug_port (char *line, char *word, int pos, int state) |
void | config_jitterbuffer (struct chan_list *ch) |
void | debug_numplan (int port, int numplan, char *type) |
char * | description (void) |
Provides a description of the module. | |
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) |
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 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) |
char * | key (void) |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static int | misdn_answer (struct ast_channel *ast) |
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_digit (struct ast_channel *ast, char digit) |
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) |
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 struct ast_channel * | misdn_new (struct chan_list *cl, int state, char *exten, char *callerid, int format, int port, int c) |
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_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[]) |
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_stacks (int fd, int argc, char *argv[]) |
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) |
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 misdn_bchannel *bc) |
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) |
int | reload (void) |
Reload stuff. | |
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 int | start_bc_tones (struct chan_list *cl) |
static int | stop_bc_tones (struct chan_list *cl) |
static int | stop_indicate (struct chan_list *cl) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
static int | update_config (struct chan_list *ch, int orig) |
static int | update_ec_config (struct misdn_bchannel *bc) |
int | usecount (void) |
Provides a usecount. | |
Variables | |
allowed_bearers | allowed_bearers_array [] |
chan_list * | cl_te = NULL |
ast_mutex_t | cl_te_lock |
static struct ast_cli_entry | cli_port_block |
static struct ast_cli_entry | cli_port_down |
static struct ast_cli_entry | cli_port_unblock |
static struct ast_cli_entry | cli_port_up |
static struct ast_cli_entry | cli_reload |
static struct ast_cli_entry | cli_restart_port |
static struct ast_cli_entry | cli_send_cd |
static struct ast_cli_entry | cli_send_digit |
static struct ast_cli_entry | cli_send_display |
static struct ast_cli_entry | cli_set_crypt_debug |
static struct ast_cli_entry | cli_set_debug |
static struct ast_cli_entry | cli_set_tics |
static struct ast_cli_entry | cli_show_cl |
static struct ast_cli_entry | cli_show_cls |
static struct ast_cli_entry | cli_show_config |
static struct ast_cli_entry | cli_show_port |
static struct ast_cli_entry | cli_show_stacks |
static struct ast_cli_entry | cli_toggle_echocancel |
static char * | desc = "Channel driver for mISDN Support (Bri/Pri)" |
chan_list | dummy_cl |
static int | g_config_initialized = 0 |
static unsigned long | 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 char ** | misdn_key_vector = NULL |
static int | misdn_key_vector_size = 0 |
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 |
static struct robin_list * | robin = NULL |
static struct state_struct | state_array [] |
static int | tracing = 0 |
static int | usecnt = 0 |
static ast_mutex_t | usecnt_lock |
Definition in file chan_misdn.c.
#define AST_BRIDGED_P | ( | ast | ) | ast_bridged_channel(ast) |
#define AST_CID_P | ( | ast | ) | ast->cid.cid_num |
Definition at line 257 of file chan_misdn.c.
Referenced by do_immediate_setup(), misdn_call(), misdn_hangup(), misdn_show_cls(), print_bc_info(), process_ast_dsp(), and release_chan().
#define AST_DESTROY_CFG ast_config_destroy |
#define AST_LOAD_CFG ast_config_load |
#define MISDN_ASTERISK_PVT | ( | ast | ) | 1 |
#define MISDN_ASTERISK_TECH_PVT | ( | ast | ) | ast->tech_pvt |
Definition at line 262 of file chan_misdn.c.
Referenced by cb_events(), do_immediate_setup(), misdn_answer(), misdn_call(), misdn_digit(), 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 129 of file chan_misdn.c.
Referenced by misdn_call(), misdn_hangup(), misdn_request(), print_bc_info(), and read_config().
#define ORG_MISDN 2 |
Definition at line 130 of file chan_misdn.c.
Referenced by cb_events(), do_immediate_setup(), and misdn_indication().
enum misdn_chan_state |
Definition at line 104 of file chan_misdn.c.
00104 { 00105 MISDN_NOTHING, /*!< at beginning */ 00106 MISDN_WAITING4DIGS, /*!< when waiting for infos */ 00107 MISDN_EXTCANTMATCH, /*!< when asterisk couldnt match our ext */ 00108 MISDN_DIALING, /*!< when pbx_start */ 00109 MISDN_PROGRESS, /*!< we got a progress */ 00110 MISDN_PROCEEDING, /*!< we got a progress */ 00111 MISDN_CALLING, /*!< when misdn_call is called */ 00112 MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */ 00113 MISDN_ALERTING, /*!< when Alerting */ 00114 MISDN_BUSY, /*!< when BUSY */ 00115 MISDN_CONNECTED, /*!< when connected */ 00116 MISDN_PRECONNECTED, /*!< when connected */ 00117 MISDN_DISCONNECTED, /*!< when connected */ 00118 MISDN_RELEASED, /*!< when connected */ 00119 MISDN_BRIDGED, /*!< when bridged */ 00120 MISDN_CLEANING, /*!< when hangup from * but we were connected before */ 00121 MISDN_HUNGUP_FROM_MISDN, /*!< when DISCONNECT/RELEASE/REL_COMP cam from misdn */ 00122 MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */ 00123 /* misdn_hangup */ 00124 MISDN_HOLDED, /*!< if this chan is holded */ 00125 MISDN_HOLD_DISCONNECT /*!< if this chan is holded */ 00126 00127 };
static char* bearer2str | ( | int | cap | ) | [static] |
Definition at line 360 of file chan_misdn.c.
Referenced by print_bc_info(), and print_bearer().
00360 { 00361 static char *bearers[]={ 00362 "Speech", 00363 "Audio 3.1k", 00364 "Unres Digital", 00365 "Res Digital", 00366 "Video", 00367 "Unknown Bearer" 00368 }; 00369 00370 switch (cap) { 00371 case INFO_CAPABILITY_SPEECH: 00372 return bearers[0]; 00373 break; 00374 case INFO_CAPABILITY_AUDIO_3_1K: 00375 return bearers[1]; 00376 break; 00377 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 00378 return bearers[2]; 00379 break; 00380 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 00381 return bearers[3]; 00382 break; 00383 case INFO_CAPABILITY_VIDEO: 00384 return bearers[4]; 00385 break; 00386 default: 00387 return bearers[5]; 00388 break; 00389 } 00390 }
static enum event_response_e cb_events | ( | enum event_e | event, | |
struct misdn_bchannel * | bc, | |||
void * | user_data | |||
) | [static] |
Definition at line 3145 of file chan_misdn.c.
References 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_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, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, cl_queue_chan(), cl_te, chan_list::context, ast_frame::data, ast_frame::datalen, dialtone_indicate(), do_immediate_setup(), export_ch(), ast_channel::exten, find_chan_by_bc(), find_holded(), ast_frame::frametype, hangup_chan(), hanguptone_indicate(), chan_list::ignore_dtmf, init_chan_list(), chan_list::l3id, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING_ACKNOWLEDGE, misdn_cfg_get(), misdn_cfg_is_msn_valid(), MISDN_CONNECTED, MISDN_DIALING, MISDN_EXTCANTMATCH, misdn_get_ch_state(), misdn_new(), MISDN_NOTHING, MISDN_WAITING4DIGS, allowed_bearers::name, ast_frame::offset, ORG_MISDN, chan_list::orginator, pbx_builtin_setvar_helper(), pbx_start_chan(), print_bearer(), read_config(), ast_channel::rings, ast_frame::samples, ast_frame::src, chan_list::state, stop_indicate(), ast_frame::subclass, and ast_channel::transfercapability.
Referenced by load_module().
03146 { 03147 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03148 03149 if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ 03150 int debuglevel=1; 03151 03152 if ( event==EVENT_CLEANUP && !user_data) 03153 debuglevel=5; 03154 03155 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"); 03156 if (debuglevel==1) { 03157 misdn_lib_log_ies(bc); 03158 chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state)); 03159 } 03160 } 03161 03162 if (!ch) { 03163 switch(event) { 03164 case EVENT_SETUP: 03165 case EVENT_DISCONNECT: 03166 case EVENT_PORT_ALARM: 03167 case EVENT_RETRIEVE: 03168 case EVENT_NEW_BC: 03169 break; 03170 case EVENT_RELEASE_COMPLETE: 03171 chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); 03172 break; 03173 case EVENT_CLEANUP: 03174 case EVENT_TONE_GENERATE: 03175 case EVENT_BCHAN_DATA: 03176 return -1; 03177 03178 default: 03179 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); 03180 return -1; 03181 } 03182 } 03183 03184 if (ch ) { 03185 switch (event) { 03186 case EVENT_TONE_GENERATE: 03187 break; 03188 case EVENT_DISCONNECT: 03189 case EVENT_RELEASE: 03190 case EVENT_RELEASE_COMPLETE: 03191 case EVENT_CLEANUP: 03192 case EVENT_TIMEOUT: 03193 if (!ch->ast) 03194 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)); 03195 break; 03196 default: 03197 if ( !ch->ast || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03198 if (event!=EVENT_BCHAN_DATA) 03199 ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event)); 03200 return -1; 03201 } 03202 } 03203 } 03204 03205 03206 switch (event) { 03207 case EVENT_PORT_ALARM: 03208 { 03209 int boa=0; 03210 03211 misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int)); 03212 if (boa) { 03213 cb_log(1,bc->port," --> blocking\n"); 03214 misdn_lib_port_block(bc->port); 03215 } 03216 } 03217 break; 03218 03219 case EVENT_BCHAN_ACTIVATED: 03220 break; 03221 03222 case EVENT_NEW_L3ID: 03223 ch->l3id=bc->l3_id; 03224 ch->addr=bc->addr; 03225 break; 03226 03227 case EVENT_NEW_BC: 03228 if (!ch) { 03229 ch=find_holded(cl_te,bc); 03230 } 03231 03232 if (!ch) { 03233 ast_log(LOG_WARNING,"NEW_BC without chan_list?\n"); 03234 break; 03235 } 03236 03237 if (bc) 03238 ch->bc=(struct misdn_bchannel*)user_data; 03239 break; 03240 03241 case EVENT_DTMF_TONE: 03242 { 03243 /* sending INFOS as DTMF-Frames :) */ 03244 struct ast_frame fr; 03245 memset(&fr, 0 , sizeof(fr)); 03246 fr.frametype = AST_FRAME_DTMF; 03247 fr.subclass = bc->dtmf ; 03248 fr.src=NULL; 03249 fr.data = NULL ; 03250 fr.datalen = 0; 03251 fr.samples = 0 ; 03252 fr.mallocd =0 ; 03253 fr.offset= 0 ; 03254 03255 if (!ch->ignore_dtmf) { 03256 chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf); 03257 ast_queue_frame(ch->ast, &fr); 03258 } else { 03259 chan_misdn_log(2, bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", bc->dtmf); 03260 } 03261 } 03262 break; 03263 case EVENT_STATUS: 03264 break; 03265 03266 case EVENT_INFORMATION: 03267 { 03268 int stop_tone; 03269 misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int)); 03270 if ( stop_tone ) { 03271 stop_indicate(ch); 03272 } 03273 03274 if (ch->state == MISDN_WAITING4DIGS ) { 03275 /* Ok, incomplete Setup, waiting till extension exists */ 03276 { 03277 int l = sizeof(bc->dad); 03278 strncat(bc->dad,bc->info_dad, l); 03279 bc->dad[l-1] = 0; 03280 } 03281 03282 03283 { 03284 int l = sizeof(ch->ast->exten); 03285 strncpy(ch->ast->exten, bc->dad, l); 03286 ch->ast->exten[l-1] = 0; 03287 } 03288 /* chan_misdn_log(5, bc->port, "Can Match Extension: dad:%s oad:%s\n",bc->dad,bc->oad);*/ 03289 03290 /* Check for Pickup Request first */ 03291 if (!strcmp(ch->ast->exten, ast_pickup_ext())) { 03292 int ret;/** Sending SETUP_ACK**/ 03293 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03294 if (ast_pickup_call(ch->ast)) { 03295 hangup_chan(ch); 03296 } else { 03297 struct ast_channel *chan=ch->ast; 03298 ch->state = MISDN_CALLING_ACKNOWLEDGE; 03299 ast_setstate(chan, AST_STATE_DOWN); 03300 hangup_chan(ch); 03301 ch->ast=NULL; 03302 break; 03303 } 03304 } 03305 03306 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 03307 03308 chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n"); 03309 if (bc->nt) 03310 hanguptone_indicate(ch); 03311 ch->state=MISDN_EXTCANTMATCH; 03312 bc->out_cause=1; 03313 03314 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03315 03316 break; 03317 } 03318 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 03319 ch->state=MISDN_DIALING; 03320 03321 stop_indicate(ch); 03322 /* chan_misdn_log(1, bc->port, " --> * Starting Ast ctx:%s\n", ch->context);*/ 03323 if (pbx_start_chan(ch)<0) { 03324 hangup_chan(ch); 03325 03326 chan_misdn_log(-1, bc->port, "ast_pbx_start returned < 0 in INFO\n"); 03327 if (bc->nt) hanguptone_indicate(ch); 03328 03329 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03330 } 03331 } 03332 03333 } else { 03334 /* sending INFOS as DTMF-Frames :) */ 03335 struct ast_frame fr; 03336 fr.frametype = AST_FRAME_DTMF; 03337 fr.subclass = bc->info_dad[0] ; 03338 fr.src=NULL; 03339 fr.data = NULL ; 03340 fr.datalen = 0; 03341 fr.samples = 0 ; 03342 fr.mallocd =0 ; 03343 fr.offset= 0 ; 03344 03345 03346 int digits; 03347 misdn_cfg_get( 0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int)); 03348 if (ch->state != MISDN_CONNECTED ) { 03349 if (digits) { 03350 int l = sizeof(bc->dad); 03351 strncat(bc->dad,bc->info_dad, l); 03352 bc->dad[l-1] = 0; 03353 l = sizeof(ch->ast->exten); 03354 strncpy(ch->ast->exten, bc->dad, l); 03355 ch->ast->exten[l-1] = 0; 03356 03357 ast_cdr_update(ch->ast); 03358 } 03359 03360 ast_queue_frame(ch->ast, &fr); 03361 } 03362 } 03363 } 03364 break; 03365 case EVENT_SETUP: 03366 { 03367 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 03368 if (ch && ch->state != MISDN_NOTHING ) { 03369 chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n"); 03370 return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /* Ignore MSNs which are not in our List */ 03371 } 03372 } 03373 03374 03375 int msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad); 03376 if (!bc->nt && ! msn_valid) { 03377 chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n"); 03378 return RESPONSE_IGNORE_SETUP; /* Ignore MSNs which are not in our List */ 03379 } 03380 03381 print_bearer(bc); 03382 03383 { 03384 struct chan_list *ch=init_chan_list(ORG_MISDN); 03385 struct ast_channel *chan; 03386 03387 if (!ch) { chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n"); return 0;} 03388 03389 ch->bc = bc; 03390 ch->l3id=bc->l3_id; 03391 ch->addr=bc->addr; 03392 ch->orginator = ORG_MISDN; 03393 03394 chan=misdn_new(ch, AST_STATE_RESERVED,bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel); 03395 ch->ast = chan; 03396 03397 read_config(ch, ORG_MISDN); 03398 03399 export_ch(chan, bc, ch); 03400 03401 ch->ast->rings=1; 03402 ast_setstate(ch->ast, AST_STATE_RINGING); 03403 03404 int pres,screen; 03405 03406 switch (bc->pres) { 03407 case 1: 03408 pres=AST_PRES_RESTRICTED; chan_misdn_log(2,bc->port," --> PRES: Restricted (1)\n"); 03409 break; 03410 case 2: 03411 pres=AST_PRES_UNAVAILABLE; chan_misdn_log(2,bc->port," --> PRES: Restricted (2)\n"); 03412 break; 03413 default: 03414 pres=AST_PRES_ALLOWED; chan_misdn_log(2,bc->port," --> PRES: Restricted (%d)\n", bc->pres); 03415 } 03416 03417 switch (bc->screen) { 03418 case 0: 03419 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (0)\n"); 03420 break; 03421 case 1: 03422 screen=AST_PRES_USER_NUMBER_PASSED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: Passed screen (1)\n"); 03423 break; 03424 case 2: 03425 screen=AST_PRES_USER_NUMBER_FAILED_SCREEN; chan_misdn_log(2,bc->port," --> SCREEN: failed screen (2)\n"); 03426 break; 03427 case 3: 03428 screen=AST_PRES_NETWORK_NUMBER; chan_misdn_log(2,bc->port," --> SCREEN: Network Number (3)\n"); 03429 break; 03430 default: 03431 screen=AST_PRES_USER_NUMBER_UNSCREENED; chan_misdn_log(2,bc->port," --> SCREEN: Unscreened (%d)\n",bc->screen); 03432 } 03433 03434 chan->cid.cid_pres=pres+screen; 03435 03436 pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability)); 03437 chan->transfercapability=bc->capability; 03438 03439 switch (bc->capability) { 03440 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 03441 pbx_builtin_setvar_helper(chan,"CALLTYPE","DIGITAL"); 03442 break; 03443 default: 03444 pbx_builtin_setvar_helper(chan,"CALLTYPE","SPEECH"); 03445 } 03446 03447 /** queue new chan **/ 03448 cl_queue_chan(&cl_te, ch) ; 03449 03450 03451 if (!strstr(ch->allowed_bearers,"all")) { 03452 int i; 03453 for (i=0; i< sizeof(allowed_bearers_array)/sizeof(struct allowed_bearers); i++) { 03454 if (allowed_bearers_array[i].cap == bc->capability) { 03455 if ( !strstr( ch->allowed_bearers, allowed_bearers_array[i].name)) { 03456 chan_misdn_log(0,bc->port,"Bearer Not allowed\b"); 03457 bc->out_cause=88; 03458 03459 ch->state=MISDN_EXTCANTMATCH; 03460 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03461 return RESPONSE_OK; 03462 } 03463 } 03464 03465 } 03466 } 03467 03468 /* Check for Pickup Request first */ 03469 if (!strcmp(chan->exten, ast_pickup_ext())) { 03470 int ret;/** Sending SETUP_ACK**/ 03471 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03472 if (ast_pickup_call(chan)) { 03473 hangup_chan(ch); 03474 } else { 03475 ch->state = MISDN_CALLING_ACKNOWLEDGE; 03476 ast_setstate(chan, AST_STATE_DOWN); 03477 hangup_chan(ch); 03478 ch->ast=NULL; 03479 break; 03480 } 03481 } 03482 03483 /* 03484 added support for s extension hope it will help those poor cretains 03485 which haven't overlap dial. 03486 */ 03487 { 03488 int ai; 03489 misdn_cfg_get( bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai)); 03490 if ( ai ) { 03491 do_immediate_setup(bc, ch , chan); 03492 break; 03493 } 03494 03495 03496 03497 } 03498 03499 /* check if we should jump into s when we have no dad */ 03500 { 03501 int im; 03502 misdn_cfg_get( bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im)); 03503 if ( im && ast_strlen_zero(bc->dad) ) { 03504 do_immediate_setup(bc, ch , chan); 03505 break; 03506 } 03507 } 03508 03509 03510 chan_misdn_log(5,bc->port,"CONTEXT:%s\n",ch->context); 03511 if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 03512 03513 chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n"); 03514 03515 if (bc->nt) 03516 hanguptone_indicate(ch); 03517 ch->state=MISDN_EXTCANTMATCH; 03518 bc->out_cause=1; 03519 03520 if (bc->nt) 03521 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03522 else 03523 misdn_lib_send_event(bc, EVENT_RELEASE ); 03524 03525 break; 03526 } 03527 03528 if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) { 03529 ch->state=MISDN_DIALING; 03530 03531 if (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port)) ) { 03532 int ret; 03533 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03534 } else { 03535 int ret; 03536 ret= misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03537 } 03538 03539 if (pbx_start_chan(ch)<0) { 03540 hangup_chan(ch); 03541 03542 chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n"); 03543 chan=NULL; 03544 03545 if (bc->nt) { 03546 hanguptone_indicate(ch); 03547 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03548 } else 03549 misdn_lib_send_event(bc, EVENT_RELEASE); 03550 } 03551 } else { 03552 03553 if (bc->sending_complete) { 03554 ch->state=MISDN_EXTCANTMATCH; 03555 bc->out_cause=1; 03556 03557 if (bc->nt) { 03558 chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n"); 03559 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE); 03560 } else { 03561 chan_misdn_log(0,bc->port," --> sending_complete so we never match ..\n"); 03562 misdn_lib_send_event(bc, EVENT_RELEASE); 03563 } 03564 03565 } else { 03566 03567 int ret= misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03568 if (ret == -ENOCHAN) { 03569 ast_log(LOG_WARNING,"Channel was catched, before we could Acknowledge\n"); 03570 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 03571 } 03572 /* send tone to phone :) */ 03573 03574 /** ADD IGNOREPAT **/ 03575 03576 int stop_tone; 03577 misdn_cfg_get( 0, MISDN_GEN_STOP_TONE, &stop_tone, sizeof(int)); 03578 if ( (!ast_strlen_zero(bc->dad)) && stop_tone ) 03579 stop_indicate(ch); 03580 else { 03581 dialtone_indicate(ch); 03582 } 03583 03584 ch->state=MISDN_WAITING4DIGS; 03585 } 03586 } 03587 03588 } 03589 break; 03590 case EVENT_SETUP_ACKNOWLEDGE: 03591 { 03592 ch->state = MISDN_CALLING_ACKNOWLEDGE; 03593 if (!ast_strlen_zero(bc->infos_pending)) { 03594 /* TX Pending Infos */ 03595 03596 { 03597 int l = sizeof(bc->dad); 03598 strncat(bc->dad,bc->infos_pending, l - strlen(bc->dad)); 03599 bc->dad[l-1] = 0; 03600 } 03601 { 03602 int l = sizeof(ch->ast->exten); 03603 strncpy(ch->ast->exten, bc->dad, l); 03604 ch->ast->exten[l-1] = 0; 03605 } 03606 { 03607 int l = sizeof(bc->info_dad); 03608 strncpy(bc->info_dad, bc->infos_pending, l); 03609 bc->info_dad[l-1] = 0; 03610 } 03611 strncpy(bc->infos_pending,"", 1); 03612 03613 misdn_lib_send_event(bc, EVENT_INFORMATION); 03614 } 03615 } 03616 break; 03617 case EVENT_PROCEEDING: 03618 { 03619 03620 if ( misdn_cap_is_speech(bc->capability) && 03621 misdn_inband_avail(bc) ) { 03622 start_bc_tones(ch); 03623 } 03624 03625 ch->state = MISDN_PROCEEDING; 03626 03627 ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING); 03628 } 03629 break; 03630 case EVENT_PROGRESS: 03631 if (!bc->nt ) { 03632 if ( misdn_cap_is_speech(bc->capability) && 03633 misdn_inband_avail(bc) 03634 ) { 03635 start_bc_tones(ch); 03636 } 03637 03638 ast_queue_control(ch->ast, AST_CONTROL_PROGRESS); 03639 03640 ch->state=MISDN_PROGRESS; 03641 } 03642 break; 03643 03644 03645 case EVENT_ALERTING: 03646 { 03647 ch->state = MISDN_ALERTING; 03648 03649 ast_queue_control(ch->ast, AST_CONTROL_RINGING); 03650 ast_setstate(ch->ast, AST_STATE_RINGING); 03651 03652 cb_log(1,bc->port,"Set State Ringing\n"); 03653 03654 if ( misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) { 03655 cb_log(1,bc->port,"Starting Tones, we have inband Data\n"); 03656 start_bc_tones(ch); 03657 } else { 03658 cb_log(1,bc->port,"We have no inband Data, the other end must create ringing\n"); 03659 if (ch->far_alerting) { 03660 cb_log(1,bc->port,"The other end can not do ringing eh ?.. we must do all ourself.."); 03661 start_bc_tones(ch); 03662 /*tone_indicate(ch, TONE_FAR_ALERTING);*/ 03663 } 03664 } 03665 } 03666 break; 03667 case EVENT_CONNECT: 03668 { 03669 /*we answer when we've got our very new L3 ID from the NT stack */ 03670 misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE); 03671 03672 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast); 03673 03674 misdn_lib_echo(bc,0); 03675 stop_indicate(ch); 03676 03677 if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) { 03678 struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged); 03679 03680 chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad); 03681 if (bridged_ch) { 03682 bridged_ch->bc->cpnnumplan=bc->cpnnumplan; 03683 ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad)); 03684 } 03685 } 03686 } 03687 03688 03689 /* notice that we don't break here!*/ 03690 03691 case EVENT_CONNECT_ACKNOWLEDGE: 03692 { 03693 ch->l3id=bc->l3_id; 03694 ch->addr=bc->addr; 03695 03696 start_bc_tones(ch); 03697 03698 03699 ch->state = MISDN_CONNECTED; 03700 ast_queue_control(ch->ast, AST_CONTROL_ANSWER); 03701 } 03702 break; 03703 case EVENT_DISCONNECT: 03704 /*we might not have an ch->ast ptr here anymore*/ 03705 if (ch) { 03706 struct chan_list *holded_ch=find_holded(cl_te, bc); 03707 03708 chan_misdn_log(3,bc->port," --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state); 03709 if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { 03710 /* If there's inband information available (e.g. a 03711 recorded message saying what was wrong with the 03712 dialled number, or perhaps even giving an 03713 alternative number, then play it instead of 03714 immediately releasing the call */ 03715 chan_misdn_log(1,bc->port, " --> Inband Info Avail, not sending RELEASE\n"); 03716 03717 ch->state=MISDN_DISCONNECTED; 03718 start_bc_tones(ch); 03719 break; 03720 } 03721 03722 /*Check for holded channel, to implement transfer*/ 03723 if (holded_ch && ch->ast ) { 03724 cb_log(1,bc->port," --> found holded ch\n"); 03725 if (ch->state == MISDN_CONNECTED ) { 03726 misdn_transfer_bc(ch, holded_ch) ; 03727 } 03728 hangup_chan(ch); 03729 release_chan(bc); 03730 break; 03731 } 03732 03733 stop_bc_tones(ch); 03734 hangup_chan(ch); 03735 } 03736 bc->out_cause=-1; 03737 if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE); 03738 break; 03739 03740 case EVENT_RELEASE: 03741 { 03742 bc->out_cause=16; 03743 03744 hangup_chan(ch); 03745 release_chan(bc); 03746 03747 if (bc->need_release_complete) 03748 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 03749 } 03750 break; 03751 case EVENT_RELEASE_COMPLETE: 03752 { 03753 stop_bc_tones(ch); 03754 hangup_chan(ch); 03755 release_chan(bc); 03756 if(ch) 03757 ch->state=MISDN_CLEANING; 03758 } 03759 break; 03760 case EVENT_CLEANUP: 03761 { 03762 stop_bc_tones(ch); 03763 03764 switch(ch->state) { 03765 case MISDN_CALLING: 03766 bc->cause=27; /* Destination out of order */ 03767 break; 03768 default: 03769 break; 03770 } 03771 03772 hangup_chan(ch); 03773 release_chan(bc); 03774 } 03775 break; 03776 03777 case EVENT_TONE_GENERATE: 03778 { 03779 int tone_len=bc->tone_cnt; 03780 struct ast_channel *ast=ch->ast; 03781 void *tmp; 03782 int res; 03783 int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples); 03784 03785 chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n"); 03786 03787 if (!ast) break; 03788 03789 if (!ast->generator) break; 03790 03791 03792 03793 tmp = ast->generatordata; 03794 ast->generatordata = NULL; 03795 generate = ast->generator->generate; 03796 03797 if (tone_len <0 || tone_len > 512 ) { 03798 ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n",tone_len); 03799 tone_len=128; 03800 } 03801 03802 res = generate(ast, tmp, tone_len, tone_len); 03803 ast->generatordata = tmp; 03804 03805 if (res) { 03806 ast_log(LOG_WARNING, "Auto-deactivating generator\n"); 03807 ast_deactivate_generator(ast); 03808 } else { 03809 bc->tone_cnt=0; 03810 } 03811 } 03812 break; 03813 03814 case EVENT_BCHAN_DATA: 03815 { 03816 if ( !misdn_cap_is_speech(ch->bc->capability) ) { 03817 struct ast_frame frame; 03818 /*In Data Modes we queue frames*/ 03819 frame.frametype = AST_FRAME_VOICE; /*we have no data frames yet*/ 03820 frame.subclass = AST_FORMAT_ALAW; 03821 frame.datalen = bc->bframe_len; 03822 frame.samples = bc->bframe_len ; 03823 frame.mallocd =0 ; 03824 frame.offset= 0 ; 03825 frame.src = NULL; 03826 frame.data = bc->bframe ; 03827 03828 ast_queue_frame(ch->ast,&frame); 03829 } else { 03830 fd_set wrfs; 03831 struct timeval tv; 03832 tv.tv_sec=0; 03833 tv.tv_usec=0; 03834 03835 03836 FD_ZERO(&wrfs); 03837 FD_SET(ch->pipe[1],&wrfs); 03838 03839 int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv); 03840 03841 if (!t) { 03842 chan_misdn_log(9, bc->port, "Select Timed out\n"); 03843 break; 03844 } 03845 03846 if (t<0) { 03847 chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno)); 03848 break; 03849 } 03850 03851 if (FD_ISSET(ch->pipe[1],&wrfs)) { 03852 chan_misdn_log(9, bc->port, "writing %d bytes 2 asterisk\n",bc->bframe_len); 03853 int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len); 03854 03855 if (ret<=0) { 03856 chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno)); 03857 } 03858 } else { 03859 chan_misdn_log(1, bc->port, "Wripe Pipe full!\n"); 03860 } 03861 } 03862 } 03863 break; 03864 case EVENT_TIMEOUT: 03865 { 03866 if (ch && bc) 03867 chan_misdn_log(1,bc->port,"--> state: %s\n",misdn_get_ch_state(ch)); 03868 03869 switch (ch->state) { 03870 case MISDN_CALLING: 03871 case MISDN_DIALING: 03872 case MISDN_PROGRESS: 03873 case MISDN_ALERTING: 03874 case MISDN_PROCEEDING: 03875 case MISDN_CALLING_ACKNOWLEDGE: 03876 if (bc->nt) { 03877 bc->progress_indicator=8; 03878 hanguptone_indicate(ch); 03879 } 03880 03881 bc->out_cause=1; 03882 misdn_lib_send_event(bc,EVENT_DISCONNECT); 03883 break; 03884 03885 case MISDN_WAITING4DIGS: 03886 if (bc->nt) { 03887 bc->progress_indicator=8; 03888 bc->out_cause=1; 03889 hanguptone_indicate(ch); 03890 misdn_lib_send_event(bc,EVENT_DISCONNECT); 03891 } else { 03892 bc->out_cause=16; 03893 misdn_lib_send_event(bc,EVENT_RELEASE); 03894 } 03895 03896 break; 03897 03898 03899 case MISDN_CLEANING: 03900 chan_misdn_log(1,bc->port," --> in state cleaning .. so ingoring, the stack should clean it for us\n"); 03901 break; 03902 03903 default: 03904 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); 03905 } 03906 } 03907 break; 03908 03909 03910 /***************************/ 03911 /** Suplementary Services **/ 03912 /***************************/ 03913 case EVENT_RETRIEVE: 03914 { 03915 ch=find_holded(cl_te, bc); 03916 if (!ch) { 03917 ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n"); 03918 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 03919 break; 03920 } 03921 struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast); 03922 ch->state = MISDN_CONNECTED; 03923 03924 if (hold_ast) { 03925 ast_moh_stop(hold_ast); 03926 } 03927 03928 if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) 03929 misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT); 03930 03931 03932 } 03933 break; 03934 03935 case EVENT_HOLD: 03936 { 03937 int hold_allowed; 03938 misdn_cfg_get( bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int)); 03939 03940 if (!hold_allowed) { 03941 03942 chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n"); 03943 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 03944 break; 03945 } 03946 03947 #if 0 03948 { 03949 struct chan_list *holded_ch=find_holded(cl_te, bc); 03950 if (holded_ch) { 03951 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 03952 03953 chan_misdn_log(-1, bc->port, "We can't use RETRIEVE at the moment due to mISDN bug!\n"); 03954 break; 03955 } 03956 } 03957 #endif 03958 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast); 03959 03960 if (bridged){ 03961 struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged); 03962 ch->state = MISDN_HOLDED; 03963 ch->l3id = bc->l3_id; 03964 03965 bc->holded_bc=bridged_ch->bc; 03966 misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE); 03967 03968 ast_moh_start(bridged, NULL); 03969 } else { 03970 misdn_lib_send_event(bc, EVENT_HOLD_REJECT); 03971 chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n"); 03972 } 03973 } 03974 break; 03975 03976 case EVENT_FACILITY: 03977 print_facility(bc); 03978 03979 switch (bc->fac_type) { 03980 case FACILITY_CALLDEFLECT: 03981 { 03982 struct ast_channel *bridged=AST_BRIDGED_P(ch->ast); 03983 struct chan_list *ch; 03984 03985 if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) { 03986 ch=MISDN_ASTERISK_TECH_PVT(bridged); 03987 /*ch->state=MISDN_FACILITY_DEFLECTED;*/ 03988 if (ch->bc) { 03989 /* todo */ 03990 } 03991 03992 } 03993 03994 } 03995 03996 break; 03997 default: 03998 chan_misdn_log(1, bc->port," --> not yet handled\n"); 03999 } 04000 04001 break; 04002 04003 case EVENT_RESTART: 04004 04005 stop_bc_tones(ch); 04006 release_chan(bc); 04007 04008 break; 04009 04010 default: 04011 ast_log(LOG_NOTICE, "Got Unknown Event\n"); 04012 break; 04013 } 04014 04015 return RESPONSE_OK; 04016 }
int chan_misdn_jb_empty | ( | struct misdn_bchannel * | bc, | |
char * | buf, | |||
int | len | |||
) |
Definition at line 4463 of file chan_misdn.c.
References cl_te, find_chan_by_bc(), chan_list::jb, and misdn_jb_empty().
Referenced by load_module().
04464 { 04465 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 04466 04467 if (ch && ch->jb) { 04468 return misdn_jb_empty(ch->jb, buf, len); 04469 } 04470 04471 return -1; 04472 }
void chan_misdn_log | ( | int | level, | |
int | port, | |||
char * | tmpl, | |||
... | ||||
) | [static] |
Definition at line 4648 of file chan_misdn.c.
References ast_console_puts(), ast_log(), ast_strlen_zero(), 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_digit(), misdn_facility_exec(), misdn_fixup(), misdn_hangup(), misdn_indication(), misdn_jb_empty(), misdn_jb_fill(), misdn_jb_init(), misdn_new(), misdn_read(), misdn_request(), misdn_set_opt_exec(), misdn_show_cls(), misdn_transfer_bc(), misdn_write(), print_bearer(), print_facility(), process_ast_dsp(), read_config(), release_chan(), send_cause2ast(), stop_indicate(), and update_config().
04649 { 04650 if (! ((0 <= port) && (port <= max_ports))) { 04651 ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port); 04652 port=0; 04653 level=-1; 04654 } 04655 04656 va_list ap; 04657 char buf[1024]; 04658 char port_buf[8]; 04659 sprintf(port_buf,"P[%2d] ",port); 04660 04661 va_start(ap, tmpl); 04662 vsnprintf( buf, 1023, tmpl, ap ); 04663 va_end(ap); 04664 04665 if (level == -1) 04666 ast_log(LOG_WARNING, buf); 04667 04668 else if (misdn_debug_only[port] ? 04669 (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) 04670 : level <= misdn_debug[port]) { 04671 04672 ast_console_puts(port_buf); 04673 ast_console_puts(buf); 04674 } 04675 04676 if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) { 04677 time_t tm = time(NULL); 04678 char *tmp=ctime(&tm),*p; 04679 04680 FILE *fp= fopen(global_tracefile, "a+"); 04681 04682 p=strchr(tmp,'\n'); 04683 if (p) *p=':'; 04684 04685 if (!fp) { 04686 ast_console_puts("Error opening Tracefile: [ "); 04687 ast_console_puts(global_tracefile); 04688 ast_console_puts(" ] "); 04689 04690 ast_console_puts(strerror(errno)); 04691 ast_console_puts("\n"); 04692 return ; 04693 } 04694 04695 fputs(tmp,fp); 04696 fputs(" ", fp); 04697 fputs(port_buf,fp); 04698 fputs(" ", fp); 04699 fputs(buf, fp); 04700 04701 fclose(fp); 04702 } 04703 }
Definition at line 2843 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, list, chan_list::next, ast_imager::next, and chan_list::trans.
Referenced by misdn_hangup(), and release_chan().
02844 { 02845 if (chan->dsp) 02846 ast_dsp_free(chan->dsp); 02847 if (chan->trans) 02848 ast_translator_free_path(chan->trans); 02849 02850 02851 02852 ast_mutex_lock(&cl_te_lock); 02853 if (!*list) { 02854 ast_mutex_unlock(&cl_te_lock); 02855 return; 02856 } 02857 02858 if (*list == chan) { 02859 *list=(*list)->next; 02860 ast_mutex_unlock(&cl_te_lock); 02861 return ; 02862 } 02863 02864 { 02865 struct chan_list *help=*list; 02866 for (;help->next; help=help->next) { 02867 if (help->next == chan) { 02868 help->next=help->next->next; 02869 ast_mutex_unlock(&cl_te_lock); 02870 return; 02871 } 02872 } 02873 } 02874 02875 ast_mutex_unlock(&cl_te_lock); 02876 }
Definition at line 2827 of file chan_misdn.c.
References ast_mutex_lock(), ast_mutex_unlock(), chan_list::bc, chan_misdn_log(), cl_te_lock, list, and chan_list::next.
Referenced by cb_events(), and misdn_request().
02828 { 02829 chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan); 02830 02831 ast_mutex_lock(&cl_te_lock); 02832 if (!*list) { 02833 *list = chan; 02834 } else { 02835 struct chan_list *help=*list; 02836 for (;help->next; help=help->next); 02837 help->next=chan; 02838 } 02839 chan->next=NULL; 02840 ast_mutex_unlock(&cl_te_lock); 02841 }
static char* complete_ch | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1018 of file chan_misdn.c.
References complete_ch_helper().
01019 { 01020 return complete_ch_helper(line, word, pos, state, 3); 01021 }
static char* complete_ch_helper | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) | [static] |
Definition at line 994 of file chan_misdn.c.
References ast_channel_walk_locked(), ast_mutex_unlock(), ast_channel::lock, ast_channel::name, and strdup.
00995 { 00996 struct ast_channel *c; 00997 int which=0; 00998 char *ret; 00999 if (pos != rpos) 01000 return NULL; 01001 c = ast_channel_walk_locked(NULL); 01002 while(c) { 01003 if (!strncasecmp(word, c->name, strlen(word))) { 01004 if (++which > state) 01005 break; 01006 } 01007 ast_mutex_unlock(&c->lock); 01008 c = ast_channel_walk_locked(c); 01009 } 01010 if (c) { 01011 ret = strdup(c->name); 01012 ast_mutex_unlock(&c->lock); 01013 } else 01014 ret = NULL; 01015 return ret; 01016 }
static char* complete_debug_port | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1023 of file chan_misdn.c.
References strdup.
01024 { 01025 if (state) 01026 return NULL; 01027 01028 switch (pos) { 01029 case 4: if (*word == 'p') 01030 return strdup("port"); 01031 else if (*word == 'o') 01032 return strdup("only"); 01033 break; 01034 case 6: if (*word == 'o') 01035 return strdup("only"); 01036 break; 01037 } 01038 return NULL; 01039 }
void config_jitterbuffer | ( | struct chan_list * | ch | ) |
Definition at line 1283 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), chan_list::jb, chan_list::jb_len, chan_list::jb_upper_threshold, misdn_jb_destroy(), and misdn_jb_init().
Referenced by misdn_set_opt_exec(), and read_config().
01284 { 01285 struct misdn_bchannel *bc=ch->bc; 01286 int len=ch->jb_len, threshold=ch->jb_upper_threshold; 01287 01288 chan_misdn_log(5,bc->port, "config_jb: Called\n"); 01289 01290 if ( ! len ) { 01291 chan_misdn_log(1,bc->port, "config_jb: Deactivating Jitterbuffer\n"); 01292 bc->nojitter=1; 01293 } else { 01294 01295 if (len <=100 || len > 8000) { 01296 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); 01297 len=1000; 01298 } 01299 01300 if ( threshold > len ) { 01301 chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); 01302 } 01303 01304 if ( ch->jb) { 01305 cb_log(0,bc->port,"config_jb: We've got a Jitterbuffer Already on this port.\n"); 01306 misdn_jb_destroy(ch->jb); 01307 ch->jb=NULL; 01308 } 01309 01310 ch->jb=misdn_jb_init(len, threshold); 01311 01312 if (!ch->jb ) 01313 bc->nojitter=1; 01314 } 01315 }
void debug_numplan | ( | int | port, | |
int | numplan, | |||
char * | type | |||
) |
Definition at line 1318 of file chan_misdn.c.
References chan_misdn_log().
Referenced by read_config().
01319 { 01320 switch (numplan) { 01321 case NUMPLAN_INTERNATIONAL: 01322 chan_misdn_log(2, port, " --> %s: International\n",type); 01323 break; 01324 case NUMPLAN_NATIONAL: 01325 chan_misdn_log(2, port, " --> %s: National\n",type); 01326 break; 01327 case NUMPLAN_SUBSCRIBER: 01328 chan_misdn_log(2, port, " --> %s: Subscriber\n",type); 01329 break; 01330 case NUMPLAN_UNKNOWN: 01331 chan_misdn_log(2, port, " --> %s: Unknown\n",type); 01332 break; 01333 /* Maybe we should cut off the prefix if present ? */ 01334 default: 01335 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n "); 01336 break; 01337 } 01338 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 4218 of file chan_misdn.c.
References desc.
04219 { 04220 return desc; 04221 }
static int dialtone_indicate | ( | struct chan_list * | cl | ) | [static] |
AST INDICATIONS END
Definition at line 2355 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(), chan_list::norxtone, chan_list::notxtone, chan_list::ts, and ast_channel::zone.
Referenced by cb_events(), and do_immediate_setup().
02356 { 02357 const struct tone_zone_sound *ts= NULL; 02358 struct ast_channel *ast=cl->ast; 02359 02360 02361 int nd=0; 02362 misdn_cfg_get( cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd)); 02363 02364 if (nd) { 02365 chan_misdn_log(1,cl->bc->port,"Not sending Dialtone, because config wants it\n"); 02366 return 0; 02367 } 02368 02369 chan_misdn_log(3,cl->bc->port," --> Dial\n"); 02370 ts=ast_get_indication_tone(ast->zone,"dial"); 02371 cl->ts=ts; 02372 02373 if (ts) { 02374 cl->notxtone=0; 02375 cl->norxtone=0; 02376 ast_playtones_start(ast,0, ts->data, 0); 02377 chan_misdn_log(4,cl->bc->port,"Starting Playtones\n"); 02378 misdn_lib_tone_generator_start(cl->bc); 02379 } 02380 02381 return 0; 02382 }
static void do_immediate_setup | ( | struct misdn_bchannel * | bc, | |
struct chan_list * | ch, | |||
struct ast_channel * | ast | |||
) | [static] |
Definition at line 2997 of file chan_misdn.c.
References chan_list::ast, AST_CID_P, AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), chan_misdn_log(), ast_channel::context, ast_frame::data, ast_frame::datalen, dialtone_indicate(), ast_channel::exten, ast_frame::frametype, hangup_chan(), hanguptone_indicate(), chan_list::incoming_early_audio, ast_frame::mallocd, MISDN_ASTERISK_PVT, MISDN_ASTERISK_TECH_PVT, MISDN_DIALING, ast_frame::offset, ORG_MISDN, chan_list::orginator, pbx_start_chan(), ast_frame::samples, ast_frame::src, chan_list::state, and ast_frame::subclass.
Referenced by cb_events().
02998 { 02999 char predial[256]=""; 03000 char *p = predial; 03001 03002 struct ast_frame fr; 03003 03004 strncpy(predial, ast->exten, sizeof(predial) -1 ); 03005 03006 ch->state=MISDN_DIALING; 03007 03008 if (bc->nt) { 03009 int ret; 03010 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03011 } else { 03012 int ret; 03013 if ( misdn_lib_is_ptp(bc->port)) { 03014 ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE ); 03015 } else { 03016 ret = misdn_lib_send_event(bc, EVENT_PROCEEDING ); 03017 } 03018 } 03019 03020 if ( !bc->nt && (ch->orginator==ORG_MISDN) && !ch->incoming_early_audio ) 03021 chan_misdn_log(1,bc->port, " --> incoming_early_audio off\n"); 03022 else 03023 dialtone_indicate(ch); 03024 03025 chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, AST_CID_P(ast)); 03026 03027 strncpy(ast->exten,"s", 2); 03028 03029 if (pbx_start_chan(ch)<0) { 03030 ast=NULL; 03031 hangup_chan(ch); 03032 hanguptone_indicate(ch); 03033 03034 if (bc->nt) 03035 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE ); 03036 else 03037 misdn_lib_send_event(bc, EVENT_DISCONNECT ); 03038 } 03039 03040 03041 while (!ast_strlen_zero(p) ) { 03042 fr.frametype = AST_FRAME_DTMF; 03043 fr.subclass = *p ; 03044 fr.src=NULL; 03045 fr.data = NULL ; 03046 fr.datalen = 0; 03047 fr.samples = 0 ; 03048 fr.mallocd =0 ; 03049 fr.offset= 0 ; 03050 03051 if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) { 03052 ast_queue_frame(ch->ast, &fr); 03053 } 03054 p++; 03055 } 03056 }
void export_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Definition at line 3130 of file chan_misdn.c.
References chan_misdn_log(), and pbx_builtin_setvar_helper().
Referenced by cb_events().
03131 { 03132 char tmp[32]; 03133 03134 chan_misdn_log(1,bc->port,"EXPORT_PID: pid:%d\n",bc->pid); 03135 sprintf(tmp,"%d",bc->pid); 03136 pbx_builtin_setvar_helper(chan,"_MISDN_PID",tmp); 03137 }
static struct chan_list * find_chan_by_bc | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 2787 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), list, and chan_list::next.
Referenced by cb_events(), chan_misdn_jb_empty(), and release_chan().
02788 { 02789 struct chan_list *help=list; 02790 for (;help; help=help->next) { 02791 if (help->bc == bc) return help; 02792 } 02793 02794 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 02795 02796 return NULL; 02797 }
Definition at line 2799 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), list, and chan_list::next.
Referenced by import_ch().
02800 { 02801 struct chan_list *help=list; 02802 for (;help; help=help->next) { 02803 if (help->bc->pid == pid) return help; 02804 } 02805 02806 chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n",pid); 02807 02808 return NULL; 02809 }
static struct chan_list* find_holded | ( | struct chan_list * | list, | |
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 2811 of file chan_misdn.c.
References chan_list::bc, chan_misdn_log(), list, and chan_list::next.
Referenced by cb_events().
02812 { 02813 struct chan_list *help=list; 02814 02815 chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad); 02816 for (;help; help=help->next) { 02817 chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->bc->holded, help->bc->channel); 02818 if (help->bc->port == bc->port 02819 && help->bc->holded ) return help; 02820 } 02821 02822 chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad); 02823 02824 return NULL; 02825 }
static void free_robin_list | ( | void | ) | [static] |
Definition at line 226 of file chan_misdn.c.
References free_robin_list_r(), and robin.
Referenced by reload_config(), and unload_module().
00227 { 00228 free_robin_list_r(robin); 00229 robin = NULL; 00230 }
static void free_robin_list_r | ( | struct robin_list * | r | ) | [inline, static] |
Definition at line 217 of file chan_misdn.c.
References free, robin_list::group, and robin_list::next.
Referenced by free_robin_list().
00218 { 00219 if (r) { 00220 if (r->next) free_robin_list_r(r->next); 00221 if (r->group) free(r->group); 00222 free(r); 00223 } 00224 }
static struct chan_list* get_chan_by_ast | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 322 of file chan_misdn.c.
References chan_list::ast, cl_te, and chan_list::next.
Referenced by misdn_bridge().
00323 { 00324 struct chan_list *tmp; 00325 00326 for (tmp=cl_te; tmp; tmp = tmp->next) { 00327 if ( tmp->ast == ast ) return tmp; 00328 } 00329 00330 return NULL; 00331 }
static struct chan_list* get_chan_by_ast_name | ( | char * | name | ) | [static] |
Definition at line 333 of file chan_misdn.c.
References chan_list::ast, cl_te, ast_channel::name, and chan_list::next.
Referenced by misdn_send_cd(), misdn_send_digit(), misdn_send_display(), and misdn_toggle_echocancel().
00334 { 00335 struct chan_list *tmp; 00336 00337 for (tmp=cl_te; tmp; tmp = tmp->next) { 00338 if ( tmp->ast && strcmp(tmp->ast->name,name) == 0) return tmp; 00339 } 00340 00341 return NULL; 00342 }
static struct robin_list* get_robin_position | ( | char * | group | ) | [static] |
Definition at line 232 of file chan_misdn.c.
References calloc, robin_list::group, robin_list::next, robin_list::prev, robin, and strndup.
Referenced by misdn_request().
00233 { 00234 struct robin_list *iter = robin; 00235 for (; iter; iter = iter->next) { 00236 if (!strcasecmp(iter->group, group)) 00237 return iter; 00238 } 00239 struct robin_list *new = (struct robin_list *)calloc(1, sizeof(struct robin_list)); 00240 new->group = strndup(group, strlen(group)); 00241 new->channel = 1; 00242 if (robin) { 00243 new->next = robin; 00244 robin->prev = new; 00245 } 00246 robin = new; 00247 return robin; 00248 }
static void hangup_chan | ( | struct chan_list * | ch | ) | [static] |
Definition at line 2893 of file chan_misdn.c.
References chan_list::ast, ast_hangup(), ast_queue_hangup(), chan_list::bc, chan_list::need_hangup, chan_list::need_queue_hangup, and send_cause2ast().
02894 { 02895 if (!ch) { 02896 cb_log(1,0,"Cannot hangup chan, no ch\n"); 02897 return; 02898 } 02899 02900 cb_log(1,ch->bc?ch->bc->port:0,"hangup_chan\n"); 02901 02902 if (ch->need_hangup) 02903 { 02904 cb_log(1,ch->bc->port,"-> hangup\n"); 02905 send_cause2ast(ch->ast,ch->bc,ch); 02906 ch->need_hangup=0; 02907 ch->need_queue_hangup=0; 02908 if (ch->ast) 02909 ast_hangup(ch->ast); 02910 return; 02911 } 02912 02913 if (!ch->need_queue_hangup) { 02914 cb_log(1,ch->bc->port,"No need to queue hangup\n"); 02915 } 02916 02917 ch->need_queue_hangup=0; 02918 if (ch->ast) { 02919 send_cause2ast(ch->ast,ch->bc,ch); 02920 02921 if (ch->ast) 02922 ast_queue_hangup(ch->ast); 02923 cb_log(1,ch->bc->port,"-> queue_hangup\n"); 02924 } else { 02925 cb_log(1,ch->bc->port,"Cannot hangup chan, no ast\n"); 02926 } 02927 }
static int hanguptone_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2384 of file chan_misdn.c.
References chan_list::bc.
Referenced by cb_events(), do_immediate_setup(), misdn_hangup(), and misdn_indication().
02385 { 02386 misdn_lib_send_tone(cl->bc,TONE_HANGUP); 02387 return 0; 02388 }
void import_ch | ( | struct ast_channel * | chan, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) |
Definition at line 3115 of file chan_misdn.c.
References chan_misdn_log(), cl_te, find_chan_by_pid(), chan_list::other_ch, chan_list::other_pid, and pbx_builtin_getvar_helper().
Referenced by misdn_call().
03116 { 03117 char *tmp; 03118 tmp=pbx_builtin_getvar_helper(chan,"MISDN_PID"); 03119 if (tmp) { 03120 ch->other_pid=atoi(tmp); 03121 chan_misdn_log(1,bc->port,"IMPORT_PID: importing pid:%s\n",tmp); 03122 03123 if (ch->other_pid >0) { 03124 ch->other_ch=find_chan_by_pid(cl_te,ch->other_pid); 03125 if (ch->other_ch) ch->other_ch->other_ch=ch; 03126 } 03127 } 03128 }
static struct chan_list* init_chan_list | ( | int | orig | ) | [static] |
Definition at line 2421 of file chan_misdn.c.
References chan_misdn_log(), malloc, chan_list::need_busy, chan_list::need_hangup, chan_list::need_queue_hangup, and chan_list::orginator.
Referenced by cb_events(), and misdn_request().
02422 { 02423 struct chan_list *cl=malloc(sizeof(struct chan_list)); 02424 02425 if (!cl) { 02426 chan_misdn_log(-1, 0, "misdn_request: malloc failed!"); 02427 return NULL; 02428 } 02429 02430 memset(cl,0,sizeof(struct chan_list)); 02431 02432 cl->orginator=orig; 02433 cl->need_queue_hangup=1; 02434 cl->need_hangup=1; 02435 cl->need_busy=1; 02436 02437 return cl; 02438 02439 }
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 4223 of file chan_misdn.c.
References ASTERISK_GPL_KEY.
04224 { 04225 return ASTERISK_GPL_KEY; 04226 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 4030 of file chan_misdn.c.
References ast_channel_register(), ast_cli_register(), ast_log(), ast_mutex_init(), ast_register_application(), calloc, cb_events(), chan_misdn_jb_empty(), chan_misdn_log(), cl_te_lock, cli_port_block, cli_port_down, cli_port_unblock, cli_port_up, cli_reload, cli_restart_port, cli_send_cd, cli_send_digit, cli_send_display, cli_set_crypt_debug, cli_set_debug, cli_set_tics, cli_show_cl, cli_show_cls, cli_show_config, cli_show_port, cli_show_stacks, cli_toggle_echocancel, global_tracefile, LOG_ERROR, malloc, max_ports, misdn_cfg_get(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_cfg_update_ptp(), misdn_debug, misdn_debug_only, misdn_facility_exec(), misdn_set_opt_exec(), misdn_tech, misdn_type, tracing, and unload_module().
04031 { 04032 int i; 04033 04034 char ports[256]=""; 04035 04036 max_ports=misdn_lib_maxports_get(); 04037 04038 if (max_ports<=0) { 04039 ast_log(LOG_ERROR, "Unable to initialize mISDN\n"); 04040 return 0; 04041 } 04042 04043 04044 misdn_cfg_init(max_ports); 04045 g_config_initialized=1; 04046 04047 misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1)); 04048 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int)); 04049 for (i = 1; i <= max_ports; i++) 04050 misdn_debug[i] = misdn_debug[0]; 04051 misdn_debug_only = (int *)calloc(max_ports + 1, sizeof(int)); 04052 04053 04054 { 04055 char tempbuf[BUFFERSIZE+1]; 04056 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE); 04057 if (strlen(tempbuf)) 04058 tracing = 1; 04059 } 04060 04061 ast_mutex_init(&cl_te_lock); 04062 04063 misdn_cfg_update_ptp(); 04064 misdn_cfg_get_ports_string(ports); 04065 04066 if (strlen(ports)) 04067 chan_misdn_log(0, 0, "Got: %s from get_ports\n",ports); 04068 04069 { 04070 struct misdn_lib_iface iface = { 04071 .cb_event = cb_events, 04072 .cb_log = chan_misdn_log, 04073 .cb_jb_empty = chan_misdn_jb_empty, 04074 }; 04075 if (misdn_lib_init(ports, &iface, NULL)) 04076 chan_misdn_log(0, 0, "No te ports initialized\n"); 04077 04078 int ntflags=0; 04079 char ntfile[BUFFERSIZE+1]; 04080 04081 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int)); 04082 misdn_cfg_get( 0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE); 04083 04084 misdn_lib_nt_debug_init(ntflags,ntfile); 04085 04086 } 04087 04088 04089 { 04090 if (ast_channel_register(&misdn_tech)) { 04091 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type); 04092 unload_module(); 04093 return -1; 04094 } 04095 } 04096 04097 ast_cli_register(&cli_send_display); 04098 ast_cli_register(&cli_send_cd); 04099 ast_cli_register(&cli_send_digit); 04100 ast_cli_register(&cli_toggle_echocancel); 04101 ast_cli_register(&cli_set_tics); 04102 04103 ast_cli_register(&cli_show_cls); 04104 ast_cli_register(&cli_show_cl); 04105 ast_cli_register(&cli_show_config); 04106 ast_cli_register(&cli_show_port); 04107 ast_cli_register(&cli_show_stacks); 04108 04109 ast_cli_register(&cli_port_block); 04110 ast_cli_register(&cli_port_unblock); 04111 ast_cli_register(&cli_restart_port); 04112 ast_cli_register(&cli_port_up); 04113 ast_cli_register(&cli_port_down); 04114 ast_cli_register(&cli_set_debug); 04115 ast_cli_register(&cli_set_crypt_debug); 04116 ast_cli_register(&cli_reload); 04117 04118 04119 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", 04120 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n" 04121 "Sets mISDN opts. and optargs\n" 04122 "\n" 04123 "The available options are:\n" 04124 " d - Send display text on called phone, text is the optparam\n" 04125 " n - don't detect dtmf tones on called channel\n" 04126 " h - make digital outgoing call\n" 04127 " c - make crypted outgoing call, param is keyindex\n" 04128 " e - perform echo cancelation on this channel,\n" 04129 " takes taps as arguments (32,64,128,256)\n" 04130 " s - send Non Inband DTMF as inband\n" 04131 " vr - rxgain control\n" 04132 " vt - txgain control\n" 04133 ); 04134 04135 04136 ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility", 04137 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 04138 "Sends the Facility Message FACILITY_TYPE with \n" 04139 "the given Arguments to the current ISDN Channel\n" 04140 "Supported Facilities are:\n" 04141 "\n" 04142 "type=calldeflect args=Nr where to deflect\n" 04143 ); 04144 04145 04146 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 04147 04148 chan_misdn_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n"); 04149 04150 return 0; 04151 }
static int misdn_answer | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1681 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_queue_hangup(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, pbx_builtin_getvar_helper(), start_bc_tones(), chan_list::state, and stop_indicate().
01682 { 01683 struct chan_list *p; 01684 01685 01686 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 01687 01688 chan_misdn_log(1, p? (p->bc? p->bc->port : 0) : 0, "* ANSWER:\n"); 01689 01690 if (!p) { 01691 ast_log(LOG_WARNING, " --> Channel not connected ??\n"); 01692 ast_queue_hangup(ast); 01693 } 01694 01695 if (!p->bc) { 01696 chan_misdn_log(1, 0, " --> Got Answer, but theres no bc obj ??\n"); 01697 01698 ast_queue_hangup(ast); 01699 } 01700 01701 { 01702 const char *tmp_key = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY"); 01703 01704 if (tmp_key ) { 01705 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n"); 01706 { 01707 int l = sizeof(p->bc->crypt_key); 01708 strncpy(p->bc->crypt_key,tmp_key, l); 01709 p->bc->crypt_key[l-1] = 0; 01710 } 01711 } else { 01712 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n"); 01713 } 01714 01715 } 01716 01717 { 01718 const char *nodsp=pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS"); 01719 if (nodsp) { 01720 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n"); 01721 p->bc->nodsp=1; 01722 p->bc->hdlc=0; 01723 p->bc->nojitter=1; 01724 } 01725 } 01726 01727 p->state = MISDN_CONNECTED; 01728 misdn_lib_echo(p->bc,0); 01729 stop_indicate(p); 01730 01731 if ( ast_strlen_zero(p->bc->cad) ) { 01732 chan_misdn_log(2,p->bc->port," --> empty cad using dad\n"); 01733 ast_copy_string(p->bc->cad,p->bc->dad,sizeof(p->bc->cad)); 01734 } 01735 01736 misdn_lib_send_event( p->bc, EVENT_CONNECT); 01737 start_bc_tones(p); 01738 01739 return 0; 01740 }
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 | |||
) |
Definition at line 2246 of file chan_misdn.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_read(), ast_waitfor_n(), ast_write(), chan_list::bc, chan_misdn_log(), ast_channel::exten, ast_frame::frametype, get_chan_by_ast(), chan_list::ignore_dtmf, LOG_NOTICE, misdn_cfg_get(), and ast_frame::subclass.
02252 { 02253 struct chan_list *ch1,*ch2; 02254 struct ast_channel *carr[2], *who; 02255 int to=-1; 02256 struct ast_frame *f; 02257 02258 ch1=get_chan_by_ast(c0); 02259 ch2=get_chan_by_ast(c1); 02260 02261 carr[0]=c0; 02262 carr[1]=c1; 02263 02264 02265 if (ch1 && ch2 ) ; 02266 else 02267 return -1; 02268 02269 02270 int bridging; 02271 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 02272 if (bridging) { 02273 int ec; 02274 misdn_cfg_get( ch1->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int)); 02275 if ( ec ) { 02276 chan_misdn_log(2, ch1->bc->port, "Disabling Echo Cancellor when Bridged\n"); 02277 ch1->bc->ec_enable=0; 02278 manager_ec_disable(ch1->bc); 02279 } 02280 misdn_cfg_get( ch2->bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int)); 02281 if ( ec ) { 02282 chan_misdn_log(2, ch2->bc->port, "Disabling Echo Cancellor when Bridged\n"); 02283 ch2->bc->ec_enable=0; 02284 manager_ec_disable(ch2->bc); 02285 } 02286 02287 /* trying to make a mISDN_dsp conference */ 02288 chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid +1); 02289 02290 misdn_lib_bridge(ch1->bc,ch2->bc); 02291 } 02292 02293 chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad); 02294 02295 02296 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) ) 02297 ch1->ignore_dtmf=1; 02298 02299 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) ) 02300 ch2->ignore_dtmf=1; 02301 02302 02303 while(1) { 02304 to=-1; 02305 who = ast_waitfor_n(carr, 2, &to); 02306 02307 if (!who) { 02308 ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n"); 02309 break; 02310 } 02311 f = ast_read(who); 02312 02313 if (!f || f->frametype == AST_FRAME_CONTROL) { 02314 /* got hangup .. */ 02315 02316 if (!f) 02317 chan_misdn_log(1,ch1->bc->port,"Read Null Frame\n"); 02318 else 02319 chan_misdn_log(1,ch1->bc->port,"Read Frame Controll class:%d\n",f->subclass); 02320 02321 *fo=f; 02322 *rc=who; 02323 02324 break; 02325 } 02326 02327 if ( f->frametype == AST_FRAME_DTMF ) { 02328 chan_misdn_log(1,0,"Read DTMF %d from %s\n",f->subclass, who->exten); 02329 02330 *fo=f; 02331 *rc=who; 02332 break; 02333 } 02334 02335 02336 if (who == c0) { 02337 ast_write(c1,f); 02338 } 02339 else { 02340 ast_write(c0,f); 02341 } 02342 02343 } 02344 02345 chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1); 02346 02347 misdn_lib_split_bridge(ch1->bc,ch2->bc); 02348 02349 02350 return AST_BRIDGE_COMPLETE; 02351 }
static int misdn_call | ( | struct ast_channel * | ast, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 1552 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, AST_CID_P, ast_log(), ast_setstate(), AST_STATE_DIALING, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), chan_list::bc, chan_misdn_log(), ast_channel::context, ast_channel::exten, ast_channel::hangupcause, import_ch(), chan_list::l3id, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, misdn_set_opt_exec(), ast_channel::name, ORG_AST, pbx_builtin_setvar_helper(), chan_list::state, stop_bc_tones(), ast_channel::transfercapability, and update_config().
01553 { 01554 int port=0; 01555 int r; 01556 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 01557 struct misdn_bchannel *newbc; 01558 char *opts=NULL, *ext,*tokb; 01559 char dest_cp[256]; 01560 01561 { 01562 strncpy(dest_cp,dest,sizeof(dest_cp)-1); 01563 dest_cp[sizeof(dest_cp)]=0; 01564 01565 ext=strtok_r(dest_cp,"/",&tokb); 01566 01567 if (ext) { 01568 ext=strtok_r(NULL,"/",&tokb); 01569 if (ext) { 01570 opts=strtok_r(NULL,"/",&tokb); 01571 } else { 01572 chan_misdn_log(0,0,"misdn_call: No Extension given!\n"); 01573 return -1; 01574 } 01575 } 01576 } 01577 01578 if (!ast) { 01579 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n"); 01580 return -1; 01581 } 01582 01583 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) { 01584 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 01585 ast->hangupcause=41; 01586 ast_setstate(ast, AST_STATE_DOWN); 01587 return -1; 01588 } 01589 01590 if (!ch) { 01591 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 01592 ast->hangupcause=41; 01593 ast_setstate(ast, AST_STATE_DOWN); 01594 return -1; 01595 } 01596 01597 newbc=ch->bc; 01598 01599 if (!newbc) { 01600 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name); 01601 ast->hangupcause=41; 01602 ast_setstate(ast, AST_STATE_DOWN); 01603 return -1; 01604 } 01605 01606 port=newbc->port; 01607 strncpy(newbc->dad,ext,sizeof( newbc->dad)); 01608 strncpy(ast->exten,ext,sizeof(ast->exten)); 01609 01610 chan_misdn_log(1, port, "* CALL: %s\n",dest); 01611 01612 chan_misdn_log(1, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context); 01613 01614 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten); 01615 if (ast->exten) { 01616 int l = sizeof(newbc->dad); 01617 strncpy(newbc->dad,ast->exten, l); 01618 newbc->dad[l-1] = 0; 01619 } 01620 newbc->rad[0]=0; 01621 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast)); 01622 if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) { 01623 01624 if (AST_CID_P(ast)) { 01625 int l = sizeof(newbc->oad); 01626 strncpy(newbc->oad,AST_CID_P(ast), l); 01627 newbc->oad[l-1] = 0; 01628 } 01629 } 01630 01631 { 01632 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast); 01633 if (!ch) { ast_verbose("No chan_list in misdn_call"); return -1;} 01634 01635 newbc->capability=ast->transfercapability; 01636 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability)); 01637 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) { 01638 chan_misdn_log(2, port, " --> * Call with flag Digital\n"); 01639 } 01640 01641 01642 /* update screening and presentation */ 01643 update_config(ch,ORG_AST); 01644 01645 /* fill in some ies from channel vary*/ 01646 import_ch(ast, newbc, ch); 01647 01648 /* Finally The Options Override Everything */ 01649 if (opts) 01650 misdn_set_opt_exec(ast,opts); 01651 else 01652 chan_misdn_log(2,port,"NO OPTS GIVEN\n"); 01653 01654 ch->state=MISDN_CALLING; 01655 01656 r=misdn_lib_send_event( newbc, EVENT_SETUP ); 01657 01658 /** we should have l3id after sending setup **/ 01659 ch->l3id=newbc->l3_id; 01660 } 01661 01662 if ( r == -ENOCHAN ) { 01663 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n"); 01664 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1); 01665 ast->hangupcause=34; 01666 ast_setstate(ast, AST_STATE_DOWN); 01667 return -1; 01668 } 01669 01670 chan_misdn_log(1, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1); 01671 01672 ast_setstate(ast, AST_STATE_DIALING); 01673 ast->hangupcause=16; 01674 01675 if (newbc->nt) stop_bc_tones(ch); 01676 01677 return 0; 01678 }
static int misdn_digit | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 1742 of file chan_misdn.c.
References chan_list::ast, ast_log(), chan_list::bc, chan_misdn_log(), ast_channel::exten, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, MISDN_CALLING, MISDN_CALLING_ACKNOWLEDGE, send_digit_to_chan(), and chan_list::state.
01743 { 01744 struct chan_list *p; 01745 01746 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) return -1; 01747 01748 struct misdn_bchannel *bc=p->bc; 01749 chan_misdn_log(1, bc?bc->port:0, "* IND : Digit %c\n",digit); 01750 01751 if (!bc) { 01752 ast_log(LOG_WARNING, " --> !! Got Digit Event withut having bchannel Object\n"); 01753 return -1; 01754 } 01755 01756 switch (p->state ) { 01757 case MISDN_CALLING: 01758 { 01759 01760 char buf[8]; 01761 buf[0]=digit; 01762 buf[1]=0; 01763 01764 int l = sizeof(bc->infos_pending); 01765 strncat(bc->infos_pending,buf,l); 01766 bc->infos_pending[l-1] = 0; 01767 } 01768 break; 01769 case MISDN_CALLING_ACKNOWLEDGE: 01770 { 01771 bc->info_dad[0]=digit; 01772 bc->info_dad[1]=0; 01773 01774 { 01775 int l = sizeof(bc->dad); 01776 strncat(bc->dad,bc->info_dad, l - strlen(bc->dad)); 01777 bc->dad[l-1] = 0; 01778 } 01779 { 01780 int l = sizeof(p->ast->exten); 01781 strncpy(p->ast->exten, bc->dad, l); 01782 p->ast->exten[l-1] = 0; 01783 } 01784 01785 misdn_lib_send_event( bc, EVENT_INFORMATION); 01786 } 01787 break; 01788 01789 default: 01790 if ( bc->send_dtmf ) { 01791 send_digit_to_chan(p,digit); 01792 } 01793 break; 01794 } 01795 01796 return 0; 01797 }
static int misdn_facility_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 4233 of file chan_misdn.c.
References ast_log(), ast_strlen_zero(), chan_list::bc, chan_misdn_log(), LOG_WARNING, MISDN_ASTERISK_TECH_PVT, ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module().
04234 { 04235 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 04236 char *tok, *tokb; 04237 04238 chan_misdn_log(0,0,"TYPE: %s\n",chan->tech->type); 04239 04240 if (strcasecmp(chan->tech->type,"mISDN")) { 04241 ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n"); 04242 return -1; 04243 } 04244 04245 if (ast_strlen_zero((char *)data)) { 04246 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 04247 return -1; 04248 } 04249 04250 tok=strtok_r((char*)data,"|", &tokb) ; 04251 04252 if (!tok) { 04253 ast_log(LOG_WARNING, "misdn_facility Requires arguments\n"); 04254 return -1; 04255 } 04256 04257 if (!strcasecmp(tok,"calldeflect")) { 04258 tok=strtok_r(NULL,"|", &tokb) ; 04259 04260 if (!tok) { 04261 ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n"); 04262 } 04263 04264 misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok); 04265 04266 } else { 04267 ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok); 04268 } 04269 04270 return 0; 04271 04272 }
static int misdn_fixup | ( | struct ast_channel * | oldast, | |
struct ast_channel * | ast | |||
) | [static] |
Definition at line 1800 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, chan_misdn_log(), chan_list::l3id, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, misdn_get_ch_state(), and chan_list::state.
01801 { 01802 struct chan_list *p; 01803 01804 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1; 01805 01806 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); 01807 01808 p->ast = ast ; 01809 p->state=MISDN_CONNECTED; 01810 01811 return 0; 01812 }
static char* misdn_get_ch_state | ( | struct chan_list * | p | ) | [static] |
Definition at line 680 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().
00681 { 00682 int i; 00683 static char state[8]; 00684 00685 if( !p) return NULL; 00686 00687 for (i=0; i< sizeof(state_array)/sizeof(struct state_struct); i++) { 00688 if ( state_array[i].state == p->state) return state_array[i].txt; 00689 } 00690 00691 sprintf(state,"%d",p->state) ; 00692 00693 return state; 00694 }
static int misdn_hangup | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 1950 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, AST_CID_P, ast_log(), AST_STATE_RESERVED, chan_list::bc, chan_misdn_log(), cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, free, ast_channel::hangupcause, hanguptone_indicate(), chan_list::l3id, LOG_DEBUG, 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_PRECONNECTED, MISDN_PROCEEDING, MISDN_PROGRESS, MISDN_RELEASED, ast_channel::name, chan_list::need_hangup, chan_list::need_queue_hangup, ORG_AST, chan_list::orginator, pbx_builtin_getvar_helper(), chan_list::pipe, start_bc_tones(), chan_list::state, and stop_bc_tones().
01951 { 01952 struct chan_list *p; 01953 struct misdn_bchannel *bc=NULL; 01954 01955 ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name); 01956 01957 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) ) ) return -1; 01958 01959 if (!p) { 01960 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n"); 01961 return 0 ; 01962 } 01963 01964 bc=p->bc; 01965 01966 if (!bc) { 01967 ast_log(LOG_WARNING,"Hangup with private but no bc ?\n"); 01968 return 0; 01969 } 01970 01971 01972 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 01973 p->ast=NULL; 01974 01975 bc=p->bc; 01976 01977 if (ast->_state == AST_STATE_RESERVED) { 01978 /* between request and call */ 01979 ast_log(LOG_DEBUG, "State Reserved => chanIsAvail\n"); 01980 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 01981 01982 cl_dequeue_chan(&cl_te, p); 01983 01984 close(p->pipe[0]); 01985 close(p->pipe[1]); 01986 01987 free(p); 01988 if (bc) 01989 misdn_lib_release(bc); 01990 01991 return 0; 01992 } 01993 01994 p->need_hangup=0; 01995 p->need_queue_hangup=0; 01996 01997 01998 if (!p->bc->nt) 01999 stop_bc_tones(p); 02000 02001 02002 { 02003 const char *varcause=NULL; 02004 bc->out_cause=ast->hangupcause?ast->hangupcause:16; 02005 02006 if ( (varcause=pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) || 02007 (varcause=pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) { 02008 int tmpcause=atoi(varcause); 02009 bc->out_cause=tmpcause?tmpcause:16; 02010 } 02011 02012 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_P(ast), misdn_get_ch_state(p)); 02013 chan_misdn_log(2, bc->port, " --> l3id:%x\n",p->l3id); 02014 chan_misdn_log(1, bc->port, " --> cause:%d\n",bc->cause); 02015 chan_misdn_log(1, bc->port, " --> out_cause:%d\n",bc->out_cause); 02016 chan_misdn_log(1, bc->port, " --> state:%s\n", misdn_get_ch_state(p)); 02017 02018 switch (p->state) { 02019 case MISDN_CALLING: 02020 p->state=MISDN_CLEANING; 02021 misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); 02022 break; 02023 case MISDN_HOLDED: 02024 case MISDN_DIALING: 02025 start_bc_tones(p); 02026 hanguptone_indicate(p); 02027 02028 if (bc->need_disconnect) 02029 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02030 break; 02031 02032 case MISDN_CALLING_ACKNOWLEDGE: 02033 start_bc_tones(p); 02034 hanguptone_indicate(p); 02035 02036 if (bc->need_disconnect) 02037 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02038 break; 02039 02040 case MISDN_ALERTING: 02041 case MISDN_PROGRESS: 02042 case MISDN_PROCEEDING: 02043 if (p->orginator != ORG_AST) 02044 hanguptone_indicate(p); 02045 02046 /*p->state=MISDN_CLEANING;*/ 02047 if (bc->need_disconnect) 02048 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02049 break; 02050 case MISDN_CONNECTED: 02051 case MISDN_PRECONNECTED: 02052 /* Alerting or Disconect */ 02053 if (p->bc->nt) { 02054 start_bc_tones(p); 02055 hanguptone_indicate(p); 02056 p->bc->progress_indicator=8; 02057 } 02058 if (bc->need_disconnect) 02059 misdn_lib_send_event( bc, EVENT_DISCONNECT); 02060 02061 /*p->state=MISDN_CLEANING;*/ 02062 break; 02063 case MISDN_DISCONNECTED: 02064 misdn_lib_send_event( bc, EVENT_RELEASE); 02065 p->state=MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */ 02066 break; 02067 02068 case MISDN_RELEASED: 02069 case MISDN_CLEANING: 02070 p->state=MISDN_CLEANING; 02071 break; 02072 02073 case MISDN_BUSY: 02074 break; 02075 02076 case MISDN_HOLD_DISCONNECT: 02077 /* need to send release here */ 02078 chan_misdn_log(1, bc->port, " --> cause %d\n",bc->cause); 02079 chan_misdn_log(1, bc->port, " --> out_cause %d\n",bc->out_cause); 02080 02081 bc->out_cause=-1; 02082 misdn_lib_send_event(bc,EVENT_RELEASE); 02083 p->state=MISDN_CLEANING; 02084 break; 02085 default: 02086 if (bc->nt) { 02087 bc->out_cause=-1; 02088 misdn_lib_send_event(bc, EVENT_RELEASE); 02089 p->state=MISDN_CLEANING; 02090 } else { 02091 if (bc->need_disconnect) 02092 misdn_lib_send_event(bc, EVENT_DISCONNECT); 02093 } 02094 } 02095 02096 p->state=MISDN_CLEANING; 02097 02098 } 02099 02100 02101 chan_misdn_log(1, bc->port, "Channel: %s hanguped new state:%s\n",ast->name,misdn_get_ch_state(p)); 02102 02103 return 0; 02104 }
static int misdn_indication | ( | struct ast_channel * | ast, | |
int | cond | |||
) | [static] |
Definition at line 1816 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_setstate(), AST_STATE_BUSY, AST_STATE_RINGING, chan_list::bc, chan_misdn_log(), ast_channel::exten, hanguptone_indicate(), chan_list::incoming_early_audio, LOG_NOTICE, LOG_WARNING, MISDN_ALERTING, MISDN_ASTERISK_TECH_PVT, MISDN_CONNECTED, ast_channel::name, ORG_MISDN, chan_list::orginator, chan_list::other_ch, start_bc_tones(), chan_list::state, and stop_indicate().
01817 { 01818 struct chan_list *p; 01819 01820 01821 if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) { 01822 ast_log(LOG_WARNING, "Returnded -1 in misdn_indication\n"); 01823 return -1; 01824 } 01825 01826 if (!p->bc ) { 01827 chan_misdn_log(1, 0, "* IND : Indication from %s\n",ast->exten); 01828 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n"); 01829 return -1; 01830 } 01831 01832 chan_misdn_log(1, p->bc->port, "* IND : Indication [%d] from %s\n",cond, ast->exten); 01833 01834 switch (cond) { 01835 case AST_CONTROL_BUSY: 01836 chan_misdn_log(1, p->bc->port, "* IND :\tbusy\n"); 01837 chan_misdn_log(1, p->bc->port, " --> * SEND: State Busy pid:%d\n",p->bc?p->bc->pid:-1); 01838 ast_setstate(ast,AST_STATE_BUSY); 01839 01840 p->bc->out_cause=17; 01841 if (p->state != MISDN_CONNECTED) { 01842 start_bc_tones(p); 01843 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 01844 } else { 01845 chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name); 01846 } 01847 return -1; 01848 break; 01849 case AST_CONTROL_RING: 01850 chan_misdn_log(1, p->bc->port, " --> * IND :\tring pid:%d\n",p->bc?p->bc->pid:-1); 01851 return -1; 01852 break; 01853 01854 case AST_CONTROL_RINGING: 01855 switch (p->state) { 01856 case MISDN_ALERTING: 01857 chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n",p->bc?p->bc->pid:-1); 01858 break; 01859 case MISDN_CONNECTED: 01860 chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n",p->bc?p->bc->pid:-1); 01861 return -1; 01862 break; 01863 default: 01864 p->state=MISDN_ALERTING; 01865 chan_misdn_log(1, p->bc->port, " --> * IND :\tringing pid:%d\n",p->bc?p->bc->pid:-1); 01866 misdn_lib_send_event( p->bc, EVENT_ALERTING); 01867 01868 if (p->other_ch && p->other_ch->bc) { 01869 if (misdn_inband_avail(p->other_ch->bc)) { 01870 chan_misdn_log(1,p->bc->port, " --> other End is mISDN and has inband info available\n"); 01871 break; 01872 } 01873 01874 if (!p->other_ch->bc->nt) { 01875 chan_misdn_log(1,p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n"); 01876 break; 01877 } 01878 } 01879 01880 chan_misdn_log(1, p->bc->port, " --> * SEND: State Ring pid:%d\n",p->bc?p->bc->pid:-1); 01881 ast_setstate(ast,AST_STATE_RINGING); 01882 01883 if ( !p->bc->nt && (p->orginator==ORG_MISDN) && !p->incoming_early_audio ) 01884 chan_misdn_log(1,p->bc->port, " --> incoming_early_audio off\n"); 01885 else 01886 return -1; 01887 } 01888 break; 01889 case AST_CONTROL_ANSWER: 01890 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n",p->bc?p->bc->pid:-1); 01891 start_bc_tones(p); 01892 break; 01893 case AST_CONTROL_TAKEOFFHOOK: 01894 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n",p->bc?p->bc->pid:-1); 01895 return -1; 01896 break; 01897 case AST_CONTROL_OFFHOOK: 01898 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n",p->bc?p->bc->pid:-1); 01899 return -1; 01900 break; 01901 case AST_CONTROL_FLASH: 01902 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n",p->bc?p->bc->pid:-1); 01903 break; 01904 case AST_CONTROL_PROGRESS: 01905 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n",p->bc?p->bc->pid:-1); 01906 misdn_lib_send_event( p->bc, EVENT_PROGRESS); 01907 break; 01908 case AST_CONTROL_PROCEEDING: 01909 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n",p->bc?p->bc->pid:-1); 01910 misdn_lib_send_event( p->bc, EVENT_PROCEEDING); 01911 break; 01912 case AST_CONTROL_CONGESTION: 01913 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n",p->bc?p->bc->pid:-1); 01914 01915 p->bc->out_cause=42; 01916 if (p->state != MISDN_CONNECTED) { 01917 start_bc_tones(p); 01918 misdn_lib_send_event( p->bc, EVENT_RELEASE); 01919 } else { 01920 misdn_lib_send_event( p->bc, EVENT_DISCONNECT); 01921 } 01922 01923 if (p->bc->nt) { 01924 hanguptone_indicate(p); 01925 } 01926 break; 01927 case -1 : 01928 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n",p->bc?p->bc->pid:-1); 01929 01930 stop_indicate(p); 01931 01932 if (p->state == MISDN_CONNECTED) 01933 start_bc_tones(p); 01934 01935 break; 01936 01937 case AST_CONTROL_HOLD: 01938 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n",p->bc?p->bc->pid:-1); 01939 break; 01940 case AST_CONTROL_UNHOLD: 01941 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n",p->bc?p->bc->pid:-1); 01942 break; 01943 default: 01944 ast_log(LOG_NOTICE, " --> * Unknown Indication:%d pid:%d\n",cond,p->bc?p->bc->pid:-1); 01945 } 01946 01947 return 0; 01948 }
void misdn_jb_destroy | ( | struct misdn_jb * | jb | ) |
Definition at line 4516 of file chan_misdn.c.
References ast_mutex_destroy(), free, misdn_jb::mutexjb, and misdn_jb::samples.
Referenced by config_jitterbuffer(), and release_chan().
04517 { 04518 ast_mutex_destroy(&jb->mutexjb); 04519 04520 free(jb->samples); 04521 free(jb); 04522 }
int misdn_jb_empty | ( | struct misdn_jb * | jb, | |
char * | data, | |||
int | len | |||
) |
Definition at line 4588 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().
04589 { 04590 int i, wp, rp, read=0; 04591 04592 ast_mutex_lock (&jb->mutexjb); 04593 04594 rp=jb->rp; 04595 wp=jb->wp; 04596 04597 if(jb->state_empty) 04598 { 04599 for(i=0; i<len; i++) 04600 { 04601 if(wp==rp) 04602 { 04603 jb->rp=rp; 04604 jb->state_empty=0; 04605 04606 ast_mutex_unlock (&jb->mutexjb); 04607 04608 return read; 04609 } 04610 else 04611 { 04612 if(jb->ok[rp]==1) 04613 { 04614 data[i]=jb->samples[rp]; 04615 jb->ok[rp]=0; 04616 rp=(rp!=jb->size-1 ? rp+1 : 0); 04617 read+=1; 04618 } 04619 } 04620 } 04621 04622 if(wp >= rp) 04623 jb->state_buffer=wp-rp; 04624 else 04625 jb->state_buffer= jb->size-rp+wp; 04626 chan_misdn_log(9,0,"misdn_jb_empty: read:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 04627 04628 jb->rp=rp; 04629 } 04630 else 04631 chan_misdn_log(9,0,"misdn_jb_empty: Wait...requested:%d p:%x\n",len,jb); 04632 04633 ast_mutex_unlock (&jb->mutexjb); 04634 04635 return read; 04636 }
int misdn_jb_fill | ( | struct misdn_jb * | jb, | |
const char * | data, | |||
int | len | |||
) |
Definition at line 4526 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.
04527 { 04528 int i, j, rp, wp; 04529 04530 if (!jb || ! data) return 0; 04531 04532 ast_mutex_lock (&jb->mutexjb); 04533 04534 wp=jb->wp; 04535 rp=jb->rp; 04536 04537 for(i=0; i<len; i++) 04538 { 04539 jb->samples[wp]=data[i]; 04540 jb->ok[wp]=1; 04541 wp = (wp!=jb->size-1 ? wp+1 : 0); 04542 04543 if(wp==jb->rp) 04544 jb->state_full=1; 04545 } 04546 04547 if(wp>=rp) 04548 jb->state_buffer=wp-rp; 04549 else 04550 jb->state_buffer= jb->size-rp+wp; 04551 chan_misdn_log(9,0,"misdn_jb_fill: written:%d | Bufferstatus:%d p:%x\n",len,jb->state_buffer,jb); 04552 04553 if(jb->state_full) 04554 { 04555 jb->wp=wp; 04556 04557 rp=wp; 04558 for(j=0; j<jb->upper_threshold; j++) 04559 rp = (rp!=0 ? rp-1 : jb->size-1); 04560 jb->rp=rp; 04561 jb->state_full=0; 04562 jb->state_empty=1; 04563 04564 ast_mutex_unlock (&jb->mutexjb); 04565 04566 return -1; 04567 } 04568 04569 if(!jb->state_empty) 04570 { 04571 jb->bytes_wrote+=len; 04572 if(jb->bytes_wrote>=jb->upper_threshold) 04573 { 04574 jb->state_empty=1; 04575 jb->bytes_wrote=0; 04576 } 04577 } 04578 jb->wp=wp; 04579 04580 ast_mutex_unlock (&jb->mutexjb); 04581 04582 return 0; 04583 }
struct misdn_jb * misdn_jb_init | ( | int | size, | |
int | upper_threshold | |||
) |
Definition at line 4482 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().
04483 { 04484 int i; 04485 struct misdn_jb *jb = (struct misdn_jb*) malloc(sizeof(struct misdn_jb)); 04486 jb->size = size; 04487 jb->upper_threshold = upper_threshold; 04488 jb->wp = 0; 04489 jb->rp = 0; 04490 jb->state_full = 0; 04491 jb->state_empty = 0; 04492 jb->bytes_wrote = 0; 04493 jb->samples = (char *)malloc(size*sizeof(char)); 04494 04495 if (!jb->samples) { 04496 chan_misdn_log(-1,0,"No free Mem for jb->samples\n"); 04497 return NULL; 04498 } 04499 04500 jb->ok = (char *)malloc(size*sizeof(char)); 04501 04502 if (!jb->ok) { 04503 chan_misdn_log(-1,0,"No free Mem for jb->ok\n"); 04504 return NULL; 04505 } 04506 04507 for(i=0; i<size; i++) 04508 jb->ok[i]=0; 04509 04510 ast_mutex_init(&jb->mutexjb); 04511 04512 return jb; 04513 }
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 2662 of file chan_misdn.c.
References ast_callerid_parse(), ast_channel_alloc(), ast_setstate(), AST_STATE_RING, ast_strlen_zero(), chan_misdn_log(), ast_channel::cid, ast_callerid::cid_name, cid_name, ast_callerid::cid_num, cid_num, ast_channel::exten, ast_channel::fds, misdn_cfg_get(), misdn_tech, misdn_tech_wo_bridge, misdn_type, ast_channel::name, ast_channel::nativeformats, chan_list::pipe, prefformat, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, and ast_channel::writeformat.
Referenced by cb_events(), and misdn_request().
02663 { 02664 struct ast_channel *tmp; 02665 02666 tmp = ast_channel_alloc(1); 02667 02668 if (tmp) { 02669 chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid); 02670 02671 02672 if (c<=0) { 02673 c=glob_channel++; 02674 snprintf(tmp->name, sizeof(tmp->name), "%s/%d-u%d", 02675 misdn_type, port, c); 02676 } else { 02677 snprintf(tmp->name, sizeof(tmp->name), "%s/%d-%d", 02678 misdn_type, port, c); 02679 } 02680 02681 tmp->type = misdn_type; 02682 02683 tmp->nativeformats = prefformat; 02684 02685 tmp->readformat = format; 02686 tmp->rawreadformat = format; 02687 tmp->writeformat = format; 02688 tmp->rawwriteformat = format; 02689 02690 tmp->tech_pvt = chlist; 02691 02692 int bridging; 02693 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int)); 02694 if (bridging) 02695 tmp->tech = &misdn_tech; 02696 else 02697 tmp->tech = &misdn_tech_wo_bridge; 02698 02699 tmp->writeformat = format; 02700 tmp->readformat = format; 02701 tmp->priority=1; 02702 02703 if (exten) 02704 ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); 02705 else 02706 chan_misdn_log(1,0,"misdn_new: no exten given.\n"); 02707 02708 if (callerid) { 02709 char *cid_name, *cid_num; 02710 02711 ast_callerid_parse(callerid, &cid_name, &cid_num); 02712 02713 if (!ast_strlen_zero(cid_num)) 02714 tmp->cid.cid_num = strdup(cid_num); 02715 if (!ast_strlen_zero(cid_name)) 02716 tmp->cid.cid_name = strdup(cid_name); 02717 } 02718 02719 { 02720 if (pipe(chlist->pipe)<0) 02721 perror("Pipe failed\n"); 02722 02723 tmp->fds[0]=chlist->pipe[0]; 02724 02725 } 02726 02727 ast_setstate(tmp, state); 02728 if (state == AST_STATE_RING) 02729 tmp->rings = 1; 02730 else 02731 tmp->rings = 0; 02732 02733 02734 } else { 02735 chan_misdn_log(-1,0,"Unable to allocate channel structure\n"); 02736 } 02737 02738 return tmp; 02739 }
static int misdn_port_block | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 528 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00529 { 00530 int port; 00531 00532 if (argc != 4) 00533 return RESULT_SHOWUSAGE; 00534 00535 port = atoi(argv[3]); 00536 00537 misdn_lib_port_block(port); 00538 00539 return 0; 00540 }
static int misdn_port_down | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 585 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00586 { 00587 int port; 00588 00589 if (argc != 4) 00590 return RESULT_SHOWUSAGE; 00591 00592 port = atoi(argv[3]); 00593 00594 misdn_lib_get_port_down(port); 00595 00596 return 0; 00597 }
static int misdn_port_unblock | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 542 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00543 { 00544 int port; 00545 00546 if (argc != 4) 00547 return RESULT_SHOWUSAGE; 00548 00549 port = atoi(argv[3]); 00550 00551 misdn_lib_port_unblock(port); 00552 00553 return 0; 00554 }
static int misdn_port_up | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 571 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00572 { 00573 int port; 00574 00575 if (argc != 4) 00576 return RESULT_SHOWUSAGE; 00577 00578 port = atoi(argv[3]); 00579 00580 misdn_lib_get_port_up(port); 00581 00582 return 0; 00583 }
static struct ast_frame* misdn_read | ( | struct ast_channel * | ast | ) | [static] |
Definition at line 2106 of file chan_misdn.c.
References chan_list::ast, 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, chan_list::faxdetect, chan_list::frame, ast_frame::frametype, ast_frame::mallocd, MISDN_ASTERISK_TECH_PVT, ast_frame::offset, chan_list::pipe, process_ast_dsp(), ast_frame::samples, ast_frame::src, and ast_frame::subclass.
02107 { 02108 struct chan_list *tmp; 02109 int len; 02110 02111 if (!ast) { 02112 chan_misdn_log(1,0,"misdn_read called without ast\n"); 02113 return NULL; 02114 } 02115 if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) { 02116 chan_misdn_log(1,0,"misdn_read called without ast->pvt\n"); 02117 return NULL; 02118 } 02119 if (!tmp->bc) { 02120 chan_misdn_log(1,0,"misdn_read called without bc\n"); 02121 return NULL; 02122 } 02123 02124 len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf)); 02125 02126 if (len<=0) { 02127 /* we hangup here, since our pipe is closed */ 02128 chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n"); 02129 return NULL; 02130 } 02131 02132 tmp->frame.frametype = AST_FRAME_VOICE; 02133 tmp->frame.subclass = AST_FORMAT_ALAW; 02134 tmp->frame.datalen = len; 02135 tmp->frame.samples = len ; 02136 tmp->frame.mallocd =0 ; 02137 tmp->frame.offset= 0 ; 02138 tmp->frame.src = NULL; 02139 tmp->frame.data = tmp->ast_rd_buf ; 02140 02141 if (tmp->faxdetect || tmp->ast_dsp ) { 02142 return process_ast_dsp(tmp, &tmp->frame); 02143 } 02144 02145 return &tmp->frame; 02146 }
static int misdn_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 714 of file chan_misdn.c.
References ast_cli(), and reload_config().
00715 { 00716 ast_cli(fd, "Reloading mISDN Config\n"); 00717 reload_config(); 00718 return 0; 00719 }
static struct ast_channel* misdn_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 2441 of file chan_misdn.c.
References chan_list::ast, ast_log(), AST_STATE_RESERVED, ast_strlen_zero(), chan_list::bc, chan_misdn_log(), robin_list::channel, cl_queue_chan(), cl_te, get_robin_position(), group, init_chan_list(), LOG_WARNING, misdn_cfg_get(), misdn_cfg_get_next_port(), misdn_cfg_get_next_port_spin(), misdn_cfg_is_group_method(), misdn_new(), misdn_type, chan_list::need_hangup, ORG_AST, robin_list::port, and read_config().
02443 { 02444 struct ast_channel *tmp = NULL; 02445 char group[BUFFERSIZE+1]=""; 02446 char buf[128]; 02447 char buf2[128], *ext=NULL, *port_str; 02448 char *tokb=NULL, *p=NULL; 02449 int channel=0, port=0; 02450 struct misdn_bchannel *newbc = NULL; 02451 02452 struct chan_list *cl=init_chan_list(ORG_AST); 02453 02454 sprintf(buf,"%s/%s",misdn_type,(char*)data); 02455 ast_copy_string(buf2,data, 128); 02456 02457 port_str=strtok_r(buf2,"/", &tokb); 02458 02459 ext=strtok_r(NULL,"/", &tokb); 02460 02461 if (port_str) { 02462 if (port_str[0]=='g' && port_str[1]==':' ) { 02463 /* We make a group call lets checkout which ports are in my group */ 02464 port_str += 2; 02465 strncpy(group, port_str, BUFFERSIZE); 02466 group[127] = 0; 02467 chan_misdn_log(2, 0, " --> Group Call group: %s\n",group); 02468 } 02469 else if ((p = strchr(port_str, ':'))) { 02470 /* we have a preselected channel */ 02471 *p = 0; 02472 channel = atoi(++p); 02473 port = atoi(port_str); 02474 chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel); 02475 } 02476 else { 02477 port = atoi(port_str); 02478 } 02479 02480 02481 } else { 02482 ast_log(LOG_WARNING, " --> ! IND : CALL dad:%s WITHOUT PORT/Group, check extension.conf\n",ext); 02483 return NULL; 02484 } 02485 02486 if (!ast_strlen_zero(group)) { 02487 02488 char cfg_group[BUFFERSIZE+1]; 02489 struct robin_list *rr = NULL; 02490 02491 if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) { 02492 chan_misdn_log(4, port, " --> STARTING ROUND ROBIN..."); 02493 rr = get_robin_position(group); 02494 } 02495 02496 if (rr) { 02497 int robin_channel = rr->channel; 02498 int port_start; 02499 int next_chan = 1; 02500 02501 do { 02502 port_start = 0; 02503 for (port = misdn_cfg_get_next_port_spin(rr->port); port > 0 && port != port_start; 02504 port = misdn_cfg_get_next_port_spin(port)) { 02505 02506 if (!port_start) 02507 port_start = port; 02508 02509 if (port >= port_start) 02510 next_chan = 1; 02511 02512 if (port <= port_start && next_chan) { 02513 int maxbchans=misdn_lib_get_maxchans(port); 02514 if (++robin_channel >= maxbchans) { 02515 robin_channel = 1; 02516 } 02517 next_chan = 0; 02518 } 02519 02520 misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 02521 02522 if (!strcasecmp(cfg_group, group)) { 02523 int port_up; 02524 int check; 02525 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 02526 port_up = misdn_lib_port_up(port, check); 02527 02528 if (check && !port_up) 02529 chan_misdn_log(1,port,"L1 is not Up on this Port\n"); 02530 02531 if (check && port_up<0) { 02532 ast_log(LOG_WARNING,"This port (%d) is blocked\n", port); 02533 } 02534 02535 02536 if ( port_up>0 ) { 02537 newbc = misdn_lib_get_free_bc(port, robin_channel); 02538 if (newbc) { 02539 chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); 02540 if (port_up) 02541 chan_misdn_log(4, port, "portup:%d\n", port_up); 02542 rr->port = newbc->port; 02543 rr->channel = newbc->channel; 02544 break; 02545 } 02546 } 02547 } 02548 } 02549 } while (!newbc && robin_channel != rr->channel); 02550 02551 if (!newbc) 02552 chan_misdn_log(-1, port, " Failed! No free channel in group %d!", group); 02553 } 02554 02555 else { 02556 for (port=misdn_cfg_get_next_port(0); port > 0; 02557 port=misdn_cfg_get_next_port(port)) { 02558 02559 misdn_cfg_get( port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE); 02560 02561 chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port); 02562 if (!strcasecmp(cfg_group, group)) { 02563 int port_up; 02564 int check; 02565 misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); 02566 port_up = misdn_lib_port_up(port, check); 02567 02568 chan_misdn_log(4, port, "portup:%d\n", port_up); 02569 02570 if ( port_up>0 ) { 02571 newbc = misdn_lib_get_free_bc(port, 0); 02572 if (newbc) 02573 break; 02574 } 02575 } 02576 } 02577 } 02578 02579 } else { 02580 if (channel) 02581 chan_misdn_log(1, port," --> preselected_channel: %d\n",channel); 02582 newbc = misdn_lib_get_free_bc(port, channel); 02583 } 02584 02585 if (!newbc) { 02586 chan_misdn_log(-1, 0, "Could not create channel on port:%d with extensions:%s\n",port,ext); 02587 return NULL; 02588 } 02589 02590 /* create ast_channel and link all the objects together */ 02591 cl->bc=newbc; 02592 02593 tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel); 02594 cl->ast=tmp; 02595 02596 /* register chan in local list */ 02597 cl_queue_chan(&cl_te, cl) ; 02598 02599 /* fill in the config into the objects */ 02600 read_config(cl, ORG_AST); 02601 02602 /* important */ 02603 cl->need_hangup=0; 02604 02605 return tmp; 02606 }
static int misdn_restart_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 557 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00558 { 00559 int port; 00560 00561 if (argc != 4) 00562 return RESULT_SHOWUSAGE; 00563 00564 port = atoi(argv[3]); 00565 00566 misdn_lib_port_restart(port); 00567 00568 return 0; 00569 }
static int misdn_send_cd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 865 of file chan_misdn.c.
References ast_cli(), chan_list::bc, get_chan_by_ast_name(), and RESULT_SHOWUSAGE.
00866 { 00867 char *channame; 00868 char *nr; 00869 00870 if (argc != 5) 00871 return RESULT_SHOWUSAGE; 00872 00873 channame = argv[3]; 00874 nr = argv[4]; 00875 00876 ast_cli(fd, "Sending Calldeflection (%s) to %s\n",nr, channame); 00877 00878 { 00879 struct chan_list *tmp=get_chan_by_ast_name(channame); 00880 00881 if (!tmp) { 00882 ast_cli(fd, "Sending CD with nr %s to %s failed Channel does not exist\n",nr, channame); 00883 return 0; 00884 } else { 00885 00886 misdn_lib_send_facility(tmp->bc, FACILITY_CALLDEFLECT, nr); 00887 } 00888 } 00889 00890 return 0; 00891 }
static int misdn_send_digit | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 893 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().
00894 { 00895 char *channame; 00896 char *msg; 00897 00898 if (argc != 5) 00899 return RESULT_SHOWUSAGE; 00900 00901 channame = argv[3]; 00902 msg = argv[4]; 00903 00904 ast_cli(fd, "Sending %s to %s\n",msg, channame); 00905 00906 { 00907 struct chan_list *tmp=get_chan_by_ast_name(channame); 00908 00909 if (!tmp) { 00910 ast_cli(fd, "Sending %s to %s failed Channel does not exist\n",msg, channame); 00911 return 0; 00912 } else { 00913 #if 1 00914 int i; 00915 int msglen = strlen(msg); 00916 for (i=0; i<msglen; i++) { 00917 ast_cli(fd, "Sending: %c\n",msg[i]); 00918 send_digit_to_chan(tmp, msg[i]); 00919 /* res = ast_safe_sleep(tmp->ast, 250); */ 00920 usleep(250000); 00921 /* res = ast_waitfor(tmp->ast,100); */ 00922 } 00923 #else 00924 int res; 00925 res = ast_dtmf_stream(tmp->ast,NULL,msg,250); 00926 #endif 00927 } 00928 } 00929 00930 return 0; 00931 }
static int misdn_send_display | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 966 of file chan_misdn.c.
References ast_cli(), chan_list::bc, get_chan_by_ast_name(), RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
00967 { 00968 char *channame; 00969 char *msg; 00970 00971 if (argc != 5) 00972 return RESULT_SHOWUSAGE; 00973 00974 channame = argv[3]; 00975 msg = argv[4]; 00976 00977 ast_cli(fd, "Sending %s to %s\n",msg, channame); 00978 { 00979 struct chan_list *tmp; 00980 tmp=get_chan_by_ast_name(channame); 00981 00982 if (tmp && tmp->bc) { 00983 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display)); 00984 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 00985 } else { 00986 ast_cli(fd,"No such channel %s\n",channame); 00987 return RESULT_FAILURE; 00988 } 00989 } 00990 00991 return RESULT_SUCCESS ; 00992 }
int misdn_send_text | ( | struct ast_channel * | chan, | |
const char * | text | |||
) |
Definition at line 2609 of file chan_misdn.c.
References ast_log(), chan_list::bc, LOG_WARNING, and ast_channel::tech_pvt.
02610 { 02611 struct chan_list *tmp=chan->tech_pvt; 02612 02613 if (tmp && tmp->bc) { 02614 ast_copy_string(tmp->bc->display,text,sizeof(tmp->bc->display)); 02615 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION); 02616 } else { 02617 ast_log(LOG_WARNING, "No chan_list but send_text request?\n"); 02618 return -1; 02619 } 02620 02621 return 0; 02622 }
static int misdn_set_crypt_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 520 of file chan_misdn.c.
References RESULT_SHOWUSAGE.
00521 { 00522 if (argc != 5) return RESULT_SHOWUSAGE; 00523 00524 return 0; 00525 }
static int misdn_set_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 463 of file chan_misdn.c.
References ast_cli(), max_ports, misdn_debug, misdn_debug_only, and RESULT_SHOWUSAGE.
00464 { 00465 if (argc != 4 && argc != 5 && argc != 6 && argc != 7) 00466 return RESULT_SHOWUSAGE; 00467 00468 int level = atoi(argv[3]); 00469 00470 switch (argc) { 00471 case 4: 00472 case 5: { 00473 int only = 0; 00474 if (argc == 5) { 00475 if (strncasecmp(argv[4], "only", strlen(argv[4]))) 00476 return RESULT_SHOWUSAGE; 00477 else 00478 only = 1; 00479 } 00480 int i; 00481 for (i=0; i<=max_ports; i++) { 00482 misdn_debug[i] = level; 00483 misdn_debug_only[i] = only; 00484 } 00485 ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":""); 00486 } 00487 break; 00488 case 6: 00489 case 7: { 00490 if (strncasecmp(argv[4], "port", strlen(argv[4]))) 00491 return RESULT_SHOWUSAGE; 00492 int port = atoi(argv[5]); 00493 if (port <= 0 || port > max_ports) { 00494 switch (max_ports) { 00495 case 0: 00496 ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n"); 00497 break; 00498 case 1: 00499 ast_cli(fd, "port number not valid! only port 1 is availble.\n"); 00500 break; 00501 default: 00502 ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports); 00503 } 00504 return 0; 00505 } 00506 if (argc == 7) { 00507 if (strncasecmp(argv[6], "only", strlen(argv[6]))) 00508 return RESULT_SHOWUSAGE; 00509 else 00510 misdn_debug_only[port] = 1; 00511 } else 00512 misdn_debug_only[port] = 0; 00513 misdn_debug[port] = level; 00514 ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port); 00515 } 00516 } 00517 return 0; 00518 }
static int misdn_set_opt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 4275 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, chan_misdn_log(), config_jitterbuffer(), DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_FAX_DETECT, chan_list::faxdetect, chan_list::jb_len, chan_list::jb_upper_threshold, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_key_vector, misdn_key_vector_size, chan_list::orginator, rxgain, ast_channel::tech, txgain, and ast_channel_tech::type.
Referenced by load_module(), and misdn_call().
04276 { 04277 struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan); 04278 char *tok,*tokb; 04279 int keyidx=0; 04280 int rxgain=0; 04281 int txgain=0; 04282 int change_jitter=0; 04283 04284 if (strcasecmp(chan->tech->type,"mISDN")) { 04285 ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n"); 04286 return -1; 04287 } 04288 04289 if (ast_strlen_zero((char *)data)) { 04290 ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n"); 04291 return -1; 04292 } 04293 04294 for (tok=strtok_r((char*)data, ":",&tokb); 04295 tok; 04296 tok=strtok_r(NULL,":",&tokb) ) { 04297 int neglect=0; 04298 04299 if (tok[0] == '!' ) { 04300 neglect=1; 04301 tok++; 04302 } 04303 04304 switch(tok[0]) { 04305 04306 case 'd' : 04307 ast_copy_string(ch->bc->display,++tok,84); 04308 chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n",ch->bc->display); 04309 break; 04310 04311 case 'n': 04312 chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n"); 04313 ch->bc->nodsp=1; 04314 break; 04315 04316 case 'j': 04317 chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n"); 04318 tok++; 04319 change_jitter=1; 04320 04321 switch ( tok[0] ) { 04322 case 'b' : 04323 ch->jb_len=atoi(++tok); 04324 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n",ch->jb_len); 04325 break; 04326 case 't' : 04327 ch->jb_upper_threshold=atoi(++tok); 04328 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n",ch->jb_upper_threshold); 04329 break; 04330 04331 case 'n': 04332 ch->bc->nojitter=1; 04333 chan_misdn_log(1, ch->bc->port, " --> nojitter\n"); 04334 break; 04335 04336 default: 04337 ch->jb_len=4000; 04338 ch->jb_upper_threshold=0; 04339 chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n",ch->jb_len); 04340 chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n",ch->jb_upper_threshold); 04341 } 04342 04343 break; 04344 04345 case 'v': 04346 tok++; 04347 04348 switch ( tok[0] ) { 04349 case 'r' : 04350 rxgain=atoi(++tok); 04351 if (rxgain<-8) rxgain=-8; 04352 if (rxgain>8) rxgain=8; 04353 ch->bc->rxgain=rxgain; 04354 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",rxgain); 04355 break; 04356 case 't': 04357 txgain=atoi(++tok); 04358 if (txgain<-8) txgain=-8; 04359 if (txgain>8) txgain=8; 04360 ch->bc->txgain=txgain; 04361 chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n",txgain); 04362 break; 04363 } 04364 break; 04365 04366 case 'c': 04367 keyidx=atoi(++tok); 04368 04369 if (keyidx > misdn_key_vector_size || keyidx < 0 ) { 04370 ast_log(LOG_WARNING, "You entered the keyidx: %d but we have only %d keys\n",keyidx, misdn_key_vector_size ); 04371 continue; 04372 } 04373 04374 { 04375 ast_copy_string(ch->bc->crypt_key, misdn_key_vector[keyidx], sizeof(ch->bc->crypt_key)); 04376 } 04377 04378 chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n",misdn_key_vector[keyidx]); 04379 break; 04380 04381 case 'e': 04382 chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n"); 04383 04384 if (neglect) { 04385 chan_misdn_log(1, ch->bc->port, " --> disabled\n"); 04386 ch->bc->ec_enable=0; 04387 04388 } else { 04389 ch->bc->ec_enable=1; 04390 ch->bc->orig=ch->orginator; 04391 tok++; 04392 if (tok) { 04393 ch->bc->ec_deftaps=atoi(tok); 04394 } 04395 } 04396 04397 break; 04398 04399 case 'h': 04400 chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n"); 04401 04402 if (strlen(tok) > 1 && tok[1]=='1') { 04403 chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n"); 04404 ch->bc->hdlc=1; 04405 } 04406 ch->bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 04407 break; 04408 04409 case 's': 04410 chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n"); 04411 ch->bc->send_dtmf=1; 04412 break; 04413 04414 case 'f': 04415 chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n"); 04416 ch->faxdetect=1; 04417 break; 04418 04419 case 'a': 04420 chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n"); 04421 ch->ast_dsp=1; 04422 break; 04423 04424 case 'p': 04425 chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n",&tok[1]); 04426 /* CRICH: callingpres!!! */ 04427 if (strstr(tok,"allowed") ) { 04428 ch->bc->pres=0; 04429 } else if (strstr(tok,"not_screened")) { 04430 ch->bc->pres=1; 04431 } 04432 04433 04434 break; 04435 04436 04437 default: 04438 break; 04439 } 04440 } 04441 04442 if (change_jitter) 04443 config_jitterbuffer(ch); 04444 04445 04446 if (ch->faxdetect || ch->ast_dsp) { 04447 04448 if (!ch->dsp) ch->dsp = ast_dsp_new(); 04449 if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT); 04450 if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW); 04451 } 04452 04453 if (ch->ast_dsp) { 04454 chan_misdn_log(1,ch->bc->port,"SETOPT: with AST_DSP we deactivate mISDN_dsp\n"); 04455 ch->bc->nodsp=1; 04456 ch->bc->nojitter=1; 04457 } 04458 04459 return 0; 04460 }
static int misdn_set_tics | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 818 of file chan_misdn.c.
References MAXTICS, and RESULT_SHOWUSAGE.
00819 { 00820 if (argc != 4) 00821 return RESULT_SHOWUSAGE; 00822 00823 MAXTICS=atoi(argv[3]); 00824 00825 return 0; 00826 }
static int misdn_show_cl | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 792 of file chan_misdn.c.
References chan_list::ast, chan_list::bc, cl_te, ast_channel::name, chan_list::next, print_bc_info(), and RESULT_SHOWUSAGE.
00793 { 00794 struct chan_list *help=cl_te; 00795 00796 if (argc != 4) 00797 return RESULT_SHOWUSAGE; 00798 00799 for (;help; help=help->next) { 00800 struct misdn_bchannel *bc=help->bc; 00801 struct ast_channel *ast=help->ast; 00802 00803 if (bc && ast) { 00804 if (!strcasecmp(ast->name,argv[3])) { 00805 print_bc_info(fd, help, bc); 00806 break; 00807 } 00808 } 00809 } 00810 00811 00812 return 0; 00813 }
static int misdn_show_cls | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 768 of file chan_misdn.c.
References chan_list::ast, AST_CID_P, ast_cli(), chan_list::bc, chan_misdn_log(), cl_te, ast_channel::exten, chan_list::holded_bc, misdn_debug, chan_list::next, and print_bc_info().
00769 { 00770 struct chan_list *help=cl_te; 00771 00772 ast_cli(fd,"Chan List: %p\n",cl_te); 00773 00774 for (;help; help=help->next) { 00775 struct misdn_bchannel *bc=help->bc; 00776 struct ast_channel *ast=help->ast; 00777 if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast); 00778 if (bc) { 00779 print_bc_info(fd, help, bc); 00780 } else if ( (bc=help->holded_bc) ) { 00781 chan_misdn_log(0, 0, "ITS A HOLDED BC:\n"); 00782 print_bc_info(fd, help, bc); 00783 } else { 00784 ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast)); 00785 } 00786 } 00787 00788 00789 return 0; 00790 }
static int misdn_show_config | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 600 of file chan_misdn.c.
References ast_cli(), misdn_cfg_get_config_string(), misdn_cfg_get_next_port(), misdn_cfg_is_port_valid(), and RESULT_SHOWUSAGE.
00601 { 00602 char buffer[BUFFERSIZE]; 00603 enum misdn_cfg_elements elem; 00604 int linebreak; 00605 00606 int onlyport = -1; 00607 if (argc >= 4) { 00608 if (!sscanf(argv[3], "%d", &onlyport) || onlyport < 0) { 00609 ast_cli(fd, "Unknown option: %s\n", argv[3]); 00610 return RESULT_SHOWUSAGE; 00611 } 00612 } 00613 00614 if (argc == 3 || onlyport == 0) { 00615 ast_cli(fd,"Misdn General-Config: \n"); 00616 ast_cli(fd," -> Version: chan_misdn-" CHAN_MISDN_VERSION "\n"); 00617 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) { 00618 misdn_cfg_get_config_string( 0, elem, buffer, BUFFERSIZE); 00619 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00620 } 00621 ast_cli(fd, "\n"); 00622 } 00623 00624 if (onlyport < 0) { 00625 int port = misdn_cfg_get_next_port(0); 00626 for (; port > 0; port = misdn_cfg_get_next_port(port)) { 00627 ast_cli(fd, "\n[PORT %d]\n", port); 00628 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 00629 misdn_cfg_get_config_string( port, elem, buffer, BUFFERSIZE); 00630 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00631 } 00632 ast_cli(fd, "\n"); 00633 } 00634 } 00635 00636 if (onlyport > 0) { 00637 if (misdn_cfg_is_port_valid(onlyport)) { 00638 ast_cli(fd, "[PORT %d]\n", onlyport); 00639 for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) { 00640 misdn_cfg_get_config_string( onlyport, elem, buffer, BUFFERSIZE); 00641 ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : ""); 00642 } 00643 ast_cli(fd, "\n"); 00644 } else { 00645 ast_cli(fd, "Port %d is not active!\n", onlyport); 00646 } 00647 } 00648 return 0; 00649 }
static int misdn_show_port | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 846 of file chan_misdn.c.
References ast_cli(), misdn_debug, misdn_debug_only, and RESULT_SHOWUSAGE.
00847 { 00848 int port; 00849 00850 if (argc != 4) 00851 return RESULT_SHOWUSAGE; 00852 00853 port = atoi(argv[3]); 00854 00855 ast_cli(fd, "BEGIN STACK_LIST:\n"); 00856 00857 char buf[128]; 00858 get_show_stack_details(port,buf); 00859 ast_cli(fd," %s Debug:%d%s\n",buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); 00860 00861 00862 return 0; 00863 }
static int misdn_show_stacks | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 828 of file chan_misdn.c.
References ast_cli(), misdn_cfg_get_next_port(), misdn_debug, and misdn_debug_only.
00829 { 00830 int port; 00831 00832 ast_cli(fd, "BEGIN STACK_LIST:\n"); 00833 00834 for (port=misdn_cfg_get_next_port(0); port > 0; 00835 port=misdn_cfg_get_next_port(port)) { 00836 char buf[128]; 00837 get_show_stack_details(port,buf); 00838 ast_cli(fd," %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port]?"(only)":""); 00839 } 00840 00841 00842 return 0; 00843 00844 }
static int misdn_toggle_echocancel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 933 of file chan_misdn.c.
References ast_cli(), chan_list::bc, get_chan_by_ast_name(), RESULT_SHOWUSAGE, chan_list::toggle_ec, and update_ec_config().
00934 { 00935 char *channame; 00936 00937 if (argc != 4) 00938 return RESULT_SHOWUSAGE; 00939 00940 channame = argv[3]; 00941 00942 ast_cli(fd, "Toggling EchoCancel on %s\n", channame); 00943 00944 { 00945 struct chan_list *tmp=get_chan_by_ast_name(channame); 00946 00947 if (!tmp) { 00948 ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame); 00949 return 0; 00950 } else { 00951 00952 tmp->toggle_ec=tmp->toggle_ec?0:1; 00953 00954 if (tmp->toggle_ec) { 00955 update_ec_config(tmp->bc); 00956 manager_ec_enable(tmp->bc); 00957 } else { 00958 manager_ec_disable(tmp->bc); 00959 } 00960 } 00961 } 00962 00963 return 0; 00964 }
static void misdn_transfer_bc | ( | struct chan_list * | tmp_ch, | |
struct chan_list * | holded_chan | |||
) | [static] |
Definition at line 2983 of file chan_misdn.c.
References chan_list::ast, AST_BRIDGED_P, ast_channel_masquerade(), ast_moh_stop(), chan_list::bc, chan_misdn_log(), chan_list::holded_bc, MISDN_CONNECTED, MISDN_HOLD_DISCONNECT, ast_channel::name, and chan_list::state.
02984 { 02985 chan_misdn_log(4,0,"TRANSFERING %s to %s\n",holded_chan->ast->name, tmp_ch->ast->name); 02986 02987 tmp_ch->state=MISDN_HOLD_DISCONNECT; 02988 02989 ast_moh_stop(AST_BRIDGED_P(holded_chan->ast)); 02990 02991 holded_chan->state=MISDN_CONNECTED; 02992 misdn_lib_transfer(holded_chan->bc?holded_chan->bc:holded_chan->holded_bc); 02993 ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast)); 02994 }
static int misdn_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 2149 of file chan_misdn.c.
References chan_list::ast, ast_log(), chan_list::bc, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, chan_list::dropped_frame_cnt, ast_channel::exten, chan_list::frame, LOG_WARNING, MISDN_ASTERISK_TECH_PVT, misdn_get_ch_state(), MISDN_HOLDED, chan_list::notxtone, prefformat, ast_frame::samples, chan_list::state, and ast_frame::subclass.
02150 { 02151 struct chan_list *ch; 02152 int i = 0; 02153 02154 if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1; 02155 02156 if (!ch->bc ) { 02157 ast_log(LOG_WARNING, "private but no bc\n"); 02158 return -1; 02159 } 02160 02161 if (ch->state == MISDN_HOLDED) { 02162 chan_misdn_log(8, ch->bc->port, "misdn_write: Returning because holded\n"); 02163 return 0; 02164 } 02165 02166 if (ch->notxtone) { 02167 chan_misdn_log(9, ch->bc->port, "misdn_write: Returning because notxone\n"); 02168 return 0; 02169 } 02170 02171 02172 if ( !frame->subclass) { 02173 chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n"); 02174 return 0; 02175 } 02176 02177 if ( !(frame->subclass & prefformat)) { 02178 02179 chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass); 02180 return 0; 02181 } 02182 02183 02184 if ( !frame->samples ) { 02185 chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n"); 02186 return 0; 02187 } 02188 02189 if ( ! ch->bc->addr ) { 02190 chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples); 02191 return 0; 02192 } 02193 02194 #if MISDN_DEBUG 02195 { 02196 int i, max=5>frame->samples?frame->samples:5; 02197 02198 printf("write2mISDN %p %d bytes: ", p, frame->samples); 02199 02200 for (i=0; i< max ; i++) printf("%2.2x ",((char*) frame->data)[i]); 02201 printf ("\n"); 02202 } 02203 #endif 02204 02205 02206 switch (ch->bc->bc_state) { 02207 case BCHAN_ACTIVATED: 02208 case BCHAN_BRIDGED: 02209 break; 02210 default: 02211 if (!ch->dropped_frame_cnt) 02212 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\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state); 02213 02214 ch->dropped_frame_cnt++; 02215 if (ch->dropped_frame_cnt > 100) { 02216 ch->dropped_frame_cnt=0; 02217 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); 02218 02219 } 02220 02221 return 0; 02222 } 02223 02224 chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples); 02225 02226 if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) { 02227 /* Buffered Transmit (triggert by read from isdn side)*/ 02228 if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) { 02229 if (ch->bc->active) 02230 cb_log(0,ch->bc->port,"Misdn Jitterbuffer Overflow.\n"); 02231 } 02232 02233 } else { 02234 /*transmit without jitterbuffer*/ 02235 i=misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples); 02236 } 02237 02238 02239 02240 return 0; 02241 }
int pbx_start_chan | ( | struct chan_list * | ch | ) |
Channel Queue End
Definition at line 2881 of file chan_misdn.c.
References chan_list::ast, ast_pbx_start(), and chan_list::need_hangup.
Referenced by cb_events(), and do_immediate_setup().
02882 { 02883 int ret=ast_pbx_start(ch->ast); 02884 02885 if (ret>=0) 02886 ch->need_hangup=0; 02887 else 02888 ch->need_hangup=1; 02889 02890 return ret; 02891 }
static void print_bc_info | ( | int | fd, | |
struct chan_list * | help, | |||
struct misdn_bchannel * | bc | |||
) | [static] |
Definition at line 721 of file chan_misdn.c.
References chan_list::addr, chan_list::ast, AST_CID_P, ast_cli(), bearer2str(), ast_channel::exten, chan_list::holded_bc, chan_list::l3id, misdn_debug, misdn_get_ch_state(), ast_channel::name, chan_list::norxtone, chan_list::notxtone, ORG_AST, and chan_list::orginator.
Referenced by misdn_show_cl(), and misdn_show_cls().
00722 { 00723 struct ast_channel *ast=help->ast; 00724 ast_cli(fd, 00725 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n", 00726 00727 bc->pid, bc->port, bc->channel, 00728 bc->nt?"NT":"TE", 00729 help->orginator == ORG_AST?"*":"I", 00730 ast?ast->exten:NULL, 00731 ast?AST_CID_P(ast):NULL, 00732 bc->rad, 00733 ast?ast->context:NULL, 00734 misdn_get_ch_state(help) 00735 ); 00736 if (misdn_debug[bc->port] > 0) 00737 ast_cli(fd, 00738 " --> astname: %s\n" 00739 " --> ch_l3id: %x\n" 00740 " --> ch_addr: %x\n" 00741 " --> bc_addr: %x\n" 00742 " --> bc_l3id: %x\n" 00743 " --> display: %s\n" 00744 " --> activated: %d\n" 00745 " --> state: %s\n" 00746 " --> capability: %s\n" 00747 " --> echo_cancel: %d\n" 00748 " --> notone : rx %d tx:%d\n" 00749 " --> bc_hold: %d holded_bc :%d\n", 00750 help->ast->name, 00751 help->l3id, 00752 help->addr, 00753 bc->addr, 00754 bc?bc->l3_id:-1, 00755 bc->display, 00756 00757 bc->active, 00758 bc_state2str(bc->bc_state), 00759 bearer2str(bc->capability), 00760 bc->ec_enable, 00761 00762 help->norxtone,help->notxtone, 00763 bc->holded, help->holded_bc?1:0 00764 ); 00765 00766 }
static void print_bearer | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 410 of file chan_misdn.c.
References bearer2str(), and chan_misdn_log().
Referenced by cb_events().
00411 { 00412 00413 chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability)); 00414 00415 switch(bc->law) { 00416 case INFO_CODEC_ALAW: 00417 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n"); 00418 break; 00419 case INFO_CODEC_ULAW: 00420 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n"); 00421 break; 00422 } 00423 }
static void print_facility | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 393 of file chan_misdn.c.
References chan_misdn_log().
00394 { 00395 switch (bc->fac_type) { 00396 case FACILITY_CALLDEFLECT: 00397 chan_misdn_log(2,bc->port," --> calldeflect: %s\n", 00398 bc->fac.calldeflect_nr); 00399 break; 00400 case FACILITY_CENTREX: 00401 chan_misdn_log(2,bc->port," --> centrex: %s\n", 00402 bc->fac.cnip); 00403 break; 00404 default: 00405 chan_misdn_log(2,bc->port," --> unknown\n"); 00406 00407 } 00408 }
Definition at line 2742 of file chan_misdn.c.
References chan_list::ast, ast_async_goto(), AST_CID_P, chan_list::ast_dsp, ast_dsp_process(), ast_exists_extension(), AST_FRAME_DTMF, AST_FRAME_NULL, ast_log(), ast_strlen_zero(), ast_translate(), ast_verbose(), chan_list::bc, chan_misdn_log(), ast_channel::context, chan_list::dsp, ast_channel::exten, chan_list::faxdetect, chan_list::faxhandled, ast_frame::frametype, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_channel::name, option_verbose, pbx_builtin_setvar_helper(), ast_frame::subclass, chan_list::trans, and VERBOSE_PREFIX_3.
Referenced by misdn_read().
02743 { 02744 struct ast_frame *f,*f2; 02745 if (tmp->trans) 02746 f2=ast_translate(tmp->trans, frame,0); 02747 else { 02748 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n"); 02749 return NULL; 02750 } 02751 02752 f = ast_dsp_process(tmp->ast, tmp->dsp, f2); 02753 if (f && (f->frametype == AST_FRAME_DTMF)) { 02754 ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass); 02755 if (f->subclass == 'f' && tmp->faxdetect) { 02756 /* Fax tone -- Handle and return NULL */ 02757 struct ast_channel *ast = tmp->ast; 02758 if (!tmp->faxhandled) { 02759 tmp->faxhandled++; 02760 if (strcmp(ast->exten, "fax")) { 02761 if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) { 02762 if (option_verbose > 2) 02763 ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); 02764 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ 02765 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); 02766 if (ast_async_goto(ast, ast->context, "fax", 1)) 02767 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context); 02768 } else 02769 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten); 02770 } else 02771 ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); 02772 } else 02773 ast_log(LOG_DEBUG, "Fax already handled\n"); 02774 02775 } else if ( tmp->ast_dsp) { 02776 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass); 02777 return f; 02778 } 02779 } 02780 02781 frame->frametype = AST_FRAME_NULL; 02782 frame->subclass = 0; 02783 return frame; 02784 }
static int read_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
Definition at line 1361 of file chan_misdn.c.
References chan_list::allowed_bearers, chan_list::ast, ast_log(), ast_print_group(), ast_set_callerid(), ast_strlen_zero(), chan_list::bc, ast_channel::callgroup, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_rdnis, config_jitterbuffer(), ast_channel::context, chan_list::context, debug_numplan(), ast_channel::exten, chan_list::far_alerting, chan_list::incoming_early_audio, chan_list::jb_len, chan_list::jb_upper_threshold, ast_channel::language, LOG_WARNING, misdn_cfg_get(), ast_channel::musicclass, musicclass, ORG_AST, ast_channel::pickupgroup, strdup, and update_ec_config().
Referenced by cb_events(), and misdn_request().
01361 { 01362 01363 if (!ch) { 01364 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01365 return -1; 01366 } 01367 01368 struct ast_channel *ast=ch->ast; 01369 struct misdn_bchannel *bc=ch->bc; 01370 if (! ast || ! bc ) { 01371 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01372 return -1; 01373 } 01374 01375 int port=bc->port; 01376 01377 chan_misdn_log(5,port,"read_config: Getting Config\n"); 01378 01379 char lang[BUFFERSIZE+1]; 01380 01381 misdn_cfg_get( port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE); 01382 ast_copy_string(ast->language, lang, sizeof(ast->language)); 01383 01384 char musicclass[BUFFERSIZE+1]; 01385 01386 misdn_cfg_get( port, MISDN_CFG_MUSICCLASS, musicclass, BUFFERSIZE); 01387 ast_copy_string(ast->musicclass, musicclass, sizeof(ast->musicclass)); 01388 01389 misdn_cfg_get( port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int)); 01390 misdn_cfg_get( port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int)); 01391 01392 misdn_cfg_get( port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int)); 01393 01394 misdn_cfg_get( port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int)); 01395 01396 misdn_cfg_get( port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int)); 01397 01398 misdn_cfg_get( port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int)); 01399 01400 misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE); 01401 01402 01403 int hdlc=0; 01404 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01405 01406 if (hdlc) { 01407 switch (bc->capability) { 01408 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01409 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01410 chan_misdn_log(1,bc->port," --> CONF HDLC\n"); 01411 bc->hdlc=1; 01412 break; 01413 } 01414 01415 } 01416 /*Initialize new Jitterbuffer*/ 01417 { 01418 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int)); 01419 misdn_cfg_get( port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int)); 01420 01421 config_jitterbuffer(ch); 01422 } 01423 01424 misdn_cfg_get( bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context)); 01425 01426 ast_copy_string (ast->context,ch->context,sizeof(ast->context)); 01427 01428 update_ec_config(bc); 01429 01430 { 01431 int eb3; 01432 01433 misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int)); 01434 bc->early_bconnect=eb3; 01435 } 01436 01437 port=bc->port; 01438 01439 { 01440 char buf[256]; 01441 ast_group_t pg,cg; 01442 01443 misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg)); 01444 misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg)); 01445 01446 chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n",ast_print_group(buf,sizeof(buf),cg),ast_print_group(buf,sizeof(buf),pg)); 01447 ast->pickupgroup=pg; 01448 ast->callgroup=cg; 01449 } 01450 01451 if ( orig == ORG_AST) { 01452 misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int)); 01453 01454 { 01455 char callerid[BUFFERSIZE+1]; 01456 misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE); 01457 if ( ! ast_strlen_zero(callerid) ) { 01458 chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid); 01459 { 01460 int l = sizeof(bc->oad); 01461 strncpy(bc->oad,callerid, l); 01462 bc->oad[l-1] = 0; 01463 } 01464 01465 } 01466 01467 01468 misdn_cfg_get( port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int)); 01469 misdn_cfg_get( port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int)); 01470 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 01471 debug_numplan(port, bc->dnumplan,"TON"); 01472 debug_numplan(port, bc->onumplan,"LTON"); 01473 debug_numplan(port, bc->cpnnumplan,"CTON"); 01474 } 01475 01476 01477 01478 } else { /** ORIGINATOR MISDN **/ 01479 01480 misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int)); 01481 debug_numplan(port, bc->cpnnumplan,"CTON"); 01482 01483 char prefix[BUFFERSIZE+1]=""; 01484 switch( bc->onumplan ) { 01485 case NUMPLAN_INTERNATIONAL: 01486 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 01487 break; 01488 01489 case NUMPLAN_NATIONAL: 01490 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 01491 break; 01492 default: 01493 break; 01494 } 01495 01496 { 01497 int l = strlen(prefix) + strlen(bc->oad); 01498 char tmp[l+1]; 01499 strcpy(tmp,prefix); 01500 strcat(tmp,bc->oad); 01501 strcpy(bc->oad,tmp); 01502 } 01503 01504 if (!ast_strlen_zero(bc->dad)) { 01505 ast_copy_string(bc->orig_dad,bc->dad, sizeof(bc->orig_dad)); 01506 } 01507 01508 if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) { 01509 ast_copy_string(bc->dad,bc->keypad, sizeof(bc->dad)); 01510 } 01511 01512 prefix[0] = 0; 01513 01514 switch( bc->dnumplan ) { 01515 case NUMPLAN_INTERNATIONAL: 01516 misdn_cfg_get( bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE); 01517 break; 01518 case NUMPLAN_NATIONAL: 01519 misdn_cfg_get( bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE); 01520 break; 01521 default: 01522 break; 01523 } 01524 01525 { 01526 int l = strlen(prefix) + strlen(bc->dad); 01527 char tmp[l+1]; 01528 strcpy(tmp,prefix); 01529 strcat(tmp,bc->dad); 01530 strcpy(bc->dad,tmp); 01531 } 01532 01533 if ( strcmp(bc->dad,ast->exten)) { 01534 ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten)); 01535 } 01536 01537 ast_set_callerid(ast, bc->oad, NULL, bc->oad); 01538 01539 if ( !ast_strlen_zero(bc->rad) ) 01540 ast->cid.cid_rdnis=strdup(bc->rad); 01541 01542 } /* ORIG MISDN END */ 01543 01544 return 0; 01545 }
static void release_chan | ( | struct misdn_bchannel * | bc | ) | [static] |
Isdn asks us to release channel, pendant to misdn_hangup
Definition at line 2930 of file chan_misdn.c.
References ast_channel::_state, chan_list::ast, AST_CID_P, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, chan_misdn_log(), cl_dequeue_chan(), cl_te, ast_channel::context, ast_channel::exten, find_chan_by_bc(), free, chan_list::jb, MISDN_ASTERISK_TECH_PVT, MISDN_CLEANING, misdn_get_ch_state(), misdn_jb_destroy(), chan_list::pipe, and chan_list::state.
02930 { 02931 struct ast_channel *ast=NULL; 02932 { 02933 struct chan_list *ch=find_chan_by_bc(cl_te, bc); 02934 if (!ch) { 02935 chan_misdn_log(0, bc->port, "release_chan: Ch not found!\n"); 02936 return; 02937 } 02938 02939 if (ch->ast) { 02940 ast=ch->ast; 02941 } 02942 02943 chan_misdn_log(1, bc->port, "release_chan: bc with l3id: %x\n",bc->l3_id); 02944 02945 /*releaseing jitterbuffer*/ 02946 if (ch->jb ) { 02947 misdn_jb_destroy(ch->jb); 02948 ch->jb=NULL; 02949 } else { 02950 if (!bc->nojitter) 02951 chan_misdn_log(5,bc->port,"Jitterbuffer already destroyed.\n"); 02952 } 02953 02954 if (ch) { 02955 02956 close(ch->pipe[0]); 02957 close(ch->pipe[1]); 02958 02959 02960 if (ast && MISDN_ASTERISK_TECH_PVT(ast)) { 02961 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_P(ast),misdn_get_ch_state(ch)); 02962 chan_misdn_log(3, bc->port, " --> * State Down\n"); 02963 MISDN_ASTERISK_TECH_PVT(ast)=NULL; 02964 02965 02966 if (ast->_state != AST_STATE_RESERVED) { 02967 chan_misdn_log(3, bc->port, " --> Setting AST State to down\n"); 02968 ast_setstate(ast, AST_STATE_DOWN); 02969 } 02970 } 02971 02972 ch->state=MISDN_CLEANING; 02973 cl_dequeue_chan(&cl_te, ch); 02974 02975 free(ch); 02976 } else { 02977 /* chan is already cleaned, so exiting */ 02978 } 02979 } 02980 }
int reload | ( | void | ) |
Reload stuff.
This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 4202 of file chan_misdn.c.
References reload_config().
04203 { 04204 reload_config(); 04205 04206 return 0; 04207 }
void reload_config | ( | void | ) |
Definition at line 698 of file chan_misdn.c.
References ahp, ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_alias(), build_peer(), build_user(), cfg, format, free_robin_list(), global_tracefile, hp, IPTOS_MINCOST, ast_variable::lineno, ast_user_list::lock, ast_peer_list::lock, ast_alias_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_ports, misdn_cfg_get(), misdn_cfg_reload(), misdn_cfg_update_ptp(), misdn_debug, misdn_debug_only, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, update_common_options(), user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.
00699 { 00700 int i, cfg_debug; 00701 00702 free_robin_list(); 00703 misdn_cfg_reload(); 00704 misdn_cfg_update_ptp(); 00705 misdn_cfg_get( 0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE); 00706 misdn_cfg_get( 0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int)); 00707 00708 for (i = 0; i <= max_ports; i++) { 00709 misdn_debug[i] = cfg_debug; 00710 misdn_debug_only[i] = 0; 00711 } 00712 }
static void send_cause2ast | ( | struct ast_channel * | ast, | |
struct misdn_bchannel * | bc, | |||
struct chan_list * | ch | |||
) | [static] |
Definition at line 3060 of file chan_misdn.c.
References AST_CONTROL_BUSY, ast_queue_control(), chan_misdn_log(), ast_channel::hangupcause, MISDN_BUSY, chan_list::need_busy, and chan_list::state.
Referenced by hangup_chan().
03060 { 03061 if (!ast) { 03062 chan_misdn_log(1,0,"send_cause2ast: No Ast\n"); 03063 return; 03064 } 03065 if (!bc) { 03066 chan_misdn_log(1,0,"send_cause2ast: No BC\n"); 03067 return; 03068 } 03069 if (!ch) { 03070 chan_misdn_log(1,0,"send_cause2ast: No Ch\n"); 03071 return; 03072 } 03073 03074 ast->hangupcause=bc->cause; 03075 03076 switch ( bc->cause) { 03077 03078 case 1: /** Congestion Cases **/ 03079 case 2: 03080 case 3: 03081 case 4: 03082 case 22: 03083 case 27: 03084 /* 03085 * Not Queueing the Congestion anymore, since we want to hear 03086 * the inband message 03087 * 03088 chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Congestion pid:%d\n", bc?bc->pid:-1); 03089 ch->state=MISDN_BUSY; 03090 03091 ast_queue_control(ast, AST_CONTROL_CONGESTION); 03092 */ 03093 break; 03094 03095 case 21: 03096 case 17: /* user busy */ 03097 03098 ch->state=MISDN_BUSY; 03099 03100 if (!ch->need_busy) { 03101 chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n"); 03102 break; 03103 } 03104 03105 chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1); 03106 03107 ast_queue_control(ast, AST_CONTROL_BUSY); 03108 03109 ch->need_busy=0; 03110 03111 break; 03112 } 03113 }
static void send_digit_to_chan | ( | struct chan_list * | cl, | |
char | digit | |||
) | [static] |
Definition at line 426 of file chan_misdn.c.
References chan_list::ast, ast_log(), ast_playtones_start(), LOG_DEBUG, and ast_channel::name.
Referenced by misdn_digit(), and misdn_send_digit().
00427 { 00428 static const char* dtmf_tones[] = { 00429 "!941+1336/100,!0/100", /* 0 */ 00430 "!697+1209/100,!0/100", /* 1 */ 00431 "!697+1336/100,!0/100", /* 2 */ 00432 "!697+1477/100,!0/100", /* 3 */ 00433 "!770+1209/100,!0/100", /* 4 */ 00434 "!770+1336/100,!0/100", /* 5 */ 00435 "!770+1477/100,!0/100", /* 6 */ 00436 "!852+1209/100,!0/100", /* 7 */ 00437 "!852+1336/100,!0/100", /* 8 */ 00438 "!852+1477/100,!0/100", /* 9 */ 00439 "!697+1633/100,!0/100", /* A */ 00440 "!770+1633/100,!0/100", /* B */ 00441 "!852+1633/100,!0/100", /* C */ 00442 "!941+1633/100,!0/100", /* D */ 00443 "!941+1209/100,!0/100", /* * */ 00444 "!941+1477/100,!0/100" }; /* # */ 00445 struct ast_channel *chan=cl->ast; 00446 00447 if (digit >= '0' && digit <='9') 00448 ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0); 00449 else if (digit >= 'A' && digit <= 'D') 00450 ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0); 00451 else if (digit == '*') 00452 ast_playtones_start(chan,0,dtmf_tones[14], 0); 00453 else if (digit == '#') 00454 ast_playtones_start(chan,0,dtmf_tones[15], 0); 00455 else { 00456 /* not handled */ 00457 ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name); 00458 00459 00460 } 00461 }
static int start_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2402 of file chan_misdn.c.
References chan_list::bc, chan_list::norxtone, and chan_list::notxtone.
Referenced by misdn_answer(), misdn_hangup(), and misdn_indication().
02403 { 02404 misdn_lib_tone_generator_stop(cl->bc); 02405 cl->notxtone=0; 02406 cl->norxtone=0; 02407 return 0; 02408 }
static int stop_bc_tones | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2410 of file chan_misdn.c.
References chan_list::norxtone, and chan_list::notxtone.
Referenced by misdn_call(), and misdn_hangup().
02411 { 02412 if (!cl) return -1; 02413 02414 cl->notxtone=1; 02415 cl->norxtone=1; 02416 02417 return 0; 02418 }
static int stop_indicate | ( | struct chan_list * | cl | ) | [static] |
Definition at line 2390 of file chan_misdn.c.
References chan_list::ast, ast_playtones_stop(), chan_list::bc, and chan_misdn_log().
Referenced by cb_events(), misdn_answer(), and misdn_indication().
02391 { 02392 struct ast_channel *ast=cl->ast; 02393 chan_misdn_log(3,cl->bc->port," --> None\n"); 02394 misdn_lib_tone_generator_stop(cl->bc); 02395 ast_playtones_stop(ast); 02396 /*ast_deactivate_generator(ast);*/ 02397 02398 return 0; 02399 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 4155 of file chan_misdn.c.
References ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_unregister_application(), cli_port_block, cli_port_down, cli_port_unblock, cli_port_up, cli_reload, cli_restart_port, cli_send_cd, cli_send_digit, cli_send_display, cli_set_crypt_debug, cli_set_debug, cli_set_tics, cli_show_cl, cli_show_cls, cli_show_config, cli_show_port, cli_show_stacks, cli_toggle_echocancel, free, free_robin_list(), LOG_VERBOSE, misdn_cfg_destroy(), misdn_debug, misdn_debug_only, and misdn_tech.
04156 { 04157 /* First, take us out of the channel loop */ 04158 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n"); 04159 04160 if (!g_config_initialized) return 0; 04161 04162 ast_cli_unregister(&cli_send_display); 04163 04164 ast_cli_unregister(&cli_send_cd); 04165 04166 ast_cli_unregister(&cli_send_digit); 04167 ast_cli_unregister(&cli_toggle_echocancel); 04168 ast_cli_unregister(&cli_set_tics); 04169 04170 ast_cli_unregister(&cli_show_cls); 04171 ast_cli_unregister(&cli_show_cl); 04172 ast_cli_unregister(&cli_show_config); 04173 ast_cli_unregister(&cli_show_port); 04174 ast_cli_unregister(&cli_show_stacks); 04175 ast_cli_unregister(&cli_port_block); 04176 ast_cli_unregister(&cli_port_unblock); 04177 ast_cli_unregister(&cli_restart_port); 04178 ast_cli_unregister(&cli_port_up); 04179 ast_cli_unregister(&cli_port_down); 04180 ast_cli_unregister(&cli_set_debug); 04181 ast_cli_unregister(&cli_set_crypt_debug); 04182 ast_cli_unregister(&cli_reload); 04183 /* ast_unregister_application("misdn_crypt"); */ 04184 ast_unregister_application("misdn_set_opt"); 04185 ast_unregister_application("misdn_facility"); 04186 04187 ast_channel_unregister(&misdn_tech); 04188 04189 04190 free_robin_list(); 04191 misdn_cfg_destroy(); 04192 misdn_lib_destroy(); 04193 04194 if (misdn_debug) 04195 free(misdn_debug); 04196 if (misdn_debug_only) 04197 free(misdn_debug_only); 04198 04199 return 0; 04200 }
static int update_config | ( | struct chan_list * | ch, | |
int | orig | |||
) | [static] |
Definition at line 1182 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, chan_misdn_log(), ast_channel::cid, ast_callerid::cid_pres, LOG_WARNING, and misdn_cfg_get().
Referenced by misdn_call().
01183 { 01184 if (!ch) { 01185 ast_log(LOG_WARNING, "Cannot configure without chanlist\n"); 01186 return -1; 01187 } 01188 01189 struct ast_channel *ast=ch->ast; 01190 struct misdn_bchannel *bc=ch->bc; 01191 if (! ast || ! bc ) { 01192 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n"); 01193 return -1; 01194 } 01195 01196 int port=bc->port; 01197 01198 chan_misdn_log(1,port,"update_config: Getting Config\n"); 01199 01200 01201 int hdlc=0; 01202 misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int)); 01203 01204 if (hdlc) { 01205 switch (bc->capability) { 01206 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: 01207 case INFO_CAPABILITY_DIGITAL_RESTRICTED: 01208 chan_misdn_log(1,bc->port," --> CONF HDLC\n"); 01209 bc->hdlc=1; 01210 break; 01211 } 01212 01213 } 01214 01215 01216 int pres, screen; 01217 01218 misdn_cfg_get( port, MISDN_CFG_PRES, &pres, sizeof(int)); 01219 misdn_cfg_get( port, MISDN_CFG_SCREEN, &screen, sizeof(int)); 01220 chan_misdn_log(2,port," --> pres: %d screen: %d\n",pres, screen); 01221 01222 if ( (pres + screen) < 0 ) { 01223 01224 chan_misdn_log(2,port," --> pres: %x\n", ast->cid.cid_pres); 01225 01226 switch (ast->cid.cid_pres & 0x60){ 01227 01228 case AST_PRES_RESTRICTED: 01229 bc->pres=1; 01230 chan_misdn_log(2, port, " --> PRES: Restricted (0x1)\n"); 01231 break; 01232 01233 01234 case AST_PRES_UNAVAILABLE: 01235 bc->pres=2; 01236 chan_misdn_log(2, port, " --> PRES: Unavailable (0x2)\n"); 01237 break; 01238 01239 default: 01240 bc->pres=0; 01241 chan_misdn_log(2, port, " --> PRES: Allowed (0x0)\n"); 01242 } 01243 01244 switch (ast->cid.cid_pres & 0x3){ 01245 01246 case AST_PRES_USER_NUMBER_UNSCREENED: 01247 bc->screen=0; 01248 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n"); 01249 break; 01250 01251 case AST_PRES_USER_NUMBER_PASSED_SCREEN: 01252 bc->screen=1; 01253 chan_misdn_log(2, port, " --> SCREEN: Passed Screen (0x1)\n"); 01254 break; 01255 case AST_PRES_USER_NUMBER_FAILED_SCREEN: 01256 bc->screen=2; 01257 chan_misdn_log(2, port, " --> SCREEN: Failed Screen (0x2)\n"); 01258 break; 01259 01260 case AST_PRES_NETWORK_NUMBER: 01261 bc->screen=3; 01262 chan_misdn_log(2, port, " --> SCREEN: Network Nr. (0x3)\n"); 01263 break; 01264 01265 default: 01266 bc->screen=0; 01267 chan_misdn_log(2, port, " --> SCREEN: Unscreened (0x0)\n"); 01268 } 01269 01270 01271 } else { 01272 bc->screen=screen; 01273 bc->pres=pres; 01274 } 01275 01276 return 0; 01277 01278 }
static int update_ec_config | ( | struct misdn_bchannel * | bc | ) | [static] |
Definition at line 1343 of file chan_misdn.c.
References misdn_cfg_get().
Referenced by misdn_toggle_echocancel(), and read_config().
01344 { 01345 int ec; 01346 int port=bc->port; 01347 01348 misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int)); 01349 01350 if (ec == 1 ) { 01351 bc->ec_enable=1; 01352 } else if ( ec > 1 ) { 01353 bc->ec_enable=1; 01354 bc->ec_deftaps=ec; 01355 } 01356 01357 return 0; 01358 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 4209 of file chan_misdn.c.
References ast_mutex_lock(), ast_mutex_unlock(), usecnt, and usecnt_lock.
04210 { 04211 int res; 04212 ast_mutex_lock(&usecnt_lock); 04213 res = usecnt; 04214 ast_mutex_unlock(&usecnt_lock); 04215 return res; 04216 }
struct allowed_bearers allowed_bearers_array[] |
Definition at line 290 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 291 of file chan_misdn.c.
Referenced by cl_dequeue_chan(), cl_queue_chan(), and load_module().
struct ast_cli_entry cli_port_block [static] |
struct ast_cli_entry cli_port_down [static] |
struct ast_cli_entry cli_port_unblock [static] |
struct ast_cli_entry cli_port_up [static] |
struct ast_cli_entry cli_reload [static] |
Definition at line 1084 of file chan_misdn.c.
struct ast_cli_entry cli_restart_port [static] |
struct ast_cli_entry cli_send_cd [static] |
struct ast_cli_entry cli_send_digit [static] |
struct ast_cli_entry cli_send_display [static] |
struct ast_cli_entry cli_set_crypt_debug [static] |
struct ast_cli_entry cli_set_debug [static] |
struct ast_cli_entry cli_set_tics [static] |
struct ast_cli_entry cli_show_cl [static] |
struct ast_cli_entry cli_show_cls [static] |
struct ast_cli_entry cli_show_config [static] |
struct ast_cli_entry cli_show_port [static] |
struct ast_cli_entry cli_show_stacks [static] |
struct ast_cli_entry cli_toggle_echocancel [static] |
char* desc = "Channel driver for mISDN Support (Bri/Pri)" [static] |
Definition at line 269 of file chan_misdn.c.
Definition at line 288 of file chan_misdn.c.
int g_config_initialized = 0 [static] |
TE STUFF END
Definition at line 4028 of file chan_misdn.c.
unsigned long glob_channel = 0 [static] |
Definition at line 2660 of file chan_misdn.c.
char global_tracefile[BUFFERSIZE+1] |
Definition at line 65 of file chan_misdn.c.
Referenced by chan_misdn_log(), load_module(), and reload_config().
Definition at line 815 of file chan_misdn.c.
Referenced by ast_waitfor_nandfds(), load_config(), load_module(), mkbrd(), rpt_master(), unload_module(), zap_show_channel(), zap_show_channels(), and zt_request().
int max_ports [static] |
Definition at line 286 of file chan_misdn.c.
Referenced by _build_port_config(), _free_port_cfg(), chan_misdn_log(), load_module(), misdn_cfg_get_next_port(), misdn_cfg_get_ports_string(), misdn_cfg_init(), misdn_cfg_is_group_method(), misdn_cfg_is_port_valid(), misdn_set_debug(), and reload_config().
int MAXTICS = 8 |
int* misdn_debug [static] |
Definition at line 284 of file chan_misdn.c.
Referenced by chan_misdn_log(), load_module(), misdn_set_debug(), misdn_show_cls(), misdn_show_port(), misdn_show_stacks(), print_bc_info(), reload_config(), and unload_module().
int* misdn_debug_only [static] |
Definition at line 285 of file chan_misdn.c.
Referenced by chan_misdn_log(), load_module(), misdn_set_debug(), misdn_show_port(), misdn_show_stacks(), reload_config(), and unload_module().
char** misdn_key_vector = NULL [static] |
int misdn_key_vector_size = 0 [static] |
struct ast_channel_tech misdn_tech [static] |
Definition at line 2624 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 270 of file chan_misdn.c.
Referenced by load_module(), misdn_new(), and misdn_request().
int prefformat = AST_FORMAT_ALAW [static] |
struct robin_list* robin = NULL [static] |
Definition at line 209 of file chan_misdn.c.
Referenced by free_robin_list(), and get_robin_position().
struct state_struct state_array[] [static] |
int tracing = 0 [static] |
int usecnt = 0 [static] |
Definition at line 274 of file chan_misdn.c.
ast_mutex_t usecnt_lock [static] |
Definition at line 282 of file chan_misdn.c.
Referenced by __oh323_new(), agent_hangup(), agent_new(), alsa_hangup(), alsa_new(), aopen_decusecnt(), aopen_incusecnt(), ast_iax2_new(), ast_modem_new(), bestdata_decusecnt(), bestdata_incusecnt(), features_new(), i4l_decusecnt(), i4l_incusecnt(), iax2_predestroy(), local_hangup(), local_new(), mgcp_hangup(), mgcp_new(), modem_hangup(), nbs_new(), oh323_hangup(), oss_hangup(), oss_new(), phone_check_exception(), phone_hangup(), phone_new(), sip_hangup(), sip_new(), skinny_new(), usecount(), vpb_hangup(), vpb_new(), zt_hangup(), and zt_new().