Merged revisions 44559 via svnmerge from
authorChristian Richter <christian.richter@beronet.com>
Wed, 11 Oct 2006 08:23:16 +0000 (08:23 +0000)
committerChristian Richter <christian.richter@beronet.com>
Wed, 11 Oct 2006 08:23:16 +0000 (08:23 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r44559 | crichter | 2006-10-06 12:44:34 +0200 (Fr, 06 Okt 2006) | 9 lines

Merged revisions 44149 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r44149 | crichter | 2006-10-02 15:28:14 +0200 (Mo, 02 Okt 2006) | 1 line

fixed the hold/retrieve/transfer issues, removed a useless bc field, added setting of frame.delivery fields, some minor code cleanups
........

................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@44840 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_misdn.c
channels/misdn/isdn_lib.c
channels/misdn/isdn_lib.h

index dcad080..67c8845 100644 (file)
@@ -130,13 +130,19 @@ enum misdn_chan_state {
        MISDN_HUNGUP_FROM_AST, /*!< when DISCONNECT/RELEASE/REL_COMP came out of */
        /* misdn_hangup */
        MISDN_HOLDED, /*!< if this chan is holded */
-       MISDN_HOLD_DISCONNECT /*!< if this chan is holded */
+       MISDN_HOLD_DISCONNECT, /*!< if this chan is holded */
+       MISDN_FIXUP/*!< if this chan is holded */
   
 };
 
 #define ORG_AST 1
 #define ORG_MISDN 2
 
+struct hold_info {
+       int port;
+       int channel;
+};
+
 struct chan_list {
   
        char allowed_bearers[BUFFERSIZE+1];
@@ -180,7 +186,8 @@ struct chan_list {
        int dummy;
   
        struct misdn_bchannel *bc;
-       struct misdn_bchannel *holded_bc;
+
+       struct hold_info hold_info;
 
        unsigned int l3id;
        int addr;
@@ -346,6 +353,13 @@ int add_in_calls(int port);
 
 static int update_ec_config(struct misdn_bchannel *bc);
 
+
+
+
+/*protos*/ 
+
+int chan_misdn_jb_empty ( struct misdn_bchannel *bc, char *buf, int len); 
+
 /*************** Helpers *****************/
 
 static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
@@ -915,6 +929,7 @@ static struct state_struct state_array[] = {
        {MISDN_HUNGUP_FROM_MISDN,"HUNGUP_FROM_MISDN"}, /* when DISCONNECT/RELEASE/REL_COMP  cam from misdn */
        {MISDN_HOLDED,"HOLDED"}, /* when DISCONNECT/RELEASE/REL_COMP  cam from misdn */
        {MISDN_HOLD_DISCONNECT,"HOLD_DISCONNECT"}, /* when DISCONNECT/RELEASE/REL_COMP  cam from misdn */
+       {MISDN_FIXUP,"FIXUP"}, /**/
        {MISDN_HUNGUP_FROM_AST,"HUNGUP_FROM_AST"} /* when DISCONNECT/RELEASE/REL_COMP came out of */
        /* misdn_hangup */
 };
@@ -988,7 +1003,7 @@ static void print_bc_info (int fd, struct chan_list* help, struct misdn_bchannel
                        "  --> capability: %s\n"
                        "  --> echo_cancel: %d\n"
                        "  --> notone : rx %d tx:%d\n"
-                       "  --> bc_hold: %d holded_bc :%d\n",
+                       "  --> bc_hold: %d\n",
                        help->ast->name,
                        help->l3id,
                        help->addr,
@@ -1002,7 +1017,7 @@ static void print_bc_info (int fd, struct chan_list* help, struct misdn_bchannel
                        bc->ec_enable,
 
                        help->norxtone,help->notxtone,
-                       bc->holded, help->holded_bc?1:0
+                       bc->holded
                        );
   
 }
@@ -1019,11 +1034,23 @@ static int misdn_show_cls (int fd, int argc, char *argv[])
                if (misdn_debug[0] > 2) ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
                if (bc) {
                        print_bc_info(fd, help, bc);
-               } else if ( (bc=help->holded_bc) ) {
-                       chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
-                       print_bc_info(fd, help,  bc);
                } else {
-                       ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
+                       if (help->state == MISDN_HOLDED) {
+                               chan_misdn_log(0, 0, "ITS A HOLDED BC:\n");
+                               chan_misdn_log(0,0," --> l3_id: %x\n"
+                                               " --> dad:%s oad:%s\n"
+                                               " --> hold_port: %d\n"
+                                               " --> hold_channel: %d\n"
+                               
+                                               ,help->l3id
+                                               ,ast->exten
+                                               ,AST_CID_P(ast)
+                                               ,help->hold_info.port
+                                               ,help->hold_info.channel
+                                               );
+                       } else {
+                               ast_cli(fd,"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, AST_CID_P(ast));
+                       }
                }
        }
   
@@ -2077,7 +2104,7 @@ static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
        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);
        
        p->ast = ast ;
-       p->state=MISDN_CONNECTED;
+       p->state=MISDN_FIXUP;
   
        return 0;
 }
@@ -2235,10 +2262,6 @@ static int misdn_hangup(struct ast_channel *ast)
        
        bc=p->bc;
 
-       if (!bc) {
-               ast_log(LOG_WARNING,"Hangup with private but no bc ?\n");
-               return 0;
-       }
 
        
        MISDN_ASTERISK_TECH_PVT(ast)=NULL;
@@ -2246,7 +2269,13 @@ static int misdn_hangup(struct ast_channel *ast)
 
        bc=p->bc;
        
-       if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) {
+       if (ast->_state == AST_STATE_RESERVED || 
+               p->state == MISDN_NOTHING || 
+               p->state == MISDN_HOLDED || 
+               p->state == MISDN_FIXUP || 
+               p->state == MISDN_HOLD_DISCONNECT ) {
+
+               CLEAN_CH:
                /* between request and call */
                if (option_debug)
                        ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
@@ -2263,6 +2292,12 @@ static int misdn_hangup(struct ast_channel *ast)
                return 0;
        }
 
+       if (!bc) {
+               ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id);
+               goto CLEAN_CH;
+       }
+
+
        p->need_hangup=0;
        p->need_queue_hangup=0;
        p->need_busy=0;
