Index: asterisk-trunk/channels/chan_dahdi.c =================================================================== --- asterisk-trunk/channels/chan_dahdi.c (revision 176592) +++ asterisk-trunk/channels/chan_dahdi.c (working copy) @@ -257,6 +257,8 @@ #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] = ""; @@ -357,6 +359,32 @@ return j; } +/*! \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); + 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 @@ -2709,6 +2737,34 @@ #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. * + * -adr 2/17/2009 */ + + int em_w_hookcomplete_evt_rcvd = 0; /* Flag inicating if we got a HOOKCOMPLETE event while */ + /* waiting for the wink */ + if (mysig == SIG_EMWINK) { + if ( dahdi_wait_for_wink(p->subs[SUB_REAL].dfd, 10000, &em_w_hookcomplete_evt_rcvd) != 0 ) { + /* 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 */ + x = DAHDI_ONHOOK; + res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); + if (res < 0) { + if (errno != EINPROGRESS) { + ast_log(LOG_WARNING, "Unable to hangup channel: %s\n", strerror(errno)); + ast_mutex_unlock(&p->lock); + return -1; + } + } + 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; @@ -2790,7 +2846,7 @@ #ifdef HAVE_PRI } #endif - if (!res) { + if (!res || em_w_hookcomplete_evt_rcvd) { if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) { int saveerr = errno;