From 0f39ea1a985a019d2e20c8b01d91163d5f6fd767 Mon Sep 17 00:00:00 2001 From: Christian Richter Date: Fri, 18 May 2007 09:50:33 +0000 Subject: Merged revisions 62912 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ................ r62912 | crichter | 2007-05-03 16:36:32 +0200 (Do, 03 Mai 2007) | 17 lines Merged revisions 61357,61770,62885 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r61357 | crichter | 2007-04-11 14:05:57 +0200 (Mi, 11 Apr 2007) | 1 line some fixes for PMP Hold/Retrieve, it should work now, when briding=no ........ r61770 | crichter | 2007-04-24 15:50:05 +0200 (Di, 24 Apr 2007) | 1 line added lock for sending messages to avoid double sending. shuffled some empty_chans after the cb_event calls, this avoids that a release_complete from a quite different call releases a fresh created setup by accident. ........ r62885 | crichter | 2007-05-03 15:59:00 +0200 (Do, 03 Mai 2007) | 1 line fixed the problem that misdn_write did not return -1 when called with 0 samples in a frame this resultet in a deadlock in some circumstances, when the call ended because of a busy extension. added encoding of keypad. ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@64955 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_misdn.c | 13 +++-- channels/misdn/ie.c | 2 +- channels/misdn/isdn_lib.c | 110 ++++++++++++++++++++++++--------------- channels/misdn/isdn_lib.h | 1 + channels/misdn/isdn_lib_intern.h | 4 ++ channels/misdn/isdn_msg_parser.c | 4 ++ 6 files changed, 87 insertions(+), 47 deletions(-) diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index 2b759d203..3fa63317b 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -1124,8 +1124,8 @@ static int misdn_show_cls (int fd, int argc, char *argv[]) print_bc_info(fd, help, bc); } else { if (help->state == MISDN_HOLDED) { - chan_misdn_log(2, 0, "ITS A HOLDED BC:\n"); - chan_misdn_log(2,0," --> l3_id: %x\n" + ast_cli(fd, "ITS A HOLDED BC:\n"); + ast_cli(fd, " --> l3_id: %x\n" " --> dad:%s oad:%s\n" " --> hold_port: %d\n" " --> hold_channel: %d\n" @@ -2621,7 +2621,8 @@ static struct ast_frame *misdn_read(struct ast_channel *ast) chan_misdn_log(1,0,"misdn_read called without ast->pvt\n"); return NULL; } - if (!tmp->bc) { + + if (!tmp->bc && !(tmp->state==MISDN_HOLDED)) { chan_misdn_log(1,0,"misdn_read called without bc\n"); return NULL; } @@ -4625,7 +4626,11 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data) /***************************/ case EVENT_RETRIEVE: { - ch=find_holded_l3(cl_te, bc->l3_id,1); + if (!ch) { + chan_misdn_log(4, bc->port, " --> no CH, searching in holded"); + 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); diff --git a/channels/misdn/ie.c b/channels/misdn/ie.c index 3fbccab3e..9b86fe4ef 100644 --- a/channels/misdn/ie.c +++ b/channels/misdn/ie.c @@ -938,7 +938,7 @@ static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, int #endif /* IE_KEYPAD */ -#if 0 +#if 1 static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int nt, struct misdn_bchannel *bc) { unsigned char *p; diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c index 8b91937e5..9b8171d17 100644 --- a/channels/misdn/isdn_lib.c +++ b/channels/misdn/isdn_lib.c @@ -1103,6 +1103,10 @@ int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, in cb_log(8, port, "Init.BC %d.\n",bidx); memset(bc, 0,sizeof(struct misdn_bchannel)); + + bc->send_lock=malloc(sizeof(struct send_lock)); + + pthread_mutex_init(&bc->send_lock->lock, NULL); if (msn) { int l = sizeof(bc->msn); @@ -1208,6 +1212,7 @@ struct misdn_stack* stack_init( int midev, int port, int ptp ) stack->nt=1; break; +#ifndef MISDN_1_2 case ISDN_PID_L0_TE_U: break; case ISDN_PID_L0_NT_U: @@ -1216,6 +1221,7 @@ struct misdn_stack* stack_init( int midev, int port, int ptp ) break; case ISDN_PID_L0_NT_UP2: break; +#endif case ISDN_PID_L0_TE_E1: cb_log(8, port, "TE S2M Stack\n"); stack->nt=0; @@ -1547,14 +1553,6 @@ static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_ case EVENT_RELEASE_COMPLETE: case EVENT_RELEASE: - if (bc->channel>0) - empty_chan_in_stack(stack,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); break; default: break; @@ -1609,17 +1607,18 @@ static int handle_cr ( struct misdn_stack *stack, iframe_t *frm) cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo); if (bc->channel>0) empty_chan_in_stack(stack,bc->channel); - empty_bc(bc); - - clean_up_bc(bc); - dump_chan_list(stack); /*bc->pid = 0;*/ bc->need_disconnect=0; bc->need_release=0; bc->need_release_complete=0; - + cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data); + + empty_bc(bc); + clean_up_bc(bc); + dump_chan_list(stack); + if (bc->stack_holder) { cb_log(4,stack->port, "REMOVEING Holder\n"); stack_holder_remove( stack, bc); @@ -1823,7 +1822,7 @@ handle_event_nt(void *dat, void *arg) return 0; } - cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo); + cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo); bc->l3_id=hh->dinfo; } break; @@ -2657,6 +2656,18 @@ 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 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); + } + cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim); @@ -3186,21 +3197,40 @@ void misdn_lib_log_ies(struct misdn_bchannel *bc) cb_log(5, stack->port, " --> bc:%x h:%d sh:%d\n", bc, bc->holded, bc->stack_holder); } +void misdn_send_lock(struct misdn_bchannel *bc); +void misdn_send_unlock(struct misdn_bchannel *bc); + +#define RETURN(a,b) {retval=a; goto b;} + +void misdn_send_lock(struct misdn_bchannel *bc) +{ + //cb_log(0,bc->port,"Locking bc->pid:%d\n", bc->pid); + pthread_mutex_lock(&bc->send_lock->lock); +} + +void misdn_send_unlock(struct misdn_bchannel *bc) +{ + //cb_log(0,bc->port,"UnLocking bc->pid:%d\n", bc->pid); + pthread_mutex_unlock(&bc->send_lock->lock); +} + int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) { msg_t *msg; - int err = -1 ; - int ret=0; + int retval=0; - if (!bc) goto ERR; + if (!bc) RETURN(-1,OUT_POST_UNLOCK); struct misdn_stack *stack=get_stack_by_bc(bc); if (!stack) { cb_log(0,bc->port,"SENDEVENT: no Stack for event:%s oad:%s dad:%s \n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad); - return -1; + RETURN(-1,OUT); } + misdn_send_lock(bc); + + cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->uperid:%x\n",stack->nt, stack->upper_id); if ( stack->nt && !stack->l1link) { @@ -3208,7 +3238,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) bc->evq=event; cb_log(1, stack->port, "Queueing Event %s because L1 is down (btw. Activating L1)\n", isdn_get_info(msgs_g, event, 0)); misdn_lib_get_l1_up(stack); - return 0; + RETURN(0,OUT); } cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s pid:%d\n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad, bc->pid); @@ -3220,8 +3250,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) if (create_process(glob_mgr->midev, bc)<0) { cb_log(0, stack->port, " No free channel at the moment @ send_event\n"); - err=-ENOCHAN; - goto ERR; + RETURN(-ENOCHAN,OUT); } #if 0 if (stack->nt) { @@ -3237,8 +3266,6 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) case EVENT_ALERTING: case EVENT_PROCEEDING: case EVENT_SETUP_ACKNOWLEDGE: - if (!bc->nt && !stack->ptp) break; - case EVENT_CONNECT: case EVENT_RETRIEVE_ACKNOWLEDGE: @@ -3247,21 +3274,19 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) if (!find_free_chan_in_stack(stack, bc, 0,0)) { cb_log(0, stack->port, " No free channel at the moment\n"); /*FIXME: add disconnect*/ - err=-ENOCHAN; - goto ERR; + RETURN(-ENOCHAN,OUT); } if (set_chan_in_stack(stack ,bc->channel)<0) { /*FIXME: add disconnect*/ - err=-ENOCHAN; - goto ERR; + RETURN(-ENOCHAN,OUT); } } /* Its that i generate channels */ } - ret=setup_bc(bc); - if (ret == -EINVAL) { + retval=setup_bc(bc); + if (retval == -EINVAL) { cb_log(0,bc->port,"send_event: setup_bc failed\n"); } @@ -3294,7 +3319,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) 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; + RETURN(-1,OUT); } /*backup the bc*/ @@ -3309,10 +3334,11 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) if (bc->bc_state == BCHAN_BRIDGED) { misdn_split_conf(bc,bc->conf_id); struct misdn_bchannel *bc2=find_bc_by_confid(bc->conf_id); - if (!bc2) + if (!bc2) { cb_log(0,bc->port,"We have no second bc in bridge???\n"); - else + } else { misdn_split_conf(bc2,bc->conf_id); + } } if (bc->channel>0) @@ -3328,7 +3354,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) case EVENT_DISCONNECT: if (!bc->need_disconnect) { cb_log(0,bc->port," --> we have already send Disconnect\n"); - return -1; + RETURN(-1,OUT); } bc->need_disconnect=0; @@ -3336,7 +3362,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) case EVENT_RELEASE: if (!bc->need_release) { cb_log(0,bc->port," --> we have already send Release\n"); - return -1; + RETURN(-1,OUT); } bc->need_disconnect=0; bc->need_release=0; @@ -3344,7 +3370,7 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) case EVENT_RELEASE_COMPLETE: if (!bc->need_release_complete) { cb_log(0,bc->port," --> we have already send Release_complete\n"); - return -1; + RETURN(-1,OUT); } bc->need_disconnect=0; bc->need_release=0; @@ -3366,13 +3392,12 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) case EVENT_CONNECT_ACKNOWLEDGE: if ( bc->nt || misdn_cap_is_speech(bc->capability)) { - int ret=setup_bc(bc); - if (ret == -EINVAL){ + int retval=setup_bc(bc); + if (retval == -EINVAL){ cb_log(0,bc->port,"send_event: setup_bc failed\n"); } } - if (misdn_cap_is_speech(bc->capability)) { if ( !bc->nodsp) manager_ph_control(bc, DTMF_TONE_START, 0); @@ -3398,10 +3423,11 @@ int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event ) msg_queue_tail(&stack->downqueue, msg); sem_post(&glob_mgr->new_msg); - return 0; - - ERR: - return -1; +OUT: + misdn_send_unlock(bc); + +OUT_POST_UNLOCK: + return retval; } diff --git a/channels/misdn/isdn_lib.h b/channels/misdn/isdn_lib.h index 8e47b1643..af4f20fee 100644 --- a/channels/misdn/isdn_lib.h +++ b/channels/misdn/isdn_lib.h @@ -199,6 +199,7 @@ enum layer_e { struct misdn_bchannel { + struct send_lock *send_lock; int nt; int port; diff --git a/channels/misdn/isdn_lib_intern.h b/channels/misdn/isdn_lib_intern.h index 86d95a9fe..757e8e20b 100644 --- a/channels/misdn/isdn_lib_intern.h +++ b/channels/misdn/isdn_lib_intern.h @@ -29,6 +29,10 @@ ibuffer_t *astbuf; ibuffer_t *misdnbuf; +struct send_lock { + pthread_mutex_t lock; +}; + struct isdn_msg { unsigned long misdn_msg; diff --git a/channels/misdn/isdn_msg_parser.c b/channels/misdn/isdn_msg_parser.c index 6ce9ed92e..4f5666586 100644 --- a/channels/misdn/isdn_msg_parser.c +++ b/channels/misdn/isdn_msg_parser.c @@ -296,6 +296,10 @@ static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, in enc_ie_redir_nr(&setup->REDIR_NR, msg, 1, 1, bc->pres, bc->screen, 0, bc->rad, nt,bc); } + { + if (bc->keypad[0]) + enc_ie_keypad(&setup->CALLED_PN, msg, bc->keypad, nt,bc); + } if (*bc->display) { -- cgit v1.2.3