@@ -2480,6 +2515,7 @@ static struct ast_frame  *misdn_read(struct ast_channel *ast)
        tmp->frame.samples = len;
        tmp->frame.mallocd = 0;
        tmp->frame.offset = 0;
+       tmp->frame.delivery= ast_tv(0,0) ;
        tmp->frame.src = NULL;
        tmp->frame.data = tmp->ast_rd_buf;
 
@@ -2520,17 +2556,17 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
        int i  = 0;
        
        if (!ast || ! (ch=MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
+
+       if (ch->state == MISDN_HOLDED) {
+               chan_misdn_log(7, 0, "misdn_write: Returning because holded\n");
+               return 0;
+       }
        
        if (!ch->bc ) {
                ast_log(LOG_WARNING, "private but no bc\n");
                return -1;
        }
        
-       if (ch->state == MISDN_HOLDED) {
-               chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because holded\n");
-               return 0;
-       }
-       
        if (ch->notxtone) {
                chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxone\n");
                return 0;
@@ -2577,7 +2613,7 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
                        break;
                default:
                if (!ch->dropped_frame_cnt)
-                       chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d\n",frame->samples,ch->bc->addr, ast->exten, ast->cid.cid_num,misdn_get_ch_state( ch), ch->bc->bc_state);
+                       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);
                
                ch->dropped_frame_cnt++;
                if (ch->dropped_frame_cnt > 100) {
@@ -3148,16 +3184,30 @@ static struct chan_list *find_holded(struct chan_list *list, struct misdn_bchann
        
        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) {
-               chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->bc->holded, help->bc->channel);
-               if (help->bc->port == bc->port
-                   && help->bc->holded ) return help;
-       }
-       
+               chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",help->state==MISDN_HOLDED, help->hold_info.channel);
+               if (    (help->state == MISDN_HOLDED) && 
+                       (help->hold_info.port == bc->port) ) 
+                       return help;
+       }       
        chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n",bc->oad,bc->dad);
   
        return NULL;
 }
 
