From 864fd5fc6b8945ebc4e0e8fd0102c39bb1e0a898 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 25 May 2007 23:39:01 +0000 Subject: [PATCH] update git-svn-id: http://svn.openzap.org/svn/openzap/trunk@153 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/src/include/openzap.h | 12 +++- libs/openzap/src/include/zap_types.h | 5 +- libs/openzap/src/zap_analog.c | 43 ++++++++---- libs/openzap/src/zap_io.c | 97 ++++++++++++++++++++++------ 4 files changed, 122 insertions(+), 35 deletions(-) diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index f1a2c93854..b3e0f51a4a 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -188,8 +188,8 @@ #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_set_flag(obj, ZAP_CHANNEL_STATE_CHANGE);\ - obj->last_state = obj->state; obj->state = s; zap_mutex_unlock(obj->mutex); + zap_channel_set_state(obj, 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) @@ -319,7 +319,7 @@ struct zap_io_interface { struct zap_span spans[ZAP_MAX_SPANS_INTERFACE]; }; - +zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state); zap_status_t zap_span_load_tones(zap_span_t *span, char *mapname); zap_size_t zap_channel_dequeue_dtmf(zap_channel_t *zchan, char *dtmf, zap_size_t len); zap_status_t zap_channel_queue_dtmf(zap_channel_t *zchan, const char *dtmf); @@ -346,6 +346,12 @@ void zap_global_set_logger(zap_logger_t logger); void zap_global_set_default_logger(int level); uint32_t zap_separate_string(char *buf, char delim, char **array, int arraylen); void print_bits(uint8_t *b, int bl, char *buf, int blen, int e); +ZIO_CODEC_FUNCTION(zio_slin2ulaw); +ZIO_CODEC_FUNCTION(zio_ulaw2slin); +ZIO_CODEC_FUNCTION(zio_slin2alaw); +ZIO_CODEC_FUNCTION(zio_alaw2slin); +ZIO_CODEC_FUNCTION(zio_ulaw2alaw); +ZIO_CODEC_FUNCTION(zio_alaw2ulaw); #endif diff --git a/libs/openzap/src/include/zap_types.h b/libs/openzap/src/include/zap_types.h index 23bfaf9170..3801012105 100644 --- a/libs/openzap/src/include/zap_types.h +++ b/libs/openzap/src/include/zap_types.h @@ -100,13 +100,14 @@ typedef enum { ZAP_SIGEVENT_STOP, ZAP_SIGEVENT_TRANSFER, ZAP_SIGEVENT_ANSWER, + ZAP_SIGEVENT_UP, ZAP_SIGEVENT_PROGRESS, ZAP_SIGEVENT_PROGRESS_MEDIA, ZAP_SIGEVENT_NOTIFY, ZAP_SIGEVENT_MISC, ZAP_SIGEVENT_INVALID } zap_signal_event_t; -#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "MISC", "INVALID" +#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "MISC", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t) typedef enum { @@ -155,6 +156,8 @@ typedef enum { ZAP_COMMAND_GET_INTERVAL, ZAP_COMMAND_SET_CODEC, ZAP_COMMAND_GET_CODEC, + ZAP_COMMAND_SET_NATIVE_CODEC, + ZAP_COMMAND_GET_NATIVE_CODEC, ZAP_COMMAND_ENABLE_TONE_DETECT, ZAP_COMMAND_DISABLE_TONE_DETECT, ZAP_COMMAND_SEND_DTMF, diff --git a/libs/openzap/src/zap_analog.c b/libs/openzap/src/zap_analog.c index d4f80a1ff8..5852dd8a02 100644 --- a/libs/openzap/src/zap_analog.c +++ b/libs/openzap/src/zap_analog.c @@ -86,7 +86,6 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) teletone_generation_session_t ts; uint8_t frame[1024]; zap_size_t len, rlen; - zap_codec_t codec = ZAP_CODEC_SLIN, old_codec; zap_tone_type_t tt = ZAP_TONE_DTMF; char dtmf[128]; int dtmf_offset = 0; @@ -112,19 +111,19 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) zap_set_flag_locked(chan, ZAP_CHANNEL_INTHREAD); teletone_init_session(&ts, 0, teletone_handler, dt_buffer); ts.rate = 8000; - zap_channel_command(chan, ZAP_COMMAND_GET_CODEC, &old_codec); + zap_channel_command(chan, ZAP_COMMAND_GET_INTERVAL, &interval); zap_buffer_set_loops(dt_buffer, -1); while (zap_test_flag(chan, ZAP_CHANNEL_INTHREAD)) { zap_wait_flag_t flags = ZAP_READ; zap_size_t dlen = 0; - + len = sizeof(frame); elapsed += interval; state_counter += interval; - + if (!zap_test_flag(chan, ZAP_CHANNEL_STATE_CHANGE)) { switch(chan->state) { case ZAP_CHANNEL_STATE_DIALTONE: @@ -144,6 +143,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) case ZAP_CHANNEL_STATE_UP: case ZAP_CHANNEL_STATE_IDLE: { + zap_sleep(interval); continue; } @@ -153,13 +153,14 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) } } else { + zap_clear_flag_locked(chan, ZAP_CHANNEL_STATE_CHANGE); switch(chan->state) { case ZAP_CHANNEL_STATE_UP: { - zap_channel_command(chan, ZAP_COMMAND_SET_CODEC, &old_codec); - sig.event_id = ZAP_SIGEVENT_ANSWER; + sig.event_id = ZAP_SIGEVENT_UP; data->sig_cb(&sig); + continue; } break; @@ -173,6 +174,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) sig.span = chan->span; zap_copy_string(sig.dnis, dtmf, sizeof(sig.dnis)); data->sig_cb(&sig); + continue; } break; case ZAP_CHANNEL_STATE_DOWN: @@ -221,7 +223,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) state_counter = 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); @@ -245,11 +247,30 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) if (flags & ZAP_READ) { if (zap_channel_read(chan, frame, &len) == ZAP_SUCCESS) { + if (chan->effective_codec != ZAP_CODEC_SLIN) { + len *= 2; + } rlen = zap_buffer_read_loop(dt_buffer, frame, len); - if (indicate) { - if (chan->effective_codec != codec) { - zap_channel_command(chan, ZAP_COMMAND_SET_CODEC, &codec); + + if (indicate) { + zio_codec_t codec_func = NULL; + zap_status_t status; + + if (chan->effective_codec != ZAP_CODEC_SLIN) { + 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!"); + status = ZAP_FAIL; + } } + zap_channel_write(chan, frame, &rlen); } } else { @@ -264,7 +285,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj) closed_chan = chan; zap_channel_close(&chan); - zap_channel_command(closed_chan, ZAP_COMMAND_SET_CODEC, &old_codec); + zap_channel_command(closed_chan, ZAP_COMMAND_SET_NATIVE_CODEC, NULL); if (ts.buffer) { teletone_destroy_session(&ts); diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c index 61c73bb966..a651b624a2 100644 --- a/libs/openzap/src/zap_io.c +++ b/libs/openzap/src/zap_io.c @@ -370,6 +370,39 @@ zap_status_t zap_channel_set_event_callback(zap_channel_t *zchan, zio_event_cb_t return ZAP_SUCCESS; } + +zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state) +{ + int ok = 1; + + zap_mutex_unlock(zchan->mutex); + + if (zchan->state == ZAP_CHANNEL_STATE_DOWN) { + + switch(state) { + case ZAP_CHANNEL_STATE_BUSY: + ok = 0; + break; + default: + break; + } + } + + if (state == zchan->state) { + ok = 0; + } + + if (ok) { + zap_set_flag(zchan, ZAP_CHANNEL_STATE_CHANGE); + zchan->last_state = zchan->state; + zchan->state = state; + } + + 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_io_interface_t *zio; @@ -660,6 +693,17 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo } break; + case ZAP_COMMAND_SET_NATIVE_CODEC: + { + if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_CODECS)) { + zchan->effective_codec = zchan->native_codec; + zap_clear_flag(zchan, ZAP_CHANNEL_TRANSCODE); + zchan->packet_len = zchan->native_interval * (zchan->effective_codec == ZAP_CODEC_SLIN ? 16 : 8); + GOTO_STATUS(done, ZAP_SUCCESS); + } + } + break; + case ZAP_COMMAND_GET_CODEC: { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_CODECS)) { @@ -668,6 +712,14 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo } } break; + case ZAP_COMMAND_GET_NATIVE_CODEC: + { + if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_CODECS)) { + ZAP_COMMAND_OBJ_INT = zchan->native_codec; + GOTO_STATUS(done, ZAP_SUCCESS); + } + } + break; case ZAP_COMMAND_ENABLE_TONE_DETECT: { /* if they don't have thier own, use ours */ @@ -937,15 +989,17 @@ ZIO_CODEC_FUNCTION(zio_alaw2ulaw) zap_size_t zap_channel_dequeue_dtmf(zap_channel_t *zchan, char *dtmf, zap_size_t len) { - zap_size_t bytes; + zap_size_t bytes = 0; assert(zchan != NULL); - zap_mutex_lock(zchan->mutex); - if ((bytes = zap_buffer_read(zchan->digit_buffer, dtmf, len)) > 0) { - *(dtmf + bytes) = '\0'; + if (zap_buffer_inuse(zchan->digit_buffer)) { + zap_mutex_lock(zchan->mutex); + if ((bytes = zap_buffer_read(zchan->digit_buffer, dtmf, len)) > 0) { + *(dtmf + bytes) = '\0'; + } + zap_mutex_unlock(zchan->mutex); } - zap_mutex_unlock(zchan->mutex); return bytes; } @@ -1027,8 +1081,9 @@ 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)) { - int16_t sln_buf[1024], *sln = sln_buf; - zap_size_t slen; + uint8_t sln_buf[2048] = {0}; + int16_t *sln; + zap_size_t slen = 0; char digit_str[80] = ""; if (zchan->effective_codec == ZAP_CODEC_SLIN) { @@ -1038,23 +1093,25 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data zap_size_t len = *datalen; uint32_t i; uint8_t *lp = data; - slen = max; + + slen = sizeof(sln_buf); + if (len > slen) { + len = slen; + } - if (slen > len) { - slen = len; - } - - if (zchan->effective_codec == ZAP_CODEC_ULAW) { - for(i = 0; i < slen; i++) { + sln = (int16_t *) sln_buf; + for(i = 0; i < len; i++) { + if (zchan->effective_codec == ZAP_CODEC_ULAW) { *sln++ = ulaw_to_linear(*lp++); - } - } else if (zchan->effective_codec == ZAP_CODEC_ALAW) { - for(i = 0; i < slen; i++) { + } else if (zchan->effective_codec == ZAP_CODEC_ALAW) { *sln++ = alaw_to_linear(*lp++); - } + } else { + snprintf(zchan->last_error, sizeof(zchan->last_error), "codec error!"); + return ZAP_FAIL; + } } - - sln = sln_buf; + sln = (int16_t *) sln_buf; + slen = len; } teletone_dtmf_detect(&zchan->dtmf_detect, sln, (int)slen);