Merged revisions 81367 via svnmerge from
authorChristian Richter <christian.richter@beronet.com>
Thu, 30 Aug 2007 08:50:44 +0000 (08:50 +0000)
committerChristian Richter <christian.richter@beronet.com>
Thu, 30 Aug 2007 08:50:44 +0000 (08:50 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r81367 | crichter | 2007-08-30 10:31:59 +0200 (Do, 30 Aug 2007) | 11 lines

Fixed a severe issue where a misdn_read would lock the channel, but read would
not return because it blocks. later chan_misdn would try to queue a frame like
a AST_CONTROL_ANSWER which could result in a deadlock situation. misdn_read
will now not block forever anymore, and we don't queue the ANSWER frame at all
when we already was called with misdn_answer -> answer would be called twice.

Also we don't explicitly send a RELEASE_COMPLETE on receiption of a RELEASE
anymore, because mISDN does that for us, this resulted in a problem on some
switches, which would block our port after some calls for a short while.

........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@81368 65c4cc65-6c06-0410-ace0-fbb531ad65f3

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

index 87de8e4..4b1abbb 100644 (file)
@@ -2562,15 +2562,39 @@ static struct ast_frame *misdn_read(struct ast_channel *ast)
                return NULL;
        }
 
-       len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
+       fd_set rrfs;
+       struct timeval tv;
+       tv.tv_sec=0;
+       tv.tv_usec=20000;
 
-       if (len <= 0) {
-               /* we hangup here, since our pipe is closed */
-               chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
+       FD_ZERO(&rrfs);
+       FD_SET(tmp->pipe[0],&rrfs);
+
+       int t=select(FD_SETSIZE,&rrfs,NULL, NULL,&tv);
+
+       if (!t) {
+               chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n");
+               len=160;
+       }
+
+       if (t<0) {
+               chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n",strerror(errno));
+               return NULL;
+       }
+
+       if (FD_ISSET(tmp->pipe[0],&rrfs)) {
+               len=read(tmp->pipe[0],tmp->ast_rd_buf,sizeof(tmp->ast_rd_buf));
+
+               if (len<=0) {
+                       /* we hangup here, since our pipe is closed */
+                       chan_misdn_log(2,tmp->bc->port,"misdn_read: Pipe closed, hanging up\n");
+                       return NULL;
+               }
+
+       } else {
                return NULL;
        }
 
-       tmp->frame.frametype = AST_FRAME_VOICE;
        tmp->frame.subclass = AST_FORMAT_ALAW;
        tmp->frame.datalen = len;
        tmp->frame.samples = len;
@@ -4304,8 +4328,15 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                        }
                }
        }
+       ch->l3id=bc->l3_id;
+       ch->addr=bc->addr;
+
+       start_bc_tones(ch);
        
-       /* notice that we don't break here!*/
+       ch->state = MISDN_CONNECTED;
+       
+       ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
+       break;
        case EVENT_CONNECT_ACKNOWLEDGE:
        {
                ch->l3id = bc->l3_id;
@@ -4314,11 +4345,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                start_bc_tones(ch);
 
                ch->state = MISDN_CONNECTED;
-
-               if (!ch->ast)
-                       break;
-
-               ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
        }
        break;
        case EVENT_DISCONNECT:
@@ -4377,9 +4403,6 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 
                        hangup_chan(ch);
                        release_chan(bc);
-               
-                       if (bc->need_release_complete) 
-                               misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
                }
                break;
        case EVENT_RELEASE_COMPLETE:
index af80159..9f4f57f 100644 (file)
@@ -1557,9 +1557,6 @@ static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_
                case EVENT_PROGRESS:
                case EVENT_PROCEEDING:
                case EVENT_SETUP_ACKNOWLEDGE:
-
-               setup_bc(bc);
-
                case EVENT_SETUP:
                {
                        if (bc->channel == 0xff || bc->channel<=0)
@@ -1571,6 +1568,8 @@ static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_
                                return -1;
                        }
                }
+
+               setup_bc(bc);
                break;
 
                case EVENT_RELEASE_COMPLETE: