]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Add NT-mode overlap dial timeout and fix CID in overlap
authorStefan Knoblich <stkn@freeswitch.org>
Sun, 12 Oct 2008 22:07:45 +0000 (22:07 +0000)
committerStefan Knoblich <stkn@freeswitch.org>
Sun, 12 Oct 2008 22:07:45 +0000 (22:07 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@593 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/openzap/.gitignore
libs/openzap/mod_openzap/mod_openzap.c
libs/openzap/src/ozmod/ozmod_isdn/ozmod_isdn.c
libs/openzap/src/ozmod/ozmod_isdn/zap_isdn.h

index e767f23aa10dc2a7b0f6136be6f022a8d0c90723..d90d79d08d3e0dcfc61c9f0bff66de92d1b270b7 100644 (file)
@@ -9,4 +9,5 @@
 Makefile
 config.*
 configure
-
+libtool
+aclocal.m4
index fd308a0d5ebbf89af8428f2c50c4cf9cad94decc..86108913b0ae8bd952d23d302fdc259674ad2917 100644 (file)
@@ -1830,6 +1830,8 @@ static switch_status_t load_config(void)
                        uint32_t span_id = 0;
                        zap_span_t *span = NULL;
                        char *tonegroup = NULL;
+                       char *digit_timeout = NULL;
+                       uint32_t to = 0;
                        uint32_t opts = 0;
                        int q921loglevel = -1;
                        int q931loglevel = -1;
@@ -1858,7 +1860,9 @@ static switch_status_t load_config(void)
                                        opts |= 1;
                                } else if (!strcasecmp(var, "dialplan")) {
                                        dialplan = val;
-                               } 
+                               } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) {
+                                       digit_timeout = val;
+                               }
                        }
        
                        if (!id && !name) {
@@ -1879,6 +1883,10 @@ static switch_status_t load_config(void)
                                }
                        }
 
+                       if (digit_timeout) {
+                               to = atoi(digit_timeout);
+                       }
+                       
                        if (zstatus != ZAP_SUCCESS) {
                                zap_log(ZAP_LOG_ERROR, "Error finding OpenZAP span %d\n", span_id);
                                continue;
@@ -1893,8 +1901,9 @@ static switch_status_t load_config(void)
                        }
                        
                        if (zap_configure_span("isdn", span, on_clear_channel_signal, 
-                                                                  "mode", mode, 
+                                                                  "mode", mode,
                                                                   "dialect", dialect,
+                                                                  "digit_timeout", &to,
                                                                   "opts", opts,
                                                                   "q921loglevel", q921loglevel,
                                                                   "q931loglevel", q931loglevel,
index ca6a7fdd65079e14f1b97998f8b64d6324f91063..ee97409504202e60256d1f57de8db401ef608abe 100644 (file)
@@ -48,6 +48,7 @@
 #define ZAP_SPAN_IS_BRI(x)     ((x)->trunk_type == ZAP_TRUNK_BRI || (x)->trunk_type == ZAP_TRUNK_BRI_PTMP)
 #define ZAP_SPAN_IS_NT(x)      (((zap_isdn_data_t *)(x)->signal_data)->mode == Q921_NT)
 
+
 static L2ULONG zap_time_now(void)
 {
        return (L2ULONG)zap_current_time_in_ms();
@@ -596,10 +597,16 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
                                                isdn_data->channels_remote_crv[gen->CRV] = zchan;
                                                memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
 
+                                               if (zchan->mod_data) {
+                                                       memset(zchan->mod_data, 0, sizeof(zap_isdn_bchan_data_t));
+                                               }
+
                                                zap_set_string(zchan->caller_data.cid_num.digits, (char *)callingnum->Digit);
                                                zap_set_string(zchan->caller_data.cid_name, (char *)callingnum->Digit);
                                                zap_set_string(zchan->caller_data.ani.digits, (char *)callingnum->Digit);
-                                               zap_set_string(zchan->caller_data.dnis.digits, (char *)callednum->Digit);
+                                               if (!overlap_dial) {
+                                                       zap_set_string(zchan->caller_data.dnis.digits, (char *)callednum->Digit);
+                                               }
 
                                                zchan->caller_data.CRV = gen->CRV;
                                                if (cplen > sizeof(zchan->caller_data.raw_data)) {
@@ -718,6 +725,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
                                                 * overlap dial digit indication
                                                 */
                                                if (Q931IsIEPresent(gen->CalledNum)) {
+                                                       zap_isdn_bchan_data_t *data = (zap_isdn_bchan_data_t *)zchan->mod_data;
                                                        Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
                                                        int pos;
 
@@ -727,13 +735,13 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
                                                        }
 
                                                        /* TODO: make this more safe with strncat() */
-                                                       pos = strlen(zchan->caller_data.cid_num.digits);
-                                                       strcat(&zchan->caller_data.cid_num.digits[pos], (char *)callednum->Digit);
-                                                       strcat(&zchan->caller_data.cid_name[pos],       (char *)callednum->Digit);
-                                                       strcat(&zchan->caller_data.ani.digits[pos],     (char *)callednum->Digit);
+                                                       pos = strlen(zchan->caller_data.dnis.digits);
                                                        strcat(&zchan->caller_data.dnis.digits[pos],    (char *)callednum->Digit);
 
-                                                       zap_log(ZAP_LOG_DEBUG, "Received new overlap digit (%s), destination number: %s\n", callednum->Digit, zchan->caller_data.cid_num.digits);
+                                                       /* update timer */
+                                                       data->digit_timeout = zap_time_now() + isdn_data->digit_timeout;
+
+                                                       zap_log(ZAP_LOG_DEBUG, "Received new overlap digit (%s), destination number: %s\n", callednum->Digit, zchan->caller_data.dnis.digits);
                                                }
 
                                                if (Q931IsIEPresent(gen->SendComplete) || digit == '#') {
@@ -861,16 +869,11 @@ static __inline__ void state_advance(zap_channel_t *zchan)
                break;
        case ZAP_CHANNEL_STATE_DIALTONE:
                {
-/*
-                       if (!zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) {
-                               if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
-                                       if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) {
-                                               zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP);
-                                               return;
-                                       }
-                               }
+                       zap_isdn_bchan_data_t *data = (zap_isdn_bchan_data_t *)zchan->mod_data;
+
+                       if (data) {
+                               data->digit_timeout = zap_time_now() + isdn_data->digit_timeout;
                        }
-*/
                }
                break;
        case ZAP_CHANNEL_STATE_RING:
@@ -1274,6 +1277,7 @@ static void *zap_isdn_tones_run(zap_thread_t *me, void *obj)
                zap_status_t status;
                int last_chan_state = 0;
                int gated = 0;
+               L2ULONG now = zap_time_now();
 
                /*
                 * check b-channel states and generate & send tones if neccessary
@@ -1294,6 +1298,23 @@ static void *zap_isdn_tones_run(zap_thread_t *me, void *obj)
                        switch (zchan->state) {
                        case ZAP_CHANNEL_STATE_DIALTONE:
                                {
+                                       zap_isdn_bchan_data_t *data = (zap_isdn_bchan_data_t *)zchan->mod_data;
+
+                                       /* check overlap dial timeout first before generating tone */
+                                       if (data && data->digit_timeout && data->digit_timeout <= now) {
+                                               if (strlen(zchan->caller_data.dnis.digits) > 0) {
+                                                       zap_log(ZAP_LOG_DEBUG, "Overlap dial timeout, advancing to RING state\n");
+                                                       zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_RING);
+                                               } else {
+                                                       /* no digits received, hangup */
+                                                       zap_log(ZAP_LOG_DEBUG, "Overlap dial timeout, no digits received, going to HANGUP state\n");
+                                                       zchan->caller_data.hangup_cause = ZAP_CAUSE_RECOVERY_ON_TIMER_EXPIRE;   /* TODO: probably wrong cause value */
+                                                       zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP);
+                                               }
+                                               data->digit_timeout = 0;
+                                               continue;
+                                       }
+
                                        if (last_chan_state != zchan->state) {
                                                zap_buffer_zero(dt_buffer);
                                                teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_DIAL]);
@@ -1671,8 +1692,9 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_isdn_configure_span)
        char *var, *val;
        Q931Dialect_t dialect = Q931_Dialect_National;
        uint32_t opts = 0;
-    int q921loglevel = -1;
-    int q931loglevel = -1;
+       int32_t digit_timeout = 0;
+       int q921loglevel = -1;
+       int q931loglevel = -1;
 
        if (span->signal_type) {
                snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d].", span->signal_type);
