aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b>2009-07-21 04:45:19 +0000
committerjpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b>2009-07-21 04:45:19 +0000
commitdf2fb5546e93ad7828028a04afad1f821cf04f9f (patch)
tree21cba0e4502be56e81c5cc71e0b14f54c61d9121
parent92247d3021d5a11b9136c025413cf077ba4ce2b2 (diff)
Wait for wink before dialing when using E&M wink signaling
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: http://svn.digium.com/svn/asterisk/branches/1.6.1@207637 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_dahdi.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 232d28857..7bb5e1542 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -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;