added select before write to avoid deadlock on full buffer. added some defines for...
authorChristian Richter <christian.richter@beronet.com>
Tue, 6 Jun 2006 09:40:41 +0000 (09:40 +0000)
committerChristian Richter <christian.richter@beronet.com>
Tue, 6 Jun 2006 09:40:41 +0000 (09:40 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@32524 65c4cc65-6c06-0410-ace0-fbb531ad65f3

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

index aa1207c..4631fa5 100644 (file)
@@ -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");
                        }
                }
        }
index 9f23930..a53b573 100644 (file)
@@ -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);