@@ -1727,40 +1749,73 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_isdn_configure_span)
                        }
                } else if (!strcasecmp(var, "opts")) {
                        opts = va_arg(ap, uint32_t);
-            if  (opts >= ZAP_ISDN_OPT_MAX) {
-                return ZAP_FAIL;
-            }
+                       if  (opts >= ZAP_ISDN_OPT_MAX) {
+                               return ZAP_FAIL;
+                       }
                        isdn_data->opts = opts;
                } else if (!strcasecmp(var, "tonemap")) {
                        if (!(val = va_arg(ap, char *))) {
                                break;
                        }
                        tonemap = (const char *)val;
+               } else if (!strcasecmp(var, "digit_timeout")) {
+                       int *optp;
+                       if (!(optp = va_arg(ap, int *))) {
+                               break;
+                       }
+                       digit_timeout = *optp;
+               }
                } else if (!strcasecmp(var, "q921loglevel")) {
                        q921loglevel = va_arg(ap, int);
-            if (q921loglevel < Q921_LOG_NONE) {
-                q921loglevel = Q921_LOG_NONE;
-            } else if (q921loglevel > Q921_LOG_DEBUG) {
-                q921loglevel = Q921_LOG_DEBUG;
-            }
+                       if (q921loglevel < Q921_LOG_NONE) {
+                               q921loglevel = Q921_LOG_NONE;
+                       } else if (q921loglevel > Q921_LOG_DEBUG) {
+                               q921loglevel = Q921_LOG_DEBUG;
+                       }
                } else if (!strcasecmp(var, "q931loglevel")) {
                        q931loglevel = va_arg(ap, int);
-            if (q931loglevel < Q931_LOG_NONE) {
-                q931loglevel = Q931_LOG_NONE;
-            } else if (q931loglevel > Q931_LOG_DEBUG) {
-                q931loglevel = Q931_LOG_DEBUG;
-            }
+                       if (q931loglevel < Q931_LOG_NONE) {
+                               q931loglevel = Q931_LOG_NONE;
+                       } else if (q931loglevel > Q931_LOG_DEBUG) {
+                               q931loglevel = Q931_LOG_DEBUG;
+                       }
                } else {
                        snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
                        return ZAP_FAIL;
                }
        }
+
+       if (!digit_timeout) {
+               digit_timeout = DEFAULT_DIGIT_TIMEOUT;
+       }
+       else if (digit_timeout < 3000 || digit_timeout > 30000) {
+               zap_log(ZAP_LOG_WARNING, "Digit timeout %d ms outside of range (3000 - 30000 ms), using default (10000 ms)\n", digit_timeout);
+               digit_timeout = DEFAULT_DIGIT_TIMEOUT;
+       }
+
+       /* allocate per b-chan data */
+       if (isdn_data->mode == Q931_NT) {
+               zap_isdn_bchan_data_t *data;
+
+               data = malloc((span->chan_count - 1) * sizeof(zap_isdn_bchan_data_t));
+               if (!data) {
+                       return ZAP_FAIL;
+               }
+
+               for (i = 1; i <= span->chan_count; i++, data++) {
+                       if (span->channels[i]->type == ZAP_CHAN_TYPE_B) {
+                               span->channels[i]->mod_data = data;
+                               memset(data, 0, sizeof(zap_isdn_bchan_data_t));
+                       }
+               }
+       }
                                        
        span->start = zap_isdn_start;
        isdn_data->sig_cb = sig_cb;
        isdn_data->dchans[0] = dchans[0];
        isdn_data->dchans[1] = dchans[1];
        isdn_data->dchan = isdn_data->dchans[0];
+       isdn_data->digit_timeout = digit_timeout;
        
        Q921_InitTrunk(&isdn_data->q921,
                                   0,
index cf45908364d63e84c67c13d78fd32fe3f20db8bd..14b2731db51e80c0cb5d1f4dcf253d4ca011052a 100644 (file)
@@ -35,6 +35,9 @@
 #define ZAP_ISDN_H
 #include "openzap.h"
 
+#define DEFAULT_DIGIT_TIMEOUT  10000           /* default overlap timeout: 10 seconds */
+
+
 typedef enum {
        ZAP_ISDN_OPT_NONE = 0,
        ZAP_ISDN_OPT_SUGGEST_CHANNEL = (1 << 0),
@@ -56,15 +59,24 @@ struct zap_isdn_data {
        zio_signal_cb_t sig_cb;
        uint32_t flags;
        int32_t mode;
+       int32_t digit_timeout;
        zap_isdn_opts_t opts;
        zap_caller_data_t *outbound_crv[32768];
        zap_channel_t *channels_local_crv[32768];
        zap_channel_t *channels_remote_crv[32768];
 };
 
+typedef struct zap_isdn_data zap_isdn_data_t;
 
 
-typedef struct zap_isdn_data zap_isdn_data_t;
+/* b-channel private data */
+struct zap_isdn_bchan_data
+{
+       int32_t digit_timeout;
+};
+
+typedef struct zap_isdn_bchan_data zap_isdn_bchan_data_t;
+
 
 #endif