aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorcrichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b>2006-06-06 09:40:41 +0000
committercrichter <crichter@f38db490-d61c-443f-a65b-d21fe96a405b>2006-06-06 09:40:41 +0000
commit169754edd213a86e474125432efd89ce632478d5 (patch)
tree7ba787ae8b7a0b213c833de5ffc398275a21d132 /channels
parente99c73ad6c106c15e1114c5d2f954e11dd5e2f9f (diff)
added select before write to avoid deadlock on full buffer. added some defines for deadlock debugging. added code snippet for generating silence if we don't have data to write.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@32524 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_misdn.c37
-rw-r--r--channels/misdn/isdn_lib.c123
2 files changed, 139 insertions, 21 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index aa1207ceb..4631fa5e6 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -2352,7 +2352,6 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone)
break;
case TONE_FILE:
break;
-
case TONE_NONE:
chan_misdn_log(3,cl->bc->port," --> None\n");
misdn_lib_tone_generator_stop(cl->bc);
@@ -3285,7 +3284,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ast_queue_frame(ch->ast, &fr);
}
-
}
}
break;
@@ -3694,7 +3692,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
chan_misdn_log(9,bc->port,"TONE_GEN: len:%d\n");
-
+
if (!ast->generator) break;
tmp = ast->generatordata;
@@ -3702,13 +3700,13 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
generate = ast->generator->generate;
res = generate(ast, tmp, tone_len, tone_len);
ast->generatordata = tmp;
+
if (res) {
ast_log(LOG_WARNING, "Auto-deactivating generator\n");
ast_deactivate_generator(ast);
} else {
bc->tone_cnt=0;
}
-
}
break;
@@ -3728,10 +3726,35 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
ast_queue_frame(ch->ast,&frame);
} else {
- int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
+ fd_set wrfs;
+ struct timeval tv;
+ tv.tv_sec=0;
+ tv.tv_usec=0;
+
+
+ FD_ZERO(&wrfs);
+ FD_SET(ch->pipe[1],&wrfs);
+
+ int t=select(FD_SETSIZE,NULL,&wrfs,NULL,&tv);
- if (ret<=0) {
- chan_misdn_log(1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno));
+ if (!t) {
+ chan_misdn_log(9, bc->port, "Select Timed out\n");
+ break;
+ }
+
+ if (t<0) {
+ chan_misdn_log(-1, bc->port, "Select Error (err=%s)\n",strerror(errno));
+ break;
+ }
+
+ if (FD_ISSET(ch->pipe[1],&wrfs)) {
+ int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
+
+ if (ret<=0) {
+ chan_misdn_log(-1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno));
+ }
+ } else {
+ chan_misdn_log(1, bc->port, "Wripe Pipe full!\n");
}
}
}
diff --git a/channels/misdn/isdn_lib.c b/channels/misdn/isdn_lib.c
index 9f23930db..a53b573eb 100644
--- a/channels/misdn/isdn_lib.c
+++ b/channels/misdn/isdn_lib.c
@@ -599,7 +599,7 @@ int clean_up_bc(struct misdn_bchannel *bc)
cb_log(3, stack->port, "$$$ CLEARING STACK\n");
ret=mISDN_clear_stack(stack->midev,bc->b_stid);
- if (ret<0) {
+ if (ret<0 && errno) {
cb_log(-1,stack->port,"clear stack failed [%s]\n",strerror(errno));
}
@@ -1986,7 +1986,7 @@ static int do_tone(struct misdn_bchannel *bc, int len)
if (bc->generate_tone) {
cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
-
+
if ( !bc->nojitter ) {
misdn_tx_jitter(bc,len);
}
@@ -2002,13 +2002,14 @@ static int do_tone(struct misdn_bchannel *bc, int len)
void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
{
char buf[4096 + mISDN_HEADER_LEN];
+ char *data=&buf[mISDN_HEADER_LEN];
iframe_t *txfrm= (iframe_t*)buf;
int jlen, r;
- jlen=cb_jb_empty(bc,&buf[mISDN_HEADER_LEN],len);
+ jlen=cb_jb_empty(bc,data,len);
if (jlen) {
- flip_buf_bits( &buf[mISDN_HEADER_LEN], jlen);
+ flip_buf_bits( data, jlen);
if (jlen < len) {
cb_log(5,bc->port,"Jitterbuffer Underrun.\n");
@@ -2024,6 +2025,33 @@ void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
+ } else {
+#ifdef MISDN_GEN_SILENCE
+ int cnt=len/TONE_SILENCE_SIZE;
+ int rest=len%TONE_SILENCE_SIZE;
+ int i;
+
+ for (i=0; i<cnt; i++) {
+ memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
+ data +=TONE_SILENCE_SIZE;
+ }
+
+ if (rest) {
+ memcpy(data, tone_silence_flip, rest);
+ }
+
+ txfrm->prim = DL_DATA|REQUEST;
+
+ txfrm->dinfo = 0;
+
+ txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */
+
+ txfrm->len =len;
+ cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
+
+ r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
+#endif
+
}
}
@@ -2201,15 +2229,39 @@ int handle_bchan(msg_t *msg)
#endif
if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
- if ( !do_tone(bc, frm->len) ) {
+ int t;
+
+#ifdef MISDN_B_DEBUG
+ cb_log(0,bc->port,"do_tone START\n");
+#endif
+ t=do_tone(bc,frm->len);
+
+#ifdef MISDN_B_DEBUG
+ cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
+#endif
+ if ( !t ) {
if ( misdn_cap_is_speech(bc->capability)) {
if ( !bc->nojitter ) {
+#ifdef MISDN_B_DEBUG
+ cb_log(0,bc->port,"tx_jitter START\n");
+#endif
misdn_tx_jitter(bc,frm->len);
+#ifdef MISDN_B_DEBUG
+ cb_log(0,bc->port,"tx_jitter STOP\n");
+#endif
}
}
+
+#ifdef MISDN_B_DEBUG
+ cb_log(0,bc->port,"EVENT_B_DATA START\n");
+#endif
int i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
+#ifdef MISDN_B_DEBUG
+ cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
+#endif
+
if (i<0) {
cb_log(10,stack->port,"cb_event returned <0\n");
/*clean_up_bc(bc);*/
@@ -2262,7 +2314,8 @@ int handle_frm_nt(msg_t *msg)
if (!stack || !stack->nt) {
return 0;
}
-
+
+
if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
if (nt_err_cnt > 0 ) {
@@ -2520,6 +2573,8 @@ int handle_mgmt(msg_t *msg)
case SSTATUS_L1_DEACTIVATED:
cb_log(1, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
stack->l1link=0;
+
+ clear_l3(stack);
break;
case SSTATUS_L2_ESTABLISHED:
@@ -3096,10 +3151,20 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
}
if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
- if (handle_bchan(msg))
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_bchan START\n");
+#endif
+ if (handle_bchan(msg)) {
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_bchan STOP\n");
+#endif
return 0 ;
+ }
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_bchan NOTSTOP\n");
+#endif
}
-
+
if (handle_timers(msg))
return 0 ;
@@ -3112,16 +3177,46 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
/* Its important to handle l1 AFTER l2 */
if (handle_l1(msg))
return 0 ;
-
- if (handle_frm_nt(msg))
+
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_frm_nt START\n");
+#endif
+ if (handle_frm_nt(msg)) {
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_frm_nt STOP\n");
+#endif
return 0;
-
- if (handle_frm(msg))
+ }
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_frm_nt NOTSTOP\n");
+
+ cb_log(0,0,"handle_frm START\n");
+#endif
+
+ if (handle_frm(msg)) {
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_frm STOP\n");
+#endif
+
return 0;
-
- if (handle_err(msg))
+ }
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_frm NOTSTOP\n");
+
+ cb_log(0,0,"handle_err START\n");
+#endif
+
+ if (handle_err(msg)) {
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_err STOP\n");
+#endif
return 0 ;
+ }
+#ifdef MISDN_HANDLER_DEBUG
+ cb_log(0,0,"handle_err NOTSTOP\n");
+#endif
+
cb_log(-1, 0, "Unhandled Message: prim %x len %d from addr %x, dinfo %x on this port.\n",frm->prim, frm->len, frm->addr, frm->dinfo);
free_msg(msg);