--- /dev/null
+[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
+
+
--- /dev/null
+[us]
+dial => %(1000,0,350,440)
+ring => %(2000,4000,440,480)
+busy => %(500,500,480,620)
+attn => %(100,100,1400,2060,2450,2600)
--- /dev/null
+[defaults]
+codec_ms => 20
+wink_ms => 150
+flash_ms => 750
--- /dev/null
+[defaults]
+codec_ms => 20
+wink_ms => 150
+flash_ms => 750
switch_mutex_t *flag_mutex;
zap_channel_t *zchan;
int32_t token_id;
+ uint32_t wr_error;
};
typedef struct private_object private_t;
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);
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;
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)) {
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;
}
{
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]);
}
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:
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);
}
}
}
- 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;
}
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";
}
}
- 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");
}
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;
}
+++ /dev/null
-[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)
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);
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);
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,
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 {
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;
#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)
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 ;
#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
/* Used with ioctl: ZT_SPANSTAT */
struct zt_spaninfo {
- int span_no; /* span number (-1 to use name) */\r
- char name[20]; /* Name of span */\r
- char description[40]; /* Description of span */\r
- int alarms; /* alarms status */\r
- int transmit_level; /* Transmit level */\r
- int receive_level; /* Receive level */\r
- int bpv_count; /* Current BPV count */\r
- int crc4_count; /* Current CRC4 error count */\r
- int ebit_count; /* Current E-bit error count */\r
- int fas_count; /* Current FAS error count */\r
- int irq_misses; /* Current IRQ misses */\r
- int sync_src; /* Span # of sync source (0 = free run) */\r
- int configured_chan_count; /* Count of channels configured on the span */\r
- int channel_count; /* Total count of channels on the span */\r
+ 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 */\r
+ int span_no; /* span number */
int command; /* Maintenance mode to set (from zt_maintenance_mode_t) */
};
int main(int argc, char *argv[])
{
zap_span_t *span;
+ int span_id;
+
+ if (argc < 2) {
+ printf("usage %s <spanno>\n", argv[0]);
+ exit(-1);
+ }
+
+ span_id = atoi(argv[1]);
zap_global_set_default_logger(ZAP_LOG_LEVEL_DEBUG);
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);
zap_sleep(1 * 1000);
}
+
+ done:
+
zap_global_destroy();
}
zap_codec_t codec = ZAP_CODEC_SLIN;
unsigned runs = 1;
+ if (!argv[1]) {
+ printf("usage %s <modname>\n", argv[0]);
+ exit(-1);
+ }
+
+
if (zap_global_init() != ZAP_SUCCESS) {
fprintf(stderr, "Error loading OpenZAP\n");
exit(-1);
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);
if(--runs) {
goto top;
}
+
+ end:
+
zap_global_destroy();
}
continue;
}
break;
+ case ZAP_CHANNEL_STATE_DOWN:
+ {
+ goto done;
+ }
+ break;
default:
break;
}
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;
}
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';
}
}
- 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");
+ 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;
+ }
+ }
- 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);
+ 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;
+ }
- zap_mutex_lock(event->channel->mutex);
+ 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);
- 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 (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:
{
static struct {
zap_hash_t *interface_hash;
zap_mutex_t *mutex;
+ struct zap_span spans[ZAP_MAX_SPANS_INTERFACE];
+ uint32_t span_index;
} globals;
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);
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)
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)) {
free(span->isdn_data);
}
}
-
+ zap_mutex_unlock(globals.mutex);
+
return i ? ZAP_SUCCESS : ZAP_FAIL;
}
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;
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;
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;
}
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)
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);
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;
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) {
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;
}
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;
}
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;
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);
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];
+ check = &globals.spans[span_id].channels[chan_id];
+
if ((status = zap_mutex_trylock(check->mutex)) != ZAP_SUCCESS) {
- return status;
+ goto done;
}
-
- 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 (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;
}
assert(check != NULL);
*zchan = NULL;
-
zap_mutex_lock(check->mutex);
if (zap_test_flag(check, ZAP_CHANNEL_OPEN)) {
status = check->zio->close(check);
} 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");
+
+ 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 {
- 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;
- }
+ zap_log(ZAP_LOG_CRIT, "failure creating span of type %s\n", type);
+ span = NULL;
+ continue;
}
- new_span = 0;
- continue;
}
if (!span) {
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")) {
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;
}
-zap_status_t zap_global_init(void)
+static zap_status_t process_module_config(zap_io_interface_t *zio)
{
zap_config_t cfg;
char *var, *val;
- uint32_t configured = 0;
+ 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)
+{
int modcount;
time_init();
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 {
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 {
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;
}
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) {
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++;
}
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;
}
}
}
}
+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);
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;
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;
}
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);
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);
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));
}
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;
}
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) {
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)
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;
zap_status_t zt_destroy(void)
{
- return ZAP_FAIL;
+
+ memset(&zt_interface, 0, sizeof(zt_interface));
+ return ZAP_SUCCESS;
}