+
+static struct chan_list *find_holded_l3(struct chan_list *list, unsigned long l3_id, int w) 
+
+{
+       struct chan_list *help=list;
+
+       for (;help; help=help->next) {
+               if ( (help->state == MISDN_HOLDED) &&
+                        (help->l3id == l3_id)   
+                       ) 
+                       return help;
+       }
+}
+
 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan)
 {
        chan_misdn_log(4, chan->bc? chan->bc->port : 0, "* Queuing chan %p\n",chan);
@@ -3226,16 +3276,17 @@ int pbx_start_chan(struct chan_list *ch)
 
 static void hangup_chan(struct chan_list *ch)
 {
+       int port=ch?ch->bc?ch->bc->port:0:0;
        if (!ch) {
                cb_log(1,0,"Cannot hangup chan, no ch\n");
                return;
        }
 
-       cb_log(1,ch->bc?ch->bc->port:0,"hangup_chan\n");
+       cb_log(1,port,"hangup_chan\n");
 
        if (ch->need_hangup) 
        {
-               cb_log(1,ch->bc->port,"-> hangup\n");
+               cb_log(1,port,"-> hangup\n");
                send_cause2ast(ch->ast,ch->bc,ch);
                ch->need_hangup=0;
                ch->need_queue_hangup=0;
@@ -3245,7 +3296,7 @@ static void hangup_chan(struct chan_list *ch)
        }
 
        if (!ch->need_queue_hangup) {
-               cb_log(1,ch->bc->port,"No need to queue hangup\n");
+               cb_log(1,port,"No need to queue hangup\n");
        }
 
        ch->need_queue_hangup=0;
@@ -3254,9 +3305,9 @@ static void hangup_chan(struct chan_list *ch)
 
                if (ch->ast)
                        ast_queue_hangup(ch->ast);
-               cb_log(1,ch->bc->port,"-> queue_hangup\n");
+               cb_log(1,port,"-> queue_hangup\n");
        } else {
-               cb_log(1,ch->bc->port,"Cannot hangup chan, no ast\n");
+               cb_log(1,port,"Cannot hangup chan, no ast\n");
        }
 }
 
