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: https://origsvn.digium.com/svn/asterisk/trunk@32524 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
3d973a0686
commit
24818d53b1
|
@ -2352,7 +2352,6 @@ static int tone_indicate( struct chan_list *cl, enum tone_e tone)
|
||||||
break;
|
break;
|
||||||
case TONE_FILE:
|
case TONE_FILE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TONE_NONE:
|
case TONE_NONE:
|
||||||
chan_misdn_log(3,cl->bc->port," --> None\n");
|
chan_misdn_log(3,cl->bc->port," --> None\n");
|
||||||
misdn_lib_tone_generator_stop(cl->bc);
|
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);
|
ast_queue_frame(ch->ast, &fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3702,13 +3700,13 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
|
||||||
generate = ast->generator->generate;
|
generate = ast->generator->generate;
|
||||||
res = generate(ast, tmp, tone_len, tone_len);
|
res = generate(ast, tmp, tone_len, tone_len);
|
||||||
ast->generatordata = tmp;
|
ast->generatordata = tmp;
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
ast_log(LOG_WARNING, "Auto-deactivating generator\n");
|
ast_log(LOG_WARNING, "Auto-deactivating generator\n");
|
||||||
ast_deactivate_generator(ast);
|
ast_deactivate_generator(ast);
|
||||||
} else {
|
} else {
|
||||||
bc->tone_cnt=0;
|
bc->tone_cnt=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3728,10 +3726,35 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
|
||||||
|
|
||||||
ast_queue_frame(ch->ast,&frame);
|
ast_queue_frame(ch->ast,&frame);
|
||||||
} else {
|
} else {
|
||||||
|
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 (!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);
|
int ret=write(ch->pipe[1], bc->bframe, bc->bframe_len);
|
||||||
|
|
||||||
if (ret<=0) {
|
if (ret<=0) {
|
||||||
chan_misdn_log(1, bc->port, "Write returned <=0 (err=%s)\n",strerror(errno));
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -599,7 +599,7 @@ int clean_up_bc(struct misdn_bchannel *bc)
|
||||||
cb_log(3, stack->port, "$$$ CLEARING STACK\n");
|
cb_log(3, stack->port, "$$$ CLEARING STACK\n");
|
||||||
|
|
||||||
ret=mISDN_clear_stack(stack->midev,bc->b_stid);
|
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));
|
cb_log(-1,stack->port,"clear stack failed [%s]\n",strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2002,13 +2002,14 @@ static int do_tone(struct misdn_bchannel *bc, int len)
|
||||||
void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
|
void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
|
||||||
{
|
{
|
||||||
char buf[4096 + mISDN_HEADER_LEN];
|
char buf[4096 + mISDN_HEADER_LEN];
|
||||||
|
char *data=&buf[mISDN_HEADER_LEN];
|
||||||
iframe_t *txfrm= (iframe_t*)buf;
|
iframe_t *txfrm= (iframe_t*)buf;
|
||||||
int jlen, r;
|
int jlen, r;
|
||||||
|
|
||||||
jlen=cb_jb_empty(bc,&buf[mISDN_HEADER_LEN],len);
|
jlen=cb_jb_empty(bc,data,len);
|
||||||
|
|
||||||
if (jlen) {
|
if (jlen) {
|
||||||
flip_buf_bits( &buf[mISDN_HEADER_LEN], jlen);
|
flip_buf_bits( data, jlen);
|
||||||
|
|
||||||
if (jlen < len) {
|
if (jlen < len) {
|
||||||
cb_log(5,bc->port,"Jitterbuffer Underrun.\n");
|
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);
|
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 );
|
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
|
#endif
|
||||||
|
|
||||||
if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
|
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 ( misdn_cap_is_speech(bc->capability)) {
|
||||||
if ( !bc->nojitter ) {
|
if ( !bc->nojitter ) {
|
||||||
|
#ifdef MISDN_B_DEBUG
|
||||||
|
cb_log(0,bc->port,"tx_jitter START\n");
|
||||||
|
#endif
|
||||||
misdn_tx_jitter(bc,frm->len);
|
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);
|
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) {
|
if (i<0) {
|
||||||
cb_log(10,stack->port,"cb_event returned <0\n");
|
cb_log(10,stack->port,"cb_event returned <0\n");
|
||||||
/*clean_up_bc(bc);*/
|
/*clean_up_bc(bc);*/
|
||||||
|
@ -2263,6 +2315,7 @@ int handle_frm_nt(msg_t *msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
|
if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
|
||||||
|
|
||||||
if (nt_err_cnt > 0 ) {
|
if (nt_err_cnt > 0 ) {
|
||||||
|
@ -2520,6 +2573,8 @@ int handle_mgmt(msg_t *msg)
|
||||||
case SSTATUS_L1_DEACTIVATED:
|
case SSTATUS_L1_DEACTIVATED:
|
||||||
cb_log(1, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
|
cb_log(1, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
|
||||||
stack->l1link=0;
|
stack->l1link=0;
|
||||||
|
|
||||||
|
clear_l3(stack);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSTATUS_L2_ESTABLISHED:
|
case SSTATUS_L2_ESTABLISHED:
|
||||||
|
@ -3096,9 +3151,19 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ((frm->addr | ISDN_PID_BCHANNEL_BIT )>> 28 ) == 0x5) {
|
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 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
|
#ifdef MISDN_HANDLER_DEBUG
|
||||||
|
cb_log(0,0,"handle_bchan NOTSTOP\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (handle_timers(msg))
|
if (handle_timers(msg))
|
||||||
return 0 ;
|
return 0 ;
|
||||||
|
@ -3113,14 +3178,44 @@ int manager_isdn_handler(iframe_t *frm ,msg_t *msg)
|
||||||
if (handle_l1(msg))
|
if (handle_l1(msg))
|
||||||
return 0 ;
|
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;
|
return 0;
|
||||||
|
}
|
||||||
|
#ifdef MISDN_HANDLER_DEBUG
|
||||||
|
cb_log(0,0,"handle_frm_nt NOTSTOP\n");
|
||||||
|
|
||||||
if (handle_frm(msg))
|
cb_log(0,0,"handle_frm START\n");
|
||||||
return 0;
|
#endif
|
||||||
|
|
||||||
|
if (handle_frm(msg)) {
|
||||||
|
#ifdef MISDN_HANDLER_DEBUG
|
||||||
|
cb_log(0,0,"handle_frm STOP\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (handle_err(msg))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
#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);
|
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);
|
free_msg(msg);
|
||||||
|
|
Loading…
Reference in New Issue