From a2dea73797bb17be37870360523da9ff0a0e8d42 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 May 2007 02:41:50 +0000 Subject: [PATCH] update git-svn-id: http://svn.openzap.org/svn/openzap/trunk@186 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/conf/openzap.conf | 19 ++ libs/openzap/conf/tones.conf | 5 + libs/openzap/conf/wanpipe.conf | 4 + libs/openzap/conf/zt.conf | 4 + libs/openzap/mod_openzap/mod_openzap.c | 67 +++--- libs/openzap/openzap.conf.ex | 38 ---- libs/openzap/src/include/openzap.h | 9 +- libs/openzap/src/include/zap_types.h | 10 +- libs/openzap/src/include/zap_zt.h | 30 +-- libs/openzap/src/testanalog.c | 17 +- libs/openzap/src/testapp.c | 11 +- libs/openzap/src/zap_analog.c | 254 +++++++++++------------ libs/openzap/src/zap_io.c | 276 ++++++++++++++----------- libs/openzap/src/zap_isdn.c | 2 +- libs/openzap/src/zap_wanpipe.c | 48 +++-- libs/openzap/src/zap_zt.c | 79 +++++-- 16 files changed, 489 insertions(+), 384 deletions(-) create mode 100644 libs/openzap/conf/openzap.conf create mode 100644 libs/openzap/conf/tones.conf create mode 100644 libs/openzap/conf/wanpipe.conf create mode 100644 libs/openzap/conf/zt.conf delete mode 100644 libs/openzap/openzap.conf.ex diff --git a/libs/openzap/conf/openzap.conf b/libs/openzap/conf/openzap.conf new file mode 100644 index 0000000000..d8a2f4b792 --- /dev/null +++ b/libs/openzap/conf/openzap.conf @@ -0,0 +1,19 @@ +[span wanpipe] +name => OpenZAP +number => 1 +fxs-channel => 1:3-4 + +[span wanpipe] +fxo-channel => 1:1-2 + +[span zt] +name => OpenZAP +number => 2 +fxs-channel => 1 + +[span zt] +name => OpenZAP +number => 2 +fxo-channel => 3 + + diff --git a/libs/openzap/conf/tones.conf b/libs/openzap/conf/tones.conf new file mode 100644 index 0000000000..2032823d0c --- /dev/null +++ b/libs/openzap/conf/tones.conf @@ -0,0 +1,5 @@ +[us] +dial => %(1000,0,350,440) +ring => %(2000,4000,440,480) +busy => %(500,500,480,620) +attn => %(100,100,1400,2060,2450,2600) diff --git a/libs/openzap/conf/wanpipe.conf b/libs/openzap/conf/wanpipe.conf new file mode 100644 index 0000000000..ba609ac42e --- /dev/null +++ b/libs/openzap/conf/wanpipe.conf @@ -0,0 +1,4 @@ +[defaults] +codec_ms => 20 +wink_ms => 150 +flash_ms => 750 diff --git a/libs/openzap/conf/zt.conf b/libs/openzap/conf/zt.conf new file mode 100644 index 0000000000..ba609ac42e --- /dev/null +++ b/libs/openzap/conf/zt.conf @@ -0,0 +1,4 @@ +[defaults] +codec_ms => 20 +wink_ms => 150 +flash_ms => 750 diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 19530cf755..25612c196f 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -88,6 +88,7 @@ struct private_object { switch_mutex_t *flag_mutex; zap_channel_t *zchan; int32_t token_id; + uint32_t wr_error; }; typedef struct private_object private_t; @@ -365,6 +366,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch zap_wait_flag_t wflags = ZAP_READ; char dtmf[128] = ""; zap_status_t status; + int total_to = timeout; + int chunk; channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -374,6 +377,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch assert(tech_pvt->zchan != NULL); + chunk = tech_pvt->zchan->effective_interval * 2; + top: if (switch_test_flag(tech_pvt, TFLAG_HOLD)) { switch_yield(tech_pvt->zchan->effective_interval * 1000); *frame = &tech_pvt->cng_frame; @@ -389,14 +394,20 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch return SWITCH_STATUS_FALSE; } - status = zap_channel_wait(tech_pvt->zchan, &wflags, timeout); + status = zap_channel_wait(tech_pvt->zchan, &wflags, chunk); if (status == ZAP_FAIL) { return SWITCH_STATUS_GENERR; } - + if (status == ZAP_TIMEOUT) { - return SWITCH_STATUS_BREAK; + if (timeout > 0 && !switch_test_flag(tech_pvt, TFLAG_HOLD)) { + total_to -= chunk; + if (total_to <= 0) { + return SWITCH_STATUS_BREAK; + } + } + goto top; } if (!(wflags & ZAP_READ)) { @@ -445,12 +456,16 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc if (!switch_test_flag(tech_pvt, TFLAG_IO)) { return SWITCH_STATUS_FALSE; } - + len = frame->datalen; if (zap_channel_write(tech_pvt->zchan, frame->data, &len) != ZAP_SUCCESS) { - return SWITCH_STATUS_GENERR; + if (++tech_pvt->wr_error > 10) { + return SWITCH_STATUS_GENERR; + } } + tech_pvt->wr_error = 0; + return SWITCH_STATUS_SUCCESS; } @@ -628,6 +643,10 @@ static switch_core_session_t *zap_channel_get_session(zap_channel_t *channel, in { switch_core_session_t *session = NULL; + if (id > ZAP_MAX_TOKENS) { + return NULL; + } + if (!switch_strlen_zero(channel->tokens[id])) { session = switch_core_session_locate(channel->tokens[id]); } @@ -648,7 +667,7 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal) private_t *tech_pvt = NULL; zap_status_t status; - zap_log(ZAP_LOG_DEBUG, "got sig [%s]\n", zap_signal_event2str(sigmsg->event_id)); + zap_log(ZAP_LOG_DEBUG, "got fxs sig [%s]\n", zap_signal_event2str(sigmsg->event_id)); switch(sigmsg->event_id) { case ZAP_SIGEVENT_START: @@ -676,7 +695,13 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal) for (i = 0; i < sigmsg->channel->token_count; i++) { if ((session = zap_channel_get_session(sigmsg->channel, i))) { tech_pvt = switch_core_session_get_private(session); - if (i) { + if (sigmsg->channel->token_count == 1) { + if (switch_test_flag(tech_pvt, TFLAG_HOLD)) { + switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); + } else { + switch_set_flag_locked(tech_pvt, TFLAG_HOLD); + } + } else if (i) { switch_set_flag_locked(tech_pvt, TFLAG_HOLD); } else { switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); @@ -685,23 +710,6 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal) } } } - case ZAP_SIGEVENT_HOLD: - { - if ((session = zap_channel_get_session(sigmsg->channel, sigmsg->channel->token_count-1))) { - tech_pvt = switch_core_session_get_private(session); - switch_set_flag_locked(tech_pvt, TFLAG_HOLD); - switch_core_session_rwunlock(session); - } - } - break; - case ZAP_SIGEVENT_UNHOLD: - { - if ((session = zap_channel_get_session(sigmsg->channel, sigmsg->channel->token_count-1))) { - tech_pvt = switch_core_session_get_private(session); - switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); - switch_core_session_rwunlock(session); - } - } break; } @@ -771,7 +779,6 @@ static switch_status_t load_config(void) if ((spans = switch_xml_child(cfg, "analog_spans"))) { for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - char *mod = (char *) switch_xml_attr_soft(myspan, "module"); char *id = (char *) switch_xml_attr_soft(myspan, "id"); char *context = "default"; char *dialplan = "XML"; @@ -798,10 +805,6 @@ static switch_status_t load_config(void) } } - if (!mod) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'module'\n"); - } - if (!id) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n"); } @@ -820,13 +823,13 @@ static switch_status_t load_config(void) max = atoi(max_digits); } - if (zap_span_find(mod, span_id, &span) != ZAP_SUCCESS) { - zap_log(ZAP_LOG_ERROR, "Error finding OpenZAP span %s:%d\n", mod, span_id); + if (zap_span_find(span_id, &span) != ZAP_SUCCESS) { + zap_log(ZAP_LOG_ERROR, "Error finding OpenZAP span %d\n", span_id); continue; } if (zap_analog_configure_span(span, tonegroup, to, max, on_zap_signal) != ZAP_SUCCESS) { - zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %s:%d\n", mod, span_id); + zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %d\n", span_id); continue; } diff --git a/libs/openzap/openzap.conf.ex b/libs/openzap/openzap.conf.ex deleted file mode 100644 index 3a01165ef9..0000000000 --- a/libs/openzap/openzap.conf.ex +++ /dev/null @@ -1,38 +0,0 @@ -[openzap] -load => wanpipe -;load => zt - -[+wanpipe.conf] -[span] -enabled => 1 -fxs-channel => 1:3-4 - - -[span] -enabled => 1 -fxo-channel => 1:1-2 - - -[+zt.conf] - -[span] -enabled => 0 -b-channel => 1-23 -d-channel=> 24 - -[span] -enabled => 0 -b-channel => 25-47 -d-channel=> 48 - -[span] -enabled => 0 -fxo-channel => 49 -fxs-channel => 50 - -[+tones.conf] -[us] -dial => %(1000,0,350,440) -ring => %(2000,4000,440,480) -busy => %(500,500,480,620) -attn => %(100,100,1400,2060,2450,2600) diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index 3f47bc7a68..0d43156956 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -317,14 +317,13 @@ struct zap_io_interface { zio_configure_t configure; zio_open_t open; zio_close_t close; + zio_destroy_channel_t destroy_channel; zio_command_t command; zio_wait_t wait; zio_read_t read; zio_write_t write; zio_span_poll_event_t poll_event; zio_span_next_event_t next_event; - uint32_t span_index; - struct zap_span spans[ZAP_MAX_SPANS_INTERFACE]; }; void zap_channel_rotate_tokens(zap_channel_t *zchan); @@ -337,15 +336,15 @@ zap_status_t zap_channel_queue_dtmf(zap_channel_t *zchan, const char *dtmf); zap_time_t zap_current_time_in_ms(void); zap_status_t zap_span_poll_event(zap_span_t *span, uint32_t ms); zap_status_t zap_span_next_event(zap_span_t *span, zap_event_t **event); -zap_status_t zap_span_find(const char *name, uint32_t id, zap_span_t **span); +zap_status_t zap_span_find(uint32_t id, zap_span_t **span); zap_status_t zap_span_create(zap_io_interface_t *zio, zap_span_t **span); zap_status_t zap_span_close_all(zap_io_interface_t *zio); zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_chan_type_t type, zap_channel_t **chan); zap_status_t zap_span_set_event_callback(zap_span_t *span, zio_event_cb_t event_callback); zap_status_t zap_channel_set_event_callback(zap_channel_t *zchan, zio_event_cb_t event_callback); -zap_status_t zap_channel_open(const char *name, uint32_t span_id, uint32_t chan_id, zap_channel_t **zchan); +zap_status_t zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t **zchan); zap_status_t zap_channel_open_chan(zap_channel_t *zchan); -zap_status_t zap_channel_open_any(const char *name, uint32_t span_id, zap_direction_t direction, zap_channel_t **zchan); +zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, zap_channel_t **zchan); zap_status_t zap_channel_close(zap_channel_t **zchan); zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, void *obj); zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to); diff --git a/libs/openzap/src/include/zap_types.h b/libs/openzap/src/include/zap_types.h index 2c97f40aed..9eb2082ec2 100644 --- a/libs/openzap/src/include/zap_types.h +++ b/libs/openzap/src/include/zap_types.h @@ -102,8 +102,6 @@ typedef enum { ZAP_SIGEVENT_TRANSFER, ZAP_SIGEVENT_ANSWER, ZAP_SIGEVENT_UP, - ZAP_SIGEVENT_HOLD, - ZAP_SIGEVENT_UNHOLD, ZAP_SIGEVENT_FLASH, ZAP_SIGEVENT_PROGRESS, ZAP_SIGEVENT_PROGRESS_MEDIA, @@ -111,7 +109,7 @@ typedef enum { ZAP_SIGEVENT_MISC, ZAP_SIGEVENT_INVALID } zap_signal_event_t; -#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "HOLD", "UNHOLD", "FLASH", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "MISC", "INVALID" +#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "MISC", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t) typedef enum { @@ -222,7 +220,8 @@ typedef enum { ZAP_CHANNEL_WINK = (1 << 9), ZAP_CHANNEL_FLASH = (1 << 10), ZAP_CHANNEL_STATE_CHANGE = (1 << 11), - ZAP_CHANNEL_HOLD = (1 << 12) + ZAP_CHANNEL_HOLD = (1 << 12), + ZAP_CHANNEL_INUSE = (1 << 13) } zap_channel_flag_t; @@ -240,6 +239,7 @@ typedef struct zap_span zap_span_t; #define ZIO_CONFIGURE_ARGS (const char *category, const char *var, const char *val, int lineno) #define ZIO_OPEN_ARGS (zap_channel_t *zchan) #define ZIO_CLOSE_ARGS (zap_channel_t *zchan) +#define ZIO_DESTROY_CHANNEL_ARGS (zap_channel_t *zchan) #define ZIO_COMMAND_ARGS (zap_channel_t *zchan, zap_command_t command, void *obj) #define ZIO_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to) #define ZIO_READ_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen) @@ -254,6 +254,7 @@ typedef zap_status_t (*zio_configure_span_t) ZIO_CONFIGURE_SPAN_ARGS ; typedef zap_status_t (*zio_configure_t) ZIO_CONFIGURE_ARGS ; typedef zap_status_t (*zio_open_t) ZIO_OPEN_ARGS ; typedef zap_status_t (*zio_close_t) ZIO_CLOSE_ARGS ; +typedef zap_status_t (*zio_destroy_channel_t) ZIO_DESTROY_CHANNEL_ARGS ; typedef zap_status_t (*zio_command_t) ZIO_COMMAND_ARGS ; typedef zap_status_t (*zio_wait_t) ZIO_WAIT_ARGS ; typedef zap_status_t (*zio_read_t) ZIO_READ_ARGS ; @@ -268,6 +269,7 @@ typedef zap_status_t (*zio_write_t) ZIO_WRITE_ARGS ; #define ZIO_CONFIGURE_FUNCTION(name) zap_status_t name ZIO_CONFIGURE_ARGS #define ZIO_OPEN_FUNCTION(name) zap_status_t name ZIO_OPEN_ARGS #define ZIO_CLOSE_FUNCTION(name) zap_status_t name ZIO_CLOSE_ARGS +#define ZIO_DESTROY_CHANNEL_FUNCTION(name) zap_status_t name ZIO_DESTROY_CHANNEL_ARGS #define ZIO_COMMAND_FUNCTION(name) zap_status_t name ZIO_COMMAND_ARGS #define ZIO_WAIT_FUNCTION(name) zap_status_t name ZIO_WAIT_ARGS #define ZIO_READ_FUNCTION(name) zap_status_t name ZIO_READ_ARGS diff --git a/libs/openzap/src/include/zap_zt.h b/libs/openzap/src/include/zap_zt.h index 47b5470b7f..48ee34bbc9 100644 --- a/libs/openzap/src/include/zap_zt.h +++ b/libs/openzap/src/include/zap_zt.h @@ -89,25 +89,25 @@ struct zt_gains { /* Used with ioctl: ZT_SPANSTAT */ struct zt_spaninfo { - int span_no; /* span number (-1 to use name) */ - char name[20]; /* Name of span */ - char description[40]; /* Description of span */ - int alarms; /* alarms status */ - int transmit_level; /* Transmit level */ - int receive_level; /* Receive level */ - int bpv_count; /* Current BPV count */ - int crc4_count; /* Current CRC4 error count */ - int ebit_count; /* Current E-bit error count */ - int fas_count; /* Current FAS error count */ - int irq_misses; /* Current IRQ misses */ - int sync_src; /* Span # of sync source (0 = free run) */ - int configured_chan_count; /* Count of channels configured on the span */ - int channel_count; /* Total count of channels on the span */ + int span_no; /* span number (-1 to use name) */ + char name[20]; /* Name of span */ + char description[40]; /* Description of span */ + int alarms; /* alarms status */ + int transmit_level; /* Transmit level */ + int receive_level; /* Receive level */ + int bpv_count; /* Current BPV count */ + int crc4_count; /* Current CRC4 error count */ + int ebit_count; /* Current E-bit error count */ + int fas_count; /* Current FAS error count */ + int irq_misses; /* Current IRQ misses */ + int sync_src; /* Span # of sync source (0 = free run) */ + int configured_chan_count; /* Count of channels configured on the span */ + int channel_count; /* Total count of channels on the span */ int span_count; /* Total count of zaptel spans on the system*/ }; struct zt_maintinfo { - int span_no; /* span number */ + int span_no; /* span number */ int command; /* Maintenance mode to set (from zt_maintenance_mode_t) */ }; diff --git a/libs/openzap/src/testanalog.c b/libs/openzap/src/testanalog.c index c42f40fc46..5e27509259 100644 --- a/libs/openzap/src/testanalog.c +++ b/libs/openzap/src/testanalog.c @@ -61,6 +61,14 @@ static ZIO_SIGNAL_CB_FUNCTION(on_signal) int main(int argc, char *argv[]) { zap_span_t *span; + int span_id; + + if (argc < 2) { + printf("usage %s \n", argv[0]); + exit(-1); + } + + span_id = atoi(argv[1]); zap_global_set_default_logger(ZAP_LOG_LEVEL_DEBUG); @@ -71,14 +79,14 @@ int main(int argc, char *argv[]) zap_log(ZAP_LOG_DEBUG, "OpenZAP loaded\n"); - if (zap_span_find("zt", 1, &span) != ZAP_SUCCESS) { + if (zap_span_find(span_id, &span) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "Error finding OpenZAP span\n"); - exit(-1); + goto done; } if (zap_analog_configure_span(span, "us", 2000, 11, on_signal) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "Error configuring OpenZAP span\n"); - exit(-1); + goto done; } zap_analog_start(span); @@ -86,6 +94,9 @@ int main(int argc, char *argv[]) zap_sleep(1 * 1000); } + + done: + zap_global_destroy(); } diff --git a/libs/openzap/src/testapp.c b/libs/openzap/src/testapp.c index d980a034df..309239c3d4 100644 --- a/libs/openzap/src/testapp.c +++ b/libs/openzap/src/testapp.c @@ -8,6 +8,12 @@ int main(int argc, char *argv[]) zap_codec_t codec = ZAP_CODEC_SLIN; unsigned runs = 1; + if (!argv[1]) { + printf("usage %s \n", argv[0]); + exit(-1); + } + + if (zap_global_init() != ZAP_SUCCESS) { fprintf(stderr, "Error loading OpenZAP\n"); exit(-1); @@ -17,7 +23,7 @@ int main(int argc, char *argv[]) top: //if (zap_channel_open_any("wanpipe", 0, ZAP_TOP_DOWN, &chan) == ZAP_SUCCESS) { - if (zap_channel_open("zt", 1, 1, &chan) == ZAP_SUCCESS) { + if (zap_channel_open(argv[1], 1, 1, &chan) == ZAP_SUCCESS) { int x = 0; printf("opened channel %d:%d\n", chan->span_id, chan->chan_id); @@ -65,6 +71,9 @@ int main(int argc, char *argv[]) if(--runs) { goto top; } + + end: + zap_global_destroy(); } diff --git a/libs/openzap/src/zap_analog.c b/libs/openzap/src/zap_analog.c index eb5c381d7d..55acc7814e 100644 --- a/libs/openzap/src/zap_analog.c +++ b/libs/openzap/src/zap_analog.c @@ -165,6 +165,11 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) continue; } break; + case ZAP_CHANNEL_STATE_DOWN: + { + goto done; + } + break; default: break; } @@ -176,10 +181,12 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) case ZAP_CHANNEL_STATE_UP: { if (zap_test_flag(chan, ZAP_CHANNEL_HOLD)) { - sig.event_id = ZAP_SIGEVENT_UNHOLD; + zap_clear_flag(chan, ZAP_CHANNEL_HOLD); + sig.event_id = ZAP_SIGEVENT_FLASH; } else { sig.event_id = ZAP_SIGEVENT_UP; } + data->sig_cb(&sig); continue; } @@ -199,14 +206,6 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) goto done; } break; - case ZAP_CHANNEL_STATE_HOLD: - { - sig.event_id = ZAP_SIGEVENT_HOLD; - data->sig_cb(&sig); - zap_set_flag_locked(chan, ZAP_CHANNEL_HOLD); - zap_set_state_locked(chan, ZAP_CHANNEL_STATE_DIALTONE); - } - break; case ZAP_CHANNEL_STATE_DIALTONE: { *dtmf = '\0'; @@ -242,126 +241,127 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) } } - if ((dlen = zap_channel_dequeue_dtmf(chan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) { - if (chan->state == ZAP_CHANNEL_STATE_DIALTONE || chan->state == ZAP_CHANNEL_STATE_COLLECT) { - zap_log(ZAP_LOG_DEBUG, "DTMF %s\n", dtmf + dtmf_offset); - if (chan->state == ZAP_CHANNEL_STATE_DIALTONE) { - zap_set_state_locked(chan, ZAP_CHANNEL_STATE_COLLECT); - } - dtmf_offset = strlen(dtmf); - last_digit = elapsed; - } - } - - - if (last_digit && ((elapsed - last_digit > data->digit_timeout) || strlen(dtmf) > data->max_dialstr)) { - zap_log(ZAP_LOG_DEBUG, "Number obtained [%s]\n", dtmf); - zap_set_state_locked(chan, ZAP_CHANNEL_STATE_IDLE); - last_digit = 0; - } - - if (zap_channel_wait(chan, &flags, interval * 2) != ZAP_SUCCESS) { - continue; - } - - if (!(flags & ZAP_READ)) { - continue; - } - - if (zap_channel_read(chan, frame, &len) != ZAP_SUCCESS) { - goto done; - } - - if (!indicate) { - continue; - } - - if (chan->effective_codec != ZAP_CODEC_SLIN) { - len *= 2; - } - - rlen = zap_buffer_read_loop(dt_buffer, frame, len); - - if (chan->effective_codec != ZAP_CODEC_SLIN) { - zio_codec_t codec_func = NULL; - - if (chan->native_codec == ZAP_CODEC_ULAW) { - codec_func = zio_slin2ulaw; - } else if (chan->native_codec == ZAP_CODEC_ALAW) { - codec_func = zio_slin2alaw; - } - - if (codec_func) { - status = codec_func(frame, sizeof(frame), &rlen); - } else { - snprintf(chan->last_error, sizeof(chan->last_error), "codec error!"); - goto done; - } - } - - zap_channel_write(chan, frame, &rlen); - } - - done: - - closed_chan = chan; - zap_channel_close(&chan); - - zap_channel_command(closed_chan, ZAP_COMMAND_SET_NATIVE_CODEC, NULL); - - if (ts.buffer) { - teletone_destroy_session(&ts); - } - - if (dt_buffer) { - zap_buffer_destroy(&dt_buffer); - } - - zap_clear_flag(closed_chan, ZAP_CHANNEL_INTHREAD); - - zap_log(ZAP_LOG_DEBUG, "ANALOG CHANNEL thread ended.\n"); - - return NULL; -} - -static zap_status_t process_event(zap_span_t *span, zap_event_t *event) -{ - zap_log(ZAP_LOG_DEBUG, "EVENT [%s][%d:%d]\n", zap_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id); - - zap_mutex_lock(event->channel->mutex); + if ((dlen = zap_channel_dequeue_dtmf(chan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) { + if (chan->state == ZAP_CHANNEL_STATE_DIALTONE || chan->state == ZAP_CHANNEL_STATE_COLLECT) { + zap_log(ZAP_LOG_DEBUG, "DTMF %s\n", dtmf + dtmf_offset); + if (chan->state == ZAP_CHANNEL_STATE_DIALTONE) { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_COLLECT); + } + dtmf_offset = strlen(dtmf); + last_digit = elapsed; + } + } - switch(event->enum_id) { - case ZAP_OOB_ONHOOK: - { - zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DOWN); - } - break; - case ZAP_OOB_FLASH: - { - zap_sigmsg_t sig; - zap_analog_data_t *data = event->channel->span->analog_data; - memset(&sig, 0, sizeof(sig)); - sig.chan_id = event->channel->chan_id; - sig.span_id = event->channel->span_id; - sig.channel = event->channel; - sig.span = event->channel->span; - - if (event->channel->state == ZAP_CHANNEL_STATE_UP) { - if (event->channel->token_count > 1) { - zap_channel_rotate_tokens(event->channel); - sig.event_id = ZAP_SIGEVENT_FLASH; - data->sig_cb(&sig); - } else { - if (zap_test_flag(event->channel, ZAP_CHANNEL_HOLD)) { - zap_clear_flag_locked(event->channel, ZAP_CHANNEL_HOLD); - zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_UP); - } else { - zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_HOLD); - } - } - } - } + if (last_digit && ((elapsed - last_digit > data->digit_timeout) || strlen(dtmf) > data->max_dialstr)) { + zap_log(ZAP_LOG_DEBUG, "Number obtained [%s]\n", dtmf); + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_IDLE); + last_digit = 0; + } + + if (zap_channel_wait(chan, &flags, interval * 2) != ZAP_SUCCESS) { + continue; + } + + if (!(flags & ZAP_READ)) { + continue; + } + + if (zap_channel_read(chan, frame, &len) != ZAP_SUCCESS) { + goto done; + } + + if (!indicate) { + continue; + } + + if (chan->effective_codec != ZAP_CODEC_SLIN) { + len *= 2; + } + + rlen = zap_buffer_read_loop(dt_buffer, frame, len); + + if (chan->effective_codec != ZAP_CODEC_SLIN) { + zio_codec_t codec_func = NULL; + + if (chan->native_codec == ZAP_CODEC_ULAW) { + codec_func = zio_slin2ulaw; + } else if (chan->native_codec == ZAP_CODEC_ALAW) { + codec_func = zio_slin2alaw; + } + + if (codec_func) { + status = codec_func(frame, sizeof(frame), &rlen); + } else { + snprintf(chan->last_error, sizeof(chan->last_error), "codec error!"); + goto done; + } + } + + zap_channel_write(chan, frame, &rlen); + } + + done: + + closed_chan = chan; + zap_channel_close(&chan); + + zap_channel_command(closed_chan, ZAP_COMMAND_SET_NATIVE_CODEC, NULL); + + if (ts.buffer) { + teletone_destroy_session(&ts); + } + + if (dt_buffer) { + zap_buffer_destroy(&dt_buffer); + } + + zap_clear_flag(closed_chan, ZAP_CHANNEL_INTHREAD); + + zap_log(ZAP_LOG_DEBUG, "ANALOG CHANNEL thread ended.\n"); + + return NULL; + } + + static zap_status_t process_event(zap_span_t *span, zap_event_t *event) + { + zap_sigmsg_t sig; + zap_analog_data_t *data = event->channel->span->analog_data; + + memset(&sig, 0, sizeof(sig)); + sig.chan_id = event->channel->chan_id; + sig.span_id = event->channel->span_id; + sig.channel = event->channel; + sig.span = event->channel->span; + + zap_log(ZAP_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n", + zap_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, zap_channel_state2str(event->channel->state)); + + zap_mutex_lock(event->channel->mutex); + + + switch(event->enum_id) { + case ZAP_OOB_ONHOOK: + { + zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DOWN); + } + break; + case ZAP_OOB_FLASH: + { + + sig.event_id = ZAP_SIGEVENT_FLASH; + zap_channel_rotate_tokens(event->channel); + + if (zap_test_flag(event->channel, ZAP_CHANNEL_HOLD)) { + zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_UP); + } else { + data->sig_cb(&sig); + if (event->channel->token_count == 1) { + zap_set_flag_locked(event->channel, ZAP_CHANNEL_HOLD); + zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DIALTONE); + } + } + } break; case ZAP_OOB_OFFHOOK: { diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c index 7890ceaaa2..3154ac2c05 100644 --- a/libs/openzap/src/zap_io.c +++ b/libs/openzap/src/zap_io.c @@ -73,6 +73,8 @@ zap_time_t zap_current_time_in_ms(void) static struct { zap_hash_t *interface_hash; zap_mutex_t *mutex; + struct zap_span spans[ZAP_MAX_SPANS_INTERFACE]; + uint32_t span_index; } globals; @@ -198,14 +200,16 @@ static uint32_t hashfromstring(void *ky) zap_status_t zap_span_create(zap_io_interface_t *zio, zap_span_t **span) { zap_span_t *new_span = NULL; + zap_status_t status = ZAP_FAIL; assert(zio != NULL); - if (zio->span_index < ZAP_MAX_SPANS_INTERFACE) { - new_span = &zio->spans[++zio->span_index]; + zap_mutex_lock(globals.mutex); + if (globals.span_index < ZAP_MAX_SPANS_INTERFACE) { + new_span = &globals.spans[++globals.span_index]; memset(new_span, 0, sizeof(*new_span)); zap_set_flag(new_span, ZAP_SPAN_CONFIGURED); - new_span->span_id = zio->span_index; + new_span->span_id = globals.span_index; new_span->zio = zio; zap_mutex_create(&new_span->mutex); zap_copy_string(new_span->tone_map[ZAP_TONEMAP_DIAL], "%(1000,0,350,440)", ZAP_TONEMAP_LEN); @@ -214,10 +218,11 @@ zap_status_t zap_span_create(zap_io_interface_t *zio, zap_span_t **span) zap_copy_string(new_span->tone_map[ZAP_TONEMAP_ATTN], "%(100,100,1400,2060,2450,2600)", ZAP_TONEMAP_LEN); new_span->trunk_type = ZAP_TRUNK_NONE; *span = new_span; - return ZAP_SUCCESS; + status = ZAP_SUCCESS; } - - return ZAP_FAIL; + zap_mutex_unlock(globals.mutex); + + return status; } zap_status_t zap_span_close_all(zap_io_interface_t *zio) @@ -225,8 +230,9 @@ zap_status_t zap_span_close_all(zap_io_interface_t *zio) zap_span_t *span; uint32_t i, j; - for(i = 0; i < zio->span_index; i++) { - span = &zio->spans[i]; + zap_mutex_lock(globals.mutex); + for(i = 0; i < globals.span_index; i++) { + span = &globals.spans[i]; for(j = 0; j < span->chan_count; j++) { if (zap_test_flag((&span->channels[j]), ZAP_CHANNEL_CONFIGURED)) { @@ -246,7 +252,8 @@ zap_status_t zap_span_close_all(zap_io_interface_t *zio) free(span->isdn_data); } } - + zap_mutex_unlock(globals.mutex); + return i ? ZAP_SUCCESS : ZAP_FAIL; } @@ -304,24 +311,17 @@ zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_cha return ZAP_FAIL; } -zap_status_t zap_span_find(const char *name, uint32_t id, zap_span_t **span) +zap_status_t zap_span_find(uint32_t id, zap_span_t **span) { - zap_io_interface_t *zio; zap_span_t *fspan; - zap_mutex_lock(globals.mutex); - zio = (zap_io_interface_t *) hashtable_search(globals.interface_hash, (char *)name); - zap_mutex_unlock(globals.mutex); - - if (!zio) { - return ZAP_FAIL; - } - if (id > ZAP_MAX_SPANS_INTERFACE) { return ZAP_FAIL; } - fspan = &zio->spans[id]; + zap_mutex_lock(globals.mutex); + fspan = &globals.spans[id]; + zap_mutex_unlock(globals.mutex); if (!zap_test_flag(fspan, ZAP_SPAN_CONFIGURED)) { return ZAP_FAIL; @@ -348,6 +348,8 @@ zap_status_t zap_span_poll_event(zap_span_t *span, uint32_t ms) if (span->zio->poll_event) { return span->zio->poll_event(span, ms); + } else { + zap_log(ZAP_LOG_ERROR, "poll_event method not implemented in module %s!", span->zio->name); } return ZAP_NOTIMPL; @@ -359,8 +361,10 @@ zap_status_t zap_span_next_event(zap_span_t *span, zap_event_t **event) if (span->zio->next_event) { return span->zio->next_event(span, event); + } else { + zap_log(ZAP_LOG_ERROR, "next_event method not implemented in module %s!", span->zio->name); } - + return ZAP_NOTIMPL; } @@ -403,9 +407,11 @@ zap_status_t zap_channel_clear_token(zap_channel_t *zchan, int32_t token_id) void zap_channel_rotate_tokens(zap_channel_t *zchan) { - memmove(zchan->tokens[1], zchan->tokens[0], zchan->token_count * ZAP_TOKEN_STRLEN); - zap_copy_string(zchan->tokens[0], zchan->tokens[zchan->token_count], ZAP_TOKEN_STRLEN); - *zchan->tokens[zchan->token_count] = '\0'; + if (zchan->token_count) { + memmove(zchan->tokens[1], zchan->tokens[0], zchan->token_count * ZAP_TOKEN_STRLEN); + zap_copy_string(zchan->tokens[0], zchan->tokens[zchan->token_count], ZAP_TOKEN_STRLEN); + *zchan->tokens[zchan->token_count] = '\0'; + } } zap_status_t zap_channel_add_token(zap_channel_t *zchan, char *token) @@ -414,7 +420,8 @@ zap_status_t zap_channel_add_token(zap_channel_t *zchan, char *token) zap_mutex_lock(zchan->mutex); if (zchan->token_count < ZAP_MAX_TOKENS) { - zap_copy_string(zchan->tokens[zchan->token_count], token, sizeof(zchan->tokens[zchan->token_count])); + memmove(zchan->tokens[1], zchan->tokens[0], zchan->token_count * ZAP_TOKEN_STRLEN); + zap_copy_string(zchan->tokens[0], token, ZAP_TOKEN_STRLEN); zchan->token_count++; } zap_mutex_unlock(zchan->mutex); @@ -455,9 +462,8 @@ zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t sta return ok ? ZAP_SUCCESS : ZAP_FAIL; } -zap_status_t zap_channel_open_any(const char *name, uint32_t span_id, zap_direction_t direction, zap_channel_t **zchan) +zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, zap_channel_t **zchan) { - zap_io_interface_t *zio; zap_status_t status = ZAP_FAIL; zap_channel_t *check; uint32_t i,j; @@ -465,18 +471,11 @@ zap_status_t zap_channel_open_any(const char *name, uint32_t span_id, zap_direct uint32_t span_max; zap_mutex_lock(globals.mutex); - zio = (zap_io_interface_t *) hashtable_search(globals.interface_hash, (char *)name); - zap_mutex_unlock(globals.mutex); - - if (!zio) { - zap_log(ZAP_LOG_ERROR, "Invalid interface name!\n"); - return ZAP_FAIL; - } if (span_id) { span_max = span_id; } else { - span_max = zio->span_index; + span_max = globals.span_index; } if (direction == ZAP_TOP_DOWN) { @@ -485,10 +484,8 @@ zap_status_t zap_channel_open_any(const char *name, uint32_t span_id, zap_direct j = span_max; } - zap_mutex_lock(globals.mutex); - for(;;) { - span = &zio->spans[j]; + span = &globals.spans[j]; if (!zap_test_flag(span, ZAP_SPAN_CONFIGURED)) { goto next_loop; @@ -523,13 +520,13 @@ zap_status_t zap_channel_open_any(const char *name, uint32_t span_id, zap_direct } check = &span->channels[i]; - - if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_OPEN)) { + + if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_INUSE)) { status = check->zio->open(check); - + if (status == ZAP_SUCCESS) { - zap_set_flag(check, ZAP_CHANNEL_OPEN); + zap_set_flag(check, ZAP_CHANNEL_INUSE); *zchan = check; return status; } @@ -563,6 +560,7 @@ static zap_status_t zap_channel_reset(zap_channel_t *zchan) zchan->event_callback = NULL; zap_clear_flag(zchan, ZAP_CHANNEL_DTMF_DETECT); zap_clear_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF); + zap_clear_flag(zchan, ZAP_CHANNEL_INUSE); zap_clear_flag_locked(zchan, ZAP_CHANNEL_HOLD); memset(zchan->tokens, 0, sizeof(zchan->tokens)); zchan->token_count = 0; @@ -598,7 +596,7 @@ zap_status_t zap_channel_open_chan(zap_channel_t *zchan) if ((status = zap_mutex_trylock(zchan->mutex)) != ZAP_SUCCESS) { return status; } - if (zap_test_flag(zchan, ZAP_CHANNEL_READY) && ! zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) { + if (zap_test_flag(zchan, ZAP_CHANNEL_READY) && !zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) { status = zchan->span->zio->open(zchan); if (status == ZAP_SUCCESS) { zap_set_flag(zchan, ZAP_CHANNEL_OPEN); @@ -609,33 +607,40 @@ zap_status_t zap_channel_open_chan(zap_channel_t *zchan) return status; } -zap_status_t zap_channel_open(const char *name, uint32_t span_id, uint32_t chan_id, zap_channel_t **zchan) +zap_status_t zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t **zchan) { - zap_io_interface_t *zio; zap_status_t status = ZAP_FAIL; zap_mutex_lock(globals.mutex); - zio = (zap_io_interface_t *) hashtable_search(globals.interface_hash, (char *)name); - zap_mutex_unlock(globals.mutex); - - if (span_id < ZAP_MAX_SPANS_INTERFACE && chan_id < ZAP_MAX_CHANNELS_SPAN && zio) { + + if (span_id < ZAP_MAX_SPANS_INTERFACE && chan_id < ZAP_MAX_CHANNELS_SPAN) { zap_channel_t *check; - check = &zio->spans[span_id].channels[chan_id]; - if ((status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) { - return status; - } + check = &globals.spans[span_id].channels[chan_id]; - if (zap_test_flag(check, ZAP_CHANNEL_READY) && ! zap_test_flag(check, ZAP_CHANNEL_OPEN)) { - status = check->zio->open(check); - if (status == ZAP_SUCCESS) { - zap_set_flag(check, ZAP_CHANNEL_OPEN); - *zchan = check; + if ((status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) { + goto done; + } + + if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_INUSE)) { + if (!zap_test_flag(check, ZAP_CHANNEL_OPEN)) { + status = check->zio->open(check); + if (status == ZAP_SUCCESS) { + zap_set_flag(check, ZAP_CHANNEL_OPEN); + } + } else { + status = ZAP_SUCCESS; } + zap_set_flag(check, ZAP_CHANNEL_INUSE); + *zchan = check; } zap_mutex_unlock(check->mutex); } + done: + + zap_mutex_unlock(globals.mutex); + return status; } @@ -649,7 +654,6 @@ zap_status_t zap_channel_close(zap_channel_t **zchan) assert(check != NULL); *zchan = NULL; - zap_mutex_lock(check->mutex); if (zap_test_flag(check, ZAP_CHANNEL_OPEN)) { status = check->zio->close(check); @@ -1286,49 +1290,56 @@ static struct { } interfaces; -static uint32_t load_config(zap_io_interface_t *zio) +static zap_status_t load_config(void) { - char cfg_name[256]; + char cfg_name[] = "openzap.conf"; zap_config_t cfg; char *var, *val; int catno = -1; zap_span_t *span = NULL; - int new_span = 0; unsigned configured = 0, d = 0; char name[80] = ""; char number[25] = ""; - - assert(zio != NULL); - snprintf(cfg_name, sizeof(cfg_name), "%s.conf", zio->name); - - zap_log(ZAP_LOG_DEBUG, "configuring %s\n", zio->name); + zap_io_interface_t *zio = NULL; if (!zap_config_open_file(&cfg, cfg_name)) { return ZAP_FAIL; } while (zap_config_next_pair(&cfg, &var, &val)) { - if (!strcasecmp(cfg.category, "span")) { + if (!strncasecmp(cfg.category, "span", 4)) { if (cfg.catno != catno) { + char *type = cfg.category + 4; + if (*type == ' ') { + type++; + } + zap_log(ZAP_LOG_DEBUG, "found config for span\n"); catno = cfg.catno; - new_span = 1; - span = NULL; - } - - if (new_span) { - if (!strcasecmp(var, "enabled") && ! zap_true(val)) { - zap_log(ZAP_LOG_DEBUG, "span (disabled)\n"); - } else { - if (zap_span_create(zio, &span) == ZAP_SUCCESS) { - zap_log(ZAP_LOG_DEBUG, "created span %d\n", span->span_id); - } else { - zap_log(ZAP_LOG_CRIT, "failure creating span\n"); - span = NULL; - } + + if (zap_strlen_zero(type)) { + zap_log(ZAP_LOG_CRIT, "failure creating span, no type specified.\n"); + span = NULL; + continue; + } + + zap_mutex_lock(globals.mutex); + zio = (zap_io_interface_t *) hashtable_search(globals.interface_hash, type); + zap_mutex_unlock(globals.mutex); + + if (!zio) { + zap_log(ZAP_LOG_CRIT, "failure creating span, no such type '%s'\n", type); + span = NULL; + continue; + } + + if (zap_span_create(zio, &span) == ZAP_SUCCESS) { + zap_log(ZAP_LOG_DEBUG, "created span %d of type %s\n", span->span_id, type); + } else { + zap_log(ZAP_LOG_CRIT, "failure creating span of type %s\n", type); + span = NULL; + continue; } - new_span = 0; - continue; } if (!span) { @@ -1337,9 +1348,7 @@ static uint32_t load_config(zap_io_interface_t *zio) zap_log(ZAP_LOG_DEBUG, "span %d [%s]=[%s]\n", span->span_id, var, val); - if (!strcasecmp(var, "enabled")) { - zap_log(ZAP_LOG_WARNING, "'enabled' command ignored when it's not the first command in a [span]\n"); - } else if (!strcasecmp(var, "trunk_type")) { + if (!strcasecmp(var, "trunk_type")) { span->trunk_type = zap_str2zap_trunk_type(val); zap_log(ZAP_LOG_DEBUG, "setting trunk type to '%s'\n", zap_trunk_type2str(span->trunk_type)); } else if (!strcasecmp(var, "name")) { @@ -1391,24 +1400,47 @@ static uint32_t load_config(zap_io_interface_t *zio) d++; } } - } else if (zio->configure) { - zio->configure(cfg.category, var, val, cfg.lineno); } else { zap_log(ZAP_LOG_ERROR, "unknown param [%s] '%s' / '%s'\n", cfg.category, var, val); } } zap_config_close_file(&cfg); - zap_log(ZAP_LOG_INFO, "wanpipe configured %u channel(s)\n", configured); + zap_log(ZAP_LOG_INFO, "Configured %u channel(s)\n", configured); - return configured; + return configured ? ZAP_SUCCESS : ZAP_FAIL; +} + +static zap_status_t process_module_config(zap_io_interface_t *zio) +{ + zap_config_t cfg; + char *var, *val; + char filename[256] = ""; + assert(zio != NULL); + + snprintf(filename, sizeof(filename), "%s.conf", zio->name); + + if (!zio->configure) { + zap_log(ZAP_LOG_ERROR, "Module %s does not support configuration.\n", zio->name); + return ZAP_FAIL; + } + + if (!zap_config_open_file(&cfg, filename)) { + zap_log(ZAP_LOG_ERROR, "Cannot open %s\n", filename); + return ZAP_FAIL; + } + + while (zap_config_next_pair(&cfg, &var, &val)) { + zio->configure(cfg.category, var, val, cfg.lineno); + } + + zap_config_close_file(&cfg); + + return ZAP_SUCCESS; } zap_status_t zap_global_init(void) { - zap_config_t cfg; - char *var, *val; - uint32_t configured = 0; int modcount; time_init(); @@ -1419,11 +1451,11 @@ zap_status_t zap_global_init(void) modcount = 0; zap_mutex_create(&globals.mutex); -#ifdef Z -AP_WANPIPE_SUPPORT +#ifdef ZAP_WANPIPE_SUPPORT if (wanpipe_init(&interfaces.wanpipe_interface) == ZAP_SUCCESS) { zap_mutex_lock(globals.mutex); hashtable_insert(globals.interface_hash, (void *)interfaces.wanpipe_interface->name, interfaces.wanpipe_interface); + process_module_config(interfaces.wanpipe_interface); zap_mutex_unlock(globals.mutex); modcount++; } else { @@ -1435,6 +1467,7 @@ AP_WANPIPE_SUPPORT if (zt_init(&interfaces.zt_interface) == ZAP_SUCCESS) { zap_mutex_lock(globals.mutex); hashtable_insert(globals.interface_hash, (void *)interfaces.zt_interface->name, interfaces.zt_interface); + process_module_config(interfaces.zt_interface); zap_mutex_unlock(globals.mutex); modcount++; } else { @@ -1447,32 +1480,7 @@ AP_WANPIPE_SUPPORT return ZAP_FAIL; } - if (!zap_config_open_file(&cfg, "openzap.conf")) { - zap_log(ZAP_LOG_ERROR, "Cannot open openzap.conf!\n"); - return ZAP_FAIL; - } - - while (zap_config_next_pair(&cfg, &var, &val)) { - if (!strcasecmp(cfg.category, "openzap")) { - if (!strcmp(var, "load")) { - zap_io_interface_t *zio; - - zap_mutex_lock(globals.mutex); - zio = (zap_io_interface_t *) hashtable_search(globals.interface_hash, val); - zap_mutex_unlock(globals.mutex); - - if (zio) { - configured += load_config(zio); - } else { - zap_log(ZAP_LOG_WARNING, "Attempted to load Non-Existant module '%s'\n", val); - } - } - } - } - - zap_config_close_file(&cfg); - - if (configured) { + if (load_config() == ZAP_SUCCESS) { return ZAP_SUCCESS; } @@ -1482,7 +1490,31 @@ AP_WANPIPE_SUPPORT zap_status_t zap_global_destroy(void) { + unsigned int i,j; time_end(); + + for(i = 1; i <= globals.span_index; i++) { + zap_span_t *cur_span = &globals.spans[i]; + + if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) { + zap_mutex_lock(cur_span->mutex); + for(j = 1; j <= cur_span->chan_count; j++) { + zap_channel_t *cur_chan = &cur_span->channels[j]; + if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) { + if (cur_span->zio->destroy_channel) { + zap_log(ZAP_LOG_INFO, "Closing channel %u:%u fd:%d\n", cur_chan->span_id, cur_chan->chan_id, cur_chan->sockfd); + if (cur_span->zio->destroy_channel(cur_chan) == ZAP_SUCCESS) { + zap_clear_flag_locked(cur_chan, ZAP_CHANNEL_CONFIGURED); + } else { + zap_log(ZAP_LOG_ERROR, "Error Closing channel %u:%u fd:%d\n", cur_chan->span_id, cur_chan->chan_id, cur_chan->sockfd); + } + } + } + } + zap_mutex_unlock(cur_span->mutex); + } + } + #ifdef ZAP_ZT_SUPPORT if (interfaces.zt_interface) { diff --git a/libs/openzap/src/zap_isdn.c b/libs/openzap/src/zap_isdn.c index 55b58e890f..7bca3922b1 100644 --- a/libs/openzap/src/zap_isdn.c +++ b/libs/openzap/src/zap_isdn.c @@ -202,7 +202,7 @@ zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931D for(i = 1; i <= span->chan_count; i++) { if (span->channels[i].type == ZAP_CHAN_TYPE_DQ921) { - if (zap_channel_open(span->zio->name, span->span_id, i, &dchans[x]) == ZAP_SUCCESS) { + if (zap_channel_open(span->span_id, i, &dchans[x]) == ZAP_SUCCESS) { zap_log(ZAP_LOG_DEBUG, "opening d-channel #%d %d:%d\n", x, dchans[x]->span_id, dchans[x]->chan_id); x++; } diff --git a/libs/openzap/src/zap_wanpipe.c b/libs/openzap/src/zap_wanpipe.c index fc14f0ad8f..9d3dcc43f1 100644 --- a/libs/openzap/src/zap_wanpipe.c +++ b/libs/openzap/src/zap_wanpipe.c @@ -108,13 +108,29 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start, static ZIO_CONFIGURE_FUNCTION(wanpipe_configure) { + int num; + if (!strcasecmp(category, "defaults")) { if (!strcasecmp(var, "codec_ms")) { - unsigned codec_ms = atoi(val); - if (codec_ms < 10 || codec_ms > 60) { + num = atoi(val); + if (num < 10 || num > 60) { zap_log(ZAP_LOG_WARNING, "invalid codec ms at line %d\n", lineno); } else { - wp_globals.codec_ms = codec_ms; + wp_globals.codec_ms = num; + } + } else if (!strcasecmp(var, "wink_ms")) { + num = atoi(val); + if (num < 500 || num > 2000) { + zap_log(ZAP_LOG_WARNING, "invalid wink ms at line %d\n", lineno); + } else { + wp_globals.wink_ms = num; + } + } else if (!strcasecmp(var, "flash_ms")) { + num = atoi(val); + if (num < 500 || num > 2000) { + zap_log(ZAP_LOG_WARNING, "invalid flash ms at line %d\n", lineno); + } else { + wp_globals.flash_ms = num; } } } @@ -479,6 +495,14 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) } +static ZIO_DESTROY_CHANNEL_FUNCTION(wanpipe_destroy_channel) +{ + tdmv_api_close_socket(&zchan->sockfd); + zchan->sockfd = WP_INVALID_SOCKET; + + return ZAP_SUCCESS; +} + zap_status_t wanpipe_init(zap_io_interface_t **zio) { assert(zio != NULL); @@ -500,6 +524,7 @@ zap_status_t wanpipe_init(zap_io_interface_t **zio) wanpipe_interface.poll_event = wanpipe_poll_event; #endif wanpipe_interface.next_event = wanpipe_next_event; + wanpipe_interface.destroy_channel = wanpipe_destroy_channel; *zio = &wanpipe_interface; return ZAP_SUCCESS; @@ -507,23 +532,6 @@ zap_status_t wanpipe_init(zap_io_interface_t **zio) zap_status_t wanpipe_destroy(void) { - unsigned int i,j; - - for(i = 1; i <= wanpipe_interface.span_index; i++) { - zap_span_t *cur_span = &wanpipe_interface.spans[i]; - - if (zap_test_flag(cur_span, ZAP_SPAN_CONFIGURED)) { - for(j = 1; j <= cur_span->chan_count; j++) { - zap_channel_t *cur_chan = &cur_span->channels[j]; - if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) { - zap_log(ZAP_LOG_INFO, "Closing channel %u:%u fd:%d\n", cur_chan->span_id, cur_chan->chan_id, cur_chan->sockfd); - tdmv_api_close_socket(&cur_chan->sockfd); - } - } - } - } - memset(&wanpipe_interface, 0, sizeof(wanpipe_interface)); - return ZAP_SUCCESS; } diff --git a/libs/openzap/src/zap_zt.c b/libs/openzap/src/zap_zt.c index c91c585c70..9f86ffe01f 100644 --- a/libs/openzap/src/zap_zt.c +++ b/libs/openzap/src/zap_zt.c @@ -54,7 +54,7 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za zap_channel_t *chan; zap_socket_t sockfd = ZT_INVALID_SOCKET; int command; - int len = zt_globals.codec_ms * 8; + int len; snprintf(path, sizeof(path), "/dev/zap/%d", x); sockfd = open(path, O_RDWR); @@ -70,25 +70,26 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za continue; } #endif - + + + len = zt_globals.codec_ms * 8; if (ioctl(chan->sockfd, ZT_SET_BLOCKSIZE, &len)) { zap_log(ZAP_LOG_INFO, "failure configuring device %s as OpenZAP device %d:%d fd:%d err:%s\n", path, chan->span_id, chan->chan_id, sockfd, strerror(errno)); close(sockfd); continue; - } else { - chan->packet_len = len; - chan->effective_interval = chan->native_interval = chan->packet_len / 8; - - if (chan->effective_codec == ZAP_CODEC_SLIN) { - chan->packet_len *= 2; - } + } + + chan->packet_len = len; + chan->effective_interval = chan->native_interval = chan->packet_len / 8; + + if (chan->effective_codec == ZAP_CODEC_SLIN) { + chan->packet_len *= 2; } - if (ioctl(sockfd, ZT_GET_PARAMS, &ztp) < 0) { - close(sockfd); zap_log(ZAP_LOG_INFO, "failure configuring device %s as OpenZAP device %d:%d fd:%d\n", path, chan->span_id, chan->chan_id, sockfd); + close(sockfd); continue; } zap_log(ZAP_LOG_INFO, "configuring device %s as OpenZAP device %d:%d fd:%d\n", path, chan->span_id, chan->chan_id, sockfd); @@ -100,7 +101,16 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za chan->native_codec = chan->effective_codec = ZAP_CODEC_ULAW; } } + + ztp.wink_time = zt_globals.wink_ms; + ztp.flash_time = zt_globals.flash_ms; + if (ioctl(sockfd, ZT_SET_PARAMS, &ztp) < 0) { + zap_log(ZAP_LOG_INFO, "failure configuring device %s as OpenZAP device %d:%d fd:%d\n", path, chan->span_id, chan->chan_id, sockfd); + close(sockfd); + continue; + } + if (!zap_strlen_zero(name)) { zap_copy_string(chan->chan_name, name, sizeof(chan->chan_name)); } @@ -175,17 +185,34 @@ static ZIO_CONFIGURE_SPAN_FUNCTION(zt_configure_span) static ZIO_CONFIGURE_FUNCTION(zt_configure) { + + int num; + if (!strcasecmp(category, "defaults")) { if (!strcasecmp(var, "codec_ms")) { - unsigned codec_ms = atoi(val); - if (codec_ms < 10 || codec_ms > 60) { + num = atoi(val); + if (num < 10 || num > 60) { zap_log(ZAP_LOG_WARNING, "invalid codec ms at line %d\n", lineno); } else { - zt_globals.codec_ms = codec_ms; + zt_globals.codec_ms = num; + } + } else if (!strcasecmp(var, "wink_ms")) { + num = atoi(val); + if (num < 500 || num > 2000) { + zap_log(ZAP_LOG_WARNING, "invalid wink ms at line %d\n", lineno); + } else { + zt_globals.wink_ms = num; + } + } else if (!strcasecmp(var, "flash_ms")) { + num = atoi(val); + if (num < 500 || num > 2000) { + zap_log(ZAP_LOG_WARNING, "invalid flash ms at line %d\n", lineno); + } else { + zt_globals.flash_ms = num; } } } - + return ZAP_SUCCESS; } @@ -364,6 +391,15 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) event_id = ZAP_OOB_ONHOOK; } break; + case ZT_EVENT_WINKFLASH: + { + if (span->channels[i].state == ZAP_CHANNEL_STATE_DOWN) { + event_id = ZAP_OOB_WINK; + } else { + event_id = ZAP_OOB_FLASH; + } + } + break; case ZT_EVENT_RINGOFFHOOK: { if (span->channels[i].type == ZAP_CHAN_TYPE_FXS) { @@ -425,6 +461,14 @@ static ZIO_WRITE_FUNCTION(zt_write) return ZAP_FAIL; } +static ZIO_DESTROY_CHANNEL_FUNCTION(zt_destroy_channel) +{ + close(zchan->sockfd); + zchan->sockfd = ZT_INVALID_SOCKET; + + return ZAP_SUCCESS; +} + static zap_io_interface_t zt_interface; zap_status_t zt_init(zap_io_interface_t **zio) @@ -447,6 +491,7 @@ zap_status_t zt_init(zap_io_interface_t **zio) zt_interface.write = zt_write; zt_interface.poll_event = zt_poll_event; zt_interface.next_event = zt_next_event; + zt_interface.destroy_channel = zt_destroy_channel; *zio = &zt_interface; @@ -455,5 +500,7 @@ zap_status_t zt_init(zap_io_interface_t **zio) zap_status_t zt_destroy(void) { - return ZAP_FAIL; + + memset(&zt_interface, 0, sizeof(zt_interface)); + return ZAP_SUCCESS; }