diff options
Diffstat (limited to 'channels/chan_misdn.c')
-rw-r--r-- | channels/chan_misdn.c | 196 |
1 files changed, 145 insertions, 51 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index d862a4633..68f319cd1 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -140,6 +140,7 @@ struct chan_list { enum misdn_chan_state state; int need_queue_hangup; int need_hangup; + int need_busy; int holded; int orginator; @@ -715,6 +716,35 @@ static int misdn_set_crypt_debug(int fd, int argc, char *argv[]) } +static int misdn_port_block(int fd, int argc, char *argv[]) +{ + int port; + + if (argc != 4) + return RESULT_SHOWUSAGE; + + port = atoi(argv[3]); + + misdn_lib_port_block(port); + + return 0; +} + +static int misdn_port_unblock(int fd, int argc, char *argv[]) +{ + int port; + + if (argc != 4) + return RESULT_SHOWUSAGE; + + port = atoi(argv[3]); + + misdn_lib_port_unblock(port); + + return 0; +} + + static int misdn_restart_port (int fd, int argc, char *argv[]) { int port; @@ -877,6 +907,7 @@ static struct state_struct state_array[] = { {MISDN_ALERTING,"ALERTING"}, /* when Alerting */ {MISDN_BUSY,"BUSY"}, /* when BUSY */ {MISDN_CONNECTED,"CONNECTED"}, /* when connected */ + {MISDN_PRECONNECTED,"PRECONNECTED"}, /* when connected */ {MISDN_DISCONNECTED,"DISCONNECTED"}, /* when connected */ {MISDN_RELEASED,"RELEASED"}, /* when connected */ {MISDN_BRIDGED,"BRIDGED"}, /* when bridged */ @@ -909,7 +940,6 @@ static char *misdn_get_ch_state(struct chan_list *p) static void reload_config(void) { int i, cfg_debug; - chan_misdn_log(-1, 0, "Dynamic Crypting Activation is not support during reload at the moment\n"); free_robin_list(); misdn_cfg_reload(); @@ -1381,6 +1411,19 @@ static struct ast_cli_entry cli_show_cl = complete_ch }; +static struct ast_cli_entry cli_port_block= +{ {"misdn","port","block", NULL}, + misdn_port_block, + "Blocks the given port", + "Usage: misdn port block\n" +}; + +static struct ast_cli_entry cli_port_unblock= +{ {"misdn","port","unblock", NULL}, + misdn_port_unblock, + "Unblocks the given port", + "Usage: misdn port unblock\n" +}; static struct ast_cli_entry cli_restart_port = @@ -1559,12 +1602,12 @@ static void config_jitterbuffer(struct chan_list *ch) } else { if (len <=100 || len > 8000) { - chan_misdn_log(-1,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); + chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer out of Bounds, setting to 1000\n"); len=1000; } if ( threshold > len ) { - chan_misdn_log(-1,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); + chan_misdn_log(0,bc->port,"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n"); } if ( ch->jb) { @@ -1676,21 +1719,38 @@ static int read_config(struct chan_list *ch, int orig) { ast_copy_string (ast->context,ch->context,sizeof(ast->context)); { - int ec, ectr; + int ec; misdn_cfg_get( port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int)); - misdn_cfg_get( port, MISDN_CFG_ECHOTRAINING, &ectr, sizeof(int)); if (ec == 1 ) { bc->ec_enable=1; } else if ( ec > 1 ) { bc->ec_enable=1; bc->ec_deftaps=ec; } +#ifdef WITH_ECHOTRAINING + int ectr; + misdn_cfg_get( port, MISDN_CFG_ECHOTRAINING, &ectr, sizeof(int)); if ( ectr >= 0 ) { bc->ec_training=ectr; } +#endif + +#ifdef WITH_BEROEC + misdn_cfg_get(port, MISDN_CFG_BNECHOCANCEL,&bc->bnec_tail, sizeof(int)); + misdn_cfg_get(port, MISDN_CFG_BNEC_ANTIHOWL, &bc->bnec_ah, sizeof(int)); + misdn_cfg_get(port, MISDN_CFG_BNEC_NLP, &bc->bnec_nlp, sizeof(int)); + misdn_cfg_get(port, MISDN_CFG_BNEC_TD, &bc->bnec_td, sizeof(int)); + misdn_cfg_get(port, MISDN_CFG_BNEC_ADAPT, &bc->bnec_adapt, sizeof(int)); + misdn_cfg_get(port, MISDN_CFG_BNEC_ZEROCOEFF, &bc->bnec_zero, sizeof(int)); + + if (bc->bnec_tail && bc->ec_enable) { + ast_log(LOG_WARNING,"Are you sure you wan't to mix BNEC with Zapec ? This might cause bad audio quality!\n"); + bc->ec_enable=0; + } +#endif } { @@ -1839,7 +1899,7 @@ static int misdn_call(struct ast_channel *ast, char *dest, int timeout) if (ext) { opts=strtok_r(NULL,"/",&tokb); } else { - chan_misdn_log(-1,0,"misdn_call: No Extension given!\n"); + chan_misdn_log(0,0,"misdn_call: No Extension given!\n"); return -1; } } @@ -2265,6 +2325,11 @@ static int misdn_hangup(struct ast_channel *ast) return 0; } + p->need_hangup=0; + p->need_queue_hangup=0; + p->need_busy=0; + + if (!p->bc->nt) stop_bc_tones(p); @@ -2295,13 +2360,8 @@ static int misdn_hangup(struct ast_channel *ast) start_bc_tones(p); hanguptone_indicate(p); - if (bc->nt) { - if (bc->need_disconnect) - misdn_lib_send_event( bc, EVENT_DISCONNECT); - } else { - misdn_lib_send_event( bc, EVENT_RELEASE_COMPLETE); - p->state=MISDN_CLEANING; - } + if (bc->need_disconnect) + misdn_lib_send_event( bc, EVENT_DISCONNECT); break; case MISDN_CALLING_ACKNOWLEDGE: @@ -2323,6 +2383,7 @@ static int misdn_hangup(struct ast_channel *ast) misdn_lib_send_event( bc, EVENT_DISCONNECT); break; case MISDN_CONNECTED: + case MISDN_PRECONNECTED: /* Alerting or Disconect */ if (p->bc->nt) { start_bc_tones(p); @@ -2755,6 +2816,7 @@ static struct chan_list *init_chan_list(int orig) cl->orginator=orig; cl->need_queue_hangup=1; cl->need_hangup=1; + cl->need_busy=1; cl->overlap_dial_task=-1; return cl; @@ -2844,18 +2906,19 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat if (!strcasecmp(cfg_group, group)) { int port_up; - int check,checkl2; + int check; misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); - misdn_cfg_get(port, MISDN_CFG_PP_L2_CHECK, &checkl2, sizeof(int)); - check=checkl2?2:check; - port_up = misdn_lib_port_up(port, check); if (check && !port_up) chan_misdn_log(1,port,"L1 is not Up on this Port\n"); + if (check && port_up<0) { + ast_log(LOG_WARNING,"This port (%d) is blocked\n", port); + } + - if ( port_up ) { + if ( port_up>0 ) { newbc = misdn_lib_get_free_bc(port, robin_channel); if (newbc) { chan_misdn_log(4, port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel); @@ -2871,7 +2934,7 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat } while (!newbc && robin_channel != rr->channel); if (!newbc) - chan_misdn_log(4, port, " Failed! No free channel in group %d!", group); + chan_misdn_log(-1, port, " Failed! No free channel in group %d!", group); } else { @@ -2883,15 +2946,13 @@ static struct ast_channel *misdn_request(const char *type, int format, void *dat chan_misdn_log(3,port, "Group [%s] Port [%d]\n", group, port); if (!strcasecmp(cfg_group, group)) { int port_up; - int check,checkl2; + int check; misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int)); - misdn_cfg_get(port, MISDN_CFG_PP_L2_CHECK, &checkl2, sizeof(int)); - check=checkl2?2:check; port_up = misdn_lib_port_up(port, check); chan_misdn_log(4, port, "portup:%d\n", port_up); - if ( port_up ) { + if ( port_up>0 ) { newbc = misdn_lib_get_free_bc(port, 0); if (newbc) break; @@ -3178,9 +3239,11 @@ static void hangup_chan(struct chan_list *ch) return; } + cb_log(1,ch->bc?ch->bc->port:0,"hangup_chan\n"); if (ch->need_hangup) { + cb_log(1,ch->bc->port,"-> hangup\n"); send_cause2ast(ch->ast,ch->bc,ch); ch->need_hangup=0; ch->need_queue_hangup=0; @@ -3196,7 +3259,10 @@ static void hangup_chan(struct chan_list *ch) ch->need_queue_hangup=0; if (ch->ast) { send_cause2ast(ch->ast,ch->bc,ch); - ast_queue_hangup(ch->ast); + + if (ch->ast) + ast_queue_hangup(ch->ast); + cb_log(1,ch->bc->port,"-> queue_hangup\n"); } else { cb_log(1,ch->bc->port,"Cannot hangup chan, no ast\n"); } @@ -3385,11 +3451,20 @@ static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, st case 21: case 17: /* user busy */ - chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1); ch->state=MISDN_BUSY; + + if (!ch->need_busy) { + chan_misdn_log(1,bc?bc->port:0, "Queued busy already\n"); + break; + } + + chan_misdn_log(1, bc?bc->port:0, " --> * SEND: Queue Busy pid:%d\n", bc?bc->pid:-1); + ast_queue_control(ast, AST_CONTROL_BUSY); + ch->need_busy=0; + break; } } @@ -3463,15 +3538,23 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) struct chan_list *ch=find_chan_by_bc(cl_te, bc); if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */ - chan_misdn_log(1, 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"); - misdn_lib_log_ies(bc); - chan_misdn_log(2,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state)); + int debuglevel=1; + + if ( event==EVENT_CLEANUP && !user_data) + debuglevel=5; + + 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"); + if (debuglevel==1) { + misdn_lib_log_ies(bc); + chan_misdn_log(4,bc->port," --> bc_state:%s\n",bc_state2str(bc->bc_state)); + } } if (!ch) { switch(event) { case EVENT_SETUP: case EVENT_DISCONNECT: + case EVENT_PORT_ALARM: break; case EVENT_RELEASE_COMPLETE: chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n"); @@ -3510,7 +3593,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) switch (event) { - + case EVENT_PORT_ALARM: + { + int boa=0; + misdn_cfg_get( bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int)); + if (boa) { + cb_log(1,bc->port," --> blocking\n"); + misdn_lib_port_block(bc->port); + } + } + break; case EVENT_BCHAN_ACTIVATED: break; @@ -3521,21 +3613,11 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) case EVENT_NEW_L3ID: ch->l3id=bc->l3_id; ch->addr=bc->addr; - - if (bc->nt && ch->state == MISDN_PRECONNECTED ) { - /* OK we've got the very new l3id so we can answer - now */ - start_bc_tones(ch); - - ch->state = MISDN_CONNECTED; - ast_queue_control(ch->ast, AST_CONTROL_ANSWER); - - } break; case EVENT_NEW_BC: if (bc) - ch->bc=bc; + ch->bc=(struct misdn_bchannel*)user_data; break; case EVENT_DTMF_TONE: @@ -4002,6 +4084,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) break; case EVENT_CONNECT: { + /*we answer when we've got our very new L3 ID from the NT stack */ misdn_lib_send_event(bc,EVENT_CONNECT_ACKNOWLEDGE); struct ast_channel *bridged=AST_BRIDGED_P(ch->ast); @@ -4020,11 +4103,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) } } - /*we answer when we've got our very new L3 ID from the NT stack */ - if (bc->nt) { - ch->state=MISDN_PRECONNECTED; - break; - } /* notice that we don't break here!*/ @@ -4045,9 +4123,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) if (ch) { struct chan_list *holded_ch=find_holded(cl_te, bc); - if (ch->ast) - send_cause2ast(ch->ast,bc,ch); - 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); if ( ch->orginator==ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) { /* If there's inband information available (e.g. a @@ -4064,11 +4139,12 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) /*Check for holded channel, to implement transfer*/ if (holded_ch && ch->ast ) { + cb_log(1,bc->port," --> found holded ch\n"); if (ch->state == MISDN_CONNECTED ) { misdn_transfer_bc(ch, holded_ch) ; - misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); - break; } + misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); + break; } stop_bc_tones(ch); @@ -4085,7 +4161,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) hangup_chan(ch); release_chan(bc); - if (bc->cause >= 0 && bc->need_release_complete) + if (bc->need_release_complete) misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE); } break; @@ -4101,6 +4177,15 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) case EVENT_CLEANUP: { stop_bc_tones(ch); + + switch(ch->state) { + case MISDN_CALLING: + bc->cause=27; /* Destination out of order */ + break; + default: + break; + } + hangup_chan(ch); release_chan(bc); } @@ -4378,6 +4463,8 @@ static int unload_module(void *mod) ast_cli_unregister(&cli_show_port); ast_cli_unregister(&cli_show_ports_stats); ast_cli_unregister(&cli_show_stacks); + ast_cli_unregister(&cli_port_block); + ast_cli_unregister(&cli_port_unblock); ast_cli_unregister(&cli_restart_port); ast_cli_unregister(&cli_port_up); ast_cli_unregister(&cli_port_down); @@ -4491,6 +4578,8 @@ static int load_module(void *mod) ast_cli_register(&cli_show_stacks); ast_cli_register(&cli_show_ports_stats); + ast_cli_register(&cli_port_block); + ast_cli_register(&cli_port_unblock); ast_cli_register(&cli_restart_port); ast_cli_register(&cli_port_up); ast_cli_register(&cli_port_down); @@ -4722,6 +4811,10 @@ static int misdn_set_opt_exec(struct ast_channel *chan, void *data) if (neglect) { chan_misdn_log(1, ch->bc->port, " --> disabled\n"); ch->bc->ec_enable=0; + +#ifdef WITH_BEROEC + ch->bc->bnec_tail=0; +#endif } else { ch->bc->ec_enable=1; ch->bc->orig=ch->orginator; @@ -5001,6 +5094,7 @@ void chan_misdn_log(int level, int port, char *tmpl, ...) if (level == -1) ast_log(LOG_WARNING, buf); + else if (misdn_debug_only[port] ? (level==1 && misdn_debug[port]) || (level==misdn_debug[port]) : level <= misdn_debug[port]) { |