]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fixed a severe issue where a misdn_read would lock the channel, but read would
authorChristian Richter <christian.richter@beronet.com>
Thu, 30 Aug 2007 08:31:59 +0000 (08:31 +0000)
committerChristian Richter <christian.richter@beronet.com>
Thu, 30 Aug 2007 08:31:59 +0000 (08:31 +0000)
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/branches/1.4@81367 65c4cc65-6c06-0410-ace0-fbb531ad65f3

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

index 4a83bc1bb1cf7841231b1c68f88218a2d56822ec..70fa81f7dbb7c910af546f19a73faa15ca69a509 100644 (file)
@@ -2674,11 +2674,36 @@ 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;
        }
 
@@ -4468,8 +4493,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;
@@ -4478,10 +4510,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:
@@ -4541,9 +4569,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 e8fff355eb8ab1bc991e642a5356e1a1761fc356..e02d8a075942a9aa8ba971ac1bcf8b75ba8bf92a 100644 (file)
@@ -1566,9 +1566,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)
@@ -1580,6 +1577,8 @@ static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_
                                return -1;
                        }
                }
+
+               setup_bc(bc);
                break;
 
                case EVENT_RELEASE_COMPLETE: