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