teletone_generation_session_t tone_session;
zap_time_t last_event_time;
char tokens[ZAP_MAX_TOKENS+1][ZAP_TOKEN_STRLEN];
- uint8_t need_tone[ZAP_TONEMAP_INVALID+1];
+ uint8_t needed_tones[ZAP_TONEMAP_INVALID];
+ uint8_t detected_tones[ZAP_TONEMAP_INVALID];
+ zap_tonemap_t last_detected_tone;
+
uint32_t token_count;
char chan_name[128];
char chan_number[32];
- zap_tonemap_t detected_tone;
- zap_tonemap_t last_detected_tone;
struct zap_caller_data caller_data;
struct zap_span *span;
struct zap_io_interface *zio;
zap_status_t zap_channel_outgoing_call(zap_channel_t *zchan);
void zap_channel_rotate_tokens(zap_channel_t *zchan);
+void zap_channel_clear_detected_tones(zap_channel_t *zchan);
+void zap_channel_clear_needed_tones(zap_channel_t *zchan);
zap_status_t zap_channel_clear_token(zap_channel_t *zchan, int32_t token_id);
zap_status_t zap_channel_add_token(zap_channel_t *zchan, char *token);
zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state);
ZAP_TONEMAP_DIAL,
ZAP_TONEMAP_RING,
ZAP_TONEMAP_BUSY,
+ ZAP_TONEMAP_FAIL1,
+ ZAP_TONEMAP_FAIL2,
+ ZAP_TONEMAP_FAIL3,
ZAP_TONEMAP_ATTN,
ZAP_TONEMAP_INVALID
} zap_tonemap_t;
-#define TONEMAP_STRINGS "NONE", "DIAL", "RING", "BUSY", "ATTN", "INVALID"
+#define TONEMAP_STRINGS "NONE", "DIAL", "RING", "BUSY", "FAIL1", "FAIL2", "FAIL3", "ATTN", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_tonemap, zap_tonemap2str, zap_tonemap_t)
typedef enum {
if (!zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) {
zap_channel_command(zchan, ZAP_COMMAND_OFFHOOK, NULL);
zap_channel_command(zchan, ZAP_COMMAND_ENABLE_PROGRESS_DETECT, NULL);
- zchan->need_tone[ZAP_TONEMAP_DIAL] = 1;
+ zchan->needed_tones[ZAP_TONEMAP_DIAL] = 1;
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DIALING);
zap_thread_create_detached(zap_analog_channel_run, zchan);
return ZAP_SUCCESS;
zap_size_t dtmf_offset = 0;
zap_analog_data_t *data = chan->span->analog_data;
zap_channel_t *closed_chan;
- uint32_t state_counter = 0, elapsed = 0, interval = 0, last_digit = 0, indicate = 0;
+ uint32_t state_counter = 0, elapsed = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000;
zap_sigmsg_t sig;
zap_status_t status;
-
zap_log(ZAP_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n");
switch(chan->state) {
case ZAP_CHANNEL_STATE_DIALING:
{
- if (state_counter > 5000) {
- if (chan->need_tone[ZAP_TONEMAP_DIAL]) {
+ if (state_counter > dial_timeout) {
+ if (chan->needed_tones[ZAP_TONEMAP_DIAL]) {
zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY);
} else {
zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP);
case ZAP_CHANNEL_STATE_UP:
{
zap_channel_use(chan);
+ zap_channel_clear_needed_tones(chan);
if (chan->type == ZAP_CHAN_TYPE_FXO && !zap_test_flag(chan, ZAP_CHANNEL_OFFHOOK)) {
zap_channel_command(chan, ZAP_COMMAND_OFFHOOK, NULL);
goto done;
}
- if (chan->detected_tone) {
+ if (chan->type == ZAP_CHAN_TYPE_FXO && chan->detected_tones[0]) {
zap_sigmsg_t sig;
+ int i;
memset(&sig, 0, sizeof(sig));
sig.chan_id = chan->chan_id;
sig.span_id = chan->span_id;
sig.channel = chan;
sig.event_id = ZAP_SIGEVENT_TONE_DETECTED;
- zap_log(ZAP_LOG_DEBUG, "Detected tone %s\n", zap_tonemap2str(chan->detected_tone));
- data->sig_cb(&sig);
- if (chan->type == ZAP_CHAN_TYPE_FXO) {
-
- if (chan->need_tone[chan->detected_tone]) {
- switch (chan->detected_tone) {
- case ZAP_TONEMAP_DIAL:
- {
- zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, chan->caller_data.ani);
- state_counter = 0;
- chan->need_tone[ZAP_TONEMAP_RING] = 1;
- chan->need_tone[ZAP_TONEMAP_BUSY] = 1;
- }
- break;
- case ZAP_TONEMAP_RING:
- {
- zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP);
- }
- break;
- case ZAP_TONEMAP_BUSY:
- {
- zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY);
- }
- break;
- default:
- break;
- }
- chan->need_tone[chan->detected_tone] = 0;
+ for (i = 1; i < ZAP_TONEMAP_INVALID; i++) {
+ if (chan->detected_tones[i]) {
+ zap_log(ZAP_LOG_DEBUG, "Detected tone %s\n", zap_tonemap2str(chan->detected_tones[i]));
+ sig.raw_data = &i;
+ data->sig_cb(&sig);
}
}
- chan->detected_tone = 0;
+
+ if (chan->detected_tones[ZAP_TONEMAP_DIAL]) {
+ zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, chan->caller_data.ani);
+ state_counter = 0;
+ chan->needed_tones[ZAP_TONEMAP_RING] = 1;
+ chan->needed_tones[ZAP_TONEMAP_BUSY] = 1;
+ chan->needed_tones[ZAP_TONEMAP_FAIL1] = 1;
+ chan->needed_tones[ZAP_TONEMAP_FAIL2] = 1;
+ chan->needed_tones[ZAP_TONEMAP_FAIL3] = 1;
+ dial_timeout = (chan->dtmf_on + chan->dtmf_off) * strlen(chan->caller_data.ani) + 50;
+ } else if (chan->detected_tones[ZAP_TONEMAP_RING]) {
+ zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP);
+ } else if (chan->detected_tones[ZAP_TONEMAP_BUSY]) {
+ zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY);
+ }
+
+ zap_channel_clear_detected_tones(chan);
}
if (chan->dtmf_buffer && zap_buffer_inuse(chan->dtmf_buffer)) {
}
while (zap_config_next_pair(&cfg, &var, &val)) {
+ int detect = 0;
+
if (!strcasecmp(cfg.category, mapname) && var && val) {
- int index = zap_str2zap_tonemap(var);
- char valbuf[512];
+ uint32_t index;
+ char *mapname;
+
+ if (!strncasecmp(var, "detect-", 7)) {
+ mapname = var + 7;
+ detect = 1;
+ } else if (!strncasecmp(var, "generate-", 9)) {
+ mapname = var + 9;
+ }
+
+ index = zap_str2zap_tonemap(mapname);
- if (index > ZAP_TONEMAP_INVALID || index == ZAP_TONEMAP_NONE) {
- zap_log(ZAP_LOG_WARNING, "Unknown tone name %s\n", var);
+ if (index >= ZAP_TONEMAP_INVALID || index == ZAP_TONEMAP_NONE) {
+ zap_log(ZAP_LOG_WARNING, "Unknown tone name %s\n", mapname);
} else {
- char *p, *next;
- int i = 0;
- zap_set_string(valbuf, val);
- val = valbuf;
- if ((p = strchr(val, ':'))) {
- *p++ = '\0';
+ if (detect) {
+ char *p = val, *next;
+ int i = 0;
do {
teletone_process_t this;
next = strchr(p, ',');
p = next + 1;
}
} while (next);
-
+ zap_log(ZAP_LOG_DEBUG, "added tone detect [%s] = [%s]\n", mapname, val);
+ } else {
+ zap_log(ZAP_LOG_DEBUG, "added tone generation [%s] = [%s]\n", mapname, val);
zap_copy_string(span->tone_map[index], val, sizeof(span->tone_map[index]));
-
}
- zap_log(ZAP_LOG_DEBUG, "added tone [%s] = [%s]\n", var, val);
- zap_copy_string(span->tone_map[index], val, sizeof(span->tone_map[index]));
x++;
}
}
case ZAP_COMMAND_DISABLE_PROGRESS_DETECT:
{
zap_clear_flag_locked(zchan, ZAP_CHANNEL_PROGRESS_DETECT);
+ zap_channel_clear_detected_tones(zchan);
+ zap_channel_clear_needed_tones(zchan);
GOTO_STATUS(done, ZAP_SUCCESS);
}
break;
/******************************/
+void zap_channel_clear_detected_tones(zap_channel_t *zchan)
+{
+ memset(zchan->detected_tones, 0, sizeof(zchan->detected_tones[0]) * ZAP_TONEMAP_INVALID);
+}
+
+void zap_channel_clear_needed_tones(zap_channel_t *zchan)
+{
+ memset(zchan->needed_tones, 0, sizeof(zchan->needed_tones[0]) * ZAP_TONEMAP_INVALID);
+}
+
zap_size_t zap_channel_dequeue_dtmf(zap_channel_t *zchan, char *dtmf, zap_size_t len)
{
zap_size_t bytes = 0;
if (zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) {
uint32_t i;
- for (i = 0; i < ZAP_TONEMAP_INVALID+1; i++) {
+ for (i = 1; i < ZAP_TONEMAP_INVALID; i++) {
if (zchan->span->tone_finder[i].tone_count) {
- if (teletone_multi_tone_detect(&zchan->span->tone_finder[i], sln, (int)slen) && i != zchan->last_detected_tone) {
- zchan->detected_tone = i;
- zchan->last_detected_tone = i;
+ if (zchan->needed_tones[i] && teletone_multi_tone_detect(&zchan->span->tone_finder[i], sln, (int)slen)) {
+ zchan->detected_tones[i] = 1;
+ zchan->needed_tones[i] = 0;
+ zchan->detected_tones[0]++;
}
}
}