From 87a7c7793b7933315a0a7014ec20ef07f9a66ef6 Mon Sep 17 00:00:00 2001 From: crichter Date: Tue, 23 May 2006 12:38:06 +0000 Subject: * export_ies uses now _VAR else the vars are not copied to the dest chan * when receiving a connect from the NT Side we wait until we have the final l3id until we queue the answer to asterisk to avoid bridging conflicts * when not bridged to misdn we had a segfault after receiving the connect due to a strcasecmp bug.. this didn't happen before, cause we hadn't had the bridge before * cleanup of the bchannels is queued now, due to possible race conditions * added mISDN_clear_stack when cleaning the bchannel git-svn-id: http://svn.digium.com/svn/asterisk/trunk@29667 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_misdn.c | 54 +++++++++++++++++++++--------- channels/misdn/isdn_lib.c | 85 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 110 insertions(+), 29 deletions(-) diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index 830d41690..59e21ffcf 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -3029,10 +3029,6 @@ void import_ies(struct ast_channel *chan, struct misdn_bchannel *bc) tmp=pbx_builtin_getvar_helper(chan,"PRI_USER1"); if (tmp) bc->user1=atoi(tmp); - - tmp=pbx_builtin_getvar_helper(chan,"RDNIS"); - if (tmp) ast_copy_string(bc->rad,tmp,sizeof(bc->rad)); - } void export_ies(struct ast_channel *chan, struct misdn_bchannel *bc) @@ -3040,18 +3036,18 @@ void export_ies(struct ast_channel *chan, struct misdn_bchannel *bc) char tmp[32]; sprintf(tmp,"%d",bc->mode); - pbx_builtin_setvar_helper(chan,"PRI_MODE",tmp); + pbx_builtin_setvar_helper(chan,"_PRI_MODE",tmp); sprintf(tmp,"%d",bc->urate); - pbx_builtin_setvar_helper(chan,"PRI_URATE",tmp); + pbx_builtin_setvar_helper(chan,"_PRI_URATE",tmp); sprintf(tmp,"%d",bc->rate); - pbx_builtin_setvar_helper(chan,"PRI_RATE",tmp); + pbx_builtin_setvar_helper(chan,"_PRI_RATE",tmp); sprintf(tmp,"%d",bc->user1); - pbx_builtin_setvar_helper(chan,"PRI_USER1",tmp); + pbx_builtin_setvar_helper(chan,"_PRI_USER1",tmp); - pbx_builtin_setvar_helper(chan,"RDNIS",bc->rad); + pbx_builtin_setvar_helper(chan,"_RDNIS",bc->rad); } @@ -3139,6 +3135,17 @@ 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) { + /* 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: @@ -3526,15 +3533,21 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) misdn_lib_echo(bc,0); tone_indicate(ch, TONE_NONE); - if (bridged && strcasecmp(bridged->tech->type,"mISDN")) { + if (bridged && !strcasecmp(bridged->tech->type,"mISDN")) { struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged); chan_misdn_log(1,bc->port," --> copying cpndialplan:%d and cad:%s to the A-Channel\n",bc->cpnnumplan,bc->cad); - - bridged_ch->bc->cpnnumplan=bc->cpnnumplan; - ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad)); + if (bridged_ch) { + bridged_ch->bc->cpnnumplan=bc->cpnnumplan; + ast_copy_string(bridged_ch->bc->cad,bc->cad,sizeof(bc->cad)); + } } } + + /*we answer when we've got our very new L3 ID from the NT stack */ + if (bc->nt) break; + + /* notice that we don't break here!*/ case EVENT_CONNECT_ACKNOWLEDGE: { @@ -3557,7 +3570,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) send_cause2ast(ch->ast,bc); - chan_misdn_log(0,bc->port," org:%d nt:%d, inbandavail:%d state:%d\n", ch->orginator, bc->nt, misdn_inband_avail(bc), ch->state); + 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 recorded message saying what was wrong with the @@ -3964,10 +3977,20 @@ static int load_module(void *mod) ast_cli_register(&cli_reload); - ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_flags", + ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt", "misdn_set_opt(::..):\n" "Sets mISDN opts. and optargs\n" "\n" + "The available options are:\n" + " d - Send display text on called phone, text is the optparam\n" + " n - don't detect dtmf tones on called channel\n" + " h - make digital outgoing call\n" + " c - make crypted outgoing call, param is keyindex\n" + " e - perform echo cancelation on this channel,\n" + " takes taps as arguments (32,64,128,256)\n" + " s - send Non Inband DTMF as inband\n" + " vr - rxgain control\n" + " vt - txgain control\n" ); @@ -3978,7 +4001,6 @@ static int load_module(void *mod) "Supported Facilities are:\n" "\n" "type=calldeflect args=Nr where to deflect\n" - "\n" ); diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index 91700ff0a..d2ae1440b 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -18,6 +18,8 @@ void misdn_join_conf(struct misdn_bchannel *bc, int conf_id); void misdn_split_conf(struct misdn_bchannel *bc, int conf_id); +int queue_cleanup_bc(struct misdn_bchannel *bc) ; + struct misdn_stack* get_misdn_stack( void ); @@ -579,10 +581,14 @@ int clean_up_bc(struct misdn_bchannel *bc) manager_ec_disable(bc); } + mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); + cb_log(2, stack->port, "$$$ CLEARING STACK\n"); - /*mISDN_clear_stack(stack->midev,bc->b_stid);*/ - - mISDN_write_frame(stack->midev, buff, bc->addr|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); + ret=mISDN_clear_stack(stack->midev,bc->b_stid); + if (ret<0) { + cb_log(-1,stack->port,"clear stack failed [%s]\n",strerror(errno)); + } + bc->b_stid = 0; bc_state_change(bc, BCHAN_CLEANED); @@ -600,7 +606,7 @@ void clear_l3(struct misdn_stack *stack) cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data); empty_chan_in_stack(stack,i+1); empty_bc(&stack->bc[i]); - clean_up_bc(&stack->bc[i]); + queue_cleanup_bc(&stack->bc[i]); } @@ -766,7 +772,7 @@ static int create_process (int midev, struct misdn_bchannel *bc) { if (!free_chan) return -1; bc->channel=free_chan; - cb_log(0,stack->port, " --> found channel: %d\n",free_chan); + cb_log(4,stack->port, " --> found channel: %d\n",free_chan); for (i=0; i <= MAXPROCS; i++) if (stack->procids[i]==0) break; @@ -975,9 +981,6 @@ int setup_bc(struct misdn_bchannel *bc) bc_state_change(bc,BCHAN_SETUP); - /*manager_bchannel_deactivate(bc);*/ - - return 0; } @@ -1470,7 +1473,7 @@ int handle_cr ( struct misdn_stack *stack, iframe_t *frm) cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo); empty_chan_in_stack(stack,bc->channel); empty_bc(bc); - clean_up_bc(bc); + queue_cleanup_bc(bc); dump_chan_list(stack); bc->pid = 0; cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data); @@ -1508,7 +1511,7 @@ void misdn_lib_release(struct misdn_bchannel *bc) empty_chan_in_stack(stack,bc->channel); empty_bc(bc); } - clean_up_bc(bc); + queue_cleanup_bc(bc); } @@ -2055,6 +2058,9 @@ int handle_bchan(msg_t *msg) /* we kill the channel later, when we received some data. */ bc->addr= frm->addr; + } else if ( bc->addr < 0) { + cb_log(-1, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno)); + bc->addr=0; } cb_log(4, stack->port," --> Got Adr %x\n", bc->addr); @@ -2912,7 +2918,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) empty_chan_in_stack(stack,bc->channel); empty_bc(bc); - clean_up_bc(bc); + queue_cleanup_bc(bc); } /** we set it up later at RETRIEVE_ACK again.**/ @@ -2984,6 +2990,9 @@ int handle_err(msg_t *msg) } switch (frm->prim) { + case MGR_SETSTACK|INDICATION: + return handle_bchan(msg); + break; case DL_DATA|INDICATION: { int port=(frm->addr&MASTER_ID_MASK) >> 8; @@ -3113,6 +3122,32 @@ int misdn_lib_get_port_info(int port) return 0; } + +int queue_cleanup_bc(struct misdn_bchannel *bc) +{ + msg_t *msg=alloc_msg(MAX_MSG_SIZE); + iframe_t *frm; + if (!msg) { + cb_log(-1, bc->port, "misgn_lib_get_port: alloc_msg failed!\n"); + return -1; + } + frm=(iframe_t*)msg->data; + + /* activate bchannel */ + frm->prim = MGR_CLEARSTACK| REQUEST; + + frm->addr = bc->l3_id; + + frm->dinfo = bc->port; + frm->len = 0; + + msg_queue_tail(&glob_mgr->activatequeue, msg); + sem_post(&glob_mgr->new_msg); + + return 0; + +} + int misdn_lib_port_restart(int port) { struct misdn_stack *stack=find_stack_by_port(port); @@ -3212,6 +3247,27 @@ void manager_event_handler(void *arg) iframe_t *frm = (iframe_t*) msg->data ; switch ( frm->prim) { + + case MGR_CLEARSTACK | REQUEST: + /*a queued bchannel cleanup*/ + { + struct misdn_stack *stack=find_stack_by_port(frm->dinfo); + if (!stack) { + cb_log(-1,0,"no stack found with port [%d]!! so we cannot cleanup the bc\n",frm->dinfo); + free_msg(msg); + break; + } + + struct misdn_bchannel *bc=find_bc_by_l3id(stack,frm->addr); + if (bc) { + cb_log(1,bc->port,"CLEARSTACK queued, cleaning up\n"); + clean_up_bc(bc); + } else { + cb_log(-1,stack->port,"bc could not be cleaned correctly !! addr [%x]\n",frm->addr); + } + } + free_msg(msg); + break; case MGR_SETSTACK | REQUEST : break; default: @@ -3517,8 +3573,11 @@ void manager_bchannel_deactivate(struct misdn_bchannel * bc) dact.addr = bc->addr | FLG_MSG_DOWN; dact.dinfo = 0; dact.len = 0; - - mISDN_write(stack->midev, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC); + char buf[128]; + mISDN_write_frame(stack->midev, buf, bc->addr| FLG_MSG_DOWN, DL_RELEASE|REQUEST,0,0,NULL, TIMEOUT_1SEC); + + mISDN_read(stack->midev, buf, 128, TIMEOUT_1SEC); + clear_ibuffer(bc->astbuf); bc_state_change(bc,BCHAN_RELEASE); -- cgit v1.2.3