diff --git a/libs/openzap/general.makefile b/libs/openzap/general.makefile index b6d3777436..9a060c86c7 100644 --- a/libs/openzap/general.makefile +++ b/libs/openzap/general.makefile @@ -1,3 +1,3 @@ CC=gcc -CC_CFLAGS += -Wall -Werror -Wextra -std=c99 -pedantic -Wno-unused-parameter +CC_CFLAGS += -Wall -Werror -Wextra -Wno-unused-parameter #-std=c99 -pedantic -Wno-unused-parameter diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 822459a1be..21f63022d9 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -620,12 +620,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi if ((p = strchr(outbound_profile->destination_number, '/'))) { dest = p + 1; span_id = atoi(outbound_profile->destination_number); - if ((p = strchr(dest, '/'))) { - chan_id = atoi(dest); - dest = p + 1; - } + chan_id = atoi(dest); } + dest = outbound_profile->destination_number; + if (!dest) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n"); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; @@ -643,6 +642,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } + if (status != ZAP_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channels available\n"); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; @@ -667,6 +667,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi snprintf(name, sizeof(name), "OPENZAP/%s", dest); switch_channel_set_name(channel, name); zap_set_string(zchan->caller_data.ani, dest); + zap_set_string(zchan->caller_data.cid_name, outbound_profile->caller_id_name); + zap_set_string(zchan->caller_data.cid_num, outbound_profile->caller_id_number); caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); switch_channel_set_caller_profile(channel, caller_profile); tech_pvt->caller_profile = caller_profile; @@ -681,6 +683,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } zap_channel_outgoing_call(zchan); + return SWITCH_CAUSE_SUCCESS; } diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index 13683aaa3b..d38cf87938 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -178,7 +178,6 @@ \command flag the or'd list of flags to set */ #define zap_set_flag(obj, flag) (obj)->flags |= (flag) - #define zap_set_flag_locked(obj, flag) assert(obj->mutex != NULL); \ zap_mutex_lock(obj->mutex); \ (obj)->flags |= (flag); \ @@ -193,9 +192,14 @@ #define zap_clear_flag_locked(obj, flag) assert(obj->mutex != NULL); zap_mutex_lock(obj->mutex); (obj)->flags &= ~(flag); zap_mutex_unlock(obj->mutex); -#define zap_set_state_locked(obj, s) assert(obj->mutex != NULL); zap_mutex_lock(obj->mutex); \ - zap_log(ZAP_LOG_DEBUG, "Changing state from %s to %s\n", zap_channel_state2str(obj->state), zap_channel_state2str(s)); \ - zap_channel_set_state(obj, s); +#define zap_set_state_locked(obj, s) if ( obj->state == s ) { \ + zap_log(ZAP_LOG_WARNING, "Why bother changing state from %s to %s\n", zap_channel_state2str(obj->state), zap_channel_state2str(s)); \ + } else { \ + int st = obj->state; \ + zap_channel_set_state(obj, s); \ + if (obj->state == s) zap_log(ZAP_LOG_DEBUG, "Changing state from %s to %s\n", zap_channel_state2str(st), zap_channel_state2str(s)); \ + else zap_log(ZAP_LOG_WARNING, "VETO Changing state from %s to %s\n", zap_channel_state2str(st), zap_channel_state2str(s)); \ + } #define zap_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119) @@ -433,7 +437,7 @@ zap_status_t zap_fsk_demod_feed(zap_fsk_data_state_t *state, int16_t *data, size zap_status_t zap_fsk_demod_destroy(zap_fsk_data_state_t *state); int zap_fsk_demod_init(zap_fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize); zap_status_t zap_fsk_data_init(zap_fsk_data_state_t *state, uint8_t *data, uint32_t datalen); -zap_status_t zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_mdmf_type_t type, int8_t *data, uint32_t datalen); +zap_status_t zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_mdmf_type_t type, uint8_t *data, uint32_t datalen); zap_status_t zap_fsk_data_add_checksum(zap_fsk_data_state_t *state); zap_status_t zap_fsk_data_add_sdmf(zap_fsk_data_state_t *state, char *date, char *number); zap_status_t zap_channel_outgoing_call(zap_channel_t *zchan); @@ -452,7 +456,7 @@ 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(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_close_all(void); 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); diff --git a/libs/openzap/src/testcid.c b/libs/openzap/src/testcid.c index eca951d252..d374a34081 100644 --- a/libs/openzap/src/testcid.c +++ b/libs/openzap/src/testcid.c @@ -29,7 +29,9 @@ int main(int argc, char *argv[]) uint8_t databuf[1024] = ""; struct helper foo = {0}; int x, bytes, start_bits = 180, stop_bits = 5, sbits = 300; - + char time_str[9]; + struct tm tm; + time_t now; if (argc < 2) { int x; @@ -41,10 +43,16 @@ int main(int argc, char *argv[]) } + time(&now); + localtime_r(&now, &tm); + strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm); + zap_fsk_data_init(&fsk_data, databuf, sizeof(databuf)); #if 1 - zap_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, "06061234", 8); - zap_fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NUM, "5551212", 7); + + zap_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, time_str, strlen(time_str)); + //zap_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, "06091213", 8); + zap_fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NUM, "14149361212", 7); zap_fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NAME, "Fred Smith", 10); for(x = 0; x < 0; x++) zap_fsk_data_add_mdmf(&fsk_data, MDMF_ALT_ROUTE, url, strlen(url)); diff --git a/libs/openzap/src/zap_analog.c b/libs/openzap/src/zap_analog.c index eb4337b156..421c17b73c 100644 --- a/libs/openzap/src/zap_analog.c +++ b/libs/openzap/src/zap_analog.c @@ -127,16 +127,19 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) ts.buffer = NULL; if (zap_channel_open_chan(chan) != ZAP_SUCCESS) { + zap_log(ZAP_LOG_ERROR, "OPEN ERROR\n"); goto done; } if (zap_buffer_create(&dt_buffer, 1024, 3192, 0) != ZAP_SUCCESS) { snprintf(chan->last_error, sizeof(chan->last_error), "memory error!"); + zap_log(ZAP_LOG_ERROR, "MEM ERROR\n"); goto done; } if (zap_channel_command(chan, ZAP_COMMAND_ENABLE_DTMF_DETECT, &tt) != ZAP_SUCCESS) { snprintf(chan->last_error, sizeof(chan->last_error), "error initilizing tone detector!"); + zap_log(ZAP_LOG_ERROR, "TONE ERROR\n"); goto done; } @@ -189,7 +192,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) { if (state_counter > 60000) { zap_set_state_locked(chan, ZAP_CHANNEL_STATE_DOWN); - } else { + } else if (!chan->fsk_buffer || !zap_buffer_inuse(chan->fsk_buffer)) { zap_sleep(interval); continue; } @@ -218,8 +221,13 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) break; case ZAP_CHANNEL_STATE_HANGUP: { - if (state_counter > 1000) { - zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY); + + if (state_counter > 500) { + if (zap_test_flag(chan, ZAP_CHANNEL_OFFHOOK)) { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY); + } else { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_DOWN); + } } } break; @@ -254,6 +262,12 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zap_channel_command(chan, ZAP_COMMAND_OFFHOOK, NULL); } + if (chan->fsk_buffer && zap_buffer_inuse(chan->fsk_buffer)) { + zap_log(ZAP_LOG_DEBUG, "Cancel FSK transmit due to early answer.\n"); + zap_buffer_zero(chan->fsk_buffer); + } + + if (chan->type == ZAP_CHAN_TYPE_FXS && zap_test_flag(chan, ZAP_CHANNEL_RINGING)) { zap_channel_command(chan, ZAP_COMMAND_GENERATE_RING_OFF, NULL); } @@ -309,6 +323,43 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) break; case ZAP_CHANNEL_STATE_GENRING: { + zap_fsk_data_state_t fsk_data; + uint8_t databuf[1024] = ""; + char time_str[9]; + struct tm tm; + time_t now; + zap_mdmf_type_t mt = MDMF_INVALID; + + time(&now); + localtime_r(&now, &tm); + strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm); + + zap_fsk_data_init(&fsk_data, databuf, sizeof(databuf)); + zap_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *) time_str, 8); + + if (zap_strlen_zero(chan->caller_data.cid_num)) { + mt = MDMF_NO_NUM; + zap_set_string(chan->caller_data.cid_num, "O"); + } else if (!strcasecmp(chan->caller_data.cid_num, "P") || !strcasecmp(chan->caller_data.cid_num, "O")) { + mt = MDMF_NO_NUM; + } else { + mt = MDMF_PHONE_NUM; + } + zap_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) chan->caller_data.cid_num, strlen(chan->caller_data.cid_num)); + + if (zap_strlen_zero(chan->caller_data.cid_name)) { + mt = MDMF_NO_NAME; + zap_set_string(chan->caller_data.cid_name, "O"); + } else if (!strcasecmp(chan->caller_data.cid_name, "P") || !strcasecmp(chan->caller_data.cid_name, "O")) { + mt = MDMF_NO_NAME; + } else { + mt = MDMF_PHONE_NAME; + } + zap_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) chan->caller_data.cid_name, strlen(chan->caller_data.cid_name)); + + zap_fsk_data_add_checksum(&fsk_data); + zap_channel_send_fsk_data(chan, &fsk_data, -14); + //zap_channel_command(chan, ZAP_COMMAND_TRACE_OUTPUT, "/tmp/outbound.ul"); zap_channel_command(chan, ZAP_COMMAND_GENERATE_RING_ON, NULL); } break; @@ -374,6 +425,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) } if (zap_channel_read(chan, frame, &len) != ZAP_SUCCESS) { + zap_log(ZAP_LOG_ERROR, "READ ERROR\n"); goto done; } @@ -412,7 +464,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zap_channel_clear_detected_tones(chan); } - if (chan->dtmf_buffer && zap_buffer_inuse(chan->dtmf_buffer)) { + if ((chan->dtmf_buffer && zap_buffer_inuse(chan->dtmf_buffer)) || (chan->fsk_buffer && zap_buffer_inuse(chan->fsk_buffer))) { rlen = len; memset(frame, 0, len); zap_channel_write(chan, frame, sizeof(frame), &rlen); @@ -506,7 +558,6 @@ static zap_status_t process_event(zap_span_t *span, zap_event_t *event) { if (event->channel->state == ZAP_CHANNEL_STATE_DOWN && !zap_test_flag(event->channel, ZAP_CHANNEL_INTHREAD)) { - /*zap_channel_command(event->channel, ZAP_COMMAND_TRACE_INPUT, "/tmp/inbound.ul");*/ zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_GET_CALLERID); zap_thread_create_detached(zap_analog_channel_run, event->channel); } diff --git a/libs/openzap/src/zap_callerid.c b/libs/openzap/src/zap_callerid.c index 8c44e11e60..25229befbe 100644 --- a/libs/openzap/src/zap_callerid.c +++ b/libs/openzap/src/zap_callerid.c @@ -61,7 +61,7 @@ zap_status_t zap_fsk_data_add_sdmf(zap_fsk_data_state_t *state, char *date, char return ZAP_SUCCESS; } -zap_status_t zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_mdmf_type_t type, int8_t *data, uint32_t datalen) +zap_status_t zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_mdmf_type_t type, uint8_t *data, uint32_t datalen) { state->buf[0] = ZAP_CID_TYPE_MDMF; state->buf[state->bpos++] = type; diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c index cb9a38bafc..eb5b342721 100644 --- a/libs/openzap/src/zap_io.c +++ b/libs/openzap/src/zap_io.c @@ -235,7 +235,7 @@ zap_status_t zap_span_create(zap_io_interface_t *zio, zap_span_t **span) return status; } -zap_status_t zap_span_close_all(zap_io_interface_t *zio) +zap_status_t zap_span_close_all(void) { zap_span_t *span; uint32_t i, j; @@ -425,9 +425,9 @@ zap_status_t zap_channel_send_fsk_data(zap_channel_t *zchan, zap_fsk_data_state_ if (!zchan->fsk_buffer) { zap_buffer_create(&zchan->fsk_buffer, 128, 128, 0); } - zap_fsk_modulator_init(&fsk_trans, FSK_BELL202, zchan->rate, fsk_data, -14, 180, 5, 180, zchan_fsk_write_sample, zchan); + zap_fsk_modulator_init(&fsk_trans, FSK_BELL202, zchan->rate, fsk_data, db_level, 180, 5, 180, zchan_fsk_write_sample, zchan); zap_fsk_modulator_send_all((&fsk_trans)); - zchan->buffer_delay = 2000 / zchan->effective_interval; + zchan->buffer_delay = 3500 / zchan->effective_interval; return ZAP_SUCCESS; } @@ -497,8 +497,8 @@ zap_status_t zap_channel_add_token(zap_channel_t *zchan, char *token) zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state) { int ok = 1; - - zap_mutex_unlock(zchan->mutex); + + zap_mutex_lock(zchan->mutex); if (zchan->state == ZAP_CHANNEL_STATE_DOWN) { @@ -511,6 +511,17 @@ zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t sta } } + if (zchan->state == ZAP_CHANNEL_STATE_BUSY) { + + switch(state) { + case ZAP_CHANNEL_STATE_UP: + ok = 0; + break; + default: + break; + } + } + if (state == zchan->state) { ok = 0; } @@ -660,7 +671,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)) { status = zchan->span->zio->open(zchan); if (status == ZAP_SUCCESS) { zap_set_flag(zchan, ZAP_CHANNEL_OPEN); @@ -701,7 +712,7 @@ zap_status_t zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t zap_mutex_unlock(check->mutex); } - done: + done: zap_mutex_unlock(globals.mutex); @@ -1526,11 +1537,10 @@ zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t data if (zchan->native_codec != ZAP_CODEC_SLIN) { dlen *= 2; } - + len = blen > dlen ? dlen : blen; br = zap_buffer_read(buffer, auxbuf, len); - if (br < dlen) { memset(auxbuf + br, 0, dlen - br); } @@ -1548,7 +1558,6 @@ zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t data } } - if (zchan->fds[1]) { unsigned int dlen = (unsigned int) *datalen; write(zchan->fds[1], data, dlen); @@ -1792,14 +1801,14 @@ zap_status_t zap_global_destroy(void) #ifdef ZAP_ZT_SUPPORT + zap_span_close_all(); + if (interfaces.zt_interface) { - zap_span_close_all(interfaces.zt_interface); zt_destroy(); } #endif #ifdef ZAP_WANPIPE_SUPPORT if (interfaces.wanpipe_interface) { - zap_span_close_all(interfaces.wanpipe_interface); wanpipe_destroy(); } #endif diff --git a/libs/openzap/src/zap_wanpipe.c b/libs/openzap/src/zap_wanpipe.c index b9acfc2b0c..1ac08b40f6 100644 --- a/libs/openzap/src/zap_wanpipe.c +++ b/libs/openzap/src/zap_wanpipe.c @@ -696,6 +696,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) if (diff > wp_globals.wink_ms) { zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); + zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_OFFHOOK; goto event; } @@ -705,6 +706,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event) if (diff > wp_globals.flash_ms) { zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH); zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK); + zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_ONHOOK; goto event; } diff --git a/libs/openzap/src/zap_zt.c b/libs/openzap/src/zap_zt.c index 26ac640f79..90f310fc92 100644 --- a/libs/openzap/src/zap_zt.c +++ b/libs/openzap/src/zap_zt.c @@ -465,6 +465,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) case ZT_EVENT_RINGOFFHOOK: { if (span->channels[i].type == ZAP_CHAN_TYPE_FXS) { + zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK); event_id = ZAP_OOB_OFFHOOK; } else if (span->channels[i].type == ZAP_CHAN_TYPE_FXO) { event_id = ZAP_OOB_RING_START;