Add NT-mode overlap dial timeout and fix CID in overlap

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@593 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Stefan Knoblich 2008-10-12 22:07:45 +00:00
parent 18baa59c02
commit 4c4047d5cf
4 changed files with 112 additions and 35 deletions

View File

@ -9,4 +9,5 @@
Makefile
config.*
configure
libtool
aclocal.m4

View 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,

View 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,

View 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,16 +59,25 @@ 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;
/* 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
/* For Emacs: