diff options
author | crichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-10-06 10:44:34 +0000 |
---|---|---|
committer | crichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-10-06 10:44:34 +0000 |
commit | e8b084baa07b898eccd35bb5c5eec81028998331 (patch) | |
tree | 6852f9e7e9aaaafd7958039f4ccf2de50e21fbaf /channels | |
parent | b97375bc72d01557442ed5e13539c1a8562670c6 (diff) |
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: http://svn.digium.com/svn/asterisk/branches/1.4@44559 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_misdn.c | 189 | ||||
-rw-r--r-- | channels/misdn/isdn_lib.c | 82 | ||||
-rw-r--r-- | channels/misdn/isdn_lib.h | 2 |
3 files changed, 183 insertions, 90 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index c1a0f0dfc..a048e70fb 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -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) @@ -916,6 +930,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 */ }; @@ -989,7 +1004,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, @@ -1003,7 +1018,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 ); } @@ -1020,11 +1035,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)); + } } } @@ -2078,7 +2105,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 */ ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n"); MISDN_ASTERISK_TECH_PVT(ast)=NULL; @@ -2262,6 +2291,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; @@ -2474,6 +2509,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; @@ -2514,17 +2550,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; @@ -2571,7 +2607,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) { @@ -3142,16 +3178,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); @@ -3220,16 +3270,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; @@ -3239,7 +3290,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; @@ -3248,9 +3299,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"); } } @@ -3260,7 +3311,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; } @@ -3331,7 +3382,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)); } @@ -3389,6 +3440,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); @@ -3630,6 +3682,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); @@ -3732,6 +3785,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; @@ -3756,9 +3810,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 */ + } } } @@ -4100,9 +4160,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; @@ -4135,18 +4193,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); @@ -4237,6 +4299,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 ; @@ -4327,23 +4390,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; @@ -4358,31 +4423,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"); diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index 19268d0e6..2f69d1759 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -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; } @@ -1408,21 +1407,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; } @@ -1745,16 +1756,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; } } @@ -3178,8 +3190,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); @@ -3198,9 +3208,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 ) { @@ -3228,14 +3235,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) @@ -3244,11 +3264,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; @@ -4084,6 +4099,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) { diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h index 4289b42ba..4eda56cbf 100644 --- a/channels/misdn/isdn_lib.h +++ b/channels/misdn/isdn_lib.h @@ -294,8 +294,6 @@ struct misdn_bchannel { int holded; int stack_holder; - struct misdn_bchannel *holded_bc; - int pres; int screen; |