]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Wait for wink before dialing when using E&M wink signaling
authorJeff Peeler <jpeeler@digium.com>
Tue, 21 Jul 2009 04:45:19 +0000 (04:45 +0000)
committerJeff Peeler <jpeeler@digium.com>
Tue, 21 Jul 2009 04:45:19 +0000 (04:45 +0000)
This patch adds a new dahdi_wait function to specifically wait for the wink
event. If the wink is not eventually received the channel is hung up.

(closes issue #14434)
Reported by: araasch
Patches:
      emwinkmod uploaded by araasch (license 693)

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

channels/chan_dahdi.c

index 232d28857daafcd75769723d2a2ba20b5ac4c80b..7bb5e1542d192c4227ebbaf61a5de3595f1b394b 100644 (file)
@@ -223,6 +223,8 @@ static const char config[] = "chan_dahdi.conf";
 #define CALLPROGRESS_FAX_INCOMING      4
 #define CALLPROGRESS_FAX               (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
 
+#define OUTBOUND_EM_WINK_RX_TIMEOUT     10000   /*!< Default time to wait for wink on outbound E&M Wink start trunks in ms*/
+
 static char defaultcic[64] = "";
 static char defaultozz[64] = "";
 
@@ -320,6 +322,34 @@ static inline int dahdi_wait_event(int fd)
        return j;
 }
 
+static char *event2str(int event);
+
+/*! \brief Waits for a wink from the far party with a timeout, returns 0 on wink received, -1 on timeout */
+static inline int dahdi_wait_for_wink(int dfd, int timeout_ms, int *hookcomplete_evt_rcvd)
+{
+       int res = 0;
+       while (timeout_ms > 0)
+       {
+               res = dahdi_get_event(dfd);
+               ast_debug(2, "Detected event: %s, timeout_ms %d\n", event2str(res), timeout_ms);
+               switch (res) {
+               case DAHDI_EVENT_NONE:
+                       timeout_ms -= 100;
+                       usleep(100000);
+                       break;
+               case DAHDI_EVENT_HOOKCOMPLETE:
+                       *hookcomplete_evt_rcvd = 1;
+                       break;
+               case DAHDI_EVENT_WINKFLASH:
+                       return 0;
+                       break;
+               default:
+                       break;
+        }
+       }
+       return -1; /* indicate timeout has elapsed */
+}
+
 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
 #define READ_SIZE 160
 
@@ -2449,6 +2479,8 @@ static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
        char *s = NULL;
 #endif
        char dest[256]; /* must be same length as p->dialdest */
+       /* flag for if we got a HOOKCOMPLETE event while waiting for the wink */
+       int em_w_hookcomplete_evt_rcvd = 0;
        ast_mutex_lock(&p->lock);
        ast_copy_string(dest, rdest, sizeof(dest));
        ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
@@ -2623,6 +2655,28 @@ static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
 #ifdef HAVE_PRI
                }
 #endif
+
+               /* If the outbound protocol is E&M Wink start, this code will wait for the wink
+                * before proceeding. It waits for the wink to be detected with a timeout and
+                * also detects and notes the HOOKCOMPLETE event which will come before the
+                * WINKFLASH event in the normal operation of outbound E&M Wink trunks.
+                */
+               if (mysig == SIG_EMWINK) {
+                       if (dahdi_wait_for_wink(p->subs[SUB_REAL].dfd, OUTBOUND_EM_WINK_RX_TIMEOUT, &em_w_hookcomplete_evt_rcvd)) {
+                               /* we never received a wink from the far side */
+                               ast_log(LOG_WARNING, "Timer elapsed while waiting to receive a wink on an E&M Wink trunk\n");
+                               /* put this channel on hook and exit */
+                               res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
+                               if (res < 0) {
+                                       ast_log(LOG_WARNING, "Unable to hangup channel: %s\n", strerror(errno));
+                               } else {
+                                       ast_log(LOG_WARNING, "Stopping channel since we did not get a wink before timeout\n");
+                               }
+                               ast_mutex_unlock(&p->lock);
+                               return -1;
+                       }
+               }
+
                ast_debug(1, "Dialing '%s'\n", c);
                p->dop.op = DAHDI_DIAL_OP_REPLACE;
 
@@ -2690,7 +2744,7 @@ static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
                        p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
                } else
                        p->echobreak = 0;
-               if (!res) {
+               if (!res || em_w_hookcomplete_evt_rcvd) {
                        if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
                                int saveerr = errno;