From e728218e2ff6540e3e46ea352a0b4c0d54b55f9c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 24 Nov 2007 18:04:14 +0000 Subject: [PATCH] add dial regexs git-svn-id: http://svn.openzap.org/svn/openzap/trunk@352 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/conf/openzap.conf.xml | 8 ++- libs/openzap/mod_openzap/mod_openzap.c | 79 ++++++++++++++++++++++---- libs/openzap/src/include/openzap.h | 2 + libs/openzap/src/include/zap_types.h | 6 +- libs/openzap/src/zap_analog.c | 13 ++++- libs/openzap/src/zap_io.c | 8 +++ libs/openzap/src/zap_isdn.c | 4 +- 7 files changed, 101 insertions(+), 19 deletions(-) diff --git a/libs/openzap/conf/openzap.conf.xml b/libs/openzap/conf/openzap.conf.xml index be802f9f5f..45780e9787 100644 --- a/libs/openzap/conf/openzap.conf.xml +++ b/libs/openzap/conf/openzap.conf.xml @@ -5,10 +5,14 @@ - - + + + + + + diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 292ac052e0..3f322039a2 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -35,7 +35,8 @@ #include "zap_isdn.h" SWITCH_MODULE_LOAD_FUNCTION(mod_openzap_load); -SWITCH_MODULE_DEFINITION(mod_openzap, mod_openzap_load, NULL, NULL); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openzap_shutdown); +SWITCH_MODULE_DEFINITION(mod_openzap, mod_openzap_load, mod_openzap_shutdown, NULL); switch_endpoint_interface_t *openzap_endpoint_interface; @@ -46,6 +47,9 @@ struct span_config { zap_span_t *span; char dialplan[80]; char context[80]; + char dial_regex[256]; + char fail_dial_regex[256]; + }; static struct span_config SPAN_CONFIG[ZAP_MAX_SPANS_INTERFACE] = {0}; @@ -974,6 +978,42 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal) cycle_foreground(sigmsg->channel, 1); } break; + + case ZAP_SIGEVENT_COLLECTED_DIGIT: + { + char *dtmf = sigmsg->raw_data; + char *regex = SPAN_CONFIG[sigmsg->channel->span->span_id].dial_regex; + char *fail_regex = SPAN_CONFIG[sigmsg->channel->span->span_id].fail_dial_regex; + + if (switch_strlen_zero(regex)) { + regex = NULL; + } + + if (switch_strlen_zero(fail_regex)) { + fail_regex = NULL; + } + + if ((regex || fail_regex) && !switch_strlen_zero(dtmf)) { + switch_regex_t *re = NULL; + int ovector[30]; + int match = 0; + + if (fail_regex) { + match = switch_regex_perform(dtmf, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); + status = match ? ZAP_SUCCESS : ZAP_BREAK; + switch_regex_safe_free(re); + } + + if (status == ZAP_SUCCESS && regex) { + match = switch_regex_perform(dtmf, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])); + status = match ? ZAP_BREAK : ZAP_SUCCESS; + } + + switch_regex_safe_free(re); + } + + } + break; } return status; @@ -1036,15 +1076,17 @@ static ZIO_SIGNAL_CB_FUNCTION(on_isdn_signal) static ZIO_SIGNAL_CB_FUNCTION(on_analog_signal) { + switch_status_t status; + switch (sigmsg->channel->type) { case ZAP_CHAN_TYPE_FXO: { - on_fxo_signal(sigmsg); + status = on_fxo_signal(sigmsg); } break; case ZAP_CHAN_TYPE_FXS: { - on_fxs_signal(sigmsg); + status = on_fxs_signal(sigmsg); } break; default: @@ -1055,7 +1097,7 @@ static ZIO_SIGNAL_CB_FUNCTION(on_analog_signal) break; } - return ZAP_SUCCESS; + return status; } static void zap_logger(char *file, const char *func, int line, int level, char *fmt, ...) @@ -1105,6 +1147,8 @@ static switch_status_t load_config(void) char *tonegroup = NULL; char *digit_timeout = NULL; char *max_digits = NULL; + char *dial_regex = NULL; + char *fail_dial_regex = NULL; uint32_t span_id = 0, to = 0, max = 0; zap_span_t *span = NULL; @@ -1114,13 +1158,17 @@ static switch_status_t load_config(void) if (!strcasecmp(var, "tonegroup")) { tonegroup = val; - } else if (!strcasecmp(var, "digit_timeout")) { + } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) { digit_timeout = val; } else if (!strcasecmp(var, "context")) { context = val; } else if (!strcasecmp(var, "dialplan")) { dialplan = val; - } else if (!strcasecmp(var, "max_digits")) { + } else if (!strcasecmp(var, "dial-regex")) { + dial_regex = val; + } else if (!strcasecmp(var, "fail-dial-regex")) { + fail_dial_regex = val; + } else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) { digit_timeout = val; } } @@ -1154,10 +1202,17 @@ static switch_status_t load_config(void) } SPAN_CONFIG[span->span_id].span = span; - switch_copy_string(SPAN_CONFIG[span->span_id].context, context, sizeof(SPAN_CONFIG[span->span_id].context)); - switch_copy_string(SPAN_CONFIG[span->span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span->span_id].dialplan)); + switch_set_string(SPAN_CONFIG[span->span_id].context, context); + switch_set_string(SPAN_CONFIG[span->span_id].dialplan, dialplan); + + if (dial_regex) { + switch_set_string(SPAN_CONFIG[span->span_id].dial_regex, dial_regex); + } + + if (fail_dial_regex) { + switch_set_string(SPAN_CONFIG[span->span_id].fail_dial_regex, fail_dial_regex); + } - zap_analog_start(span); } } @@ -1255,7 +1310,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_openzap_load) return SWITCH_STATUS_SUCCESS; } - +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_openzap_shutdown) +{ + zap_global_destroy(); + return SWITCH_STATUS_SUCCESS; +} /* For Emacs: * Local Variables: diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index a9209ad8c2..14b46b7167 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -518,6 +518,8 @@ void print_bits(uint8_t *b, int bl, char *buf, int blen, int e, uint8_t ss); void print_hex_bytes(uint8_t *data, zap_size_t dlen, char *buf, zap_size_t blen); int zap_hash_equalkeys(void *k1, void *k2); uint32_t zap_hash_hashfromstring(void *ky); +uint32_t zap_running(void); + ZIO_CODEC_FUNCTION(zio_slin2ulaw); ZIO_CODEC_FUNCTION(zio_ulaw2slin); ZIO_CODEC_FUNCTION(zio_slin2alaw); diff --git a/libs/openzap/src/include/zap_types.h b/libs/openzap/src/include/zap_types.h index 8be5007779..aac07d19f4 100644 --- a/libs/openzap/src/include/zap_types.h +++ b/libs/openzap/src/include/zap_types.h @@ -180,10 +180,11 @@ typedef enum { ZAP_SIGEVENT_ALARM_TRAP, ZAP_SIGEVENT_ALARM_CLEAR, ZAP_SIGEVENT_MISC, + ZAP_SIGEVENT_COLLECTED_DIGIT, ZAP_SIGEVENT_INVALID } zap_signal_event_t; #define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", \ - "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "ALARM_TRAP", "ALARM_CLEAR", "MISC", "INVALID" + "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "ALARM_TRAP", "ALARM_CLEAR", "MISC", "COLLECTED_DIGIT", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t) typedef enum { @@ -205,7 +206,8 @@ typedef enum { ZAP_TIMEOUT, ZAP_NOTIMPL, ZAP_CHECKSUM_ERROR, - ZAP_STATUS_COUNT + ZAP_STATUS_COUNT, + ZAP_BREAK } zap_status_t; typedef enum { diff --git a/libs/openzap/src/zap_analog.c b/libs/openzap/src/zap_analog.c index bc02794acd..2cb06d0d91 100644 --- a/libs/openzap/src/zap_analog.c +++ b/libs/openzap/src/zap_analog.c @@ -177,7 +177,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zap_size_t dtmf_offset = 0; zap_analog_data_t *analog_data = zchan->span->signal_data; zap_channel_t *closed_chan; - uint32_t state_counter = 0, elapsed = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000; + uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000; zap_sigmsg_t sig; zap_status_t status; @@ -490,17 +490,24 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zap_log(ZAP_LOG_DEBUG, "DTMF %s\n", dtmf + dtmf_offset); if (zchan->state == ZAP_CHANNEL_STATE_DIALTONE) { zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_COLLECT); + collecting = 1; } dtmf_offset = strlen(dtmf); last_digit = elapsed; + sig.event_id = ZAP_SIGEVENT_COLLECTED_DIGIT; + sig.raw_data = dtmf; + if (analog_data->sig_cb(&sig) == ZAP_BREAK) { + collecting = 0; + } } } - if (last_digit && ((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; + collecting = 0; } if (zap_channel_wait(zchan, &flags, interval * 2) != ZAP_SUCCESS) { @@ -741,7 +748,7 @@ static void *zap_analog_run(zap_thread_t *me, void *obj) zap_log(ZAP_LOG_DEBUG, "ANALOG thread starting.\n"); - while(zap_test_flag(analog_data, ZAP_ANALOG_RUNNING)) { + while(zap_running() && zap_test_flag(analog_data, ZAP_ANALOG_RUNNING)) { int waitms = 10; zap_status_t status; diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c index d8aa4778ef..1255b1352e 100644 --- a/libs/openzap/src/zap_io.c +++ b/libs/openzap/src/zap_io.c @@ -85,6 +85,7 @@ static struct { zap_mutex_t *mutex; struct zap_span spans[ZAP_MAX_SPANS_INTERFACE]; uint32_t span_index; + uint32_t running; } globals; @@ -1965,6 +1966,7 @@ zap_status_t zap_global_init(void) } if (load_config() == ZAP_SUCCESS) { + globals.running = 1; return ZAP_SUCCESS; } @@ -1972,6 +1974,10 @@ zap_status_t zap_global_init(void) return ZAP_FAIL; } +uint32_t zap_running(void) +{ + return globals.running; +} zap_status_t zap_global_destroy(void) @@ -1980,6 +1986,8 @@ zap_status_t zap_global_destroy(void) time_end(); zap_span_close_all(); + globals.running = 0; + zap_sleep(200); for(i = 1; i <= globals.span_index; i++) { zap_span_t *cur_span = &globals.spans[i]; diff --git a/libs/openzap/src/zap_isdn.c b/libs/openzap/src/zap_isdn.c index c159230ad5..5f92cfa4b6 100644 --- a/libs/openzap/src/zap_isdn.c +++ b/libs/openzap/src/zap_isdn.c @@ -508,7 +508,7 @@ static __inline__ void check_events(zap_span_t *span) break; case ZAP_FAIL: { - zap_log(ZAP_LOG_DEBUG, "Event Failure!\n"); + zap_log(ZAP_LOG_DEBUG, "Event Failure! %d\n", zap_running()); } break; default: @@ -532,7 +532,7 @@ static void *zap_isdn_run(zap_thread_t *me, void *obj) Q921Start(&isdn_data->q921); - while(zap_test_flag(isdn_data, ZAP_ISDN_RUNNING)) { + while(zap_running() && zap_test_flag(isdn_data, ZAP_ISDN_RUNNING)) { zap_wait_flag_t flags = ZAP_READ; zap_status_t status = zap_channel_wait(isdn_data->dchan, &flags, 100);