From fa05585f1a55255ec937ed2cb3eb52743613b972 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 9 Dec 2010 12:48:33 -0200 Subject: [PATCH 01/17] freetdm: ftmod_zt - created zt_channel_next_event() to poll for events on a single channel --- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 9247edc72e..9a6597c892 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -177,6 +177,7 @@ static ftdm_socket_t CONTROL_FD = ZT_INVALID_SOCKET; FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event); FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event); +FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event); /** * \brief Initialises codec, and rx/tx gains @@ -981,6 +982,107 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) return k ? FTDM_SUCCESS : FTDM_FAIL; } +/** + * \brief Retrieves an event from a ftdmtel span + * \param ftdmchan Channel to retrieve event from + * \param event FreeTDM event to return + * \return Success or failure + */ +FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event) +{ + uint32_t i, event_id = FTDM_OOB_INVALID; + zt_event_t zt_event_id = 0; + ftdm_span_t *span = ftdmchan->span; + + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) { + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT); + if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { + snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); + return FTDM_FAIL; + } + + switch(zt_event_id) { + case ZT_EVENT_RINGEROFF: + { + return FTDM_FAIL; + } + break; + case ZT_EVENT_RINGERON: + { + return FTDM_FAIL; + } + break; + case ZT_EVENT_RINGBEGIN: + { + event_id = FTDM_OOB_RING_START; + } + break; + case ZT_EVENT_ONHOOK: + { + event_id = FTDM_OOB_ONHOOK; + } + break; + case ZT_EVENT_WINKFLASH: + { + if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { + event_id = FTDM_OOB_WINK; + } else { + event_id = FTDM_OOB_FLASH; + } + } + break; + case ZT_EVENT_RINGOFFHOOK: + { + if (ftdmchan->type == FTDM_CHAN_TYPE_FXS || (ftdmchan->type == FTDM_CHAN_TYPE_EM && ftdmchan->state != FTDM_CHANNEL_STATE_UP)) { + ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); + event_id = FTDM_OOB_OFFHOOK; + } else if (ftdmchan->type == FTDM_CHAN_TYPE_FXO) { + event_id = FTDM_OOB_RING_START; + } else { + event_id = FTDM_OOB_NOOP; + } + } + break; + case ZT_EVENT_ALARM: + { + event_id = FTDM_OOB_ALARM_TRAP; + } + break; + case ZT_EVENT_NOALARM: + { + event_id = FTDM_OOB_ALARM_CLEAR; + } + break; + case ZT_EVENT_BITSCHANGED: + { + event_id = FTDM_OOB_CAS_BITS_CHANGE; + int bits = 0; + int err = ioctl(ftdmchan->sockfd, codes.GETRXBITS, &bits); + if (err) { + return FTDM_FAIL; + } + ftdmchan->rx_cas_bits = bits; + } + break; + default: + { + ftdm_log(FTDM_LOG_WARNING, "Unhandled event %d for %d:%d\n", zt_event_id, span->span_id, i); + event_id = FTDM_OOB_INVALID; + } + break; + } + + ftdmchan->last_event_time = 0; + span->event_header.e_type = FTDM_EVENT_OOB; + span->event_header.enum_id = event_id; + span->event_header.channel = ftdmchan; + *event = &span->event_header; + return FTDM_SUCCESS; + } + + return FTDM_FAIL; +} + /** * \brief Retrieves an event from a ftdmtel span * \param span Span to retrieve event from From 36a84423e7c788a73348420ebcd9dcee95d34fd3 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 9 Dec 2010 12:52:32 -0200 Subject: [PATCH 02/17] freetdm: ftmod_zt - fixed typo on documentation --- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 9a6597c892..e1d664092a 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -983,7 +983,7 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) } /** - * \brief Retrieves an event from a ftdmtel span + * \brief Retrieves an event from a ftdm channel * \param ftdmchan Channel to retrieve event from * \param event FreeTDM event to return * \return Success or failure From 723a598c24ffd6b70b67e1ee1864a87ba33ed1ce Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Tue, 21 Dec 2010 16:32:02 -0200 Subject: [PATCH 03/17] freetdm: core - lock the channel on ftdm_channel_read_event() ftmod_zt - not locking the channel on zt_channel_next_event(), minor changes --- libs/freetdm/src/ftdm_io.c | 9 +++++++-- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index c04dd85a17..458025e5de 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1142,14 +1142,17 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm ftdm_span_t *span = ftdmchan->span; ftdm_assert_return(span->fio != NULL, FTDM_FAIL, "No I/O module attached to this span!\n"); + ftdm_channel_lock(ftdmchan); + if (!span->fio->channel_next_event) { ftdm_log(FTDM_LOG_ERROR, "channel_next_event method not implemented in module %s!", span->fio->name); - return FTDM_NOTIMPL; + status = FTDM_NOTIMPL; + goto done; } status = span->fio->channel_next_event(ftdmchan, event); if (status != FTDM_SUCCESS) { - return status; + goto done; } /* before returning the event to the user we do some core operations with certain OOB events */ @@ -1177,6 +1180,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm break; } +done: + ftdm_channel_unlock(ftdmchan); return status; } diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 25f9b291ed..7ce3f71cc8 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -1007,7 +1007,8 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event) if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) { ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT); if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { - snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event from channel: %s\n", + strerror(errno)); return FTDM_FAIL; } @@ -1044,7 +1045,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event) case ZT_EVENT_RINGOFFHOOK: { if (ftdmchan->type == FTDM_CHAN_TYPE_FXS || (ftdmchan->type == FTDM_CHAN_TYPE_EM && ftdmchan->state != FTDM_CHANNEL_STATE_UP)) { - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK); event_id = FTDM_OOB_OFFHOOK; } else if (ftdmchan->type == FTDM_CHAN_TYPE_FXO) { event_id = FTDM_OOB_RING_START; @@ -1076,7 +1077,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event) break; default: { - ftdm_log(FTDM_LOG_WARNING, "Unhandled event %d for %d:%d\n", zt_event_id, span->span_id, i); + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled event %d for %d:%d\n", zt_event_id, span->span_id, i); event_id = FTDM_OOB_INVALID; } break; From a3b01c195be3c1454c60e634477d8c825c60ac77 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 21 Dec 2010 15:35:13 -0600 Subject: [PATCH 04/17] rtp adjustments when using jitterbuffer --- src/switch_ivr.c | 2 +- src/switch_rtp.c | 39 ++++++++++++--------------------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index cd74c332b7..68d5a55b40 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2285,7 +2285,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 break; } - stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen); + stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen, 0); ts += interval; if ((jb_frame = stfu_n_read_a_frame(jb))) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4e667fb49b..aa4ca7a5ca 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2135,19 +2135,6 @@ static void do_flush(switch_rtp_t *rtp_session) flushed++; -#ifdef _MSC_VER -#pragma warning(push) /* remove this stuff when "if (0" is removed */ -#pragma warning(disable:4127) -#endif - if (0 && rtp_session->jb) { - stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), - rtp_session->recv_msg.header.pt, - rtp_session->recv_msg.body, bytes - rtp_header_len); - } -#ifdef _MSC_VER -#pragma warning(pop) -#endif - rtp_session->stats.inbound.raw_bytes += bytes; rtp_session->stats.inbound.flush_packet_count++; rtp_session->stats.inbound.packet_count++; @@ -2196,12 +2183,13 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->stats.inbound.packet_count++; } - if ((rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) || - *bytes < rtp_header_len || - switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) { - return SWITCH_STATUS_SUCCESS; + if (*bytes != 0 && !rtp_session->jb) { + if ((rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) || + *bytes < rtp_header_len || + switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) { + return SWITCH_STATUS_SUCCESS; + } } - if (rtp_session->jb && rtp_session->recv_msg.header.version == 2 && *bytes) { if (rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te && @@ -2211,14 +2199,15 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), rtp_session->recv_msg.header.pt, - rtp_session->recv_msg.body, *bytes - rtp_header_len); + rtp_session->recv_msg.body, *bytes - rtp_header_len, rtp_session->timer.samplecount); *bytes = 0; status = SWITCH_STATUS_FALSE; } - if (rtp_session->jb) { + if (rtp_session->jb && !rtp_session->checked_jb) { if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) { memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen); + if (jb_frame->plc) { (*flags) |= SFF_PLC; } else { @@ -2229,6 +2218,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->recv_msg.header.pt = jb_frame->pt; status = SWITCH_STATUS_SUCCESS; } + rtp_session->checked_jb++; } @@ -2385,7 +2375,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->read_pollfd) { if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) { rtp_session->hot_hits += rtp_session->samples_per_interval; - + if (rtp_session->hot_hits >= rtp_session->samples_per_second * 5) { switch_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); hot_socket = 1; @@ -2927,12 +2917,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (do_cng) { uint8_t *data = (uint8_t *) rtp_session->recv_msg.body; - int fdr; - - if ((poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, 0)) == SWITCH_STATUS_SUCCESS) { - goto recvfrom; - } - + memset(data, 0, 2); data[0] = 65; rtp_session->recv_msg.header.pt = (uint32_t) rtp_session->cng_pt ? rtp_session->cng_pt : SWITCH_RTP_CNG_PAYLOAD; From e80a40cf6835052ccf9750b6c89cd2fa4b776584 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 21 Dec 2010 15:35:30 -0600 Subject: [PATCH 05/17] rtp adjustments when using jitterbuffer --- libs/stfu/stfu.c | 29 +++++++++++++++++++++-------- libs/stfu/stfu.h | 7 ++++--- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index b7df8ea870..d2c443a9e7 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -100,7 +100,9 @@ struct stfu_instance { uint32_t sync_out; uint32_t sync_in; - + int32_t ts_offset; + int32_t ts_drift; + int32_t ts_diff; int32_t last_ts_diff; int32_t same_ts; @@ -126,6 +128,11 @@ static void default_logger(const char *file, const char *func, int line, int lev stfu_logger_t stfu_log = null_logger; +int32_t stfu_n_get_drift(stfu_instance_t *i) +{ + return i->ts_drift; +} + void stfu_global_set_logger(stfu_logger_t logger) { if (logger) { @@ -376,7 +383,7 @@ static void stfu_n_swap(stfu_instance_t *i) i->out_queue->last_jitter = 0; } -stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last) +stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last) { uint32_t index = 0; stfu_frame_t *frame; @@ -402,6 +409,12 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void } } + if (timer_ts && ts && !i->ts_offset) { + i->ts_offset = timer_ts - ts; + } + + i->ts_drift = ts + (i->ts_offset - timer_ts); + if (i->sync_in) { good_ts = 1; i->sync_in = 0; @@ -480,12 +493,12 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s %u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u:%u - %u %d %u %u %d %d\n", i->name, - i->qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count, - i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count, - ts, ts / i->samples_per_packet, - i->period_missing_count, i->period_need_range_avg, - i->last_wr_ts, ts, i->diff, i->diff_total / least1(i->period_packet_in_count)); + stfu_log(STFU_LOG_EMERG, "I: %s %u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u:%u - %u %d %u %u %d %d %d\n", i->name, + i->qlen, i->period_packet_in_count, i->period_time, i->consecutive_good_count, + i->decrement_time, i->period_clean_count, i->decrement_time, i->consecutive_bad_count, + ts, ts / i->samples_per_packet, + i->period_missing_count, i->period_need_range_avg, + i->last_wr_ts, ts, i->diff, i->diff_total / least1(i->period_packet_in_count), i->ts_drift); } if (last || i->in_queue->array_len == i->in_queue->array_size) { diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index ad769c62e2..b92bb3f839 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -181,15 +181,16 @@ void stfu_n_report(stfu_instance_t *i, stfu_report_t *r); void stfu_n_destroy(stfu_instance_t **i); stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second); stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen); -stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, int last); +stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last); stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i); void stfu_n_reset(stfu_instance_t *i); stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets); void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata); void stfu_n_debug(stfu_instance_t *i, const char *name); +int32_t stfu_n_get_drift(stfu_instance_t *i); -#define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 1) -#define stfu_n_eat(i,t,p,d,l) stfu_n_add_data(i, t, p, d, l, 0) +#define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 0, 1) +#define stfu_n_eat(i,t,p,d,l,tt) stfu_n_add_data(i, t, p, d, l, tt, 0) #ifdef __cplusplus } From a1e425029c3a123d1b77d8e81acea873af81961e Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 21 Dec 2010 16:59:25 -0600 Subject: [PATCH 06/17] FS-2944 --- conf/directory/default/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/directory/default/default.xml b/conf/directory/default/default.xml index 5db60112dc..aa138f18d9 100644 --- a/conf/directory/default/default.xml +++ b/conf/directory/default/default.xml @@ -1,7 +1,7 @@