From d9ad22285aec51840ee7d2a842d53d5851d48a6c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 1 Jun 2007 00:31:50 +0000 Subject: [PATCH] analog for zt works, still need some more for wanpipe git-svn-id: http://svn.openzap.org/svn/openzap/trunk@190 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/freetdm/mod_openzap/mod_openzap.c | 12 ++- libs/freetdm/src/include/openzap.h | 8 +- libs/freetdm/src/include/zap_types.h | 14 ++- libs/freetdm/src/include/zap_zt.h | 4 +- libs/freetdm/src/testanalog.c | 2 +- libs/freetdm/src/testapp.c | 7 +- libs/freetdm/src/zap_analog.c | 83 ++++++++++++++- libs/freetdm/src/zap_io.c | 137 ++++++++++++++++++------- libs/freetdm/src/zap_isdn.c | 2 +- libs/freetdm/src/zap_zt.c | 8 ++ 10 files changed, 221 insertions(+), 56 deletions(-) diff --git a/libs/freetdm/mod_openzap/mod_openzap.c b/libs/freetdm/mod_openzap/mod_openzap.c index 0e970d772d..a2c974a599 100644 --- a/libs/freetdm/mod_openzap/mod_openzap.c +++ b/libs/freetdm/mod_openzap/mod_openzap.c @@ -470,7 +470,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc } len = frame->datalen; - if (zap_channel_write(tech_pvt->zchan, frame->data, &len) != ZAP_SUCCESS) { + if (zap_channel_write(tech_pvt->zchan, frame->data, frame->buflen, &len) != ZAP_SUCCESS) { if (++tech_pvt->wr_error > 10) { return SWITCH_STATUS_GENERR; } @@ -764,11 +764,21 @@ static switch_core_session_t *zap_channel_get_session(zap_channel_t *channel, in static ZIO_SIGNAL_CB_FUNCTION(on_fxo_signal) { switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; zap_status_t status; zap_log(ZAP_LOG_DEBUG, "got fxo sig [%s]\n", zap_signal_event2str(sigmsg->event_id)); switch(sigmsg->event_id) { + case ZAP_SIGEVENT_UP: + { + if ((session = zap_channel_get_session(sigmsg->channel, 0))) { + channel = switch_core_session_get_channel(session); + switch_channel_mark_answered(channel); + switch_core_session_rwunlock(session); + } + } + break; case ZAP_SIGEVENT_START: { status = zap_channel_from_event(sigmsg, &session); diff --git a/libs/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 1804090136..55a5e8d14e 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -248,6 +248,7 @@ struct zap_channel { zap_channel_state_t last_state; zap_mutex_t *mutex; teletone_dtmf_detect_state_t dtmf_detect; + uint32_t dtmf_delay; zap_event_t event_header; char last_error[256]; zio_event_cb_t event_callback; @@ -260,9 +261,12 @@ struct zap_channel { teletone_generation_session_t tone_session; zap_time_t last_event_time; char tokens[ZAP_MAX_TOKENS+1][ZAP_TOKEN_STRLEN]; + uint8_t need_tone[ZAP_TONEMAP_INVALID+1]; uint32_t token_count; char chan_name[128]; char chan_number[32]; + zap_tonemap_t detected_tone; + zap_tonemap_t last_detected_tone; struct zap_caller_data caller_data; struct zap_span *span; struct zap_io_interface *zio; @@ -310,6 +314,8 @@ struct zap_span { zap_event_t event_header; char last_error[256]; char tone_map[ZAP_TONEMAP_INVALID+1][ZAP_TONEMAP_LEN]; + teletone_tone_map_t tone_detect_map[ZAP_TONEMAP_INVALID+1]; + teletone_multi_tone_t tone_finder[ZAP_TONEMAP_INVALID+1]; zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN]; zio_channel_outgoing_call_t outgoing_call; void *app_data; @@ -359,7 +365,7 @@ zap_status_t zap_channel_use(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_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *datalen); -zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *datalen); +zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t datasize, zap_size_t *datalen); zap_status_t zap_global_init(void); zap_status_t zap_global_destroy(void); void zap_global_set_logger(zap_logger_t logger); diff --git a/libs/freetdm/src/include/zap_types.h b/libs/freetdm/src/include/zap_types.h index b1431878f1..2a828965e1 100644 --- a/libs/freetdm/src/include/zap_types.h +++ b/libs/freetdm/src/include/zap_types.h @@ -57,13 +57,14 @@ typedef uint64_t zap_time_t; #define ZAP_TONEMAP_LEN 128 typedef enum { + ZAP_TONEMAP_NONE, ZAP_TONEMAP_DIAL, ZAP_TONEMAP_RING, ZAP_TONEMAP_BUSY, ZAP_TONEMAP_ATTN, ZAP_TONEMAP_INVALID } zap_tonemap_t; -#define TONEMAP_STRINGS "DIAL", "RING", "BUSY", "ATTN", "INVALID" +#define TONEMAP_STRINGS "NONE", "DIAL", "RING", "BUSY", "ATTN", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_tonemap, zap_tonemap2str, zap_tonemap_t) typedef enum { @@ -108,10 +109,11 @@ typedef enum { ZAP_SIGEVENT_PROGRESS, ZAP_SIGEVENT_PROGRESS_MEDIA, ZAP_SIGEVENT_NOTIFY, + ZAP_SIGEVENT_TONE_DETECTED, ZAP_SIGEVENT_MISC, ZAP_SIGEVENT_INVALID } zap_signal_event_t; -#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "MISC", "INVALID" +#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "MISC", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t) typedef enum { @@ -173,6 +175,8 @@ typedef enum { ZAP_COMMAND_GENERATE_RING_OFF, ZAP_COMMAND_OFFHOOK, ZAP_COMMAND_ONHOOK, + ZAP_COMMAND_ENABLE_PROGRESS_DETECT, + ZAP_COMMAND_DISABLE_PROGRESS_DETECT, ZAP_COMMAND_COUNT } zap_command_t; @@ -208,9 +212,10 @@ typedef enum { ZAP_CHANNEL_STATE_ATTN, ZAP_CHANNEL_STATE_IDLE, ZAP_CHANNEL_STATE_GENRING, + ZAP_CHANNEL_STATE_DIALING, ZAP_CHANNEL_STATE_INVALID } zap_channel_state_t; -#define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", "RING", "BUSY", "ATTN", "IDLE", "GENRING", "INVALID" +#define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", "RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t) typedef enum { @@ -229,7 +234,8 @@ typedef enum { ZAP_CHANNEL_HOLD = (1 << 12), ZAP_CHANNEL_INUSE = (1 << 13), ZAP_CHANNEL_OFFHOOK = (1 << 14), - ZAP_CHANNEL_RINGING = (1 << 15) + ZAP_CHANNEL_RINGING = (1 << 15), + ZAP_CHANNEL_PROGRESS_DETECT = (1 << 16) } zap_channel_flag_t; diff --git a/libs/freetdm/src/include/zap_zt.h b/libs/freetdm/src/include/zap_zt.h index 48ee34bbc9..1ad2e65c20 100644 --- a/libs/freetdm/src/include/zap_zt.h +++ b/libs/freetdm/src/include/zap_zt.h @@ -207,7 +207,7 @@ typedef enum { #define ZT_SETGAINS _IOWR (ZT_CODE, 17, struct zt_gains) /* Set Channel audio gains */ #define ZT_AUDIOMODE _IOW (ZT_CODE, 32, int) /* Set a clear channel into audio mode */ - +#define ZT_ECHOCANCEL _IOW (ZT_CODE, 33, int) /* Control Echo Canceller */ #define ZT_HDLCRAWMODE _IOW (ZT_CODE, 36, int) /* Set a clear channel into HDLC w/out FCS checking/calculation mode */ #define ZT_HDLCFCSMODE _IOW (ZT_CODE, 37, int) /* Set a clear channel into HDLC w/ FCS mode */ @@ -221,7 +221,7 @@ typedef enum { #define ZT_SETLINEAR _IOW (ZT_CODE, 40, int) #define ZT_GETCONFMUTE _IOR (ZT_CODE, 49, int) /* Get Conference to mute mode */ - +#define ZT_ECHOTRAIN _IOW (ZT_CODE, 50, int) /* Control Echo Trainer */ /* Openzap ZT hardware interface functions */ diff --git a/libs/freetdm/src/testanalog.c b/libs/freetdm/src/testanalog.c index 086eab7514..e1f17d23fd 100644 --- a/libs/freetdm/src/testanalog.c +++ b/libs/freetdm/src/testanalog.c @@ -25,7 +25,7 @@ static void *test_call(zap_thread_t *me, void *obj) if (flags & ZAP_READ) { if (zap_channel_read(chan, frame, &len) == ZAP_SUCCESS) { //zap_log(ZAP_LOG_DEBUG, "WRITE %d\n", len); - zap_channel_write(chan, frame, &len); + zap_channel_write(chan, frame, sizeof(frame), &len); } else { break; } diff --git a/libs/freetdm/src/testapp.c b/libs/freetdm/src/testapp.c index 309239c3d4..12b22b30b3 100644 --- a/libs/freetdm/src/testapp.c +++ b/libs/freetdm/src/testapp.c @@ -8,11 +8,6 @@ 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"); @@ -23,7 +18,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(argv[1], 1, 1, &chan) == ZAP_SUCCESS) { + if (zap_channel_open(1, 1, &chan) == ZAP_SUCCESS) { int x = 0; printf("opened channel %d:%d\n", chan->span_id, chan->chan_id); diff --git a/libs/freetdm/src/zap_analog.c b/libs/freetdm/src/zap_analog.c index 400a8999ac..a6feaabc07 100644 --- a/libs/freetdm/src/zap_analog.c +++ b/libs/freetdm/src/zap_analog.c @@ -38,6 +38,14 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj); static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxo_outgoing_call) { + if (!zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) { + zap_channel_command(zchan, ZAP_COMMAND_OFFHOOK, NULL); + zap_channel_command(zchan, ZAP_COMMAND_ENABLE_PROGRESS_DETECT, NULL); + zchan->need_tone[ZAP_TONEMAP_DIAL] = 1; + zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DIALING); + zap_thread_create_detached(zap_analog_channel_run, zchan); + return ZAP_SUCCESS; + } return ZAP_FAIL; } @@ -114,6 +122,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zap_sigmsg_t sig; zap_status_t status; + zap_log(ZAP_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n"); ts.buffer = NULL; @@ -156,6 +165,17 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) if (!zap_test_flag(chan, ZAP_CHANNEL_STATE_CHANGE)) { switch(chan->state) { + case ZAP_CHANNEL_STATE_DIALING: + { + if (state_counter > 5000) { + if (chan->need_tone[ZAP_TONEMAP_DIAL]) { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY); + } else { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP); + } + } + } + break; case ZAP_CHANNEL_STATE_GENRING: { if (state_counter > 60000) { @@ -183,7 +203,11 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) case ZAP_CHANNEL_STATE_HANGUP: { if (state_counter > 2000) { - zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY); + if (chan->type == ZAP_CHAN_TYPE_FXO) { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_DOWN); + } else { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY); + } } } break; @@ -231,6 +255,11 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) continue; } break; + case ZAP_CHANNEL_STATE_DIALING: + { + zap_channel_use(chan); + } + break; case ZAP_CHANNEL_STATE_IDLE: { zap_channel_use(chan); @@ -323,6 +352,55 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) goto done; } + if (chan->detected_tone) { + zap_sigmsg_t sig; + memset(&sig, 0, sizeof(sig)); + sig.chan_id = chan->chan_id; + sig.span_id = chan->span_id; + sig.channel = chan; + sig.event_id = ZAP_SIGEVENT_TONE_DETECTED; + zap_log(ZAP_LOG_DEBUG, "Detected tone %s\n", zap_tonemap2str(chan->detected_tone)); + data->sig_cb(&sig); + + if (chan->type == ZAP_CHAN_TYPE_FXO) { + + if (chan->need_tone[chan->detected_tone]) { + switch (chan->detected_tone) { + case ZAP_TONEMAP_DIAL: + { + zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, chan->caller_data.ani); + state_counter = 0; + chan->need_tone[ZAP_TONEMAP_RING] = 1; + chan->need_tone[ZAP_TONEMAP_BUSY] = 1; + } + break; + case ZAP_TONEMAP_RING: + { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP); + } + break; + case ZAP_TONEMAP_BUSY: + { + zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY); + } + break; + default: + break; + } + chan->need_tone[chan->detected_tone] = 0; + } + } + chan->detected_tone = 0; + } + + if (chan->dtmf_buffer && zap_buffer_inuse(chan->dtmf_buffer)) { + rlen = len; + memset(frame, 0, len); + zap_channel_write(chan, frame, sizeof(frame), &rlen); + continue; + } + + if (!indicate) { continue; } @@ -337,6 +415,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) rlen = zap_buffer_read_loop(dt_buffer, frame, len); + if (chan->effective_codec != ZAP_CODEC_SLIN) { zio_codec_t codec_func = NULL; @@ -354,7 +433,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) } } - zap_channel_write(chan, frame, &rlen); + zap_channel_write(chan, frame, sizeof(frame), &rlen); } done: diff --git a/libs/freetdm/src/zap_io.c b/libs/freetdm/src/zap_io.c index 49bc73e73a..6df7ee8bc4 100644 --- a/libs/freetdm/src/zap_io.c +++ b/libs/freetdm/src/zap_io.c @@ -271,9 +271,30 @@ zap_status_t zap_span_load_tones(zap_span_t *span, char *mapname) while (zap_config_next_pair(&cfg, &var, &val)) { if (!strcasecmp(cfg.category, mapname) && var && val) { int index = zap_str2zap_tonemap(var); - if (index > ZAP_TONEMAP_INVALID) { + char valbuf[512]; + + if (index > ZAP_TONEMAP_INVALID || index == ZAP_TONEMAP_NONE) { zap_log(ZAP_LOG_WARNING, "Unknown tone name %s\n", var); } else { + char *p, *next; + int i = 0; + zap_set_string(valbuf, val); + val = valbuf; + if ((p = strchr(val, ':'))) { + *p++ = '\0'; + do { + teletone_process_t this; + next = strchr(p, ','); + this = atof(p); + span->tone_detect_map[index].freqs[i++] = this; + if (next) { + p = next + 1; + } + } while (next); + + zap_copy_string(span->tone_map[index], val, sizeof(span->tone_map[index])); + + } zap_log(ZAP_LOG_DEBUG, "added tone [%s] = [%s]\n", var, val); zap_copy_string(span->tone_map[index], val, sizeof(span->tone_map[index])); x++; @@ -718,7 +739,7 @@ static zap_status_t zchan_activate_dtmf_buffer(zap_channel_t *zchan) } if (!zchan->dtmf_on) { - zchan->dtmf_on = 150; + zchan->dtmf_on = 250; } if (!zchan->dtmf_off) { @@ -726,11 +747,16 @@ static zap_status_t zchan_activate_dtmf_buffer(zap_channel_t *zchan) } memset(&zchan->tone_session, 0, sizeof(zchan->tone_session)); - teletone_init_session(&zchan->tone_session, 1024, NULL, NULL); + teletone_init_session(&zchan->tone_session, 0, NULL, NULL); zchan->tone_session.rate = 8000; zchan->tone_session.duration = zchan->dtmf_on * (zchan->tone_session.rate / 1000); zchan->tone_session.wait = zchan->dtmf_off * (zchan->tone_session.rate / 1000); + /* + zchan->tone_session.debug = 1; + zchan->tone_session.debug_stream = stdout; + */ + return ZAP_SUCCESS; } @@ -809,6 +835,22 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo } } break; + case ZAP_COMMAND_ENABLE_PROGRESS_DETECT: + { + /* if they don't have thier own, use ours */ + teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_DIAL], &zchan->span->tone_detect_map[ZAP_TONEMAP_DIAL]); + teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_RING], &zchan->span->tone_detect_map[ZAP_TONEMAP_RING]); + teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_BUSY], &zchan->span->tone_detect_map[ZAP_TONEMAP_BUSY]); + zap_set_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT); + GOTO_STATUS(done, ZAP_SUCCESS); + } + break; + case ZAP_COMMAND_DISABLE_PROGRESS_DETECT: + { + zap_clear_flag_locked(zchan, ZAP_CHANNEL_PROGRESS_DETECT); + GOTO_STATUS(done, ZAP_SUCCESS); + } + break; case ZAP_COMMAND_ENABLE_TONE_DETECT: { /* if they don't have thier own, use ours */ @@ -816,8 +858,8 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT; if (tt == ZAP_TONE_DTMF) { teletone_dtmf_detect_init (&zchan->dtmf_detect, 8000); - zap_set_flag(zchan, ZAP_CHANNEL_DTMF_DETECT); - zap_set_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF); + zap_set_flag_locked(zchan, ZAP_CHANNEL_DTMF_DETECT); + zap_set_flag_locked(zchan, ZAP_CHANNEL_SUPRESS_DTMF); GOTO_STATUS(done, ZAP_SUCCESS); } else { snprintf(zchan->last_error, sizeof(zchan->last_error), "invalid command"); @@ -890,6 +932,8 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { char *cur; char *digits = ZAP_COMMAND_OBJ_CHAR_P; + int x = 0; + if (!zchan->dtmf_buffer) { if ((status = zchan_activate_dtmf_buffer(zchan)) != ZAP_SUCCESS) { GOTO_STATUS(done, status); @@ -901,10 +945,11 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo int wrote = 0; if ((wrote = teletone_mux_tones(&zchan->tone_session, &zchan->tone_session.TONES[(int)*cur]))) { zap_buffer_write(zchan->dtmf_buffer, zchan->tone_session.buffer, wrote * 2); + x++; } } - zchan->skip_read_frames = 200; + zchan->skip_read_frames = 200 * x; GOTO_STATUS(done, ZAP_SUCCESS); } } @@ -1169,7 +1214,7 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data } } - if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT)) { + if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT) || zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) { uint8_t sln_buf[1024] = {0}; int16_t *sln; zap_size_t slen = 0; @@ -1203,47 +1248,62 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data slen = len; } - teletone_dtmf_detect(&zchan->dtmf_detect, sln, (int)slen); - teletone_dtmf_get(&zchan->dtmf_detect, digit_str, sizeof(digit_str)); - - if(*digit_str) { - zio_event_cb_t event_callback = NULL; - - zap_channel_queue_dtmf(zchan, digit_str); - - if (zchan->span->event_callback) { - event_callback = zchan->span->event_callback; - } else if (zchan->event_callback) { - event_callback = zchan->event_callback; + if (zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) { + uint32_t i; + + for (i = 0; i < ZAP_TONEMAP_INVALID+1; i++) { + if (zchan->span->tone_finder[i].tone_count) { + if (teletone_multi_tone_detect(&zchan->span->tone_finder[i], sln, (int)slen) && i != zchan->last_detected_tone) { + zchan->detected_tone = i; + zchan->last_detected_tone = i; + } + } } + } - if (event_callback) { - zchan->event_header.channel = zchan; - zchan->event_header.e_type = ZAP_EVENT_DTMF; - zchan->event_header.data = digit_str; - event_callback(zchan, &zchan->event_header); - zchan->event_header.e_type = ZAP_EVENT_NONE; - zchan->event_header.data = NULL; + if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT)) { + + teletone_dtmf_detect(&zchan->dtmf_detect, sln, (int)slen); + teletone_dtmf_get(&zchan->dtmf_detect, digit_str, sizeof(digit_str)); + + if(*digit_str) { + zio_event_cb_t event_callback = NULL; + + zap_channel_queue_dtmf(zchan, digit_str); + + if (zchan->span->event_callback) { + event_callback = zchan->span->event_callback; + } else if (zchan->event_callback) { + event_callback = zchan->event_callback; + } + + if (event_callback) { + zchan->event_header.channel = zchan; + zchan->event_header.e_type = ZAP_EVENT_DTMF; + zchan->event_header.data = digit_str; + event_callback(zchan, &zchan->event_header); + zchan->event_header.e_type = ZAP_EVENT_NONE; + zchan->event_header.data = NULL; + } + if (zap_test_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF)) { + zchan->skip_read_frames = 20; + } + if (zchan->skip_read_frames > 0) { + memset(data, 0, *datalen); + zchan->skip_read_frames--; + } } - if (zap_test_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF)) { - zchan->skip_read_frames = 20; - } - if (zchan->skip_read_frames > 0) { - memset(data, 0, *datalen); - zchan->skip_read_frames--; - } } } - return status; } -zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *datalen) +zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t datasize, zap_size_t *datalen) { zap_status_t status = ZAP_FAIL; zio_codec_t codec_func = NULL; - zap_size_t dtmf_blen, max = *datalen; + zap_size_t dtmf_blen, max = datasize; assert(zchan != NULL); assert(zchan->zio != NULL); @@ -1277,11 +1337,11 @@ zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *dat } } - if (zchan->dtmf_buffer && (dtmf_blen = zap_buffer_inuse(zchan->dtmf_buffer))) { + if (zchan->dtmf_buffer && (dtmf_blen = zap_buffer_inuse(zchan->dtmf_buffer)) && (!zchan->dtmf_delay || --zchan->dtmf_delay == 0)) { zap_size_t dlen = *datalen; uint8_t auxbuf[1024]; zap_size_t len, br; - + if (zchan->native_codec != ZAP_CODEC_SLIN) { dlen *= 2; } @@ -1305,6 +1365,7 @@ zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *dat zio_slin2alaw(data, max, datalen); } } + } status = zchan->zio->write(zchan, data, datalen); diff --git a/libs/freetdm/src/zap_isdn.c b/libs/freetdm/src/zap_isdn.c index 7bca3922b1..a8e7281460 100644 --- a/libs/freetdm/src/zap_isdn.c +++ b/libs/freetdm/src/zap_isdn.c @@ -95,7 +95,7 @@ static int zap_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen) #endif assert(span != NULL); - return zap_channel_write(span->isdn_data->dchan, msg, &len) == ZAP_SUCCESS ? 0 : -1; + return zap_channel_write(span->isdn_data->dchan, msg, len, &len) == ZAP_SUCCESS ? 0 : -1; } static void *zap_isdn_run(zap_thread_t *me, void *obj) diff --git a/libs/freetdm/src/zap_zt.c b/libs/freetdm/src/zap_zt.c index c5486ab8cf..9b02a35b0f 100644 --- a/libs/freetdm/src/zap_zt.c +++ b/libs/freetdm/src/zap_zt.c @@ -59,6 +59,14 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za sockfd = open(path, O_RDWR); if (sockfd != ZT_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) { + len = 64; + if (ioctl(chan->sockfd, ZT_ECHOCANCEL, &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; + } + 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",