char *tonegroup = NULL;
char *digit_timeout = NULL;
char *max_digits = NULL;
+ char *hotline = NULL;
char *dial_regex = NULL;
char *hold_music = NULL;
char *fail_dial_regex = NULL;
hold_music = val;
} else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) {
max_digits = val;
+ } else if (!strcasecmp(var, "hotline")) {
+ hotline = val;
} else if (!strcasecmp(var, "enable-analog-option")) {
analog_options = enable_analog_option(val, analog_options);
}
"tonemap", tonegroup,
"digit_timeout", &to,
"max_dialstr", &max,
+ "hotline", hotline,
"enable_callerid", enable_callerid,
TAG_END) != ZAP_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %d\n", span_id);
ZAP_CHANNEL_FEATURE_DTMF_GENERATE = (1 << 1),
ZAP_CHANNEL_FEATURE_CODECS = (1 << 2),
ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 3),
- ZAP_CHANNEL_FEATURE_CALLERID = (1 << 4)
+ ZAP_CHANNEL_FEATURE_CALLERID = (1 << 4),
+ ZAP_CHANNEL_FEATURE_PROGRESS = (1 << 5)
} zap_channel_feature_t;
typedef enum {
{
zap_analog_data_t *analog_data;
const char *tonemap = "us";
+ const char *hotline = "";
uint32_t digit_timeout = 10;
uint32_t max_dialstr = 11;
const char *var, *val;
break;
}
max_dialstr = *intval;
- }
+ } else if (!strcasecmp(var, "hotline")) {
+ if (!(val = va_arg(ap, char *))) {
+ break;
+ }
+ hotline = val;
+ }
}
digit_timeout = 2000;
}
- if (max_dialstr < 2 || max_dialstr > 20) {
+ if ((max_dialstr < 2 && !strlen(hotline)) || max_dialstr > 20) {
max_dialstr = 11;
}
analog_data->digit_timeout = digit_timeout;
analog_data->max_dialstr = max_dialstr;
analog_data->sig_cb = sig_cb;
+ strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline));
span->signal_type = ZAP_SIGTYPE_ANALOG;
span->signal_data = analog_data;
span->outgoing_call = span->trunk_type == ZAP_TRUNK_FXS ? analog_fxs_outgoing_call : analog_fxo_outgoing_call;
collecting = 0;
}
}
+ else if(!analog_data->max_dialstr)
+ {
+ last_digit = elapsed;
+ collecting = 0;
+ strcpy(dtmf, analog_data->hotline);
+ }
}
- if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) {
+ if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) {
zap_log(ZAP_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_IDLE);
last_digit = 0;
}
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_UP);
} else {
- zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DIALTONE);
+ if(!analog_data->max_dialstr) {
+ zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_COLLECT);
+ } else {
+ zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DIALTONE);
+ }
zap_mutex_unlock(event->channel->mutex);
locked = 0;
zap_thread_create_detached(zap_analog_channel_run, event->channel);
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DOWN);
}
}
+ case ZAP_OOB_DTMF:
+ {
+ const char * digit_str = (const char *)event->data;
+ if(digit_str) {
+ if (event->channel->state == ZAP_CHANNEL_STATE_CALLWAITING && (*digit_str == 'D' || *digit_str == 'A')) {
+ event->channel->detected_tones[ZAP_TONEMAP_CALLWAITING_ACK]++;
+ } else {
+ zio_event_cb_t event_callback = NULL;
+
+ zap_channel_queue_dtmf(event->channel, digit_str);
+ if (span->event_callback) {
+ event_callback = span->event_callback;
+ } else if (event->channel->event_callback) {
+ event_callback = event->channel->event_callback;
+ }
+
+ if (event_callback) {
+ event->channel->event_header.channel = event->channel;
+ event->channel->event_header.e_type = ZAP_EVENT_DTMF;
+ event->channel->event_header.data = (void *)digit_str;
+ event_callback(event->channel, &event->channel->event_header);
+ event->channel->event_header.e_type = ZAP_EVENT_NONE;
+ event->channel->event_header.data = NULL;
+ }
+
+ }
+ zap_safe_free(event->data);
+ }
+ }
}
end:
zap_log(ZAP_LOG_DEBUG, "ANALOG thread starting.\n");
while(zap_running() && zap_test_flag(analog_data, ZAP_ANALOG_RUNNING)) {
- int waitms = 10;
+ int waitms = 1000;
zap_status_t status;
status = zap_span_poll_event(span, waitms);
ZAP_ANALOG_CALLERID = (1 << 1)
} zap_analog_flag_t;
+#define ZAP_MAX_HOTLINE_STR 20
struct zap_analog_data {
uint32_t flags;
uint32_t max_dialstr;
uint32_t digit_timeout;
+ char hotline[ZAP_MAX_HOTLINE_STR];
zio_signal_cb_t sig_cb;
};
if (!zchan->fsk_buffer) {
zap_buffer_create(&zchan->fsk_buffer, 128, 128, 0);
+ } else {
+ zap_buffer_zero(zchan->fsk_buffer);
}
+
if (zchan->token_count > 1) {
zap_fsk_modulator_init(&fsk_trans, FSK_BELL202, zchan->rate, fsk_data, db_level, 80, 5, 0, zchan_fsk_write_sample, zchan);
zap_fsk_modulator_send_all((&fsk_trans));
zap_fsk_modulator_send_all((&fsk_trans));
zchan->buffer_delay = 3500 / zchan->effective_interval;
}
+
return ZAP_SUCCESS;
}
switch(state) {
case ZAP_CHANNEL_STATE_DIALTONE:
+ case ZAP_CHANNEL_STATE_COLLECT:
case ZAP_CHANNEL_STATE_DIALING:
case ZAP_CHANNEL_STATE_RING:
case ZAP_CHANNEL_STATE_PROGRESS_MEDIA:
break;
case ZAP_COMMAND_ENABLE_PROGRESS_DETECT:
{
- /* if they don't have thier own, use ours */
- zap_channel_clear_detected_tones(zchan);
- zap_channel_clear_needed_tones(zchan);
- teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_DIAL], &zchan->span->tone_detect_map[ZAP_TONEMAP_DIAL]);
- teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_RING], &zchan->span->tone_detect_map[ZAP_TONEMAP_RING]);
- teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_BUSY], &zchan->span->tone_detect_map[ZAP_TONEMAP_BUSY]);
- zap_set_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT);
- GOTO_STATUS(done, ZAP_SUCCESS);
+ if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_PROGRESS)) {
+ /* if they don't have thier own, use ours */
+ zap_channel_clear_detected_tones(zchan);
+ zap_channel_clear_needed_tones(zchan);
+ teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_DIAL], &zchan->span->tone_detect_map[ZAP_TONEMAP_DIAL]);
+ teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_RING], &zchan->span->tone_detect_map[ZAP_TONEMAP_RING]);
+ teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_BUSY], &zchan->span->tone_detect_map[ZAP_TONEMAP_BUSY]);
+ zap_set_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT);
+ GOTO_STATUS(done, ZAP_SUCCESS);
+ }
}
break;
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);
+ if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_PROGRESS)) {
+ 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;
case ZAP_COMMAND_ENABLE_DTMF_DETECT:
}
}
- if (zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) {
+ if (zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT) && !zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_PROGRESS)) {
uint32_t i;
for (i = 1; i < ZAP_TONEMAP_INVALID; i++) {
}
}
- if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT)) {
+ if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT) && !zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_DETECT)) {
teletone_dtmf_detect(&zchan->dtmf_detect, sln, (int)slen);
teletone_dtmf_get(&zchan->dtmf_detect, digit_str, sizeof(digit_str));