From 51ef9ad083bf929cb406c464c4bdce07830d00ef Mon Sep 17 00:00:00 2001 From: crichter Date: Fri, 22 Jun 2007 15:32:54 +0000 Subject: Merged revisions 70311 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r70311 | crichter | 2007-06-20 16:47:59 +0200 (Mi, 20 Jun 2007) | 1 line on receiption of cause:44 we mark the channel as in use and inform the user about the situation, we need to test the RESTART stuff then. Also shuffled the empty_chan_in_stack function after the bchannel cleaning functions, to avoid race conditions. ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@71121 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_misdn.c | 2 ++ channels/misdn/isdn_lib.c | 70 ++++++++++++++++++++++++++++++++--------------- channels/misdn/isdn_lib.h | 2 ++ 3 files changed, 52 insertions(+), 22 deletions(-) (limited to 'channels') diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index 98c982ba1..a74229977 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -3379,6 +3379,8 @@ 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) { struct chan_list *help=list; + + if (bc->pri) return NULL; chan_misdn_log(6, bc->port, "$$$ find_holded: channel:%d oad:%s dad:%s\n",bc->channel, bc->oad,bc->dad); for (;help; help=help->next) { diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index d9632a003..249ba50fe 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -549,9 +549,7 @@ static void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state static void empty_bc(struct misdn_bchannel *bc) { bc->bframe_len=0; - - bc->in_use= 0; bc->cw= 0; bc->dec=0; @@ -671,6 +669,7 @@ static int clean_up_bc(struct misdn_bchannel *bc) mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); bc->b_stid = 0; + bc->in_use = 0; bc_state_change(bc, BCHAN_CLEANED); return ret; @@ -1118,6 +1117,7 @@ int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, in bc->port=stack->port; bc->nt=stack->nt?1:0; + bc->pri=stack->pri; { ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE); @@ -1500,14 +1500,6 @@ static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_ switch (event) { case EVENT_CONNECT_ACKNOWLEDGE: -#if 0 - if ( !misdn_cap_is_speech(bc->capability)) { - int ret=setup_bc(bc); - if (ret == -EINVAL){ - cb_log(0,bc->port,"send_event: setup_bc failed\n"); - } - } -#endif break; case EVENT_CONNECT: @@ -1599,10 +1591,9 @@ static int handle_cr ( struct misdn_stack *stack, iframe_t *frm) } if (bc) { + int channel = bc->channel; cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo); - if (bc->channel>0) - empty_chan_in_stack(stack,bc->channel); - + /*bc->pid = 0;*/ bc->need_disconnect=0; bc->need_release=0; @@ -1612,6 +1603,10 @@ static int handle_cr ( struct misdn_stack *stack, iframe_t *frm) empty_bc(bc); clean_up_bc(bc); + + if (channel>0) + empty_chan_in_stack(stack,bc->channel); + dump_chan_list(stack); if (bc->stack_holder) { @@ -2066,12 +2061,16 @@ handle_event_nt(void *dat, void *arg) break; case EVENT_RELEASE: case EVENT_RELEASE_COMPLETE: - if (bc->channel>0) - empty_chan_in_stack(stack, bc->channel); + { + int channel=bc->channel; int tmpcause=bc->cause; empty_bc(bc); bc->cause=tmpcause; clean_up_bc(bc); + + if (channel>0) + empty_chan_in_stack(stack, bc->channel); + } break; default: @@ -2638,6 +2637,7 @@ handle_frm_bc: empty_chan_in_stack(stack, bc->channel); empty_bc(bc); bc_state_change(bc,BCHAN_CLEANED); + bc->in_use=0; cb_log(0, stack->port, "GOT IGNORE SETUP\n"); @@ -2655,14 +2655,22 @@ handle_frm_bc: if (event == EVENT_RELEASE_COMPLETE) { /* release bchannel only after we've anounced the RELEASE_COMPLETE */ - if (bc->channel>0) - empty_chan_in_stack(stack,bc->channel); + int channel=bc->channel; int tmpcause=bc->cause; int tmp_out_cause=bc->out_cause; empty_bc(bc); bc->cause=tmpcause; bc->out_cause=tmp_out_cause; clean_up_bc(bc); + + if (tmpcause == 44) { + cb_log(0,stack->port,"**** Received CAUSE:44, so not cleaning up channel %d\n", channel); + cb_log(0,stack->port,"**** This channel is now no longer available,\nplease try to restart it with 'misdn send restart '\n"); + set_chan_in_stack(stack,bc->channel); + } else { + if (channel>0) + empty_chan_in_stack(stack,bc->channel); + } } cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim); @@ -3342,11 +3350,14 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) misdn_split_conf(bc2,bc->conf_id); } } + + int channel=bc->channel; - if (bc->channel>0) - empty_chan_in_stack(stack,bc->channel); empty_bc(bc); clean_up_bc(bc); + + if (channel>0) + empty_chan_in_stack(stack,bc->channel); } } @@ -3380,14 +3391,17 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) if (!stack->nt) { /*create clenaup in TE*/ - if (bc->channel>0) - empty_chan_in_stack(stack,bc->channel); + int channel=bc->channel; + int tmpcause=bc->cause; int tmp_out_cause=bc->out_cause; empty_bc(bc); bc->cause=tmpcause; bc->out_cause=tmp_out_cause; clean_up_bc(bc); + + if (channel>0) + empty_chan_in_stack(stack,bc->channel); } break; @@ -3676,9 +3690,21 @@ int misdn_lib_send_restart(int port, int channel) for (;i<=max;i++) { dummybc.channel=i; - cb_log(0, port, "Restarting channel %d\n",i); + cb_log(0, port, "Restarting and cleaning channel %d\n",i); misdn_lib_send_event(&dummybc, EVENT_RESTART); /*do we need to wait before we get an EVENT_RESTART_ACK ?*/ + + /* clean up chan in stack, to be sure we don't think it's + * in use anymore */ + int cnt; + for (cnt=0; cnt<=stack->b_num; cnt++) { + if (stack->bc[cnt].channel == i) { + empty_bc(&stack->bc[cnt]); + clean_up_bc(&stack->bc[cnt]); + } + } + empty_chan_in_stack(stack, i); + } return 0; diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h index 5ad837a2a..4eab0d5cd 100644 --- a/channels/misdn/isdn_lib.h +++ b/channels/misdn/isdn_lib.h @@ -202,6 +202,8 @@ struct misdn_bchannel { struct send_lock *send_lock; int nt; + int pri; + int port; /** init stuff **/ int b_stid; -- cgit v1.2.3