@@ -3266,7 +3317,7 @@ static void release_chan(struct misdn_bchannel *bc) {
        {
                struct chan_list *ch=find_chan_by_bc(cl_te, bc);
                if (!ch)  {
-                       chan_misdn_log(0, bc->port, "release_chan: Ch not found!\n");
+                       chan_misdn_log(1, bc->port, "release_chan: Ch not found!\n");
                        return;
                }
                
@@ -3337,7 +3388,7 @@ static void misdn_transfer_bc(struct chan_list *tmp_ch, struct chan_list *holded
        ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
 
        holded_chan->state=MISDN_CONNECTED;
-       misdn_lib_transfer(holded_chan->bc?holded_chan->bc:holded_chan->holded_bc);
+       //misdn_lib_transfer(holded_chan->bc);
        ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
 }
 
@@ -3395,6 +3446,7 @@ static void do_immediate_setup(struct misdn_bchannel *bc,struct chan_list *ch ,
                fr.samples = 0 ;
                fr.mallocd =0 ;
                fr.offset= 0 ;
+               fr.delivery= ast_tv(0,0) ;
 
                if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
                        ast_queue_frame(ch->ast, &fr);
@@ -3636,6 +3688,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                fr.samples = 0 ;
                fr.mallocd =0 ;
                fr.offset= 0 ;
+               fr.delivery= ast_tv(0,0) ;
                
                if (!ch->ignore_dtmf) {
                        chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
@@ -3738,6 +3791,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                        fr.samples = 0 ;
                        fr.mallocd =0 ;
                        fr.offset= 0 ;
+                       fr.delivery= ast_tv(0,0) ;
 
                        
                        int digits;
@@ -3762,9 +3816,15 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
        case EVENT_SETUP:
        {
                struct chan_list *ch=find_chan_by_bc(cl_te, bc);
-               if (ch && ch->state != MISDN_NOTHING ) {
-                       chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
-                       return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE;
+               if (ch) {
+                       switch (ch->state) {
+                               case MISDN_NOTHING:
+                               ch=NULL;
+                               break;
+                               default:
+                               chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
+                               return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /*  Ignore MSNs which are not in our List */
+                       }
                }
        }
        
@@ -4106,9 +4166,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                }
        }
        
-       
        /* notice that we don't break here!*/
-
        case EVENT_CONNECT_ACKNOWLEDGE:
        {
                ch->l3id=bc->l3_id;
@@ -4141,18 +4199,22 @@ 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 ) {
+               if (    holded_ch && 
+                       holded_ch != ch && 
+                       ch->ast && 
+                       ch->state == MISDN_CONNECTED    ) {
                        cb_log(1,bc->port," --> found holded ch\n");
-                       if  (ch->state == MISDN_CONNECTED ) {
-                               misdn_transfer_bc(ch, holded_ch) ;
-                               hangup_chan(ch);
-                       //      release_chan(bc);
-                               break;
-                       }
+                       misdn_transfer_bc(ch, holded_ch) ;
                }
                
                stop_bc_tones(ch);
                hangup_chan(ch);
+       } else {
+       /*      ch=find_holded_l3(cl_te, bc->l3_id,1);
+               if (ch) {
+                       hangup_chan(ch);
+               }
+       */
        }
        bc->out_cause=-1;
        if (bc->need_release) misdn_lib_send_event(bc,EVENT_RELEASE);
@@ -4243,6 +4305,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                        frame.samples = bc->bframe_len ;
                        frame.mallocd =0 ;
                        frame.offset= 0 ;
+                       frame.delivery= ast_tv(0,0) ;
                        frame.src = NULL;
                        frame.data = bc->bframe ;
                        
@@ -4333,23 +4396,25 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
        /***************************/
        case EVENT_RETRIEVE:
        {
-               ch=find_holded(cl_te, bc);
+               ch=find_holded_l3(cl_te, bc->l3_id,1);
                if (!ch) {
                        ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
                        misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
                        break;
                }
-               struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
+
+               /*remember the channel again*/
+               ch->bc=bc;
                ch->state = MISDN_CONNECTED;
+
+               struct ast_channel *hold_ast=AST_BRIDGED_P(ch->ast);
                
                if (hold_ast) {
                        ast_moh_stop(hold_ast);
                }
-               
+       
                if ( misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
                        misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
-               
-               
        }
        break;
     
@@ -4364,31 +4429,25 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                        misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
                        break;
                }
-
-#if 0
-               {
-                       struct chan_list *holded_ch=find_holded(cl_te, bc);
-                       if (holded_ch) {
-                               misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
-
-                               chan_misdn_log(-1, bc->port, "We can't use RETRIEVE at the moment due to mISDN bug!\n");
-                               break;
-                       }
-               }
-#endif
-               struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
                
-               if (bridged){
-                       struct chan_list *bridged_ch=MISDN_ASTERISK_TECH_PVT(bridged);
+               struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
+
+               if (bridged) {
+                       chan_misdn_log(2,bc->port,"Bridge Partner is of type: %s\n",bridged->tech->type);
                        ch->state = MISDN_HOLDED;
                        ch->l3id = bc->l3_id;
                        
-                       bc->holded_bc=bridged_ch->bc;
                        misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
 
                        /* XXX This should queue an AST_CONTROL_HOLD frame on this channel
                         * instead of starting moh on the bridged channel directly */
                        ast_moh_start(bridged, NULL, NULL);
+
+                       /*forget the channel now*/
+                       ch->bc=NULL;
+                       ch->hold_info.port=bc->port;
+                       ch->hold_info.channel=bc->channel;
+
                } else {
                        misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
                        chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
index 1ccea50..b2fb1d1 100644 (file)
@@ -501,7 +501,8 @@ char *bc_state2str(enum bchannel_state state) {
 
 void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
 {
-       cb_log(5,bc->port,"BC_STATE_CHANGE: from:%s to:%s\n",
+       cb_log(5,bc->port,"BC_STATE_CHANGE: l3id:%x from:%s to:%s\n",
+               bc->l3_id,
               bc_state2str(bc->bc_state),
               bc_state2str(state) );
        
@@ -616,8 +617,6 @@ static void empty_bc(struct misdn_bchannel *bc)
        bc->fac_out.Function = Fac_None;
        
        bc->te_choose_channel = 0;
-
-       bc->holded_bc=NULL;
 }
 
 
@@ -1409,21 +1408,33 @@ static struct misdn_bchannel *find_bc_by_addr(unsigned long addr)
        struct misdn_stack* stack;
        int i;
 
-       
        for (stack=glob_mgr->stack_list;
             stack;
             stack=stack->next) {
-               
                for (i=0; i< stack->b_num; i++) {
-
                        if ( (stack->bc[i].addr&STACK_ID_MASK)==(addr&STACK_ID_MASK) ||  stack->bc[i].layer_id== addr ) {
                                return &stack->bc[i];
                        }
                }
-               
        }
+       
+       return NULL;
+}
 
+struct misdn_bchannel *find_bc_by_confid(unsigned long confid)
+{
+       struct misdn_stack* stack;
+       int i;
        
+       for (stack=glob_mgr->stack_list;
+            stack;
+            stack=stack->next) {
+               for (i=0; i< stack->b_num; i++) {
+                       if ( stack->bc[i].conf_id==confid ) {
+                               return &stack->bc[i];
+                       }
+               }
+       }
        return NULL;
 }
 
@@ -1746,16 +1757,17 @@ handle_event_nt(void *dat, void *arg)
                        
                        struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
                        struct misdn_bchannel *hold_bc=stack_holder_find(stack,bc->l3_id);
+                       cb_log(4, stack->port, "bc_l3id:%x holded_bc_l3id:%x\n",bc->l3_id, hold_bc->l3_id);
 
                        if (hold_bc) {
-
                                cb_log(4, stack->port, "REMOVEING Holder\n");
-                               stack_holder_remove(stack, hold_bc);
 
+                               /*swap the backup to our new channel back*/
+                               stack_holder_remove(stack, hold_bc);
                                memcpy(bc,hold_bc,sizeof(struct misdn_bchannel));
-                               cb_event(EVENT_NEW_BC, hold_bc, bc);
-
                                free(hold_bc);
+
+                               bc->holded=0;
                        }
                        
                }
@@ -3179,8 +3191,6 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
        case EVENT_CONNECT:
        case EVENT_RETRIEVE_ACKNOWLEDGE:
 
-               bc->holded=0;
-               
                if (stack->nt) {
                        if (bc->channel <=0 ) { /*  else we have the channel already */
                                bc->channel = find_free_chan_in_stack(stack, bc, 0);
@@ -3199,9 +3209,6 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
                        cb_log(0,bc->port,"send_event: setup_bc failed\n");
                }
 
-               cb_log(0,bc->port,"After SETUP BC\n");
-
-               
                if (misdn_cap_is_speech(bc->capability)) {
                        if ((event==EVENT_CONNECT)||(event==EVENT_RETRIEVE_ACKNOWLEDGE)) {
                                if ( *bc->crypt_key ) {
@@ -3229,14 +3236,27 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
        case EVENT_HOLD_ACKNOWLEDGE:
        {
                struct misdn_bchannel *holded_bc=malloc(sizeof(struct misdn_bchannel));
+               if (!holded_bc) {
+                       cb_log(0,bc->port, "Could not allocate holded_bc!!!\n");
+                       return -1;
+               }
+
+               /*backup the bc*/
                memcpy(holded_bc,bc,sizeof(struct misdn_bchannel));
                holded_bc->holded=1;
+               bc_state_change(holded_bc,BCHAN_CLEANED);
+
                stack_holder_add(stack,holded_bc);
-               
+       
+               /*kill the bridge and clean the bchannel*/
                if (stack->nt) {
                        if (bc->bc_state == BCHAN_BRIDGED) {
                                misdn_split_conf(bc,bc->conf_id);
-                               misdn_split_conf(bc->holded_bc,bc->holded_bc->conf_id);
+                               struct misdn_bchannel *bc2=find_bc_by_confid(bc->conf_id);
+                               if (!bc2) 
+                                       cb_log(0,bc->port,"We have no second bc in bridge???\n");
+                               else 
+                                       misdn_split_conf(bc2,bc->conf_id);
                        }
 
                        if (bc->channel>0)
@@ -3245,11 +3265,6 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
                        clean_up_bc(bc);
                }
                
-               /** we set it up later at RETRIEVE_ACK again.**/
-               /*holded_bc->upset=0;
-                 holded_bc->active=0;*/
-               bc_state_change(holded_bc,BCHAN_CLEANED);
-               cb_event( EVENT_NEW_BC, bc,  holded_bc);
        }
        break;
 
@@ -4085,6 +4100,27 @@ void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holde
        }
 }
 
+struct misdn_bchannel *stack_holder_find_bychan(struct misdn_stack *stack, int chan)
+{
+       struct misdn_bchannel *help;
+
+       cb_log(4,stack?stack->port:0, "*HOLDER: find_bychan %c\n", chan);
+       
+       if (!stack) return NULL;
+       
+       for (help=stack->holding;
+            help;
+            help=help->next) {
+               if (help->channel == chan) {
+                       cb_log(4,stack->port, "*HOLDER: found_bychan bc\n");
+                       return help;
+               }
+       }
+
+       cb_log(4,stack->port, "*HOLDER: find_bychan nothing\n");
+       return NULL;
+
+}
 
 struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id)
 {
index 4289b42..4eda56c 100644 (file)
@@ -294,8 +294,6 @@ struct misdn_bchannel {
        int holded;
        int stack_holder;
 
-       struct misdn_bchannel *holded_bc;
-       
        int pres;
        int screen;