From b02682bdbee84142708b4a8b97ca67ad4131ac9e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 22:55:43 -0500 Subject: [PATCH 001/244] freetdm: ftdm_r2 - process only OOB events --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 4 ++++ libs/freetdm/src/testsangomaboost.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index ab85d2b4d6..cfb57b28e6 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -988,6 +988,10 @@ static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *e return -1; } + if (fevent->e_type != FTDM_EVENT_OOB) { + return 0; + } + switch (fevent->enum_id) { case FTDM_OOB_CAS_BITS_CHANGE: { diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index e9042eef17..01e5a6be22 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -52,7 +52,6 @@ #define __USE_BSD #endif #include -#endif #include "freetdm.h" From 87bb33ae3a79c7c6abb61d3e7b74c84b3562f30e Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 08:44:55 -0600 Subject: [PATCH 002/244] windows fix x64 build warnings freetdm --- libs/freetdm/src/ftdm_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 249d8580b5..46ae77f435 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3415,7 +3415,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read) ftdm_status_t status = ftdmchan->fio->read(ftdmchan, data, datalen); if (status == FTDM_SUCCESS && ftdmchan->fds[FTDM_READ_TRACE_INDEX] > -1) { ftdm_size_t dlen = *datalen; - if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, dlen) != dlen) { + if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, (int)dlen) != dlen) { ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %zd bytes\n", dlen); } } @@ -3428,7 +3428,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read) ftdm_size_t dlen = *datalen; ftdm_size_t rc = 0; - write_chan_io_dump(&ftdmchan->rxdump, data, dlen); + write_chan_io_dump(&ftdmchan->rxdump, data, (int)dlen); /* if dtmf debug is enabled and initialized, write there too */ if (ftdmchan->dtmfdbg.file) { From fa05585f1a55255ec937ed2cb3eb52743613b972 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 9 Dec 2010 12:48:33 -0200 Subject: [PATCH 003/244] 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 004/244] 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 e680c821297c26530b118ab4ef77f030b1f6e365 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 08:59:06 -0600 Subject: [PATCH 005/244] Freetdm windows fixes --- libs/freetdm/freetdm.2010.sln | 2 -- libs/freetdm/src/testsangomaboost.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/freetdm.2010.sln b/libs/freetdm/freetdm.2010.sln index f4bd907a6d..44431d675a 100644 --- a/libs/freetdm/freetdm.2010.sln +++ b/libs/freetdm/freetdm.2010.sln @@ -119,10 +119,8 @@ Global {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64 {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64 {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32 {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64 {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32 - {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32 {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64 {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32 {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index 01e5a6be22..b254a08bb8 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -51,7 +51,9 @@ #if defined(__linux__) && !defined(__USE_BSD) #define __USE_BSD #endif +#ifndef WIN32 #include +#endif #include "freetdm.h" From a15f51d5772c47fe3a3e49542d227dad5e7e9944 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 09:22:17 -0600 Subject: [PATCH 006/244] ESL-37 [patch] Make last_event pointer last longer --- libs/esl/src/esl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 4a02a8fe38..ce582d3837 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -1177,7 +1177,6 @@ ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char * return ESL_FAIL; } - esl_event_safe_destroy(&handle->last_event); esl_event_safe_destroy(&handle->last_sr_event); *handle->last_sr_reply = '\0'; From cfd4d52dd07085c2dab6e89f4c7be9a7b4f4287d Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 12:01:24 -0600 Subject: [PATCH 007/244] fix memory alloc issue --- src/mod/endpoints/mod_sofia/sofia_presence.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 143666ceb8..5d666f03ee 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -90,6 +90,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co char *user_via = NULL; char *contact_str = NULL; char *dup_dest = NULL; + char *remote_host = NULL; if (!to) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n"); @@ -185,11 +186,9 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co /* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */ - remote_ip = malloc(sizeof(80)); dup_dest = strdup(dst->contact); if (switch_stristr("fs_path", dst->contact)) { - char *remote_host = NULL; const char *s; if ((s = switch_stristr("fs_path=", dst->contact))) { @@ -202,7 +201,6 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co if (!zstr(remote_host)) { switch_split_user_domain(remote_host, NULL, &remote_ip); } - switch_safe_free(remote_host); } if (zstr(remote_ip)) { @@ -236,7 +234,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co } switch_safe_free(dup_dest); - free(remote_ip); + switch_safe_free(remote_host); status = SWITCH_STATUS_SUCCESS; From 8016813234b471e5636bcff963f5a4ed3391d972 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 14:03:09 -0600 Subject: [PATCH 008/244] freetdm VS2010 build fix --- libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj index ec69333410..9f01a3b1a1 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj @@ -103,7 +103,7 @@ ProgramDatabase - FreeSwitchCore.lib;%(AdditionalDependencies) + FreeSwitch.lib;%(AdditionalDependencies) ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true $(OutDir)$(TargetName).pdb @@ -127,7 +127,7 @@ ProgramDatabase - FreeSwitchCore.lib;%(AdditionalDependencies) + FreeSwitch.lib;%(AdditionalDependencies) ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true $(OutDir)$(TargetName).pdb From c6e7988bf87c910ce19366c40694f1e14fd58cb3 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 14:25:39 -0600 Subject: [PATCH 009/244] FS-2904 detect_speech documentation incomplete --- src/mod/applications/mod_dptools/mod_dptools.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 4fd6a676ea..eaff5b9364 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -269,7 +269,7 @@ SWITCH_STANDARD_APP(bind_digit_action_function) } -#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR pause OR resume" +#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR nogrammar OR pause OR resume OR stop OR param " SWITCH_STANDARD_APP(detect_speech_function) { char *argv[4]; From 3406d05ba7fafb8e20f69bede72db3564bf8b198 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 23:05:49 -0600 Subject: [PATCH 010/244] Fix fallback to CORE_DB when MSSQL fails init --- src/switch_core_sqldb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 4364ff2844..b561ebe775 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1624,6 +1624,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ runtime.odbc_dsn = NULL; runtime.odbc_user = NULL; runtime.odbc_pass = NULL; + runtime.odbc_dbtype = DBTYPE_DEFAULT; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n"); goto top; } From 98ed05cc9800c205389b0f286afddea923cab757 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Fri, 10 Dec 2010 14:30:47 -0500 Subject: [PATCH 011/244] Add reuse-connections sofia profile param to allow users to turn off TPTAG_REUSE, thus not re-using TCP connections --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 6970a7ab05..61d165753c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -225,6 +225,7 @@ typedef enum { PFLAG_DEL_SUBS_ON_REG, PFLAG_IGNORE_183NOSDP, PFLAG_PRESENCE_PROBE_ON_REGISTER, + PFLAG_NO_CONNECTION_REUSE, /* No new flags below this line */ PFLAG_MAX } PFLAGS; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2e13b544d0..e34d7aef9d 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1486,6 +1486,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void TAG_IF(profile->timer_t2, NTATAG_SIP_T2(profile->timer_t2)), TAG_IF(profile->timer_t4, NTATAG_SIP_T4(profile->timer_t4)), SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed"), + TAG_IF(sofia_test_pflag(profile, PFLAG_NO_CONNECTION_REUSE), + TPTAG_REUSE(0)), TAG_END()); /* Last tag should always finish the sequence */ if (!profile->nua) { @@ -3673,6 +3675,13 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { profile->timer_t4 = 4000; } + } else if (!strcasecmp(var, "reuse-connections")) { + switch_bool_t value = switch_true(val); + if (!value) { + sofia_set_pflag(profile, PFLAG_NO_CONNECTION_REUSE); + } else { + sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE); + } } } From c5e2fc1571827e7bd861ce69a6878102fe16ef13 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Fri, 10 Dec 2010 14:56:29 -0500 Subject: [PATCH 012/244] fix configure --srcdir for freetdm --- libs/freetdm/configure.gnu | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/configure.gnu b/libs/freetdm/configure.gnu index 5785ffc0e7..d00cd18473 100755 --- a/libs/freetdm/configure.gnu +++ b/libs/freetdm/configure.gnu @@ -1,3 +1,3 @@ #! /bin/sh -./configure "$@" --with-pic - +srcpath=$(dirname $0 2>/dev/null ) || srcpath="." +$srcpath/configure "$@" --with-pic From bbf1cd1f437d4a90b2b8bf7b9017c3786b2777f5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 9 Dec 2010 14:09:38 -0600 Subject: [PATCH 013/244] allow epoch in strftime_tz --- .../applications/mod_commands/mod_commands.c | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index eacde59949..9d6920e6cd 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -4278,21 +4278,33 @@ SWITCH_STANDARD_API(strftime_tz_api_function) char *format = NULL; const char *tz_name = NULL; char date[80] = ""; + char *mycmd = NULL, *p; + switch_time_t when = 0; - if (!zstr(cmd)) { - format = strchr(cmd, ' '); - tz_name = cmd; - if (format) { + if (cmd) mycmd = strdup(cmd); + + if (!zstr(mycmd)) { + tz_name = mycmd; + + if ((format = strchr(mycmd, ' '))) { *format++ = '\0'; } + + if ((p = strchr(format, '|'))) { + *p++ = '\0'; + when = atol(format); + format = p; + } } - if (switch_strftime_tz(tz_name, format, date, sizeof(date), 0) == SWITCH_STATUS_SUCCESS) { /* The lookup of the zone may fail. */ + if (switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) { /* The lookup of the zone may fail. */ stream->write_function(stream, "%s", date); } else { stream->write_function(stream, "-ERR Invalid Timezone\n"); } + switch_safe_free(mycmd); + return SWITCH_STATUS_SUCCESS; } @@ -4715,7 +4727,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "show", "Show", show_function, SHOW_SYNTAX); SWITCH_ADD_API(commands_api_interface, "sql_escape", "Escape a string to prevent sql injection", sql_escape, SQL_ESCAPE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "status", "status", status_function, ""); - SWITCH_ADD_API(commands_api_interface, "strftime_tz", "strftime_tz", strftime_tz_api_function, " [format string]"); + SWITCH_ADD_API(commands_api_interface, "strftime_tz", "strftime_tz", strftime_tz_api_function, " [|][format string]"); SWITCH_ADD_API(commands_api_interface, "stun", "stun", stun_function, "[:port]"); SWITCH_ADD_API(commands_api_interface, "system", "Execute a system command", system_function, SYSTEM_SYNTAX); SWITCH_ADD_API(commands_api_interface, "time_test", "time_test", time_test_function, " [count]"); From d5470961642db233aba14432a66195b4acef370f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Dec 2010 17:47:24 -0600 Subject: [PATCH 014/244] dramatic jitterbuffer changes --- src/include/private/switch_core_pvt.h | 3 +- src/include/switch_rtp.h | 7 +- src/include/switch_types.h | 2 + .../applications/mod_commands/mod_commands.c | 57 ++++++++++++ .../applications/mod_dptools/mod_dptools.c | 26 +++++- src/mod/endpoints/mod_sofia/mod_sofia.c | 45 ++++++++- src/mod/endpoints/mod_sofia/sofia_glue.c | 33 +++++-- src/switch_core_io.c | 43 ++++++++- src/switch_ivr.c | 4 +- src/switch_rtp.c | 92 +++++++++++++++++-- 10 files changed, 285 insertions(+), 27 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 13410a00ae..a565299fae 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -31,7 +31,7 @@ * this file does not exist!!!! * */ - +#include "spandsp.h" #include "switch_profile.h" #ifndef WIN32 @@ -169,6 +169,7 @@ struct switch_core_session { switch_log_level_t loglevel; uint32_t soft_lock; switch_ivr_dmachine_t *dmachine; + plc_state_t *plc; }; struct switch_media_bug { diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 7269a2b8d9..e3e9f665a3 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -229,7 +229,12 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi \param queue_frames the number of frames to delay \return SWITCH_STATUS_SUCCESS */ -SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames); +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, + uint32_t queue_frames, + uint32_t max_queue_frames, + uint32_t samples_per_packet, uint32_t samples_per_second); + +SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session); /*! \brief Set an RTP Flag diff --git a/src/include/switch_types.h b/src/include/switch_types.h index c01638089f..d020775d48 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -790,6 +790,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION, SWITCH_MESSAGE_INDICATE_UDPTL_MODE, SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, + SWITCH_MESSAGE_INDICATE_JITTER_BUFFER, SWITCH_MESSAGE_INVALID } switch_core_session_message_types_t; @@ -1093,6 +1094,7 @@ typedef enum { CF_PASSTHRU_PTIME_MISMATCH, CF_BRIDGE_NOWRITE, CF_RECOVERED, + CF_JITTERBUFFER, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CF_FLAG_MAX } switch_channel_flag_t; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 9d6920e6cd..dba86e3103 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2542,6 +2542,60 @@ SWITCH_STANDARD_API(uuid_simplify_function) } +#define JITTERBUFFER_SYNTAX " [0|[:]]" +SWITCH_STANDARD_API(uuid_jitterbuffer_function) +{ + char *mydata = NULL, *argv[2] = { 0 }; + int argc = 0; + + switch_status_t status = SWITCH_STATUS_FALSE; + + if (zstr(cmd)) { + goto error; + } + + mydata = strdup(cmd); + switch_assert(mydata); + + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc < 2) { + goto error; + } + if (argv[1]) { + switch_core_session_message_t msg = { 0 }; + switch_core_session_t *lsession = NULL; + + msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER; + msg.string_arg = argv[1]; + msg.from = __FILE__; + + if ((lsession = switch_core_session_locate(argv[0]))) { + status = switch_core_session_receive_message(lsession, &msg); + switch_core_session_rwunlock(lsession); + } + goto ok; + } else { + goto error; + } + + error: + stream->write_function(stream, "-USAGE: %s\n", JITTERBUFFER_SYNTAX); + switch_safe_free(mydata); + return SWITCH_STATUS_SUCCESS; + ok: + switch_safe_free(mydata); + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Success\n"); + } else { + stream->write_function(stream, "-ERR Operation Failed\n"); + } + + return SWITCH_STATUS_SUCCESS; +} + + #define PHONE_EVENT_SYNTAX "" SWITCH_STANDARD_API(uuid_phone_event_function) { @@ -4770,6 +4824,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_transfer", "Transfer a session", transfer_function, TRANSFER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_dual_transfer", "Transfer a session and its partner", dual_transfer_function, DUAL_TRANSFER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_simplify", "Try to cut out of a call path / attended xfer", uuid_simplify_function, SIMPLIFY_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_jitterbuffer", "Try to cut out of a call path / attended xfer", + uuid_jitterbuffer_function, JITTERBUFFER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "xml_locate", "find some xml", xml_locate_function, "[root |
]"); SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, " "); switch_console_set_complete("add alias add"); @@ -4866,6 +4922,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid"); switch_console_set_complete("add uuid_getvar ::console::list_uuid"); switch_console_set_complete("add uuid_hold ::console::list_uuid"); + switch_console_set_complete("add uuid_jitterbuffer ::console::list_uuid"); switch_console_set_complete("add uuid_kill ::console::list_uuid"); switch_console_set_complete("add uuid_limit_release ::console::list_uuid"); switch_console_set_complete("add uuid_loglevel ::console::list_uuid console"); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index eaff5b9364..e508486380 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -957,6 +957,17 @@ SWITCH_STANDARD_APP(redirect_function) switch_core_session_receive_message(session, &msg); } +SWITCH_STANDARD_APP(jitterbuffer_function) +{ + switch_core_session_message_t msg = { 0 }; + + /* Tell the channel to change the jitter buffer */ + msg.from = __FILE__; + msg.string_arg = data; + msg.message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER; + switch_core_session_receive_message(session, &msg); +} + SWITCH_STANDARD_APP(display_function) { switch_core_session_message_t msg = { 0 }; @@ -1303,13 +1314,22 @@ SWITCH_STANDARD_API(strftime_api_function) char date[80] = ""; switch_time_t thetime; char *p; - if (!zstr(cmd) && (p = strchr(cmd, '|'))) { - thetime = switch_time_make(atoi(cmd), 0); + char *mycmd = NULL; + + if (!zstr(cmd)) { + mycmd = strdup(cmd); + } + + if (!zstr(mycmd) && (p = strchr(cmd, '|'))) { + *p++ = '\0'; + + thetime = switch_time_make(atol(cmd), 0); cmd = p + 1; } else { thetime = switch_micro_time_now(); } switch_time_exp_lt(&tm, thetime); + if (zstr(cmd)) { switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); } else { @@ -3513,6 +3533,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "ivr", "Run an ivr menu", "Run an ivr menu.", ivr_application_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "redirect", "Send session redirect", "Send a redirect message to a session.", redirect_function, "", SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "jitterbuffer", "Send session jitterbuffer", "Send a jitterbuffer message to a session.", + jitterbuffer_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "send_display", "Send session a new display", "Send session a new display.", display_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "respond", "Send session respond", "Send a respond message to a session.", respond_function, "", diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 74c4c0897e..0e64d54a0a 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -906,7 +906,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f tech_pvt->read_frame.flags = SFF_NONE; status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags); - + if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { if (status == SWITCH_STATUS_TIMEOUT) { @@ -1332,6 +1332,49 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } } break; + case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER: + { + if (switch_rtp_ready(tech_pvt->rtp_session)) { + int len, maxlen = 0, qlen = 0, maxqlen = 50; + + if (msg->string_arg) { + char *p; + + if ((len = atoi(msg->string_arg))) { + qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000); + } + + if (qlen) { + if ((p = strchr(msg->string_arg, ':'))) { + p++; + maxlen = atol(p); + } + } + + + if (maxlen) { + maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000); + } + } + + if (qlen) { + if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen, + tech_pvt->read_impl.samples_per_packet, + tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", len, qlen, maxqlen); + switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + } + + } else { + switch_rtp_deactivate_jitter_buffer(tech_pvt->rtp_session); + } + } + } + break; case SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO: { if (switch_rtp_ready(tech_pvt->rtp_session) && !zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 6416778ab0..74f5d3d764 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3153,18 +3153,37 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) { int len = atoi(val); + int maxlen = 50; + char *p; - if (len < 100 || len > 1000) { + if ((p = strchr(val, ':'))) { + p++; + maxlen = atoi(val); + } + + if (len < 20 || len > 10000) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, - "Invalid Jitterbuffer spec [%d] must be between 100 and 1000\n", len); + "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len); } else { - int qlen; - + int qlen, maxqlen = 0; + qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, - qlen); - switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen); + if (maxlen) { + maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000); + } + + if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen, + tech_pvt->read_impl.samples_per_packet, + tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + } + } } diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 6f3e65a9f4..a2df79d1bc 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -235,7 +235,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi if (switch_test_flag(*frame, SFF_CNG)) { status = SWITCH_STATUS_SUCCESS; - if (!session->bugs) { + if (!session->bugs && !session->plc) { goto done; } is_cng = 1; @@ -303,7 +303,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->raw_read_frame.datalen = session->raw_read_frame.buflen; if (is_cng) { - memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); + if (session->plc) { + plc_fillin(session->plc, session->raw_read_frame.data, read_frame->codec->implementation->decoded_bytes_per_packet / 2); + is_cng = 0; + flag &= !SFF_CNG; + } else { + memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->decoded_bytes_per_packet); + } session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); read_frame = &session->raw_read_frame; @@ -326,6 +332,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->read_impl.actual_samples_per_second, session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &read_frame->flags); + + if (status == SWITCH_STATUS_SUCCESS) { + if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && !session->plc) { + session->plc = plc_init(NULL); + } + + if (session->plc) { + if (switch_test_flag(read_frame, SFF_PLC)) { + plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); + switch_clear_flag(read_frame, SFF_PLC); + } else { + plc_rx(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2); + } + } + } + + } if (do_resample && ((status == SWITCH_STATUS_SUCCESS) || is_cng)) { @@ -361,6 +384,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; + session->raw_read_frame.flags = 0; + if (switch_test_flag(read_frame, SFF_PLC)) { + session->raw_read_frame.flags |= SFF_PLC; + } read_frame = &session->raw_read_frame; break; case SWITCH_STATUS_NOOP: @@ -383,6 +410,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->raw_read_frame.seq = read_frame->seq; session->raw_read_frame.m = read_frame->m; session->raw_read_frame.payload = read_frame->payload; + session->raw_read_frame.flags = 0; + if (switch_test_flag(read_frame, SFF_PLC)) { + session->raw_read_frame.flags |= SFF_PLC; + } + read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; break; @@ -462,7 +494,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi read_frame->datalen = session->read_resampler->to_len * 2; read_frame->rate = session->read_resampler->to_rate; switch_mutex_unlock(session->resample_mutex); - } if (read_frame->datalen == session->read_impl.decoded_bytes_per_packet) { @@ -481,7 +512,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi } } - if (perfect || switch_buffer_inuse(session->raw_read_buffer) >= session->read_impl.decoded_bytes_per_packet) { if (perfect) { enc_frame = read_frame; @@ -810,6 +840,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess session->raw_write_frame.ssrc = frame->ssrc; session->raw_write_frame.seq = frame->seq; session->raw_write_frame.payload = frame->payload; + session->raw_write_frame.flags = 0; + if (switch_test_flag(frame, SFF_PLC)) { + session->raw_write_frame.flags |= SFF_PLC; + } + write_frame = &session->raw_write_frame; break; case SWITCH_STATUS_BREAK: diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 46ba4e6659..6e2aeaf637 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2290,7 +2290,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 qlen = delay_ms / (interval); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen); - jb = stfu_n_init(qlen, 0); + jb = stfu_n_init(qlen, qlen, read_impl.samples_per_packet, read_impl.samples_per_second); write_frame.codec = switch_core_session_get_read_codec(session); @@ -2300,7 +2300,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, 0, read_frame->payload, read_frame->data, read_frame->datalen); ts += interval; if ((jb_frame = stfu_n_read_a_frame(jb))) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index ee1c4acf5e..aba14b2d0a 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1618,12 +1618,65 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_ return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames) +static void jb_callback(stfu_instance_t *i, void *udata) +{ + switch_core_session_t *session = (switch_core_session_t *) udata; + stfu_report_t r = { 0 }; + + stfu_n_report(i, &r); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, + "%s JB REPORT:\nlen: %u\nin: %u\nclean: %u\ngood: %u\nbad: %u\n", + switch_core_session_get_name(session), + r.qlen, + r.packet_in_count, + r.clean_count, + r.consecutive_good_count, + r.consecutive_bad_count + ); + +} + +SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session) +{ + + if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) { + return SWITCH_STATUS_FALSE; + } + + READ_INC(rtp_session); + stfu_n_destroy(&rtp_session->jb); + READ_DEC(rtp_session); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, + uint32_t queue_frames, + uint32_t max_queue_frames, + uint32_t samples_per_packet, + uint32_t samples_per_second) { - rtp_session->jb = stfu_n_init(queue_frames, 0); + if (!switch_rtp_ready(rtp_session)) { + return SWITCH_STATUS_FALSE; + } - return SWITCH_STATUS_SUCCESS; + READ_INC(rtp_session); + if (rtp_session->jb) { + stfu_n_resize(rtp_session->jb, queue_frames); + } else { + rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames || 50, samples_per_packet, samples_per_second); + } + READ_DEC(rtp_session); + + if (rtp_session->jb) { + switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); + stfu_n_call_me(rtp_session->jb, jb_callback, session); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; } SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port) @@ -2016,14 +2069,18 @@ static void do_flush(switch_rtp_t *rtp_session) switch_size_t bytes; switch_status_t status; - if (!switch_rtp_ready(rtp_session) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) { + if (!switch_rtp_ready(rtp_session) || + switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || + switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) + ) { return; } READ_INC(rtp_session); if (switch_rtp_ready(rtp_session)) { - + uint32_t flushed = 0; + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_DEBUG_RTP_READ)) { switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); if (!session) { @@ -2047,6 +2104,16 @@ static void do_flush(switch_rtp_t *rtp_session) bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes); if (bytes) { + + flushed++; + + if (rtp_session->jb) { + stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), + ntohs((uint16_t) rtp_session->recv_msg.header.seq), + rtp_session->recv_msg.header.pt, + rtp_session->recv_msg.body, bytes - rtp_header_len); + } + rtp_session->stats.inbound.raw_bytes += bytes; rtp_session->stats.inbound.flush_packet_count++; rtp_session->stats.inbound.packet_count++; @@ -2056,6 +2123,10 @@ static void do_flush(switch_rtp_t *rtp_session) } } while (bytes > 0); + if (rtp_session->jb && flushed) { + stfu_n_sync(rtp_session->jb, flushed); + } + if (was_blocking && switch_rtp_ready(rtp_session)) { switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK); switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE); @@ -2104,7 +2175,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t stfu_n_reset(rtp_session->jb); } - stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), rtp_session->recv_msg.header.pt, + stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), + ntohs((uint16_t) rtp_session->recv_msg.header.seq), + rtp_session->recv_msg.header.pt, rtp_session->recv_msg.body, *bytes - rtp_header_len); *bytes = 0; status = SWITCH_STATUS_FALSE; @@ -2114,14 +2187,14 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t 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; + (*flags) |= SFF_PLC; } else { rtp_session->stats.inbound.jb_packet_count++; } *bytes = jb_frame->dlen + rtp_header_len; rtp_session->recv_msg.header.ts = htonl(jb_frame->ts); rtp_session->recv_msg.header.pt = jb_frame->pt; - + rtp_session->recv_msg.header.seq = htons((uint16_t)jb_frame->seq); status = SWITCH_STATUS_SUCCESS; } } @@ -2824,7 +2897,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ 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; @@ -3053,6 +3126,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp frame->packet = &rtp_session->recv_msg; frame->packetlen = bytes; frame->source = __FILE__; + switch_set_flag(frame, SFF_RAW_RTP); if (frame->payload == rtp_session->recv_te) { switch_set_flag(frame, SFF_RFC2833); From c312454f0c3045ac34a1c0eeab0506b2230daafb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Dec 2010 17:48:19 -0600 Subject: [PATCH 015/244] dramatic jitterbuffer changes --- libs/stfu/stfu.c | 467 ++++++++++++++++++++++++++++++++++++++--------- libs/stfu/stfu.h | 20 +- 2 files changed, 394 insertions(+), 93 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 0422cd2081..66b165ba3f 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -27,6 +27,7 @@ */ #include "stfu.h" +//#define DB_JB 1 #ifdef _MSC_VER /* warning C4706: assignment within conditional expression*/ #pragma warning(disable: 4706) @@ -35,9 +36,12 @@ struct stfu_queue { struct stfu_frame *array; struct stfu_frame int_frame; + uint32_t real_array_size; uint32_t array_size; uint32_t array_len; uint32_t wr_len; + uint32_t last_index; + int32_t last_jitter; }; typedef struct stfu_queue stfu_queue_t; @@ -48,27 +52,72 @@ struct stfu_instance { struct stfu_queue *out_queue; struct stfu_frame *last_frame; uint32_t cur_ts; + uint32_t cur_seq; uint32_t last_wr_ts; + uint32_t last_wr_seq; uint32_t last_rd_ts; - uint32_t interval; + uint32_t samples_per_packet; + uint32_t samples_per_second; uint32_t miss_count; uint32_t max_plc; + uint32_t qlen; + uint32_t max_qlen; + uint32_t orig_qlen; + uint32_t packet_count; + uint32_t consecutive_good_count; + uint32_t consecutive_bad_count; + uint32_t period_good_count; + uint32_t period_bad_count; + uint32_t period_packet_in_count; + uint32_t period_packet_out_count; + uint32_t period_missing_count; + uint32_t period_need_range; + uint32_t period_need_range_avg; + uint32_t period_clean_count; + + uint32_t session_clean_count; + uint32_t session_missing_count; + + uint32_t session_packet_in_count; + uint32_t session_packet_out_count; + + uint32_t sync; + + + int32_t ts_diff; + int32_t last_ts_diff; + int32_t same_ts; + + uint32_t last_seq; + + uint32_t period_time; + uint32_t decrement_time; + + uint32_t plc_len; + + stfu_n_call_me_t callback; + void *udata; }; +static void stfu_n_reset_counters(stfu_instance_t *i); static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen) { unsigned char *m; - if (qlen <= queue->array_size) { - return STFU_IT_FAILED;; + if (qlen <= queue->real_array_size) { + queue->array_size = qlen; + if (queue->array_len > qlen) { + queue->array_len = qlen; + } + } else { + m = realloc(queue->array, qlen * sizeof(struct stfu_frame)); + assert(m); + memset(m + queue->array_size * sizeof(struct stfu_frame), 0, (qlen * sizeof(struct stfu_frame)) - (queue->array_size * sizeof(struct stfu_frame))); + queue->array = (struct stfu_frame *) m; + queue->real_array_size = queue->array_size = qlen; } - m = realloc(queue->array, qlen * sizeof(struct stfu_frame)); - assert(m); - memset(m + queue->array_size, 0, qlen * sizeof(struct stfu_frame) - queue->array_size); - queue->array = (struct stfu_frame *) m; - queue->array_size = qlen; return STFU_IT_WORKED; } @@ -77,8 +126,16 @@ static void stfu_n_init_aqueue(stfu_queue_t *queue, uint32_t qlen) queue->array = calloc(qlen, sizeof(struct stfu_frame)); assert(queue->array != NULL); memset(queue->array, 0, sizeof(struct stfu_frame) * qlen); - queue->array_size = qlen; + queue->real_array_size = queue->array_size = qlen; queue->int_frame.plc = 1; + memset(queue->int_frame.data, 255, sizeof(queue->int_frame.data)); +} + + +void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata) +{ + i->callback = callback; + i->udata = udata; } void stfu_n_destroy(stfu_instance_t **i) @@ -97,24 +154,40 @@ void stfu_n_destroy(stfu_instance_t **i) void stfu_n_report(stfu_instance_t *i, stfu_report_t *r) { assert(i); - r->in_len = i->in_queue->array_len; - r->in_size = i->in_queue->array_size; - r->out_len = i->out_queue->array_len; - r->out_size = i->out_queue->array_size; + r->qlen = i->qlen; + r->packet_in_count = i->period_packet_in_count; + r->clean_count = i->period_clean_count; + r->consecutive_good_count = i->consecutive_good_count; + r->consecutive_bad_count = i->consecutive_bad_count; } stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) { stfu_status_t s; + if (i->qlen == i->max_qlen) { + return STFU_IT_FAILED; + } + + if (i->max_qlen && qlen > i->max_qlen) { + if (i->qlen < i->max_qlen) { + qlen = i->max_qlen; + } else { + return STFU_IT_FAILED; + } + } + if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) { s = stfu_n_resize_aqueue(&i->b_queue, qlen); + i->qlen = qlen; + i->max_plc = 5; + i->last_frame = NULL; } return s; } -stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc) +stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second) { struct stfu_instance *i; @@ -123,82 +196,172 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc) return NULL; } memset(i, 0, sizeof(*i)); + i->qlen = qlen; + i->max_qlen = max_qlen; + i->orig_qlen = qlen; + i->samples_per_packet = samples_per_packet; + stfu_n_init_aqueue(&i->a_queue, qlen); stfu_n_init_aqueue(&i->b_queue, qlen); i->in_queue = &i->a_queue; i->out_queue = &i->b_queue; + + i->max_plc = i->qlen / 2; - if (max_plc) { - i->max_plc = max_plc; - } else { - i->max_plc = qlen / 2; - } + i->samples_per_second = samples_per_second ? samples_per_second : 8000; + + i->period_time = ((i->samples_per_second * 20) / i->samples_per_packet); + i->decrement_time = ((i->samples_per_second * 15) / i->samples_per_packet); return i; } +static void stfu_n_reset_counters(stfu_instance_t *i) +{ +#ifdef DB_JB + printf("COUNER RESET........\n"); +#endif + + if (i->callback) { + i->callback(i, i->udata); + } + + i->consecutive_good_count = 0; + i->consecutive_bad_count = 0; + i->period_good_count = 0; + i->period_clean_count = 0; + i->period_bad_count = 0; + i->period_packet_in_count = 0; + i->period_packet_out_count = 0; + i->period_missing_count = 0; + i->period_need_range = 0; + i->period_need_range_avg = 0; +} + void stfu_n_reset(stfu_instance_t *i) { +#ifdef DB_JB + printf("RESET\n"); +#endif i->in_queue = &i->a_queue; i->out_queue = &i->b_queue; i->in_queue->array_len = 0; i->out_queue->array_len = 0; i->out_queue->wr_len = 0; i->last_frame = NULL; - i->miss_count = 0; + + i->in_queue->last_jitter = 0; + i->out_queue->last_jitter = 0; + + stfu_n_reset_counters(i); + + i->last_seq = 0; + + i->cur_ts = 0; + i->cur_seq = 0; i->last_wr_ts = 0; - i->miss_count = 0; - i->interval = 0; + i->last_wr_seq = 0; + i->last_rd_ts = 0; + i->miss_count = 0; + i->packet_count = 0; } -static int32_t stfu_n_measure_interval(stfu_queue_t *queue) +stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets) { - uint32_t index; - int32_t d, most = 0, last = 0, this, track[STFU_MAX_TRACK] = {0}; - for(index = 0; index < queue->array_len; index++) { - this = queue->array[index].ts; - if (last) { + if (packets > i->qlen) { + stfu_n_reset(i); + } else { + i->sync = packets; + } - if ((d = this - last) > 0 && d / 10 < STFU_MAX_TRACK) { - track[(d/10)]++; - } - } - - last = this; - } - - for(index = 0; index < STFU_MAX_TRACK; index++) { - if (track[index] > track[most]) { - most = index; - } - } - - return most * 10; + return STFU_IT_WORKED; } -static int16_t stfu_n_process(stfu_instance_t *i, stfu_queue_t *queue) -{ - if (!i->interval && !(i->interval = stfu_n_measure_interval(queue))) { - return -1; - } - return 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 seq, uint32_t pt, void *data, size_t datalen, int last) { uint32_t index; stfu_frame_t *frame; size_t cplen = 0; + int good_seq = 0, good_ts = 0; + + if (!i->samples_per_packet && ts && i->last_rd_ts) { + i->ts_diff = ts - i->last_rd_ts; + + if (i->last_ts_diff == i->ts_diff) { + if (++i->same_ts == 5) { + i->samples_per_packet = i->ts_diff; + } + } else { + i->same_ts = 0; + } + + i->last_ts_diff = i->ts_diff; + + if (!i->samples_per_packet) { + i->last_rd_ts = ts; + return STFU_IT_FAILED; + } + } + + if (seq && seq == i->last_seq + 1) { + good_seq = 1; + } + + if (ts && ts == i->last_rd_ts + i->samples_per_packet) { + good_ts = 1; + } + + + if (good_seq || good_ts) { + i->period_clean_count++; + i->session_clean_count++; + } + + i->period_packet_in_count++; + i->session_packet_in_count++; + + if (i->session_packet_in_count == 150) { + return STFU_IT_WORKED; + } + + i->period_need_range_avg = i->period_need_range / (i->period_missing_count || 1); + + if (i->period_missing_count > i->qlen * 2) { + stfu_n_resize(i, i->qlen + 1); + stfu_n_reset_counters(i); + } + + if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) { + stfu_n_resize(i, i->qlen - 1); + stfu_n_reset_counters(i); + stfu_n_sync(i, i->qlen); + } + + if ((i->period_packet_in_count > i->period_time)) { + i->period_packet_in_count = 0; + + if (i->period_missing_count == 0 && i->qlen > i->orig_qlen) { + stfu_n_resize(i, i->qlen - 1); + stfu_n_sync(i, i->qlen); + } + + stfu_n_reset_counters(i); + } + +#ifdef DB_JB + printf("%u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u/%u - %u %d\n", + 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, + seq, ts, + i->period_missing_count, i->period_need_range_avg); +#endif + if (last || i->in_queue->array_len == i->in_queue->array_size) { stfu_queue_t *other_queue; - if (i->out_queue->wr_len < i->out_queue->array_len) { - return STFU_IT_FAILED; - } - other_queue = i->in_queue; i->in_queue = i->out_queue; i->out_queue = other_queue; @@ -207,57 +370,92 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void i->out_queue->wr_len = 0; i->last_frame = NULL; i->miss_count = 0; - - if (stfu_n_process(i, i->out_queue) < 0) { - if (i->in_queue->array_len == i->in_queue->array_size && i->out_queue->array_len == i->out_queue->array_size) { - stfu_n_resize(i, i->out_queue->array_size * 2); - } - //return STFU_IT_FAILED; - } - for(index = 0; index < i->out_queue->array_len; index++) { - i->out_queue->array[index].was_read = 0; - } - } + i->in_queue->last_index = 0; + i->out_queue->last_index = 0; + i->out_queue->last_jitter = 0; + } if (last) { return STFU_IM_DONE; } - index = i->in_queue->array_len++; + for(index = 0; index < i->out_queue->array_size; index++) { + if (i->in_queue->array[index].was_read) { + break; + } + } + + index = i->in_queue->array_len++; + frame = &i->in_queue->array[index]; if ((cplen = datalen) > sizeof(frame->data)) { cplen = sizeof(frame->data); } + i->last_seq = seq; i->last_rd_ts = ts; + i->packet_count++; memcpy(frame->data, data, cplen); + frame->pt = pt; frame->ts = ts; + frame->seq = seq; frame->dlen = cplen; frame->was_read = 0; return STFU_IT_WORKED; } -static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame, uint32_t *index) +static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_frame_t **r_frame) +{ + uint32_t i = 0; + stfu_frame_t *frame = NULL; + stfu_queue_t *queue; + + assert(r_frame); + + *r_frame = NULL; + + for (queue = in->out_queue ; queue && queue != in->in_queue ; queue = in->in_queue) { + + for(i = 0; i < queue->real_array_size; i++) { + frame = &queue->array[i]; + if (!frame->was_read) { + *r_frame = frame; + queue->last_index = i; + frame->was_read = 1; + in->period_packet_out_count++; + in->session_packet_out_count++; + return 1; + } + } + + } + + return 0; +} + + +static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, uint32_t seq, stfu_frame_t **r_frame) { uint32_t i = 0; stfu_frame_t *frame = NULL; assert(r_frame); - assert(index); *r_frame = NULL; - for(i = 0; i < queue->array_len; i++) { + for(i = 0; i < queue->real_array_size; i++) { frame = &queue->array[i]; - if (frame->ts == ts) { + if ((seq && frame->seq == seq) || frame->ts == ts) { *r_frame = frame; - *index = i; + queue->last_index = i; frame->was_read = 1; + in->period_packet_out_count++; + in->session_packet_out_count++; return 1; } } @@ -267,40 +465,139 @@ static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) { - uint32_t index; stfu_frame_t *rframe = NULL; - - if (((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) { + int found = 0; + + if (!i->samples_per_packet || ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) { return NULL; } if (i->cur_ts == 0) { i->cur_ts = i->out_queue->array[0].ts; } else { - i->cur_ts += i->interval; + i->cur_ts += i->samples_per_packet; } + if (i->cur_seq == 0) { + i->cur_seq = i->out_queue->array[0].seq; + } else { + i->cur_seq++; + } - if (stfu_n_find_frame(i->out_queue, i->cur_ts, &rframe, &index) || stfu_n_find_frame(i->in_queue, i->cur_ts, &rframe, &index)) { + if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) { + found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, i->cur_seq, &rframe); + } + + if (!found && i->sync) { +#ifdef DB_JB + printf("SYNC %u\n", i->sync); +#endif + if ((found = stfu_n_find_any_frame(i, &rframe))) { + i->cur_seq = rframe->seq; + i->cur_ts = rframe->ts; + } + i->sync--; + } + + + if (!found && i->samples_per_packet) { +#ifdef DB_JB + int y; + stfu_frame_t *frame = NULL; +#endif + int32_t delay = i->last_rd_ts - i->cur_ts; + int32_t need = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet; + + + i->period_missing_count++; + i->session_missing_count++; + i->period_need_range += need; + +#ifdef DB_JB + printf("MISSING %u %u %u %u %d %u %d\n", i->cur_seq, i->cur_ts, i->packet_count, i->last_rd_ts, delay, i->qlen, need); +#endif + + if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) { + i->packet_count = 0; + } + +#ifdef DB_JB + for(y = 0; y < i->out_queue->array_size; y++) { + if ((y % 5) == 0) printf("\n"); + frame = &i->out_queue->array[y]; + printf("%u:%u\t", frame->seq, frame->ts); + } + printf("\n\n"); + + + for(y = 0; y < i->in_queue->array_size; y++) { + if ((y % 5) == 0) printf("\n"); + frame = &i->in_queue->array[y]; + printf("%u:%u\t", frame->seq, frame->ts); + } + printf("\n\n"); +#endif + + if (delay < 0) { + stfu_n_reset(i); + return NULL; + } + } + +#ifdef DB_JB + if (found) { + printf("O: %u:%u %u\n", rframe->seq, rframe->seq, rframe->plc); + assert(found && rframe->seq); + } else { + printf("DATA: %u %u %d %s %d\n", i->packet_count, i->consecutive_good_count, i->out_queue->last_jitter, found ? "found" : "not found", i->qlen); + } +#endif + + + if (found) { + i->consecutive_good_count++; + i->period_good_count++; + i->consecutive_bad_count = 0; + } else { + i->consecutive_bad_count++; + i->period_bad_count++; + i->consecutive_good_count = 0; + } + + if (found) { i->last_frame = rframe; i->out_queue->wr_len++; i->last_wr_ts = rframe->ts; + i->last_wr_seq = rframe->seq; i->miss_count = 0; + if (rframe->dlen) { + i->plc_len = rframe->dlen; + } } else { i->last_wr_ts = i->cur_ts; + i->last_wr_seq = i->cur_seq; rframe = &i->out_queue->int_frame; - - if (i->last_frame && i->last_frame != rframe) { - rframe->dlen = i->last_frame->dlen; + rframe->dlen = i->plc_len; + + if (i->last_frame) { /* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */ - memcpy(rframe->data, i->last_frame->data, rframe->dlen); + if (i->miss_count) { + memset(rframe->data, 255, rframe->dlen); + } else { + memcpy(rframe->data, i->last_frame->data, rframe->dlen); + } } rframe->ts = i->cur_ts; - if (++i->miss_count > i->max_plc) { - i->out_queue->wr_len = i->out_queue->array_size; - i->cur_ts = 0; + i->miss_count++; + +#ifdef DB_JB + printf("PLC %d %d %ld %u %u\n", i->miss_count, rframe->plc, rframe->dlen, rframe->seq, rframe->ts); +#endif + + if (i->miss_count > i->max_plc) { + stfu_n_reset(i); rframe = NULL; } } diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index 900db6f9ac..d2760b27bc 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -75,6 +75,7 @@ typedef enum { struct stfu_frame { uint32_t ts; uint32_t pt; + uint32_t seq; uint8_t data[STFU_DATALEN]; size_t dlen; uint8_t was_read; @@ -86,24 +87,27 @@ struct stfu_instance; typedef struct stfu_instance stfu_instance_t; typedef struct { - uint32_t in_len; - uint32_t in_size; - uint32_t out_len; - uint32_t out_size; - + uint32_t qlen; + uint32_t packet_in_count; + uint32_t clean_count; + uint32_t consecutive_good_count; + uint32_t consecutive_bad_count; } stfu_report_t; +typedef void (*stfu_n_call_me_t)(stfu_instance_t *i, void *); 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_plc); +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 seq, uint32_t pt, void *data, size_t datalen, 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); #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_n_eat(i,t,s,p,d,l) stfu_n_add_data(i, t, s, p, d, l, 0) #ifdef __cplusplus } From b7c80a8490e00ef1c76dc9eeb8627f92ffb18d48 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Dec 2010 17:48:40 -0600 Subject: [PATCH 016/244] add plc to core --- Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index e701494a2e..72ad3f718c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -102,6 +102,7 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/pcre CORE_CFLAGS += -I$(switch_srcdir)/libs/speex/include -Ilibs/speex/include CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include -Ilibs/srtp/crypto/include +CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src CORE_LIBS = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la @@ -249,7 +250,8 @@ libfreeswitch_la_SOURCES = \ libs/miniupnpc/minissdpc.c \ libs/miniupnpc/upnperrors.c \ libs/libnatpmp/natpmp.c \ - libs/libnatpmp/getgateway.c + libs/libnatpmp/getgateway.c\ + libs/spandsp/src/plc.c if ENABLE_CPP libfreeswitch_la_SOURCES += src/switch_cpp.cpp From 19d1385714600212c47f06e8f4f0c7fa06e18c29 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Dec 2010 17:58:24 -0600 Subject: [PATCH 017/244] temp tiff hack (make spandsp-reconf) --- libs/spandsp/src/spandsp.h.in | 3 ++- src/include/private/switch_core_pvt.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/spandsp/src/spandsp.h.in b/libs/spandsp/src/spandsp.h.in index 9167c1c2cc..eaed548c97 100644 --- a/libs/spandsp/src/spandsp.h.in +++ b/libs/spandsp/src/spandsp.h.in @@ -39,8 +39,9 @@ #include #include @INSERT_MATH_HEADER@ +#if !defined(SPANDSP_NO_TIFF) #include - +#endif #include #include #include diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index a565299fae..422d5f2930 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -31,6 +31,7 @@ * this file does not exist!!!! * */ +#define SPANDSP_NO_TIFF 1 #include "spandsp.h" #include "switch_profile.h" From 55203ed0d72d28df807ea9f8d326e00cd77f5ee4 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Fri, 10 Dec 2010 19:14:08 -0500 Subject: [PATCH 018/244] Support for call ID --- libs/freetdm/src/ftdm_io.c | 75 ++++++++++++++++++++++++++---- libs/freetdm/src/include/freetdm.h | 8 +++- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index eaa25e3da5..78ae3d2b65 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -57,11 +57,14 @@ struct tm *localtime_r(const time_t *clock, struct tm *result); #define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 #define FTDM_READ_TRACE_INDEX 0 #define FTDM_WRITE_TRACE_INDEX 1 +#define MAX_CALLIDS 6000 ftdm_time_t time_last_throttle_log = 0; ftdm_time_t time_current_throttle_log = 0; static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter); +static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data); +static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data); static int time_is_init = 0; @@ -235,6 +238,10 @@ static struct { ftdm_span_t *spans; ftdm_group_t *groups; cpu_monitor_t cpu_monitor; + + ftdm_caller_data_t *call_ids[MAX_CALLIDS+1]; + ftdm_mutex_t *call_id_mutex; + uint32_t last_call_id; } globals; enum ftdm_enum_cpu_alarm_action_flags @@ -1896,8 +1903,6 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan) ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF; } - ftdm_call_clear_vars(&ftdmchan->caller_data); - memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len); if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) { @@ -2483,6 +2488,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100); + ftdm_call_set_call_id(&ftdmchan->caller_data); ftdm_channel_unlock(ftdmchan); return status; @@ -2545,9 +2551,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n"); ftdm_mutex_lock(ftdmchan->mutex); - - memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK); @@ -2587,7 +2590,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) sigmsg.channel = ftdmchan; sigmsg.event_id = FTDM_SIGEVENT_RELEASED; ftdm_span_send_signal(ftdmchan->span, &sigmsg); - } + ftdm_call_clear_call_id(&ftdmchan->caller_data); + } if (ftdmchan->txdrops || ftdmchan->rxdrops) { ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", @@ -2595,8 +2599,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) } ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); - - + memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); ftdm_mutex_unlock(ftdmchan->mutex); return FTDM_SUCCESS; @@ -5328,7 +5331,7 @@ static void execute_safety_hangup(void *data) FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { if (sigmsg->channel) { - ftdm_mutex_lock(sigmsg->channel->mutex); + ftdm_mutex_lock(sigmsg->channel->mutex); } /* some core things to do on special events */ @@ -5347,6 +5350,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t case FTDM_SIGEVENT_START: { + ftdm_call_set_call_id(&sigmsg->channel->caller_data); ftdm_set_echocancel_call_begin(sigmsg->channel); if (sigmsg->channel->dtmfdbg.requested) { ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL); @@ -5376,7 +5380,10 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t break; } - + + if (sigmsg->channel) { + sigmsg->call_id = sigmsg->channel->caller_data.call_id; + } /* if the signaling module uses a queue for signaling notifications, then enqueue it */ if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) { ftdm_span_queue_signal(span, sigmsg); @@ -5471,6 +5478,7 @@ static void ftdm_cpu_monitor_stop(void) FT_DECLARE(ftdm_status_t) ftdm_global_init(void) { + int i; memset(&globals, 0, sizeof(globals)); time_init(); @@ -5485,6 +5493,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void) ftdm_mutex_create(&globals.mutex); ftdm_mutex_create(&globals.span_mutex); ftdm_mutex_create(&globals.group_mutex); + ftdm_mutex_create(&globals.call_id_mutex); + ftdm_sched_global_init(); if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n"); @@ -5494,6 +5504,9 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void) ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n"); return FTDM_FAIL; } + for(i=0;icall_id, FTDM_FAIL, "Overwriting non-cleared call-id"); + + ftdm_mutex_lock(globals.call_id_mutex); + current_call_id = globals.last_call_id; + + do { + if (++current_call_id > MAX_CALLIDS) { + current_call_id = 1; + } + if (globals.call_ids[current_call_id] != NULL) { + continue; + } + } while (0); + + globals.last_call_id = current_call_id; + caller_data->call_id = current_call_id; + + globals.call_ids[current_call_id] = caller_data; + ftdm_mutex_unlock(globals.call_id_mutex); + return FTDM_SUCCESS; +} + +static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data) +{ + ftdm_assert_return((caller_data->call_id && caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Clearing call with invalid call-id\n"); + ftdm_mutex_lock(globals.call_id_mutex); + if (globals.call_ids[caller_data->call_id]) { + caller_data->call_id = 0; + globals.call_ids[caller_data->call_id] = NULL; + } else { + ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id); + } + ftdm_mutex_unlock(globals.call_id_mutex); + return FTDM_SUCCESS; +} + + + /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 4ee6ff5f52..cc32d66bdd 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -295,6 +295,11 @@ typedef struct ftdm_caller_data { /* user information layer 1 protocol */ ftdm_user_layer1_prot_t bearer_layer1; ftdm_variable_container_t variables; /*! Date: Fri, 10 Dec 2010 21:43:03 -0600 Subject: [PATCH 019/244] fix build on windows for last commit --- Freeswitch.2008.sln | 1 + libs/stfu/stfu.c | 2 +- .../mod_managed/freeswitch_wrap.2010.cxx | 22 +++++++++++++++++-- .../mod_managed/managed/swig.2010.cs | 16 +++++++++++--- w32/Console/FreeSwitchConsole.2008.vcproj | 8 +++---- w32/Console/FreeSwitchConsole.2010.vcxproj | 8 +++---- w32/Library/FreeSwitchCore.2008.vcproj | 8 +++---- w32/Library/FreeSwitchCore.2010.vcxproj | 11 ++++++---- 8 files changed, 54 insertions(+), 22 deletions(-) diff --git a/Freeswitch.2008.sln b/Freeswitch.2008.sln index 01a4cf43c1..e171ffe418 100644 --- a/Freeswitch.2008.sln +++ b/Freeswitch.2008.sln @@ -381,6 +381,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Li ProjectSection(ProjectDependencies) = postProject {8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9} {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C} + {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3} {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 66b165ba3f..6015207452 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -506,7 +506,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) stfu_frame_t *frame = NULL; #endif int32_t delay = i->last_rd_ts - i->cur_ts; - int32_t need = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet; + uint32_t need = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet; i->period_missing_count++; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 8033a8faa5..1ad1b16b9a 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -28290,15 +28290,33 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_rtcp(void * jarg1, int jar } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5) { int jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; uint32_t arg2 ; + uint32_t arg3 ; + uint32_t arg4 ; + uint32_t arg5 ; switch_status_t result; arg1 = (switch_rtp_t *)jarg1; arg2 = (uint32_t)jarg2; - result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2); + arg3 = (uint32_t)jarg3; + arg4 = (uint32_t)jarg4; + arg5 = (uint32_t)jarg5; + result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2,arg3,arg4,arg5); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jarg1) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + result = (switch_status_t)switch_rtp_deactivate_jitter_buffer(arg1); jresult = result; return jresult; } diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 4d14f10879..4b9ce71e60 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -4640,8 +4640,13 @@ public class freeswitch { return ret; } - public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames); + public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames, uint max_queue_frames, uint samples_per_packet, uint samples_per_second) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames, max_queue_frames, samples_per_packet, samples_per_second); + return ret; + } + + public static switch_status_t switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); return ret; } @@ -12448,7 +12453,10 @@ class freeswitchPINVOKE { public static extern int switch_rtp_activate_rtcp(HandleRef jarg1, int jarg2, ushort jarg3); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_jitter_buffer")] - public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2); + public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")] + public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")] public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2); @@ -21554,6 +21562,7 @@ public enum switch_channel_flag_t { CF_PASSTHRU_PTIME_MISMATCH, CF_BRIDGE_NOWRITE, CF_RECOVERED, + CF_JITTERBUFFER, CF_FLAG_MAX } @@ -23243,6 +23252,7 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION, SWITCH_MESSAGE_INDICATE_UDPTL_MODE, SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, + SWITCH_MESSAGE_INDICATE_JITTER_BUFFER, SWITCH_MESSAGE_INVALID } diff --git a/w32/Console/FreeSwitchConsole.2008.vcproj b/w32/Console/FreeSwitchConsole.2008.vcproj index 80f062abe0..7fc1784d14 100644 --- a/w32/Console/FreeSwitchConsole.2008.vcproj +++ b/w32/Console/FreeSwitchConsole.2008.vcproj @@ -46,7 +46,7 @@ Disabled - %(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) + %(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true EnableFastChecks @@ -109,7 +109,7 @@ Disabled - %(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) + %(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true EnableFastChecks @@ -134,7 +134,7 @@ - %(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) + %(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDLL @@ -161,7 +161,7 @@ X64 - %(RootDir)%(Directory)include;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) + %(RootDir)%(Directory)include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(RootDir)%(Directory)..\libs\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDLL diff --git a/w32/Library/FreeSwitchCore.2008.vcproj b/w32/Library/FreeSwitchCore.2008.vcproj index ca15da8b52..6ba5b95959 100644 --- a/w32/Library/FreeSwitchCore.2008.vcproj +++ b/w32/Library/FreeSwitchCore.2008.vcproj @@ -47,7 +47,7 @@ Disabled - ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories) + ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;%(PreprocessorDefinitions) true EnableFastChecks @@ -147,7 +147,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs Disabled - ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories) + ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;%(PreprocessorDefinitions) true EnableFastChecks @@ -199,7 +199,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs Disabled - ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories) + ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;%(PreprocessorDefinitions) MultiThreadedDLL Use @@ -248,7 +248,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs Disabled - ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;%(AdditionalIncludeDirectories) + ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\win32\sqlite;..\..\libs\pcre;..\..\libs\stfu;..\..\libs\speex\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-3.8.2\libtiff;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;%(PreprocessorDefinitions) MultiThreadedDLL Use @@ -766,6 +766,9 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs {89385c74-5860-4174-9caf-a39e7c48909c} false + + {1cbb0077-18c5-455f-801c-0a0ce7b0bbf5} + {03207781-0d1c-4db3-a71d-45c608f28dbd} false From 349e9d5913f953ec6a40b24b9ea4866cfd2eef43 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 10 Dec 2010 23:07:15 -0600 Subject: [PATCH 020/244] fix accidental removal --- libs/freetdm/src/testsangomaboost.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index ed2a7bd39d..b254a08bb8 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -53,6 +53,7 @@ #endif #ifndef WIN32 #include +#endif #include "freetdm.h" From ee5d1c4dcf134a78756c74e2c3a91172f48bc240 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 11 Dec 2010 10:41:34 -0600 Subject: [PATCH 021/244] missed a spot --- src/switch_core_session.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 2567d17712..c2766170a8 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1118,6 +1118,11 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * } switch_mutex_unlock(runtime.session_hash_mutex); + if ((*session)->plc) { + plc_free((*session)->plc); + (*session)->plc = NULL; + } + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data((*session)->channel, event); switch_event_fire(&event); From 009c41d460f1356c67240ff5ead72376f532a709 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 11 Dec 2010 11:41:19 -0600 Subject: [PATCH 022/244] add new function to init an empty switch_sockaddr_t to avoid an unnecessary dns lookup on 0.0.0.0 --- src/include/switch_apr.h | 2 ++ src/switch_apr.c | 12 ++++++++++++ src/switch_rtp.c | 5 +++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index dc81d1a522..d89a13bb30 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -1110,6 +1110,8 @@ SWITCH_DECLARE(int) switch_sockaddr_equal(const switch_sockaddr_t *sa1, const sw SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool); + /** * Send data over a network. * @param sock The socket to send the data over. diff --git a/src/switch_apr.c b/src/switch_apr.c index dccc37be96..7c027f8c68 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -729,6 +729,18 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recv(switch_socket_t *sock, char * return apr_socket_recv(sock, buf, len); } +SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool) +{ + switch_sockaddr_t *new_sa; + + new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t)); + switch_assert(new_sa); + new_sa->pool = pool; + memset(new_sa, 0, sizeof(new_sa)); + *sa = new_sa; + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_sockaddr_info_get(switch_sockaddr_t ** sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index aba14b2d0a..772c2508a0 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1367,9 +1367,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session switch_rtp_set_flag(rtp_session, flags); /* for from address on recvfrom calls */ - switch_sockaddr_info_get(&rtp_session->from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool); + switch_sockaddr_create(&rtp_session->from_addr, pool); + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { - switch_sockaddr_info_get(&rtp_session->rtcp_from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool); + switch_sockaddr_create(&rtp_session->rtcp_from_addr, pool); } rtp_session->seq = (uint16_t) rand(); rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL)); From 577d7b5538f3ce2017092cfec54532a10d3382b9 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Sat, 11 Dec 2010 13:19:49 -0600 Subject: [PATCH 023/244] skypopen: added a proof of concept standalone OSS audio driver (for Skype-oss clients) --- src/mod/endpoints/mod_skypopen/oss/Makefile | 43 +++ src/mod/endpoints/mod_skypopen/oss/main.c | 335 ++++++++++++++++++ src/mod/endpoints/mod_skypopen/oss/scull.h | 64 ++++ src/mod/endpoints/mod_skypopen/oss/scull.init | 142 ++++++++ 4 files changed, 584 insertions(+) create mode 100644 src/mod/endpoints/mod_skypopen/oss/Makefile create mode 100644 src/mod/endpoints/mod_skypopen/oss/main.c create mode 100644 src/mod/endpoints/mod_skypopen/oss/scull.h create mode 100644 src/mod/endpoints/mod_skypopen/oss/scull.init diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile new file mode 100644 index 0000000000..91cc61ba1e --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/oss/Makefile @@ -0,0 +1,43 @@ +# Comment/uncomment the following line to disable/enable debugging +#DEBUG = y +LDDINC=/usr/src/linux-headers-2.6.32-26-server/include + +# Add your debugging flag (or not) to CFLAGS +ifeq ($(DEBUG),y) + DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines +else + DEBFLAGS = -O2 -Wall +endif + +EXTRA_CFLAGS += $(DEBFLAGS) +EXTRA_CFLAGS += -I$(LDDINC) + +ifneq ($(KERNELRELEASE),) +# call from kernel build system + +scull-objs := main.o + +obj-m := scull.o + +else + +KERNELDIR ?= /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) + +modules: + $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules + +endif + + + +clean: + rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions + +depend .depend dep: + $(CC) $(EXTRA_CFLAGS) -M *.c > .depend + + +ifeq (.depend,$(wildcard .depend)) +include .depend +endif diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c new file mode 100644 index 0000000000..4d36ac00d5 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -0,0 +1,335 @@ +/* + * main.c -- the bare scull char module + * + * Copyright (C) 2010 Giovanni Maruzzelli + * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet + * Copyright (C) 2001 O'Reilly & Associates + * + * The source code in this file can be freely used, adapted, + * and redistributed in source or binary form, so long as an + * acknowledgment appears in derived source files. The citation + * should list that the code comes from the book "Linux Device + * Drivers" by Alessandro Rubini and Jonathan Corbet, published + * by O'Reilly & Associates. No warranty is attached; + * we cannot take responsibility for errors or fitness for use. + * + */ + +#include +#include +#include + +#include /* printk() */ +#include /* kmalloc() */ +#include /* everything... */ +#include /* error codes */ +#include /* size_t */ +#include +#include /* O_ACCMODE */ +#include +#include + +#include /* cli(), *_flags */ +#include /* copy_*_user */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scull.h" /* local definitions */ + +/* + * Our parameters which can be set at load time. + */ + +int scull_major = SCULL_MAJOR; +int scull_minor = 3; +int scull_nr_devs = SCULL_NR_DEVS; /* number of bare scull devices */ + +module_param(scull_major, int, S_IRUGO); +module_param(scull_minor, int, S_IRUGO); +module_param(scull_nr_devs, int, S_IRUGO); + +MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Heavy modified by: Giovanni Maruzzelli"); +MODULE_LICENSE("Dual BSD/GPL"); + +static struct scull_dev *scull_devices; /* allocated in scull_init_module */ + +#define GIOVA_BLK 3840 +#define GIOVA_SLEEP 40000 + +void my_timer_callback_inq( unsigned long data ) +{ + struct scull_dev *dev = (void *)data; + + wake_up_interruptible(&dev->inq); + mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); + +} + +void my_timer_callback_outq( unsigned long data ) +{ + struct scull_dev *dev = (void *)data; + + wake_up_interruptible(&dev->outq); + mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); +} + +/* The clone-specific data structure includes a key field */ + +struct scull_listitem { + struct scull_dev device; + dev_t key; + struct list_head list; + +}; + +/* The list of devices, and a lock to protect it */ +static LIST_HEAD(scull_c_list); +static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED; + +/* Look for a device or create one if missing */ +static struct scull_dev *scull_c_lookfor_device(dev_t key) +{ + struct scull_listitem *lptr; + + list_for_each_entry(lptr, &scull_c_list, list) { + if (lptr->key == key) + return &(lptr->device); + } + + /* not found */ + lptr = kmalloc(sizeof(struct scull_listitem), GFP_KERNEL); + if (!lptr) + return NULL; + + /* initialize the device */ + memset(lptr, 0, sizeof(struct scull_listitem)); + lptr->key = key; + + init_waitqueue_head(&lptr->device.inq); + init_waitqueue_head(&lptr->device.outq); + printk(" Timer installing\n"); + setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); + setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); + printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP/1000, jiffies ); + mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); + mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); + /* place it in the list */ + list_add(&lptr->list, &scull_c_list); + + return &(lptr->device); +} +static int scull_c_open(struct inode *inode, struct file *filp) +{ + struct scull_dev *dev; + dev_t key; + + if (!current->pid) { + printk("Process \"%s\" has no pid\n", current->comm); + return -EINVAL; + } + key = current->pid; + + /* look for a scullc device in the list */ + spin_lock(&scull_c_lock); + dev = scull_c_lookfor_device(key); + spin_unlock(&scull_c_lock); + + if (!dev) + return -ENOMEM; + + /* then, everything else is copied from the bare scull device */ + filp->private_data = dev; + return 0; /* success */ +} + +static int scull_c_release(struct inode *inode, struct file *filp) +{ + /* + * Nothing to do, because the device is persistent. + * A `real' cloned device should be freed on last close + */ + return 0; +} + + + +/*************************************************************/ +/* + * Open and close + */ + +ssize_t scull_read(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos) +{ + struct scull_dev *dev = filp->private_data; + + DEFINE_WAIT(wait); + prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&dev->inq, &wait); + return count; + +} + +ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos) +{ + struct scull_dev *dev = filp->private_data; + DEFINE_WAIT(wait); + prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&dev->outq, &wait); + + return count; + +} +/* + * The ioctl() implementation + */ + +int scull_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int __user *p = argp; + + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, p); + case SNDCTL_DSP_GETBLKSIZE: + return put_user(GIOVA_BLK, p); + case SNDCTL_DSP_GETFMTS: + return put_user(28731, p); + + default: + return 0; + } + +} + +struct file_operations scull_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = scull_read, + .write = scull_write, + .ioctl = scull_ioctl, + .open = scull_c_open, + .release = scull_c_release, +}; + +/* + * Finally, the module stuff + */ + +/* + * The cleanup function is used to handle initialization failures as well. + * Thefore, it must be careful to work correctly even if some of the items + * have not been initialized + */ + +void scull_cleanup_module(void) +{ + int i; + int ret; + struct scull_listitem *lptr, *next; + dev_t devno = MKDEV(scull_major, scull_minor); + + /* Get rid of our char dev entries */ + if (scull_devices) { + for (i = 0; i < scull_nr_devs; i++) { + cdev_del(&scull_devices[i].cdev); + } + kfree(scull_devices); + } + + + /* And all the cloned devices */ + list_for_each_entry_safe(lptr, next, &scull_c_list, list) { + ret= del_timer( &lptr->device.timer_inq ); + if (ret) printk("The inq timer was still in use...\n"); + ret= del_timer( &lptr->device.timer_outq ); + if (ret) printk("The outq timer was still in use...\n"); + list_del(&lptr->list); + kfree(lptr); + } + printk("Timer uninstalling\n"); + /* cleanup_module is never called if registering failed */ + unregister_chrdev_region(devno, scull_nr_devs); + +} + + +/* + * Set up the char_dev structure for this device. + */ +static void scull_setup_cdev(struct scull_dev *dev, int index) +{ + int err, devno = MKDEV(scull_major, scull_minor + index); + + cdev_init(&dev->cdev, &scull_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &scull_fops; + err = cdev_add (&dev->cdev, devno, 1); + /* Fail gracefully if need be */ + if (err) + printk(KERN_NOTICE "Error %d adding scull%d", err, index); +} + + + +int scull_init_module(void) +{ + int result, i; + dev_t dev = 0; + + /* + * Get a range of minor numbers to work with, asking for a dynamic + * major unless directed otherwise at load time. + */ + if (scull_major) { + dev = MKDEV(scull_major, scull_minor); + result = register_chrdev_region(dev, scull_nr_devs, "dsp"); + } else { + result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, + "dsp"); + scull_major = MAJOR(dev); + } + if (result < 0) { + printk(KERN_WARNING "scull: can't get major %d\n", scull_major); + return result; + } + + /* + * allocate the devices -- we can't have them static, as the number + * can be specified at load time + */ + scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL); + if (!scull_devices) { + result = -ENOMEM; + goto fail; /* Make this more graceful */ + } + memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev)); + + /* Initialize each device. */ + for (i = 0; i < scull_nr_devs; i++) { + scull_setup_cdev(&scull_devices[i], i); + } + + /* At this point call the init function for any friend device */ + dev = MKDEV(scull_major, scull_minor + scull_nr_devs); + return 0; /* succeed */ + +fail: + scull_cleanup_module(); + return result; +} + +module_init(scull_init_module); +module_exit(scull_cleanup_module); diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.h b/src/mod/endpoints/mod_skypopen/oss/scull.h new file mode 100644 index 0000000000..e86281bd94 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/oss/scull.h @@ -0,0 +1,64 @@ +/* + * scull.h -- definitions for the char module + * + * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet + * Copyright (C) 2001 O'Reilly & Associates + * + * The source code in this file can be freely used, adapted, + * and redistributed in source or binary form, so long as an + * acknowledgment appears in derived source files. The citation + * should list that the code comes from the book "Linux Device + * Drivers" by Alessandro Rubini and Jonathan Corbet, published + * by O'Reilly & Associates. No warranty is attached; + * we cannot take responsibility for errors or fitness for use. + * + * $Id: scull.h,v 1.15 2004/11/04 17:51:18 rubini Exp $ + */ + +#ifndef _SCULL_H_ +#define _SCULL_H_ + +#include /* needed for the _IOW etc stuff used later */ + +#ifndef SCULL_MAJOR +#define SCULL_MAJOR 14 /* dynamic major by default */ +#endif + +#ifndef SCULL_NR_DEVS +#define SCULL_NR_DEVS 1 /* scull0 through scull3 */ +#endif + +struct scull_dev { + struct cdev cdev; /* Char device structure */ + wait_queue_head_t inq; /* read and write queues */ + wait_queue_head_t outq; /* read and write queues */ + struct timer_list timer_inq; + struct timer_list timer_outq; + //unsigned long read_howmany; + //unsigned long write_howmany; + //unsigned long read_sleeped_acc; + //unsigned long write_sleeped_acc; + //double read_delay; /* how much delay last time */ + //double write_delay; /* how much delay last time */ +}; + + +/* + * The different configurable parameters + */ +extern int scull_major; /* main.c */ +extern int scull_nr_devs; + + +/* + * Prototypes for shared functions + */ + +ssize_t scull_read(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos); +ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos); +int scull_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +#endif /* _SCULL_H_ */ diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.init b/src/mod/endpoints/mod_skypopen/oss/scull.init new file mode 100644 index 0000000000..e0523ce456 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/oss/scull.init @@ -0,0 +1,142 @@ +#!/bin/bash +# Sample init script for the a driver module + +DEVICE="scull" +SECTION="misc" + +# The list of filenames and minor numbers: $PREFIX is prefixed to all names +PREFIX="scull" +FILES=" 0 0 1 1 2 2 3 3 priv 16 + pipe0 32 pipe1 33 pipe2 34 pipe3 35 + single 48 uid 64 wuid 80" + +INSMOD=/sbin/insmod; # use /sbin/modprobe if you prefer + +function device_specific_post_load () { + true; # fill at will +} +function device_specific_pre_unload () { + true; # fill at will +} + +# Everything below this line should work unchanged for any char device. +# Obviously, however, no options on the command line: either in +# /etc/${DEVICE}.conf or /etc/modules.conf (if modprobe is used) + +# Optional configuration file: format is +# owner +# group +# mode +# options +CFG=/etc/${DEVICE}.conf + +# kernel version, used to look for modules +KERNEL=`uname -r` + +#FIXME: it looks like there is no misc section. Where should it be? +MODDIR="/lib/modules/${KERNEL}/kernel/drivers/${SECTION}" +if [ ! -d $MODDIR ]; then MODDIR="/lib/modules/${KERNEL}/${SECTION}"; fi + +# Root or die +if [ "$(id -u)" != "0" ] +then + echo "You must be root to load or unload kernel modules" + exit 1 +fi + +# Read configuration file +if [ -r $CFG ]; then + OWNER=`awk "\\$1==\"owner\" {print \\$2}" $CFG` + GROUP=`awk "\\$1==\"group\" {print \\$2}" $CFG` + MODE=`awk "\\$1==\"mode\" {print \\$2}" $CFG` + # The options string may include extra blanks or only blanks + OPTIONS=`sed -n '/^options / s/options //p' $CFG` +fi + + +# Create device files +function create_files () { + cd /dev + local devlist="" + local file + while true; do + if [ $# -lt 2 ]; then break; fi + file="${DEVICE}$1" + mknod $file c $MAJOR $2 + devlist="$devlist $file" + shift 2 + done + if [ -n "$OWNER" ]; then chown $OWNER $devlist; fi + if [ -n "$GROUP" ]; then chgrp $GROUP $devlist; fi + if [ -n "$MODE" ]; then chmod $MODE $devlist; fi +} + +# Remove device files +function remove_files () { + cd /dev + local devlist="" + local file + while true; do + if [ $# -lt 2 ]; then break; fi + file="${DEVICE}$1" + devlist="$devlist $file" + shift 2 + done + rm -f $devlist +} + +# Load and create files +function load_device () { + + if [ -f $MODDIR/$DEVICE.o ]; then + devpath=$MODDIR/$DEVICE.o + else if [ -f ./$DEVICE.o ]; then + devpath=./$DEVICE.o + else + devpath=$DEVICE; # let insmod/modprobe guess + fi; fi + if [ "$devpath" != "$DEVICE" ]; then + echo -n " (loading file $devpath)" + fi + + if $INSMOD $devpath $OPTIONS; then + MAJOR=`awk "\\$2==\"$DEVICE\" {print \\$1}" /proc/devices` + remove_files $FILES + create_files $FILES + device_specific_post_load + else + echo " FAILED!" + fi +} + +# Unload and remove files +function unload_device () { + device_specific_pre_unload + /sbin/rmmod $DEVICE + remove_files $FILES +} + + +case "$1" in + start) + echo -n "Loading $DEVICE" + load_device + echo "." + ;; + stop) + echo -n "Unloading $DEVICE" + unload_device + echo "." + ;; + force-reload|restart) + echo -n "Reloading $DEVICE" + unload_device + load_device + echo "." + ;; + *) + echo "Usage: $0 {start|stop|restart|force-reload}" + exit 1 +esac + +exit 0 From 7b59313902498fa061bbb6b096ddd9fb3094774e Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Sat, 11 Dec 2010 13:20:35 -0600 Subject: [PATCH 024/244] skypopen: added a proof of concept standalone OSS audio driver (for Skype-oss clients) --- src/mod/endpoints/mod_skypopen/oss/scull.init | 142 ------------------ 1 file changed, 142 deletions(-) delete mode 100644 src/mod/endpoints/mod_skypopen/oss/scull.init diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.init b/src/mod/endpoints/mod_skypopen/oss/scull.init deleted file mode 100644 index e0523ce456..0000000000 --- a/src/mod/endpoints/mod_skypopen/oss/scull.init +++ /dev/null @@ -1,142 +0,0 @@ -#!/bin/bash -# Sample init script for the a driver module - -DEVICE="scull" -SECTION="misc" - -# The list of filenames and minor numbers: $PREFIX is prefixed to all names -PREFIX="scull" -FILES=" 0 0 1 1 2 2 3 3 priv 16 - pipe0 32 pipe1 33 pipe2 34 pipe3 35 - single 48 uid 64 wuid 80" - -INSMOD=/sbin/insmod; # use /sbin/modprobe if you prefer - -function device_specific_post_load () { - true; # fill at will -} -function device_specific_pre_unload () { - true; # fill at will -} - -# Everything below this line should work unchanged for any char device. -# Obviously, however, no options on the command line: either in -# /etc/${DEVICE}.conf or /etc/modules.conf (if modprobe is used) - -# Optional configuration file: format is -# owner -# group -# mode -# options -CFG=/etc/${DEVICE}.conf - -# kernel version, used to look for modules -KERNEL=`uname -r` - -#FIXME: it looks like there is no misc section. Where should it be? -MODDIR="/lib/modules/${KERNEL}/kernel/drivers/${SECTION}" -if [ ! -d $MODDIR ]; then MODDIR="/lib/modules/${KERNEL}/${SECTION}"; fi - -# Root or die -if [ "$(id -u)" != "0" ] -then - echo "You must be root to load or unload kernel modules" - exit 1 -fi - -# Read configuration file -if [ -r $CFG ]; then - OWNER=`awk "\\$1==\"owner\" {print \\$2}" $CFG` - GROUP=`awk "\\$1==\"group\" {print \\$2}" $CFG` - MODE=`awk "\\$1==\"mode\" {print \\$2}" $CFG` - # The options string may include extra blanks or only blanks - OPTIONS=`sed -n '/^options / s/options //p' $CFG` -fi - - -# Create device files -function create_files () { - cd /dev - local devlist="" - local file - while true; do - if [ $# -lt 2 ]; then break; fi - file="${DEVICE}$1" - mknod $file c $MAJOR $2 - devlist="$devlist $file" - shift 2 - done - if [ -n "$OWNER" ]; then chown $OWNER $devlist; fi - if [ -n "$GROUP" ]; then chgrp $GROUP $devlist; fi - if [ -n "$MODE" ]; then chmod $MODE $devlist; fi -} - -# Remove device files -function remove_files () { - cd /dev - local devlist="" - local file - while true; do - if [ $# -lt 2 ]; then break; fi - file="${DEVICE}$1" - devlist="$devlist $file" - shift 2 - done - rm -f $devlist -} - -# Load and create files -function load_device () { - - if [ -f $MODDIR/$DEVICE.o ]; then - devpath=$MODDIR/$DEVICE.o - else if [ -f ./$DEVICE.o ]; then - devpath=./$DEVICE.o - else - devpath=$DEVICE; # let insmod/modprobe guess - fi; fi - if [ "$devpath" != "$DEVICE" ]; then - echo -n " (loading file $devpath)" - fi - - if $INSMOD $devpath $OPTIONS; then - MAJOR=`awk "\\$2==\"$DEVICE\" {print \\$1}" /proc/devices` - remove_files $FILES - create_files $FILES - device_specific_post_load - else - echo " FAILED!" - fi -} - -# Unload and remove files -function unload_device () { - device_specific_pre_unload - /sbin/rmmod $DEVICE - remove_files $FILES -} - - -case "$1" in - start) - echo -n "Loading $DEVICE" - load_device - echo "." - ;; - stop) - echo -n "Unloading $DEVICE" - unload_device - echo "." - ;; - force-reload|restart) - echo -n "Reloading $DEVICE" - unload_device - load_device - echo "." - ;; - *) - echo "Usage: $0 {start|stop|restart|force-reload}" - exit 1 -esac - -exit 0 From 2f0105d0506a0101f546c8f27c4cb0d1a766ee5d Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sat, 11 Dec 2010 16:53:52 -0600 Subject: [PATCH 025/244] FS-2921 Fix typo in STFU library --- libs/stfu/stfu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 6015207452..fce968c990 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -219,7 +219,7 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_ static void stfu_n_reset_counters(stfu_instance_t *i) { #ifdef DB_JB - printf("COUNER RESET........\n"); + printf("COUNTER RESET........\n"); #endif if (i->callback) { From e8792d0ad3742f5babdde4e1ec62cf97cc5deb66 Mon Sep 17 00:00:00 2001 From: Brian West Date: Sun, 12 Dec 2010 08:11:11 -0600 Subject: [PATCH 026/244] swig all --- .../languages/mod_managed/freeswitch_wrap.cxx | 22 +++++++++++++++++-- src/mod/languages/mod_managed/managed/swig.cs | 16 +++++++++++--- src/mod/languages/mod_perl/mod_perl_wrap.cpp | 6 ++--- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index a65d82d9cb..1d3c5d60ce 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -28993,15 +28993,33 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_rtcp(void * jarg1, int jar } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5) { int jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; uint32_t arg2 ; + uint32_t arg3 ; + uint32_t arg4 ; + uint32_t arg5 ; switch_status_t result; arg1 = (switch_rtp_t *)jarg1; arg2 = (uint32_t)jarg2; - result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2); + arg3 = (uint32_t)jarg3; + arg4 = (uint32_t)jarg4; + arg5 = (uint32_t)jarg5; + result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2,arg3,arg4,arg5); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jarg1) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + result = (switch_status_t)switch_rtp_deactivate_jitter_buffer(arg1); jresult = result; return jresult; } diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index e024c586f8..9decf74045 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -4630,8 +4630,13 @@ public class freeswitch { return ret; } - public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames); + public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames, uint max_queue_frames, uint samples_per_packet, uint samples_per_second) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames, max_queue_frames, samples_per_packet, samples_per_second); + return ret; + } + + public static switch_status_t switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_deactivate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); return ret; } @@ -12434,7 +12439,10 @@ class freeswitchPINVOKE { public static extern int switch_rtp_activate_rtcp(HandleRef jarg1, int jarg2, ushort jarg3); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_jitter_buffer")] - public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2); + public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")] + public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")] public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2); @@ -21500,6 +21508,7 @@ public enum switch_channel_flag_t { CF_PASSTHRU_PTIME_MISMATCH, CF_BRIDGE_NOWRITE, CF_RECOVERED, + CF_JITTERBUFFER, CF_FLAG_MAX } @@ -23167,6 +23176,7 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION, SWITCH_MESSAGE_INDICATE_UDPTL_MODE, SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, + SWITCH_MESSAGE_INDICATE_JITTER_BUFFER, SWITCH_MESSAGE_INVALID } diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp index 2efbdf1abc..370c88bc99 100644 --- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp +++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp @@ -9732,17 +9732,17 @@ XS(SWIG_init) { SWIG_TypeClientData(SWIGTYPE_p_IVRMenu, (void*) "freeswitch::IVRMenu"); SWIG_TypeClientData(SWIGTYPE_p_API, (void*) "freeswitch::API"); SWIG_TypeClientData(SWIGTYPE_p_input_callback_state, (void*) "freeswitch::input_callback_state_t"); - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_HUP", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_HUP))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_FREE", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_FREE))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_RDLOCK", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_RDLOCK))); SvREADONLY_on(sv); From f87a32c66a059474f160a9055e7d582c424c152b Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Mon, 13 Dec 2010 11:29:38 -0500 Subject: [PATCH 027/244] removed unnecessary initialization --- libs/freetdm/src/ftdm_io.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 78ae3d2b65..8dd0a2de01 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -5478,7 +5478,6 @@ static void ftdm_cpu_monitor_stop(void) FT_DECLARE(ftdm_status_t) ftdm_global_init(void) { - int i; memset(&globals, 0, sizeof(globals)); time_init(); @@ -5504,9 +5503,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void) ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n"); return FTDM_FAIL; } - for(i=0;i Date: Mon, 13 Dec 2010 10:30:00 -0600 Subject: [PATCH 028/244] Fix samples for playback --- src/switch_ivr_play_say.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 3c8fa5e10f..d8d18f38a4 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1573,10 +1573,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done playing file\n"); if (read_impl.samples_per_second) { - switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_out / read_impl.samples_per_second); - switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_out / (read_impl.samples_per_second / 1000)); + switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_in / read_impl.samples_per_second); + switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_in / (read_impl.samples_per_second / 1000)); } - switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_out); + switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_in); switch_core_session_io_write_lock(session); switch_channel_set_private(channel, "__fh", NULL); From 3a645dee60b50ee188cb3b0a34866c728003059e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 09:36:45 -0600 Subject: [PATCH 029/244] FS-2913 --- src/mod/endpoints/mod_sofia/sofia_glue.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 74f5d3d764..65aedd3431 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -5060,9 +5060,20 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName const char *port = switch_channel_get_variable(channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE); const char *r_ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE); const char *r_port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE); + const char *use_uuid; sofia_set_flag(tech_pvt, TFLAG_RECOVERING); + if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) { + if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel), + use_uuid); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n", + switch_channel_get_name(channel), use_uuid); + } + } + if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && ip && port) { const char *tmp; tech_pvt->iananame = tech_pvt->rm_encoding = (char *) switch_channel_get_variable(channel, "sip_use_codec_name"); From dfecc914876b164ce64c53c4f048aa38ed65d9c5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 11:20:12 -0600 Subject: [PATCH 030/244] remove check for va_list completely in sofia since i don't event think it happens ever --- src/mod/endpoints/mod_sofia/sofia.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index e34d7aef9d..591cd7f4aa 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1717,16 +1717,9 @@ void launch_sofia_profile_thread(sofia_profile_t *profile) static void logger(void *logarg, char const *fmt, va_list ap) { - /* gcc 4.4 gets mad at us for testing if (ap) so let's try to work around it....*/ - void *ap_ptr = (void *) (intptr_t) ap; - if (!fmt) return; - if (ap_ptr) { - switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, "%s", fmt); - } + switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, mod_sofia_globals.tracelevel, fmt, ap); } static su_log_t *sofia_get_logger(const char *name) From cb2d073632211b8459ca29aba4785c875bbfc8ec Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 11:50:06 -0600 Subject: [PATCH 031/244] FS-2924 --- src/switch_apr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/switch_apr.c b/src/switch_apr.c index 7c027f8c68..7a6bfc75d9 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -732,11 +732,21 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recv(switch_socket_t *sock, char * SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool) { switch_sockaddr_t *new_sa; + int family = APR_INET; new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t)); switch_assert(new_sa); new_sa->pool = pool; memset(new_sa, 0, sizeof(new_sa)); + + new_sa->family = family; + new_sa->sa.sin.sin_family = family; + + new_sa->salen = sizeof(struct sockaddr_in); + new_sa->addr_str_len = 16; + new_sa->ipaddr_ptr = &(new_sa->sa.sin.sin_addr); + new_sa->ipaddr_len = sizeof(struct in_addr); + *sa = new_sa; return SWITCH_STATUS_SUCCESS; } From 84c7fa2fbc43fadd37f406dc7cd6f20db1221386 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 13 Dec 2010 13:42:38 -0600 Subject: [PATCH 032/244] my bad fix warning --- src/switch_apr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_apr.c b/src/switch_apr.c index 7a6bfc75d9..c0e51f9766 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -732,7 +732,7 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recv(switch_socket_t *sock, char * SWITCH_DECLARE(switch_status_t) switch_sockaddr_create(switch_sockaddr_t **sa, switch_memory_pool_t *pool) { switch_sockaddr_t *new_sa; - int family = APR_INET; + unsigned short family = APR_INET; new_sa = apr_pcalloc(pool, sizeof(apr_sockaddr_t)); switch_assert(new_sa); From 321013efe74037a098e261bf805a426c27b75dbf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 14:01:53 -0600 Subject: [PATCH 033/244] have mod_sofia always elect to be the session refresher so we know it will work, also make the session-expires set to 0 imply 100% disabled session timers --- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 ++-- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 0e64d54a0a..d4f8b1b45a 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -723,7 +723,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)), TAG_IF(cid, SIPTAG_HEADER_STR(cid)), NUTAG_SESSION_TIMER(session_timeout), - TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)), + NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), @@ -739,7 +739,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)), TAG_IF(cid, SIPTAG_HEADER_STR(cid)), NUTAG_SESSION_TIMER(session_timeout), - TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)), + NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")), SIPTAG_CONTENT_TYPE_STR("application/sdp"), diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 65aedd3431..3d56b6d9a1 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2342,7 +2342,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) nua_invite(tech_pvt->nh, NUTAG_AUTOANSWER(0), NUTAG_SESSION_TIMER(session_timeout), - TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)), + NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher), TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)), TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), From a2faee2023041cfc0cf41965b4a2447eb6d2c75a Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 13 Dec 2010 16:27:51 -0500 Subject: [PATCH 034/244] freetdm: ftdm_r2 - fix stats --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 9d94c6d088..9206493ad2 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -665,7 +665,7 @@ static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm) { ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Alarm notification: %d\n", alarm); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Alarm notification: %d\n", alarm); } static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode) @@ -1955,7 +1955,7 @@ static FIO_API_FUNCTION(ftdm_r2_api) "Max DNIS: %d\n" "ANI First: %s\n" "Immediate Accept: %s\n" - "Job Thread: %lu\n" + "Job Thread: %u\n" "Job Max ms: %d\n" "Job Loops: %lu\n", openr2_proto_get_variant_string(r2variant), From cfeae1ba99b9c6a545a9c7608eca4b7ba1f22192 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Mon, 13 Dec 2010 14:57:43 -0800 Subject: [PATCH 035/244] Bump Doxygen.conf version to 1.0.6... belatedly --- docs/Doxygen.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Doxygen.conf b/docs/Doxygen.conf index ccdb3b8a47..2c06417833 100644 --- a/docs/Doxygen.conf +++ b/docs/Doxygen.conf @@ -31,7 +31,7 @@ PROJECT_NAME = FreeSWITCH # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.0.4 +PROJECT_NUMBER = 1.0.6 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. From 28cab5ed46a140b70d92ea27214f445dfbd26467 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 17:59:32 -0600 Subject: [PATCH 036/244] FS-2923 --- src/switch_ivr_play_say.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index d8d18f38a4..710c0a738c 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1761,6 +1761,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, switch_assert(session); + if (!digit_timeout) { + digit_timeout = timeout; + } + if (max_digits < min_digits) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits); From 2e51b571b08d6573936ee787088a72df64d37f65 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 18:00:10 -0600 Subject: [PATCH 037/244] update --- libs/stfu/stfu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index fce968c990..c0d4a96ee5 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -27,7 +27,7 @@ */ #include "stfu.h" -//#define DB_JB 1 +#define DB_JB 1 #ifdef _MSC_VER /* warning C4706: assignment within conditional expression*/ #pragma warning(disable: 4706) @@ -305,11 +305,11 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin } } - if (seq && seq == i->last_seq + 1) { + if ((seq && seq == i->last_seq + 1) || (i->last_seq > 65500 && seq == 0)) { good_seq = 1; } - if (ts && ts == i->last_rd_ts + i->samples_per_packet) { + if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) { good_ts = 1; } @@ -450,7 +450,7 @@ static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t for(i = 0; i < queue->real_array_size; i++) { frame = &queue->array[i]; - if ((seq && frame->seq == seq) || frame->ts == ts) { + if (((seq || in->last_seq) && frame->seq == seq) || frame->ts == ts) { *r_frame = frame; queue->last_index = i; frame->was_read = 1; @@ -547,7 +547,6 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) #ifdef DB_JB if (found) { printf("O: %u:%u %u\n", rframe->seq, rframe->seq, rframe->plc); - assert(found && rframe->seq); } else { printf("DATA: %u %u %d %s %d\n", i->packet_count, i->consecutive_good_count, i->out_queue->last_jitter, found ? "found" : "not found", i->qlen); } @@ -579,6 +578,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) rframe = &i->out_queue->int_frame; rframe->dlen = i->plc_len; +#if 0 if (i->last_frame) { /* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */ if (i->miss_count) { @@ -587,7 +587,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) memcpy(rframe->data, i->last_frame->data, rframe->dlen); } } - +#endif rframe->ts = i->cur_ts; i->miss_count++; From 0ca7930fa3270bd71e5781539afa7af8b9c975a4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 18:14:39 -0600 Subject: [PATCH 038/244] small tweak to new plc code --- src/switch_core_io.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/switch_core_io.c b/src/switch_core_io.c index a2df79d1bc..c3113e9680 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -325,13 +325,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_thread_rwlock_unlock(session->bug_rwlock); } - status = switch_core_codec_decode(use_codec, - session->read_codec, - read_frame->data, - read_frame->datalen, - session->read_impl.actual_samples_per_second, - session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, - &read_frame->flags); + if (switch_test_flag(read_frame, SFF_PLC)) { + session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet; + session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t); + memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen); + status = SWITCH_STATUS_SUCCESS; + } else { + status = switch_core_codec_decode(use_codec, + session->read_codec, + read_frame->data, + read_frame->datalen, + session->read_impl.actual_samples_per_second, + session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, + &read_frame->flags); + } if (status == SWITCH_STATUS_SUCCESS) { if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && !session->plc) { From 7f8ba794c9d60d560968f8f61680d2fffd6c1b31 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 18:17:11 -0600 Subject: [PATCH 039/244] doh --- libs/stfu/stfu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index c0d4a96ee5..12713201a0 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -27,7 +27,7 @@ */ #include "stfu.h" -#define DB_JB 1 +//#define DB_JB 1 #ifdef _MSC_VER /* warning C4706: assignment within conditional expression*/ #pragma warning(disable: 4706) From d11c83b16e79f20d00082633d03c68fd0c6c0930 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 13 Dec 2010 18:28:43 -0600 Subject: [PATCH 040/244] revert to the last transfered conference on recover --- src/mod/applications/mod_conference/mod_conference.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 4cbb052994..9b170a32e0 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -4366,6 +4366,8 @@ static switch_status_t conf_api_sub_transfer(conference_obj_t *conference, switc } } + switch_channel_set_variable(channel, "last_transfered_conference", argv[2]); + unlock_member(member); stream->write_function(stream, "OK Member '%d' sent to conference %s.\n", member->id, argv[2]); @@ -5374,6 +5376,14 @@ SWITCH_STANDARD_APP(conference_function) } #endif + if (switch_channel_test_flag(channel, CF_RECOVERED)) { + const char *check = switch_channel_get_variable(channel, "last_transfered_conference"); + + if (!zstr(check)) { + conf_name = (char *) check; + } + } + switch_event_create(¶ms, SWITCH_EVENT_COMMAND); switch_assert(params); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "conf_name", conf_name); From 7e047c3fd12cf3d6a4fae02021ea561512041d8f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 14 Dec 2010 00:15:36 -0600 Subject: [PATCH 041/244] more ongoing work on jb --- libs/stfu/stfu.c | 73 ++++++++++++++++++------ src/mod/endpoints/mod_sofia/sofia_glue.c | 6 +- src/switch_rtp.c | 2 +- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 12713201a0..547c337278 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -28,6 +28,11 @@ #include "stfu.h" //#define DB_JB 1 + +#ifndef UINT_MAX +# define UINT_MAX 4294967295U +#endif + #ifdef _MSC_VER /* warning C4706: assignment within conditional expression*/ #pragma warning(disable: 4706) @@ -123,6 +128,7 @@ static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen) static void stfu_n_init_aqueue(stfu_queue_t *queue, uint32_t qlen) { + queue->array = calloc(qlen, sizeof(struct stfu_frame)); assert(queue->array != NULL); memset(queue->array, 0, sizeof(struct stfu_frame) * qlen); @@ -166,6 +172,7 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) stfu_status_t s; if (i->qlen == i->max_qlen) { + printf("FUCKER1\n"); return STFU_IT_FAILED; } @@ -173,6 +180,7 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) if (i->qlen < i->max_qlen) { qlen = i->max_qlen; } else { + printf("FUCKER2\n"); return STFU_IT_FAILED; } } @@ -196,6 +204,12 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_ return NULL; } memset(i, 0, sizeof(*i)); + + +#ifdef DB_JB + printf("INIT %u %u\n", qlen, max_qlen); +#endif + i->qlen = qlen; i->max_qlen = max_qlen; i->orig_qlen = qlen; @@ -281,10 +295,11 @@ stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets) stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uint32_t pt, void *data, size_t datalen, int last) { - uint32_t index; + uint32_t index = 0; stfu_frame_t *frame; size_t cplen = 0; int good_seq = 0, good_ts = 0; + uint32_t min_seq = UINT_MAX, min_ts = UINT_MAX, min_index = 0; if (!i->samples_per_packet && ts && i->last_rd_ts) { i->ts_diff = ts - i->last_rd_ts; @@ -322,21 +337,20 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin i->period_packet_in_count++; i->session_packet_in_count++; - if (i->session_packet_in_count == 150) { - return STFU_IT_WORKED; - } - i->period_need_range_avg = i->period_need_range / (i->period_missing_count || 1); - + if (i->period_missing_count > i->qlen * 2) { +#ifdef DB_JB + printf("resize %u %u\n", i->qlen, i->qlen + 1); +#endif stfu_n_resize(i, i->qlen + 1); stfu_n_reset_counters(i); - } - - if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) { - stfu_n_resize(i, i->qlen - 1); - stfu_n_reset_counters(i); - stfu_n_sync(i, i->qlen); + } else { + if (i->qlen > i->orig_qlen && (i->consecutive_good_count > i->decrement_time || i->period_clean_count > i->decrement_time)) { + stfu_n_resize(i, i->qlen - 1); + stfu_n_reset_counters(i); + stfu_n_sync(i, i->qlen); + } } if ((i->period_packet_in_count > i->period_time)) { @@ -379,13 +393,31 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin return STFU_IM_DONE; } - for(index = 0; index < i->out_queue->array_size; index++) { + for(index = 0; index < i->in_queue->array_size; index++) { + if (i->in_queue->array[index].was_read) { + min_index = index; break; } + + if (i->in_queue->array[index].seq < min_seq) { + min_seq = i->in_queue->array[index].seq; + min_index = index; + } + + if (i->in_queue->array[index].ts < min_ts) { + min_ts = i->in_queue->array[index].ts; + min_index = index; + } } - index = i->in_queue->array_len++; + index = min_index; + + if (i->in_queue->array_len < i->in_queue->array_size) { + i->in_queue->array_len++; + } + + assert(index < i->in_queue->array_size); frame = &i->in_queue->array[index]; @@ -468,7 +500,8 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) stfu_frame_t *rframe = NULL; int found = 0; - if (!i->samples_per_packet || ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) { + if (!i->samples_per_packet || !i->out_queue->array_len) { + //|| ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) { return NULL; } @@ -481,7 +514,11 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) if (i->cur_seq == 0) { i->cur_seq = i->out_queue->array[0].seq; } else { - i->cur_seq++; + i->cur_seq++; + /* if we bother using this for anything that doesn't have 16 bit seq, we'll make this a param */ + if (i->cur_seq == 65535) { + i->cur_seq = 0; + } } if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) { @@ -496,7 +533,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) i->cur_seq = rframe->seq; i->cur_ts = rframe->ts; } - i->sync--; + i->sync = 0; } @@ -546,7 +583,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) #ifdef DB_JB if (found) { - printf("O: %u:%u %u\n", rframe->seq, rframe->seq, rframe->plc); + printf("O: %u:%u %u %d\n", rframe->seq, rframe->ts, rframe->plc, rframe->seq - i->last_seq); } else { printf("DATA: %u %u %d %s %d\n", i->packet_count, i->consecutive_good_count, i->out_queue->last_jitter, found ? "found" : "not found", i->qlen); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 3d56b6d9a1..803059a8da 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3153,19 +3153,19 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) { int len = atoi(val); - int maxlen = 50; + int maxlen = 0; char *p; if ((p = strchr(val, ':'))) { p++; - maxlen = atoi(val); + maxlen = atoi(p); } if (len < 20 || len > 10000) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len); } else { - int qlen, maxqlen = 0; + int qlen, maxqlen = 50; qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 772c2508a0..b4f60fcd55 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1667,7 +1667,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * if (rtp_session->jb) { stfu_n_resize(rtp_session->jb, queue_frames); } else { - rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames || 50, samples_per_packet, samples_per_second); + rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames ? max_queue_frames : 50, samples_per_packet, samples_per_second); } READ_DEC(rtp_session); From 0e83cbe5cae49a326ce687d1079471dd072b915b Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Sun, 12 Dec 2010 13:39:03 -0600 Subject: [PATCH 042/244] skypopen: slightly improve OSS audio driver --- src/mod/endpoints/mod_skypopen/oss/main.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 4d36ac00d5..17cc5e33ed 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -60,8 +60,8 @@ MODULE_LICENSE("Dual BSD/GPL"); static struct scull_dev *scull_devices; /* allocated in scull_init_module */ -#define GIOVA_BLK 3840 -#define GIOVA_SLEEP 40000 +#define GIOVA_BLK 1920 +#define GIOVA_SLEEP 20000 void my_timer_callback_inq( unsigned long data ) { @@ -130,11 +130,11 @@ static int scull_c_open(struct inode *inode, struct file *filp) struct scull_dev *dev; dev_t key; - if (!current->pid) { - printk("Process \"%s\" has no pid\n", current->comm); + if (!current->tgid) { + printk("Process \"%s\" has no tgid\n", current->comm); return -EINVAL; } - key = current->pid; + key = current->tgid; /* look for a scullc device in the list */ spin_lock(&scull_c_lock); @@ -174,6 +174,8 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count, prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->inq, &wait); + //memset(buf, 255, count); + return count; } From 6e310ef8fc0d5b7e00460b7603f6b5854aa61db1 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Mon, 13 Dec 2010 07:33:37 -0600 Subject: [PATCH 043/244] skypopen: slightly improve OSS audio driver --- src/mod/endpoints/mod_skypopen/oss/main.c | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 17cc5e33ed..c1228d63f1 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -61,14 +61,14 @@ MODULE_LICENSE("Dual BSD/GPL"); static struct scull_dev *scull_devices; /* allocated in scull_init_module */ #define GIOVA_BLK 1920 -#define GIOVA_SLEEP 20000 +#define GIOVA_SLEEP 20 void my_timer_callback_inq( unsigned long data ) { struct scull_dev *dev = (void *)data; wake_up_interruptible(&dev->inq); - mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); + mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); } @@ -77,7 +77,7 @@ void my_timer_callback_outq( unsigned long data ) struct scull_dev *dev = (void *)data; wake_up_interruptible(&dev->outq); - mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); + mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); } /* The clone-specific data structure includes a key field */ @@ -117,9 +117,9 @@ static struct scull_dev *scull_c_lookfor_device(dev_t key) printk(" Timer installing\n"); setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); - printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP/1000, jiffies ); - mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); - mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP/1000) ); + printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP, jiffies ); + mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); /* place it in the list */ list_add(&lptr->list, &scull_c_list); @@ -170,11 +170,11 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count, { struct scull_dev *dev = filp->private_data; - DEFINE_WAIT(wait); - prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&dev->inq, &wait); - //memset(buf, 255, count); + DEFINE_WAIT(wait); + prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&dev->inq, &wait); + //memset(buf, 255, count); return count; @@ -184,10 +184,10 @@ ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { struct scull_dev *dev = filp->private_data; - DEFINE_WAIT(wait); - prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&dev->outq, &wait); + DEFINE_WAIT(wait); + prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&dev->outq, &wait); return count; @@ -252,7 +252,7 @@ void scull_cleanup_module(void) } - /* And all the cloned devices */ + /* And all the cloned devices */ list_for_each_entry_safe(lptr, next, &scull_c_list, list) { ret= del_timer( &lptr->device.timer_inq ); if (ret) printk("The inq timer was still in use...\n"); @@ -261,7 +261,7 @@ void scull_cleanup_module(void) list_del(&lptr->list); kfree(lptr); } - printk("Timer uninstalling\n"); + printk("Timer uninstalling\n"); /* cleanup_module is never called if registering failed */ unregister_chrdev_region(devno, scull_nr_devs); From 7997d24f33eaab50ed1e9068f8326e6e0dd706cf Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 14 Dec 2010 06:45:43 -0600 Subject: [PATCH 044/244] skypopen: tweaking the OSS audio driver --- src/mod/endpoints/mod_skypopen/oss/main.c | 29 ++++++++++++++-------- src/mod/endpoints/mod_skypopen/oss/scull.h | 2 ++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index c1228d63f1..925441b254 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -67,6 +67,7 @@ void my_timer_callback_inq( unsigned long data ) { struct scull_dev *dev = (void *)data; + dev->readable=1; wake_up_interruptible(&dev->inq); mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); @@ -76,6 +77,7 @@ void my_timer_callback_outq( unsigned long data ) { struct scull_dev *dev = (void *)data; + dev->writable=1; wake_up_interruptible(&dev->outq); mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); } @@ -130,11 +132,11 @@ static int scull_c_open(struct inode *inode, struct file *filp) struct scull_dev *dev; dev_t key; - if (!current->tgid) { - printk("Process \"%s\" has no tgid\n", current->comm); + if (!current->pid) { + printk("Process \"%s\" has no pid\n", current->comm); return -EINVAL; } - key = current->tgid; + key = current->pid; /* look for a scullc device in the list */ spin_lock(&scull_c_lock); @@ -170,12 +172,14 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count, { struct scull_dev *dev = filp->private_data; - DEFINE_WAIT(wait); - prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&dev->inq, &wait); + //DEFINE_WAIT(wait); + //prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); + //schedule(); + //finish_wait(&dev->inq, &wait); //memset(buf, 255, count); + wait_event_interruptible(dev->inq, dev->readable); + dev->readable=0; return count; } @@ -184,10 +188,13 @@ ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { struct scull_dev *dev = filp->private_data; - DEFINE_WAIT(wait); - prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&dev->outq, &wait); + //DEFINE_WAIT(wait); + //prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); + //schedule(); + //finish_wait(&dev->outq, &wait); + + wait_event_interruptible(dev->outq, dev->writable); + dev->writable=0; return count; diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.h b/src/mod/endpoints/mod_skypopen/oss/scull.h index e86281bd94..565b8b38b7 100644 --- a/src/mod/endpoints/mod_skypopen/oss/scull.h +++ b/src/mod/endpoints/mod_skypopen/oss/scull.h @@ -34,6 +34,8 @@ struct scull_dev { wait_queue_head_t outq; /* read and write queues */ struct timer_list timer_inq; struct timer_list timer_outq; + int readable; + int writable; //unsigned long read_howmany; //unsigned long write_howmany; //unsigned long read_sleeped_acc; From 739ac99e3b80a15c81def7f65e24b035a96b3602 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 14 Dec 2010 08:38:57 -0600 Subject: [PATCH 045/244] skypopen: tweaking the OSS audio driver, still gives a load average higher than snd-dummy + snd-pcm-oss on CentOS 5 (but not much more, and lower cpu load), but now is very very good on tickless kernels, eg: Ubuntu 10.04 LTS --- src/mod/endpoints/mod_skypopen/oss/Makefile | 2 +- src/mod/endpoints/mod_skypopen/oss/main.c | 28 ++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile index 91cc61ba1e..465db533e4 100644 --- a/src/mod/endpoints/mod_skypopen/oss/Makefile +++ b/src/mod/endpoints/mod_skypopen/oss/Makefile @@ -1,6 +1,6 @@ # Comment/uncomment the following line to disable/enable debugging #DEBUG = y -LDDINC=/usr/src/linux-headers-2.6.32-26-server/include +#LDDINC=/usr/src/linux-headers-2.6.32-26-server/include # Add your debugging flag (or not) to CFLAGS ifeq ($(DEBUG),y) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 925441b254..8da9c549ac 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -67,7 +67,7 @@ void my_timer_callback_inq( unsigned long data ) { struct scull_dev *dev = (void *)data; - dev->readable=1; + //dev->readable=1; wake_up_interruptible(&dev->inq); mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); @@ -77,7 +77,7 @@ void my_timer_callback_outq( unsigned long data ) { struct scull_dev *dev = (void *)data; - dev->writable=1; + //dev->writable=1; wake_up_interruptible(&dev->outq); mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); } @@ -172,14 +172,14 @@ ssize_t scull_read(struct file *filp, char __user *buf, size_t count, { struct scull_dev *dev = filp->private_data; - //DEFINE_WAIT(wait); - //prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); - //schedule(); - //finish_wait(&dev->inq, &wait); + DEFINE_WAIT(wait); + prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&dev->inq, &wait); //memset(buf, 255, count); - wait_event_interruptible(dev->inq, dev->readable); - dev->readable=0; + //wait_event_interruptible(dev->inq, dev->readable); + //dev->readable=0; return count; } @@ -188,13 +188,13 @@ ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { struct scull_dev *dev = filp->private_data; - //DEFINE_WAIT(wait); - //prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); - //schedule(); - //finish_wait(&dev->outq, &wait); + DEFINE_WAIT(wait); + prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&dev->outq, &wait); - wait_event_interruptible(dev->outq, dev->writable); - dev->writable=0; + //wait_event_interruptible(dev->outq, dev->writable); + //dev->writable=0; return count; From 36b2346445188c279b8d3da2c139a0ca862f2511 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 14 Dec 2010 09:28:57 -0600 Subject: [PATCH 046/244] add path --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 72ad3f718c..da89572c6f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -102,7 +102,7 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/pcre CORE_CFLAGS += -I$(switch_srcdir)/libs/speex/include -Ilibs/speex/include CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include -Ilibs/srtp/crypto/include -CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src +CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src -I$(switch_srcdir)/libs/tiff-3.8.2/libtiff CORE_LIBS = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la From 905fdcc2488dfa0b8cc8bb4d2f0f199704a943b8 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 14 Dec 2010 11:23:47 -0500 Subject: [PATCH 047/244] freetdm: Support for channel restarts --- libs/freetdm/mod_freetdm/mod_freetdm.c | 22 ++ libs/freetdm/src/ftdm_io.c | 101 ++++---- libs/freetdm/src/ftdm_m3ua.c | 2 +- .../freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c | 2 +- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 4 +- .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 8 +- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 32 ++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 10 +- .../ftmod_sangoma_isdn_stack_hndl.c | 108 ++++++++- .../ftmod_sangoma_isdn_stack_out.c | 218 ++---------------- .../ftmod_sangoma_isdn_stack_rcv.c | 22 +- .../ftmod_sangoma_isdn_support.c | 104 ++++++++- libs/freetdm/src/include/freetdm.h | 9 + libs/freetdm/src/include/private/ftdm_core.h | 1 - libs/freetdm/src/include/private/ftdm_types.h | 3 +- 15 files changed, 367 insertions(+), 279 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 38197bb2f0..26b84636ca 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3922,6 +3922,28 @@ SWITCH_STANDARD_API(ft_function) } } stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain); + } else if (!strcasecmp(argv[0], "restart")) { + uint32_t chan_id = 0; + ftdm_channel_t *chan; + ftdm_span_t *span = NULL; + if (argc < 3) { + stream->write_function(stream, "-ERR Usage: ftdm restart \n"); + goto end; + } + ftdm_span_find_by_name(argv[1], &span); + if (!span) { + stream->write_function(stream, "-ERR invalid span\n"); + goto end; + } + + chan_id = atoi(argv[2]); + chan = ftdm_span_get_channel(span, chan_id); + if (!chan) { + stream->write_function(stream, "-ERR Could not find chan\n"); + goto end; + } + stream->write_function(stream, "Resetting channel %s:%s\n", argv[2], argv[3]); + ftdm_channel_reset(chan); } else { char *rply = ftdm_api_execute(cmd); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index e13d0196b8..deeb578c81 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -65,6 +65,8 @@ ftdm_time_t time_current_throttle_log = 0; static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter); static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data); static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data); +static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan); +static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan); static int time_is_init = 0; @@ -1874,45 +1876,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc return status; } -static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan) -{ - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); - ftdm_channel_done(ftdmchan); - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_HOLD); - - memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens)); - ftdmchan->token_count = 0; - - ftdm_channel_flush_dtmf(ftdmchan); - - if (ftdmchan->gen_dtmf_buffer) { - ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer); - } - - if (ftdmchan->digit_buffer) { - ftdm_buffer_zero(ftdmchan->digit_buffer); - } - - if (!ftdmchan->dtmf_on) { - ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON; - } - - if (!ftdmchan->dtmf_off) { - ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF; - } - - memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len); - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) { - ftdmchan->effective_codec = ftdmchan->native_codec; - ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE); - } - - return FTDM_SUCCESS; -} FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan) { @@ -2462,6 +2425,21 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const ch return status; } +FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) +{ + ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); +#ifdef __WINDOWS__ + UNREFERENCED_PARAMETER(file); + UNREFERENCED_PARAMETER(func); + UNREFERENCED_PARAMETER(line); +#endif + + ftdm_channel_lock(ftdmchan); + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 0); + ftdm_channel_unlock(ftdmchan); + return FTDM_SUCCESS; +} + FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { ftdm_status_t status = FTDM_FAIL; @@ -2545,12 +2523,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa } } -static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan); -FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) +static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) { ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n"); - ftdm_mutex_lock(ftdmchan->mutex); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK); @@ -2591,17 +2570,47 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) sigmsg.event_id = FTDM_SIGEVENT_RELEASED; ftdm_span_send_signal(ftdmchan->span, &sigmsg); ftdm_call_clear_call_id(&ftdmchan->caller_data); - } + } if (ftdmchan->txdrops || ftdmchan->rxdrops) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", ftdmchan->txdrops, ftdmchan->rxdrops); } ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); - ftdm_mutex_unlock(ftdmchan->mutex); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD); + + memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens)); + ftdmchan->token_count = 0; + + ftdm_channel_flush_dtmf(ftdmchan); + + if (ftdmchan->gen_dtmf_buffer) { + ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer); + } + + if (ftdmchan->digit_buffer) { + ftdm_buffer_zero(ftdmchan->digit_buffer); + } + + if (!ftdmchan->dtmf_on) { + ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON; + } + + if (!ftdmchan->dtmf_off) { + ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF; + } + + memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len); + + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) { + ftdmchan->effective_codec = ftdmchan->native_codec; + ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE); + } + ftdm_mutex_unlock(ftdmchan->mutex); return FTDM_SUCCESS; } @@ -2632,7 +2641,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan) status = check->fio->close(check); if (status == FTDM_SUCCESS) { ftdm_clear_flag(check, FTDM_CHANNEL_INUSE); - ftdm_channel_reset(check); + ftdm_channel_done(check); *ftdmchan = NULL; } } else { diff --git a/libs/freetdm/src/ftdm_m3ua.c b/libs/freetdm/src/ftdm_m3ua.c index 1a6fe362e7..5a468d1378 100644 --- a/libs/freetdm/src/ftdm_m3ua.c +++ b/libs/freetdm/src/ftdm_m3ua.c @@ -156,7 +156,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) release_request_id((m3ua_request_id_t)ftdmchan->extra_id); ftdmchan->extra_id = 0; } - ftdm_channel_done(ftdmchan); + ftdm_channel_close(ftdmchan); } break; case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index 6a8a4eb379..c6a0e5ff0e 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -1325,7 +1325,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) } Q931ReleaseCRV(&isdn_data->q931, gen->CRV); } - ftdm_channel_done(ftdmchan); + ftdm_channel_close(ftdmchan); } break; case FTDM_CHANNEL_STATE_PROGRESS: diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 220a96515b..b3b4f2a9dc 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -281,10 +281,10 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_DOWN: { - ftdm_channel_done(ftdmchan); + ftdm_channel_close(ftdmchan); ftdmchan->call_data = NULL; - ftdm_channel_done(peerchan); + ftdm_channel_close(peerchan); peerchan->call_data = NULL; } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index 50a01cc0ec..a196725d4e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -839,7 +839,7 @@ static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon if ((ftdmchan = find_ftdmchan(span, event, 1))) { ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_channel_done(ftdmchan); + ftdm_channel_close(ftdmchan); } else { ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); @@ -1106,7 +1106,7 @@ static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mc ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res); if (res != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n"); - ftdm_channel_done(ftdmchan); + ftdm_channel_close(ftdmchan); return; } ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id); @@ -1426,11 +1426,11 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) ftdmchan->sflags = 0; memset(ftdmchan->call_data, 0, sizeof(sangoma_boost_call_t)); if (sangoma_boost_data->sigmod && call_stopped_ack_sent) { - /* we dont want to call ftdm_channel_done just yet until call released is received */ + /* we dont want to call ftdm_channel_close just yet until call released is received */ ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n", ftdmchan->span_id, ftdmchan->chan_id); } else { - ftdm_channel_done(ftdmchan); + ftdm_channel_close(ftdmchan); } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index e20d3ae7e0..49e16ea12c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -65,7 +65,13 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_INBOUND, ZSM_UNACCEPTABLE, {FTDM_ANY_STATE, FTDM_END}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END} + {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_END} + }, + { + ZSD_INBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_RESET, FTDM_END}, + {FTDM_CHANNEL_STATE_DOWN, FTDM_END} }, { ZSD_INBOUND, @@ -170,7 +176,13 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_ANY_STATE, FTDM_END}, - {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END} + {FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END} + }, + { + ZSD_OUTBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_RESET, FTDM_END}, + {FTDM_CHANNEL_STATE_DOWN, FTDM_END} }, { ZSD_OUTBOUND, @@ -780,7 +792,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) sngisdn_snd_release(ftdmchan, 0); if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); + sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); } } else { sngisdn_snd_disconnect(ftdmchan); @@ -838,6 +850,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) /* IMPLEMENT ME */ } break; + case FTDM_CHANNEL_STATE_RESET: + { + sngisdn_snd_restart(ftdmchan); + } + break; default: { ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "unsupported sngisdn_rcvd state %s\n", ftdm_channel_state2str(ftdmchan->state)); @@ -862,10 +879,6 @@ static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg) ftdm_status_t status = FTDM_FAIL; switch (sigmsg->event_id) { - case FTDM_SIGEVENT_RESTART: - /* TODO: Send a channel restart here */ - /* Implement me */ - break; case FTDM_SIGEVENT_FACILITY: sngisdn_snd_fac_req(ftdmchan); break; @@ -1072,7 +1085,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || span->trunk_type == FTDM_TRUNK_BRI) { - sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING); + sngisdn_set_span_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING); } /* Initialize scheduling context */ @@ -1167,6 +1180,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) goto done; } + /* TODO: Move functions to table + function pointers */ if (!strcasecmp(argv[0], "trace")) { char *trace_opt; @@ -1210,7 +1224,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) } sngisdn_print_phy_stats(stream, span); } - + if (!strcasecmp(argv[0], "show_spans")) { ftdm_span_t *span = NULL; if (argc == 2) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index f15eff9200..4662d4e9bb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -352,8 +352,11 @@ void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info); ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data); ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data); +ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail); +ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail); +void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status); +void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status); -ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail); ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); @@ -374,6 +377,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan); void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan); void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan); void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan); +void sngisdn_snd_restart(ftdm_channel_t *ftdmchan); void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len); void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event); @@ -453,6 +457,9 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt); ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad); ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind); +ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap); +ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId); +ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd); ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len); @@ -482,7 +489,6 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis void handle_sng_log(uint8_t level, char *fmt,...); -void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status); void sngisdn_delayed_setup(void* p_sngisdn_info); void sngisdn_delayed_release(void* p_sngisdn_info); void sngisdn_delayed_connect(void* p_sngisdn_info); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index fb65d20cab..003227016d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -33,7 +33,8 @@ */ #include "ftmod_sangoma_isdn.h" -ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn); +static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn); +static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan); /* Remote side transmit a SETUP */ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) @@ -232,6 +233,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); } break; + case FTDM_CHANNEL_STATE_RESET: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); break; @@ -285,6 +289,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_HANGUP: /* Race condition, we just hung up the call - ignore this message */ break; + case FTDM_CHANNEL_STATE_RESET: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); @@ -301,6 +308,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: /* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */ break; + case FTDM_CHANNEL_STATE_RESET: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); @@ -375,6 +385,9 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) /* We are already in progress media, we can't go to any higher state except up */ /* Do nothing */ break; + case FTDM_CHANNEL_STATE_RESET: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); @@ -414,6 +427,9 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_UP: ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val); break; + case FTDM_CHANNEL_STATE_RESET: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId); break; @@ -531,7 +547,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_DIALING: /* Remote side rejected our SETUP message on outbound call */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { - sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); + sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); } /* fall-through */ case FTDM_CHANNEL_STATE_PROCEED: @@ -581,6 +597,9 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) /* set abort flag so that we do not transmit another release complete on this channel once FS core is done */ } break; + case FTDM_CHANNEL_STATE_RESET: + /* User initiated reset, so they do not know about this call */ + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); @@ -1050,18 +1069,91 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event) return; } +static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan) +{ + switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_RESET: + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + break; + case FTDM_CHANNEL_STATE_DOWN: + /* Do nothing */ + break; + default: + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n", + ftdm_channel_state2str(ftdmchan->state)); + } + + return; +} + + void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) { int16_t suId = sngisdn_event->suId; int16_t dChan = sngisdn_event->dChan; uint8_t ces = sngisdn_event->ces; uint8_t evntType = sngisdn_event->evntType; - - ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - - /* Function does not require any info from ssHlEvnt struct for now */ - /*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/ + uint8_t chan_no = 0; + Rst *rstEvnt = &sngisdn_event->event.rstEvnt; + sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[dChan].spans[1]; + if (!signal_data) { + ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId); + return; + } + + if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) { + ftdm_log(FTDM_LOG_CRIT, "Receved RESTART, but Restart Indicator IE not present\n"); + return; + } + + switch(rstEvnt->rstInd.rstClass.val) { + case IN_CL_INDCHAN: /* Indicated b-channel */ + if (rstEvnt->chanId.eh.pres) { + if (rstEvnt->chanId.intType.val == IN_IT_BASIC) { + if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) { + chan_no = rstEvnt->chanId.infoChanSel.val; + } + } else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) { + if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) { + chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0]; + } + } + } + if (!chan_no) { + ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n"); + return; + } + break; + case IN_CL_SNGINT: /* Single interface */ + case IN_CL_ALLINT: /* All interfaces */ + /* In case restart class indicates all interfaces, we will duplicate + this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm, + so treat it as a single interface anyway */ + break; + default: + ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val); + return; + } + + if (chan_no) { /* For a single channel */ + if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) { + ftdm_log(FTDM_LOG_CRIT, "Received RESTART on invalid channel:%d\n", chan_no); + } else { + ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no); + sngisdn_process_restart_confirm(ftdmchan); + } + } else { /* for all channels */ + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + + chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + sngisdn_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr)); + } + ftdm_iterator_free(chaniter); + } + ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; @@ -1090,7 +1182,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event) return; } -ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn) +static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 297c59c3b7..bb04f887ab 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -51,72 +51,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex); memset(&conEvnt, 0, sizeof(conEvnt)); - - conEvnt.bearCap[0].eh.pres = PRSNT_NODEF; - conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF; - conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability); - - conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF; - conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT; - conEvnt.bearCap[0].infoTranRate0.pres = PRSNT_NODEF; - conEvnt.bearCap[0].infoTranRate0.val = IN_ITR_64KBIT; - conEvnt.bearCap[0].tranMode.pres = PRSNT_NODEF; - conEvnt.bearCap[0].tranMode.val = IN_TM_CIRCUIT; - - conEvnt.chanId.eh.pres = PRSNT_NODEF; - conEvnt.chanId.prefExc.pres = PRSNT_NODEF; - conEvnt.chanId.prefExc.val = IN_PE_EXCLSVE; - conEvnt.chanId.dChanInd.pres = PRSNT_NODEF; - conEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN; - conEvnt.chanId.intIdentPres.pres = PRSNT_NODEF; - conEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT; - conEvnt.chanId.intIdent.pres = NOTPRSNT; - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI || - ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - /* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it. - Check with Trillium if this ever causes calls to fail in the field */ - - /* BRI only params */ - conEvnt.chanId.intType.pres = PRSNT_NODEF; - conEvnt.chanId.intType.val = IN_IT_BASIC; - conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id; - } else { - /* PRI only params */ - conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF; - conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN && - conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { - - /* We are bridging a call from T1 */ - conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; - - } else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { - - /* We are bridging a call from E1 */ - conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; - } - - conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF; - conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT; - - conEvnt.chanId.intType.pres = PRSNT_NODEF; - conEvnt.chanId.intType.val = IN_IT_OTHER; - conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - conEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN; - conEvnt.chanId.chanMapType.pres = PRSNT_NODEF; - conEvnt.chanId.chanMapType.val = IN_CMT_BCHAN; - conEvnt.chanId.nmbMap.pres = PRSNT_NODEF; - conEvnt.chanId.nmbMap.val = IN_NM_CHNNMB; - conEvnt.chanId.codeStand1.pres = PRSNT_NODEF; - conEvnt.chanId.codeStand1.val = IN_CSTD_CCITT; - conEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF; - conEvnt.chanId.chanNmbSlotMap.len = 1; - conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; - } - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { conEvnt.sndCmplt.eh.pres = PRSNT_NODEF; } @@ -126,6 +60,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) } ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits); + set_chan_id_ie(ftdmchan, &conEvnt.chanId); + set_bear_cap_ie(ftdmchan, &conEvnt.bearCap[0]); set_called_num(ftdmchan, &conEvnt.cdPtyNmb); set_calling_num(ftdmchan, &conEvnt.cgPtyNmb); set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2); @@ -161,38 +97,7 @@ void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan) memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - cnStEvnt.chanId.eh.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE; - cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF; - cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN; - cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF; - cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT; - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI || - ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - - /* BRI only params */ - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_BASIC; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id; - } else { - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_OTHER; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN; - cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN; - cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB; - cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF; - cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT; - cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanNmbSlotMap.len = 1; - cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; - } ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -221,38 +126,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan) memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - cnStEvnt.chanId.eh.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE; - cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF; - cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN; - cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF; - cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT; - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI || - ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - - /* BRI only params */ - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_BASIC; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id; - } else { - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_OTHER; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN; - cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN; - cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB; - cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF; - cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT; - cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanNmbSlotMap.len = 1; - cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; - } - + set_chan_id_ie(ftdmchan, &cnStEvnt.chanId); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -277,41 +151,11 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_i } memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - cnStEvnt.chanId.eh.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE; - cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF; - cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN; - cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF; - cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT; - - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI || - ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - - /* BRI only params */ - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_BASIC; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id; - } else { - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_OTHER; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN; - cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN; - cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB; - cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF; - cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT; - cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanNmbSlotMap.len = 1; - cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; - } + set_chan_id_ie(ftdmchan, &cnStEvnt.chanId); set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); @@ -397,39 +241,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) } memset(&cnStEvnt, 0, sizeof(cnStEvnt)); - - cnStEvnt.chanId.eh.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF; - cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE; - cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF; - cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN; - cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF; - cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT; - if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI || - ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - - /* BRI only params */ - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_BASIC; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id; - } else { - cnStEvnt.chanId.intType.pres = PRSNT_NODEF; - cnStEvnt.chanId.intType.val = IN_IT_OTHER; - cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF; - cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN; - cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN; - cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB; - cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF; - cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT; - cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF; - cnStEvnt.chanId.chanNmbSlotMap.len = 1; - cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; - } - + set_chan_id_ie(ftdmchan, &cnStEvnt.chanId); set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind); set_facility_ie(ftdmchan, &cnStEvnt.facilityStr); ftdm_call_clear_data(&ftdmchan->caller_data); @@ -563,6 +376,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan) } return; } + void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) { RelEvnt relEvnt; @@ -618,6 +432,24 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) return; } +void sngisdn_snd_restart(ftdm_channel_t *ftdmchan) +{ + Rst rstEvnt; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + memset(&rstEvnt, 0, sizeof(rstEvnt)); + + set_chan_id_ie(ftdmchan, &rstEvnt.chanId); + set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd); + + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, CES_MNGMNT); + + if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, signal_data->dchan_id, CES_MNGMNT, IN_SND_RST)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n"); + } + return; +} + /* We received an incoming frame on the d-channel, send data to the stack */ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index af180d1f7c..4b04fb065e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -630,8 +630,9 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces ISDN_FUNC_TRACE_ENTER(__FUNCTION__); + ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); - + /* Enqueue the event to each span within the dChan */ for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; @@ -725,14 +726,25 @@ void sngisdn_rcv_q931_ind(InMngmt *status) ftdmspan = signal_data->ftdm_span; if (status->t.usta.alarm.event == LCM_EVENT_UP) { + uint32_t chan_no = status->t.usta.evntParm[2]; ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", status->t.usta.suId, DECODE_LCM_CATEGORY(status->t.usta.alarm.category), DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); - sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); + + if (chan_no) { + ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no); + if (ftdmchan) { + sngisdn_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP); + sngisdn_set_chan_avail_rate(ftdmchan, SNGISDN_AVAIL_UP); + } else { + ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no); + } + } else { + sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); + sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); + } } else { ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", status->t.usta.suId, @@ -741,7 +753,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status) DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); - sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); + sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 76d11d6d34..28768a1f09 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -136,19 +136,25 @@ ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn return FTDM_SUCCESS; } -ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) +ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail) { - if (span->trunk_type == FTDM_TRUNK_BRI || - span->trunk_type == FTDM_TRUNK_BRI_PTMP) { + if (FTDM_SPAN_IS_BRI(chan->span)) { + ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); + chan->availability_rate = avail; + } + return FTDM_SUCCESS; +} +ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) +{ + if (FTDM_SPAN_IS_BRI(span)) { ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *curr = NULL; - chaniter = ftdm_span_get_chan_iterator(span, NULL); for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); - ((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail; + sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail); } ftdm_iterator_free(chaniter); } @@ -676,7 +682,6 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) return FTDM_SUCCESS; } - ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr) { ftdm_status_t status; @@ -789,6 +794,93 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s return FTDM_SUCCESS; } +ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId) +{ + if (!ftdmchan) { + return FTDM_SUCCESS; + } + chanId->eh.pres = PRSNT_NODEF; + chanId->prefExc.pres = PRSNT_NODEF; + chanId->prefExc.val = IN_PE_EXCLSVE; + chanId->dChanInd.pres = PRSNT_NODEF; + chanId->dChanInd.val = IN_DSI_NOTDCHAN; + chanId->intIdentPres.pres = PRSNT_NODEF; + chanId->intIdentPres.val = IN_IIP_IMPLICIT; + + if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI || + ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) { + + /* BRI only params */ + chanId->intType.pres = PRSNT_NODEF; + chanId->intType.val = IN_IT_BASIC; + chanId->infoChanSel.pres = PRSNT_NODEF; + chanId->infoChanSel.val = ftdmchan->physical_chan_id; + } else { + chanId->intType.pres = PRSNT_NODEF; + chanId->intType.val = IN_IT_OTHER; + chanId->infoChanSel.pres = PRSNT_NODEF; + chanId->infoChanSel.val = IN_ICS_B1CHAN; + chanId->chanMapType.pres = PRSNT_NODEF; + chanId->chanMapType.val = IN_CMT_BCHAN; + chanId->nmbMap.pres = PRSNT_NODEF; + chanId->nmbMap.val = IN_NM_CHNNMB; + chanId->codeStand1.pres = PRSNT_NODEF; + chanId->codeStand1.val = IN_CSTD_CCITT; + chanId->chanNmbSlotMap.pres = PRSNT_NODEF; + chanId->chanNmbSlotMap.len = 1; + chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; + } + return FTDM_SUCCESS; +} + +ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + bearCap->eh.pres = PRSNT_NODEF; + bearCap->infoTranCap.pres = PRSNT_NODEF; + bearCap->infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability); + + bearCap->codeStand0.pres = PRSNT_NODEF; + bearCap->codeStand0.val = IN_CSTD_CCITT; + bearCap->infoTranRate0.pres = PRSNT_NODEF; + bearCap->infoTranRate0.val = IN_ITR_64KBIT; + bearCap->tranMode.pres = PRSNT_NODEF; + bearCap->tranMode.val = IN_TM_CIRCUIT; + + if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) { + /* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it. + Check with Trillium if this ever causes calls to fail in the field */ + + /* PRI only params */ + bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; + bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); + + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN && + bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { + + /* We are bridging a call from T1 */ + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; + + } else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { + + /* We are bridging a call from E1 */ + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; + } + + bearCap->lyr1Ident.pres = PRSNT_NODEF; + bearCap->lyr1Ident.val = IN_L1_IDENT; + } + return FTDM_SUCCESS; +} + +ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd) +{ + rstInd->eh.pres = PRSNT_NODEF; + rstInd->rstClass.pres = PRSNT_NODEF; + rstInd->rstClass.val = IN_CL_INDCHAN; + return FTDM_SUCCESS; +} void sngisdn_t3_timeout(void* p_sngisdn_info) { diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index cc32d66bdd..a3cddadb81 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -702,6 +702,14 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char /*! \brief Hangup the call with cause recording the source code point where it was called (see ftdm_channel_call_hangup_with_cause for an easy to use macro) */ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t); +/*! \brief Reset the channel */ +#define ftdm_channel_reset(ftdmchan) _ftdm_channel_reset(__FILE__, __FUNCTION__, __LINE__, (ftdmchan)) + +/*! \brief Reset the channel (see _ftdm_channel_reset for an easy to use macro) + * \note if there was a call on this channel, call will be cleared without any notifications to the user + */ +FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan); + /*! \brief Put a call on hold (if supported by the signaling stack) */ #define ftdm_channel_call_hold(ftdmchan) _ftdm_channel_call_hold(__FILE__, __FUNCTION__, __LINE__, (ftdmchan)) @@ -741,6 +749,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa /*! \brief Get span signaling status (ie: whether protocol layer is up or down) */ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status); + /*! * \brief Set user private data in the channel * diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index deabafd537..9222da3a42 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -599,7 +599,6 @@ FT_DECLARE(void) ftdm_channel_rotate_tokens(ftdm_channel_t *ftdmchan); FT_DECLARE(int) ftdm_load_module(const char *name); FT_DECLARE(int) ftdm_load_module_assume(const char *name); FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap); -FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan); FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void); FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan); diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 313044abc4..f03c060e5a 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -228,12 +228,13 @@ typedef enum { FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_IN_LOOP, + FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_INVALID } ftdm_channel_state_t; #define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \ "RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \ "RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \ - "HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID" + "HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID" FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t) typedef enum { From 6c6eab8c13d2d7dddcd078a25f8d64bf94cfa910 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 14 Dec 2010 12:00:29 -0600 Subject: [PATCH 048/244] Do not set nat mode when the device's network_ip is within the acl also so if your FS is behind nat and your phone is too then it will still make the right decisions --- src/mod/endpoints/mod_sofia/sofia.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 591cd7f4aa..d429f59672 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6267,6 +6267,13 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ for (x = 0; x < profile->nat_acl_count; x++) { last_acl = profile->nat_acl[x]; if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) { + /* override the decision to say this is nat because the network_ip is within the acl too */ + if ((ok = switch_check_network_list_ip(network_ip, last_acl))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Endpoint is already inside nat with us.\n"); + ok = 0; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Decision stands they are behind nat.\n"); + } break; } } From 1d668e25ab8bfbf92bdaebf11a2b756f22895b33 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 14 Dec 2010 12:43:51 -0600 Subject: [PATCH 049/244] hrm --- src/mod/endpoints/mod_sofia/sofia.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index d429f59672..f2a555e946 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6267,7 +6267,21 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ for (x = 0; x < profile->nat_acl_count; x++) { last_acl = profile->nat_acl[x]; if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) { - /* override the decision to say this is nat because the network_ip is within the acl too */ + /* NAT mode double check logic and examples. + + Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point + is most likely behind nat with us so we need to veto that decision to turn on nat processing. + + Example 2: the contact_host is 192.168.1.100 and the network_ip is 192.0.2.100 which is a public internet ip + the remote endpoint is likely behind a remote nat traversing the public internet. + + This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net + in cases where we don't really need to be doing this. + + Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind + remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process. + + */ if ((ok = switch_check_network_list_ip(network_ip, last_acl))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Endpoint is already inside nat with us.\n"); ok = 0; From 56515c3a643eda32d8d527a215d4934e521e5e07 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 14 Dec 2010 16:04:25 -0500 Subject: [PATCH 050/244] Minor change to allow skip states --- libs/freetdm/src/ftdm_io.c | 16 +++++++++------- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 9 +++------ .../ftmod_sangoma_isdn_stack_hndl.c | 7 +++++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index deeb578c81..4bd0fdd33e 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2379,14 +2379,16 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS); ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA); } else { - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); - } + if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) { + if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); + } - /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n"); - goto done; + /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ + if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n"); + goto done; + } } ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 49e16ea12c..f8867d5fcf 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -704,12 +704,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) sigev.event_id = FTDM_SIGEVENT_PROGRESS; ftdm_span_send_signal(ftdmchan->span, &sigev); } else { - /* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */ - if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) { - /* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */ - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; - sngisdn_snd_progress(ftdmchan, prog_ind); - } + /* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */ + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; + sngisdn_snd_progress(ftdmchan, prog_ind); } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 003227016d..bdd371704d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -493,6 +493,9 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event) /* This is a race condition. We just sent a DISCONNECT, on this channel */ /* Do nothing */ break; + case FTDM_CHANNEL_STATE_RESET: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); @@ -598,7 +601,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) } break; case FTDM_CHANNEL_STATE_RESET: - /* User initiated reset, so they do not know about this call */ + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n"); break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n", @@ -1103,7 +1106,7 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) } if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) { - ftdm_log(FTDM_LOG_CRIT, "Receved RESTART, but Restart Indicator IE not present\n"); + ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n"); return; } From c6417fa2b389364f83e6bad6fdd4ff9f059b589e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 14 Dec 2010 16:50:10 -0500 Subject: [PATCH 051/244] freetdm: ftmod_r2 - disable MF dump for forward calls on call accepted --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 9206493ad2..6bec6b0cf7 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -585,6 +585,8 @@ static void dump_mf(openr2_chan_t *r2chan) static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode) { ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); + ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Call accepted\n"); clear_accept_pending(ftdmchan); @@ -607,6 +609,11 @@ static void ftdm_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t m return; } } else { + /* nothing went wrong during call setup, MF has ended, we can and must disable the MF dump */ + if (r2data->mf_dump_size) { + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); + } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } } From 1c01144c207d7462e93a6955a5cf129373e84df3 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 14 Dec 2010 16:55:40 -0500 Subject: [PATCH 052/244] freetdm: open all media dumps as binary. Fixes Windows corrupted cores. --- libs/freetdm/src/ftdm_io.c | 8 +++++--- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 4 ++-- libs/freetdm/src/include/ftdm_declare.h | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index e13d0196b8..2fa795344a 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2715,7 +2715,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co close(ftdmchan->fds[FTDM_READ_TRACE_INDEX]); ftdmchan->fds[FTDM_READ_TRACE_INDEX] = -1; } - if ((ftdmchan->fds[FTDM_READ_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) { + if ((ftdmchan->fds[FTDM_READ_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC + | FTDM_O_BINARY, S_IRUSR | S_IWUSR)) > -1) { ftdm_log(FTDM_LOG_DEBUG, "Tracing channel %u:%u input to [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, path); GOTO_STATUS(done, FTDM_SUCCESS); } @@ -2731,7 +2732,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co close(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX]); ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = -1; } - if ((ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) { + if ((ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] = open(path, O_WRONLY | O_CREAT | O_TRUNC + | FTDM_O_BINARY, S_IRUSR | S_IWUSR)) > -1) { ftdm_log(FTDM_LOG_DEBUG, "Tracing channel %u:%u output to [%s]\n", ftdmchan->span_id, ftdmchan->chan_id, path); GOTO_STATUS(done, FTDM_SUCCESS); } @@ -3376,7 +3378,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons ftdmchan->span_id, ftdmchan->chan_id, currtime.tm_year-100, currtime.tm_mon+1, currtime.tm_mday, currtime.tm_hour, currtime.tm_min, currtime.tm_sec, ftdmchan->native_codec == FTDM_CODEC_ULAW ? "ulaw" : ftdmchan->native_codec == FTDM_CODEC_ALAW ? "alaw" : "sln"); - ftdmchan->dtmfdbg.file = fopen(dfile, "w"); + ftdmchan->dtmfdbg.file = fopen(dfile, "wb"); if (!ftdmchan->dtmfdbg.file) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "failed to open debug dtmf file %s\n", dfile); } else { diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 6bec6b0cf7..1549833571 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -568,14 +568,14 @@ static void dump_mf(openr2_chan_t *r2chan) ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in prefix %s\n", logname); snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.input.alaw" : "%s/s%dc%d.input.alaw", logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); - f = fopen(dfile, "w"); + f = fopen(dfile, "wb"); ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO input in file %s\n", dfile); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_INPUT, f); fclose(f); snprintf(dfile, sizeof(dfile), logname ? "%s.s%dc%d.output.alaw" : "%s/s%dc%d.output.alaw", logname ? logname : r2data->logdir, ftdmchan->span_id, ftdmchan->chan_id); - f = fopen(dfile, "w"); + f = fopen(dfile, "wb"); ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dumping IO output in file %s\n", dfile); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DUMP_OUTPUT, f); fclose(f); diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index 4aba703f28..5c57e01a70 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -158,12 +158,14 @@ typedef __int64 int64_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef __int8 int8_t; +#define FTDM_O_BINARY O_BINARY #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 #else #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL #endif /* _MSC_VER */ #else /* __WINDOWS__ */ +#define FTDM_O_BINARY 0 #define FTDM_INVALID_SOCKET -1 typedef int ftdm_socket_t; #include From eafd7e5e15b2a5b6b28d75e107a1490e60e64563 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 14 Dec 2010 16:55:31 -0600 Subject: [PATCH 053/244] skypopen: tweaking the OSS audio driver --- src/mod/endpoints/mod_skypopen/oss/Makefile | 6 +- src/mod/endpoints/mod_skypopen/oss/main.c | 190 +++++++++--------- .../mod_skypopen/oss/{scull.h => skypopen.h} | 40 ++-- 3 files changed, 110 insertions(+), 126 deletions(-) rename src/mod/endpoints/mod_skypopen/oss/{scull.h => skypopen.h} (55%) diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile index 465db533e4..8df20f68c5 100644 --- a/src/mod/endpoints/mod_skypopen/oss/Makefile +++ b/src/mod/endpoints/mod_skypopen/oss/Makefile @@ -4,7 +4,7 @@ # Add your debugging flag (or not) to CFLAGS ifeq ($(DEBUG),y) - DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines + DEBFLAGS = -O -g -DSKYPOPEN_DEBUG # "-O" is needed to expand inlines else DEBFLAGS = -O2 -Wall endif @@ -15,9 +15,9 @@ EXTRA_CFLAGS += -I$(LDDINC) ifneq ($(KERNELRELEASE),) # call from kernel build system -scull-objs := main.o +skypopen-objs := main.o -obj-m := scull.o +obj-m := skypopen.o else diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 8da9c549ac..4fd959f44a 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -1,5 +1,5 @@ /* - * main.c -- the bare scull char module + * main.c -- the bare skypopen char module * * Copyright (C) 2010 Giovanni Maruzzelli * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet @@ -41,33 +41,32 @@ #include #include -#include "scull.h" /* local definitions */ +#include "skypopen.h" /* local definitions */ /* * Our parameters which can be set at load time. */ -int scull_major = SCULL_MAJOR; -int scull_minor = 3; -int scull_nr_devs = SCULL_NR_DEVS; /* number of bare scull devices */ +int skypopen_major = SKYPOPEN_MAJOR; +int skypopen_minor = 3; +int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */ -module_param(scull_major, int, S_IRUGO); -module_param(scull_minor, int, S_IRUGO); -module_param(scull_nr_devs, int, S_IRUGO); +module_param(skypopen_major, int, S_IRUGO); +module_param(skypopen_minor, int, S_IRUGO); +module_param(skypopen_nr_devs, int, S_IRUGO); -MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Heavy modified by: Giovanni Maruzzelli"); +MODULE_AUTHOR("Original: Alessandro Rubini, Jonathan Corbet. Modified by: Giovanni Maruzzelli for FreeSWITCH skypopen"); MODULE_LICENSE("Dual BSD/GPL"); -static struct scull_dev *scull_devices; /* allocated in scull_init_module */ +static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */ #define GIOVA_BLK 1920 #define GIOVA_SLEEP 20 void my_timer_callback_inq( unsigned long data ) { - struct scull_dev *dev = (void *)data; + struct skypopen_dev *dev = (void *)data; - //dev->readable=1; wake_up_interruptible(&dev->inq); mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); @@ -75,83 +74,83 @@ void my_timer_callback_inq( unsigned long data ) void my_timer_callback_outq( unsigned long data ) { - struct scull_dev *dev = (void *)data; + struct skypopen_dev *dev = (void *)data; - //dev->writable=1; wake_up_interruptible(&dev->outq); mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); } /* The clone-specific data structure includes a key field */ -struct scull_listitem { - struct scull_dev device; +struct skypopen_listitem { + struct skypopen_dev device; dev_t key; struct list_head list; }; /* The list of devices, and a lock to protect it */ -static LIST_HEAD(scull_c_list); -static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(skypopen_c_list); +static spinlock_t skypopen_c_lock = SPIN_LOCK_UNLOCKED; /* Look for a device or create one if missing */ -static struct scull_dev *scull_c_lookfor_device(dev_t key) +static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) { - struct scull_listitem *lptr; + struct skypopen_listitem *lptr; - list_for_each_entry(lptr, &scull_c_list, list) { + list_for_each_entry(lptr, &skypopen_c_list, list) { if (lptr->key == key) return &(lptr->device); } /* not found */ - lptr = kmalloc(sizeof(struct scull_listitem), GFP_KERNEL); + lptr = kmalloc(sizeof(struct skypopen_listitem), GFP_KERNEL); if (!lptr) return NULL; /* initialize the device */ - memset(lptr, 0, sizeof(struct scull_listitem)); + memset(lptr, 0, sizeof(struct skypopen_listitem)); lptr->key = key; - init_waitqueue_head(&lptr->device.inq); - init_waitqueue_head(&lptr->device.outq); - printk(" Timer installing\n"); - setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); - setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); - printk( "Starting timer to fire in %dms (%ld)\n", GIOVA_SLEEP, jiffies ); - mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); - mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + init_waitqueue_head(&lptr->device.inq); + init_waitqueue_head(&lptr->device.outq); + setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); + setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); + printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); + mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); + mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + /* place it in the list */ - list_add(&lptr->list, &scull_c_list); + list_add(&lptr->list, &skypopen_c_list); return &(lptr->device); } -static int scull_c_open(struct inode *inode, struct file *filp) + +/* + * Open and close + */ +static int skypopen_c_open(struct inode *inode, struct file *filp) { - struct scull_dev *dev; + struct skypopen_dev *dev; dev_t key; - if (!current->pid) { - printk("Process \"%s\" has no pid\n", current->comm); - return -EINVAL; - } key = current->pid; - /* look for a scullc device in the list */ - spin_lock(&scull_c_lock); - dev = scull_c_lookfor_device(key); - spin_unlock(&scull_c_lock); + /* look for a skypopenc device in the list */ + spin_lock(&skypopen_c_lock); + dev = skypopen_c_lookfor_device(key); + spin_unlock(&skypopen_c_lock); if (!dev) return -ENOMEM; - /* then, everything else is copied from the bare scull device */ + /* then, everything else is copied from the bare skypopen device */ filp->private_data = dev; return 0; /* success */ } -static int scull_c_release(struct inode *inode, struct file *filp) +static int skypopen_c_release(struct inode *inode, struct file *filp) { /* * Nothing to do, because the device is persistent. @@ -163,39 +162,29 @@ static int scull_c_release(struct inode *inode, struct file *filp) /*************************************************************/ -/* - * Open and close - */ -ssize_t scull_read(struct file *filp, char __user *buf, size_t count, +ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { - struct scull_dev *dev = filp->private_data; - + struct skypopen_dev *dev = filp->private_data; DEFINE_WAIT(wait); + prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->inq, &wait); - //memset(buf, 255, count); - - //wait_event_interruptible(dev->inq, dev->readable); - //dev->readable=0; return count; } -ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, +ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { - struct scull_dev *dev = filp->private_data; + struct skypopen_dev *dev = filp->private_data; DEFINE_WAIT(wait); + prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->outq, &wait); - - //wait_event_interruptible(dev->outq, dev->writable); - //dev->writable=0; - return count; } @@ -203,7 +192,7 @@ ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, * The ioctl() implementation */ -int scull_ioctl(struct inode *inode, struct file *filp, +int skypopen_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; @@ -223,14 +212,14 @@ int scull_ioctl(struct inode *inode, struct file *filp, } -struct file_operations scull_fops = { +struct file_operations skypopen_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .read = scull_read, - .write = scull_write, - .ioctl = scull_ioctl, - .open = scull_c_open, - .release = scull_c_release, + .read = skypopen_read, + .write = skypopen_write, + .ioctl = skypopen_ioctl, + .open = skypopen_c_open, + .release = skypopen_c_release, }; /* @@ -243,34 +232,34 @@ struct file_operations scull_fops = { * have not been initialized */ -void scull_cleanup_module(void) +void skypopen_cleanup_module(void) { int i; int ret; - struct scull_listitem *lptr, *next; - dev_t devno = MKDEV(scull_major, scull_minor); + struct skypopen_listitem *lptr, *next; + dev_t devno = MKDEV(skypopen_major, skypopen_minor); /* Get rid of our char dev entries */ - if (scull_devices) { - for (i = 0; i < scull_nr_devs; i++) { - cdev_del(&scull_devices[i].cdev); + if (skypopen_devices) { + for (i = 0; i < skypopen_nr_devs; i++) { + cdev_del(&skypopen_devices[i].cdev); } - kfree(scull_devices); + kfree(skypopen_devices); } /* And all the cloned devices */ - list_for_each_entry_safe(lptr, next, &scull_c_list, list) { + list_for_each_entry_safe(lptr, next, &skypopen_c_list, list) { ret= del_timer( &lptr->device.timer_inq ); - if (ret) printk("The inq timer was still in use...\n"); + //printk( "Stopped skypopen OSS driver read timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); ret= del_timer( &lptr->device.timer_outq ); - if (ret) printk("The outq timer was still in use...\n"); + //printk( "Stopped skypopen OSS driver write timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); list_del(&lptr->list); kfree(lptr); } - printk("Timer uninstalling\n"); /* cleanup_module is never called if registering failed */ - unregister_chrdev_region(devno, scull_nr_devs); + unregister_chrdev_region(devno, skypopen_nr_devs); + printk("skypopen OSS driver unloaded\n"); } @@ -278,40 +267,41 @@ void scull_cleanup_module(void) /* * Set up the char_dev structure for this device. */ -static void scull_setup_cdev(struct scull_dev *dev, int index) +static void skypopen_setup_cdev(struct skypopen_dev *dev, int index) { - int err, devno = MKDEV(scull_major, scull_minor + index); + int err, devno = MKDEV(skypopen_major, skypopen_minor + index); - cdev_init(&dev->cdev, &scull_fops); + cdev_init(&dev->cdev, &skypopen_fops); dev->cdev.owner = THIS_MODULE; - dev->cdev.ops = &scull_fops; + dev->cdev.ops = &skypopen_fops; err = cdev_add (&dev->cdev, devno, 1); /* Fail gracefully if need be */ if (err) - printk(KERN_NOTICE "Error %d adding scull%d", err, index); + printk(KERN_NOTICE "Error %d adding skypopen%d", err, index); } -int scull_init_module(void) +int skypopen_init_module(void) { int result, i; dev_t dev = 0; + printk("skypopen OSS driver loading (www.freeswitch.org)\n"); /* * Get a range of minor numbers to work with, asking for a dynamic * major unless directed otherwise at load time. */ - if (scull_major) { - dev = MKDEV(scull_major, scull_minor); - result = register_chrdev_region(dev, scull_nr_devs, "dsp"); + if (skypopen_major) { + dev = MKDEV(skypopen_major, skypopen_minor); + result = register_chrdev_region(dev, skypopen_nr_devs, "dsp"); } else { - result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, + result = alloc_chrdev_region(&dev, skypopen_minor, skypopen_nr_devs, "dsp"); - scull_major = MAJOR(dev); + skypopen_major = MAJOR(dev); } if (result < 0) { - printk(KERN_WARNING "scull: can't get major %d\n", scull_major); + printk(KERN_WARNING "skypopen OSS driver: can't get major %d\n", skypopen_major); return result; } @@ -319,26 +309,26 @@ int scull_init_module(void) * allocate the devices -- we can't have them static, as the number * can be specified at load time */ - scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL); - if (!scull_devices) { + skypopen_devices = kmalloc(skypopen_nr_devs * sizeof(struct skypopen_dev), GFP_KERNEL); + if (!skypopen_devices) { result = -ENOMEM; goto fail; /* Make this more graceful */ } - memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev)); + memset(skypopen_devices, 0, skypopen_nr_devs * sizeof(struct skypopen_dev)); /* Initialize each device. */ - for (i = 0; i < scull_nr_devs; i++) { - scull_setup_cdev(&scull_devices[i], i); + for (i = 0; i < skypopen_nr_devs; i++) { + skypopen_setup_cdev(&skypopen_devices[i], i); } /* At this point call the init function for any friend device */ - dev = MKDEV(scull_major, scull_minor + scull_nr_devs); + dev = MKDEV(skypopen_major, skypopen_minor + skypopen_nr_devs); return 0; /* succeed */ fail: - scull_cleanup_module(); + skypopen_cleanup_module(); return result; } -module_init(scull_init_module); -module_exit(scull_cleanup_module); +module_init(skypopen_init_module); +module_exit(skypopen_cleanup_module); diff --git a/src/mod/endpoints/mod_skypopen/oss/scull.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h similarity index 55% rename from src/mod/endpoints/mod_skypopen/oss/scull.h rename to src/mod/endpoints/mod_skypopen/oss/skypopen.h index 565b8b38b7..5469048c04 100644 --- a/src/mod/endpoints/mod_skypopen/oss/scull.h +++ b/src/mod/endpoints/mod_skypopen/oss/skypopen.h @@ -1,5 +1,5 @@ /* - * scull.h -- definitions for the char module + * skypopen.h -- definitions for the char module * * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet * Copyright (C) 2001 O'Reilly & Associates @@ -12,55 +12,49 @@ * by O'Reilly & Associates. No warranty is attached; * we cannot take responsibility for errors or fitness for use. * - * $Id: scull.h,v 1.15 2004/11/04 17:51:18 rubini Exp $ + * $Id: skypopen.h,v 1.15 2004/11/04 17:51:18 rubini Exp $ */ -#ifndef _SCULL_H_ -#define _SCULL_H_ +#ifndef _SKYPOPEN_H_ +#define _SKYPOPEN_H_ #include /* needed for the _IOW etc stuff used later */ -#ifndef SCULL_MAJOR -#define SCULL_MAJOR 14 /* dynamic major by default */ +#ifndef SKYPOPEN_MAJOR +#define SKYPOPEN_MAJOR 14 /* dynamic major by default */ #endif -#ifndef SCULL_NR_DEVS -#define SCULL_NR_DEVS 1 /* scull0 through scull3 */ +#ifndef SKYPOPEN_NR_DEVS +#define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */ #endif -struct scull_dev { +struct skypopen_dev { struct cdev cdev; /* Char device structure */ wait_queue_head_t inq; /* read and write queues */ wait_queue_head_t outq; /* read and write queues */ struct timer_list timer_inq; struct timer_list timer_outq; - int readable; - int writable; - //unsigned long read_howmany; - //unsigned long write_howmany; - //unsigned long read_sleeped_acc; - //unsigned long write_sleeped_acc; - //double read_delay; /* how much delay last time */ - //double write_delay; /* how much delay last time */ + int timer_inq_started; + int timer_outq_started; }; /* * The different configurable parameters */ -extern int scull_major; /* main.c */ -extern int scull_nr_devs; +extern int skypopen_major; /* main.c */ +extern int skypopen_nr_devs; /* * Prototypes for shared functions */ -ssize_t scull_read(struct file *filp, char __user *buf, size_t count, +ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); -ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, +ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); -int scull_ioctl(struct inode *inode, struct file *filp, +int skypopen_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -#endif /* _SCULL_H_ */ +#endif /* _SKYPOPEN_H_ */ From 2324c299177be42375610c4928a3b77e60a8bf10 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 14 Dec 2010 22:29:25 -0600 Subject: [PATCH 054/244] round two better code thanks mikej --- src/mod/endpoints/mod_sofia/sofia.c | 51 +++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f2a555e946..7e4e34f4ab 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6255,7 +6255,8 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (!is_nat && profile->nat_acl_count) { uint32_t x = 0; - int ok = 1; + int contact_private_ip = 1; + int network_private_ip = 0; char *last_acl = NULL; const char *contact_host = NULL; @@ -6264,35 +6265,37 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if (!zstr(contact_host)) { + /* NAT mode double check logic and examples. + + Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point + is most likely behind nat with us so we need to veto that decision to turn on nat processing. + + Example 2: the contact_host is 192.168.1.100 and the network_ip is 192.0.2.100 which is a public internet ip + the remote endpoint is likely behind a remote nat traversing the public internet. + + This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net + in cases where we don't really need to be doing this. + + Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind + remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process. + + */ + for (x = 0; x < profile->nat_acl_count; x++) { last_acl = profile->nat_acl[x]; - if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) { - /* NAT mode double check logic and examples. - - Example 1: the contact_host is 192.168.1.100 and the network_ip is also 192.168.1.100 the end point - is most likely behind nat with us so we need to veto that decision to turn on nat processing. - - Example 2: the contact_host is 192.168.1.100 and the network_ip is 192.0.2.100 which is a public internet ip - the remote endpoint is likely behind a remote nat traversing the public internet. - - This secondary check is here to double check the conclusion of nat settigs to ensure we don't set net - in cases where we don't really need to be doing this. - - Why would you want to do this? Well if your FreeSWITCH is behind nat and you want to talk to endpoints behind - remote NAT over the public internet in addition to endpoints behind nat with you. This simplifies that process. - - */ - if ((ok = switch_check_network_list_ip(network_ip, last_acl))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Endpoint is already inside nat with us.\n"); - ok = 0; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Decision stands they are behind nat.\n"); - } + if ((contact_private_ip = switch_check_network_list_ip(contact_host, last_acl))) { break; } } + if (contact_private_ip) { + for (x = 0; x < profile->nat_acl_count; x++) { + if ((network_private_ip = switch_check_network_list_ip(network_ip, profile->nat_acl[x]))) { + break; + } + } + } - if (ok) { + if (contact_private_ip && !network_private_ip) { is_nat = last_acl; } } From e9958c5b0c37b44ff4dd644245412a526ba6118f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 14 Dec 2010 23:46:26 -0600 Subject: [PATCH 055/244] more jb work, add debug command and logging (sorry jlenk if this breaks win32) --- src/include/switch_rtp.h | 2 ++ src/mod/endpoints/mod_sofia/mod_sofia.c | 11 +++++++ src/switch_ivr.c | 2 +- src/switch_rtp.c | 39 +++++++++++++++++++++---- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index e3e9f665a3..c48a40e6d1 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -234,6 +234,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * uint32_t max_queue_frames, uint32_t samples_per_packet, uint32_t samples_per_second); +SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name); + SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session); /*! diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index d4f8b1b45a..4a3c7c0479 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1339,6 +1339,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (msg->string_arg) { char *p; + const char *s; + + if (!strncasecmp(msg->string_arg, "debug:", 6)) { + s = msg->string_arg + 6; + if (s && !strcmp(s, "off")) { + s = NULL; + } + switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s); + goto end; + } + if ((len = atoi(msg->string_arg))) { qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000); diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 6e2aeaf637..5cd4d4d34f 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -2300,7 +2300,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 break; } - stfu_n_eat(jb, ts, 0, read_frame->payload, read_frame->data, read_frame->datalen); + stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen); ts += interval; if ((jb_frame = stfu_n_read_a_frame(jb))) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index b4f60fcd55..306e58a839 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -229,7 +229,7 @@ struct switch_rtp { uint32_t sync_packets; int rtcp_interval; switch_bool_t rtcp_fresh_frame; - + uint8_t checked_jb; #ifdef ENABLE_ZRTP zrtp_session_t *zrtp_session; zrtp_profile_t *zrtp_profile; @@ -1652,6 +1652,32 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t return SWITCH_STATUS_SUCCESS; } +static void jb_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) +{ + int ret; + char *data; + va_list ap; + + va_start(ap, fmt); + ret = stfu_vasprintf(&data, fmt, ap); + if (ret != -1) { + switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "%s", data); + free(data); + } + + //switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN, file, func, line, NULL, level, fmt, ap); + va_end(ap); +} + +SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name) +{ + + stfu_n_debug(rtp_session->jb, name); + stfu_global_set_logger(jb_logger); + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames, uint32_t max_queue_frames, @@ -1674,6 +1700,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * if (rtp_session->jb) { switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); stfu_n_call_me(rtp_session->jb, jb_callback, session); + return SWITCH_STATUS_SUCCESS; } @@ -2108,9 +2135,8 @@ static void do_flush(switch_rtp_t *rtp_session) flushed++; - if (rtp_session->jb) { + if (0 && rtp_session->jb) { stfu_n_eat(rtp_session->jb, ntohl(rtp_session->recv_msg.header.ts), - ntohs((uint16_t) rtp_session->recv_msg.header.seq), rtp_session->recv_msg.header.pt, rtp_session->recv_msg.body, bytes - rtp_header_len); } @@ -2177,7 +2203,6 @@ 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), - ntohs((uint16_t) rtp_session->recv_msg.header.seq), rtp_session->recv_msg.header.pt, rtp_session->recv_msg.body, *bytes - rtp_header_len); *bytes = 0; @@ -2195,9 +2220,9 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes = jb_frame->dlen + rtp_header_len; rtp_session->recv_msg.header.ts = htonl(jb_frame->ts); rtp_session->recv_msg.header.pt = jb_frame->pt; - rtp_session->recv_msg.header.seq = htons((uint16_t)jb_frame->seq); status = SWITCH_STATUS_SUCCESS; } + rtp_session->checked_jb++; } return status; @@ -2342,6 +2367,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ READ_INC(rtp_session); + rtp_session->checked_jb = 0; + while (switch_rtp_ready(rtp_session)) { int do_cng = 0; bytes = 0; @@ -2894,7 +2921,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; } From c4154633cca4b5b9764e192770d08c04f71a6970 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Wed, 15 Dec 2010 09:43:36 -0500 Subject: [PATCH 056/244] FS-2929 --- src/mod/applications/mod_spy/mod_spy.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c index 5093ad8f22..cb8981d264 100644 --- a/src/mod/applications/mod_spy/mod_spy.c +++ b/src/mod/applications/mod_spy/mod_spy.c @@ -131,7 +131,6 @@ SWITCH_STANDARD_API(dump_hash) static switch_status_t process_event(switch_event_t *event) { switch_core_session_t *session = NULL; - switch_channel_t *channel; char *username[3] = { 0 }; char *domain[3] = { 0 }; char key[512]; @@ -172,18 +171,19 @@ static switch_status_t process_event(switch_event_t *event) return SWITCH_STATUS_FALSE; } - session = switch_core_session_locate(uuid); - channel = switch_core_session_get_channel(session); + if ((session = switch_core_session_locate(uuid))) { + switch_channel_t *channel = switch_core_session_get_channel(session); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key); - my_uuid = switch_event_get_header(event, "Unique-ID"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key); + my_uuid = switch_event_get_header(event, "Unique-ID"); - switch_channel_set_variable(channel, "spy_uuid", my_uuid); + switch_channel_set_variable(channel, "spy_uuid", my_uuid); - switch_channel_set_state(channel, CS_EXCHANGE_MEDIA); - switch_channel_set_flag(channel, CF_BREAK); + switch_channel_set_state(channel, CS_EXCHANGE_MEDIA); + switch_channel_set_flag(channel, CF_BREAK); - switch_core_session_rwunlock(session); + switch_core_session_rwunlock(session); + } return SWITCH_STATUS_SUCCESS; } From 3085523f568cad7c9cc720d1899783fd33128bb9 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 15 Dec 2010 09:56:27 -0500 Subject: [PATCH 057/244] freetdm: define special size formatting that actually works on Linux and Windows --- libs/freetdm/src/ftdm_io.c | 19 ++++++++++--------- libs/freetdm/src/include/ftdm_declare.h | 2 ++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 2fa795344a..fca3adc9ad 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2801,10 +2801,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co GOTO_STATUS(done, FTDM_FAIL); } if (start_chan_io_dump(ftdmchan, &ftdmchan->rxdump, size) != FTDM_SUCCESS) { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump of size %zd\n", size); + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable input dump of size %"FTDM_SIZE_FMT"\n", size); GOTO_STATUS(done, FTDM_FAIL); } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %zd\n", size); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled input dump with size %"FTDM_SIZE_FMT"\n", size); GOTO_STATUS(done, FTDM_SUCCESS); } break; @@ -2816,7 +2816,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable input dump\n"); GOTO_STATUS(done, FTDM_SUCCESS); } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled input dump of size %zd\n", ftdmchan->rxdump.size); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled input dump of size %"FTDM_SIZE_FMT"\n", + ftdmchan->rxdump.size); stop_chan_io_dump(&ftdmchan->rxdump); GOTO_STATUS(done, FTDM_SUCCESS); } @@ -2834,7 +2835,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to enable output dump of size %d\n", size); GOTO_STATUS(done, FTDM_FAIL); } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %zd\n", size); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Enabled output dump with size %"FTDM_SIZE_FMT"\n", size); GOTO_STATUS(done, FTDM_SUCCESS); } break; @@ -2846,7 +2847,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No need to disable output dump\n"); GOTO_STATUS(done, FTDM_SUCCESS); } - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled output dump of size %zd\n", ftdmchan->rxdump.size); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Disabled output dump of size %"FTDM_SIZE_FMT"\n", ftdmchan->rxdump.size); stop_chan_io_dump(&ftdmchan->txdump); GOTO_STATUS(done, FTDM_SUCCESS); } @@ -2879,7 +2880,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co GOTO_STATUS(done, FTDM_FAIL); } dump_chan_io_to_file(ftdmchan, &ftdmchan->txdump, obj); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %zd to file %p\n", ftdmchan->txdump.size, obj); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %"FTDM_SIZE_FMT" to file %p\n", ftdmchan->txdump.size, obj); GOTO_STATUS(done, FTDM_SUCCESS); } break; @@ -3448,7 +3449,7 @@ static FIO_WRITE_FUNCTION(ftdm_raw_write) } if (ftdmchan->fds[FTDM_WRITE_TRACE_INDEX] > -1) { if ((write(ftdmchan->fds[FTDM_WRITE_TRACE_INDEX], data, dlen)) != dlen) { - ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %zd bytes\n", dlen); + ftdm_log(FTDM_LOG_WARNING, "Raw output trace failed to write all of the %"FTDM_SIZE_FMT" bytes\n", dlen); } } write_chan_io_dump(&ftdmchan->txdump, data, dlen); @@ -3461,7 +3462,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read) if (status == FTDM_SUCCESS && ftdmchan->fds[FTDM_READ_TRACE_INDEX] > -1) { ftdm_size_t dlen = *datalen; if ((ftdm_size_t)write(ftdmchan->fds[FTDM_READ_TRACE_INDEX], data, (int)dlen) != dlen) { - ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %zd bytes\n", dlen); + ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %"FTDM_SIZE_FMT" bytes\n", dlen); } } @@ -4702,7 +4703,7 @@ static ftdm_status_t load_config(void) len = strlen(val); if (len >= FTDM_MAX_NAME_STR_SZ) { len = FTDM_MAX_NAME_STR_SZ - 1; - ftdm_log(FTDM_LOG_WARNING, "Truncating group name %s to %zd length\n", val, len); + ftdm_log(FTDM_LOG_WARNING, "Truncating group name %s to %"FTDM_SIZE_FMT" length\n", val, len); } memcpy(chan_config.group_name, val, len); chan_config.group_name[len] = '\0'; diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index 5c57e01a70..bfec448253 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -159,6 +159,7 @@ typedef __int32 int32_t; typedef __int16 int16_t; typedef __int8 int8_t; #define FTDM_O_BINARY O_BINARY +#define FTDM_SIZE_FMT "Id" #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 #else @@ -166,6 +167,7 @@ typedef __int8 int8_t; #endif /* _MSC_VER */ #else /* __WINDOWS__ */ #define FTDM_O_BINARY 0 +#define FTDM_SIZE_FMT "zd" #define FTDM_INVALID_SOCKET -1 typedef int ftdm_socket_t; #include From 5fd5ee0d4889440f443446994dc74be157f78653 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Dec 2010 09:39:42 -0600 Subject: [PATCH 058/244] doh --- libs/stfu/stfu.c | 604 ++++++++++++++++++++++++++++++++--------------- libs/stfu/stfu.h | 90 ++++++- 2 files changed, 499 insertions(+), 195 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 547c337278..72459caad9 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -33,11 +33,19 @@ # define UINT_MAX 4294967295U #endif +#ifndef UINT16_MAX +# define UINT16_MAX 65535 +#endif + #ifdef _MSC_VER /* warning C4706: assignment within conditional expression*/ #pragma warning(disable: 4706) #endif +#define least1(_z) (_z ? _z : 1) + +static int stfu_log_level = 7; + struct stfu_queue { struct stfu_frame *array; struct stfu_frame int_frame; @@ -53,13 +61,13 @@ typedef struct stfu_queue stfu_queue_t; struct stfu_instance { struct stfu_queue a_queue; struct stfu_queue b_queue; + struct stfu_queue c_queue; struct stfu_queue *in_queue; struct stfu_queue *out_queue; + struct stfu_queue *old_queue; struct stfu_frame *last_frame; uint32_t cur_ts; - uint32_t cur_seq; uint32_t last_wr_ts; - uint32_t last_wr_seq; uint32_t last_rd_ts; uint32_t samples_per_packet; uint32_t samples_per_second; @@ -76,6 +84,7 @@ struct stfu_instance { uint32_t period_packet_in_count; uint32_t period_packet_out_count; uint32_t period_missing_count; + uint32_t period_need_range; uint32_t period_need_range_avg; uint32_t period_clean_count; @@ -86,25 +95,55 @@ struct stfu_instance { uint32_t session_packet_in_count; uint32_t session_packet_out_count; - uint32_t sync; + uint32_t sync_out; + uint32_t sync_in; int32_t ts_diff; int32_t last_ts_diff; int32_t same_ts; - uint32_t last_seq; - uint32_t period_time; uint32_t decrement_time; uint32_t plc_len; + uint32_t plc_pt; + uint32_t diff; + uint32_t diff_total; + uint8_t ready; + uint8_t debug; + char *name; stfu_n_call_me_t callback; void *udata; }; static void stfu_n_reset_counters(stfu_instance_t *i); +static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...); +static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...); + +stfu_logger_t stfu_log = null_logger; + +void stfu_global_set_logger(stfu_logger_t logger) +{ + if (logger) { + stfu_log = logger; + } else { + stfu_log = null_logger; + } +} + +void stfu_global_set_default_logger(int level) +{ + if (level < 0 || level > 7) { + level = 7; + } + + stfu_log = default_logger; + stfu_log_level = level; +} + + static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen) { @@ -151,12 +190,27 @@ void stfu_n_destroy(stfu_instance_t **i) if (i && *i) { ii = *i; *i = NULL; + if (ii->name) free(ii->name); free(ii->a_queue.array); free(ii->b_queue.array); + free(ii->c_queue.array); free(ii); } } +void stfu_n_debug(stfu_instance_t *i, const char *name) +{ + if (i->name) free(i->name); + + if (name) { + i->name = strdup(name); + i->debug = 1; + } else { + i->name = strdup("none"); + i->debug = 0; + } +} + void stfu_n_report(stfu_instance_t *i, stfu_report_t *r) { assert(i); @@ -172,7 +226,6 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) stfu_status_t s; if (i->qlen == i->max_qlen) { - printf("FUCKER1\n"); return STFU_IT_FAILED; } @@ -180,13 +233,14 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) if (i->qlen < i->max_qlen) { qlen = i->max_qlen; } else { - printf("FUCKER2\n"); return STFU_IT_FAILED; } } if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) { s = stfu_n_resize_aqueue(&i->b_queue, qlen); + s = stfu_n_resize_aqueue(&i->c_queue, qlen); + i->qlen = qlen; i->max_plc = 5; i->last_frame = NULL; @@ -205,11 +259,6 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_ } memset(i, 0, sizeof(*i)); - -#ifdef DB_JB - printf("INIT %u %u\n", qlen, max_qlen); -#endif - i->qlen = qlen; i->max_qlen = max_qlen; i->orig_qlen = qlen; @@ -217,8 +266,12 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_ stfu_n_init_aqueue(&i->a_queue, qlen); stfu_n_init_aqueue(&i->b_queue, qlen); + stfu_n_init_aqueue(&i->c_queue, qlen); + i->in_queue = &i->a_queue; i->out_queue = &i->b_queue; + i->old_queue = &i->c_queue; + i->name = strdup("none"); i->max_plc = i->qlen / 2; @@ -232,9 +285,9 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_ static void stfu_n_reset_counters(stfu_instance_t *i) { -#ifdef DB_JB - printf("COUNTER RESET........\n"); -#endif + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s COUNTER RESET........\n", i->name); + } if (i->callback) { i->callback(i, i->udata); @@ -248,36 +301,44 @@ static void stfu_n_reset_counters(stfu_instance_t *i) i->period_packet_in_count = 0; i->period_packet_out_count = 0; i->period_missing_count = 0; + i->period_need_range = 0; i->period_need_range_avg = 0; + + i->diff = 0; + i->diff_total = 0; + } void stfu_n_reset(stfu_instance_t *i) { -#ifdef DB_JB - printf("RESET\n"); -#endif + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s RESET\n", i->name); + } + + i->ready = 0; i->in_queue = &i->a_queue; i->out_queue = &i->b_queue; + i->old_queue = &i->c_queue; + i->in_queue->array_len = 0; i->out_queue->array_len = 0; i->out_queue->wr_len = 0; i->last_frame = NULL; - i->in_queue->last_jitter = 0; i->out_queue->last_jitter = 0; + stfu_n_reset_counters(i); - - i->last_seq = 0; - + stfu_n_sync(i, 1); + i->cur_ts = 0; - i->cur_seq = 0; i->last_wr_ts = 0; - i->last_wr_seq = 0; i->last_rd_ts = 0; i->miss_count = 0; i->packet_count = 0; + + } stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets) @@ -286,20 +347,39 @@ stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets) if (packets > i->qlen) { stfu_n_reset(i); } else { - i->sync = packets; + i->sync_out = packets; + i->sync_in = packets; } return STFU_IT_WORKED; } -stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uint32_t pt, void *data, size_t datalen, int last) +static void stfu_n_swap(stfu_instance_t *i) +{ + stfu_queue_t *last_in = i->in_queue, *last_out = i->out_queue, *last_old = i->old_queue; + + i->ready = 1; + + i->in_queue = last_out; + i->out_queue = last_old; + i->old_queue = last_in; + + i->in_queue->array_len = 0; + i->out_queue->wr_len = 0; + i->last_frame = NULL; + i->miss_count = 0; + i->in_queue->last_index = 0; + i->out_queue->last_index = 0; + 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) { uint32_t index = 0; stfu_frame_t *frame; size_t cplen = 0; - int good_seq = 0, good_ts = 0; - uint32_t min_seq = UINT_MAX, min_ts = UINT_MAX, min_index = 0; + int good_ts = 0; if (!i->samples_per_packet && ts && i->last_rd_ts) { i->ts_diff = ts - i->last_rd_ts; @@ -320,16 +400,27 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin } } - if ((seq && seq == i->last_seq + 1) || (i->last_seq > 65500 && seq == 0)) { - good_seq = 1; - } - - if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) { + if (i->sync_in) { good_ts = 1; + i->sync_in = 0; + } else { + + if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000 && ts < 5000)) { + good_ts = 1; + } + + if (i->last_wr_ts) { + if ((ts <= i->last_wr_ts && (i->last_wr_ts != UINT_MAX || ts == i->last_wr_ts))) { + stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); + if (i->in_queue->array_len < i->in_queue->array_size) { + i->in_queue->array_len++; + } + return STFU_ITS_TOO_LATE; + } + } } - - if (good_seq || good_ts) { + if (good_ts) { i->period_clean_count++; i->session_clean_count++; } @@ -337,12 +428,12 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin i->period_packet_in_count++; i->session_packet_in_count++; - i->period_need_range_avg = i->period_need_range / (i->period_missing_count || 1); + i->period_need_range_avg = i->period_need_range / least1(i->period_missing_count); if (i->period_missing_count > i->qlen * 2) { -#ifdef DB_JB - printf("resize %u %u\n", i->qlen, i->qlen + 1); -#endif + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s resize %u %u\n", i->name, i->qlen, i->qlen + 1); + } stfu_n_resize(i, i->qlen + 1); stfu_n_reset_counters(i); } else { @@ -353,7 +444,24 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin } } + + i->diff = 0; + + if (i->last_wr_ts) { + if (ts < 1000 && i->last_wr_ts > (UINT_MAX - 1000)) { + i->diff = abs(((UINT_MAX - i->last_wr_ts) + ts) / i->samples_per_packet); + } else if (ts) { + i->diff = abs(i->last_wr_ts - ts) / i->samples_per_packet; + } + } + + i->diff_total += i->diff; + if ((i->period_packet_in_count > i->period_time)) { + uint32_t avg; + + avg = i->diff_total / least1(i->period_packet_in_count); + i->period_packet_in_count = 0; if (i->period_missing_count == 0 && i->qlen > i->orig_qlen) { @@ -364,68 +472,38 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin stfu_n_reset_counters(i); } -#ifdef DB_JB - printf("%u i=%u/%u - g:%u/%u c:%u/%u b:%u - %u/%u - %u %d\n", - 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, - seq, ts, - i->period_missing_count, i->period_need_range_avg); -#endif + + + 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)); + } if (last || i->in_queue->array_len == i->in_queue->array_size) { - stfu_queue_t *other_queue; - - other_queue = i->in_queue; - i->in_queue = i->out_queue; - i->out_queue = other_queue; - - i->in_queue->array_len = 0; - i->out_queue->wr_len = 0; - i->last_frame = NULL; - i->miss_count = 0; - i->in_queue->last_index = 0; - i->out_queue->last_index = 0; - i->out_queue->last_jitter = 0; + stfu_n_swap(i); } if (last) { return STFU_IM_DONE; } - for(index = 0; index < i->in_queue->array_size; index++) { - - if (i->in_queue->array[index].was_read) { - min_index = index; - break; - } - - if (i->in_queue->array[index].seq < min_seq) { - min_seq = i->in_queue->array[index].seq; - min_index = index; - } - - if (i->in_queue->array[index].ts < min_ts) { - min_ts = i->in_queue->array[index].ts; - min_index = index; - } - } - - index = min_index; - - if (i->in_queue->array_len < i->in_queue->array_size) { - i->in_queue->array_len++; - } - + index = i->in_queue->array_len++; assert(index < i->in_queue->array_size); - frame = &i->in_queue->array[index]; + if (i->in_queue->array_len == i->in_queue->array_size) { + stfu_n_swap(i); + } + if ((cplen = datalen) > sizeof(frame->data)) { cplen = sizeof(frame->data); } - i->last_seq = seq; i->last_rd_ts = ts; i->packet_count++; @@ -433,44 +511,13 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t seq, uin frame->pt = pt; frame->ts = ts; - frame->seq = seq; frame->dlen = cplen; frame->was_read = 0; return STFU_IT_WORKED; } -static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_frame_t **r_frame) -{ - uint32_t i = 0; - stfu_frame_t *frame = NULL; - stfu_queue_t *queue; - - assert(r_frame); - - *r_frame = NULL; - - for (queue = in->out_queue ; queue && queue != in->in_queue ; queue = in->in_queue) { - - for(i = 0; i < queue->real_array_size; i++) { - frame = &queue->array[i]; - if (!frame->was_read) { - *r_frame = frame; - queue->last_index = i; - frame->was_read = 1; - in->period_packet_out_count++; - in->session_packet_out_count++; - return 1; - } - } - - } - - return 0; -} - - -static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, uint32_t seq, stfu_frame_t **r_frame) +static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_queue_t *queue, stfu_frame_t **r_frame) { uint32_t i = 0; stfu_frame_t *frame = NULL; @@ -481,8 +528,7 @@ static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t for(i = 0; i < queue->real_array_size; i++) { frame = &queue->array[i]; - - if (((seq || in->last_seq) && frame->seq == seq) || frame->ts == ts) { + if (!frame->was_read) { *r_frame = frame; queue->last_index = i; frame->was_read = 1; @@ -492,6 +538,34 @@ static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t } } + return 0; +} + + +static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame) +{ + uint32_t i = 0; + stfu_frame_t *frame = NULL; + + if (r_frame) { + *r_frame = NULL; + } + + for(i = 0; i < queue->array_size; i++) { + frame = &queue->array[i]; + + if (frame->ts == ts) { + if (r_frame) { + *r_frame = frame; + queue->last_index = i; + frame->was_read = 1; + in->period_packet_out_count++; + in->session_packet_out_count++; + } + return 1; + } + } + return 0; } @@ -500,48 +574,76 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) stfu_frame_t *rframe = NULL; int found = 0; - if (!i->samples_per_packet || !i->out_queue->array_len) { - //|| ((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) { - return NULL; - } - - if (i->cur_ts == 0) { - i->cur_ts = i->out_queue->array[0].ts; - } else { - i->cur_ts += i->samples_per_packet; + if (!i->samples_per_packet) { + return NULL; } - if (i->cur_seq == 0) { - i->cur_seq = i->out_queue->array[0].seq; + if (!i->ready) { + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s XXXSKIP\n", i->name); + } + return NULL; + } + + + if (i->cur_ts == 0 && i->last_wr_ts < 1000) { + uint32_t x = 0; + for (x = 0; x < i->out_queue->array_len; x++) { + if (!i->out_queue->array[x].was_read) { + i->cur_ts = i->out_queue->array[x].ts; + break; + } + if (i->cur_ts == 0) { + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s XXXPUNT\n", i->name); + return NULL; + } + } + } } else { - i->cur_seq++; - /* if we bother using this for anything that doesn't have 16 bit seq, we'll make this a param */ - if (i->cur_seq == 65535) { - i->cur_seq = 0; + i->cur_ts = i->cur_ts + i->samples_per_packet; + } + + found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, &rframe); + + if (found) { + if (i->out_queue->array_len) { + i->out_queue->array_len--; + } + } else { + found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, &rframe); + + if (!found) { + found = stfu_n_find_frame(i, i->old_queue, i->cur_ts, &rframe); } } - if (!(found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, i->cur_seq, &rframe))) { - found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, i->cur_seq, &rframe); + if (i->sync_out) { + if (!found) { + if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) { + i->cur_ts = rframe->ts; + } + + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s SYNC %u %u:%u\n", i->name, i->sync_out, i->cur_ts, i->cur_ts / i->samples_per_packet); + } + + } + i->sync_out = 0; } - if (!found && i->sync) { -#ifdef DB_JB - printf("SYNC %u\n", i->sync); -#endif - if ((found = stfu_n_find_any_frame(i, &rframe))) { - i->cur_seq = rframe->seq; - i->cur_ts = rframe->ts; + if (!i->cur_ts) { + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s NO TS\n", i->name); } - i->sync = 0; + return NULL; } if (!found && i->samples_per_packet) { -#ifdef DB_JB int y; stfu_frame_t *frame = NULL; -#endif + int32_t delay = i->last_rd_ts - i->cur_ts; uint32_t need = abs(i->last_rd_ts - i->cur_ts) / i->samples_per_packet; @@ -550,30 +652,32 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) i->session_missing_count++; i->period_need_range += need; -#ifdef DB_JB - printf("MISSING %u %u %u %u %d %u %d\n", i->cur_seq, i->cur_ts, i->packet_count, i->last_rd_ts, delay, i->qlen, need); -#endif + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s MISSING %u:%u %u %u %d %u %d\n", i->name, + i->cur_ts, i->cur_ts / i->samples_per_packet, i->packet_count, i->last_rd_ts, delay, i->qlen, need); + } if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) { i->packet_count = 0; } -#ifdef DB_JB - for(y = 0; y < i->out_queue->array_size; y++) { - if ((y % 5) == 0) printf("\n"); - frame = &i->out_queue->array[y]; - printf("%u:%u\t", frame->seq, frame->ts); - } - printf("\n\n"); + if (stfu_log != null_logger && i->debug) { + for(y = 0; y < i->out_queue->array_size; y++) { + if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s", i->name); + frame = &i->out_queue->array[y]; + stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet); + } + stfu_log(STFU_LOG_EMERG, "%s\n", i->name); - for(y = 0; y < i->in_queue->array_size; y++) { - if ((y % 5) == 0) printf("\n"); - frame = &i->in_queue->array[y]; - printf("%u:%u\t", frame->seq, frame->ts); + for(y = 0; y < i->in_queue->array_size; y++) { + if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s", i->name); + frame = &i->in_queue->array[y]; + stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet); + } + stfu_log(STFU_LOG_EMERG, "%s\n\n\n", i->name); + } - printf("\n\n"); -#endif if (delay < 0) { stfu_n_reset(i); @@ -581,14 +685,11 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) } } -#ifdef DB_JB - if (found) { - printf("O: %u:%u %u %d\n", rframe->seq, rframe->ts, rframe->plc, rframe->seq - i->last_seq); - } else { - printf("DATA: %u %u %d %s %d\n", i->packet_count, i->consecutive_good_count, i->out_queue->last_jitter, found ? "found" : "not found", i->qlen); + if (stfu_log != null_logger && i->debug) { + if (found) { + stfu_log(STFU_LOG_EMERG, "%s O: %u:%u %u\n", i->name, rframe->ts, rframe->ts / i->samples_per_packet, rframe->plc); + } } -#endif - if (found) { i->consecutive_good_count++; @@ -602,36 +703,28 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) if (found) { i->last_frame = rframe; - i->out_queue->wr_len++; - i->last_wr_ts = rframe->ts; - i->last_wr_seq = rframe->seq; - i->miss_count = 0; + i->out_queue->wr_len++; + i->last_wr_ts = rframe->ts; + + i->miss_count = 0; if (rframe->dlen) { i->plc_len = rframe->dlen; } + + i->plc_pt = rframe->pt; + } else { i->last_wr_ts = i->cur_ts; - i->last_wr_seq = i->cur_seq; rframe = &i->out_queue->int_frame; rframe->dlen = i->plc_len; - -#if 0 - if (i->last_frame) { - /* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */ - if (i->miss_count) { - memset(rframe->data, 255, rframe->dlen); - } else { - memcpy(rframe->data, i->last_frame->data, rframe->dlen); - } - } -#endif + rframe->pt = i->plc_pt; rframe->ts = i->cur_ts; - i->miss_count++; - -#ifdef DB_JB - printf("PLC %d %d %ld %u %u\n", i->miss_count, rframe->plc, rframe->dlen, rframe->seq, rframe->ts); -#endif + + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s PLC %d %d %ld %u:%u\n", i->name, + i->miss_count, rframe->plc, rframe->dlen, rframe->ts, rframe->ts / i->samples_per_packet); + } if (i->miss_count > i->max_plc) { stfu_n_reset(i); @@ -639,9 +732,138 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) } } - return rframe; + return rframe; } +#ifdef WIN32 +#ifndef vsnprintf +#define vsnprintf _vsnprintf +#endif +#endif + + +int vasprintf(char **ret, const char *format, va_list ap); + +int stfu_vasprintf(char **ret, const char *fmt, va_list ap) +{ +#if !defined(WIN32) && !defined(__sun) + return vasprintf(ret, fmt, ap); +#else + char *buf; + int len; + size_t buflen; + va_list ap2; + char *tmp = NULL; + +#ifdef _MSC_VER +#if _MSC_VER >= 1500 + /* hack for incorrect assumption in msvc header files for code analysis */ + __analysis_assume(tmp); +#endif + ap2 = ap; +#else + va_copy(ap2, ap); +#endif + + len = vsnprintf(tmp, 0, fmt, ap2); + + if (len > 0 && (buf = malloc((buflen = (size_t) (len + 1)))) != NULL) { + len = vsnprintf(buf, buflen, fmt, ap); + *ret = buf; + } else { + *ret = NULL; + len = -1; + } + + va_end(ap2); + return len; +#endif +} + + + + +int stfu_snprintf(char *buffer, size_t count, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vsnprintf(buffer, count-1, fmt, ap); + if (ret < 0) + buffer[count-1] = '\0'; + va_end(ap); + return ret; +} + +static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) +{ + if (file && func && line && level && fmt) { + return; + } + return; +} + + + +static const char *LEVEL_NAMES[] = { + "EMERG", + "ALERT", + "CRIT", + "ERROR", + "WARNING", + "NOTICE", + "INFO", + "DEBUG", + NULL +}; + +static const char *cut_path(const char *in) +{ + const char *p, *ret = in; + char delims[] = "/\\"; + char *i; + + for (i = delims; *i; i++) { + p = in; + while ((p = strchr(p, *i)) != 0) { + ret = ++p; + } + } + return ret; +} + + +static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) +{ + const char *fp; + char *data; + va_list ap; + int ret; + + if (level < 0 || level > 7) { + level = 7; + } + if (level > stfu_log_level) { + return; + } + + fp = cut_path(file); + + va_start(ap, fmt); + + ret = stfu_vasprintf(&data, fmt, ap); + + if (ret != -1) { + fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], file, line, func, data); + free(data); + } + + va_end(ap); + +} + + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index d2760b27bc..f65511b5f4 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -38,6 +38,8 @@ extern "C" { #include #include #include +#include + #ifdef _MSC_VER #ifndef uint32_t @@ -62,6 +64,85 @@ typedef unsigned long in_addr_t; #endif #include + + +#ifdef WIN32 +#include +#include +typedef SOCKET stfu_socket_t; +typedef unsigned __int64 uint64_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int8 uint8_t; +typedef __int64 int64_t; +typedef __int32 int32_t; +typedef __int16 int16_t; +typedef __int8 int8_t; +typedef intptr_t stfu_ssize_t; +typedef int stfu_filehandle_t; +#define STFU_SOCK_INVALID INVALID_SOCKET +#define strerror_r(num, buf, size) strerror_s(buf, size, num) +#if defined(STFU_DECLARE_STATIC) +#define STFU_DECLARE(type) type __stdcall +#define STFU_DECLARE_NONSTD(type) type __cdecl +#define STFU_DECLARE_DATA +#elif defined(STFU_EXPORTS) +#define STFU_DECLARE(type) __declspec(dllexport) type __stdcall +#define STFU_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl +#define STFU_DECLARE_DATA __declspec(dllexport) +#else +#define STFU_DECLARE(type) __declspec(dllimport) type __stdcall +#define STFU_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl +#define STFU_DECLARE_DATA __declspec(dllimport) +#endif +#else +#define STFU_DECLARE(type) type +#define STFU_DECLARE_NONSTD(type) type +#define STFU_DECLARE_DATA +#include +#include +#include +#include +#include +#include +#include +#define STFU_SOCK_INVALID -1 +typedef int stfu_socket_t; +typedef ssize_t stfu_ssize_t; +typedef int stfu_filehandle_t; +#endif + + +#define STFU_PRE __FILE__, __FUNCTION__, __LINE__ +#define STFU_LOG_LEVEL_DEBUG 7 +#define STFU_LOG_LEVEL_INFO 6 +#define STFU_LOG_LEVEL_NOTICE 5 +#define STFU_LOG_LEVEL_WARNING 4 +#define STFU_LOG_LEVEL_ERROR 3 +#define STFU_LOG_LEVEL_CRIT 2 +#define STFU_LOG_LEVEL_ALERT 1 +#define STFU_LOG_LEVEL_EMERG 0 + +#define STFU_LOG_DEBUG STFU_PRE, STFU_LOG_LEVEL_DEBUG +#define STFU_LOG_INFO STFU_PRE, STFU_LOG_LEVEL_INFO +#define STFU_LOG_NOTICE STFU_PRE, STFU_LOG_LEVEL_NOTICE +#define STFU_LOG_WARNING STFU_PRE, STFU_LOG_LEVEL_WARNING +#define STFU_LOG_ERROR STFU_PRE, STFU_LOG_LEVEL_ERROR +#define STFU_LOG_CRIT STFU_PRE, STFU_LOG_LEVEL_CRIT +#define STFU_LOG_ALERT STFU_PRE, STFU_LOG_LEVEL_ALERT +#define STFU_LOG_EMERG STFU_PRE, STFU_LOG_LEVEL_EMERG +typedef void (*stfu_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...); + + +int stfu_vasprintf(char **ret, const char *fmt, va_list ap); + +STFU_DECLARE_DATA extern stfu_logger_t stfu_log; + +/*! Sets the logger for libstfu. Default is the null_logger */ +void stfu_global_set_logger(stfu_logger_t logger); +/*! Sets the default log level for libstfu */ +void stfu_global_set_default_logger(int level); + #define STFU_DATALEN 16384 #define STFU_QLEN 300 #define STFU_MAX_TRACK 256 @@ -69,13 +150,13 @@ typedef unsigned long in_addr_t; typedef enum { STFU_IT_FAILED, STFU_IT_WORKED, - STFU_IM_DONE + STFU_IM_DONE, + STFU_ITS_TOO_LATE } stfu_status_t; struct stfu_frame { uint32_t ts; uint32_t pt; - uint32_t seq; uint8_t data[STFU_DATALEN]; size_t dlen; uint8_t was_read; @@ -100,14 +181,15 @@ 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 seq, 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, 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); #define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 1) -#define stfu_n_eat(i,t,s,p,d,l) stfu_n_add_data(i, t, s, p, d, l, 0) +#define stfu_n_eat(i,t,p,d,l) stfu_n_add_data(i, t, p, d, l, 0) #ifdef __cplusplus } From 2c8d5d8ec9833f02f6a7b58079dbeb71da0e2456 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Dec 2010 10:22:45 -0600 Subject: [PATCH 059/244] use our version for better compat --- src/switch_rtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 306e58a839..08a22ccac2 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1659,7 +1659,7 @@ static void jb_logger(const char *file, const char *func, int line, int level, c va_list ap; va_start(ap, fmt); - ret = stfu_vasprintf(&data, fmt, ap); + ret = switch_vasprintf(&data, fmt, ap); if (ret != -1) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "%s", data); free(data); From 416f6388c3756b92b99bd36ab12de957cf55409b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 15 Dec 2010 10:37:57 -0600 Subject: [PATCH 060/244] windows build fixes for last commit --- libs/stfu/stfu.c | 4 +++- libs/stfu/stfu.h | 2 +- src/switch_rtp.c | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 72459caad9..4965b12e34 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -40,6 +40,8 @@ #ifdef _MSC_VER /* warning C4706: assignment within conditional expression*/ #pragma warning(disable: 4706) +/* warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details. */ +#pragma warning(disable:4996) #endif #define least1(_z) (_z ? _z : 1) @@ -641,7 +643,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) if (!found && i->samples_per_packet) { - int y; + uint32_t y; stfu_frame_t *frame = NULL; int32_t delay = i->last_rd_ts - i->cur_ts; diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index f65511b5f4..ad769c62e2 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -136,7 +136,7 @@ typedef void (*stfu_logger_t)(const char *file, const char *func, int line, int int stfu_vasprintf(char **ret, const char *fmt, va_list ap); -STFU_DECLARE_DATA extern stfu_logger_t stfu_log; +extern stfu_logger_t stfu_log; /*! Sets the logger for libstfu. Default is the null_logger */ void stfu_global_set_logger(stfu_logger_t logger); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 08a22ccac2..4e667fb49b 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2135,11 +2135,18 @@ 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++; From 102640ad7be96a2f23194cefbb1ca824416576dd Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 11:45:50 -0500 Subject: [PATCH 061/244] freetdm: support for SIGEVENT_RING --- libs/freetdm/mod_freetdm/mod_freetdm.c | 1 + .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 25 +++++++++--- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 6 ++- .../ftmod_sangoma_isdn_stack_hndl.c | 38 ++++++++++++++----- libs/freetdm/src/include/freetdm.h | 5 ++- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 26b84636ca..d8f98f1c61 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2167,6 +2167,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) } break; case FTDM_SIGEVENT_PROGRESS: + case FTDM_SIGEVENT_RINGING: { if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { channel = switch_core_session_get_channel(session); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index f8867d5fcf..48ddddce6b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -215,7 +215,7 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_DIALING, FTDM_END}, {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, + FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END} }, { @@ -223,14 +223,20 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_PROCEED, FTDM_END}, {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, - FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, - }, + FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, + }, { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}, {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, }, + { + ZSD_OUTBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_RINGING, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, + }, { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, @@ -692,8 +698,17 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) break; case FTDM_CHANNEL_STATE_RINGING: { - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; - sngisdn_snd_alert(ftdmchan, prog_ind); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + /* OUTBOUND...so we were told by the line of this so notify the user */ + sigev.event_id = FTDM_SIGEVENT_RINGING; + ftdm_span_send_signal(ftdmchan->span, &sigev); + if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } + } else { + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; + sngisdn_snd_alert(ftdmchan, prog_ind); + } } break; case FTDM_CHANNEL_STATE_PROGRESS: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 4662d4e9bb..0c6c1c6eef 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -101,9 +101,11 @@ typedef enum { FLAG_GLARE = (1 << 6), FLAG_DELAYED_REL = (1 << 7), FLAG_SENT_PROCEED = (1 << 8), - FLAG_SEND_DISC = (1 << 9), + FLAG_SEND_DISC = (1 << 9), /* Used for BRI only, flag is set after we request line CONNECTED */ - FLAG_ACTIVATING = (1 << 10), + FLAG_ACTIVATING = (1 << 10), + /* Used when we receive an ALERT msg + inband tones ready */ + FLAG_MEDIA_READY = (1 << 11), } sngisdn_flag_t; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index bdd371704d..7e9e360c6d 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -278,6 +278,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { switch(ftdmchan->state) { case FTDM_CHANNEL_STATE_PROCEED: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_DIALING: @@ -364,21 +365,38 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); goto sngisdn_process_cnst_ind_end; } - + switch(ftdmchan->state) { case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: - if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); - } else if (evntType == MI_CALLPROC) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED); - } else { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); - } - break; case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_RINGING: if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } + switch (evntType) { + case MI_CALLPROC: + if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED); + } + break; + case MI_ALERTING: + if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING); + } + break; + case MI_PROGRESS: + if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { + + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) { + + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); + } + break; + default: + /* We should never reach this section !*/ + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType); } break; case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index a3cddadb81..f8f69abc71 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -314,7 +314,8 @@ typedef enum { FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */ FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */ FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */ - FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */ + FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */ + FTDM_SIGEVENT_RINGING, /*!< Remote side is in ringing state */ FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */ FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */ FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */ @@ -327,7 +328,7 @@ typedef enum { FTDM_SIGEVENT_FACILITY, /* !< In call facility event */ FTDM_SIGEVENT_INVALID } ftdm_signal_event_t; -#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \ +#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \ "PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \ "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "MSG", "INVALID" From 8e62bfcb95fb3f0eb68214c8cb2586a3cfe8de8e Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 15 Dec 2010 11:50:41 -0600 Subject: [PATCH 062/244] vs2008 express fix build dependency --- Freeswitch.2008.express.sln | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Freeswitch.2008.express.sln b/Freeswitch.2008.express.sln index 672406bda2..ad3cafe5cd 100644 --- a/Freeswitch.2008.express.sln +++ b/Freeswitch.2008.express.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 +# Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Console\FreeSwitchConsole.2008.vcproj", "{1AF3A893-F7BE-43DD-B697-8AB2397C0D67}" ProjectSection(ProjectDependencies) = postProject {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} @@ -11,6 +11,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Li ProjectSection(ProjectDependencies) = postProject {8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9} {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C} + {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3} {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} From ea2b4774441a594e71ad921fe4721318fa200159 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 12:56:49 -0500 Subject: [PATCH 063/244] Freetdm:fix for ftdm_channel_close not always passed double-pointer --- libs/freetdm/src/ftdm_io.c | 12 +++--------- libs/freetdm/src/ftdm_m3ua.c | 2 +- libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c | 2 +- libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c | 6 +++--- .../ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c | 8 +++++--- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 4bd0fdd33e..eaf057e8a8 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2430,14 +2430,9 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const ch FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); -#ifdef __WINDOWS__ - UNREFERENCED_PARAMETER(file); - UNREFERENCED_PARAMETER(func); - UNREFERENCED_PARAMETER(line); -#endif ftdm_channel_lock(ftdmchan); - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 0); + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 1); ftdm_channel_unlock(ftdmchan); return FTDM_SUCCESS; } @@ -2578,8 +2573,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", ftdmchan->txdrops, ftdmchan->rxdrops); } - - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); + memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD); @@ -2612,6 +2606,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE); } + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n"); ftdm_mutex_unlock(ftdmchan->mutex); return FTDM_SUCCESS; } @@ -2642,7 +2637,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan) if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { status = check->fio->close(check); if (status == FTDM_SUCCESS) { - ftdm_clear_flag(check, FTDM_CHANNEL_INUSE); ftdm_channel_done(check); *ftdmchan = NULL; } diff --git a/libs/freetdm/src/ftdm_m3ua.c b/libs/freetdm/src/ftdm_m3ua.c index 5a468d1378..8d3e00213a 100644 --- a/libs/freetdm/src/ftdm_m3ua.c +++ b/libs/freetdm/src/ftdm_m3ua.c @@ -156,7 +156,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) release_request_id((m3ua_request_id_t)ftdmchan->extra_id); ftdmchan->extra_id = 0; } - ftdm_channel_close(ftdmchan); + ftdm_channel_close(&ftdmchan); } break; case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index c6a0e5ff0e..5b4ce7196a 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -1325,7 +1325,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) } Q931ReleaseCRV(&isdn_data->q931, gen->CRV); } - ftdm_channel_close(ftdmchan); + ftdm_channel_close(&ftdmchan); } break; case FTDM_CHANNEL_STATE_PROGRESS: diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index b3b4f2a9dc..27fbe2139f 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -280,12 +280,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_DOWN: - { - ftdm_channel_close(ftdmchan); + { ftdmchan->call_data = NULL; + ftdm_channel_close(&ftdmchan); - ftdm_channel_close(peerchan); peerchan->call_data = NULL; + ftdm_channel_close(&peerchan); } break; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index a196725d4e..f59b3b8c4f 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -839,7 +839,7 @@ static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon if ((ftdmchan = find_ftdmchan(span, event, 1))) { ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); - ftdm_channel_close(ftdmchan); + ftdm_channel_close(&ftdmchan); } else { ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); @@ -1105,8 +1105,9 @@ static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mc ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res); if (res != FTDM_SUCCESS) { + ftdm_channel_t *toclose = ftdmchan; ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n"); - ftdm_channel_close(ftdmchan); + ftdm_channel_close(&toclose); return; } ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id); @@ -1430,7 +1431,8 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n", ftdmchan->span_id, ftdmchan->chan_id); } else { - ftdm_channel_close(ftdmchan); + ftdm_channel_t *toclose = ftdmchan; + ftdm_channel_close(&toclose); } } break; From a95af703237509fa55c07df6e381dd6b19550665 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Wed, 15 Dec 2010 19:43:13 +0100 Subject: [PATCH 064/244] Skinny: set max message size to 2048 for now (part of FS-2912) --- src/mod/endpoints/mod_skinny/skinny_protocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index d85a190ba8..4d0b7922ec 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -552,7 +552,7 @@ struct PACKED service_url_stat_res_message { /*****************************************************************************/ #define SKINNY_MESSAGE_FIELD_SIZE 4 /* 4-bytes field */ #define SKINNY_MESSAGE_HEADERSIZE 12 /* three 4-bytes fields */ -#define SKINNY_MESSAGE_MAXSIZE 1000 +#define SKINNY_MESSAGE_MAXSIZE 2048 union skinny_data { /* no data for KEEP_ALIVE_MESSAGE */ From dcdbeff9d80202ef8ab0c9a3aff73a09f407b53d Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 17:43:40 -0200 Subject: [PATCH 065/244] freetdm: ftmod_wanpipe - now receiving ftdm macros for channel polling, instead of using POLLPRI, etc., directly ftmod_r2 - also using ftdm macros for polling --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 10 +++------ .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 22 +++++++++++++++++-- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 1549833571..10e0c4ac9f 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1720,7 +1720,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) /* deliver the actual channel events to the user now without any channel locking */ ftdm_span_trigger_signals(span); -#ifndef WIN32 + /* figure out what event to poll each channel for. POLLPRI when the channel is down, * POLLPRI|POLLIN|POLLOUT otherwise */ memset(poll_events, 0, sizeof(short)*span->chan_count); @@ -1732,16 +1732,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) { ftdmchan = ftdm_iterator_current(citer); r2chan = R2CALL(ftdmchan)->r2chan; - poll_events[i] = POLLPRI; + poll_events[i] = FTDM_EVENTS; if (openr2_chan_get_read_enabled(r2chan)) { - poll_events[i] |= POLLIN; + poll_events[i] |= FTDM_READ; } } - status = ftdm_span_poll_event(span, waitms, poll_events); -#else - status = ftdm_span_poll_event(span, waitms, NULL); -#endif /* run any span timers */ ftdm_sched_run(r2data->sched); diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index e1b6658945..627ef7bb67 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -1051,16 +1051,34 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event) for(i = 1; i <= span->chan_count; i++) { ftdm_channel_t *ftdmchan = span->channels[i]; + uint32_t chan_events = 0; + + /* if the user specify which events to poll the channel for, we translate them from ftdm_wait_flag_t + * to events that either sangoma_waitfor_many() or poll() understands. if not, we poll for POLLPRI */ + if (poll_events) { + if (poll_events[j] & FTDM_READ) { + chan_events = POLLIN; + } + if (poll_events[j] & FTDM_WRITE) { + chan_events |= POLLOUT; + } + if (poll_events[j] & FTDM_EVENTS) { + chan_events |= POLLPRI; + } + } else { + chan_events = POLLPRI; + } + #ifdef LIBSANGOMA_VERSION if (!ftdmchan->io_data) { continue; /* should never happen but happens when shutting down */ } pfds[j] = ftdmchan->io_data; - inflags[j] = poll_events ? poll_events[j] : POLLPRI; + inflags[j] = chan_events; #else memset(&pfds[j], 0, sizeof(pfds[j])); pfds[j].fd = span->channels[i]->sockfd; - pfds[j].events = poll_events ? poll_events[j] : POLLPRI; + pfds[j].events = chan_events; #endif /* The driver probably should be able to do this wink/flash/ringing by itself this is sort of a hack to make it work! */ From 20ba5da47991e2b00854ffb66985ce9388d412b2 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 18:08:55 -0200 Subject: [PATCH 066/244] freetdm: ftmod_r2 - implemented set_channel_sig_status() --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 10e0c4ac9f..6e78810b0c 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -449,6 +449,24 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status) return FTDM_SUCCESS; } +static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) +{ + openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; + switch(status) { + case FTDM_SIG_STATE_DOWN: + case FTDM_SIG_STATE_SUSPENDED: + openr2_chan_set_blocked(r2chan); + break; + case FTDM_SIG_STATE_UP: + openr2_chan_set_idle(r2chan); + break; + default: + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Ignoring unknown sigstatus: %d\n", status); + return FTDM_FAIL; + } + return FTDM_SUCCESS; +} + /* always called from the monitor thread */ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) { @@ -1419,13 +1437,12 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) span->sig_read = NULL; span->sig_write = NULL; - /* let the core set the states, we just read them */ - span->get_channel_sig_status = ftdm_r2_get_channel_sig_status; - span->signal_cb = sig_cb; span->signal_type = FTDM_SIGTYPE_R2; span->signal_data = r2data; span->outgoing_call = r2_outgoing_call; + span->get_channel_sig_status = ftdm_r2_get_channel_sig_status; + span->set_channel_sig_status = ftdm_r2_set_channel_sig_status; span->state_map = &r2_state_map; From 715d250e171a94736b19019ac742f739899ad997 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Wed, 15 Dec 2010 21:29:52 +0100 Subject: [PATCH 067/244] Skinny: handle new XMLAlarmMessage This add support for new SCCP Firmware 9.1 (part of FS-2912) --- src/mod/endpoints/mod_skinny/skinny_protocol.h | 3 +++ src/mod/endpoints/mod_skinny/skinny_server.c | 2 +- src/mod/endpoints/mod_skinny/skinny_tables.c | 1 + src/mod/endpoints/mod_skinny/skinny_tables.h | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 4d0b7922ec..ee3c33a497 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -547,6 +547,9 @@ struct PACKED service_url_stat_res_message { #define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F /* See struct PACKED extended_data_message */ +/* XMLAlarmMessage */ +#define XML_ALARM_MESSAGE 0x015A + /*****************************************************************************/ /* SKINNY MESSAGE */ /*****************************************************************************/ diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index cfafea6f01..c03e3ce8af 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1970,7 +1970,7 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re "Received %s (type=%x,length=%d) from %s:%d.\n", skinny_message_type2str(request->type), request->type, request->length, listener->device_name, listener->device_instance); } - if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE) { + if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE && request->type != XML_ALARM_MESSAGE) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Device should send a register message first.\n"); return SWITCH_STATUS_FALSE; diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 0a27ad76c4..053b350b46 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -99,6 +99,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE}, {"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE}, {"UserToDeviceDataVersion1Message", USER_TO_DEVICE_DATA_VERSION1_MESSAGE}, + {"XMLAlarmMessage", XML_ALARM_MESSAGE}, {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage") diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 14962b8b78..c119e1f141 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -87,7 +87,7 @@ uint32_t func(const char *str)\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[65]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[66]; const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) From bb8d901c4f437c57b1c349575d5d93eea4fb4203 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 18:32:35 -0200 Subject: [PATCH 068/244] freetdm: ftmod_wanpipe - replaced some POLL macros by SANG_WAIT_OBJ_* --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 627ef7bb67..2db4326847 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -1053,20 +1053,20 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event) ftdm_channel_t *ftdmchan = span->channels[i]; uint32_t chan_events = 0; - /* if the user specify which events to poll the channel for, we translate them from ftdm_wait_flag_t - * to events that either sangoma_waitfor_many() or poll() understands. if not, we poll for POLLPRI */ + /* translate events from ftdm to libsnagoma. if the user don't specify which events to poll the + * channel for, we just use SANG_WAIT_OBJ_HAS_EVENTS */ if (poll_events) { if (poll_events[j] & FTDM_READ) { - chan_events = POLLIN; + chan_events = SANG_WAIT_OBJ_HAS_INPUT; } if (poll_events[j] & FTDM_WRITE) { - chan_events |= POLLOUT; + chan_events |= SANG_WAIT_OBJ_HAS_OUTPUT; } if (poll_events[j] & FTDM_EVENTS) { - chan_events |= POLLPRI; + chan_events |= SANG_WAIT_OBJ_HAS_EVENTS; } } else { - chan_events = POLLPRI; + chan_events = SANG_WAIT_OBJ_HAS_EVENTS; } #ifdef LIBSANGOMA_VERSION From 72f99898d2dc3dc3bdd7365d1c113462d4d139cb Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Wed, 15 Dec 2010 18:48:49 -0200 Subject: [PATCH 069/244] freetdm: ftmod_r2 - updated warning message --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 6e78810b0c..ef9201bbe6 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -461,7 +461,7 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) openr2_chan_set_idle(r2chan); break; default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Ignoring unknown sigstatus: %d\n", status); + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%s'\n", status); return FTDM_FAIL; } return FTDM_SUCCESS; From dd345b913bcec51f247da22bba045a227e7db320 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 16:29:03 -0500 Subject: [PATCH 070/244] freetdm: Support for RAW traces --- libs/freetdm/src/ftdm_io.c | 8 +- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 +- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 14 +++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 9 ++- .../ftmod_sangoma_isdn_cfg.c | 4 + .../ftmod_sangoma_isdn_cntrl.c | 2 +- .../ftmod_sangoma_isdn_stack_rcv.c | 64 +++++++-------- .../ftmod_sangoma_isdn_trace.c | 79 ++++++++++++++++++- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c | 4 +- .../ftmod_sangoma_ss7_handle.c | 4 +- .../ftmod_sangoma_ss7_main.c | 18 ++--- libs/freetdm/src/include/freetdm.h | 37 ++++++++- 12 files changed, 183 insertions(+), 62 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 6166c551f7..3fa763fe79 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -280,6 +280,9 @@ FTDM_STR2ENUM(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t, CHA FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID) +FTDM_ENUM_NAMES(TRACE_DIR_NAMES, TRACE_DIR_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_trace_dir, ftdm_trace_dir2str, ftdm_trace_dir_t, TRACE_DIR_NAMES, FTDM_TRACE_INVALID) + FTDM_ENUM_NAMES(TON_NAMES, TON_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t, TON_NAMES, FTDM_TON_INVALID) @@ -5292,6 +5295,7 @@ static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigm if (sigmsg->channel) { ftdm_call_clear_data(&(sigmsg->channel->caller_data)); } + ftdm_safe_free(sigmsg->raw_data); return status; } @@ -5299,8 +5303,6 @@ static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg { ftdm_sigmsg_t *new_sigmsg = NULL; - ftdm_assert_return((sigmsg->raw_data == NULL), FTDM_FAIL, "No raw data should be used with asynchronous notification\n"); - new_sigmsg = ftdm_calloc(1, sizeof(*sigmsg)); if (!new_sigmsg) { return FTDM_FAIL; @@ -5347,7 +5349,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { - ftdm_signaling_status_t sigstatus = ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE) ? sigmsg->sigstatus : *((ftdm_signaling_status_t*)(sigmsg->raw_data)); + ftdm_signaling_status_t sigstatus = ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE) ? sigmsg->ev_data.sigstatus.status : *((ftdm_signaling_status_t*)(sigmsg->raw_data)); if (sigstatus == FTDM_SIG_STATE_UP) { ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); } else { diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 1549833571..8c2fd51a64 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -255,7 +255,7 @@ static void ftdm_r2_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling sig.span_id = ftdmchan->span_id; sig.channel = ftdmchan; sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.sigstatus = status; + sig.ev_data.sigstatus.status = status; if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status)); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 48ddddce6b..bb29b4f4a5 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -976,7 +976,8 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status) } static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) -{ +{ + sngisdn_span_data_t *signal_data = span->signal_data; ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id); if (sngisdn_stack_start(span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name); @@ -986,6 +987,14 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD); ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); + if (signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) { + sngisdn_activate_trace(span, SNGISDN_TRACE_Q921); + } + + if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) { + sngisdn_activate_trace(span, SNGISDN_TRACE_Q931); + } + /*start the span monitor thread*/ if (ftdm_thread_create_detached(ftdm_sangoma_isdn_run, span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT,"Failed to start Sangoma ISDN Span Monitor Thread!\n"); @@ -1210,6 +1219,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]); goto done; } + if (!strcasecmp(trace_opt, "q921")) { sngisdn_activate_trace(span, SNGISDN_TRACE_Q921); } else if (!strcasecmp(trace_opt, "q931")) { @@ -1218,7 +1228,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE); } else { stream->write_function(stream, "-ERR invalid trace option \n"); - } + } } if (!strcasecmp(argv[0], "l1_stats")) { ftdm_span_t *span; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 0c6c1c6eef..6a440e4f66 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -261,6 +261,8 @@ typedef struct sngisdn_span_data { int8_t facility_timeout; uint8_t num_local_numbers; uint8_t ignore_cause_value; + uint8_t raw_trace_q931; + uint8_t raw_trace_q921; uint8_t timer_t3; uint8_t restart_opt; char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; @@ -427,8 +429,11 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event); void sngisdn_rcv_phy_ind(SuId suId, Reason reason); void sngisdn_rcv_q921_ind(BdMngmt *status); -void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len); -void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len); +void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); +void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); +void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); +void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); + void get_memory_info(void); ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index cce10cc1dd..c979000223 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -296,6 +296,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ parse_yesno(var, val, &signal_data->facility_ie_decode); } else if (!strcasecmp(var, "ignore-cause-value")) { parse_yesno(var, val, &signal_data->ignore_cause_value); + } else if (!strcasecmp(var, "q931-raw-trace")) { + parse_yesno(var, val, &signal_data->raw_trace_q931); + } else if (!strcasecmp(var, "q921-raw-trace")) { + parse_yesno(var, val, &signal_data->raw_trace_q921); } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c index 5060cb6bba..668b63006c 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c @@ -47,7 +47,7 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status sig.span_id = ftdmchan->span_id; sig.channel = ftdmchan; sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.sigstatus = status; + sig.ev_data.sigstatus.status = status; ftdm_span_send_signal(ftdmchan->span, &sig); return; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c index 4b04fb065e..3afdaa599e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c @@ -34,9 +34,6 @@ #include "ftmod_sangoma_isdn.h" -#define MAX_DECODE_STR_LEN 2000 - - void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces) { uint8_t bchan_no = 0; @@ -777,9 +774,6 @@ void sngisdn_rcv_cc_ind(CcMngmt *status) return; } -#define Q931_TRC_EVENT(event) (event == TL3PKTTX)?"TX": \ - (event == TL3PKTRX)?"RX":"UNKNOWN" - void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) { MsgLen mlen; @@ -788,13 +782,20 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) Buffer *tmp; Data *cptr; uint8_t data; + ftdm_trace_dir_t dir; uint8_t tdata[1000]; - char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */ - + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.suId]; + ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer"); mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len; - - if (mlen != 0) { + + if (trc->t.trc.evnt == TL3PKTTX) { + dir = FTDM_TRACE_OUTGOING; + } else { + dir = FTDM_TRACE_INCOMING; + } + + if (mlen) { tmp = mBuf->b_cont; cptr = tmp->b_rptr; data = *cptr++; @@ -809,41 +810,40 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) } data = *cptr++; } - - sngisdn_trace_q931(data_str, tdata, mlen); - ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d FRAME %s:%s\n", trc->t.trc.suId, Q931_TRC_EVENT(trc->t.trc.evnt), data_str); + if (signal_data->raw_trace_q931 == SNGISDN_OPT_TRUE) { + sngisdn_trace_raw_q931(signal_data, dir, tdata, mlen); + } else { + sngisdn_trace_interpreted_q931(signal_data, dir, tdata, mlen); + } } - - ftdm_safe_free(data_str); - /* We do not need to free mBuf in this case because stack does it */ - /* SPutMsg(mBuf); */ return; } -#define Q921_TRC_EVENT(event) (event == TL2FRMRX)?"RX": \ - (event == TL2FRMTX)?"TX": \ - (event == TL2TMR)?"TMR EXPIRED":"UNKNOWN" - void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf) { MsgLen mlen; + Buffer *tmp; MsgLen i; int16_t j; - Buffer *tmp; Data *cptr; uint8_t data; - uint8_t tdata[16]; - char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */ - + ftdm_trace_dir_t dir; + uint8_t tdata[1000]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.lnkNmb]; if (trc->t.trc.evnt == TL2TMR) { - goto end_of_trace; + return; } + if (trc->t.trc.evnt == TL2FRMTX) { + dir = FTDM_TRACE_OUTGOING; + } else { + dir = FTDM_TRACE_INCOMING; + } + ftdm_assert(mBuf != NULLP, "Received a Q921 trace with no buffer"); mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len; - if (mlen != 0) { tmp = mBuf->b_cont; cptr = tmp->b_rptr; @@ -865,12 +865,12 @@ void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf) } } - sngisdn_trace_q921(data_str, tdata, mlen); - ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] s%d FRAME %s:%s\n", trc->t.trc.lnkNmb, Q921_TRC_EVENT(trc->t.trc.evnt), data_str); + if (signal_data->raw_trace_q921 == SNGISDN_OPT_TRUE) { + sngisdn_trace_raw_q921(signal_data, dir, tdata, mlen); + } else { + sngisdn_trace_interpreted_q921(signal_data, dir, tdata, mlen); + } } -end_of_trace: - ftdm_safe_free(data_str); - SPutMsg(mBuf); return; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c index e5167164b3..c03976a1c2 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c @@ -36,14 +36,15 @@ #include "ftmod_sangoma_isdn_trace.h" #define OCTET(x) (ieData[x-1] & 0xFF) +#define MAX_DECODE_STR_LEN 2000 void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end); -void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len); -void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len); uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start); uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi); char* get_code_2_str(int code, struct code2str *pCodeTable); +void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len); +void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len); char* get_code_2_str(int code, struct code2str *pCodeTable) { @@ -97,7 +98,42 @@ uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi) return 0; } -void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len) +void sngisdn_trace_interpreted_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) +{ + char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */ + sngisdn_decode_q921(data_str, data, data_len); + ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] s%d FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str); + ftdm_safe_free(data_str); +} + +void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) +{ + uint8_t *raw_data; + ftdm_sigmsg_t sigev; + + memset(&sigev, 0, sizeof(sigev)); + + sigev.span_id = signal_data->ftdm_span->span_id; + sigev.chan_id = signal_data->dchan->chan_id; + sigev.channel = signal_data->dchan; + sigev.event_id = FTDM_SIGEVENT_TRACE_RAW; + + sigev.ev_data.logevent.dir = dir; + sigev.ev_data.logevent.level = 2; + + /* TODO: Map trace to call ID here */ + sigev.call_id = 0; + + raw_data = ftdm_malloc(data_len); + ftdm_assert(raw_data, "Failed to malloc"); + + memcpy(raw_data, data, data_len); + sigev.raw_data = raw_data; + sigev.raw_data_len = data_len; + ftdm_span_send_signal(signal_data->ftdm_span, &sigev); +} + +void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len) { int str_len; uint32_t i; @@ -169,7 +205,42 @@ void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len) return; } -void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len) + +void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) +{ + char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */ + sngisdn_decode_q931(data_str, data, data_len); + ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] %s FRAME %s:%s\n", signal_data->ftdm_span->name, ftdm_trace_dir2str(dir), data_str); + ftdm_safe_free(data_str); +} + +void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len) +{ + uint8_t *raw_data; + ftdm_sigmsg_t sigev; + + memset(&sigev, 0, sizeof(sigev)); + + sigev.span_id = signal_data->ftdm_span->span_id; + sigev.chan_id = signal_data->dchan->chan_id; + sigev.channel = signal_data->dchan; + sigev.event_id = FTDM_SIGEVENT_TRACE_RAW; + + sigev.ev_data.logevent.dir = dir; + sigev.ev_data.logevent.level = 3; + + /* TODO: Map trace to call ID here */ + + raw_data = ftdm_malloc(data_len); + ftdm_assert(raw_data, "Failed to malloc"); + + memcpy(raw_data, data, data_len); + sigev.raw_data = raw_data; + sigev.raw_data_len = data_len; + ftdm_span_send_signal(signal_data->ftdm_span, &sigev); +} + +void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len) { uint32_t str_len; uint8_t prot_disc, callRefFlag; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index 34cca80140..dc2d24f42a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -1589,7 +1589,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; ftdm_span_send_signal(ftdmchan->span, &sigev); /* if this is the first channel in the range */ @@ -1689,7 +1689,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; ftdm_span_send_signal(ftdmchan->span, &sigev); /* if this is the first channel in the range */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index 7517ee42a0..dcfb7f79e0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -2004,7 +2004,7 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* bring the sig status down */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; ftdm_span_send_signal(ftdmchan->span, &sigev); /* unlock the channel again before we exit */ @@ -2135,7 +2135,7 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* bring the sig status down */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; ftdm_span_send_signal(ftdmchan->span, &sigev); /* unlock the channel again before we exit */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 5c171a9f6b..05a325b913 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -841,7 +841,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", ""); /* all flags are down so we can bring up the sig status */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; ftdm_span_send_signal (ftdmchan->span, &sigev); } /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */ } /* if !blocked */ @@ -949,7 +949,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* if the sig_status is up...bring it down */ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; ftdm_span_send_signal (ftdmchan->span, &sigev); } @@ -1033,7 +1033,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* bring the sig status back up */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; ftdm_span_send_signal(ftdmchan->span, &sigev); } @@ -1046,7 +1046,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* bring the sig status down */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; ftdm_span_send_signal(ftdmchan->span, &sigev); /* go back to the last state */ @@ -1058,7 +1058,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* bring the sig status down */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; ftdm_span_send_signal(ftdmchan->span, &sigev); /* send a BLA */ @@ -1076,7 +1076,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* bring the sig status up */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; ftdm_span_send_signal(ftdmchan->span, &sigev); /* send a uba */ @@ -1092,7 +1092,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* bring the sig status down */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; ftdm_span_send_signal(ftdmchan->span, &sigev); /* send a blo */ @@ -1110,7 +1110,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* bring the sig status up */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; ftdm_span_send_signal(ftdmchan->span, &sigev); /* send a ubl */ @@ -1149,7 +1149,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* bring the channel signaling status to down */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; + sigev.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; ftdm_span_send_signal (ftdmchan->span, &sigev); /* remove any reset flags */ diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index f8f69abc71..18da29f566 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -325,12 +325,14 @@ typedef enum { FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */ FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */ FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */ - FTDM_SIGEVENT_FACILITY, /* !< In call facility event */ - FTDM_SIGEVENT_INVALID + FTDM_SIGEVENT_FACILITY, /*!< In call facility event */ + FTDM_SIGEVENT_TRACE, /*! Date: Wed, 15 Dec 2010 16:29:44 -0500 Subject: [PATCH 071/244] freetdm: Support for RAW traces --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index d8f98f1c61..6f6025ac36 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2077,7 +2077,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { - ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus; + ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->ev_data.sigstatus.status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n", spanid, chanid, ftdm_signaling_status2str(sigstatus)); } @@ -2183,7 +2183,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) break; case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { - ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus; + ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->ev_data.sigstatus.status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n", spanid, chanid, ftdm_signaling_status2str(sigstatus)); } From 53346e494876aaa5af9b9adf39e7f510cac938ad Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 15 Dec 2010 16:42:47 -0500 Subject: [PATCH 072/244] Freetdm: exposed channel availability rate to user --- libs/freetdm/src/ftdm_io.c | 12 ++++++++++++ libs/freetdm/src/include/freetdm.h | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 3fa763fe79..1750d6d7d9 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1702,6 +1702,18 @@ static ftdm_status_t __inline__ get_best_rated(ftdm_channel_t **fchan, ftdm_chan return FTDM_SUCCESS; } + +FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan) +{ + int availability = -1; + ftdm_channel_lock(ftdmchan); + if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_AV_RATE)) { + availability = ftdmchan->availability_rate; + } + ftdm_channel_unlock(ftdmchan); + return availability; +} + FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) { ftdm_status_t status = FTDM_FAIL; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 18da29f566..41bf819a1c 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -696,6 +696,14 @@ typedef enum { /*! \brief Override the default queue handler */ FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *handler); +/*! \brief Return the availability rate for a channel + * \param ftdmchan Channel to get the availability from + * + * \retval > 0 if availability is supported + * \retval -1 if availability is not supported + */ +FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan); + /*! \brief Answer call */ #define ftdm_channel_call_answer(ftdmchan) _ftdm_channel_call_answer(__FILE__, __FUNCTION__, __LINE__, (ftdmchan)) From 00046ee0f232cdd4dd9b98c376ad849cbbb90147 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Dec 2010 20:01:34 -0600 Subject: [PATCH 073/244] FS-2933 --- src/switch_ivr_originate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index e61534798b..b6ae346a66 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1751,6 +1751,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess early_state_t early_state = { 0 }; int read_packet = 0; int check_reject = 1; + switch_codec_implementation_t read_impl = { 0 }; if (strstr(bridgeto, SWITCH_ENT_ORIGINATE_DELIM)) { return switch_ivr_enterprise_originate(session, bleg, cause, bridgeto, timelimit_sec, table, cid_name_override, cid_num_override, @@ -1777,6 +1778,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_set_flag(caller_channel, CF_ORIGINATOR); oglobals.session = session; + switch_core_session_get_read_impl(session, &read_impl); if ((to_var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) { timelimit_sec = atoi(to_var); @@ -3066,7 +3068,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if ((ringback.fh || silence || ringback.audio_buffer || oglobals.bridge_early_media > -1) && write_frame.codec && write_frame.datalen) { if (silence) { - write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet; + write_frame.datalen = read_impl.decoded_bytes_per_packet; switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, silence); } From 93cc3dc556939a99288b50d8324d0299d0c61b86 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Dec 2010 20:59:23 -0600 Subject: [PATCH 074/244] normalize tests for outbound channels to use switch_channel_direction instead of testing for CF_OUTBOUND --- src/mod/applications/mod_conference/mod_conference.c | 8 ++++---- src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp | 1 - src/mod/endpoints/mod_h323/mod_h323.cpp | 3 +-- src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp | 1 - src/mod/endpoints/mod_opal/mod_opal.cpp | 5 ++--- src/mod/endpoints/mod_skinny/mod_skinny.c | 2 -- src/mod/endpoints/mod_skinny/skinny_server.c | 4 ++-- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 1 - src/mod/endpoints/mod_sofia/mod_sofia.c | 10 +++++----- src/mod/endpoints/mod_sofia/sofia.c | 12 ++++++------ src/mod/endpoints/mod_sofia/sofia_glue.c | 4 ++-- src/switch_channel.c | 6 +++--- src/switch_core_state_machine.c | 2 +- src/switch_cpp.cpp | 2 +- src/switch_ivr.c | 2 +- src/switch_ivr_bridge.c | 4 ++-- 16 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 9b170a32e0..53ce82b4cb 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2456,7 +2456,7 @@ static void conference_loop_output(conference_member_t *member) switch_event_destroy(&event); } - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { /* test to see if outbound channel has answered */ if (switch_channel_test_flag(channel, CF_ANSWERED) && !switch_test_flag(member->conference, CFLAG_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, @@ -2599,7 +2599,7 @@ static void conference_loop_output(conference_member_t *member) switch_channel_cause2str(switch_channel_get_cause(channel))); /* if it's an outbound channel, store the release cause in the conference struct, we might need it */ - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { member->conference->bridge_hangup_cause = switch_channel_get_cause(channel); } @@ -5446,7 +5446,7 @@ SWITCH_STANDARD_APP(conference_function) launch_conference_thread(conference); } else { - int enforce_security = !switch_channel_test_flag(channel, CF_OUTBOUND); + int enforce_security = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND; const char *pvar = switch_channel_get_variable(channel, "conference_enforce_security"); if (pvar) { @@ -5655,7 +5655,7 @@ SWITCH_STANDARD_APP(conference_function) } else { /* if we're not using "bridge:" set the conference answered flag */ /* and this isn't an outbound channel, answer the call */ - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) switch_set_flag(conference, CFLAG_ANSWERED); } diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp index 7e20b7c25e..13e433557d 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp @@ -1324,7 +1324,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_profile = tech_pvt->caller_profile; caller_profile->destination_number = rdest; - switch_channel_set_flag(channel, CF_OUTBOUND); switch_set_flag(tech_pvt, TFLAG_OUTBOUND); switch_channel_set_state(channel, CS_INIT); gsmopen_call(tech_pvt, rdest, 30); diff --git a/src/mod/endpoints/mod_h323/mod_h323.cpp b/src/mod/endpoints/mod_h323/mod_h323.cpp index 74fb6ae11a..3d79917434 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.cpp +++ b/src/mod/endpoints/mod_h323/mod_h323.cpp @@ -725,7 +725,6 @@ FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* tran name += outbound_profile->destination_number; switch_channel_set_name(m_fsChannel, name); - switch_channel_set_flag(m_fsChannel, CF_OUTBOUND); switch_channel_set_state(m_fsChannel, CS_INIT); } @@ -1508,7 +1507,7 @@ switch_status_t FSH323Connection::receive_message(switch_core_session_message_t break; } case SWITCH_MESSAGE_INDICATE_ANSWER: { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_FALSE; } AnsweringCall(H323Connection::AnswerCallNow); diff --git a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp index 3abbe3ecfb..1b126eb277 100644 --- a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp +++ b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp @@ -868,7 +868,6 @@ switch_status_t Board::KhompPvt::justStart(switch_caller_profile_t *profile) _caller_profile = switch_caller_profile_clone(_session, profile); switch_channel_set_caller_profile(channel, _caller_profile); - switch_channel_set_flag(channel, CF_OUTBOUND); switch_channel_set_state(channel, CS_INIT); } else diff --git a/src/mod/endpoints/mod_opal/mod_opal.cpp b/src/mod/endpoints/mod_opal/mod_opal.cpp index 8935bbb06d..0760588019 100644 --- a/src/mod/endpoints/mod_opal/mod_opal.cpp +++ b/src/mod/endpoints/mod_opal/mod_opal.cpp @@ -580,7 +580,6 @@ FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint, void* userDat name += outbound_profile->destination_number; switch_channel_set_name(m_fsChannel, name); - switch_channel_set_flag(m_fsChannel, CF_OUTBOUND); switch_channel_set_state(m_fsChannel, CS_INIT); } } @@ -966,7 +965,7 @@ switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg It would only happen if someone called switch_channel_answer() instead of switch_channel_mark_answered() on an outbound call. it should not do anything if someone does it by accident somewhere hense this in both cases: - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_FALSE; } @@ -1025,7 +1024,7 @@ switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg { int fixed = 0; - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_FALSE; } diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 2df8937647..5320ca52d1 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -1080,8 +1080,6 @@ switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, swi switch_channel_set_caller_profile(nchannel, caller_profile); tech_pvt->caller_profile = caller_profile; - switch_channel_set_flag(nchannel, CF_OUTBOUND); - if ((sql = switch_mprintf( "INSERT INTO skinny_active_lines " "(device_name, device_instance, line_instance, channel_uuid, call_id, call_state) " diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index c03e3ce8af..9bf9d9fb9b 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -343,7 +343,7 @@ switch_status_t skinny_session_send_call_info(switch_core_session_t *session, li zstr((called_party_number = switch_channel_get_variable(channel, "destination_number")))) { called_party_number = "0000000000"; } - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { call_type = SKINNY_INBOUND_CALL; } else { call_type = SKINNY_OUTBOUND_CALL; @@ -1674,7 +1674,7 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste ); switch_set_flag_locked(tech_pvt, TFLAG_IO); - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { switch_channel_mark_answered(channel); } if (switch_channel_test_flag(channel, CF_HOLD)) { diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 65c1b120fd..56188a4188 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -1364,7 +1364,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_profile = tech_pvt->caller_profile; caller_profile->destination_number = rdest; - switch_channel_set_flag(channel, CF_OUTBOUND); switch_mutex_lock(tech_pvt->flag_mutex); switch_set_flag(tech_pvt, TFLAG_OUTBOUND); switch_mutex_unlock(tech_pvt->flag_mutex); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 4a3c7c0479..07e125ad6c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -508,7 +508,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END()); } } else { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending CANCEL to %s\n", switch_channel_get_name(channel)); if (!tech_pvt->got_bye) { switch_channel_set_variable(channel, "sip_hangup_disposition", "send_cancel"); @@ -573,7 +573,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) char *sticky = NULL; const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full"); - if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_SUCCESS; } @@ -653,7 +653,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) switch_channel_clear_flag(channel, CF_PROXY_MODE); } - if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) { + if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); tech_pvt->num_codecs = 0; sofia_glue_tech_prepare_codecs(tech_pvt); @@ -1683,7 +1683,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE); if (!(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA))) { - if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) { + if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); tech_pvt->num_codecs = 0; @@ -2198,7 +2198,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } else { if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || !tech_pvt->iananame) { sofia_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION); - if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) { + if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); tech_pvt->num_codecs = 0; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7e4e34f4ab..94eab68858 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -357,7 +357,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, goto error; } - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { switch_channel_answer(channel); switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number")); switch_ivr_session_transfer(session, "auto_answer", NULL, NULL); @@ -4114,7 +4114,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } - if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { sip_contact_t *p_contact = sip->sip_contact; int i = 0; char var_name[80]; @@ -4645,7 +4645,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, status = 183; } - if (channel && (status == 180 || status == 183) && switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { const char *val; if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) { nua_notify(nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END()); @@ -4692,7 +4692,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (r_sdp) { if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { - if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) { + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA"); } sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); @@ -4715,7 +4715,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } goto done; } else { - if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && !switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) { + if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "DELAYED NEGOTIATION"); } else { if (sofia_glue_tech_media(tech_pvt, (char *) r_sdp) != SWITCH_STATUS_SUCCESS) { @@ -4910,7 +4910,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_glue_tech_set_local_sdp(tech_pvt, NULL, SWITCH_FALSE); if (!switch_channel_media_ready(channel)) { - if (!switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND)) { + if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { //const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); tech_pvt->num_codecs = 0; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 803059a8da..0f52bbc8fb 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -4687,8 +4687,8 @@ void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp) switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, sdp); if (!sofia_test_flag(tech_pvt, TFLAG_CHANGE_MEDIA) && !sofia_test_flag(tech_pvt, TFLAG_RECOVERING) && - (switch_channel_test_flag(other_channel, CF_OUTBOUND) && - switch_channel_test_flag(tech_pvt->channel, CF_OUTBOUND) && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) { + (switch_channel_direction(other_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && + switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) { switch_ivr_nomedia(val, SMF_FORCE); sofia_set_flag_locked(tech_pvt, TFLAG_CHANGE_MEDIA); } diff --git a/src/switch_channel.c b/src/switch_channel.c index a9c87c5954..b0ee9f527c 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2622,7 +2622,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_pre_answer(switch_channel return SWITCH_STATUS_SUCCESS; } - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { msg.message_id = SWITCH_MESSAGE_INDICATE_PROGRESS; msg.from = channel->name; status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line); @@ -2657,7 +2657,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_ring_ready_value(switch_c return SWITCH_STATUS_SUCCESS; } - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { msg.message_id = SWITCH_MESSAGE_INDICATE_RINGING; msg.from = channel->name; msg.numeric_arg = rv; @@ -2800,7 +2800,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t * switch_assert(channel != NULL); - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index c77f3f1a68..ccd6dacc9c 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -124,7 +124,7 @@ static void switch_core_standard_on_routing(switch_core_session_t *session) } if (!count) { - if (switch_channel_test_flag(session->channel, CF_OUTBOUND)) { + if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { if (switch_channel_test_flag(session->channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No Dialplan on answered channel, changing state to HANGUP\n"); diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 40462db567..1ba850d7e4 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -1206,7 +1206,7 @@ SWITCH_DECLARE(void) bridge(CoreSession &session_a, CoreSession &session_b) if (switch_channel_ready(channel_a) && switch_channel_ready(channel_b)) { session_a.begin_allow_threads(); - if (!switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_media_ready(channel_a)) { + if (switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_media_ready(channel_a)) { switch_channel_pre_answer(channel_a); } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 5cd4d4d34f..494871ec8a 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -140,7 +140,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, const char *var; /* - if (!switch_channel_test_flag(channel, CF_OUTBOUND) && !switch_channel_test_flag(channel, CF_PROXY_MODE) && + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_media_ready(channel) && !switch_channel_test_flag(channel, CF_SERVICE)) { if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media.\n"); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index afd33f16a0..ceab8b1b96 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -435,8 +435,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) switch_channel_t *un = ans_a ? chan_b : chan_a; switch_channel_t *a = un == chan_b ? chan_a : chan_b; - if (!switch_channel_test_flag(un, CF_OUTBOUND)) { - if (switch_channel_test_flag(a, CF_OUTBOUND) || (un == chan_a && !originator)) { + if (switch_channel_direction(un) == SWITCH_CALL_DIRECTION_INBOUND) { + if (switch_channel_direction(a) == SWITCH_CALL_DIRECTION_OUTBOUND || (un == chan_a && !originator)) { switch_channel_pass_callee_id(a, un); } From 43393f26d102ef63b24e776d33f53b5f44b84d3c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Dec 2010 20:59:33 -0600 Subject: [PATCH 075/244] normalize tests for outbound channels to use switch_channel_direction instead of testing for CF_OUTBOUND --- libs/freetdm/mod_freetdm/mod_freetdm.c | 15 ++++++++------- libs/openzap/mod_openzap/mod_openzap.c | 25 +++++++++++++------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 38197bb2f0..e0961e3f9a 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -802,7 +802,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio phy_id = ftdm_channel_get_ph_id(tech_pvt->ftdmchan); ftdm_log(FTDM_LOG_DEBUG, "Got Freeswitch message in R2 channel %d [%d]\n", phy_id, msg->message_id); - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_SUCCESS; } @@ -849,7 +849,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, return SWITCH_STATUS_SUCCESS; } - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_SUCCESS; } @@ -892,7 +892,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio return SWITCH_STATUS_FALSE; } - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_SUCCESS; } @@ -924,7 +924,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio return SWITCH_STATUS_FALSE; } - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { return SWITCH_STATUS_SUCCESS; } @@ -981,7 +981,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { if ((var = switch_channel_get_variable(channel, "freetdm_pre_buffer_size"))) { int tmp = atoi(var); if (tmp > -1) { @@ -1363,7 +1363,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi tech_pvt->caller_profile = caller_profile; - switch_channel_set_flag(channel, CF_OUTBOUND); switch_channel_set_state(channel, CS_INIT); if (ftdm_channel_add_token(ftdmchan, switch_core_session_get_uuid(*new_session), ftdm_channel_get_token_count(ftdmchan)) != FTDM_SUCCESS) { switch_core_session_destroy(new_session); @@ -1811,7 +1810,9 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); } - if (channel_a && channel_b && !switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_test_flag(channel_b, CF_OUTBOUND)) { + if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND && + switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) { + cause = SWITCH_CAUSE_ATTENDED_TRANSFER; if (br_a_uuid && br_b_uuid) { switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid); diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 8425372ef5..6a75dc85ff 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -821,7 +821,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_RINGING: { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); } else { zap_set_state_locked_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); @@ -830,7 +830,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio break; case SWITCH_MESSAGE_INDICATE_PROGRESS: { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA); } else { @@ -841,7 +841,7 @@ static switch_status_t channel_receive_message_cas(switch_core_session_t *sessio break; case SWITCH_MESSAGE_INDICATE_ANSWER: { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED); } else { /* lets make the ozmod_r2 module life easier by moving thru each @@ -888,7 +888,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_RINGING: { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); } else { zap_set_state_wait(tech_pvt->zchan, ZAP_CHANNEL_STATE_PROGRESS); @@ -897,7 +897,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, break; case SWITCH_MESSAGE_INDICATE_PROGRESS: { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_MEDIA); } else { @@ -914,7 +914,7 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session, break; case SWITCH_MESSAGE_INDICATE_ANSWER: { - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { zap_set_flag(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED); } else { /* Don't skip messages in the ISDN call setup @@ -957,7 +957,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED); zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA); @@ -991,7 +991,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_ANSWERED); zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_PROGRESS); zap_set_flag_locked(tech_pvt->zchan, ZAP_CHANNEL_MEDIA); @@ -1000,7 +1000,7 @@ static switch_status_t channel_receive_message_fxs(switch_core_session_t *sessio } break; case SWITCH_MESSAGE_INDICATE_RINGING: - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { if (!switch_channel_test_flag(channel, CF_ANSWERED) && !switch_channel_test_flag(channel, CF_EARLY_MEDIA) && @@ -1052,7 +1052,7 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: - if (!switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { if ((var = switch_channel_get_variable(channel, "openzap_pre_buffer_size"))) { int tmp = atoi(var); if (tmp > -1) { @@ -1327,7 +1327,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi tech_pvt->caller_profile = caller_profile; - switch_channel_set_flag(channel, CF_OUTBOUND); switch_channel_set_state(channel, CS_INIT); if (zap_channel_add_token(zchan, switch_core_session_get_uuid(*new_session), zchan->token_count) != ZAP_SUCCESS) { switch_core_session_destroy(new_session); @@ -1678,7 +1677,9 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal) switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); } - if (channel_a && channel_b && !switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_test_flag(channel_b, CF_OUTBOUND)) { + if (channel_a && channel_b && switch_channel_direction(channel_a) == SWITCH_CALL_DIRECTION_INBOUND && + switch_channel_direction(channel_b) == SWITCH_CALL_DIRECTION_INBOUND) { + cause = SWITCH_CAUSE_ATTENDED_TRANSFER; if (br_a_uuid && br_b_uuid) { switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid); From 3ff07445d4846f5b6c7b5338b396e60d330074fd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Dec 2010 09:45:43 -0600 Subject: [PATCH 076/244] add CF_DIALPLAN --- src/include/switch_types.h | 1 + src/switch_core_state_machine.c | 4 +++- src/switch_ivr_bridge.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index d020775d48..e04f437eb3 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1095,6 +1095,7 @@ typedef enum { CF_BRIDGE_NOWRITE, CF_RECOVERED, CF_JITTERBUFFER, + CF_DIALPLAN, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CF_FLAG_MAX } switch_channel_flag_t; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index ccd6dacc9c..59cc17d33a 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -123,7 +123,9 @@ static void switch_core_standard_on_routing(switch_core_session_t *session) } } - if (!count) { + if (count) { + switch_channel_set_flag(session->channel, CF_DIALPLAN); + } else { if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { if (switch_channel_test_flag(session->channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index ceab8b1b96..aa5ddb9232 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -100,7 +100,7 @@ static void send_display(switch_core_session_t *session, switch_core_session_t * caller_channel = switch_core_session_get_channel(session); caller_profile = switch_channel_get_caller_profile(caller_channel); - if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(caller_channel, CF_DIALPLAN)) { name = caller_profile->callee_id_name; number = caller_profile->callee_id_number; From c44b7a74651d2b7ae896a9180ce1f84433c540ed Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Dec 2010 10:10:15 -0600 Subject: [PATCH 077/244] fix formatting in debug mode --- libs/stfu/stfu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 4965b12e34..2ffb86fdb6 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -664,20 +664,21 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) } if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s ", i->name); for(y = 0; y < i->out_queue->array_size; y++) { - if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s", i->name); + if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s ", i->name); frame = &i->out_queue->array[y]; stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet); } - stfu_log(STFU_LOG_EMERG, "%s\n", i->name); + stfu_log(STFU_LOG_EMERG, "\n%s ", i->name); for(y = 0; y < i->in_queue->array_size; y++) { - if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s", i->name); + if ((y % 5) == 0) stfu_log(STFU_LOG_EMERG, "\n%s ", i->name); frame = &i->in_queue->array[y]; stfu_log(STFU_LOG_EMERG, "%u:%u\t", frame->ts, frame->ts / i->samples_per_packet); } - stfu_log(STFU_LOG_EMERG, "%s\n\n\n", i->name); + stfu_log(STFU_LOG_EMERG, "\n%s\n\n\n", i->name); } From 2081bf97b9836f5299c22edbb1ead077842ea2bc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Dec 2010 11:33:38 -0600 Subject: [PATCH 078/244] use a packet buffer for ESL --- Makefile.am | 6 +- libs/esl/Makefile | 6 +- libs/esl/src/esl.c | 155 ++++++++++++++++++++----------------- libs/esl/src/include/esl.h | 8 +- libs/esl/testclient.c | 41 ++++++++++ 5 files changed, 141 insertions(+), 75 deletions(-) diff --git a/Makefile.am b/Makefile.am index da89572c6f..df1ee2e0d0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -276,7 +276,8 @@ bin_PROGRAMS = freeswitch fs_cli fs_ivrd tone2wav fs_encode ## ## fs_cli () ## -fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c libs/esl/src/esl_json.c +fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c \ + libs/esl/src/esl_threadmutex.c libs/esl/fs_cli.c libs/esl/src/esl_json.c libs/esl/src/esl_buffer.c fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm @@ -304,7 +305,8 @@ tone2wav_LDADD = libfreeswitch.la ## ## fs_ivrd () ## -fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c libs/esl/src/esl_json.c +fs_ivrd_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_event.c \ + libs/esl/src/esl_threadmutex.c libs/esl/ivrd.c libs/esl/src/esl_json.c libs/esl/src/esl_buffer.c fs_ivrd_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include fs_ivrd_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm diff --git a/libs/esl/Makefile b/libs/esl/Makefile index a180406bda..ab50bac4d9 100644 --- a/libs/esl/Makefile +++ b/libs/esl/Makefile @@ -9,9 +9,9 @@ CXXFLAGS=$(BASE_FLAGS) -Wall -Werror -Wno-unused-variable MYLIB=libesl.a LIBS=-lncurses -lpthread -lesl -lm LDFLAGS=-L. -OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o -SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c -HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h src/include/esl_json.h +OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o src/esl_buffer.o +SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c src/esl_buffer.c +HEADERS=src/include/esl_config.h src/include/esl_event.h src/include/esl.h src/include/esl_threadmutex.h src/include/esl_oop.h src/include/esl_json.h src/include/esl_buffer.h SOLINK=-shared -Xlinker -x # comment the next line to disable c++ (no swig mods for you then) OBJS += src/esl_oop.o diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index ce582d3837..3397dbfb55 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -428,6 +428,10 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s esl_mutex_create(&handle->mutex); } + if (!handle->packet_buf) { + esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0); + } + handle->connected = 1; esl_send_recv(handle, "connect\n\n"); @@ -632,6 +636,10 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char * if (!handle->mutex) { esl_mutex_create(&handle->mutex); } + + if (!handle->packet_buf) { + esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0); + } handle->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -805,6 +813,11 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle) esl_mutex_destroy(&mutex); } + if (handle->packet_buf) { + esl_buffer_destroy(&handle->packet_buf); + } + + return status; } @@ -825,7 +838,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms if (check_q) { esl_mutex_lock(handle->mutex); - if (handle->race_event) { + if (handle->race_event || esl_buffer_packet_count(handle->packet_buf)) { esl_mutex_unlock(handle->mutex); return esl_recv_event(handle, check_q, save_event); } @@ -894,12 +907,15 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms } +static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t datalen) +{ + return recv(handle->sock, data, datalen, 0); +} ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event) { char *c; esl_ssize_t rrval; - int crc = 0; esl_event_t *revent = NULL; char *beg; char *hname, *hval; @@ -907,7 +923,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ char *cl; esl_ssize_t len; int zc = 0; - int bread = 0; if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) { return ESL_FAIL; @@ -916,9 +931,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ esl_mutex_lock(handle->mutex); if (!handle->connected || handle->sock == ESL_SOCK_INVALID) { - handle->connected = 0; - esl_mutex_unlock(handle->mutex); - return ESL_FAIL; + goto fail; } esl_event_safe_destroy(&handle->last_event); @@ -932,76 +945,62 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ goto parse_event; } - memset(handle->header_buf, 0, sizeof(handle->header_buf)); + + while(!revent && handle->connected) { + esl_size_t len; + + if ((len = esl_buffer_read_packet(handle->packet_buf, handle->socket_buf, sizeof(handle->socket_buf)))) { + char *data = (char *) handle->socket_buf; + char *p, *e; + + esl_event_create(&revent, ESL_EVENT_CLONE); + revent->event_id = ESL_EVENT_SOCKET_DATA; + esl_event_add_header_string(revent, ESL_STACK_BOTTOM, "Event-Name", "SOCKET_DATA"); + + hname = p = data; + while(p) { + hname = p; + p = NULL; - c = handle->header_buf; - beg = c; + if ((hval = strchr(hname, ':'))) { + *hval++ = '\0'; + while(*hval == ' ' || *hval == '\t') hval++; - while(handle->connected) { - if (bread + 2 >= sizeof(handle->header_buf)) { - esl_log(ESL_LOG_CRIT, "OUT OF BUFFER SPACE!\n"); - handle->connected = 0; - esl_mutex_unlock(handle->mutex); - return ESL_DISCONNECTED; + if ((e = strchr(hval, '\n'))) { + *e++ = '\0'; + while(*e == '\n' || *e == '\r') e++; + + if (hname && hval) { + esl_url_decode(hval); + esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval); + esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval); + } + + p = e; + } + } + } + + break; } - rrval = recv(handle->sock, c, 1, 0); + rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf)); + if (rrval == 0) { if (++zc >= 100) { - handle->connected = 0; - esl_mutex_unlock(handle->mutex); - return ESL_DISCONNECTED; + goto fail; } + continue; } else if (rrval < 0) { strerror_r(handle->errnum, handle->err, sizeof(handle->err)); goto fail; - } else { - zc = 0; - - if (*c == '\n') { - - *(c+1) = '\0'; - - if (++crc == 2) { - break; - } - - if (!revent) { - esl_event_create(&revent, ESL_EVENT_CLONE); - revent->event_id = ESL_EVENT_SOCKET_DATA; - esl_event_add_header_string(revent, ESL_STACK_BOTTOM, "Event-Name", "SOCKET_DATA"); - - } - - hname = beg; - hval = col = NULL; - - if (hname && (col = strchr(hname, ':'))) { - hval = col + 1; - *col = '\0'; - while(*hval == ' ') hval++; - } - - *c = '\0'; - - if (hname && hval) { - esl_url_decode(hval); - esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval); - esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval); - } - - c = beg; - bread = 0; - continue; - - } else { - crc = 0; - } - - c++; } - } + zc = 0; + + esl_buffer_write(handle->packet_buf, handle->socket_buf, rrval); + } + if (!revent) { goto fail; } @@ -1016,12 +1015,28 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ *(body + len) = '\0'; do { - esl_ssize_t r; - if ((r = recv(handle->sock, body + sofar, len - sofar, 0)) < 0) { - strerror_r(handle->errnum, handle->err, sizeof(handle->err)); - goto fail; + esl_ssize_t r,s = esl_buffer_inuse(handle->packet_buf); + + if (s >= len) { + sofar = esl_buffer_read(handle->packet_buf, body, len); + } else { + r = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf)); + + if (r < 0) { + strerror_r(handle->errnum, handle->err, sizeof(handle->err)); + goto fail; + } else if (r == 0) { + if (++zc >= 100) { + goto fail; + } + continue; + } + + zc = 0; + + esl_buffer_write(handle->packet_buf, handle->socket_buf, r); } - sofar += r; + } while (sofar < len); revent->body = body; @@ -1123,6 +1138,8 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ fail: + esl_mutex_unlock(handle->mutex); + handle->connected = 0; return ESL_FAIL; diff --git a/libs/esl/src/include/esl.h b/libs/esl/src/include/esl.h index 9f28c3d925..99ab53ae95 100644 --- a/libs/esl/src/include/esl.h +++ b/libs/esl/src/include/esl.h @@ -251,6 +251,7 @@ typedef int esl_filehandle_t; #include "esl_json.h" typedef int16_t esl_port_t; +typedef size_t esl_size_t; typedef enum { ESL_SUCCESS, @@ -259,7 +260,11 @@ typedef enum { ESL_DISCONNECTED } esl_status_t; +#define BUF_CHUNK 65536 * 50 +#define BUF_START 65536 * 100 + #include +#include /*! \brief A handle that will hold the socket information and different events received. */ @@ -273,7 +278,8 @@ typedef struct { /*! The error number reported by the OS */ int errnum; /*! The inner contents received by the socket. Used only internally. */ - char header_buf[4196]; + esl_buffer_t *packet_buf; + char socket_buf[65536]; /*! Last command reply */ char last_reply[1024]; /*! Las command reply when called with esl_send_recv */ diff --git a/libs/esl/testclient.c b/libs/esl/testclient.c index 9fa271fd0b..a031836d50 100644 --- a/libs/esl/testclient.c +++ b/libs/esl/testclient.c @@ -6,6 +6,47 @@ int main(void) { esl_handle_t handle = {{0}}; + esl_buffer_t *buffer; + char doh[65536]; + + esl_buffer_create(&buffer, 32 * 1024, 32 * 1024, 0); + + snprintf(doh, sizeof(doh), "TEST 1 FOO BAR 1234\n"); + esl_buffer_write(buffer, doh, strlen(doh)); + esl_buffer_write(buffer, doh, strlen(doh)); + esl_buffer_write(buffer, doh, strlen(doh)); + snprintf(doh, sizeof(doh), "TEST 1 END\n\n"); + esl_buffer_write(buffer, doh, strlen(doh)); + + + + snprintf(doh, sizeof(doh), "TEST 2 BAR FOO 4321\n"); + esl_buffer_write(buffer, doh, strlen(doh)); + esl_buffer_write(buffer, doh, strlen(doh)); + esl_buffer_write(buffer, doh, strlen(doh)); + snprintf(doh, sizeof(doh), "TEST 2 END\n\n"); + esl_buffer_write(buffer, doh, strlen(doh)); + + snprintf(doh, sizeof(doh), "TEST 2 BAR FOO 4321\n"); + esl_buffer_write(buffer, doh, strlen(doh)); + esl_buffer_write(buffer, doh, strlen(doh)); + esl_buffer_write(buffer, doh, strlen(doh)); + snprintf(doh, sizeof(doh), "TEST 2 END\n\n"); + esl_buffer_write(buffer, doh, strlen(doh)); + + printf("COUNT %ld\n", esl_buffer_packet_count(buffer)); + + memset(doh, 0, sizeof(doh)); + esl_buffer_read_packet(buffer, doh, sizeof(doh)); + printf("TEST: [%s]\n", doh); + + memset(doh, 0, sizeof(doh)); + + + esl_buffer_read_packet(buffer, doh, sizeof(doh)); + printf("TEST2: [%s]\n", doh); + + return 0; esl_connect(&handle, "localhost", 8021, NULL, "ClueCon"); From 2800ea199d6c233fe0aeee91de3be33dfee19607 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Dec 2010 11:34:02 -0600 Subject: [PATCH 079/244] tune event socket params a bit --- .../event_handlers/mod_event_socket/mod_event_socket.c | 10 +++++----- src/switch_event.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index ee7cfc9eaf..596a953dcb 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -31,8 +31,8 @@ */ #include #define CMD_BUFLEN 1024 * 1000 -#define MAX_QUEUE_LEN 5000 -#define MAX_MISSED 200 +#define MAX_QUEUE_LEN 25000 +#define MAX_MISSED 2000 SWITCH_MODULE_LOAD_FUNCTION(mod_event_socket_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_socket_shutdown); SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime); @@ -170,7 +170,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) { switch_log_node_t *dnode = switch_log_node_dup(node); - if (switch_queue_trypush(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) { + if (switch_queue_push(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) { if (l->lost_logs) { int ll = l->lost_logs; switch_event_t *event; @@ -366,7 +366,7 @@ static void event_handler(switch_event_t *event) if (send) { if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) { - if (switch_queue_trypush(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) { + if (switch_queue_push(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) { if (l->lost_events) { int le = l->lost_events; l->lost_events = 0; @@ -1233,7 +1233,7 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event, if (switch_channel_get_state(chan) < CS_HANGUP && switch_channel_test_flag(chan, CF_DIVERT_EVENTS)) { switch_event_t *e = NULL; while (switch_core_session_dequeue_event(listener->session, &e, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { - if (switch_queue_trypush(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) { + if (switch_queue_push(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) { switch_core_session_queue_event(listener->session, &e); break; } diff --git a/src/switch_event.c b/src/switch_event.c index f782c15900..dce42f8e29 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -339,7 +339,7 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t *thread, voi launch_dispatch_threads(SOFT_MAX_DISPATCH + 1, DISPATCH_QUEUE_LEN, RUNTIME_POOL); switch_mutex_unlock(EVENT_QUEUE_MUTEX); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Out of threads!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Out of event dispatch threads! Slowing things down.\n"); switch_yield(1000000); } } From 526436fd1f8c15b5a8bb82557245d56a5587c536 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Dec 2010 11:58:18 -0600 Subject: [PATCH 080/244] doh --- libs/esl/src/esl_buffer.c | 354 ++++++++++++++++++++++++++++++ libs/esl/src/include/esl_buffer.h | 146 ++++++++++++ 2 files changed, 500 insertions(+) create mode 100644 libs/esl/src/esl_buffer.c create mode 100644 libs/esl/src/include/esl_buffer.h diff --git a/libs/esl/src/esl_buffer.c b/libs/esl/src/esl_buffer.c new file mode 100644 index 0000000000..51fbfb2768 --- /dev/null +++ b/libs/esl/src/esl_buffer.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2010, Anthony Minessale II + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "esl_buffer.h" + +static unsigned buffer_id = 0; + +struct esl_buffer { + unsigned char *data; + unsigned char *head; + esl_size_t used; + esl_size_t actually_used; + esl_size_t datalen; + esl_size_t max_len; + esl_size_t blocksize; + unsigned id; + int loops; +}; + + +ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t blocksize, esl_size_t start_len, esl_size_t max_len) +{ + esl_buffer_t *new_buffer; + + new_buffer = malloc(sizeof(*new_buffer)); + if (new_buffer) { + memset(new_buffer, 0, sizeof(*new_buffer)); + + if (start_len) { + new_buffer->data = malloc(start_len); + if (!new_buffer->data) { + free(new_buffer); + return ESL_FAIL; + } + memset(new_buffer->data, 0, start_len); + } + + new_buffer->max_len = max_len; + new_buffer->datalen = start_len; + new_buffer->id = buffer_id++; + new_buffer->blocksize = blocksize; + new_buffer->head = new_buffer->data; + + *buffer = new_buffer; + return ESL_SUCCESS; + } + + return ESL_FAIL; +} + +ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer) +{ + + assert(buffer != NULL); + + return buffer->datalen; + +} + + +ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer) +{ + assert(buffer != NULL); + + + if (buffer->max_len) { + return (esl_size_t) (buffer->max_len - buffer->used); + } + return 1000000; + +} + +ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer) +{ + assert(buffer != NULL); + + return buffer->used; +} + +ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen) +{ + esl_size_t reading = 0; + + assert(buffer != NULL); + + if (buffer->used < 1) { + buffer->used = 0; + return 0; + } else if (buffer->used >= datalen) { + reading = datalen; + } else { + reading = buffer->used; + } + + buffer->used = buffer->actually_used - reading; + buffer->head = buffer->data + reading; + + return reading; +} + +ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen) +{ + esl_size_t reading = 0; + + assert(buffer != NULL); + + if (buffer->used < 1) { + buffer->used = 0; + return 0; + } else if (buffer->used >= datalen) { + reading = datalen; + } else { + reading = buffer->used; + } + + buffer->used -= reading; + buffer->head += reading; + + return buffer->used; +} + +ESL_DECLARE(void) esl_buffer_set_loops(esl_buffer_t *buffer, int loops) +{ + buffer->loops = loops; +} + +ESL_DECLARE(esl_size_t) esl_buffer_read_loop(esl_buffer_t *buffer, void *data, esl_size_t datalen) +{ + esl_size_t len; + if ((len = esl_buffer_read(buffer, data, datalen)) < datalen) { + if (buffer->loops == 0) { + return len; + } + buffer->head = buffer->data; + buffer->used = buffer->actually_used; + len = esl_buffer_read(buffer, (char*)data + len, datalen - len); + buffer->loops--; + } + return len; +} + +ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen) +{ + esl_size_t reading = 0; + + assert(buffer != NULL); + assert(data != NULL); + + + if (buffer->used < 1) { + buffer->used = 0; + return 0; + } else if (buffer->used >= datalen) { + reading = datalen; + } else { + reading = buffer->used; + } + + memcpy(data, buffer->head, reading); + buffer->used -= reading; + buffer->head += reading; + + /* if (buffer->id == 4) printf("%u o %d = %d\n", buffer->id, (unsigned)reading, (unsigned)buffer->used); */ + return reading; +} + + +ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer) +{ + char *pe, *p, *e, *head = (char *) buffer->head; + esl_size_t x = 0; + + assert(buffer != NULL); + + e = (head + buffer->used); + + for (p = head; p && *p && p < e; p++) { + if (*p == '\n') { + pe = p+1; + if (*pe == '\r') pe++; + if (pe <= e && *pe == '\n') { + p = pe++; + x++; + } + } + } + + return x; +} + +ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen) +{ + char *pe, *p, *e, *head = (char *) buffer->head; + esl_size_t datalen = 0; + + assert(buffer != NULL); + assert(data != NULL); + + e = (head + buffer->used); + + for (p = head; p && *p && p < e; p++) { + if (*p == '\n') { + pe = p+1; + if (*pe == '\r') pe++; + if (pe <= e && *pe == '\n') { + pe++; + datalen = pe - head; + if (datalen > maxlen) { + datalen = maxlen; + } + break; + } + } + } + + return esl_buffer_read(buffer, data, datalen); +} + +ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen) +{ + esl_size_t freespace, actual_freespace; + + assert(buffer != NULL); + assert(data != NULL); + assert(buffer->data != NULL); + + if (!datalen) { + return buffer->used; + } + + actual_freespace = buffer->datalen - buffer->actually_used; + if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) { + memmove(buffer->data, buffer->head, buffer->used); + buffer->head = buffer->data; + buffer->actually_used = buffer->used; + } + + freespace = buffer->datalen - buffer->used; + + /* + if (buffer->data != buffer->head) { + memmove(buffer->data, buffer->head, buffer->used); + buffer->head = buffer->data; + } + */ + + if (freespace < datalen) { + esl_size_t new_size, new_block_size; + void *data; + + new_size = buffer->datalen + datalen; + new_block_size = buffer->datalen + buffer->blocksize; + + if (new_block_size > new_size) { + new_size = new_block_size; + } + buffer->head = buffer->data; + data = realloc(buffer->data, new_size); + if (!data) { + return 0; + } + buffer->data = data; + buffer->head = buffer->data; + buffer->datalen = new_size; + } + + + freespace = buffer->datalen - buffer->used; + + if (freespace < datalen) { + return 0; + } else { + memcpy(buffer->head + buffer->used, data, datalen); + buffer->used += datalen; + buffer->actually_used += datalen; + } + /* if (buffer->id == 4) printf("%u i %d = %d\n", buffer->id, (unsigned)datalen, (unsigned)buffer->used); */ + + return buffer->used; +} + +ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer) +{ + assert(buffer != NULL); + assert(buffer->data != NULL); + + buffer->used = 0; + buffer->actually_used = 0; + buffer->head = buffer->data; +} + +ESL_DECLARE(esl_size_t) esl_buffer_zwrite(esl_buffer_t *buffer, const void *data, esl_size_t datalen) +{ + esl_size_t w; + + if (!(w = esl_buffer_write(buffer, data, datalen))) { + esl_buffer_zero(buffer); + return esl_buffer_write(buffer, data, datalen); + } + + return w; +} + +ESL_DECLARE(void) esl_buffer_destroy(esl_buffer_t **buffer) +{ + if (*buffer) { + free((*buffer)->data); + free(*buffer); + } + + *buffer = NULL; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/libs/esl/src/include/esl_buffer.h b/libs/esl/src/include/esl_buffer.h new file mode 100644 index 0000000000..c7901e4ede --- /dev/null +++ b/libs/esl/src/include/esl_buffer.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2010, Anthony Minessale II + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "esl.h" +#ifndef ESL_BUFFER_H +#define ESL_BUFFER_H +/** + * @defgroup esl_buffer Buffer Routines + * @ingroup buffer + * The purpose of this module is to make a plain buffering interface that can be used for read/write buffers + * throughout the application. + * @{ + */ +struct esl_buffer; +typedef struct esl_buffer esl_buffer_t; + +/*! \brief Allocate a new dynamic esl_buffer + * \param buffer returned pointer to the new buffer + * \param blocksize length to realloc by as data is added + * \param start_len ammount of memory to reserve initially + * \param max_len length the buffer is allowed to grow to + * \return status + */ +ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t blocksize, esl_size_t start_len, esl_size_t max_len); + +/*! \brief Get the length of a esl_buffer_t + * \param buffer any buffer of type esl_buffer_t + * \return int size of the buffer. + */ +ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer); + +/*! \brief Get the freespace of a esl_buffer_t + * \param buffer any buffer of type esl_buffer_t + * \return int freespace in the buffer. + */ +ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer); + +/*! \brief Get the in use amount of a esl_buffer_t + * \param buffer any buffer of type esl_buffer_t + * \return int ammount of buffer curently in use + */ +ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer); + +/*! \brief Read data from a esl_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer. + * \param buffer any buffer of type esl_buffer_t + * \param data pointer to the read data to be returned + * \param datalen amount of data to be returned + * \return int ammount of data actually read + */ +ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_size_t datalen); + +ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, esl_size_t maxlen); +ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer); + +/*! \brief Read data endlessly from a esl_buffer_t + * \param buffer any buffer of type esl_buffer_t + * \param data pointer to the read data to be returned + * \param datalen amount of data to be returned + * \return int ammount of data actually read + * \note Once you have read all the data from the buffer it will loop around. + */ +ESL_DECLARE(esl_size_t) esl_buffer_read_loop(esl_buffer_t *buffer, void *data, esl_size_t datalen); + +/*! \brief Assign a number of loops to read + * \param buffer any buffer of type esl_buffer_t + * \param loops the number of loops (-1 for infinite) + */ +ESL_DECLARE(void) esl_buffer_set_loops(esl_buffer_t *buffer, int32_t loops); + +/*! \brief Write data into a esl_buffer_t up to the length of datalen + * \param buffer any buffer of type esl_buffer_t + * \param data pointer to the data to be written + * \param datalen amount of data to be written + * \return int amount of buffer used after the write, or 0 if no space available + */ +ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen); + +/*! \brief Remove data from the buffer + * \param buffer any buffer of type esl_buffer_t + * \param datalen amount of data to be removed + * \return int size of buffer, or 0 if unable to toss that much data + */ +ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen); + +/*! \brief Remove all data from the buffer + * \param buffer any buffer of type esl_buffer_t + */ +ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer); + +/*! \brief Destroy the buffer + * \param buffer buffer to destroy + * \note only neccessary on dynamic buffers (noop on pooled ones) + */ +ESL_DECLARE(void) esl_buffer_destroy(esl_buffer_t **buffer); + +/*! \brief Seek to offset from the beginning of the buffer + * \param buffer buffer to seek + * \param datalen offset in bytes + * \return new position + */ +ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen); + +/** @} */ + +ESL_DECLARE(esl_size_t) esl_buffer_zwrite(esl_buffer_t *buffer, const void *data, esl_size_t datalen); + +#endif +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ From 871c871b80d314b08bdf82e40e5ea04193c0f5a6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Dec 2010 12:17:02 -0600 Subject: [PATCH 081/244] wrong week to quit sniffing glue --- libs/esl/testclient.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/libs/esl/testclient.c b/libs/esl/testclient.c index a031836d50..9fa271fd0b 100644 --- a/libs/esl/testclient.c +++ b/libs/esl/testclient.c @@ -6,47 +6,6 @@ int main(void) { esl_handle_t handle = {{0}}; - esl_buffer_t *buffer; - char doh[65536]; - - esl_buffer_create(&buffer, 32 * 1024, 32 * 1024, 0); - - snprintf(doh, sizeof(doh), "TEST 1 FOO BAR 1234\n"); - esl_buffer_write(buffer, doh, strlen(doh)); - esl_buffer_write(buffer, doh, strlen(doh)); - esl_buffer_write(buffer, doh, strlen(doh)); - snprintf(doh, sizeof(doh), "TEST 1 END\n\n"); - esl_buffer_write(buffer, doh, strlen(doh)); - - - - snprintf(doh, sizeof(doh), "TEST 2 BAR FOO 4321\n"); - esl_buffer_write(buffer, doh, strlen(doh)); - esl_buffer_write(buffer, doh, strlen(doh)); - esl_buffer_write(buffer, doh, strlen(doh)); - snprintf(doh, sizeof(doh), "TEST 2 END\n\n"); - esl_buffer_write(buffer, doh, strlen(doh)); - - snprintf(doh, sizeof(doh), "TEST 2 BAR FOO 4321\n"); - esl_buffer_write(buffer, doh, strlen(doh)); - esl_buffer_write(buffer, doh, strlen(doh)); - esl_buffer_write(buffer, doh, strlen(doh)); - snprintf(doh, sizeof(doh), "TEST 2 END\n\n"); - esl_buffer_write(buffer, doh, strlen(doh)); - - printf("COUNT %ld\n", esl_buffer_packet_count(buffer)); - - memset(doh, 0, sizeof(doh)); - esl_buffer_read_packet(buffer, doh, sizeof(doh)); - printf("TEST: [%s]\n", doh); - - memset(doh, 0, sizeof(doh)); - - - esl_buffer_read_packet(buffer, doh, sizeof(doh)); - printf("TEST2: [%s]\n", doh); - - return 0; esl_connect(&handle, "localhost", 8021, NULL, "ClueCon"); From dfdf4e1e23e527e82c6bd1c44870fbe59d1db312 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 16 Dec 2010 12:27:55 -0600 Subject: [PATCH 082/244] windows fix for last esl commit --- libs/esl/src/esl.2008.vcproj | 8 ++++++++ libs/esl/src/esl.2010.vcxproj | 2 ++ 2 files changed, 10 insertions(+) diff --git a/libs/esl/src/esl.2008.vcproj b/libs/esl/src/esl.2008.vcproj index 101348dd59..89daa17d9e 100644 --- a/libs/esl/src/esl.2008.vcproj +++ b/libs/esl/src/esl.2008.vcproj @@ -290,6 +290,10 @@ RelativePath=".\esl.c" > + + @@ -316,6 +320,10 @@ RelativePath=".\include\esl.h" > + + diff --git a/libs/esl/src/esl.2010.vcxproj b/libs/esl/src/esl.2010.vcxproj index b215fe4bc8..fd5e3a8353 100644 --- a/libs/esl/src/esl.2010.vcxproj +++ b/libs/esl/src/esl.2010.vcxproj @@ -128,6 +128,7 @@ + @@ -135,6 +136,7 @@ + From a082c9e913bb3d777d29e4692a8a6e8afcd552e2 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 17:01:06 -0200 Subject: [PATCH 083/244] freetdm: ftmod_r2 - implemented ftdm_r2_get_span_sig_status() and ftdm_r2_set_span_sig_status() mod_freetdm - created sigstatus api command --- libs/freetdm/mod_freetdm/mod_freetdm.c | 78 +++++++++++++++++++++- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 71 +++++++++++++++++++- 2 files changed, 147 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 38197bb2f0..daddc9abc1 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3542,7 +3542,83 @@ SWITCH_STANDARD_API(ft_function) goto end; } - if (!strcasecmp(argv[0], "dump")) { + if (!strcasecmp(argv[0], "sigstatus")) { + ftdm_span_t *span = NULL; + ftdm_signaling_status_t sigstatus; + + if (argc < 3) { + stream->write_function(stream, "-ERR Usage: ftdm sigstatus get|set [] [] []\n"); + goto end; + } + if (!strcasecmp(argv[1], "get") && argc < 3) { + stream->write_function(stream, "-ERR sigstatus get usage: get \n"); + goto end; + } + if (!strcasecmp(argv[1], "set") && argc != 5) { + stream->write_function(stream, "-ERR sigstatus set usage: set |all \n"); + goto end; + } + + ftdm_span_find_by_name(argv[2], &span); + if (!span) { + stream->write_function(stream, "-ERR invalid span\n"); + goto end; + } + + if (!strcasecmp(argv[1], "get")) { + if (argc == 4) { + uint32_t chan_id = atol(argv[3]); + ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); + if (!fchan) { + stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id); + goto end; + } + + if ((FTDM_SUCCESS == ftdm_channel_get_sig_status(fchan, &sigstatus))) { + stream->write_function(stream, "channel %d signaling status: %s\n", chan_id, ftdm_signaling_status2str(sigstatus)); + } else { + stream->write_function(stream, "-ERR failed to get channel sigstatus\n"); + } + goto end; + } else { + if ((FTDM_SUCCESS == ftdm_span_get_sig_status(span, &sigstatus))) { + stream->write_function(stream, "signaling_status: %s\n", ftdm_signaling_status2str(sigstatus)); + } else { + stream->write_function(stream, "-ERR failed to read span status: %s\n", ftdm_span_get_last_error(span)); + } + } + goto end; + } + if (!strcasecmp(argv[1], "set")) { + sigstatus = ftdm_str2ftdm_signaling_status(argv[4]); + + if (!strcasecmp(argv[3], "all")) { + if ((FTDM_SUCCESS == ftdm_span_set_sig_status(span, sigstatus))) { + stream->write_function(stream, "Signaling status of all channels from span %s set to %s\n", + ftdm_span_get_name(span), ftdm_signaling_status2str(sigstatus)); + } else { + stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus)); + } + goto end; + } else { + uint32_t chan_id = atol(argv[3]); + ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); + if (!fchan) { + stream->write_function(stream, "-ERR failed to get channel id '%d'\n", chan_id); + goto end; + } + + if ((FTDM_SUCCESS == ftdm_channel_set_sig_status(fchan, sigstatus))) { + stream->write_function(stream, "Signaling status of channel %d set to %s\n", chan_id, + ftdm_signaling_status2str(sigstatus)); + } else { + stream->write_function(stream, "-ERR failed to set span sigstatus to '%s'\n", ftdm_signaling_status2str(sigstatus)); + } + goto end; + } + } + + } else if (!strcasecmp(argv[0], "dump")) { if (argc < 2) { stream->write_function(stream, "-ERR Usage: ftdm dump []\n"); goto end; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index ef9201bbe6..b4e9e138cc 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -461,12 +461,79 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) openr2_chan_set_idle(r2chan); break; default: - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%s'\n", status); + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); return FTDM_FAIL; } return FTDM_SUCCESS; } +static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status) +{ + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *citer = NULL; + uint32_t i; + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + if (!chaniter) { + ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); + return FTDM_FAIL; + } + /* if ALL channels are non-idle, report SUSPENDED. UP otherwise. */ + *status = FTDM_SIG_STATE_SUSPENDED; + for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + ftdm_channel_t *fchan = ftdm_iterator_current(citer); + + if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) { + *status = FTDM_SIG_STATE_UP; + break; + } + } + ftdm_iterator_free(chaniter); + return FTDM_SUCCESS; +} + +static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) +{ + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *citer = NULL; + uint32_t span_opr = -1; + uint32_t i; + + /* we either set the channels to BLOCK or IDLE */ + switch(status) { + case FTDM_SIG_STATE_DOWN: + case FTDM_SIG_STATE_SUSPENDED: + span_opr = 0; + break; + case FTDM_SIG_STATE_UP: + span_opr = 1; + break; + default: + ftdm_log(FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); + return FTDM_FAIL; + } + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + if (!chaniter) { + ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); + return FTDM_FAIL; + } + /* iterate over all channels, setting them to the requested state */ + for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + ftdm_channel_t *fchan = ftdm_iterator_current(citer); + openr2_chan_t *r2chan = R2CALL(fchan)->r2chan; + if (span_opr == 0) { + openr2_chan_set_blocked(r2chan); + ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel blocked\n"); + } else { + openr2_chan_set_idle(r2chan); + ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel idle\n"); + } + } + ftdm_iterator_free(chaniter); + return FTDM_SUCCESS; +} + /* always called from the monitor thread */ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) { @@ -1441,6 +1508,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) span->signal_type = FTDM_SIGTYPE_R2; span->signal_data = r2data; span->outgoing_call = r2_outgoing_call; + span->get_span_sig_status = ftdm_r2_get_span_sig_status; + span->set_span_sig_status = ftdm_r2_set_span_sig_status; span->get_channel_sig_status = ftdm_r2_get_channel_sig_status; span->set_channel_sig_status = ftdm_r2_set_channel_sig_status; From dcce6bb510ccc2096350abba07ff9f9efb8e6b9f Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 16 Dec 2010 13:52:46 -0600 Subject: [PATCH 084/244] vs2010 fix build --- libs/esl/src/esl_buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/esl/src/esl_buffer.c b/libs/esl/src/esl_buffer.c index 51fbfb2768..8032169fe3 100644 --- a/libs/esl/src/esl_buffer.c +++ b/libs/esl/src/esl_buffer.c @@ -277,7 +277,7 @@ ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, if (freespace < datalen) { esl_size_t new_size, new_block_size; - void *data; + void *data1; new_size = buffer->datalen + datalen; new_block_size = buffer->datalen + buffer->blocksize; @@ -286,11 +286,11 @@ ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, new_size = new_block_size; } buffer->head = buffer->data; - data = realloc(buffer->data, new_size); - if (!data) { + data1 = realloc(buffer->data, new_size); + if (!data1) { return 0; } - buffer->data = data; + buffer->data = data1; buffer->head = buffer->data; buffer->datalen = new_size; } From 6b66a0516bcc4d7bd9461366ea7bf958b4ef9aeb Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 18:19:50 -0200 Subject: [PATCH 085/244] freetdm: ftmod_r2 - fixed infinite loop on span stop --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index d1b24da1b8..952b94b63f 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -55,10 +55,13 @@ static int32_t g_thread_count = 0; typedef int openr2_call_status_t; -/* when the users kills a span we clear this flag to kill the signaling thread */ +/* when the user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread + * knows it must stop, and we wait for FTDM_R2_RUNNING to be clear, which tells us the + * signaling thread is done. */ /* FIXME: what about the calls that are already up-and-running? */ typedef enum { FTDM_R2_RUNNING = (1 << 0), + FTDM_R2_SPAN_STARTED = (1 << 1), } ftdm_r2_flag_t; /* private call information stored in ftdmchan->call_data void* ptr, @@ -424,13 +427,14 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) static ftdm_status_t ftdm_r2_start(ftdm_span_t *span) { ftdm_r2_data_t *r2_data = span->signal_data; - ftdm_set_flag(r2_data, FTDM_R2_RUNNING); + ftdm_set_flag(r2_data, FTDM_R2_SPAN_STARTED); return ftdm_thread_create_detached(ftdm_r2_run, span); } static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span) { ftdm_r2_data_t *r2_data = span->signal_data; + ftdm_clear_flag(r2_data, FTDM_R2_SPAN_STARTED); while (ftdm_test_flag(r2_data, FTDM_R2_RUNNING)) { ftdm_log(FTDM_LOG_DEBUG, "Waiting for R2 span %s\n", span->name); ftdm_sleep(100); @@ -1759,6 +1763,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) uint32_t txqueue_size = 4; short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); + /* as long as this thread is running, this flag is set */ + ftdm_set_flag(r2data, FTDM_R2_RUNNING); + #ifdef __linux__ r2data->monitor_thread_id = syscall(SYS_gettid); #endif @@ -1781,7 +1788,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) memset(&start, 0, sizeof(start)); memset(&end, 0, sizeof(end)); - while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_RUNNING)) { + while (ftdm_running() && ftdm_test_flag(r2data, FTDM_R2_SPAN_STARTED)) { res = gettimeofday(&end, NULL); if (res) { ftdm_log(FTDM_LOG_CRIT, "Failure gettimeofday [%s]\n", strerror(errno)); From 7b1de56baa504c97cd42790fa3defc9f2182f9c1 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 16 Dec 2010 14:24:54 -0600 Subject: [PATCH 086/244] vs2010 fix build --- libs/esl/src/esl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 3397dbfb55..f5bab62fcb 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -947,9 +947,9 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ while(!revent && handle->connected) { - esl_size_t len; + esl_size_t len1; - if ((len = esl_buffer_read_packet(handle->packet_buf, handle->socket_buf, sizeof(handle->socket_buf)))) { + if ((len1 = esl_buffer_read_packet(handle->packet_buf, handle->socket_buf, sizeof(handle->socket_buf)))) { char *data = (char *) handle->socket_buf; char *p, *e; From 43dd86fb96f8a20b405df6f6fda932ad6cc2e017 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 18:47:40 -0200 Subject: [PATCH 087/244] freetdm: ftmod_r2 - small code clean --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 952b94b63f..9f35971abb 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -473,20 +473,16 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status) { - ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *citer = NULL; - uint32_t i; - - chaniter = ftdm_span_get_chan_iterator(span, NULL); + ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL); if (!chaniter) { ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); return FTDM_FAIL; } /* if ALL channels are non-idle, report SUSPENDED. UP otherwise. */ *status = FTDM_SIG_STATE_SUSPENDED; - for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { ftdm_channel_t *fchan = ftdm_iterator_current(citer); - if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) { *status = FTDM_SIG_STATE_UP; break; @@ -501,7 +497,6 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *citer = NULL; uint32_t span_opr = -1; - uint32_t i; /* we either set the channels to BLOCK or IDLE */ switch(status) { @@ -523,7 +518,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) return FTDM_FAIL; } /* iterate over all channels, setting them to the requested state */ - for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { ftdm_channel_t *fchan = ftdm_iterator_current(citer); openr2_chan_t *r2chan = R2CALL(fchan)->r2chan; if (span_opr == 0) { From a134136ee715f6b392ec8bf3c5b3e31af7953c18 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Thu, 16 Dec 2010 19:44:32 -0200 Subject: [PATCH 088/244] freetdm: ftmod_r2 - notify the core when we change the signaling status of a channel or span through the api --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 9f35971abb..14eca429e8 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -468,6 +468,7 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); return FTDM_FAIL; } + ftdm_r2_set_chan_sig_status(ftdmchan, status); return FTDM_SUCCESS; } @@ -528,6 +529,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) openr2_chan_set_idle(r2chan); ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel idle\n"); } + ftdm_r2_set_chan_sig_status(fchan, status); } ftdm_iterator_free(chaniter); return FTDM_SUCCESS; From 9db4a8265c8e43d36a3333f96e4cc13a8fc1c37c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Dec 2010 16:03:05 -0600 Subject: [PATCH 089/244] tweak on calle[re] id --- src/switch_channel.c | 2 ++ src/switch_core_state_machine.c | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index b0ee9f527c..ef21e8c8f1 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2386,6 +2386,8 @@ SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *chann { switch_assert(channel != NULL); + switch_channel_set_flag(channel, CF_DIALPLAN); + switch_mutex_lock(channel->profile_mutex); caller_extension->next = channel->caller_profile->caller_extension; channel->caller_profile->caller_extension = caller_extension; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 59cc17d33a..ccd6dacc9c 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -123,9 +123,7 @@ static void switch_core_standard_on_routing(switch_core_session_t *session) } } - if (count) { - switch_channel_set_flag(session->channel, CF_DIALPLAN); - } else { + if (!count) { if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { if (switch_channel_test_flag(session->channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, From 0f937ca13415ee60fb636cdbb6e6e5121d4fcb63 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 16 Dec 2010 18:29:45 -0500 Subject: [PATCH 090/244] freetdm: Add documentation on sig status --- libs/freetdm/docs/sigstatus.txt | 59 ++++++++++++++++++++++++++++++ libs/freetdm/src/include/freetdm.h | 1 + 2 files changed, 60 insertions(+) create mode 100644 libs/freetdm/docs/sigstatus.txt diff --git a/libs/freetdm/docs/sigstatus.txt b/libs/freetdm/docs/sigstatus.txt new file mode 100644 index 0000000000..10561bfb5b --- /dev/null +++ b/libs/freetdm/docs/sigstatus.txt @@ -0,0 +1,59 @@ +FreeTDM can both notify and set signaling status changes in the different protocols thru a unified interface. More +specific details on the C data types and function prototypes are found in freetdm.h + +The API provides the following functions and data types to do it: + +The signaling status in any channel/span is represented thru ftdm_signaling_status_t + + /* The signaling link is down (no d-chans up in the span/group, MFC-R2 bit pattern unidentified) */ + FTDM_SIG_STATE_DOWN, + /* The signaling link is suspended (MFC-R2 bit pattern blocked, PRI maintenance, ss7 blocked?) */ + FTDM_SIG_STATE_SUSPENDED, + /* The signaling link is ready and calls can be placed (ie: d-chan up, MFC-R2 both rx and tx in IDLE) */ + FTDM_SIG_STATE_UP, + /* Invalid status */ + FTDM_SIG_STATE_INVALID + +Changes in the signaling status are notified to the user using the standard callback notification function provided +during configuration using the sigevent type FTDM_SIGEVENT_SIGSTATUS_CHANGED which is sent when the line status changes. + +On startup the signalling status default is FTDM_SIG_STATE_DOWN, and no notification is provided until the state change, +so applications must assume the status is down unless told otherwise. + +When ftdm_span_start is called, the signaling stack takes care of attempting to bring the status to UP +but it will ultimately depend on the other side too. + +== Setting the signaling status == + +Users can set the signaling status on a given channel/span thru FreeTDM the following API functions: + +ftdm_channel_set_sig_status +ftdm_span_set_sig_status + +If the user calls ftdm_channel_set_sig_status(chan, FTDM_SIG_STATE_SUSPENDED), the signaling stack will try to set +the status of the line to the one requested, if successful, it will result in a SIGEVENT_SIGSTATUS_CHANGED notification +being sent with status FTDM_SIG_STATE_SUSPENDED. + +** MFC-R2 Signaling Notes ** +For MFC-R2, calling ftdm_span_start() results in setting the tx CAS bits to IDLE. However, if the rx bits are in BLOCKED state +the signaling status will be reported as SUSPENDED. + +If the user calls ftdm_channel_set_sig_status(chan, SUSPENDED), the tx CAS bits will be set to BLOCKED and, if, the current rx bits +are IDLE then a SIGEVENT_SIGSTATUS_CHANGED with state SUSPENDED will be sent. If the rx bits are already in blocked then no further +SIGEVENT_SIGSTATUS_CHANGED notification is needed (because it was already sent when the rx bits were initially detected as BLOCKED). + +If the user calls ftdm_channel_set_sig_status(chan, UP), the tx CAS bits will be set to IDLE and, if, the current rx bits +are IDLE, then SIGEVENT_SIGSTATUS_CHANGED with state UP will be sent. If the rx bits are BLOCKED, then no notification is +sent at all until the rx bits change. + +Bottom line is, for MFC-R2, SIGEVENT_SIGSTATUS_CHANGED UP is only sent to the user when both the rx and tx bits are in IDLE, and +SIGEVENT_SIGSTATUS_CHANGED SUSPENDED is only sent to the user when any of the rx or tx bits are in BLOCKED. + +== Getting the signaling status == +Users can get the signaling status on a given channel/span thru FreeTDM the following API functions: + +ftdm_channel_get_sig_status +ftdm_span_get_sig_status + +The line status returned should be the same as the last time a SIGEVENT_SIGSTATUS_CHANGED was reported. + diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 41bf819a1c..56a9dc0577 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -367,6 +367,7 @@ typedef struct ftdm_channel_config { /*! \brief Signaling status on a given span or specific channel on protocols that support it + \note see docs/sigstatus.txt for more extensive documentation on signaling status */ typedef enum { /* The signaling link is down (no d-chans up in the span/group, MFC-R2 bit pattern unidentified) */ From ae7279f1741234e4c3209c7eec9e743791df1087 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Fri, 17 Dec 2010 08:44:20 -0600 Subject: [PATCH 091/244] skypopen: added hrtimers support to OSS audio driver --- src/mod/endpoints/mod_skypopen/oss/main.c | 168 +++++++++++++++--- src/mod/endpoints/mod_skypopen/oss/skypopen.h | 23 ++- 2 files changed, 163 insertions(+), 28 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 4fd959f44a..2abc5b342a 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -60,15 +60,18 @@ MODULE_LICENSE("Dual BSD/GPL"); static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */ -#define GIOVA_BLK 1920 -#define GIOVA_SLEEP 20 +static int unload = 0; +#ifdef CENTOS +#define HRTIMER_MODE_REL HRTIMER_REL +#endif// CENTOS +#ifndef WANT_HRTIMER void my_timer_callback_inq( unsigned long data ) { struct skypopen_dev *dev = (void *)data; wake_up_interruptible(&dev->inq); - mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + mod_timer( &dev->timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); } @@ -77,8 +80,66 @@ void my_timer_callback_outq( unsigned long data ) struct skypopen_dev *dev = (void *)data; wake_up_interruptible(&dev->outq); - mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + mod_timer( &dev->timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); } +#else// WANT_HRTIMER + +#ifndef CENTOS +static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq ) +{ + struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); + ktime_t now; + + if(unload) + return HRTIMER_NORESTART; + + now = ktime_get(); + hrtimer_forward(&dev->timer_inq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->inq); + + return HRTIMER_RESTART; +} +static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq ) +{ + struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq); + ktime_t now; + + if(unload) + return HRTIMER_NORESTART; + + now = ktime_get(); + hrtimer_forward(&dev->timer_outq, now, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->outq); + + return HRTIMER_RESTART; +} +#else// CENTOS +static int my_hrtimer_callback_inq( struct hrtimer *timer_inq ) +{ + struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); + + if(unload) + return HRTIMER_NORESTART; + + hrtimer_forward(&dev->timer_inq, timer_inq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->inq); + + return HRTIMER_RESTART; +} +static int my_hrtimer_callback_outq( struct hrtimer *timer_outq ) +{ + struct skypopen_dev *dev = container_of(timer_outq, struct skypopen_dev, timer_outq); + + if(unload) + return HRTIMER_NORESTART; + + hrtimer_forward(&dev->timer_outq, timer_outq->expires, ktime_set(0, SKYPOPEN_SLEEP * 1000000)); + wake_up_interruptible(&dev->outq); + + return HRTIMER_RESTART; +} +#endif// CENTOS +#endif// WANT_HRTIMER /* The clone-specific data structure includes a key field */ @@ -97,6 +158,12 @@ static spinlock_t skypopen_c_lock = SPIN_LOCK_UNLOCKED; static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) { struct skypopen_listitem *lptr; +#ifdef WANT_HRTIMER +#if 0 + ktime_t ktime_inq; + ktime_t ktime_outq; +#endif //0 +#endif// WANT_HRTIMER list_for_each_entry(lptr, &skypopen_c_list, list) { if (lptr->key == key) @@ -112,14 +179,29 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) memset(lptr, 0, sizeof(struct skypopen_listitem)); lptr->key = key; - init_waitqueue_head(&lptr->device.inq); - init_waitqueue_head(&lptr->device.outq); - setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); - setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); - printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); - mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); - printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); - mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(GIOVA_SLEEP) ); + init_waitqueue_head(&lptr->device.inq); + init_waitqueue_head(&lptr->device.outq); +#ifndef WANT_HRTIMER + setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); + setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); + printk( "Starting skypopen OSS driver read timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); + mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); + printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); + mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); +#else// WANT_HRTIMER +#if 0 + ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &lptr->device.timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + lptr->device.timer_inq.function = &my_hrtimer_callback_inq; + hrtimer_start( &lptr->device.timer_inq, ktime_inq, HRTIMER_MODE_REL ); + + ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &lptr->device.timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + lptr->device.timer_outq.function = &my_hrtimer_callback_outq; + hrtimer_start( &lptr->device.timer_outq, ktime_outq, HRTIMER_MODE_REL ); +#endif + +#endif// WANT_HRTIMER /* place it in the list */ list_add(&lptr->list, &skypopen_c_list); @@ -135,7 +217,7 @@ static int skypopen_c_open(struct inode *inode, struct file *filp) struct skypopen_dev *dev; dev_t key; - key = current->pid; + key = current->tgid; /* look for a skypopenc device in the list */ spin_lock(&skypopen_c_lock); @@ -163,12 +245,27 @@ static int skypopen_c_release(struct inode *inode, struct file *filp) /*************************************************************/ -ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, +static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { - struct skypopen_dev *dev = filp->private_data; DEFINE_WAIT(wait); + struct skypopen_dev *dev = filp->private_data; +#ifdef WANT_HRTIMER +#if 1 + if(dev->timer_inq_started == 0){ + ktime_t ktime_inq; + ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &dev->timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + dev->timer_inq.function = &my_hrtimer_callback_inq; + hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL ); + dev->timer_inq_started = 1; + } +#endif +#endif// WANT_HRTIMER + + + //printk("READ\n"); prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->inq, &wait); @@ -176,12 +273,27 @@ ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, } -ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, +static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { - struct skypopen_dev *dev = filp->private_data; DEFINE_WAIT(wait); + struct skypopen_dev *dev = filp->private_data; +#ifdef WANT_HRTIMER +#if 1 + if(dev->timer_outq_started == 0){ + ktime_t ktime_outq; + ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); + hrtimer_init( &dev->timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + dev->timer_outq.function = &my_hrtimer_callback_outq; + hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL ); + dev->timer_outq_started = 1; + } +#endif +#endif// WANT_HRTIMER + + + //printk("WRITE\n"); prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->outq, &wait); @@ -192,7 +304,7 @@ ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, * The ioctl() implementation */ -int skypopen_ioctl(struct inode *inode, struct file *filp, +static int skypopen_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; @@ -202,7 +314,7 @@ int skypopen_ioctl(struct inode *inode, struct file *filp, case OSS_GETVERSION: return put_user(SOUND_VERSION, p); case SNDCTL_DSP_GETBLKSIZE: - return put_user(GIOVA_BLK, p); + return put_user(SKYPOPEN_BLK, p); case SNDCTL_DSP_GETFMTS: return put_user(28731, p); @@ -239,6 +351,11 @@ void skypopen_cleanup_module(void) struct skypopen_listitem *lptr, *next; dev_t devno = MKDEV(skypopen_major, skypopen_minor); + + unload = 1; + + msleep(100); + /* Get rid of our char dev entries */ if (skypopen_devices) { for (i = 0; i < skypopen_nr_devs; i++) { @@ -247,13 +364,20 @@ void skypopen_cleanup_module(void) kfree(skypopen_devices); } - /* And all the cloned devices */ list_for_each_entry_safe(lptr, next, &skypopen_c_list, list) { +#ifndef WANT_HRTIMER ret= del_timer( &lptr->device.timer_inq ); - //printk( "Stopped skypopen OSS driver read timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); + printk( "Stopped skypopen OSS driver read timer\n"); ret= del_timer( &lptr->device.timer_outq ); - //printk( "Stopped skypopen OSS driver write timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid ); + printk( "Stopped skypopen OSS driver write timer\n"); +#else// WANT_HRTIMER + ret = hrtimer_cancel( &lptr->device.timer_inq ); + printk( "Stopped skypopen OSS driver read HRtimer\n"); + ret = hrtimer_cancel( &lptr->device.timer_outq ); + printk( "Stopped skypopen OSS driver write HRtimer\n"); + +#endif// WANT_HRTIMER list_del(&lptr->list); kfree(lptr); } diff --git a/src/mod/endpoints/mod_skypopen/oss/skypopen.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h index 5469048c04..2324e448cb 100644 --- a/src/mod/endpoints/mod_skypopen/oss/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/oss/skypopen.h @@ -20,6 +20,11 @@ #include /* needed for the _IOW etc stuff used later */ +#define SKYPOPEN_BLK 960 +#define SKYPOPEN_SLEEP 10 + +#define CENTOS + #ifndef SKYPOPEN_MAJOR #define SKYPOPEN_MAJOR 14 /* dynamic major by default */ #endif @@ -28,12 +33,18 @@ #define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */ #endif +#define WANT_HRTIMER struct skypopen_dev { struct cdev cdev; /* Char device structure */ wait_queue_head_t inq; /* read and write queues */ wait_queue_head_t outq; /* read and write queues */ +#ifndef WANT_HRTIMER struct timer_list timer_inq; struct timer_list timer_outq; +#else// WANT_HRTIMER + struct hrtimer timer_inq; + struct hrtimer timer_outq; +#endif// WANT_HRTIMER int timer_inq_started; int timer_outq_started; }; @@ -50,11 +61,11 @@ extern int skypopen_nr_devs; * Prototypes for shared functions */ -ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, - loff_t *f_pos); -ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos); -int skypopen_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +//ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, + //loff_t *f_pos); +//ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, + //loff_t *f_pos); +//int skypopen_ioctl(struct inode *inode, struct file *filp, + //unsigned int cmd, unsigned long arg); #endif /* _SKYPOPEN_H_ */ From c2262aba2be55a9df2a14be5560ac0227516cd49 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 17 Dec 2010 09:52:26 -0500 Subject: [PATCH 092/244] freetdm: Fix for OPENZAP-128 ioctl interface in FreeBSD expects unsigned long --- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 70 ++++++++++++---------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 7320934a49..f40196499c 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -53,42 +53,48 @@ static struct { float txgain; } zt_globals; +#if defined(__FreeBSD__) +typedef unsigned long ioctlcmd; +#else +typedef int ioctlcmd; +#endif + /** * \brief General IOCTL codes */ struct ioctl_codes { - int GET_BLOCKSIZE; - int SET_BLOCKSIZE; - int FLUSH; - int SYNC; - int GET_PARAMS; - int SET_PARAMS; - int HOOK; - int GETEVENT; - int IOMUX; - int SPANSTAT; - int MAINT; - int GETCONF; - int SETCONF; - int CONFLINK; - int CONFDIAG; - int GETGAINS; - int SETGAINS; - int SPANCONFIG; - int CHANCONFIG; - int SET_BUFINFO; - int GET_BUFINFO; - int AUDIOMODE; - int ECHOCANCEL; - int HDLCRAWMODE; - int HDLCFCSMODE; - int SPECIFY; - int SETLAW; - int SETLINEAR; - int GETCONFMUTE; - int ECHOTRAIN; - int SETTXBITS; - int GETRXBITS; + ioctlcmd GET_BLOCKSIZE; + ioctlcmd SET_BLOCKSIZE; + ioctlcmd FLUSH; + ioctlcmd SYNC; + ioctlcmd GET_PARAMS; + ioctlcmd SET_PARAMS; + ioctlcmd HOOK; + ioctlcmd GETEVENT; + ioctlcmd IOMUX; + ioctlcmd SPANSTAT; + ioctlcmd MAINT; + ioctlcmd GETCONF; + ioctlcmd SETCONF; + ioctlcmd CONFLINK; + ioctlcmd CONFDIAG; + ioctlcmd GETGAINS; + ioctlcmd SETGAINS; + ioctlcmd SPANCONFIG; + ioctlcmd CHANCONFIG; + ioctlcmd SET_BUFINFO; + ioctlcmd GET_BUFINFO; + ioctlcmd AUDIOMODE; + ioctlcmd ECHOCANCEL; + ioctlcmd HDLCRAWMODE; + ioctlcmd HDLCFCSMODE; + ioctlcmd SPECIFY; + ioctlcmd SETLAW; + ioctlcmd SETLINEAR; + ioctlcmd GETCONFMUTE; + ioctlcmd ECHOTRAIN; + ioctlcmd SETTXBITS; + ioctlcmd GETRXBITS; }; /** From d3a24be0baa8a98eabacef7b0ee7b3d088ada316 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Fri, 17 Dec 2010 15:50:11 -0200 Subject: [PATCH 093/244] freetdm: ftmod_r2 - updated ftdm_r2_set_channel_sig_status() to notify the user of signaling changes just when specified on docs/sigstatus.txt. also updated ftdm_r2_set_span_sig_status(), so that it uses the former to set channels status, instead of doing it directly. --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 56 +++++++++++++--------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 14eca429e8..5377250588 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -456,19 +456,43 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status) static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) { openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; + openr2_cas_signal_t rxcas, txcas; + + /* get the current rx and tx cas bits */ + openr2_chan_get_cas(r2chan, &rxcas, &txcas); + + /* if we're already in the state the user asks us to be, we have nothing to do */ + if (status == FTDM_SIG_STATE_SUSPENDED && txcas == OR2_CAS_BLOCK) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel signaling status already in BLOCK state\n"); + return FTDM_SUCCESS; + } + if (status == FTDM_SIG_STATE_UP && txcas == OR2_CAS_IDLE) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel signaling status already in IDLE state\n"); + return FTDM_SUCCESS; + } + + /* set the signaling as requested and send SIGEVENT_SIGSTATUS_CHANGED, if applicable. + * see docs/sigstatus.txt for details */ switch(status) { - case FTDM_SIG_STATE_DOWN: case FTDM_SIG_STATE_SUSPENDED: openr2_chan_set_blocked(r2chan); + if (rxcas == OR2_CAS_IDLE) { + ftdm_r2_set_chan_sig_status(ftdmchan, status); + } break; case FTDM_SIG_STATE_UP: openr2_chan_set_idle(r2chan); + if (rxcas == OR2_CAS_IDLE) { + ftdm_r2_set_chan_sig_status(ftdmchan, status); + } break; + case FTDM_SIG_STATE_DOWN: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "The user is not allowed to set signaling status to DOWN\n"); + return FTDM_FAIL; default: ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); return FTDM_FAIL; } - ftdm_r2_set_chan_sig_status(ftdmchan, status); return FTDM_SUCCESS; } @@ -497,20 +521,10 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) { ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *citer = NULL; - uint32_t span_opr = -1; - /* we either set the channels to BLOCK or IDLE */ - switch(status) { - case FTDM_SIG_STATE_DOWN: - case FTDM_SIG_STATE_SUSPENDED: - span_opr = 0; - break; - case FTDM_SIG_STATE_UP: - span_opr = 1; - break; - default: - ftdm_log(FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); - return FTDM_FAIL; + if (status == FTDM_SIG_STATE_DOWN) { + ftdm_log(FTDM_LOG_WARNING, "The user is not allowed to set the span signaling status to DOWN\n"); + return FTDM_FAIL; } chaniter = ftdm_span_get_chan_iterator(span, NULL); @@ -521,15 +535,11 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) /* iterate over all channels, setting them to the requested state */ for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { ftdm_channel_t *fchan = ftdm_iterator_current(citer); - openr2_chan_t *r2chan = R2CALL(fchan)->r2chan; - if (span_opr == 0) { - openr2_chan_set_blocked(r2chan); - ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel blocked\n"); - } else { - openr2_chan_set_idle(r2chan); - ftdm_log_chan_msg(fchan, FTDM_LOG_NOTICE, "Channel idle\n"); + /* we set channel's state through ftdm_r2_set_channel_sig_status(), since it already takes + * care of notifying the user when appropriate */ + if ((ftdm_r2_set_channel_sig_status(fchan, status)) != FTDM_SUCCESS) { + ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to set signaling status to %s\n", ftdm_signaling_status2str(status)); } - ftdm_r2_set_chan_sig_status(fchan, status); } ftdm_iterator_free(chaniter); return FTDM_SUCCESS; From bad1eb118358e0b814cde075388c4e342992e4bf Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Fri, 17 Dec 2010 12:19:14 -0800 Subject: [PATCH 094/244] Update ChangeLog through Dec 16, 2010 --- docs/ChangeLog | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/ChangeLog b/docs/ChangeLog index 96066b6e8c..0ca48c0e81 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -20,6 +20,7 @@ freeswitch (1.0.7) build: Remove mod_spidermonkey from windows 2008 x64 builds - does not work (r:280e894d) build: fix warnings on windows x64 builds src and mods projects - only libsofia included on the libs side (r:45ecbc2f) build: Patch debian init.d script to set ulimit values (r:0eb33e57/FS-2844) + build: add plc to core (r:b7c80a84) codec2: working prototype, still for testing only (r:04ca0751) config: move limit.conf to db.conf config: Update VM phrase macros to voice option then action on main, config menus @@ -33,6 +34,7 @@ freeswitch (1.0.7) config: Fix phrase files, still missing a sound file (r:6741f350/FS-2742) config: Disallow global-intercept and group-intercept can intercept an outbound call in default dialplan (r:890871ba/FS-2777) config: fix single domain assumption in default config to be more portable *cough* bkw *cough* (r:f987903e) + config: Bump Doxygen.conf version to 1.0.6... belatedly (r:cfeae1ba) core: Add RTCP support (FSRTP-14) core: handle some errors on missing db handle conditions core: add ... and shutdown as a fail-safe when no modules are loaded @@ -145,6 +147,15 @@ freeswitch (1.0.7) core: Application intercept causes FS to stop processing calls (r:12fc65f7/FS-2872) core: fix edge cases for endless loop in sql thread (r:5d7c09ed) core: prevent race while changing codecs mid call (r:7aa72b67) + core: Fix crash in ODBC when SQL Server kills TCP connection (r:5aba96e3/FS-2910) + core: Fix fallback to CORE_DB when MSSQL fails init (r:3406d05b) + core: add new function to init an empty switch_sockaddr_t to avoid an unnecessary dns lookup on 0.0.0.0 (r:009c41d4) + core: fix endless RTP loop in Windows (r:cb2d0736/FS-2924) + core: play_and_get_digits should actually timeout, not last forever... (r:28cab5ed/FS-2923) + core: Fix crash w/o core dump (r:00046ee0/FS-2933) + core: normalize tests for outbound channels to use switch_channel_direction instead of testing for CF_OUTBOUND (r:93cc3dc5) + core: add CF_DIALPLAN (r:3ff07445) + core: tweak on calle[re] id (r:9db4a826) lang: Improve French phrase files (FSCONFIG-23) libapr: Fix issue where after a bridge with a member, uuid of Agent is set to single quote character ' (r:3fee704d/FS-2738) libdingaling: fix race on shutdown causing crash (FSMOD-47) @@ -163,6 +174,8 @@ freeswitch (1.0.7) libesl: fix leak-on-error in esl_connect_timeout() (r:4263d60e) libesl: Call close on connection handle if the connection fails (r:413dcc4c/ESL-50) libesl: allow fs_cli -x to have args up to 1024 chars (was 256) (r:7039ba47) + libesl: Make last_event pointer last longer (r:a15f51d5/ESL-37) + libesl: use a packet buffer for ESL (r:2081bf97) libfreetdm: implemented freetdm config nodes and ss7 initial configuration libfreetdm: fix codec for CAS signaling (r:b76e7f18) libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c) @@ -220,6 +233,8 @@ freeswitch (1.0.7) mod_commands: add escaping empty strings to sql_escape (r:7bd0a5a6/FS-2833) mod_commands: add uuid_fileman : <-- same vals as the callbacks in js and lua to control the currently playing file of a channel from the cli or ESL (for the people who were ignoring me on the conference call so I decided to implement it instead of try to explain it ) (r:c4369fc8) mod_commands: FS-2210 Add support for auto completion for uuid_simplify (r:72bcc01b/FS-2210) + mod_commands: allow epoch in strftime_tz (r:bbf1cd1f) + mod_commands: Dramatic jitterbuffer changes (r:d5470961) mod_conference: Fix reporting of volume up/down (MODAPP-419) mod_conference: add last talking time per member to conference xml list mod_conference: add terminate-on-silence conference param @@ -229,6 +244,7 @@ freeswitch (1.0.7) mod_conference: Fix floor change events not always firing (r:8f1767d3/MODAPP-424) mod_conference: refactor conference to use switch_ivr_dmachine for the digit parsing controls are now bound to each member separately based on conference_controls channel var, then the caller-controls param in the profile or a default to "default" (r:ac19f73c) mod_conference: Fix crash on dtmf action (r:4d5389bd/FS-2781) + mod_conference: revert to the last transfered conference on recover (r:d11c83b1) mod_curl: use method=post when post requested (r:c6a4ddd0/FSMOD-69) mod_db: fix stack corruption (MODAPP-407) mod_dialplan_xml: Add in the INFO log the caller id number when processing a request (Currenly only show the caller name) (r:e1df5e13) @@ -500,6 +516,11 @@ freeswitch (1.0.7) mod_sofia: Fix wrong IP in VIA and contact HEADER for MESSAGE method while fs run in private network (r:59ea4a1b/FS-2886) mod_sofia: SIP-header History-Info might exist multiple times, but only last header is exposed as a channel variable (r:8cf15012/FS-2881) mod_sofia: Add support to reboot Yealink phone remotely (r:fdc31908/FS-2897) + mod_sofia: Add reuse-connections sofia profile param to allow users to turn off TPTAG_REUSE, thus not re-using TCP connections (r:98ed05cc) + mod_sofia: Make sofia recover also work on custom uuid (r:3a645dee/FS-2913) + mod_sofia: remove check for va_list completely in sofia since i don't even think it happens ever (r:dfecc914) + mod_sofia: have mod_sofia always elect to be the session refresher so we know it will work, also make the session-expires set to 0 imply 100% disabled session timers (r:321013ef) + mod_sofia: Do not set nat mode when the device's network_ip is within the acl also so if your FS is behind nat and your phone is too then it will still make the right decisions (r:6c6eab8c) mod_spandsp: initial checkin of mod_fax/mod_voipcodecs merge into mod_spandsp (r:fa9a59a8) mod_spandsp: rework of new mod_spandsp to have functions broken up into different c files (r:65400642) mod_spandsp: improve duplicate digit detection and add 'min_dup_digit_spacing_ms' channel variable for use with the dtmf detector (r:eab4f246/FSMOD-45) @@ -515,6 +536,7 @@ freeswitch (1.0.7) mod_spidermonkey: fix seg in js hangup (r:7d554c11) mod_spidermonkey: Fix mod_spidermonkey build on FreeBSD, (Undefined symbol PR_LocalTimeParameters). (r:3edb8419) mod_spy: add support for loopback endpoint (MODAPP-416) + mod_spy: fix crash when session can't be located (r:c4154633/FS-2929) mod_tts_commandline: fix core dump, temp file problem. flush can be called several times (FSMOD-35) mod_unimrcp: fix fortify findings for mod_unimrcp (r:336f0b4e/FSMOD-67) mod_valet_parking: add event data to valet parking hold event From 6b522089574944f85c94825f3b0bbc3ebfe8a715 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Fri, 17 Dec 2010 18:28:57 -0200 Subject: [PATCH 095/244] freetdm: core - moved validation of sigstatus from implementation to core, on sigstatus getters/setters core - locking the channel on ftdm_channel_get_sig_status() and ftdm_channel_set_sig_status(), but not on ftdm_span_get_sig_status() nor ftdm_span_set_sig_status() ftmod_r2 - locking channels on ftdm_r2_get_span_sig_status() and ftdm_r2_set_span_sig_status() --- libs/freetdm/src/ftdm_io.c | 24 +++++++++++++++++++--- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 13 +++++------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 1750d6d7d9..7fb5afdb59 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2488,9 +2488,18 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_sig_status(ftdm_channel_t *ftdmchan, { ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel\n"); ftdm_assert_return(ftdmchan->span != NULL, FTDM_FAIL, "Null span\n"); - + + if (sigstatus == FTDM_SIG_STATE_DOWN) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "The user is not allowed to set the signaling status to DOWN, valid states are UP or SUSPENDED\n"); + return FTDM_FAIL; + } + if (ftdmchan->span->set_channel_sig_status) { - return ftdmchan->span->set_channel_sig_status(ftdmchan, sigstatus); + ftdm_status_t res; + ftdm_channel_lock(ftdmchan); + res = ftdmchan->span->set_channel_sig_status(ftdmchan, sigstatus); + ftdm_channel_unlock(ftdmchan); + return res; } else { ftdm_log(FTDM_LOG_ERROR, "set_channel_sig_status method not implemented!\n"); return FTDM_FAIL; @@ -2504,7 +2513,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_sig_status(ftdm_channel_t *ftdmchan, ftdm_assert_return(sigstatus != NULL, FTDM_FAIL, "Null sig status parameter\n"); if (ftdmchan->span->get_channel_sig_status) { - return ftdmchan->span->get_channel_sig_status(ftdmchan, sigstatus); + ftdm_status_t res; + ftdm_channel_lock(ftdmchan); + res = ftdmchan->span->get_channel_sig_status(ftdmchan, sigstatus); + ftdm_channel_unlock(ftdmchan); + return res; } else { /* don't log error here, it can be called just to test if its supported */ return FTDM_NOTIMPL; @@ -2515,6 +2528,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa { ftdm_assert_return(span != NULL, FTDM_FAIL, "Null span\n"); + if (sigstatus == FTDM_SIG_STATE_DOWN) { + ftdm_log(FTDM_LOG_WARNING, "The user is not allowed to set the signaling status to DOWN, valid states are UP or SUSPENDED\n"); + return FTDM_FAIL; + } + if (span->set_span_sig_status) { return span->set_span_sig_status(span, sigstatus); } else { diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 5377250588..ccf7fdf89a 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -486,9 +486,6 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_channel_sig_status) ftdm_r2_set_chan_sig_status(ftdmchan, status); } break; - case FTDM_SIG_STATE_DOWN: - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "The user is not allowed to set signaling status to DOWN\n"); - return FTDM_FAIL; default: ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot set signaling status to unknown value '%d'\n", status); return FTDM_FAIL; @@ -508,10 +505,13 @@ static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status) *status = FTDM_SIG_STATE_SUSPENDED; for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { ftdm_channel_t *fchan = ftdm_iterator_current(citer); + ftdm_channel_lock(fchan); if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) { *status = FTDM_SIG_STATE_UP; + ftdm_channel_unlock(fchan); break; } + ftdm_channel_unlock(fchan); } ftdm_iterator_free(chaniter); return FTDM_SUCCESS; @@ -522,11 +522,6 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *citer = NULL; - if (status == FTDM_SIG_STATE_DOWN) { - ftdm_log(FTDM_LOG_WARNING, "The user is not allowed to set the span signaling status to DOWN\n"); - return FTDM_FAIL; - } - chaniter = ftdm_span_get_chan_iterator(span, NULL); if (!chaniter) { ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); @@ -537,9 +532,11 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_r2_set_span_sig_status) ftdm_channel_t *fchan = ftdm_iterator_current(citer); /* we set channel's state through ftdm_r2_set_channel_sig_status(), since it already takes * care of notifying the user when appropriate */ + ftdm_channel_lock(fchan); if ((ftdm_r2_set_channel_sig_status(fchan, status)) != FTDM_SUCCESS) { ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to set signaling status to %s\n", ftdm_signaling_status2str(status)); } + ftdm_channel_unlock(fchan); } ftdm_iterator_free(chaniter); return FTDM_SUCCESS; From 8f452bc5199c6964518f9b505fa904493b3814e9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 17 Dec 2010 14:35:53 -0600 Subject: [PATCH 096/244] cid logic changes for calle[re] --- src/include/switch_channel.h | 2 ++ src/mod/endpoints/mod_sofia/mod_sofia.c | 2 ++ src/switch_channel.c | 40 +++++++++++++++++++++++-- src/switch_ivr.c | 15 ---------- src/switch_ivr_bridge.c | 4 +++ src/switch_ivr_originate.c | 18 ----------- 6 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index d6bce5e8bf..e726554d81 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -312,6 +312,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switc */ SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension); +SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel, switch_bool_t in); + /*! \brief Retrieve caller extension from a given channel \param channel channel to retrieve extension from diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 07e125ad6c..884e5bf9f5 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4065,6 +4065,8 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_channel_set_variable(nchannel, "sip_invite_params", "intercom=true"); } + DUMP_EVENT(var_event); + if (((hval = switch_event_get_header(var_event, "effective_callee_id_name")) || (hval = switch_event_get_header(var_event, "sip_callee_id_name"))) && !zstr(hval)) { caller_profile->callee_id_name = switch_core_strdup(caller_profile->pool, hval); diff --git a/src/switch_channel.c b/src/switch_channel.c index ef21e8c8f1..aa7f6699b7 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2382,12 +2382,48 @@ SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switc return status; } +SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel, switch_bool_t in) +{ + + if (in) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(channel, CF_DIALPLAN)) { + switch_channel_set_flag(channel, CF_DIALPLAN); + + switch_mutex_lock(channel->profile_mutex); + if (channel->caller_profile->callee_id_name) { + switch_channel_set_variable(channel, "pre_transfer_caller_id_name", channel->caller_profile->caller_id_name); + channel->caller_profile->caller_id_name = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_name); + } + channel->caller_profile->callee_id_name = SWITCH_BLANK_STRING; + + if (channel->caller_profile->callee_id_number) { + switch_channel_set_variable(channel, "pre_transfer_caller_id_number", channel->caller_profile->caller_id_number); + channel->caller_profile->caller_id_number = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_number); + } + channel->caller_profile->callee_id_number = SWITCH_BLANK_STRING; + switch_mutex_unlock(channel->profile_mutex); + } + + return; + } + + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(channel, CF_DIALPLAN)) { + switch_channel_clear_flag(channel, CF_DIALPLAN); + switch_mutex_lock(channel->profile_mutex); + channel->caller_profile->callee_id_name = SWITCH_BLANK_STRING; + channel->caller_profile->callee_id_number = SWITCH_BLANK_STRING; + switch_mutex_unlock(channel->profile_mutex); + } + +} + + SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension) { switch_assert(channel != NULL); - switch_channel_set_flag(channel, CF_DIALPLAN); - + switch_channel_sort_cid(channel, SWITCH_TRUE); + switch_mutex_lock(channel->profile_mutex); caller_extension->next = channel->caller_profile->caller_extension; channel->caller_profile->caller_extension = caller_extension; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 494871ec8a..cd74c332b7 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1544,21 +1544,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ new_profile->destination_number = switch_core_strdup(new_profile->pool, extension); new_profile->rdnis = switch_core_strdup(new_profile->pool, profile->destination_number); - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - if (profile->callee_id_name) { - switch_channel_set_variable(channel, "pre_transfer_caller_id_name", new_profile->caller_id_name); - new_profile->caller_id_name = switch_core_strdup(new_profile->pool, profile->callee_id_name); - profile->callee_id_name = SWITCH_BLANK_STRING; - } - - if (profile->callee_id_number) { - switch_channel_set_variable(channel, "pre_transfer_caller_id_number", new_profile->caller_id_number); - new_profile->caller_id_number = switch_core_strdup(new_profile->pool, profile->callee_id_number); - profile->callee_id_number = SWITCH_BLANK_STRING; - } - } - - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL); /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index aa5ddb9232..2f2dcdbc95 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1052,6 +1052,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * switch_channel_set_variable(caller_channel, "signal_bridge", "true"); switch_channel_set_variable(peer_channel, "signal_bridge", "true"); + switch_channel_sort_cid(peer_channel, SWITCH_FALSE); + /* fire events that will change the data table from "show channels" */ if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); @@ -1117,6 +1119,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR); switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR); + switch_channel_sort_cid(peer_channel, SWITCH_FALSE); + b_leg->session = peer_session; switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid)); b_leg->stream_id = stream_id; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index b6ae346a66..87a47e65aa 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2383,24 +2383,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess new_profile->chan_name = SWITCH_BLANK_STRING; new_profile->destination_number = switch_core_strdup(new_profile->pool, chan_data); - if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - const char *callee_id_name = new_profile->callee_id_name; - const char *callee_id_number = new_profile->callee_id_number; - - if (zstr(callee_id_number)) { - callee_id_number = caller_caller_profile->destination_number; - } - - if (zstr(callee_id_name)) { - callee_id_name = callee_id_number; - } - - new_profile->caller_id_name = callee_id_name; - new_profile->caller_id_number = callee_id_number; - new_profile->callee_id_name = SWITCH_BLANK_STRING; - new_profile->callee_id_number = SWITCH_BLANK_STRING; - } - if (cid_name_override) { new_profile->caller_id_name = switch_core_strdup(new_profile->pool, cid_name_override); } From 1e0df408cfb343599e30df7ed41137431cdf4a51 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 17 Dec 2010 15:28:19 -0600 Subject: [PATCH 097/244] oops --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 884e5bf9f5..07e125ad6c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4065,8 +4065,6 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session switch_channel_set_variable(nchannel, "sip_invite_params", "intercom=true"); } - DUMP_EVENT(var_event); - if (((hval = switch_event_get_header(var_event, "effective_callee_id_name")) || (hval = switch_event_get_header(var_event, "sip_callee_id_name"))) && !zstr(hval)) { caller_profile->callee_id_name = switch_core_strdup(caller_profile->pool, hval); From ee562c82e1e3e321c2ece3b5970114a31b693f33 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 17 Dec 2010 16:06:11 -0600 Subject: [PATCH 098/244] FS-2879 --- src/mod/applications/mod_fifo/mod_fifo.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 3943ac6ea6..f275363706 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -3075,16 +3075,24 @@ SWITCH_STANDARD_APP(fifo_function) done: switch_mutex_lock(globals.mutex); - if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node_caller_count(node) == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name); - switch_core_hash_delete(globals.fifo_hash, node->name); + if (node && node->ready == FIFO_DELAY_DESTROY) { + int doit = 0; + switch_thread_rwlock_wrlock(node->rwlock); - node->ready = 0; - switch_mutex_lock(node->mutex); - switch_core_hash_destroy(&node->consumer_hash); - switch_mutex_unlock(node->mutex); + doit = node->consumer_count == 0 && node_caller_count(node) == 0; switch_thread_rwlock_unlock(node->rwlock); - switch_core_destroy_memory_pool(&node->pool); + + if (doit) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name); + switch_core_hash_delete(globals.fifo_hash, node->name); + + node->ready = 0; + switch_mutex_lock(node->mutex); + switch_core_hash_destroy(&node->consumer_hash); + switch_mutex_unlock(node->mutex); + switch_thread_rwlock_unlock(node->rwlock); + switch_core_destroy_memory_pool(&node->pool); + } } switch_mutex_unlock(globals.mutex); From 6e2f07f1e63a3bba9721ccaebf2a4d03e02edc9b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 17 Dec 2010 16:19:56 -0600 Subject: [PATCH 099/244] hide debug line --- libs/stfu/stfu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 2ffb86fdb6..b7df8ea870 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -413,7 +413,9 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void if (i->last_wr_ts) { if ((ts <= i->last_wr_ts && (i->last_wr_ts != UINT_MAX || ts == i->last_wr_ts))) { - stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); + } if (i->in_queue->array_len < i->in_queue->array_size) { i->in_queue->array_len++; } From 257c7edaf7d7e6151d11e5ef924d87a77f2c369b Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Fri, 17 Dec 2010 14:54:51 -0800 Subject: [PATCH 100/244] Update phrase_en.xml for version 1.0.14 of the sounds package --- docs/phrase/phrase_en.xml | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml index a028a2aae0..41bc69cde1 100644 --- a/docs/phrase/phrase_en.xml +++ b/docs/phrase/phrase_en.xml @@ -221,6 +221,7 @@ + @@ -241,6 +242,8 @@ + + @@ -259,6 +262,12 @@ + + + + + + @@ -362,8 +371,6 @@ - - @@ -390,15 +397,10 @@ - - - - - @@ -409,10 +411,7 @@ - - - @@ -425,20 +424,10 @@ - - - - - - - - - - - - - + + + From ab0a2bfa034aa535de9dae1cf7cbf03224ad2bf3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 17 Dec 2010 17:08:24 -0600 Subject: [PATCH 101/244] prune --- src/mod/applications/mod_fifo/mod_fifo.c | 103 ++++++++++++----------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index f275363706..9d9896956e 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -291,6 +291,7 @@ static switch_status_t fifo_queue_popfly(fifo_queue_t *queue, const char *uuid) struct fifo_node { char *name; switch_mutex_t *mutex; + switch_mutex_t *update_mutex; fifo_queue_t *fifo_list[MAX_PRI]; switch_hash_t *consumer_hash; int outbound_priority; @@ -801,6 +802,7 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu switch_core_hash_init(&node->consumer_hash, node->pool); switch_thread_rwlock_create(&node->rwlock, node->pool); switch_mutex_init(&node->mutex, SWITCH_MUTEX_NESTED, node->pool); + switch_mutex_init(&node->update_mutex, SWITCH_MUTEX_NESTED, node->pool); cbt.buf = outbound_count; cbt.len = sizeof(outbound_count); sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", name); @@ -1193,10 +1195,10 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->busy = 0; node->ring_consumer_count = 1; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } else { goto end; } @@ -1437,10 +1439,10 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void cbh->ready = 1; if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->ring_consumer_count = 0; node->busy = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } @@ -1501,10 +1503,10 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) switch_mutex_unlock(globals.mutex); if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->ring_consumer_count++; node->busy = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS); @@ -1601,12 +1603,12 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) switch_event_destroy(&ovars); if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); if (node->ring_consumer_count-- < 0) { node->ring_consumer_count = 0; } node->busy = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } switch_core_destroy_memory_pool(&h->pool); @@ -1754,9 +1756,35 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o if (globals.debug) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Trying priority: %d\n", cur_priority); + restart: + for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); if ((node = (fifo_node_t *) val)) { + + if (node->ready == FIFO_DELAY_DESTROY) { + int doit = 0; + + switch_mutex_lock(node->update_mutex); + doit = node->consumer_count == 0 && node_caller_count(node) == 0; + switch_mutex_unlock(node->update_mutex); + + if (doit) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name); + switch_core_hash_delete(globals.fifo_hash, node->name); + + node->ready = 0; + switch_mutex_lock(node->mutex); + switch_core_hash_destroy(&node->consumer_hash); + switch_mutex_unlock(node->mutex); + switch_mutex_unlock(node->update_mutex); + switch_core_destroy_memory_pool(&node->pool); + goto restart; + } + + } + + if (node->outbound_priority == 0) node->outbound_priority = 5; if (node->has_outbound && node->ready && !node->busy && node->outbound_priority == cur_priority) { ppl_waiting = node_caller_count(node); @@ -2219,6 +2247,7 @@ SWITCH_STANDARD_APP(fifo_function) if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) { node = create_node(nlist[i], importance, globals.sql_mutex); node->ready = 1; + switch_thread_rwlock_rdlock(node->rwlock); } node_list[node_count++] = node; } @@ -2306,7 +2335,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_answer(channel); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); if ((pri = switch_channel_get_variable(channel, "fifo_priority"))) { p = atoi(pri); @@ -2344,7 +2373,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(channel, "fifo_priority", tmp); } - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); ts = switch_micro_time_now(); switch_time_exp_lt(&tm, ts); @@ -2450,9 +2479,9 @@ SWITCH_STANDARD_APP(fifo_function) } switch_mutex_lock(globals.mutex); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node_remove_uuid(node, uuid); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); send_presence(node); check_cancel(node); switch_mutex_unlock(globals.mutex); @@ -2682,9 +2711,9 @@ SWITCH_STANDARD_APP(fifo_function) } if (pop && !node_caller_count(node)) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->start_waiting = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } } @@ -3074,29 +3103,9 @@ SWITCH_STANDARD_APP(fifo_function) done: - switch_mutex_lock(globals.mutex); - if (node && node->ready == FIFO_DELAY_DESTROY) { - int doit = 0; - - switch_thread_rwlock_wrlock(node->rwlock); - doit = node->consumer_count == 0 && node_caller_count(node) == 0; + if (node) { switch_thread_rwlock_unlock(node->rwlock); - - if (doit) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name); - switch_core_hash_delete(globals.fifo_hash, node->name); - - node->ready = 0; - switch_mutex_lock(node->mutex); - switch_core_hash_destroy(&node->consumer_hash); - switch_mutex_unlock(node->mutex); - switch_thread_rwlock_unlock(node->rwlock); - switch_core_destroy_memory_pool(&node->pool); - } - } - switch_mutex_unlock(globals.mutex); - switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG); @@ -3707,9 +3716,9 @@ SWITCH_STANDARD_API(fifo_api_function) switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node_caller_count(node), len); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); x++; } @@ -3718,9 +3727,9 @@ SWITCH_STANDARD_API(fifo_api_function) } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node_caller_count(node), len); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } else { stream->write_function(stream, "none\n"); } @@ -3730,9 +3739,9 @@ SWITCH_STANDARD_API(fifo_api_function) switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); stream->write_function(stream, "%s:%d\n", (char *) var, node->has_outbound); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); x++; } @@ -3741,9 +3750,9 @@ SWITCH_STANDARD_API(fifo_api_function) } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); stream->write_function(stream, "%s:%d\n", argv[1], node->has_outbound); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } else { stream->write_function(stream, "none\n"); } @@ -4116,7 +4125,7 @@ static switch_status_t load_config(int reload, int del_all) node->ready = FIFO_DELAY_DESTROY; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); for (x = 0; x < MAX_PRI; x++) { while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) { switch_event_destroy(&pop); @@ -4125,7 +4134,7 @@ static switch_status_t load_config(int reload, int del_all) switch_core_hash_delete(globals.fifo_hash, node->name); switch_core_hash_destroy(&node->consumer_hash); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); switch_core_destroy_memory_pool(&node->pool); goto top; } @@ -4401,7 +4410,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown) switch_hash_this(hi, NULL, NULL, &val); node = (fifo_node_t *) val; - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); switch_mutex_lock(node->mutex); for (x = 0; x < MAX_PRI; x++) { while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) { @@ -4411,7 +4420,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown) switch_mutex_unlock(node->mutex); switch_core_hash_delete(globals.fifo_hash, node->name); switch_core_hash_destroy(&node->consumer_hash); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); switch_core_destroy_memory_pool(&node->pool); } From 668763f4907b1b6115827160037b867800224df6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 17 Dec 2010 17:27:23 -0600 Subject: [PATCH 102/244] prevent race on codec change mid-call --- src/mod/endpoints/mod_sofia/mod_sofia.c | 5 ++++- src/mod/endpoints/mod_sofia/sofia_glue.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 07e125ad6c..8aa37b95be 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1084,7 +1084,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f tech_pvt->last_ts = 0; /* inform them of the codec they are actually sending */ - +#if 0 if (++tech_pvt->codec_reinvites > 2) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Ok, some devices *cough* X-lite *cough*\n" @@ -1093,7 +1093,10 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f } else { sofia_glue_do_invite(session); } +#endif + *frame = &silence_frame; + return SWITCH_STATUS_SUCCESS; } } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 0f52bbc8fb..029f60ad33 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2669,7 +2669,8 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) tech_pvt->rm_encoding, tech_pvt->codec_ms, tech_pvt->rm_rate); - + + switch_yield(tech_pvt->read_impl.microseconds_per_packet); switch_core_session_lock_codec_write(tech_pvt->session); switch_core_session_lock_codec_read(tech_pvt->session); resetting = 1; From 2343708a9c13f942d0db94281a953215297d5b39 Mon Sep 17 00:00:00 2001 From: cypromis Date: Sat, 18 Dec 2010 01:15:55 +0100 Subject: [PATCH 103/244] Sun Studio does not like __FUNCTION__ and -mt makes better multithreaded code --- configure.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.in b/configure.in index de7261266e..b1ab0f1723 100644 --- a/configure.in +++ b/configure.in @@ -205,10 +205,14 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then APR_ADDTO(SWITCH_AM_CFLAGS, -DPIC) APR_ADDTO(SWITCH_AM_CFLAGS, -erroff=E_END_OF_LOOP_CODE_NOT_REACHED) APR_ADDTO(SWITCH_AM_CFLAGS, -errtags=yes) + APR_ADDTO(SWITCH_AM_CFLAGS, -D__FUNCTION__=__func__ ) + APR_ADDTO(SWITCH_AM_CFLAGS, -mt) APR_ADDTO(SWITCH_AM_CXXFLAGS, -errtags=yes) APR_ADDTO(SWITCH_AM_CXXFLAGS, -KPIC) APR_ADDTO(SWITCH_AM_CXXFLAGS, -DPIC) APR_ADDTO(SWITCH_AM_CXXFLAGS, "-features=extensions") + APR_ADDTO(SWITCH_AM_CXXFLAGS, -D__FUNCTION__=__func__) + APR_ADDTO(SWITCH_AM_CXXFLAGS, -mt) APR_ADDTO(SWITCH_AM_LDFLAGS, -R${prefix}/lib) if test "${enable_64}" = "yes"; then From c81a94485765bd1a5a437c2d1e0d318733677786 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Fri, 17 Dec 2010 16:16:39 -0800 Subject: [PATCH 104/244] lang: Update langs - Add pt_PT, update es to have es_ES and es_MX, update mod_say_es and add mod_say_pt (FS-2937) --- build/modules.conf.in | 1 + docs/phrase/phrase_es_ES.xml | 994 ++++++++++++++++++ docs/phrase/phrase_es_MX.xml | 993 +++++++++++++++++ docs/phrase/phrase_pt_BR.xml | 987 +++++++++++++++++ docs/phrase/phrase_pt_PT.xml | 987 +++++++++++++++++ src/mod/say/mod_say_es/mod_say_es.c | 12 +- src/mod/say/mod_say_pt/Makefile | 2 + src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj | 283 +++++ .../say/mod_say_pt/mod_say_pt.2010.vcxproj | 131 +++ src/mod/say/mod_say_pt/mod_say_pt.c | 548 ++++++++++ src/mod/say/mod_say_pt/mod_say_pt.vcproj | 51 + 11 files changed, 4986 insertions(+), 3 deletions(-) create mode 100644 docs/phrase/phrase_es_ES.xml create mode 100644 docs/phrase/phrase_es_MX.xml create mode 100644 docs/phrase/phrase_pt_BR.xml create mode 100644 docs/phrase/phrase_pt_PT.xml create mode 100644 src/mod/say/mod_say_pt/Makefile create mode 100644 src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj create mode 100644 src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj create mode 100644 src/mod/say/mod_say_pt/mod_say_pt.c create mode 100644 src/mod/say/mod_say_pt/mod_say_pt.vcproj diff --git a/build/modules.conf.in b/build/modules.conf.in index 13e655672c..bd5d49a7ad 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -100,6 +100,7 @@ say/mod_say_en #say/mod_say_fr #say/mod_say_it #say/mod_say_nl +#say/mod_say_pt say/mod_say_ru #say/mod_say_zh #say/mod_say_hu diff --git a/docs/phrase/phrase_es_ES.xml b/docs/phrase/phrase_es_ES.xml new file mode 100644 index 0000000000..ad99c1bf73 --- /dev/null +++ b/docs/phrase/phrase_es_ES.xml @@ -0,0 +1,994 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/phrase/phrase_es_MX.xml b/docs/phrase/phrase_es_MX.xml new file mode 100644 index 0000000000..527f8c3c89 --- /dev/null +++ b/docs/phrase/phrase_es_MX.xml @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/phrase/phrase_pt_BR.xml b/docs/phrase/phrase_pt_BR.xml new file mode 100644 index 0000000000..9cc400c76b --- /dev/null +++ b/docs/phrase/phrase_pt_BR.xml @@ -0,0 +1,987 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/phrase/phrase_pt_PT.xml b/docs/phrase/phrase_pt_PT.xml new file mode 100644 index 0000000000..a0e59deb85 --- /dev/null +++ b/docs/phrase/phrase_pt_PT.xml @@ -0,0 +1,987 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/say/mod_say_es/mod_say_es.c b/src/mod/say/mod_say_es/mod_say_es.c index cf4d2f9b12..ff0ee944c2 100644 --- a/src/mod/say/mod_say_es/mod_say_es.c +++ b/src/mod/say/mod_say_es/mod_say_es.c @@ -39,8 +39,9 @@ * * Anthony Minessale II * Michael B. Murdock + * François Delawarde * - * mod_say_es.c -- Say for English + * mod_say_es.c -- Say for Spanish * */ @@ -102,7 +103,7 @@ static switch_status_t play_group(switch_say_method_t method, int a, int b, int break; default: say_file("digits/%d.wav", a); - say_file("digits/hundred.wav"); + say_file("digits/hundreds.wav"); break; } } @@ -175,7 +176,12 @@ static switch_status_t es_say_general_count(switch_core_session_t *session, char switch (say_args->method) { case SSM_COUNTED: case SSM_PRONOUNCED: - if ((status = play_group(SSM_PRONOUNCED, places[8], places[7], places[6], "digits/million.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + /* specific case, one million => un millón */ + if (!places[8] && !places[7] && (places[6] == 1)) { + say_file("digits/un.wav"); + say_file("digits/million.wav"); + } + else if ((status = play_group(SSM_PRONOUNCED, places[8], places[7], places[6], "digits/millions.wav", session, args)) != SWITCH_STATUS_SUCCESS) { return status; } if ((status = play_group(SSM_PRONOUNCED, places[5], places[4], places[3], "digits/thousand.wav", session, args)) != SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/say/mod_say_pt/Makefile b/src/mod/say/mod_say_pt/Makefile new file mode 100644 index 0000000000..2c35e6e98f --- /dev/null +++ b/src/mod/say/mod_say_pt/Makefile @@ -0,0 +1,2 @@ +BASE=../../../.. +include $(BASE)/build/modmake.rules diff --git a/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj b/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj new file mode 100644 index 0000000000..bf8c0333c5 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj b/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj new file mode 100644 index 0000000000..63fba6fae0 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_say_pt + {FA429E98-8B03-45E6-A096-A4BC5E821DE4} + mod_say_pt + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + + + + + false + + + + + + + X64 + + + + + + + false + + + MachineX64 + + + + + + + + + false + + + + + + + X64 + + + + + + + false + + + MachineX64 + + + + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + + + + diff --git a/src/mod/say/mod_say_pt/mod_say_pt.c b/src/mod/say/mod_say_pt/mod_say_pt.c new file mode 100644 index 0000000000..747a0c8984 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.c @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2007, Anthony Minessale II + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * Michael B. Murdock + * António Silva + * + * mod_say_pt.c -- Say for Portuguese + * + */ + +#include +#include +#include + +SWITCH_MODULE_LOAD_FUNCTION(mod_say_pt_load); +SWITCH_MODULE_DEFINITION(mod_say_pt, mod_say_pt_load, NULL, NULL); + +#define say_num(num, meth) { \ + char tmp[80]; \ + switch_status_t tstatus; \ + switch_say_method_t smeth = say_args->method; \ + switch_say_type_t stype = say_args->type; \ + say_args->type = SST_ITEMS; say_args->method = meth; \ + switch_snprintf(tmp, sizeof(tmp), "%u", (unsigned)num); \ + if ((tstatus = \ + pt_say_general_count(session, tmp, say_args, args)) \ + != SWITCH_STATUS_SUCCESS) { \ + return tstatus; \ + } \ + say_args->method = smeth; say_args->type = stype; \ + } \ + + +#define say_file(...) { \ + char tmp[80]; \ + switch_status_t tstatus; \ + switch_snprintf(tmp, sizeof(tmp), __VA_ARGS__); \ + if ((tstatus = \ + switch_ivr_play_file(session, NULL, tmp, args)) \ + != SWITCH_STATUS_SUCCESS){ \ + return tstatus; \ + } \ + if (!switch_channel_ready(switch_core_session_get_channel(session))) { \ + return SWITCH_STATUS_FALSE; \ + }} \ + + +static switch_status_t play_group(switch_say_method_t method, int a, int b, int c, char *what, switch_core_session_t *session, switch_input_args_t *args) +{ + + /*a => 1xx-9xx*/ + if (a) { + switch (a) { + case 1: + if (b || c) { + say_file("digits/hundred.wav"); + } else { + say_file("digits/100.wav"); + } + break; + case 2: + say_file("digits/200.wav"); + break; + case 3: + say_file("digits/300.wav"); + break; + case 5: + say_file("digits/500.wav"); + break; + default: + say_file("digits/%d.wav", a); + say_file("digits/hundreds.wav"); + break; + } + if (b || c) { + say_file("currency/and.wav"); + } + } + /* b => 1x - 9x */ + if (b) { + if (b > 1) { + if (method == SSM_COUNTED) { + say_file("digits/h-%d0.wav", b); + } else { + say_file("digits/%d0.wav", b); + if (c > 0) { + say_file("currency/and.wav"); + } + } + } else { + say_file("digits/%d%d.wav", b, c); + c = 0; + } + } + /* c => 0 - 9*/ + if (c) { + if (method == SSM_COUNTED) { + say_file("digits/h-%d.wav", c); + } else { + say_file("digits/%d.wav", c); + } + } + + if (what && (a || b || c)) { + say_file(what); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t pt_say_general_count(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + int in; + int x = 0; + int places[9] = { 0 }; + char sbuf[128] = ""; + switch_status_t status; + + if (say_args->method == SSM_ITERATED) { + if ((tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)))) { + char *p; + for (p = tosay; p && *p; p++) { + say_file("digits/%c.wav", *p); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + return SWITCH_STATUS_SUCCESS; + } + + if (!(tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf))) || strlen(tosay) > 9) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + + in = atoi(tosay); + + if (in != 0) { + for (x = 8; x >= 0; x--) { + int num = (int) pow(10, x); + if ((places[(uint32_t) x] = in / num)) { + in -= places[(uint32_t) x] * num; + } + } + + switch (say_args->method) { + case SSM_COUNTED: + case SSM_PRONOUNCED: + /* specific case, one million => um milhão */ + if (!places[8] && !places[7] && (places[6] == 1)) { + say_file("digits/1.wav"); + say_file("digits/million.wav"); + } else if ((status = play_group(SSM_PRONOUNCED, places[8], places[7], places[6], "digits/millions.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + return status; + } + if ((status = play_group(SSM_PRONOUNCED, places[5], places[4], places[3], "digits/thousand.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + return status; + } + if ((status = play_group(say_args->method, places[2], places[1], places[0], NULL, session, args)) != SWITCH_STATUS_SUCCESS) { + return status; + } + break; + default: + break; + } + } else { + say_file("digits/0.wav"); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t pt_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + int32_t t; + switch_time_t target = 0, target_now = 0; + switch_time_exp_t tm, tm_now; + uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; + switch_channel_t *channel = switch_core_session_get_channel(session); + const char *tz = switch_channel_get_variable(channel, "timezone"); + + if (say_args->type == SST_TIME_MEASUREMENT) { + int64_t hours = 0; + int64_t minutes = 0; + int64_t seconds = 0; + int64_t r = 0; + + if (strchr(tosay, ':')) { + char *tme = switch_core_session_strdup(session, tosay); + char *p; + + if ((p = strrchr(tme, ':'))) { + *p++ = '\0'; + seconds = atoi(p); + if ((p = strchr(tme, ':'))) { + *p++ = '\0'; + minutes = atoi(p); + if (tme) { + hours = atoi(tme); + } + } else { + minutes = atoi(tme); + } + } + } else { + if ((seconds = atol(tosay)) <= 0) { + seconds = (int64_t) switch_epoch_time_now(NULL); + } + + if (seconds >= 60) { + minutes = seconds / 60; + r = seconds % 60; + seconds = r; + } + + if (minutes >= 60) { + hours = minutes / 60; + r = minutes % 60; + minutes = r; + } + } + + if (hours) { + say_num(hours, SSM_PRONOUNCED); + if (hours == 1) { + say_file("time/hour.wav"); + } else { + say_file("time/hours.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("time/hours.wav"); + } + + if (minutes) { + say_num(minutes, SSM_PRONOUNCED); + if (minutes == 1) { + say_file("time/minute.wav"); + } else { + say_file("time/minutes.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("time/minutes.wav"); + } + + if (seconds) { + say_num(seconds, SSM_PRONOUNCED); + if (seconds == 1) { + say_file("time/second.wav"); + } else { + say_file("time/seconds.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("time/seconds.wav"); + } + + return SWITCH_STATUS_SUCCESS; + } + + if ((t = atol(tosay)) > 0) { + target = switch_time_make(t, 0); + target_now = switch_micro_time_now(); + } else { + target = switch_micro_time_now(); + target_now = switch_micro_time_now(); + } + + if (tz) { + int check = atoi(tz); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); + if (check) { + switch_time_exp_tz(&tm, target, check); + switch_time_exp_tz(&tm_now, target_now, check); + } else { + switch_time_exp_tz_name(tz, &tm, target); + switch_time_exp_tz_name(tz, &tm_now, target_now); + } + } else { + switch_time_exp_lt(&tm, target); + switch_time_exp_lt(&tm_now, target_now); + } + + switch (say_args->type) { + case SST_CURRENT_DATE_TIME: + say_date = say_time = 1; + break; + case SST_CURRENT_DATE: + say_date = 1; + break; + case SST_CURRENT_TIME: + say_time = 1; + break; + case SST_SHORT_DATE_TIME: + say_time = 1; + if (tm.tm_year != tm_now.tm_year) { + say_date = 1; + break; + } + if (tm.tm_yday == tm_now.tm_yday) { + say_today = 1; + break; + } + if (tm.tm_yday == tm_now.tm_yday - 1) { + say_yesterday = 1; + break; + } + if (tm.tm_yday >= tm_now.tm_yday - 5) { + say_dow = 1; + break; + } + if (tm.tm_mon != tm_now.tm_mon) { + say_month = say_day = say_dow = 1; + break; + } + + say_month = say_day = say_dow = 1; + + break; + default: + break; + } + + if (say_today) { + say_file("time/today.wav"); + } + if (say_yesterday) { + say_file("time/yesterday.wav"); + } + if (say_dow) { + say_file("time/day-%d.wav", tm.tm_wday); + } + + if (say_date) { + say_year = say_month = say_day = say_dow = 1; + say_today = say_yesterday = 0; + } + + if (say_month) { + say_file("time/mon-%d.wav", tm.tm_mon); + } + if (say_day) { + say_num(tm.tm_mday, SSM_COUNTED); + } + if (say_year) { + say_num(tm.tm_year + 1900, SSM_PRONOUNCED); + } + + if (say_time) { + int32_t hour = tm.tm_hour, pm = 0; + + if (say_date || say_today || say_yesterday || say_dow) { + if (hour == 1) { + say_file("time/at.wav"); + } else { + say_file("time/ats.wav"); + } + } + + if (hour > 12) { + hour -= 12; + pm = 1; + } else if (hour == 12) { + pm = 1; + } else if (hour == 0) { + hour = 12; + pm = 0; + } + + say_num(hour, SSM_PRONOUNCED); + + if (tm.tm_min) { + say_file("currency/and.wav"); + say_num(tm.tm_min, SSM_PRONOUNCED); + } else { + say_file("time/oclock.wav"); + } + + say_file("time/%s.wav", pm ? "p-m" : "a-m"); + } + + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t pt_say_money(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + char sbuf[16] = ""; /* enough for 999,999,999,999.99 (w/o the commas or leading $) */ + char *dollars = NULL; + char *cents = NULL; + + if (strlen(tosay) > 15 || !(tosay = switch_strip_nonnumerics(tosay, sbuf, sizeof(sbuf)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + + dollars = sbuf; + + if ((cents = strchr(sbuf, '.'))) { + *cents++ = '\0'; + if (strlen(cents) > 2) { + cents[2] = '\0'; + } + } + + /* If positive sign - skip over" */ + if (sbuf[0] == '+') { + dollars++; + } + + /* If negative say "negative" */ + if (sbuf[0] == '-') { + say_file("currency/negative.wav"); + dollars++; + } + + /* Say dollar amount */ + pt_say_general_count(session, dollars, say_args, args); + if (atoi(dollars) == 1) { + say_file("currency/dollar.wav"); + } else { + say_file("currency/dollars.wav"); + } + + /* Say "and" */ + say_file("currency/and.wav"); + + /* Say cents */ + if (cents) { + pt_say_general_count(session, cents, say_args, args); + if (atoi(cents) == 1) { + say_file("currency/cent.wav"); + } else { + say_file("currency/cents.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("currency/cents.wav"); + } + + return SWITCH_STATUS_SUCCESS; +} + + + +static switch_status_t pt_say(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + + switch_say_callback_t say_cb = NULL; + + switch (say_args->type) { + case SST_NUMBER: + case SST_ITEMS: + case SST_PERSONS: + case SST_MESSAGES: + say_cb = pt_say_general_count; + break; + case SST_TIME_MEASUREMENT: + case SST_CURRENT_DATE: + case SST_CURRENT_TIME: + case SST_CURRENT_DATE_TIME: + case SST_SHORT_DATE_TIME: + say_cb = pt_say_time; + break; + case SST_IP_ADDRESS: + return switch_ivr_say_ip(session, tosay, pt_say_general_count, say_args, args); + break; + case SST_NAME_SPELLED: + case SST_NAME_PHONETIC: + return switch_ivr_say_spell(session, tosay, say_args, args); + break; + case SST_CURRENCY: + say_cb = pt_say_money; + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown Say type=[%d]\n", say_args->type); + break; + } + + if (say_cb) { + return say_cb(session, tosay, say_args, args); + } + + return SWITCH_STATUS_FALSE; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_say_pt_load) +{ + switch_say_interface_t *say_interface; + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + say_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SAY_INTERFACE); + say_interface->interface_name = "pt"; + say_interface->say_function = pt_say; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/say/mod_say_pt/mod_say_pt.vcproj b/src/mod/say/mod_say_pt/mod_say_pt.vcproj new file mode 100644 index 0000000000..fb5d2dbab9 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.vcproj @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + From d349290f7b3f61e87bf47a683bffe9b056bd89f4 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 17 Dec 2010 19:26:43 -0500 Subject: [PATCH 105/244] freetdm: fix OPENZAP-125 (Add basic calling party category support into ftmod_r2) (Patched by ric) --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 ++ libs/freetdm/src/ftdm_call_utils.c | 23 +++++++ libs/freetdm/src/ftdm_io.c | 3 + libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 70 +++++++++++++++++++++- libs/freetdm/src/include/freetdm.h | 18 +++++- libs/freetdm/src/include/ftdm_call_utils.h | 17 ++++++ 6 files changed, 133 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index c459a57c11..0615b3821b 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1278,6 +1278,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_data.dnis.type = outbound_profile->destination_number_ton; } + if ((var = channel_get_variable(session, var_event, "freetdm_calling_party_category"))) { + ftdm_set_calling_party_category(var, (uint8_t *)&caller_data.cpc); + } + if ((var = channel_get_variable(session, var_event, "freetdm_custom_call_data"))) { ftdm_set_string(caller_data.raw_data, var); caller_data.raw_data_len = (uint32_t)strlen(var); diff --git a/libs/freetdm/src/ftdm_call_utils.c b/libs/freetdm/src/ftdm_call_utils.c index 69f2fb4fff..2b72f05b77 100644 --- a/libs/freetdm/src/ftdm_call_utils.c +++ b/libs/freetdm/src/ftdm_call_utils.c @@ -30,6 +30,12 @@ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contributors: + * + * Moises Silva + * Ricardo Barroetaveña + * */ #include "private/ftdm_core.h" @@ -144,3 +150,20 @@ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number) return FTDM_SUCCESS; } + +FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target) +{ + uint8_t val; + ftdm_status_t status = FTDM_SUCCESS; + + val = ftdm_str2ftdm_calling_party_category(string); + if (val == FTDM_CPC_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid category string (%s)\n", string); + val = FTDM_CPC_ORDINARY; + status = FTDM_FAIL; + } + + *target = val; + return status; +} + diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 1750d6d7d9..36b7632cb3 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -301,6 +301,9 @@ FTDM_STR2ENUM(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t, FTDM_ENUM_NAMES(USER_LAYER1_PROT_NAMES, USER_LAYER1_PROT_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t, USER_LAYER1_PROT_NAMES, FTDM_USER_LAYER1_PROT_INVALID) +FTDM_ENUM_NAMES(CALLING_PARTY_CATEGORY_NAMES, CALLING_PARTY_CATEGORY_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t, CALLING_PARTY_CATEGORY_NAMES, FTDM_CPC_INVALID) + static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name); static const char *cut_path(const char *in) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 14eca429e8..efd58b0af5 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -380,11 +380,72 @@ static void ft_r2_answer_call(ftdm_channel_t *ftdmchan) R2CALL(ftdmchan)->answer_pending = 0; } +static __inline__ ftdm_calling_party_category_t ftdm_openr2_cpc_to_r2_ftdm_cpc(openr2_calling_party_category_t cpc) +{ + switch (cpc) { + case OR2_CALLING_PARTY_CATEGORY_UNKNOWN: + return FTDM_CPC_UNKNOWN; + + case OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER: + return FTDM_CPC_ORDINARY; + + case OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER: + return FTDM_CPC_PRIORITY; + + case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_SUBSCRIBER: + return FTDM_CPC_UNKNOWN; + + case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_PRIORITY_SUBSCRIBER: + return FTDM_CPC_UNKNOWN; + + case OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT: + return FTDM_CPC_TEST; + + case OR2_CALLING_PARTY_CATEGORY_PAY_PHONE: + return FTDM_CPC_PAYPHONE; + + case OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL: + return FTDM_CPC_OPERATOR; + } + return FTDM_CPC_INVALID; +} + +static __inline openr2_calling_party_category_t ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdm_calling_party_category_t cpc) +{ + switch (cpc) { + case FTDM_CPC_UNKNOWN: + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; + + case FTDM_CPC_OPERATOR: + return OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL; + + case FTDM_CPC_ORDINARY: + return OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; + + case FTDM_CPC_PRIORITY: + return OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER; + + case FTDM_CPC_DATA: + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; + + case FTDM_CPC_TEST: + return OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT; + + case FTDM_CPC_PAYPHONE: + return OR2_CALLING_PARTY_CATEGORY_PAY_PHONE; + + case FTDM_CPC_INVALID: + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; + } + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; +} + /* this function must be called with the chan mutex held! */ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) { openr2_call_status_t callstatus; ftdm_r2_data_t *r2data; + openr2_calling_party_category_t category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; r2data = ftdmchan->span->signal_data; @@ -397,6 +458,12 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) ft_r2_clean_call(ftdmchan->call_data); + if (ftdmchan->caller_data.cpc == FTDM_CPC_INVALID || ftdmchan->caller_data.cpc == FTDM_CPC_UNKNOWN) { + category = r2data->category; + } else { + category = ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdmchan->caller_data.cpc); + } + /* start io dump */ if (r2data->mf_dump_size) { ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size); @@ -406,7 +473,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, ftdmchan->caller_data.cid_num.digits, ftdmchan->caller_data.dnis.digits, - r2data->category); + category); if (callstatus) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n"); @@ -615,6 +682,7 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons } else { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); } + ftdmchan->caller_data.cpc = ftdm_openr2_cpc_to_r2_ftdm_cpc(category); } /* diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 56a9dc0577..dce130f5be 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -265,6 +265,21 @@ typedef enum { #define USER_LAYER1_PROT_STRINGS "V.110", "u-law", "a-law", "Invalid" FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t) +/*! Calling Party Category */ +typedef enum { + FTDM_CPC_UNKNOWN, + FTDM_CPC_OPERATOR, + FTDM_CPC_ORDINARY, + FTDM_CPC_PRIORITY, + FTDM_CPC_DATA, + FTDM_CPC_TEST, + FTDM_CPC_PAYPHONE, + FTDM_CPC_INVALID +} ftdm_calling_party_category_t; +#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t) + + /*! \brief Number abstraction */ typedef struct { char digits[25]; @@ -294,7 +309,8 @@ typedef struct ftdm_caller_data { ftdm_bearer_cap_t bearer_capability; /* user information layer 1 protocol */ ftdm_user_layer1_prot_t bearer_layer1; - ftdm_variable_container_t variables; /*! + * Ricardo Barroetaveña + * */ #ifndef __FTDM_CALL_UTILS_H__ @@ -114,5 +120,16 @@ FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t */ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number); +/*! + * \brief Set the Calling Party Category from an enum + * + * \param cpc_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target); + #endif /* __FTDM_CALL_UTILS_H__ */ From a1a50c87ece4c26a389a8a879a04d4616a2c9e0f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 17 Dec 2010 19:33:43 -0500 Subject: [PATCH 106/244] freetdm: OPENZAP-123 - Restrict ANI presentation in ftmod_r2 (Patched by ric) --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index efd58b0af5..9a5a2b1295 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -33,6 +33,7 @@ * Contributors: * * Arnaldo Pereira + * Ricardo Barroetaveña * */ @@ -471,7 +472,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) } callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, - ftdmchan->caller_data.cid_num.digits, + ftdmchan->caller_data.pres == FTDM_PRES_ALLOWED ? ftdmchan->caller_data.cid_num.digits : NULL, ftdmchan->caller_data.dnis.digits, category); From aa69927b8fec99064da113bd6181dd38e82e0d46 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 17 Dec 2010 20:04:30 -0500 Subject: [PATCH 107/244] freetdm: OPENZAP-124 - Add round robin hunting direction (Patched by Ric) --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 ++ libs/freetdm/src/ftdm_io.c | 41 +++++++++++++++++++- libs/freetdm/src/include/freetdm.h | 4 +- libs/freetdm/src/include/private/ftdm_core.h | 1 + 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 0615b3821b..7637932b79 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1136,6 +1136,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi direction = FTDM_BOTTOM_UP; } else if (*argv[1] == 'a') { direction = FTDM_TOP_DOWN; + } else if (*argv[1] == 'r') { + direction = FTDM_RR_DOWN; + } else if (*argv[1] == 'R') { + direction = FTDM_RR_UP; } else { chan_id = atoi(argv[1]); } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 36b7632cb3..94a01aa7ba 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1706,6 +1706,21 @@ static ftdm_status_t __inline__ get_best_rated(ftdm_channel_t **fchan, ftdm_chan return FTDM_SUCCESS; } +static uint32_t __inline__ rr_next(uint32_t last, uint32_t min, uint32_t max, ftdm_direction_t direction) +{ + uint32_t next = min; + + ftdm_log(FTDM_LOG_DEBUG, "last = %d, min = %d, max = %d\n", last, min, max); + + if (direction == FTDM_RR_DOWN) { + next = (last >= max) ? min : ++last; + } else { + next = (last <= min) ? max : --last; + } + return next; +} + + FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan) { int availability = -1; @@ -1748,6 +1763,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir if (direction == FTDM_TOP_DOWN) { i = 0; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + i = rr_next(group->last_used_index, 0, group->chan_count - 1, direction); } else { i = group->chan_count-1; } @@ -1762,16 +1779,24 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir if (request_voice_channel(check, ftdmchan, caller_data, direction)) { status = FTDM_SUCCESS; + if (direction == FTDM_RR_UP || direction == FTDM_RR_DOWN) { + group->last_used_index = i; + } break; } calculate_best_rate(check, &best_rated, &best_rate); if (direction == FTDM_TOP_DOWN) { - if (i >= group->chan_count) { + if (i >= (group->chan_count - 1)) { break; } i++; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + if (check == best_rated) { + group->last_used_index = i; + } + i = rr_next(i, 0, group->chan_count - 1, direction); } else { if (i == 0) { break; @@ -1850,6 +1875,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (direction == FTDM_TOP_DOWN) { i = 1; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + i = rr_next(span->last_used_index, 1, span->chan_count, direction); } else { i = span->chan_count; } @@ -1860,6 +1887,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (i > span->chan_count) { break; } + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + if (i == span->last_used_index) { + break; + } } else { if (i == 0) { break; @@ -1873,6 +1904,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (request_voice_channel(check, ftdmchan, caller_data, direction)) { status = FTDM_SUCCESS; + if (direction == FTDM_RR_UP || direction == FTDM_RR_DOWN) { + span->last_used_index = i; + } break; } @@ -1880,6 +1914,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (direction == FTDM_TOP_DOWN) { i++; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + if (check == best_rated) { + span->last_used_index = i; + } + i = rr_next(i, 1, span->chan_count, direction); } else { i--; } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index dce130f5be..69b90f1acd 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -144,7 +144,9 @@ typedef enum { /*! \brief Hunting direction (when hunting for free channels) */ typedef enum { FTDM_TOP_DOWN, - FTDM_BOTTOM_UP + FTDM_BOTTOM_UP, + FTDM_RR_DOWN, + FTDM_RR_UP, } ftdm_direction_t; /*! \brief I/O channel type */ diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 9222da3a42..e8ee7156f8 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -493,6 +493,7 @@ struct ftdm_span { ftdm_trunk_type_t trunk_type; ftdm_analog_start_type_t start_type; ftdm_signal_type_t signal_type; + uint32_t last_used_index; /* Private signaling data. Do not touch unless you are a signaling module */ void *signal_data; fio_signal_cb_t signal_cb; From 6066993d21568fa60b5319943f58931767513d99 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 18 Dec 2010 02:24:28 +0100 Subject: [PATCH 108/244] ftmod_libpri: remove ftdm_channel_done(), only use ftdm_channel_close(). Signed-off-by: Stefan Knoblich --- .../src/ftmod/ftmod_libpri/ftmod_libpri.c | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 68f0e9e5a4..8cbc0f4f45 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -515,23 +515,17 @@ static __inline__ void state_advance(ftdm_channel_t *chan) switch (ftdm_channel_get_state(chan)) { case FTDM_CHANNEL_STATE_DOWN: { + ftdm_channel_t *chtmp = chan; chan->call_data = NULL; - ftdm_channel_done(chan); - /* - * Close channel completely, BRI PTMP will thank us - */ - if (ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { - ftdm_channel_t *chtmp = chan; - if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - } + if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n", + ftdm_channel_get_span_id(chan), + ftdm_channel_get_id(chan)); + } else { + ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n", + ftdm_channel_get_span_id(chan), + ftdm_channel_get_id(chan)); } } break; From 2b0bba8e94fd352904e5bc46c802488aa1d538ce Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 17 Dec 2010 20:27:37 -0500 Subject: [PATCH 109/244] freetdm: add __USE_BSD to ftdm_os, needed by unistd.h for usleep() and string.h to define strcasecmp() add -Werror even when the compiler is unknown. This is just a work-around to gcc not being detected as GNU by our current standalone build (not bootstrapped through FreeSWITCH) --- libs/freetdm/Makefile.am | 5 +++-- libs/freetdm/configure.ac | 2 +- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 1 - libs/freetdm/src/include/ftdm_os.h | 5 ++++- libs/freetdm/src/testsangomaboost.c | 7 +------ 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index af26f7f2af..5e804b7505 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -49,6 +49,7 @@ if HAVE_SNG_ISDN INCS += -I/usr/include/sng_isdn endif +# we needed to separate CFLAGS in FTDM_COMPAT_CFLAGS and FTDM_CFLAGS due to -c99 which causes problems with wanpipe headers FTDM_COMPAT_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_COMPAT_CFLAGS@ @DEFS@ FTDM_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_CFLAGS@ @DEFS@ COMPILE = $(CC) $(FTDM_CFLAGS) @@ -183,8 +184,8 @@ ftmod_analog_em_la_LIBADD = libfreetdm.la if HAVE_LIBSANGOMA mod_LTLIBRARIES += ftmod_wanpipe.la ftmod_wanpipe_la_SOURCES = $(SRC)/ftmod/ftmod_wanpipe/ftmod_wanpipe.c -#some structures within Wanpipe drivers are not c99 compatible, so we need to compile ftmod_wanpipe -#without c99 flags +# some structures within Wanpipe drivers are not c99 compatible, so we need to compile ftmod_wanpipe +# without c99 flags, use FTDM_COMPAT_CFLAGS instead ftmod_wanpipe_la_CFLAGS = $(AM_CFLAGS) $(FTDM_COMPAT_CFLAGS) -D__LINUX__ -I/usr/include/wanpipe ftmod_wanpipe_la_LDFLAGS = -shared -module -avoid-version -lsangoma ftmod_wanpipe_la_LIBADD = libfreetdm.la diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index 592dfd82a3..e26f10b0b2 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -82,7 +82,7 @@ sun) fi ;; *) - COMP_VENDOR_COMPAT_CFLAGS="-Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" + COMP_VENDOR_COMPAT_CFLAGS="-Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" COMP_VENDOR_CFLAGS="-std=c99 $COMP_VENDOR_COMPAT_CFLAGS" ;; esac diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index f40196499c..09208f8d2c 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -31,7 +31,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "private/ftdm_core.h" #include "ftmod_zt.h" diff --git a/libs/freetdm/src/include/ftdm_os.h b/libs/freetdm/src/include/ftdm_os.h index 5026bb7236..f3ebee9ea2 100644 --- a/libs/freetdm/src/include/ftdm_os.h +++ b/libs/freetdm/src/include/ftdm_os.h @@ -39,9 +39,12 @@ extern "C" { #endif +#if defined(__linux__) && !defined(__USE_BSD) +#define __USE_BSD +#endif + #include "ftdm_declare.h" #include "ftdm_threadmutex.h" - #include #ifndef __WINDOWS__ diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index b254a08bb8..b007fc186b 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -48,12 +48,7 @@ #include #include #include -#if defined(__linux__) && !defined(__USE_BSD) -#define __USE_BSD -#endif -#ifndef WIN32 -#include -#endif + #include "freetdm.h" From 282b156207ccae94c8d80efec72c106cf7e3b4f2 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 17 Dec 2010 21:25:45 -0600 Subject: [PATCH 110/244] windows tweak mod_say_pt add to vs2010 others not for now --- Freeswitch.2010.sln | 20 +++++++++++++++++++ src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj | 2 +- .../say/mod_say_pt/mod_say_pt.2010.vcxproj | 2 +- src/mod/say/mod_say_pt/mod_say_pt.vcproj | 2 +- w32/Setup/Setup.wixproj | 9 +++++++++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln index 186969891a..edee701d51 100644 --- a/Freeswitch.2010.sln +++ b/Freeswitch.2010.sln @@ -707,6 +707,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_distributor", "src\mod\ EndProject Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup", "w32\Setup\Setup.wixproj", "{47213370-B933-487D-9F45-BCA26D7E2B6F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_pt", "src\mod\say\mod_say_pt\mod_say_pt.2010.vcxproj", "{7C22BDFF-CC09-400C-8A09-660733980028}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All|Win32 = All|Win32 @@ -3619,6 +3621,23 @@ Global {47213370-B933-487D-9F45-BCA26D7E2B6F}.Release|x64 Setup.Build.0 = Release|x64 {47213370-B933-487D-9F45-BCA26D7E2B6F}.Release|x86 Setup.ActiveCfg = Release|x86 {47213370-B933-487D-9F45-BCA26D7E2B6F}.Release|x86 Setup.Build.0 = Release|x86 + {7C22BDFF-CC09-400C-8A09-660733980028}.All|Win32.ActiveCfg = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.All|x64.ActiveCfg = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.All|x64.Build.0 = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.All|x64 Setup.ActiveCfg = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.All|x86 Setup.ActiveCfg = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Debug|Win32.ActiveCfg = Debug|Win32 + {7C22BDFF-CC09-400C-8A09-660733980028}.Debug|Win32.Build.0 = Debug|Win32 + {7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x64.ActiveCfg = Debug|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x64.Build.0 = Debug|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x64 Setup.ActiveCfg = Debug|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Debug|x86 Setup.ActiveCfg = Debug|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Release|Win32.ActiveCfg = Release|Win32 + {7C22BDFF-CC09-400C-8A09-660733980028}.Release|Win32.Build.0 = Release|Win32 + {7C22BDFF-CC09-400C-8A09-660733980028}.Release|x64.ActiveCfg = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Release|x64.Build.0 = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Release|x64 Setup.ActiveCfg = Release|x64 + {7C22BDFF-CC09-400C-8A09-660733980028}.Release|x86 Setup.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3769,6 +3788,7 @@ Global {A4B122CF-5196-476B-8C0E-D8BD59AC3C14} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {B6A9FB7A-1CC4-442B-812D-EC33E4E4A36E} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {0382E8FD-CFDC-41C0-8B03-792C7C84FC31} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} + {7C22BDFF-CC09-400C-8A09-660733980028} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {3B08FEFD-4D3D-4C16-BA94-EE83509E32A0} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8} {7BFD517E-7F8F-4A40-A78E-8D3632738227} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8} {6374D55C-FABE-4A02-9CF1-4145308A56C5} = {57D119DC-484F-420F-B9E9-8589FD9A8DF8} diff --git a/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj b/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj index bf8c0333c5..ee0fffde02 100644 --- a/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj +++ b/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++" Version="9.00" Name="mod_say_pt" - ProjectGUID="{FA429E98-8B03-45E6-A096-A4BC5E821DE4}" + ProjectGUID="{7C22BDFF-CC09-400C-8A09-660733980028}" RootNamespace="mod_say_pt" Keyword="Win32Proj" TargetFrameworkVersion="131072" diff --git a/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj b/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj index 63fba6fae0..8c94e2cb65 100644 --- a/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj +++ b/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj @@ -20,7 +20,7 @@ mod_say_pt - {FA429E98-8B03-45E6-A096-A4BC5E821DE4} + {7C22BDFF-CC09-400C-8A09-660733980028} mod_say_pt Win32Proj diff --git a/src/mod/say/mod_say_pt/mod_say_pt.vcproj b/src/mod/say/mod_say_pt/mod_say_pt.vcproj index fb5d2dbab9..ce2a3344fc 100644 --- a/src/mod/say/mod_say_pt/mod_say_pt.vcproj +++ b/src/mod/say/mod_say_pt/mod_say_pt.vcproj @@ -3,7 +3,7 @@ ProjectType="Visual C++" Version="8.00" Name="mod_say_pt" - ProjectGUID="{FA429E98-8B03-45E6-A096-A4BC5E821DE4}" + ProjectGUID="{7C22BDFF-CC09-400C-8A09-660733980028}" RootNamespace="mod_say_pt" Keyword="Win32Proj" > diff --git a/w32/Setup/Setup.wixproj b/w32/Setup/Setup.wixproj index fa6c832777..f97000b585 100644 --- a/w32/Setup/Setup.wixproj +++ b/w32/Setup/Setup.wixproj @@ -723,6 +723,15 @@ Binaries;Content;Satellites MODLOCATION + + mod_say_pt + {7c22bdff-cc09-400c-8a09-660733980028} + True + + + Binaries;Content;Satellites + MODLOCATION + mod_say_ru {0382e8fd-cfdc-41c0-8b03-792c7c84fc31} From 1f26f2f86ad63865a13df010cc3c62e34a2d6d55 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 17 Dec 2010 22:29:33 -0600 Subject: [PATCH 111/244] presence is a 4-letter word --- src/mod/endpoints/mod_sofia/sofia_presence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 5d666f03ee..f0cade3e61 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -818,7 +818,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh); switch_safe_free(sql); - if ((sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," + if ((sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event," "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," From fcd6c54162a6270554de3b037c03398d7655732c Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sun, 19 Dec 2010 00:13:08 -0500 Subject: [PATCH 112/244] freetdm: fix attempt for OPENZAP-130 --- libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c | 9 ++++----- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 12 ++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index fbe6ca0822..bfb67e4c78 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -127,9 +127,8 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen) } else { ftdm_log(FTDM_LOG_CRIT, "span %d D-READ TIMEOUT\n", spri->span->span_id); } - - ftdm_clear_flag(spri, LPWRAP_PRI_READY); - return -1; + /* we cannot return -1, libpri seems to expect values >= 0 */ + return 0; } spri->errs = 0; res = (int)len; @@ -156,8 +155,8 @@ static int __pri_lpwrap_write(struct pri *pri, void *buf, int buflen) if (ftdm_channel_write(spri->dchan, buf, buflen, &len) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "span %d D-WRITE FAIL! [%s]\n", spri->span->span_id, spri->dchan->last_error); - ftdm_clear_flag(spri, LPWRAP_PRI_READY); - return -1; + /* we cannot return -1, libpri seems to expect values >= 0 */ + return 0; } #ifdef IODEBUG diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 09208f8d2c..b16ead7a66 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -1152,6 +1152,7 @@ static FIO_WRITE_FUNCTION(zt_write) bytes += 2; } +tryagain: w = write(ftdmchan->sockfd, data, bytes); if (w >= 0) { @@ -1159,6 +1160,17 @@ static FIO_WRITE_FUNCTION(zt_write) return FTDM_SUCCESS; } + if (errno == ELAST) { + zt_event_t zt_event_id = 0; + if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event after ELAST on write: %s\n", strerror(errno)); + return FTDM_FAIL; + } + /* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */ + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dropping event %d to be able to write data\n", zt_event_id); + goto tryagain; + } + return FTDM_FAIL; } From dd4bad220ca1f4ddcacfe69e720e7d32b744b6f9 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sun, 19 Dec 2010 12:55:55 -0500 Subject: [PATCH 113/244] freetdm: ftmod_libpri - update to use proper structure member for signaling status change notifications --- libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c | 5 ++--- libs/freetdm/src/include/freetdm.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 8cbc0f4f45..1d3c76d2e2 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -1397,8 +1397,7 @@ static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev sig.chan_id = ftdm_channel_get_id(chan); sig.channel = chan; sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.raw_data = &status; - + sig.ev_data.sigstatus.status = status; ftdm_span_send_signal(span, &sig); } } @@ -1434,7 +1433,7 @@ static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ sig.chan_id = ftdm_channel_get_id(chan); sig.channel = chan; sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.raw_data = &status; + sig.ev_data.sigstatus.status = status; ftdm_span_send_signal(span, &sig); } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 69b90f1acd..a74fd7075a 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -438,7 +438,7 @@ struct ftdm_sigmsg { union { ftdm_event_sigstatus_t sigstatus; /*!< valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED */ ftdm_event_trace_t logevent; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */ - }ev_data; + } ev_data; }; /*! \brief Crash policy From 299c139c3ec6c9b276cefce4d6f1568d0d7100dc Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Sun, 19 Dec 2010 13:40:27 -0600 Subject: [PATCH 114/244] skypopen: refined hrtimers support to OSS audio driver --- src/mod/endpoints/mod_skypopen/oss/main.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 2abc5b342a..a96e38d68a 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -250,6 +250,10 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, { DEFINE_WAIT(wait); struct skypopen_dev *dev = filp->private_data; + + if(unload) + return -1; + #ifdef WANT_HRTIMER #if 1 if(dev->timer_inq_started == 0){ @@ -278,6 +282,10 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t { DEFINE_WAIT(wait); struct skypopen_dev *dev = filp->private_data; + + if(unload) + return -1; + #ifdef WANT_HRTIMER #if 1 if(dev->timer_outq_started == 0){ @@ -372,10 +380,14 @@ void skypopen_cleanup_module(void) ret= del_timer( &lptr->device.timer_outq ); printk( "Stopped skypopen OSS driver write timer\n"); #else// WANT_HRTIMER - ret = hrtimer_cancel( &lptr->device.timer_inq ); - printk( "Stopped skypopen OSS driver read HRtimer\n"); - ret = hrtimer_cancel( &lptr->device.timer_outq ); - printk( "Stopped skypopen OSS driver write HRtimer\n"); + if(lptr->device.timer_inq_started){ + ret = hrtimer_cancel( &lptr->device.timer_inq ); + printk( "Stopped skypopen OSS driver read HRtimer\n"); + } + if(lptr->device.timer_outq_started){ + ret = hrtimer_cancel( &lptr->device.timer_outq ); + printk( "Stopped skypopen OSS driver write HRtimer\n"); + } #endif// WANT_HRTIMER list_del(&lptr->list); From b84b71defa49a715d04d9776a5f0c7040103d6db Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sun, 19 Dec 2010 21:09:50 +0100 Subject: [PATCH 115/244] FreeTDM: Stop using raw_data for FTDM_SIGEVENT_SIGSTATUS_CHANGED events. The raw_data member is used for passing heap allocated data with an event, (e.g. strings of dtmf data) the memory is freed after the event has been processed. Recent changes in the event structure added a way to pass sig status changes inline, so remove the raw_data usage for FTDM_SIGEVENT_SIGSTATUS_CHANGED events. NOTE: This (finally) fixes a bug in ftmod_libpri that was caused by the event handling changes (stack corruption due to using free() on a variable on the stack, which turned into a NULL ptr deref caused by some compat code in ftdm_io.c:ftdm_span_send_signal(). Compiles and tested on my BRI setup, i did a quick audit of all places that generate FTDM_SIGEVENT_SIGSTATUS_CHANGED events and except for the sangoma_boost module there's nothing else that left using raw_data for this event. Signed-off-by: Stefan Knoblich --- libs/freetdm/mod_freetdm/mod_freetdm.c | 2 +- libs/freetdm/src/ftdm_io.c | 3 +-- .../src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 7637932b79..80006f1ae5 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2086,7 +2086,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { - ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->ev_data.sigstatus.status; + ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to: %s\n", spanid, chanid, ftdm_signaling_status2str(sigstatus)); } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 94a01aa7ba..297c08e5ea 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -5403,8 +5403,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { - ftdm_signaling_status_t sigstatus = ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE) ? sigmsg->ev_data.sigstatus.status : *((ftdm_signaling_status_t*)(sigmsg->raw_data)); - if (sigstatus == FTDM_SIG_STATE_UP) { + if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_UP) { ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); } else { ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index f59b3b8c4f..97e242dacb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -2478,7 +2478,7 @@ static BOOST_SIG_STATUS_CB_FUNCTION(ftdm_boost_sig_status_change) sig.span_id = ftdmchan->span_id; sig.channel = ftdmchan; sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sig.raw_data = &status; + sig.ev_data.sigstatus.status = status; ftdm_span_send_signal(ftdmchan->span, &sig); return; } From 1c4c84fc0ffdba48fd42154e7f0e85ddbb1c5ede Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Sun, 19 Dec 2010 21:38:55 +0100 Subject: [PATCH 116/244] Perl's Net::Skinny : update to current handle PACKED structs --- src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm b/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm index 90de304817..94708881e3 100644 --- a/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm +++ b/src/mod/endpoints/mod_skinny/Net/Skinny/Protocol.pm @@ -48,7 +48,7 @@ sub _find { my ($name, $value) = ($1,hex($2)); $sub{$name} = sub () { $value }; $const{$name} = $value; - } elsif(/^\s*struct\s+([a-z_]+)\s*\{\s*$/) { + } elsif(/^\s*struct\s+PACKED\s+([a-z_]+)\s*\{\s*$/) { my $struct_name = $1; $struct{$struct_name} = []; while(<$fh>) { From 709c4e5f9729dfad0862fa2daaf2f0687d04a56f Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Sun, 19 Dec 2010 22:16:09 +0100 Subject: [PATCH 117/244] Skinny: Event skinny::xml_alarm --- src/mod/endpoints/mod_skinny/mod_skinny.h | 1 + .../endpoints/mod_skinny/skinny_protocol.h | 3 +-- src/mod/endpoints/mod_skinny/skinny_server.c | 22 +++++++++++++++++++ src/mod/endpoints/mod_skinny/test-skinny.pl | 6 +++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index b5cc96b7ae..20d68faba5 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -42,6 +42,7 @@ #define SKINNY_EVENT_UNREGISTER "skinny::unregister" #define SKINNY_EVENT_EXPIRE "skinny::expire" #define SKINNY_EVENT_ALARM "skinny::alarm" +#define SKINNY_EVENT_XML_ALARM "skinny::xml_alarm" #define SKINNY_EVENT_CALL_STATE "skinny::call_state" #define SKINNY_EVENT_USER_TO_DEVICE "skinny::user_to_device" #define SKINNY_EVENT_DEVICE_TO_USER "skinny::device_to_user" diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index ee3c33a497..20e7d7f92f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -627,8 +627,7 @@ union skinny_data { struct extended_data_message extended_data; uint16_t as_uint16; - char as_char; - void *raw; + char as_char[1]; }; /* diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 9bf9d9fb9b..5874be4c6c 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1963,6 +1963,26 @@ switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t *request) +{ + switch_event_t *event = NULL; + char *tmp = NULL; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "Received XML alarm.\n"); + /* skinny::xml_alarm event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_XML_ALARM); + /* Ensure that the body is null-terminated */ + tmp = malloc(request->length - 4 + 1); + memcpy(tmp, request->data.as_char, request->length - 4); + tmp[request->length - 4] = '\0'; + switch_event_add_body(event, "%s", tmp); + switch_safe_free(tmp); + switch_event_fire(&event); + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request) { if (listener->profile->debug >= 10 || request->type != KEEP_ALIVE_MESSAGE) { @@ -2032,6 +2052,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_extended_data_message(listener, request); case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE: return skinny_handle_extended_data_message(listener, request); + case XML_ALARM_MESSAGE: + return skinny_handle_xml_alarm(listener, request); default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); diff --git a/src/mod/endpoints/mod_skinny/test-skinny.pl b/src/mod/endpoints/mod_skinny/test-skinny.pl index a44afa33dc..02cf3cc2f6 100644 --- a/src/mod/endpoints/mod_skinny/test-skinny.pl +++ b/src/mod/endpoints/mod_skinny/test-skinny.pl @@ -34,6 +34,12 @@ if(!$socket) { exit 1; } # ============================================================================= +$socket->send_raw( + XML_ALARM_MESSAGE, + "\x0a\x0a\x0a\x0aSEP002699438F62\x0a192.168.3.201/24\x0a192.168.3.254\x0a\x0a\x0aCP-7961G\x0a192.168.0.253\x0a\x0asw2.wvds.local\x0a3\x0a1\x0a0\x0a0\x0a0\x0a0\x0a0\x0a4095\x0a\x0a-1\x0a1289313813826\x0a\x0a1:Register\x0a129:RegisterAck\x0a\x0a\x0a\x0a" + ); + $socket->sleep(20); + exit; $socket->send_message( REGISTER_MESSAGE, device_name => $device_name, From 9b70d9a7a565b7af2f6ee4511f687316d1ba5a48 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Sun, 19 Dec 2010 22:20:09 +0100 Subject: [PATCH 118/244] Revert perl's Net::Skinny test --- src/mod/endpoints/mod_skinny/test-skinny.pl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/test-skinny.pl b/src/mod/endpoints/mod_skinny/test-skinny.pl index 02cf3cc2f6..a44afa33dc 100644 --- a/src/mod/endpoints/mod_skinny/test-skinny.pl +++ b/src/mod/endpoints/mod_skinny/test-skinny.pl @@ -34,12 +34,6 @@ if(!$socket) { exit 1; } # ============================================================================= -$socket->send_raw( - XML_ALARM_MESSAGE, - "\x0a\x0a\x0a\x0aSEP002699438F62\x0a192.168.3.201/24\x0a192.168.3.254\x0a\x0a\x0aCP-7961G\x0a192.168.0.253\x0a\x0asw2.wvds.local\x0a3\x0a1\x0a0\x0a0\x0a0\x0a0\x0a0\x0a4095\x0a\x0a-1\x0a1289313813826\x0a\x0a1:Register\x0a129:RegisterAck\x0a\x0a\x0a\x0a" - ); - $socket->sleep(20); - exit; $socket->send_message( REGISTER_MESSAGE, device_name => $device_name, From f4d52d4caae78359b59d97bf596a269e47f4def3 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 20 Dec 2010 08:43:13 -0600 Subject: [PATCH 119/244] FS-2943: improve fail2ban logging --- src/mod/endpoints/mod_sofia/sofia_reg.c | 46 ++++++++++++------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 570e297f6d..945740eb57 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1139,30 +1139,24 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } if (auth_res != AUTH_OK && !stale) { - if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) { - if (regtype == REG_REGISTER) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SIP auth %s (REGISTER) on sofia profile '%s' " - "for [%s@%s] from ip %s\n", forbidden ? "failure" : "challenge", profile->name, to_user, to_host, network_ip); - } + if (auth_res == AUTH_FORBIDDEN) { + nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END()); + forbidden = 1; + } else { + nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END()); } if (profile->debug) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send %s for [%s@%s]\n", forbidden ? "forbidden" : "challenge", to_user, to_host); } - if (auth_res == AUTH_FORBIDDEN) { - nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END()); - - /* Log line added to support Fail2Ban */ - if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) { - if (regtype == REG_INVITE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth failure (INVITE) on sofia profile '%s' " - "for [%s@%s] from ip %s\n", profile->name, to_user, to_host, network_ip); - } - } - } else { - nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END()); + /* Log line added to support Fail2Ban */ + if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth %s (%s) on sofia profile '%s' " + "for [%s@%s] from ip %s\n", forbidden ? "failure" : "challenge", + (regtype == REG_INVITE) ? "INVITE" : "REGISTER", profile->name, to_user, to_host, network_ip); } + switch_goto_int(r, 1, end); } } @@ -1193,14 +1187,18 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand realm = from_host; } - if (regtype == REG_REGISTER) { - sofia_reg_auth_challenge(nua, profile, nh, regtype, realm, stale); - if (profile->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Requesting Registration from: [%s@%s]\n", to_user, to_host); - } - } else { - sofia_reg_auth_challenge(nua, profile, nh, regtype, realm, stale); + sofia_reg_auth_challenge(nua, profile, nh, regtype, realm, stale); + + if (profile->debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send challenge for [%s@%s]\n", to_user, to_host); } + /* Log line added to support Fail2Ban */ + if (sofia_test_pflag(profile, PFLAG_LOG_AUTH_FAIL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SIP auth challenge (%s) on sofia profile '%s' " + "for [%s@%s] from ip %s\n", (regtype == REG_INVITE) ? "INVITE" : "REGISTER", + profile->name, to_user, to_host, network_ip); + } + switch_goto_int(r, 1, end); } reg: From 34690e47ff48f5c52b13cfb7b2c0226f3c0dc92e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 20 Dec 2010 11:16:14 -0600 Subject: [PATCH 120/244] FS-2879 --- src/mod/applications/mod_fifo/mod_fifo.c | 44 +++++++++++++++--------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 9d9896956e..e9d7cfb0e6 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1761,27 +1761,28 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); if ((node = (fifo_node_t *) val)) { + int x = 0; + switch_event_t *pop; if (node->ready == FIFO_DELAY_DESTROY) { - int doit = 0; - - switch_mutex_lock(node->update_mutex); - doit = node->consumer_count == 0 && node_caller_count(node) == 0; - switch_mutex_unlock(node->update_mutex); - - if (doit) { + if (switch_thread_rwlock_trywrlock(node->rwlock) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name); switch_core_hash_delete(globals.fifo_hash, node->name); + + for (x = 0; x < MAX_PRI; x++) { + while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) { + switch_event_destroy(&pop); + } + } node->ready = 0; - switch_mutex_lock(node->mutex); switch_core_hash_destroy(&node->consumer_hash); switch_mutex_unlock(node->mutex); switch_mutex_unlock(node->update_mutex); + switch_thread_rwlock_unlock(node->rwlock); switch_core_destroy_memory_pool(&node->pool); goto restart; } - } @@ -2172,7 +2173,7 @@ SWITCH_STANDARD_APP(fifo_function) char *mydata = NULL, *argv[5] = { 0 }; fifo_node_t *node = NULL, *node_list[MAX_NODES_PER_CONSUMER + 1] = { 0 }; switch_channel_t *channel = switch_core_session_get_channel(session); - int do_wait = 1, node_count = 0, i = 0; + int do_destroy = 0, do_wait = 1, node_count = 0, i = 0; const char *moh = NULL; const char *announce = NULL; switch_event_t *event = NULL; @@ -2247,13 +2248,10 @@ SWITCH_STANDARD_APP(fifo_function) if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) { node = create_node(nlist[i], importance, globals.sql_mutex); node->ready = 1; - switch_thread_rwlock_rdlock(node->rwlock); } - node_list[node_count++] = node; - } - if (switch_true(switch_channel_get_variable(channel, "fifo_destroy_after_use")) && node->ready == 1) { - node->ready = FIFO_DELAY_DESTROY; + switch_thread_rwlock_rdlock(node->rwlock); + node_list[node_count++] = node; } switch_mutex_unlock(globals.mutex); @@ -3103,10 +3101,22 @@ SWITCH_STANDARD_APP(fifo_function) done: - if (node) { - switch_thread_rwlock_unlock(node->rwlock); + if (switch_true(switch_channel_get_variable(channel, "fifo_destroy_after_use"))) { + do_destroy = 1; } + switch_mutex_lock(globals.mutex); + for (i = 0; i < node_count; i++) { + if (!(node = node_list[i])) { + continue; + } + switch_thread_rwlock_unlock(node->rwlock); + if (node->ready == 1 && do_destroy) { + node->ready = FIFO_DELAY_DESTROY; + } + } + switch_mutex_unlock(globals.mutex); + switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG); switch_core_media_bug_resume(session); From a1a710482b8533d181bbf29eb67d2646036614ee Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 20 Dec 2010 12:15:41 -0600 Subject: [PATCH 121/244] freetdm windows build tweaks --- .../mod_freetdm/mod_freetdm.2010.vcxproj | 4 ++-- .../ftmod_sangoma_isdn.2008.vcproj | 10 +++++++--- .../ftmod_sangoma_isdn.2010.vcxproj | 18 +++++++++++++----- w32/Library/FreeSwitchCore.2010.vcxproj | 3 +-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj index 9f01a3b1a1..ec69333410 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj @@ -103,7 +103,7 @@ ProgramDatabase - FreeSwitch.lib;%(AdditionalDependencies) + FreeSwitchCore.lib;%(AdditionalDependencies) ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true $(OutDir)$(TargetName).pdb @@ -127,7 +127,7 @@ ProgramDatabase - FreeSwitch.lib;%(AdditionalDependencies) + FreeSwitchCore.lib;%(AdditionalDependencies) ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) true $(OutDir)$(TargetName).pdb diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj index e3930d8188..2e7fb82041 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj @@ -40,11 +40,12 @@ Disabled - C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true @@ -95,10 +95,11 @@ Level3 EditAndContinue + MultiThreadedDebugDLL freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) - $(OutDir);C:\Program Files\libsng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) + $(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) true Console false @@ -110,7 +111,7 @@ Disabled - C:\Program Files\libsng_isdn\include;C:\Program Files\libsng_isdn\include\sng_isdn;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) @@ -119,6 +120,7 @@ Level3 ProgramDatabase + MultiThreadedDebugDLL freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) @@ -135,11 +137,13 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true EnableFastChecks - MultiThreadedDebugDLL + MultiThreadedDLL Level3 ProgramDatabase + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + Disabled true @@ -147,23 +151,27 @@ true true MachineX86 + freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) EnableFastChecks - MultiThreadedDebugDLL + MultiThreadedDLL Level3 ProgramDatabase + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) true Windows true true + freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) diff --git a/w32/Library/FreeSwitchCore.2010.vcxproj b/w32/Library/FreeSwitchCore.2010.vcxproj index e218445a02..c74ad944b1 100644 --- a/w32/Library/FreeSwitchCore.2010.vcxproj +++ b/w32/Library/FreeSwitchCore.2010.vcxproj @@ -120,8 +120,7 @@ false - - + $(OutDir)FreeSwitchCore.lib MachineX86 From b5b2f6134dcc06ba994b1f71d619b8b4a5626b1e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 20 Dec 2010 14:06:54 -0500 Subject: [PATCH 122/244] freetdm: multiple fixes for the core and analog * Replace ftdm_channel_flag_t with defines. We reached the 32bit limit where does not seem reliable to keep using enum. * Flags member for ftdm_channel_t is now uint64_t * Added FTDM_CHANNEL_CALL_STARTED flag to indicate when the API user knows about a call * Refactored raw_data member for ftdm_sigmsg_t. If raw_data needs to be freed it must be requested explicitly through the autofree member * Added collected member to ftdm_sigmsg_t for FTDM_SIGEVENT_COLLECTED data instead of using raw_data * Created define FTDM_DIGITS_LIMIT for DNIS/ANI digits limit * Fix some stat checks and outdated code in ftmod_analog * Refactored ftdm_channel_get_history_str API to return the time offsets and time since last state change * Do not send FTDM_SIGEVENT_STOP and FTDM_SIGEVENT_RELEASED on calls that were never reported to the user --- libs/freetdm/mod_freetdm/mod_freetdm.c | 4 +- libs/freetdm/src/ftdm_io.c | 98 +++++++++++++------ .../src/ftmod/ftmod_analog/ftmod_analog.c | 37 ++++--- .../ftmod/ftmod_analog_em/ftmod_analog_em.c | 2 +- .../ftmod_sangoma_isdn_trace.c | 10 +- libs/freetdm/src/include/freetdm.h | 23 +++-- libs/freetdm/src/include/private/ftdm_core.h | 2 +- libs/freetdm/src/include/private/ftdm_types.h | 81 +++++++-------- 8 files changed, 153 insertions(+), 104 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 80006f1ae5..584ed27a83 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1920,7 +1920,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) case FTDM_SIGEVENT_COLLECTED_DIGIT: { int span_id = ftdm_channel_get_span_id(sigmsg->channel); - char *dtmf = sigmsg->raw_data; + char *dtmf = sigmsg->ev_data.collected.digits; char *regex = SPAN_CONFIG[span_id].dial_regex; char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex; ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel); @@ -2192,7 +2192,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) break; case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { - ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->ev_data.sigstatus.status; + ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n", spanid, chanid, ftdm_signaling_status2str(sigstatus)); } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 0494ef8c0e..131d92ea92 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2512,17 +2512,20 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char ftdm_log(FTDM_LOG_ERROR, "outgoing_call method not implemented in this span!\n"); } + if (status == FTDM_SUCCESS) { + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED); + ftdm_call_set_call_id(&ftdmchan->caller_data); + ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100); + } + + ftdm_channel_unlock(ftdmchan); + #ifdef __WINDOWS__ UNREFERENCED_PARAMETER(file); UNREFERENCED_PARAMETER(func); UNREFERENCED_PARAMETER(line); #endif - ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100); - - ftdm_call_set_call_id(&ftdmchan->caller_data); - ftdm_channel_unlock(ftdmchan); - return status; } @@ -2633,7 +2636,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL); - if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { + if (FTDM_IS_VOICE_CHANNEL(ftdmchan) && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED)) { ftdm_sigmsg_t sigmsg; memset(&sigmsg, 0, sizeof(sigmsg)); sigmsg.span_id = ftdmchan->span_id; @@ -2642,6 +2645,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) sigmsg.event_id = FTDM_SIGEVENT_RELEASED; ftdm_span_send_signal(ftdmchan->span, &sigmsg); ftdm_call_clear_call_id(&ftdmchan->caller_data); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED); } if (ftdmchan->txdrops || ftdmchan->rxdrops) { @@ -3712,23 +3716,21 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data } status = ftdm_raw_read(ftdmchan, data, datalen); - if (status != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "raw I/O read filed\n"); + goto done; } - if (status == FTDM_SUCCESS) { - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN) - && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) { - unsigned char *rdata = data; - for (i = 0; i < *datalen; i++) { - rdata[i] = ftdmchan->rxgain_table[rdata[i]]; - } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN) + && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) { + unsigned char *rdata = data; + for (i = 0; i < *datalen; i++) { + rdata[i] = ftdmchan->rxgain_table[rdata[i]]; } - handle_dtmf(ftdmchan, *datalen); } + handle_dtmf(ftdmchan, *datalen); - if (status == FTDM_SUCCESS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) { + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) { if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) { codec_func = fio_ulaw2slin; } else if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_ALAW) { @@ -5333,7 +5335,6 @@ static void ftdm_group_add(ftdm_group_t *group) ftdm_mutex_unlock(globals.group_mutex); } - FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *name) { ftdm_group_t *new_group = NULL; @@ -5367,7 +5368,11 @@ static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigm if (sigmsg->channel) { ftdm_call_clear_data(&(sigmsg->channel->caller_data)); } - ftdm_safe_free(sigmsg->raw_data); + if (sigmsg->raw.autofree) { + ftdm_safe_free(sigmsg->raw.data); + sigmsg->raw.data = NULL; + sigmsg->raw.len = 0; + } return status; } @@ -5431,6 +5436,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t case FTDM_SIGEVENT_START: { + ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED); ftdm_call_set_call_id(&sigmsg->channel->caller_data); ftdm_set_echocancel_call_begin(sigmsg->channel); if (sigmsg->channel->dtmfdbg.requested) { @@ -5446,6 +5452,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t break; case FTDM_SIGEVENT_STOP: + if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) { + /* this happens for FXS devices which blindly send SIGEVENT_STOP, we should fix it there ... */ + ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n"); + goto done; + } if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) { ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n"); goto done; @@ -6011,12 +6022,34 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen) return new; } -FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) + +static void write_history_entry(const ftdm_channel_t *fchan, ftdm_stream_handle_t *stream, int i, ftdm_time_t *prevtime) { char func[255]; char line[255]; char states[255]; + const char *filename = NULL; + snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); + snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); + filename = strrchr(fchan->history[i].file, *FTDM_PATH_SEPARATOR); + if (!filename) { + filename = fchan->history[i].file; + } else { + filename++; + } + if (!(*prevtime)) { + *prevtime = fchan->history[i].time; + } + snprintf(line, sizeof(func), "[%s:%d]", filename, fchan->history[i].line); + stream->write_function(stream, "%-30.30s %-30.30s %-30.30s %lums\n", states, func, line, (fchan->history[i].time - *prevtime)); + *prevtime = fchan->history[i].time; +} + +FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) +{ uint8_t i = 0; + ftdm_time_t currtime = 0; + ftdm_time_t prevtime = 0; ftdm_stream_handle_t stream = { 0 }; FTDM_STANDARD_STREAM(stream); @@ -6025,25 +6058,24 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) return stream.data; } - stream.write_function(&stream, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n"); + stream.write_function(&stream, "%-30.30s %-30.30s %-30.30s %s", + "-- States --", "-- Function --", "-- Location --", "-- Time Offset --\n"); for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) { if (!fchan->history[i].file) { break; } - snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); - snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); - snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); - stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line); + write_history_entry(fchan, &stream, i, &prevtime); } for (i = 0; i < fchan->hindex; i++) { - snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); - snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); - snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); - stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line); + write_history_entry(fchan, &stream, i, &prevtime); } + currtime = ftdm_current_time_in_ms(); + + stream.write_function(&stream, "\nTime since last state change: %lums\n", (currtime - prevtime)); + return stream.data; } @@ -6074,15 +6106,23 @@ static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data) static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data) { - ftdm_assert_return((caller_data->call_id && caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Clearing call with invalid call-id\n"); + if (caller_data->call_id) { + ftdm_assert_return((caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Cannot clear call with invalid call-id\n"); + } else { + /* there might not be a call at all */ + return FTDM_SUCCESS; + } + ftdm_mutex_lock(globals.call_id_mutex); if (globals.call_ids[caller_data->call_id]) { + ftdm_log(FTDM_LOG_DEBUG, "Cleared call with id %u\n", caller_data->call_id); caller_data->call_id = 0; globals.call_ids[caller_data->call_id] = NULL; } else { ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id); } ftdm_mutex_unlock(globals.call_id_mutex); + return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index f07f48b0d6..5b68098ed7 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -493,8 +493,10 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && - (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE - || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) { + (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING + || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE + || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING + || ftdmchan->last_state == FTDM_CHANNEL_STATE_UP)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); } else { ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; @@ -717,7 +719,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) dtmf_offset = strlen(dtmf); last_digit = elapsed; sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; - sig.raw_data = dtmf; + ftdm_set_string(sig.ev_data.collected.digits, dtmf); if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) { collecting = 0; } @@ -884,14 +886,14 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e { if (event->channel->type != FTDM_CHAN_TYPE_FXO) { ftdm_log_chan_msg(event->channel, FTDM_LOG_ERROR, "Cannot get a RING_START event on a non-fxo channel, please check your config.\n"); - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); goto end; } if (!event->channel->ring_count && (event->channel->state == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD))) { if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID); } else { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RING); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_RING); } event->channel->ring_count = 1; ftdm_mutex_unlock(event->channel->mutex); @@ -909,7 +911,12 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e } if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN); + if (event->channel->state == FTDM_CHANNEL_STATE_HANGUP && + ftdm_test_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE); + /* we do not need to process HANGUP since the device also hangup already */ + } + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); } } @@ -917,16 +924,16 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e case FTDM_OOB_FLASH: { if (event->channel->state == FTDM_CHANNEL_STATE_CALLWAITING) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP); - ftdm_clear_flag_locked(event->channel, FTDM_CHANNEL_STATE_CHANGE); - ftdm_clear_flag_locked(event->channel->span, FTDM_SPAN_STATE_CHANGE); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP); + ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE); + ftdm_clear_flag(event->channel->span, FTDM_SPAN_STATE_CHANGE); event->channel->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0; } ftdm_channel_rotate_tokens(event->channel); if (ftdm_test_flag(event->channel, FTDM_CHANNEL_HOLD) && event->channel->token_count != 1) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP); } else { sig.event_id = FTDM_SIGEVENT_FLASH; ftdm_span_send_signal(span, &sig); @@ -940,12 +947,12 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e if (ftdm_test_flag(event->channel, FTDM_CHANNEL_RINGING)) { ftdm_channel_command(event->channel, FTDM_COMMAND_GENERATE_RING_OFF, NULL); } - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP); } else { if(!analog_data->max_dialstr) { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_COLLECT); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_COLLECT); } else { - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DIALTONE); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DIALTONE); } ftdm_mutex_unlock(event->channel->mutex); locked = 0; @@ -957,7 +964,7 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL); } } - ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN); + ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); } } default: diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 886c4a8fec..843ac484a5 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -467,7 +467,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) dtmf_offset = strlen(dtmf); last_digit = elapsed; sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT; - sig.raw_data = dtmf; + ftdm_set_string(sig.ev_data.collected.digits, dtmf); if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) { collecting = 0; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c index c03976a1c2..8c421b0691 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c @@ -128,8 +128,9 @@ void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d ftdm_assert(raw_data, "Failed to malloc"); memcpy(raw_data, data, data_len); - sigev.raw_data = raw_data; - sigev.raw_data_len = data_len; + sigev.raw.data = raw_data; + sigev.raw.len = data_len; + sigev.raw.autofree = 1; ftdm_span_send_signal(signal_data->ftdm_span, &sigev); } @@ -235,8 +236,9 @@ void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d ftdm_assert(raw_data, "Failed to malloc"); memcpy(raw_data, data, data_len); - sigev.raw_data = raw_data; - sigev.raw_data_len = data_len; + sigev.raw.data = raw_data; + sigev.raw.len = data_len; + sigev.raw.autofree = 1; ftdm_span_send_signal(signal_data->ftdm_span, &sigev); } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index a74fd7075a..79e873390e 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -281,16 +281,18 @@ typedef enum { #define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid" FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t) +/*! \brief Digit limit used in DNIS/ANI */ +#define FTDM_DIGITS_LIMIT 25 /*! \brief Number abstraction */ typedef struct { - char digits[25]; + char digits[FTDM_DIGITS_LIMIT]; uint8_t type; uint8_t plan; } ftdm_number_t; typedef void * ftdm_variable_container_t; - + /*! \brief Caller information */ typedef struct ftdm_caller_data { char cid_date[8]; /*!< Caller ID date */ @@ -299,10 +301,10 @@ typedef struct ftdm_caller_data { ftdm_number_t ani; /*!< ANI (Automatic Number Identification) */ ftdm_number_t dnis; /*!< DNIS (Dialed Number Identification Service) */ ftdm_number_t rdnis; /*!< RDNIS (Redirected Dialed Number Identification Service) */ - char aniII[25]; /*! ANI II */ + char aniII[FTDM_DIGITS_LIMIT]; /*! ANI II */ uint8_t screen; /*!< Screening */ uint8_t pres; /*!< Presentation*/ - char collected[25]; /*!< Collected digits so far */ + char collected[FTDM_DIGITS_LIMIT]; /*!< Collected digits so far */ int hangup_cause; /*!< Hangup cause */ char raw_data[1024]; /*!< Protocol specific raw caller data */ uint32_t raw_data_len; /*!< Raw data length */ @@ -426,19 +428,28 @@ typedef struct { uint8_t level; /* 1 for phy layer, 2 for q921/mtp2, 3 for q931/mtp3 */ } ftdm_event_trace_t; +typedef struct { + /* Digits collected */ + char digits[FTDM_DIGITS_LIMIT]; +} ftdm_event_collected_t; + /*! \brief Generic signaling message */ struct ftdm_sigmsg { ftdm_signal_event_t event_id; /*!< The type of message */ ftdm_channel_t *channel; /*!< Related channel */ uint32_t chan_id; /*!< easy access to chan id */ uint32_t span_id; /*!< easy access to span_id */ - void *raw_data; /*!< Message specific data if any */ - uint32_t raw_data_len; /*!< Data len in case is needed */ uint32_t call_id; /*!< unique call id for this call */ union { ftdm_event_sigstatus_t sigstatus; /*!< valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED */ ftdm_event_trace_t logevent; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */ + ftdm_event_collected_t collected; /*!< valif if event_id is FTDM_SIGEVENT_COLLECTED_DIGIT */ } ev_data; + struct { + uint8_t autofree; /*!< Whether the freetdm core will free it after message delivery */ + uint32_t len; /*!< Data len */ + void *data; /*!< Signaling module specific data */ + } raw; }; /*! \brief Crash policy diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index e8ee7156f8..606a89fc77 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -411,7 +411,7 @@ struct ftdm_channel { uint32_t extra_id; ftdm_chan_type_t type; ftdm_socket_t sockfd; - uint32_t flags; + uint64_t flags; uint32_t pflags; uint32_t sflags; ftdm_alarm_flag_t alarm_flags; diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index f03c060e5a..6c521e3481 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -237,52 +237,41 @@ typedef enum { "HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID" FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t) -typedef enum { - FTDM_CHANNEL_CONFIGURED = (1 << 0), - FTDM_CHANNEL_READY = (1 << 1), - FTDM_CHANNEL_OPEN = (1 << 2), - FTDM_CHANNEL_DTMF_DETECT = (1 << 3), - FTDM_CHANNEL_SUPRESS_DTMF = (1 << 4), - FTDM_CHANNEL_TRANSCODE = (1 << 5), - FTDM_CHANNEL_BUFFER = (1 << 6), - FTDM_CHANNEL_EVENT = (1 << 7), - FTDM_CHANNEL_INTHREAD = (1 << 8), - FTDM_CHANNEL_WINK = (1 << 9), - FTDM_CHANNEL_FLASH = (1 << 10), - FTDM_CHANNEL_STATE_CHANGE = (1 << 11), - FTDM_CHANNEL_HOLD = (1 << 12), - FTDM_CHANNEL_INUSE = (1 << 13), - FTDM_CHANNEL_OFFHOOK = (1 << 14), - FTDM_CHANNEL_RINGING = (1 << 15), - FTDM_CHANNEL_PROGRESS_DETECT = (1 << 16), - FTDM_CHANNEL_CALLERID_DETECT = (1 << 17), - FTDM_CHANNEL_OUTBOUND = (1 << 18), - FTDM_CHANNEL_SUSPENDED = (1 << 19), - FTDM_CHANNEL_3WAY = (1 << 20), - FTDM_CHANNEL_PROGRESS = (1 << 21), - FTDM_CHANNEL_MEDIA = (1 << 22), - FTDM_CHANNEL_ANSWERED = (1 << 23), - FTDM_CHANNEL_MUTE = (1 << 24), - FTDM_CHANNEL_USE_RX_GAIN = (1 << 25), - FTDM_CHANNEL_USE_TX_GAIN = (1 << 26), - FTDM_CHANNEL_IN_ALARM = (1 << 27), - FTDM_CHANNEL_SIG_UP = (1 << 28), - FTDM_CHANNEL_USER_HANGUP = (1 << 29), - FTDM_CHANNEL_RX_DISABLED = (1 << 30), - FTDM_CHANNEL_TX_DISABLED = (1 << 31), - /* ok, when we reach 32, we need to move to uint64_t all the flag stuff */ -} ftdm_channel_flag_t; -#if defined(__cplusplus) && defined(WIN32) - // fix C2676 -__inline__ ftdm_channel_flag_t operator|=(ftdm_channel_flag_t a, int32_t b) { - a = (ftdm_channel_flag_t)(a | b); - return a; -} -__inline__ ftdm_channel_flag_t operator&=(ftdm_channel_flag_t a, int32_t b) { - a = (ftdm_channel_flag_t)(a & b); - return a; -} -#endif +/*!< Channel flags. This used to be an enum but we reached the 32bit limit for enums */ +#define FTDM_CHANNEL_CONFIGURED (1UL << 0) +#define FTDM_CHANNEL_READY (1UL << 1) +#define FTDM_CHANNEL_OPEN (1UL << 2) +#define FTDM_CHANNEL_DTMF_DETECT (1UL << 3) +#define FTDM_CHANNEL_SUPRESS_DTMF (1UL << 4) +#define FTDM_CHANNEL_TRANSCODE (1UL << 5) +#define FTDM_CHANNEL_BUFFER (1UL << 6) +#define FTDM_CHANNEL_EVENT (1UL << 7) +#define FTDM_CHANNEL_INTHREAD (1UL << 8) +#define FTDM_CHANNEL_WINK (1UL << 9) +#define FTDM_CHANNEL_FLASH (1UL << 10) +#define FTDM_CHANNEL_STATE_CHANGE (1UL << 11) +#define FTDM_CHANNEL_HOLD (1UL << 12) +#define FTDM_CHANNEL_INUSE (1UL << 13) +#define FTDM_CHANNEL_OFFHOOK (1UL << 14) +#define FTDM_CHANNEL_RINGING (1UL << 15) +#define FTDM_CHANNEL_PROGRESS_DETECT (1UL << 16) +#define FTDM_CHANNEL_CALLERID_DETECT (1UL << 17) +#define FTDM_CHANNEL_OUTBOUND (1UL << 18) +#define FTDM_CHANNEL_SUSPENDED (1UL << 19) +#define FTDM_CHANNEL_3WAY (1UL << 20) +#define FTDM_CHANNEL_PROGRESS (1UL << 21) +#define FTDM_CHANNEL_MEDIA (1UL << 22) +#define FTDM_CHANNEL_ANSWERED (1UL << 23) +#define FTDM_CHANNEL_MUTE (1UL << 24) +#define FTDM_CHANNEL_USE_RX_GAIN (1UL << 25) +#define FTDM_CHANNEL_USE_TX_GAIN (1UL << 26) +#define FTDM_CHANNEL_IN_ALARM (1UL << 27) +#define FTDM_CHANNEL_SIG_UP (1UL << 28) +#define FTDM_CHANNEL_USER_HANGUP (1UL << 29) +#define FTDM_CHANNEL_RX_DISABLED (1UL << 30) +#define FTDM_CHANNEL_TX_DISABLED (1UL << 31) +/*!< The user knows about a call in this channel */ +#define FTDM_CHANNEL_CALL_STARTED (1UL << 32) typedef enum { ZSM_NONE, From cfd6876c2127bd64b7c2ced80407b5b9f962549b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 20 Dec 2010 14:36:03 -0600 Subject: [PATCH 123/244] more presence and not the kind with bows and ribbons --- src/mod/endpoints/mod_sofia/sofia_presence.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index f0cade3e61..059018986c 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -840,10 +840,11 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) "where sip_subscriptions.expires > -1 and " "(event='%q' or event='%q') and sub_to_user='%q' " "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " - "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host)", + "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) " + "and (presence_id is null or presence_id = '%q@%q')", switch_str_nil(status), switch_str_nil(rpid), host, dh.status,dh.rpid, - event_type, alt_event_type, euser, host, host, profile->name))) { + event_type, alt_event_type, euser, host, host, profile->name, euser, host))) { struct presence_helper helper = { 0 }; From 82ad5278b3fac8adeebbb32bf155d024d423c43c Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 20 Dec 2010 14:55:18 -0600 Subject: [PATCH 124/244] tweak vs2010 freetdm wanpipe --- .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj index b165ac82d3..40d0a73a5b 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2010.vcxproj @@ -100,7 +100,7 @@ EditAndContinue - freetdm.lib;libsangoma.lib;%(AdditionalDependencies) + libsangoma.lib;%(AdditionalDependencies) $(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) true Console @@ -127,7 +127,7 @@ ProgramDatabase - freetdm.lib;libsangoma.lib;%(AdditionalDependencies) + libsangoma.lib;%(AdditionalDependencies) $(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories) true Console @@ -148,7 +148,7 @@ ProgramDatabase - freetdm.lib;libsangoma.lib;%(AdditionalDependencies) + libsangoma.lib;%(AdditionalDependencies) $(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) true Console @@ -174,7 +174,7 @@ ProgramDatabase - freetdm.lib;libsangoma.lib;%(AdditionalDependencies) + libsangoma.lib;%(AdditionalDependencies) $(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories) true Console From a78922a21221b1c88ebfe0093c7a55bb4bfd6be7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 20 Dec 2010 15:05:07 -0600 Subject: [PATCH 125/244] nope --- src/mod/endpoints/mod_sofia/sofia_presence.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 059018986c..f0cade3e61 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -840,11 +840,10 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) "where sip_subscriptions.expires > -1 and " "(event='%q' or event='%q') and sub_to_user='%q' " "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " - "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) " - "and (presence_id is null or presence_id = '%q@%q')", + "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host)", switch_str_nil(status), switch_str_nil(rpid), host, dh.status,dh.rpid, - event_type, alt_event_type, euser, host, host, profile->name, euser, host))) { + event_type, alt_event_type, euser, host, host, profile->name))) { struct presence_helper helper = { 0 }; From 38968d15fe3250bb86751ebb099fd6844c6346d3 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 20 Dec 2010 16:15:41 -0500 Subject: [PATCH 126/244] freetdm: fake signaling status notifications in ftmod_analog --- libs/freetdm/mod_freetdm/mod_freetdm.c | 1 + .../src/ftmod/ftmod_analog/ftmod_analog.c | 39 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 584ed27a83..7e099853a6 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1731,6 +1731,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) } break; case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + case FTDM_SIGEVENT_SIGSTATUS_CHANGED: { /* twiddle */ } break; default: { diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 5b68098ed7..0acf70b18d 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -96,6 +96,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxs_outgoing_call) static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_get_channel_sig_status) { + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) { + *status = FTDM_SIG_STATE_DOWN; + return FTDM_SUCCESS; + } *status = FTDM_SIG_STATE_UP; return FTDM_SUCCESS; } @@ -109,7 +113,25 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_get_channel_sig_status) static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_get_span_sig_status) { - *status = FTDM_SIG_STATE_UP; + ftdm_iterator_t *citer = NULL; + ftdm_iterator_t *chaniter = ftdm_span_get_chan_iterator(span, NULL); + if (!chaniter) { + ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); + return FTDM_FAIL; + } + /* if ALL channels are in alarm, report DOWN, UP otherwise. */ + *status = FTDM_SIG_STATE_DOWN; + for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { + ftdm_channel_t *fchan = ftdm_iterator_current(citer); + ftdm_channel_lock(fchan); + if (!ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) { + *status = FTDM_SIG_STATE_UP; + ftdm_channel_unlock(fchan); + break; + } + ftdm_channel_unlock(fchan); + } + ftdm_iterator_free(chaniter); return FTDM_SUCCESS; } @@ -967,6 +989,21 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); } } + break; + case FTDM_OOB_ALARM_TRAP: + { + sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sig.ev_data.sigstatus.status = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(span, &sig); + } + break; + case FTDM_OOB_ALARM_CLEAR: + { + sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sig.ev_data.sigstatus.status = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(span, &sig); + } + break; default: { ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Ignoring event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state)); From f804c75d99598cfce0d4e09c0fcef40bd8827f9d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 20 Dec 2010 15:43:54 -0600 Subject: [PATCH 127/244] presence was drafted by satan --- src/mod/endpoints/mod_sofia/sofia_presence.c | 31 +++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index f0cade3e61..4b93492eae 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -55,6 +55,7 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char * struct dialog_helper { char status[512]; char rpid[512]; + char presence_id[1024]; }; struct resub_helper { @@ -479,9 +480,10 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha { struct dialog_helper *helper = (struct dialog_helper *) pArg; - if (argc == 2) { + if (argc == 3) { switch_set_string(helper->status, argv[0]); switch_set_string(helper->rpid, argv[1]); + switch_set_string(helper->presence_id, argv[2]); } return -1; @@ -638,7 +640,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) } if (probe_euser && probe_host && (profile = sofia_glue_find_profile(probe_host))) { - sql = switch_mprintf("select status,rpid from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')", + sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs " + "where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')", probe_euser, probe_host, probe_euser, probe_host); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh); @@ -656,16 +659,16 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) "sip_dialogs.direction, " "sip_dialogs.sip_to_user, " "sip_dialogs.sip_to_host, " + "sip_presence.status," "sip_presence.rpid," "sip_dialogs.presence_id, " "sip_presence.open_closed," "'%q','%q' " + "from sip_registrations " - "from sip_registrations left join sip_dialogs on " + "left join sip_dialogs on " "sip_dialogs.presence_id = sip_registrations.sip_user || '@' || sip_registrations.sip_host " - - "or (sip_dialogs.sip_from_user = sip_registrations.sip_user " "and sip_dialogs.sip_from_host = sip_registrations.sip_host) " @@ -813,7 +816,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } - sql = switch_mprintf("select status,rpid from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')", + sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')", euser, host, euser, host); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh); switch_safe_free(sql); @@ -824,25 +827,19 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," "sip_subscriptions.accept,sip_subscriptions.profile_name" ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q'," - "sip_subscriptions.version, sip_dialogs.presence_id " + "sip_subscriptions.version, '%q' " "from sip_subscriptions " "left join sip_presence on " "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and " "sip_subscriptions.profile_name=sip_presence.profile_name) " - "left join sip_dialogs on " - - "sip_dialogs.presence_id = sip_subscriptions.sub_to_user || '@' || sip_subscriptions.sub_to_host or " - - - "(sip_dialogs.sip_from_user = sip_subscriptions.sub_to_user " - "and sip_dialogs.sip_from_host = sip_subscriptions.sub_to_host) " "where sip_subscriptions.expires > -1 and " "(event='%q' or event='%q') and sub_to_user='%q' " "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " - "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host)", - switch_str_nil(status), switch_str_nil(rpid), host, - dh.status,dh.rpid, + "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ", + + switch_str_nil(status), switch_str_nil(rpid), host, + dh.status,dh.rpid,dh.presence_id, event_type, alt_event_type, euser, host, host, profile->name))) { struct presence_helper helper = { 0 }; From 092d22a2142e00245c93f9a5a6592176c00188a8 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 20 Dec 2010 16:57:01 -0500 Subject: [PATCH 128/244] freetdm: fix get caller id command --- libs/freetdm/src/ftdm_io.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 131d92ea92..c04dd85a17 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2780,7 +2780,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); GOTO_STATUS(done, FTDM_FAIL); } - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT); + GOTO_STATUS(done, FTDM_SUCCESS); } } break; @@ -2788,7 +2789,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co { if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_CALLERID)) { ftdm_fsk_demod_destroy(&ftdmchan->fsk); - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT); + GOTO_STATUS(done, FTDM_SUCCESS); } } break; @@ -3051,7 +3053,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co case FTDM_COMMAND_DISABLE_PROGRESS_DETECT: { if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_PROGRESS)) { - ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_PROGRESS_DETECT); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_PROGRESS_DETECT); ftdm_channel_clear_detected_tones(ftdmchan); ftdm_channel_clear_needed_tones(ftdmchan); GOTO_STATUS(done, FTDM_SUCCESS); @@ -3063,8 +3065,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co /* if they don't have thier own, use ours */ if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) { teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate); - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); - ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled software DTMF detector\n"); GOTO_STATUS(done, FTDM_SUCCESS); } From d29d83d74323fda1d8c6c50627dab5504c8441b8 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 20 Dec 2010 19:23:13 -0600 Subject: [PATCH 129/244] ESL-53 Noevent/Noevents disparity --- libs/esl/fs_cli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 569e2cd169..1e3bf04ca1 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -656,7 +656,7 @@ static int process_command(esl_handle_t *handle, const char *cmd) "-----------------------------------------------\n" "/help \tHelp\n" "/exit, /quit, /bye, ... \tExit the program.\n" - "/event, /noevent, /nixevent\tEvent commands.\n" + "/event, /noevents, /nixevent\tEvent commands.\n" "/log, /nolog \tLog commands.\n" "/uuid \tFilter logs for a single call uuid\n" "/filter \tFilter commands.\n" @@ -692,7 +692,7 @@ static int process_command(esl_handle_t *handle, const char *cmd) } else if ( !strncasecmp(cmd, "event", 5) || - !strncasecmp(cmd, "noevent", 7) || + !strncasecmp(cmd, "noevents", 8) || !strncasecmp(cmd, "nixevent", 8) || !strncasecmp(cmd, "log", 3) || !strncasecmp(cmd, "nolog", 5) || From 1b1dea020675d588053f0051b5236dd60d115b08 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 20 Dec 2010 20:19:36 -0600 Subject: [PATCH 130/244] FS-2879 --- src/switch_ivr_bridge.c | 4 ---- src/switch_ivr_originate.c | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 2f2dcdbc95..aa5ddb9232 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1052,8 +1052,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * switch_channel_set_variable(caller_channel, "signal_bridge", "true"); switch_channel_set_variable(peer_channel, "signal_bridge", "true"); - switch_channel_sort_cid(peer_channel, SWITCH_FALSE); - /* fire events that will change the data table from "show channels" */ if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); @@ -1119,8 +1117,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR); switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR); - switch_channel_sort_cid(peer_channel, SWITCH_FALSE); - b_leg->session = peer_session; switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid)); b_leg->stream_id = stream_id; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 87a47e65aa..51032dec60 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2410,6 +2410,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } + new_profile->callee_id_name = switch_core_strdup(new_profile->pool, "Outbound Call"); + new_profile->callee_id_number = switch_core_strdup(new_profile->pool, new_profile->destination_number); + originate_status[i].caller_profile = NULL; originate_status[i].peer_channel = NULL; originate_status[i].peer_session = NULL; From 4f9dd5e164b355d8b116a5f3cb0f0271c3366d10 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 20 Dec 2010 23:57:45 -0500 Subject: [PATCH 131/244] mod_conference: Add XML output for conference run time, recording status and member mute-detect. Also add events for recording start and stop. This work was funded by Xpander Communications. --- .../mod_conference/mod_conference.c | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 53ce82b4cb..cf8ae96da0 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -191,7 +191,8 @@ typedef enum { EFLAG_TRANSFER = (1 << 23), EFLAG_BGDIAL_RESULT = (1 << 24), EFLAG_FLOOR_CHANGE = (1 << 25), - EFLAG_MUTE_DETECT = (1 << 26) + EFLAG_MUTE_DETECT = (1 << 26), + EFLAG_RECORD = (1 << 27) } event_type_t; typedef struct conference_file_node { @@ -270,6 +271,7 @@ typedef struct conference_obj { uint32_t not_talking_buf_len; int comfort_noise_level; int is_recording; + int record_count; int video_running; uint32_t eflags; uint32_t verbose_events; @@ -283,6 +285,7 @@ typedef struct conference_obj { uint32_t avg_score; uint32_t avg_itt; uint32_t avg_tally; + switch_time_t run_time; } conference_obj_t; /* Relationship with another member */ @@ -468,6 +471,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Hear", "%s", switch_test_flag(member, MFLAG_CAN_HEAR) ? "true" : "false" ); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Speak", "%s", switch_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false" ); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Talking", "%s", switch_test_flag(member, MFLAG_TALKING) ? "true" : "false" ); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false" ); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", switch_test_flag(member, MFLAG_MOD) ? "moderator" : "member"); @@ -563,6 +567,7 @@ static switch_status_t conference_record_stop(conference_obj_t *conference, char return count; } + /* Add a custom relationship to a member */ static conference_relationship_t *member_add_relationship(conference_member_t *member, uint32_t id) { @@ -1035,6 +1040,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v switch_mutex_unlock(globals.hash_mutex); conference->is_recording = 0; + conference->record_count = 0; while (globals.running && !switch_test_flag(conference, CFLAG_DESTRUCT)) { switch_size_t file_sample_len = samples; @@ -1099,6 +1105,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v /* Start recording if there's more than one participant. */ if (conference->auto_record && !conference->is_recording && conference->count > 1) { conference->is_recording = 1; + conference->record_count++; imember = conference->members; if (imember) { switch_channel_t *channel = switch_core_session_get_channel(imember->session); @@ -2623,6 +2630,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th switch_timer_t timer = { 0 }; uint32_t rlen; switch_size_t data_buf_len; + switch_event_t *event; data_buf_len = samples * sizeof(int16_t); @@ -2701,6 +2709,15 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th switch_core_file_set_string(&fh, SWITCH_AUDIO_COL_STR_ARTIST, "FreeSWITCH mod_conference Software Conference Module"); + if (test_eflag(conference, EFLAG_RECORD) && + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "start-recording"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", rec->path); + switch_event_fire(&event); + } + + while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(conference, CFLAG_RUNNING) && conference->count) { switch_size_t len = 0; mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer); @@ -3759,6 +3776,13 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer switch_xml_set_attr_d(x_conference, "dynamic", "true"); } + if (conference->record_count > 0) { + switch_xml_set_attr_d(x_conference, "recording", "true"); + } + + switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL) - conference->run_time); + switch_xml_set_attr_d(x_conference, "run_time", ival); + if (conference->agc_level) { char tmp[30] = ""; switch_snprintf(tmp, sizeof(tmp), "%d", conference->agc_level); @@ -3825,6 +3849,9 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer x_tag = switch_xml_add_child_d(x_flags, "can_speak", count++); switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false"); + x_tag = switch_xml_add_child_d(x_flags, "mute_detect", count++); + switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false"); + x_tag = switch_xml_add_child_d(x_flags, "talking", count++); switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_TALKING) ? "true" : "false"); @@ -4414,6 +4441,7 @@ static switch_status_t conf_api_sub_record(conference_obj_t *conference, switch_ return SWITCH_STATUS_GENERR; stream->write_function(stream, "Record file %s\n", argv[2]); + conference->record_count++; launch_conference_record_thread(conference, argv[2]); return SWITCH_STATUS_SUCCESS; } @@ -4421,6 +4449,7 @@ static switch_status_t conf_api_sub_record(conference_obj_t *conference, switch_ static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { int all; + switch_event_t *event; switch_assert(conference != NULL); switch_assert(stream != NULL); @@ -4432,6 +4461,20 @@ static switch_status_t conf_api_sub_norecord(conference_obj_t *conference, switc stream->write_function(stream, "Stop recording file %s\n", argv[2]); if (!conference_record_stop(conference, all ? NULL : argv[2]) && !all) { stream->write_function(stream, "non-existant recording '%s'\n", argv[2]); + } else { + if (all) { + conference->record_count = 0; + } else { + conference->record_count--; + } + if (test_eflag(conference, EFLAG_RECORD) && + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "stop-recording"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Path", all ? "all" : argv[2]); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Other-Recordings", conference->record_count ? "true" : "false"); + switch_event_fire(&event); + } } return SWITCH_STATUS_SUCCESS; @@ -5138,6 +5181,8 @@ static void clear_eflags(char *events, uint32_t *f) *f &= ~EFLAG_BGDIAL_RESULT; } else if (!strcmp(event, "floor-change")) { *f &= ~EFLAG_FLOOR_CHANGE; + } else if (!strcmp(event, "record")) { + *f &= ~EFLAG_RECORD; } event = next; @@ -6121,6 +6166,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_m conference->caller_id_name = switch_core_strdup(conference->pool, caller_id_name); conference->caller_id_number = switch_core_strdup(conference->pool, caller_id_number); conference->caller_controls = switch_core_strdup(conference->pool, caller_controls); + conference->run_time = switch_epoch_time_now(NULL); if (!zstr(perpetual_sound)) { From 1d7a1bd1311fe633669c7d48ba65e51ccbff24db Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Dec 2010 08:57:11 -0500 Subject: [PATCH 132/244] freetdm: use ULL for flags --- libs/freetdm/src/include/private/ftdm_types.h | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 6c521e3481..b7c6d4a6f3 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -237,41 +237,41 @@ typedef enum { "HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID" FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t) -/*!< Channel flags. This used to be an enum but we reached the 32bit limit for enums */ -#define FTDM_CHANNEL_CONFIGURED (1UL << 0) -#define FTDM_CHANNEL_READY (1UL << 1) -#define FTDM_CHANNEL_OPEN (1UL << 2) -#define FTDM_CHANNEL_DTMF_DETECT (1UL << 3) -#define FTDM_CHANNEL_SUPRESS_DTMF (1UL << 4) -#define FTDM_CHANNEL_TRANSCODE (1UL << 5) -#define FTDM_CHANNEL_BUFFER (1UL << 6) -#define FTDM_CHANNEL_EVENT (1UL << 7) -#define FTDM_CHANNEL_INTHREAD (1UL << 8) -#define FTDM_CHANNEL_WINK (1UL << 9) -#define FTDM_CHANNEL_FLASH (1UL << 10) -#define FTDM_CHANNEL_STATE_CHANGE (1UL << 11) -#define FTDM_CHANNEL_HOLD (1UL << 12) -#define FTDM_CHANNEL_INUSE (1UL << 13) -#define FTDM_CHANNEL_OFFHOOK (1UL << 14) -#define FTDM_CHANNEL_RINGING (1UL << 15) -#define FTDM_CHANNEL_PROGRESS_DETECT (1UL << 16) -#define FTDM_CHANNEL_CALLERID_DETECT (1UL << 17) -#define FTDM_CHANNEL_OUTBOUND (1UL << 18) -#define FTDM_CHANNEL_SUSPENDED (1UL << 19) -#define FTDM_CHANNEL_3WAY (1UL << 20) -#define FTDM_CHANNEL_PROGRESS (1UL << 21) -#define FTDM_CHANNEL_MEDIA (1UL << 22) -#define FTDM_CHANNEL_ANSWERED (1UL << 23) -#define FTDM_CHANNEL_MUTE (1UL << 24) -#define FTDM_CHANNEL_USE_RX_GAIN (1UL << 25) -#define FTDM_CHANNEL_USE_TX_GAIN (1UL << 26) -#define FTDM_CHANNEL_IN_ALARM (1UL << 27) -#define FTDM_CHANNEL_SIG_UP (1UL << 28) -#define FTDM_CHANNEL_USER_HANGUP (1UL << 29) -#define FTDM_CHANNEL_RX_DISABLED (1UL << 30) -#define FTDM_CHANNEL_TX_DISABLED (1UL << 31) +/*!< Channel flags. This used to be an enum but we reached the 32bit limit for enums, is safer this way */ +#define FTDM_CHANNEL_CONFIGURED (1ULL << 0) +#define FTDM_CHANNEL_READY (1ULL << 1) +#define FTDM_CHANNEL_OPEN (1ULL << 2) +#define FTDM_CHANNEL_DTMF_DETECT (1ULL << 3) +#define FTDM_CHANNEL_SUPRESS_DTMF (1ULL << 4) +#define FTDM_CHANNEL_TRANSCODE (1ULL << 5) +#define FTDM_CHANNEL_BUFFER (1ULL << 6) +#define FTDM_CHANNEL_EVENT (1ULL << 7) +#define FTDM_CHANNEL_INTHREAD (1ULL << 8) +#define FTDM_CHANNEL_WINK (1ULL << 9) +#define FTDM_CHANNEL_FLASH (1ULL << 10) +#define FTDM_CHANNEL_STATE_CHANGE (1ULL << 11) +#define FTDM_CHANNEL_HOLD (1ULL << 12) +#define FTDM_CHANNEL_INUSE (1ULL << 13) +#define FTDM_CHANNEL_OFFHOOK (1ULL << 14) +#define FTDM_CHANNEL_RINGING (1ULL << 15) +#define FTDM_CHANNEL_PROGRESS_DETECT (1ULL << 16) +#define FTDM_CHANNEL_CALLERID_DETECT (1ULL << 17) +#define FTDM_CHANNEL_OUTBOUND (1ULL << 18) +#define FTDM_CHANNEL_SUSPENDED (1ULL << 19) +#define FTDM_CHANNEL_3WAY (1ULL << 20) +#define FTDM_CHANNEL_PROGRESS (1ULL << 21) +#define FTDM_CHANNEL_MEDIA (1ULL << 22) +#define FTDM_CHANNEL_ANSWERED (1ULL << 23) +#define FTDM_CHANNEL_MUTE (1ULL << 24) +#define FTDM_CHANNEL_USE_RX_GAIN (1ULL << 25) +#define FTDM_CHANNEL_USE_TX_GAIN (1ULL << 26) +#define FTDM_CHANNEL_IN_ALARM (1ULL << 27) +#define FTDM_CHANNEL_SIG_UP (1ULL << 28) +#define FTDM_CHANNEL_USER_HANGUP (1ULL << 29) +#define FTDM_CHANNEL_RX_DISABLED (1ULL << 30) +#define FTDM_CHANNEL_TX_DISABLED (1ULL << 31) /*!< The user knows about a call in this channel */ -#define FTDM_CHANNEL_CALL_STARTED (1UL << 32) +#define FTDM_CHANNEL_CALL_STARTED (1ULL << 32) typedef enum { ZSM_NONE, From e085fea23ec990470dd83d654c6639ed526420c7 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Dec 2010 09:09:10 -0500 Subject: [PATCH 133/244] freetdm: define _GNU_SOURCE to get gethostbyname_r --- .../src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c index 982dd4794d..6ddb74d253 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/sangoma_boost_client.c @@ -31,6 +31,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define _GNU_SOURCE + #if HAVE_NETDB_H #include #endif From f5c36acfe2437835254210061030f179050f62b2 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Tue, 21 Dec 2010 13:31:21 -0200 Subject: [PATCH 134/244] freetdm: mod_freetdm - updated api commands help ftmod_r2 - updated api help and removed references to threads per channel, not used anymore --- libs/freetdm/mod_freetdm/mod_freetdm.c | 14 ++++++++++++- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 24 ++++++++-------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 7e099853a6..66bc532cbc 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3536,7 +3536,19 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t * switch_channel_cause2str(caller_data->hangup_cause)); } -#define FT_SYNTAX "list || dump [] || q931_pcap on|off [pcapfilename without suffix] || gains [] || dtmf on|off []" +#define FT_SYNTAX "USAGE:\n" \ +"--------------------------------------------------------------------------------\n" \ +"ftdm list\n" \ +"ftdm start|stop \n" \ +"ftdm restart \n" \ +"ftdm dump []\n" \ +"ftdm sigstatus get|set [] [] []\n" \ +"ftdm trace []\n" \ +"ftdm notrace []\n" \ +"ftdm q931_pcap on|off [pcapfilename without suffix]\n" \ +"ftdm gains []\n" \ +"ftdm dtmf on|off []\n" \ +"--------------------------------------------------------------------------------\n" SWITCH_STANDARD_API(ft_function) { char *mycmd = NULL, *argv[10] = { 0 }; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index d178de53cd..e3ae0cf4c5 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -50,10 +50,6 @@ #include "freetdm.h" #include "private/ftdm_core.h" -/* debug thread count for r2 legs */ -static ftdm_mutex_t* g_thread_count_mutex; -static int32_t g_thread_count = 0; - typedef int openr2_call_status_t; /* when the user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread @@ -2023,6 +2019,14 @@ static void __inline__ unblock_channel(ftdm_channel_t *fchan, ftdm_stream_handle ftdm_mutex_unlock(fchan->mutex); } +#define FT_SYNTAX "USAGE:\n" \ +"--------------------------------------------------------------------------------\n" \ +"ftdm r2 status \n" \ +"ftdm r2 loopstats \n" \ +"ftdm r2 block|unblock []\n" \ +"ftdm r2 version\n" \ +"ftdm r2 variants\n" \ +"--------------------------------------------------------------------------------\n" static FIO_API_FUNCTION(ftdm_r2_api) { ftdm_span_t *span = NULL; @@ -2206,14 +2210,6 @@ static FIO_API_FUNCTION(ftdm_r2_api) } if (argc == 1) { - if (!strcasecmp(argv[0], "threads")) { - ftdm_mutex_lock(g_thread_count_mutex); - stream->write_function(stream, "%d R2 channel threads up\n", g_thread_count); - ftdm_mutex_unlock(g_thread_count_mutex); - stream->write_function(stream, "+OK.\n"); - goto done; - } - if (!strcasecmp(argv[0], "version")) { stream->write_function(stream, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision()); stream->write_function(stream, "+OK.\n"); @@ -2239,7 +2235,7 @@ static FIO_API_FUNCTION(ftdm_r2_api) } } - stream->write_function(stream, "-ERR invalid command.\n"); + stream->write_function(stream, "%s", FT_SYNTAX); done: @@ -2268,7 +2264,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_r2_init) if (!g_mod_data_hash) { return FTDM_FAIL; } - ftdm_mutex_create(&g_thread_count_mutex); return FTDM_SUCCESS; } @@ -2288,7 +2283,6 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_r2_destroy) } } hashtable_destroy(g_mod_data_hash); - ftdm_mutex_destroy(&g_thread_count_mutex); return FTDM_SUCCESS; } From 94bd1a7f26df0f59652364e33f9e9b46729b036a Mon Sep 17 00:00:00 2001 From: Michal Bielicki Date: Tue, 21 Dec 2010 15:52:22 +0000 Subject: [PATCH 135/244] added german ringtone --- conf/vars.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/vars.xml b/conf/vars.xml index fced2ef139..05561d778c 100644 --- a/conf/vars.xml +++ b/conf/vars.xml @@ -204,6 +204,7 @@ + + - + - - + + + + + + + - - + + + + + + + + + + + + + + + + - diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 7e099853a6..0709021aca 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2717,6 +2717,9 @@ static switch_status_t load_config(void) char *hold_music = NULL; char *fail_dial_regex = NULL; const char *enable_callerid = "true"; + const char *answer_polarity = "false"; + const char *hangup_polarity = "false"; + int polarity_delay = 600; int callwaiting = 1; uint32_t span_id = 0, to = 0, max = 0; @@ -2788,6 +2791,12 @@ static switch_status_t load_config(void) dial_regex = val; } else if (!strcasecmp(var, "enable-callerid")) { enable_callerid = val; + } else if (!strcasecmp(var, "answer-polarity-reverse")) { + answer_polarity = val; + } else if (!strcasecmp(var, "hangup-polarity-reverse")) { + hangup_polarity = val; + } else if (!strcasecmp(var, "polarity-delay")) { + polarity_delay = atoi(val); } else if (!strcasecmp(var, "fail-dial-regex")) { fail_dial_regex = val; } else if (!strcasecmp(var, "hold-music")) { @@ -2848,6 +2857,9 @@ static switch_status_t load_config(void) "max_dialstr", &max, "hotline", hotline ? hotline : "", "enable_callerid", enable_callerid, + "answer_polarity_reverse", answer_polarity, + "hangup_polarity_reverse", hangup_polarity, + "polarity_delay", &polarity_delay, "callwaiting", &callwaiting, FTDM_TAG_END) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span)); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index c04dd85a17..955729df36 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1541,6 +1541,7 @@ end: ftdm_mutex_unlock(ftdmchan->span->mutex); } else { ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "VETO state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); + goto done; } /* there is an inherent race here between set and check of the change flag but we do not care because @@ -1570,7 +1571,7 @@ end: ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not processed after aprox %dms\n", ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME); } - +done: return ok ? FTDM_SUCCESS : FTDM_FAIL; } @@ -2289,8 +2290,15 @@ static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const c ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1); } else { /* the signaling stack did not touch the state, - * core is responsible from clearing flags and stuff */ - ftdm_channel_close(&chan); + * core is responsible from clearing flags and stuff, however, because ftmod_analog + * is a bitch in a serious need of refactoring, we also check whether the channel is open + * to avoid an spurious warning about the channel not being open. This is because ftmod_analog + * does not follow our convention of sending SIGEVENT_STOP and waiting for the user to move + * to HANGUP (implicitly through ftdm_channel_call_hangup(), as soon as ftmod_analog is fixed + * this check can be removed */ + if (ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { + ftdm_channel_close(&chan); + } } return FTDM_SUCCESS; } @@ -3933,7 +3941,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "cannot write in channel not open\n"); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot write in channel not open\n"); snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open"); status = FTDM_FAIL; goto done; diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h b/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h index 2c79822b29..39cbc5ff2b 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftdm_analog.h @@ -37,7 +37,9 @@ typedef enum { FTDM_ANALOG_RUNNING = (1 << 0), - FTDM_ANALOG_CALLERID = (1 << 1) + FTDM_ANALOG_CALLERID = (1 << 1), + FTDM_ANALOG_ANSWER_POLARITY_REVERSE = (1 << 2), + FTDM_ANALOG_HANGUP_POLARITY_REVERSE = (1 << 3) } ftdm_analog_flag_t; #define FTDM_MAX_HOTLINE_STR 20 @@ -47,11 +49,13 @@ struct ftdm_analog_data { uint32_t flags; uint32_t max_dialstr; uint32_t wait_dialtone_timeout; + uint32_t polarity_delay; uint32_t digit_timeout; char hotline[FTDM_MAX_HOTLINE_STR]; }; - +/* Analog flags to be set in the sflags (signaling flags) channel memeber */ +#define AF_POLARITY_REVERSE (1 << 0) static void *ftdm_analog_run(ftdm_thread_t *me, void *obj); typedef struct ftdm_analog_data ftdm_analog_data_t; diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 0acf70b18d..981df5dcc9 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -184,6 +184,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span) uint32_t digit_timeout = 10; uint32_t wait_dialtone_timeout = 30000; uint32_t max_dialstr = MAX_DTMF; + uint32_t polarity_delay = 600; const char *var, *val; int *intval; uint32_t flags = FTDM_ANALOG_CALLERID; @@ -236,6 +237,29 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span) } else { flags &= ~FTDM_ANALOG_CALLERID; } + } else if (!strcasecmp(var, "answer_polarity_reverse")) { + if (!(val = va_arg(ap, char *))) { + break; + } + if (ftdm_true(val)) { + flags |= FTDM_ANALOG_ANSWER_POLARITY_REVERSE; + } else { + flags &= ~FTDM_ANALOG_ANSWER_POLARITY_REVERSE; + } + } else if (!strcasecmp(var, "hangup_polarity_reverse")) { + if (!(val = va_arg(ap, char *))) { + break; + } + if (ftdm_true(val)) { + flags |= FTDM_ANALOG_HANGUP_POLARITY_REVERSE; + } else { + flags &= ~FTDM_ANALOG_HANGUP_POLARITY_REVERSE; + } + } else if (!strcasecmp(var, "polarity_delay")) { + if (!(intval = va_arg(ap, int *))) { + break; + } + polarity_delay = *intval; } else if (!strcasecmp(var, "callwaiting")) { if (!(intval = va_arg(ap, int *))) { break; @@ -276,6 +300,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span) analog_data->flags = flags; analog_data->digit_timeout = digit_timeout; analog_data->wait_dialtone_timeout = wait_dialtone_timeout; + analog_data->polarity_delay = polarity_delay; analog_data->max_dialstr = max_dialstr; span->signal_cb = sig_cb; strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline)); @@ -399,6 +424,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data; ftdm_channel_t *closed_chan; uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout; + uint32_t answer_on_polarity_counter = 0; ftdm_sigmsg_t sig; ftdm_status_t status; @@ -470,7 +496,12 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) if (ftdmchan->needed_tones[FTDM_TONEMAP_DIAL]) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); } else { - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); + /* do not go up if we're waiting for polarity reversal */ + if (ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) { + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } else { + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); + } } } } @@ -561,8 +592,30 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) } case FTDM_CHANNEL_STATE_UP: case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: { - ftdm_sleep(interval); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) && + ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA && + ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Answering on polarity reverse\n"); + ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE); + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); + answer_on_polarity_counter = state_counter; + } else if (ftdmchan->state == FTDM_CHANNEL_STATE_UP + && ftdm_test_sflag(ftdmchan, AF_POLARITY_REVERSE)){ + /* if this polarity reverse is close to the answer polarity reverse, ignore it */ + if (answer_on_polarity_counter + && (state_counter - answer_on_polarity_counter) > analog_data->polarity_delay) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Hanging up on polarity reverse\n"); + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, + "Not hanging up on polarity reverse, too close to Answer reverse\n"); + } + ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE); + } else { + ftdm_sleep(interval); + } continue; } break; @@ -615,6 +668,18 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) sig.event_id = FTDM_SIGEVENT_UP; } + if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && + !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) && + ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE)) { + ftdm_polarity_t polarity = FTDM_POLARITY_REVERSE; + if (ftdmchan->polarity != FTDM_POLARITY_FORWARD) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Polarity is already reversed on answer??\n"); + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on answer\n"); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity); + } + } + ftdm_span_send_signal(ftdmchan->span, &sig); continue; } @@ -639,6 +704,22 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) continue; } break; + + case FTDM_CHANNEL_STATE_HANGUP: + /* this state is only used when the user hangup, if the device hang up (onhook) we currently + * go straight to DOWN. If we ever change this (as other signaling modules do) by using this + * state for both user and device hangup, we should check here for the type of hangup since + * some actions (polarity reverse) do not make sense if the device hung up */ + if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && + ftdmchan->last_state == FTDM_CHANNEL_STATE_UP && + ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) { + ftdm_polarity_t polarity = ftdmchan->polarity == FTDM_POLARITY_REVERSE + ? FTDM_POLARITY_FORWARD : FTDM_POLARITY_REVERSE; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Reversing polarity on hangup\n"); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_POLARITY, &polarity); + } + break; + case FTDM_CHANNEL_STATE_DOWN: { sig.event_id = FTDM_SIGEVENT_STOP; @@ -847,6 +928,9 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) done: + closed_chan = ftdmchan; + + ftdm_channel_lock(closed_chan); if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL); @@ -857,7 +941,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) } - closed_chan = ftdmchan; + ftdm_clear_sflag(ftdmchan, AF_POLARITY_REVERSE); + ftdm_channel_close(&ftdmchan); ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL); @@ -875,8 +960,11 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) } ftdm_log_chan(closed_chan, FTDM_LOG_DEBUG, "ANALOG CHANNEL %d:%d thread ended.\n", closed_chan->span_id, closed_chan->chan_id); + ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD); + ftdm_channel_unlock(closed_chan); + return NULL; } @@ -903,6 +991,19 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_mutex_lock(event->channel->mutex); locked++; + /* MAINTENANCE WARNING: + * 1. Be aware you are working on the locked channel + * 2. We should not be calling ftdm_span_send_signal or ftdm_set_state when there is already a channel thread running + * however, since this is old code I am not changing it now, but new code should adhere to that convention + * otherwise, we have possible races where we compete with the user for state changes, ie, the user requests + * a state change and then we process an event, the state change from the user is pending so our ftdm_set_state + * operation will fail. In cases where we win the race, our state change will be accepted but if a user requests + * a state change before the state change we requested here is processed by the channel thread, we'll end up + * rejecting the user request. + * + * See docs/locking.txt for further information about what guarantees should signaling modules provide when + * locking/unlocking a channel + * */ switch(event->enum_id) { case FTDM_OOB_RING_START: { @@ -940,7 +1041,11 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e } ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN); } - + if (event->channel->type == FTDM_CHAN_TYPE_FXS) { + /* we always return to forward when the device goes onhook */ + ftdm_polarity_t forward_polarity = FTDM_POLARITY_FORWARD; + ftdm_channel_command(event->channel, FTDM_COMMAND_SET_POLARITY, &forward_polarity); + } } break; case FTDM_OOB_FLASH: @@ -1004,6 +1109,35 @@ static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *e ftdm_span_send_signal(span, &sig); } break; + case FTDM_OOB_POLARITY_REVERSE: + { + if (event->channel->type != FTDM_CHAN_TYPE_FXO) { + ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING, + "Ignoring polarity reversal, this should not happen in non-FXO channels!\n"); + break; + } + if (!ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD) && + ftdm_test_flag(event->channel, FTDM_CHANNEL_OFFHOOK)) { + ftdm_log_chan_msg(event->channel, FTDM_LOG_WARNING, + "Forcing onhook in channel not in thread after polarity reversal\n"); + ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL); + break; + } + if (!ftdm_test_flag(analog_data, FTDM_ANALOG_ANSWER_POLARITY_REVERSE) + && !ftdm_test_flag(analog_data, FTDM_ANALOG_HANGUP_POLARITY_REVERSE)) { + ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, + "Ignoring polarity reversal because this channel is not configured for it\n"); + break; + } + if (event->channel->state == FTDM_CHANNEL_STATE_DOWN) { + ftdm_log_chan_msg(event->channel, FTDM_LOG_DEBUG, + "Ignoring polarity reversal because this channel is down\n"); + break; + } + /* we have a good channel, set the polarity flag and let the channel thread deal with it */ + ftdm_set_sflag(event->channel, AF_POLARITY_REVERSE); + } + break; default: { ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Ignoring event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state)); diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 2db4326847..5e9318f7e5 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -784,17 +784,27 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size); } break; + case FTDM_COMMAND_SET_POLARITY: + { + ftdm_polarity_t polarity = FTDM_COMMAND_OBJ_INT; + err = sangoma_tdm_set_polarity(ftdmchan->sockfd, &tdm_api, polarity); + if (!err) { + ftdmchan->polarity = polarity; + } + } + break; default: err = FTDM_NOTIMPL; break; }; if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); + int myerrno = errno; + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to execute command %d: %s\n", command, strerror(myerrno)); + errno = myerrno; return err; } - return FTDM_SUCCESS; } @@ -1237,8 +1247,9 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event) wanpipe_tdm_api_t tdm_api; ftdm_span_t *span = ftdmchan->span; - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) { ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT); + } memset(&tdm_api, 0, sizeof(tdm_api)); status = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api); @@ -1251,7 +1262,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event) ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) { - case WP_TDMAPI_EVENT_LINK_STATUS: + case WP_API_EVENT_LINK_STATUS: { switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) { case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: @@ -1264,7 +1275,7 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event) } break; - case WP_TDMAPI_EVENT_RXHOOK: + case WP_API_EVENT_RXHOOK: { if (ftdmchan->type == FTDM_CHAN_TYPE_FXS) { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK; @@ -1300,26 +1311,26 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event) } } break; - case WP_TDMAPI_EVENT_RING_DETECT: + case WP_API_EVENT_RING_DETECT: { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP; } break; /* disabled this ones when configuring, we don't need them, do we? - case WP_TDMAPI_EVENT_RING_TRIP_DETECT: + case WP_API_EVENT_RING_TRIP_DETECT: { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK; } break; */ - case WP_TDMAPI_EVENT_RBS: + case WP_API_EVENT_RBS: { event_id = FTDM_OOB_CAS_BITS_CHANGE; ftdmchan->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits); } break; - case WP_TDMAPI_EVENT_DTMF: + case WP_API_EVENT_DTMF: { char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 }; event_id = FTDM_OOB_NOOP; @@ -1342,12 +1353,18 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event) } } break; - case WP_TDMAPI_EVENT_ALARM: + case WP_API_EVENT_ALARM: { ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm); event_id = FTDM_OOB_ALARM_TRAP; } break; + case WP_API_EVENT_POLARITY_REVERSE: + { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Got polarity reverse\n"); + event_id = FTDM_OOB_POLARITY_REVERSE; + } + break; default: { ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); @@ -1423,7 +1440,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) { - case WP_TDMAPI_EVENT_LINK_STATUS: + case WP_API_EVENT_LINK_STATUS: { switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) { case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: @@ -1436,7 +1453,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) } break; - case WP_TDMAPI_EVENT_RXHOOK: + case WP_API_EVENT_RXHOOK: { if (span->channels[i]->type == FTDM_CHAN_TYPE_FXS) { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK; @@ -1472,26 +1489,26 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) } } break; - case WP_TDMAPI_EVENT_RING_DETECT: + case WP_API_EVENT_RING_DETECT: { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP; } break; /* disabled this ones when configuring, we don't need them, do we? - case WP_TDMAPI_EVENT_RING_TRIP_DETECT: + case WP_API_EVENT_RING_TRIP_DETECT: { event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK; } break; */ - case WP_TDMAPI_EVENT_RBS: + case WP_API_EVENT_RBS: { event_id = FTDM_OOB_CAS_BITS_CHANGE; span->channels[i]->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits); } break; - case WP_TDMAPI_EVENT_DTMF: + case WP_API_EVENT_DTMF: { char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 }; event_id = FTDM_OOB_NOOP; @@ -1514,12 +1531,18 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) } } break; - case WP_TDMAPI_EVENT_ALARM: + case WP_API_EVENT_ALARM: { ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm); event_id = FTDM_OOB_ALARM_TRAP; } break; + case WP_API_EVENT_POLARITY_REVERSE: + { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Got polarity reverse\n"); + event_id = FTDM_OOB_POLARITY_REVERSE; + } + break; default: { ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 79e873390e..dfb3f1fc02 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -557,8 +557,14 @@ typedef enum { FTDM_COMMAND_COUNT, FTDM_COMMAND_SET_RX_QUEUE_SIZE, FTDM_COMMAND_SET_TX_QUEUE_SIZE, + FTDM_COMMAND_SET_POLARITY, } ftdm_command_t; +typedef enum { + FTDM_POLARITY_FORWARD = 0, + FTDM_POLARITY_REVERSE = 1 +} ftdm_polarity_t; + /*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */ typedef void *(*ftdm_malloc_func_t)(void *pool, ftdm_size_t len); typedef void *(*ftdm_calloc_func_t)(void *pool, ftdm_size_t elements, ftdm_size_t len); diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 606a89fc77..b90e98736a 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -143,7 +143,9 @@ extern "C" { \return true value if the object has the flags defined */ #define ftdm_test_flag(obj, flag) ((obj)->flags & flag) +/*!< Physical (IO) module specific flags */ #define ftdm_test_pflag(obj, flag) ((obj)->pflags & flag) +/*!< signaling module specific flags */ #define ftdm_test_sflag(obj, flag) ((obj)->sflags & flag) #define ftdm_set_alarm_flag(obj, flag) (obj)->alarm_flags |= (flag) @@ -456,6 +458,7 @@ struct ftdm_channel { ftdm_fsk_data_state_t fsk; uint8_t fsk_buf[80]; uint32_t ring_count; + ftdm_polarity_t polarity; /* Private I/O data. Do not touch unless you are an I/O module */ void *io_data; /* Private signaling data. Do not touch unless you are a signaling module */ diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 6c521e3481..db15b106c1 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -123,6 +123,7 @@ typedef enum { FTDM_STR2ENUM_P(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t) typedef enum { + FTDM_OOB_NOOP, FTDM_OOB_ONHOOK, FTDM_OOB_OFFHOOK, FTDM_OOB_WINK, @@ -131,11 +132,11 @@ typedef enum { FTDM_OOB_RING_STOP, FTDM_OOB_ALARM_TRAP, FTDM_OOB_ALARM_CLEAR, - FTDM_OOB_NOOP, FTDM_OOB_CAS_BITS_CHANGE, + FTDM_OOB_POLARITY_REVERSE, FTDM_OOB_INVALID } ftdm_oob_event_t; -#define OOB_STRINGS "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "NOOP", "CAS_BITS_CHANGE", "INVALID" +#define OOB_STRINGS "NOOP", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "CAS_BITS_CHANGE", "POLARITY_REVERSE", "INVALID" FTDM_STR2ENUM_P(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t) /*! \brief Event types */ From a3b01c195be3c1454c60e634477d8c825c60ac77 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 21 Dec 2010 15:35:13 -0600 Subject: [PATCH 139/244] 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 140/244] 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 141/244] 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 @@ - + From 81608da0067cb1bca2f718e4973e83af9371a659 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 29 Dec 2010 12:28:12 -0600 Subject: [PATCH 192/244] refactor sofia_contact to try the profile_name first then the domain to resolve the profile then fall back to querying every profile to reduce confusion with multi-homers (d'oh) also special profile name * will force a search-all situation --- src/mod/endpoints/mod_sofia/mod_sofia.c | 137 ++++++++++++++---------- 1 file changed, 81 insertions(+), 56 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 8aa37b95be..af7149b8c8 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3395,6 +3395,36 @@ SWITCH_STANDARD_API(sofia_count_reg_function) return SWITCH_STATUS_SUCCESS; } +static void select_from_profile(sofia_profile_t *profile, + const char *user, + const char *domain, + const char *concat, + const char *exclude_contact, + switch_stream_handle_t *stream) +{ + struct cb_helper cb; + char *sql; + + cb.row_process = 0; + + cb.profile = profile; + cb.stream = stream; + + if (exclude_contact) { + sql = switch_mprintf("select contact, profile_name, '%q' " + "from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%') " + "and contact not like '%%%s%%'", (concat != NULL) ? concat : "", user, domain, domain, exclude_contact); + } else { + sql = switch_mprintf("select contact, profile_name, '%q' " + "from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", + (concat != NULL) ? concat : "", user, domain, domain); + } + + switch_assert(sql); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, contact_callback, &cb); + switch_safe_free(sql); +} + SWITCH_STANDARD_API(sofia_contact_function) { char *data; @@ -3406,6 +3436,7 @@ SWITCH_STANDARD_API(sofia_contact_function) sofia_profile_t *profile = NULL; const char *exclude_contact = NULL; char *reply = "error/facility_not_subscribed"; + switch_stream_handle_t mystream = { 0 }; if (!cmd) { stream->write_function(stream, "%s", ""); @@ -3440,76 +3471,70 @@ SWITCH_STANDARD_API(sofia_contact_function) } } - if (!profile_name && domain) { - profile_name = domain; + if (zstr(domain)) { + domain = switch_core_get_variable("domain"); } - if (user && profile_name) { - char *sql; + if (!user) goto end; - if (!(profile = sofia_glue_find_profile(profile_name))) { - profile_name = domain; - domain = NULL; - } - - if (!profile && profile_name) { + if (zstr(profile_name) || strcmp(profile_name, "*") || zstr(domain)) { + if (!zstr(profile_name)) { profile = sofia_glue_find_profile(profile_name); } - - if (profile) { - struct cb_helper cb; - switch_stream_handle_t mystream = { 0 }; - - cb.row_process = 0; - - if (!domain || (!strchr(domain, '.') && strcmp(profile_name, domain))) { - domain = profile->name; - } - - SWITCH_STANDARD_STREAM(mystream); - switch_assert(mystream.data); - cb.profile = profile; - cb.stream = &mystream; - - if (exclude_contact) { - sql = switch_mprintf("select contact, profile_name, '%q' " - "from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%') " - "and contact not like '%%%s%%'", (concat != NULL) ? concat : "", user, domain, domain, exclude_contact); - } else { - sql = switch_mprintf("select contact, profile_name, '%q' " - "from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", - (concat != NULL) ? concat : "", user, domain, domain); - } - - switch_assert(sql); - sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, contact_callback, &cb); - switch_safe_free(sql); - reply = (char *) mystream.data; - if (!zstr(reply) && end_of(reply) == ',') { - end_of(reply) = '\0'; - } - - if (zstr(reply)) { - reply = "error/user_not_registered"; - } - - stream->write_function(stream, "%s", reply); - reply = NULL; - - switch_safe_free(mystream.data); + + if (!profile) { + profile = sofia_glue_find_profile(domain); } } - if (reply) { - stream->write_function(stream, "%s", reply); + if (profile || !zstr(domain)) { + SWITCH_STANDARD_STREAM(mystream); + switch_assert(mystream.data); } - switch_safe_free(data); - if (profile) { + if (zstr(domain)) { + domain = profile->name; + } + + select_from_profile(profile, user, domain, concat, exclude_contact, &mystream); sofia_glue_release_profile(profile); + + } else if (!zstr(domain)) { + switch_mutex_lock(mod_sofia_globals.hash_mutex); + if (mod_sofia_globals.profile_hash) { + switch_hash_index_t *hi; + const void *var; + void *val; + + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + if ((profile = (sofia_profile_t *) val) && !strcmp((char *)var, profile->name)) { + select_from_profile(profile, user, domain, concat, exclude_contact, &mystream); + profile = NULL; + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + } + + reply = (char *) mystream.data; + + end: + + if (zstr(reply)) { + reply = "error/user_not_registered"; + } else if (end_of(reply) == ',') { + end_of(reply) = '\0'; } + stream->write_function(stream, "%s", reply); + reply = NULL; + + switch_safe_free(mystream.data); + + switch_safe_free(data); + return SWITCH_STATUS_SUCCESS; } From 090864fa3997cf697f046200e1ea813464ec79d8 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 29 Dec 2010 13:38:43 -0500 Subject: [PATCH 193/244] freetdm: completed most of the code for the new core state processing use new core state processing functions in ftmod_r2 --- libs/freetdm/mod_freetdm/mod_freetdm.c | 15 +- libs/freetdm/src/ftdm_io.c | 63 ++-- libs/freetdm/src/ftdm_state.c | 44 ++- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 350 ++++++++---------- libs/freetdm/src/include/freetdm.h | 14 +- libs/freetdm/src/include/ftdm_declare.h | 1 + libs/freetdm/src/include/private/ftdm_core.h | 2 +- libs/freetdm/src/include/private/ftdm_state.h | 5 +- 8 files changed, 250 insertions(+), 244 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index d9c26db4fe..e08d4c1f3b 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -421,16 +421,18 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); - assert(channel != NULL); + switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); + switch_assert(tech_pvt != NULL); - assert(tech_pvt->ftdmchan != NULL); + switch_assert(tech_pvt->ftdmchan != NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel)); - ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED); + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { + ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROCEED); + } return SWITCH_STATUS_SUCCESS; } @@ -441,10 +443,10 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); - assert(channel != NULL); + switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); + switch_assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel)); @@ -2094,6 +2096,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) break; case FTDM_SIGEVENT_PROCEED:{} break; + case FTDM_SIGEVENT_INDICATION_COMPLETED:{} break; default: { diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 161ccdcc18..0c25054816 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1022,6 +1022,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t } ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY); + new_chan->state = FTDM_CHANNEL_STATE_DOWN; + new_chan->state_status = FTDM_STATE_STATUS_COMPLETED; *chan = new_chan; return FTDM_SUCCESS; } @@ -2012,10 +2014,14 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char return status; } -FT_DECLARE(void) ftdm_ack_indication(const ftdm_channel_t *fchan, ftdm_channel_indication_t indication, ftdm_status_t status) +FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *fchan, ftdm_channel_indication_t indication, ftdm_status_t status) { ftdm_sigmsg_t msg; + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Acknowledging indication %s in state %s (rc = %d)\n", + ftdm_channel_indication2str(indication), ftdm_channel_state2str(fchan->state), status); + ftdm_clear_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING); memset(&msg, 0, sizeof(msg)); + msg.channel = fchan; msg.event_id = FTDM_SIGEVENT_INDICATION_COMPLETED; msg.ev_data.indication_completed.indication = indication; msg.ev_data.indication_completed.status = status; @@ -2197,21 +2203,39 @@ FT_DECLARE(uint32_t) ftdm_channel_get_ph_span_id(const ftdm_channel_t *ftdmchan) /* * Every user requested indication *MUST* be acknowledged with the proper status (ftdm_status_t) - * If the indication fails before we notify the signaling stack, we *MUST* acknowledge ourselves, + * However, if the indication fails before we notify the signaling stack, we don't need to ack * but if we already notified the signaling stack about the indication, the signaling stack is - * responsible for the acknowledge. + * responsible for the acknowledge. Bottom line is, whenever this function returns FTDM_SUCCESS + * someone *MUST* acknowledge the indication, either the signaling stack, this function or the core + * at some later point * */ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication) { ftdm_status_t status = FTDM_SUCCESS; + ftdm_assert_return(ftdmchan, FTDM_FAIL, "Null channel\n"); + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Indicating %s in state %s\n", + ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); + ftdm_channel_lock(ftdmchan); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n", + ftdm_channel_indication2str(indication), + ftdm_channel_indication2str(ftdmchan->indication), + ftdm_channel_state2str(ftdmchan->state)); + status = FTDM_EBUSY; + goto done; + } + + ftdmchan->indication = indication; + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot indicate %s in outgoing channel in state %s\n", ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); status = FTDM_EINVAL; - ftdm_ack_indication(ftdmchan, indication, status); goto done; } @@ -2219,7 +2243,6 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring indication %s because the call is in %s state\n", ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); status = FTDM_ECANCELED; - ftdm_ack_indication(ftdmchan, indication, status); goto done; } @@ -2228,15 +2251,9 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch * (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */ case FTDM_CHANNEL_INDICATE_RINGING: status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RINGING, 1); - if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, indication, status); - } break; case FTDM_CHANNEL_INDICATE_BUSY: status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1); - if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, indication, status); - } break; case FTDM_CHANNEL_INDICATE_PROCEED: if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE)) { @@ -2244,47 +2261,34 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch goto done; } status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROCEED, 1); - if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, indication, status); - } break; case FTDM_CHANNEL_INDICATE_PROGRESS: status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); - if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, indication, status); - } break; case FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA: if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) { if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, indication, status); goto done; } } /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n"); - status = FTDM_ECANCELED; - ftdm_ack_indication(ftdmchan, indication, status); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring progress media because the call is terminating\n"); goto done; } } - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); - if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, indication, status); - } + status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); break; case FTDM_CHANNEL_INDICATE_ANSWER: - /* _ftdm_channel_call_indicate takes care of the indication ack */ + /* _ftdm_channel_call_answer takes care of the indication ack */ status = _ftdm_channel_call_answer(file, func, line, ftdmchan); break; default: ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Do not know how to indicate %d\n", indication); - status = FTDM_FAIL; - ftdm_ack_indication(ftdmchan, indication, status); + status = FTDM_EINVAL; break; } @@ -2463,6 +2467,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; ftdmchan->state = FTDM_CHANNEL_STATE_DOWN; + ftdmchan->state_status = FTDM_STATE_STATUS_COMPLETED; ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_DEBUG_DTMF, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL); @@ -5023,7 +5028,7 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const ftdm_assert_return(parameters != NULL, FTDM_FAIL, "No parameters"); if (!span->chan_count) { - ftdm_log(FTDM_LOG_WARNING, "Cannot configure signaling on span with no channels\n"); + ftdm_log(FTDM_LOG_WARNING, "Cannot configure signaling on span %s with no channels\n", span->name); return FTDM_FAIL; } diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index 2b544756ec..12dc37957a 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -37,6 +37,9 @@ FTDM_ENUM_NAMES(CHANNEL_STATE_NAMES, CHANNEL_STATE_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t, CHANNEL_STATE_NAMES, FTDM_CHANNEL_STATE_INVALID) +FTDM_ENUM_NAMES(CHANNEL_STATE_STATUS_NAMES, CHANNEL_STATE_STATUS_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_state_status, ftdm_state_status2str, ftdm_state_status_t, CHANNEL_STATE_STATUS_NAMES, FTDM_STATE_STATUS_INVALID) + /* This function is only needed for boost and we should get rid of it at the next refactoring */ FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *fchan) { @@ -54,12 +57,17 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *fchan) FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *func, int line, ftdm_channel_t *fchan) { uint8_t hindex = 0; + ftdm_time_t diff = 0; ftdm_channel_state_t state = fchan->state; if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) { + ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL, + "State change flag set but state is not completed\n"); return FTDM_SUCCESS; } + ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE); + if (state == FTDM_CHANNEL_STATE_PROGRESS) { ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); } else if (state == FTDM_CHANNEL_STATE_UP) { @@ -71,19 +79,28 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c ftdm_set_flag(fchan, FTDM_CHANNEL_MEDIA); } - /* if there is a pending ack for an indication */ + /* if there is a pending ack for an indication + * MAINTENANCE WARNING: we're assuming an indication performed + * via state change will involve a single state change + */ if (ftdm_test_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING)) { ftdm_ack_indication(fchan, fchan->indication, FTDM_SUCCESS); - ftdm_clear_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING); } - ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s\n", ftdm_channel_state2str(fchan->state), ftdm_channel_state2str(state)); - hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (hindex - 1); + hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1); ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n"); fchan->history[hindex].end_time = ftdm_current_time_in_ms(); + fchan->state_status = FTDM_STATE_STATUS_COMPLETED; + + diff = fchan->history[hindex].end_time - fchan->history[hindex].time; + + ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %llums\n", + ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff); + + /* FIXME: broadcast condition to wake up anyone waiting on state completion if the channel * is blocking (FTDM_CHANNEL_NONBLOCK is not set) */ @@ -93,9 +110,9 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c FT_DECLARE(ftdm_status_t) _ftdm_set_state(const char *file, const char *func, int line, ftdm_channel_t *fchan, ftdm_channel_state_t state) { - if (fchan->state_status == FTDM_STATE_STATUS_NEW) { - /* the current state is new, setting a new state from a signaling module - when the current state is new is equivalent to implicitly acknowledging + if (fchan->state_status != FTDM_STATE_STATUS_COMPLETED) { + /* the current state is not completed, setting a new state from a signaling module + when the current state is not completed is equivalent to implicitly acknowledging the current state */ _ftdm_channel_complete_state(file, func, line, fchan); } @@ -161,9 +178,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *f return FTDM_FAIL; } - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR, "Ignored state change request from %s to %s, the previous state change has not been processed yet\n", - ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); + if (ftdmchan->state_status != FTDM_STATE_STATUS_COMPLETED) { + ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR, + "Ignored state change request from %s to %s, the previous state change has not been processed yet (status = %s)\n", + ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state), + ftdm_state_status2str(ftdmchan->state_status)); return FTDM_FAIL; } @@ -422,9 +441,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan, ftd ftdm_channel_lock(fchan); while (fchan->state_status == FTDM_STATE_STATUS_NEW) { state = fchan->state; + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Executing state processor for %s\n", ftdm_channel_state2str(fchan->state)); state_processor(fchan); - if (state == fchan->state) { - /* if the state did not change, the state status must go to PROCESSED + if (state == fchan->state && fchan->state_status == FTDM_STATE_STATUS_NEW) { + /* if the state did not change and is still NEW, the state status must go to PROCESSED * otherwise we don't touch it since is a new state and the old state was * already completed implicitly by the state_processor() function via some internal * call to ftdm_set_state() */ diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 3809b224c4..530bb2b9b2 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -73,7 +73,6 @@ typedef struct ftdm_r2_call_t { int disconnect_rcvd:1; int ftdm_call_started:1; int protocol_error:1; - ftdm_channel_state_t chanstate; ftdm_size_t dnis_index; ftdm_size_t ani_index; char logname[255]; @@ -168,8 +167,7 @@ static ftdm_hash_t *g_mod_data_hash; /* IO interface for the command API */ static ftdm_io_interface_t g_ftdm_r2_interface; -static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan); -static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan); +static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan); /* whether R2 call accept process is pending */ #define IS_ACCEPTING_PENDING(ftdmchan) \ @@ -349,7 +347,6 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call) call->disconnect_rcvd = 0; call->ftdm_call_started = 0; call->protocol_error = 0; - call->chanstate = FTDM_CHANNEL_STATE_DOWN; call->dnis_index = 0; call->ani_index = 0; call->name[0] = 0; @@ -479,7 +476,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) } R2CALL(ftdmchan)->ftdm_call_started = 1; - R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING); ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); @@ -624,7 +620,7 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) ftdm_sched_cancel_timer(r2data->sched, r2call->protocol_error_recovery_timer); ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancelled protocol error recovery timer\n"); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - ftdm_r2_state_advance_all(ftdmchan); + ftdm_channel_advance_states(ftdmchan, ftdm_r2_state_advance); } } @@ -658,7 +654,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size); } - R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); ftdm_channel_command(ftdmchan, FTDM_COMMAND_FLUSH_TX_BUFFERS, NULL); @@ -708,12 +703,10 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons static void clear_accept_pending(ftdm_channel_t *fchan) { if (IS_ACCEPTING_PENDING(fchan)) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE); ftdm_channel_complete_state(fchan); } else if (ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE)) { ftdm_log_chan(fchan, FTDM_LOG_CRIT, "State change flag set in state %s, last state = %s\n", ftdm_channel_state2str(fchan->state), ftdm_channel_state2str(fchan->last_state)); - ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE); ftdm_channel_complete_state(fchan); } } @@ -821,7 +814,7 @@ static void ftdm_r2_on_call_end(openr2_chan_t *r2chan) ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); /* in some circumstances openr2 can call on_call_init right after this, so let's advance the state right here */ - ftdm_r2_state_advance_all(ftdmchan); + ftdm_channel_advance_states(ftdmchan, ftdm_r2_state_advance); } static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen) @@ -853,7 +846,7 @@ static void ftdm_r2_recover_from_protocol_error(void *data) goto done; } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - ftdm_r2_state_advance_all(ftdmchan); + ftdm_channel_advance_states(ftdmchan, ftdm_r2_state_advance); done: ftdm_channel_unlock(ftdmchan); } @@ -1620,10 +1613,10 @@ fail: } /* the channel must be locked when calling this function */ -static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) +static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) { ftdm_sigmsg_t sigev; - int ret; + ftdm_status_t ret; ftdm_r2_call_t *r2call = R2CALL(ftdmchan); openr2_chan_t *r2chan = r2call->r2chan; ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; @@ -1633,172 +1626,161 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; - ret = 0; + ret = FTDM_SUCCESS; - /* because we do not always acknowledge the state change (clearing the FTDM_CHANNEL_STATE_CHANGE flag) due to the accept - * procedure described below, we need the chanstate member to NOT process some states twice, so is valid entering this - * function with the FTDM_CHANNEL_STATE_CHANGE flag set but with a state that was already processed and is just waiting - * to complete (the processing is media-bound) - * */ - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE) - && (r2call->chanstate != ftdmchan->state)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state)); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state)); - r2call->chanstate = ftdmchan->state; - - if (IS_ACCEPTING_PENDING(ftdmchan)) { - /* - Moving to PROGRESS, PROGRESS_MEDIA or UP means that we must accept the call first, and accepting - the call in R2 means sending a tone, then waiting for the acknowledge from the other end, - since all of that requires sending and detecting tones, it takes a few milliseconds (I'd say around 100) - which means during that time the user should not try to perform any operations like answer, hangup or anything - else, therefore we DO NOT clear the FTDM_CHANNEL_STATE_CHANGE flag here, we rely on ftdm_io.c to block - the user thread until we're done with the accept (see on_call_accepted callback) and then we clear the state change flag, - otherwise we have a race condition between freetdm calling openr2_chan_answer_call and openr2 accepting the call first, - if freetdm calls openr2_chan_answer_call before the accept cycle completes, openr2 will fail to answer the call */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "State ack for state %s will have to wait a bit\n", ftdm_channel_state2str(ftdmchan->state)); - } else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){ - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE); - ftdm_channel_complete_state(ftdmchan); - } - - switch (ftdmchan->state) { - - /* starting an incoming call */ - case FTDM_CHANNEL_STATE_COLLECT: - { - uint32_t interval = 0; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); - ftdm_assert(interval != 0, "Invalid interval!"); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting processing of incoming call with interval %d\n", interval); - openr2_chan_enable_read(r2chan); - } - break; - - /* starting an outgoing call */ - case FTDM_CHANNEL_STATE_DIALING: - { - uint32_t interval = 0; - ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); - ftdm_assert(interval != 0, "Invalid interval!"); - ftdm_log_chan(ftdmchan, - FTDM_LOG_DEBUG, "Starting processing of outgoing call in channel with interval %d\n", interval); - openr2_chan_enable_read(r2chan); - } - break; - - /* incoming call was offered */ - case FTDM_CHANNEL_STATE_RING: - - /* notify the user about the new call */ - sigev.event_id = FTDM_SIGEVENT_START; - - ftdm_span_send_signal(ftdmchan->span, &sigev); - r2call->ftdm_call_started = 1; - - break; - - /* the call is making progress */ - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - { - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (!r2call->accepted) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n"); - ft_r2_accept_call(ftdmchan); - } - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n"); - sigev.event_id = FTDM_SIGEVENT_PROCEED; - ftdm_span_send_signal(ftdmchan->span, &sigev); - - sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; - ftdm_span_send_signal(ftdmchan->span, &sigev); - } - } - break; - - /* the call was answered */ - case FTDM_CHANNEL_STATE_UP: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n"); - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - if (!r2call->accepted) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n"); - // the answering will be done in the on_call_accepted handler - ft_r2_accept_call(ftdmchan); - r2call->answer_pending = 1; - } else { - ft_r2_answer_call(ftdmchan); - } - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying of call answered\n"); - sigev.event_id = FTDM_SIGEVENT_UP; - ftdm_span_send_signal(ftdmchan->span, &sigev); - } - } - break; - - /* just got hangup */ - case FTDM_CHANNEL_STATE_HANGUP: - { - if (!r2call->disconnect_rcvd) { - openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); - /* this will disconnect the call, but need to wait for the call end before moving to DOWN */ - openr2_chan_disconnect_call(r2chan, disconnect_cause); - } else if (!r2call->protocol_error) { - /* just ack the hangup, on_call_end will be called by openr2 right after */ - openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n"); - /* do not set to down yet, give some time for recovery */ - ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100, - ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer); - } - } - break; - - case FTDM_CHANNEL_STATE_TERMINATING: - { - /* if the call has not been started yet we must go to HANGUP right here */ - if (!r2call->ftdm_call_started) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); - } else { - openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); - /* notify the user of the call terminating and we wait for the user to move us to hangup */ - sigev.event_id = FTDM_SIGEVENT_STOP; - ftdm_span_send_signal(ftdmchan->span, &sigev); - } - } - break; - - /* finished call for good */ - case FTDM_CHANNEL_STATE_DOWN: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n"); - ret = 1; - } - break; - - /* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */ - case FTDM_CHANNEL_STATE_RINGING: - { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n"); - } - break; - - default: - { - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state)); - } - break; - - } + if (IS_ACCEPTING_PENDING(ftdmchan)) { + /* + Moving to PROGRESS, PROGRESS_MEDIA or UP means that we must accept the call first, and accepting + the call in R2 means sending a tone, then waiting for the acknowledge from the other end, + since all of that requires sending and detecting tones, it takes a few milliseconds (I'd say around 100) + which means during that time the user should not try to perform any operations like answer, hangup or anything + else, therefore we DO NOT clear the FTDM_CHANNEL_STATE_CHANGE flag here, we rely on ftdm_io.c to block + the user thread until we're done with the accept (see on_call_accepted callback) and then we clear the state change flag, + otherwise we have a race condition between freetdm calling openr2_chan_answer_call and openr2 accepting the call first, + if freetdm calls openr2_chan_answer_call before the accept cycle completes, openr2 will fail to answer the call */ + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "State ack for state %s will have to wait a bit\n", ftdm_channel_state2str(ftdmchan->state)); + } else if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN){ + ftdm_channel_complete_state(ftdmchan); } - if (ret) { + switch (ftdmchan->state) { + + /* starting an incoming call */ + case FTDM_CHANNEL_STATE_COLLECT: + { + uint32_t interval = 0; + ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); + ftdm_assert(interval != 0, "Invalid interval!"); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting processing of incoming call with interval %d\n", interval); + openr2_chan_enable_read(r2chan); + } + break; + + /* starting an outgoing call */ + case FTDM_CHANNEL_STATE_DIALING: + { + uint32_t interval = 0; + ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); + ftdm_assert(interval != 0, "Invalid interval!"); + ftdm_log_chan(ftdmchan, + FTDM_LOG_DEBUG, "Starting processing of outgoing call in channel with interval %d\n", interval); + openr2_chan_enable_read(r2chan); + } + break; + + /* incoming call was offered */ + case FTDM_CHANNEL_STATE_RING: + + /* notify the user about the new call */ + sigev.event_id = FTDM_SIGEVENT_START; + + ftdm_span_send_signal(ftdmchan->span, &sigev); + r2call->ftdm_call_started = 1; + + break; + + /* the call is making progress */ + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + { + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + if (!r2call->accepted) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Accepting call\n"); + ft_r2_accept_call(ftdmchan); + } + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n"); + sigev.event_id = FTDM_SIGEVENT_PROCEED; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; + ftdm_span_send_signal(ftdmchan->span, &sigev); + } + } + break; + + /* the call was answered */ + case FTDM_CHANNEL_STATE_UP: + { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call was answered\n"); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + if (!r2call->accepted) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call has not been accepted, need to accept first\n"); + // the answering will be done in the on_call_accepted handler + ft_r2_accept_call(ftdmchan); + r2call->answer_pending = 1; + } else { + ft_r2_answer_call(ftdmchan); + } + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying of call answered\n"); + sigev.event_id = FTDM_SIGEVENT_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + } + } + break; + + /* just got hangup */ + case FTDM_CHANNEL_STATE_HANGUP: + { + if (!r2call->disconnect_rcvd) { + openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); + /* this will disconnect the call, but need to wait for the call end before moving to DOWN */ + openr2_chan_disconnect_call(r2chan, disconnect_cause); + } else if (!r2call->protocol_error) { + /* just ack the hangup, on_call_end will be called by openr2 right after */ + openr2_chan_disconnect_call(r2chan, OR2_CAUSE_NORMAL_CLEARING); + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Clearing call due to protocol error\n"); + /* do not set to down yet, give some time for recovery */ + ftdm_sched_timer(r2data->sched, "protocolerr_recover", 100, + ftdm_r2_recover_from_protocol_error, r2chan, &r2call->protocol_error_recovery_timer); + } + } + break; + + case FTDM_CHANNEL_STATE_TERMINATING: + { + /* if the call has not been started yet we must go to HANGUP right here */ + if (!r2call->ftdm_call_started) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); + } else { + openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); + /* notify the user of the call terminating and we wait for the user to move us to hangup */ + sigev.event_id = FTDM_SIGEVENT_STOP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + } + } + break; + + /* finished call for good */ + case FTDM_CHANNEL_STATE_DOWN: + { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "R2 Call is down\n"); + ret = FTDM_BREAK; + } + break; + + /* INDICATE_RINGING doesn't apply to MFC/R2. maybe we could generate a tone */ + case FTDM_CHANNEL_STATE_RINGING: + { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "RINGING indicated, ignoring it as it doesn't apply to MFC/R2\n"); + } + break; + + default: + { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Unhandled channel state change: %s\n", ftdm_channel_state2str(ftdmchan->state)); + } + break; + + } + + if (ret == FTDM_BREAK) { ftdm_channel_t *closed_chan; closed_chan = ftdmchan; ftdm_channel_close(&closed_chan); @@ -1807,20 +1789,6 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) return ret; } -/* the channel must be locked when calling this function */ -static void ftdm_r2_state_advance_all(ftdm_channel_t *ftdmchan) -{ - /* because we do not always acknowledge the state change (clearing the FTDM_CHANNEL_STATE_CHANGE flag) due to the accept - * procedure described below, we need the chanstate member to NOT process some states twice, so is valid entering this - * function with the FTDM_CHANNEL_STATE_CHANGE flag set but with a state that was already processed and is just waiting - * to complete (the processing is media-bound) - * */ - while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE) - && (R2CALL(ftdmchan)->chanstate != ftdmchan->state)) { - ftdm_r2_state_advance(ftdmchan); - } -} - static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) { openr2_chan_t *r2chan = NULL; @@ -1949,12 +1917,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_RX_DISABLED); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED); - ftdm_r2_state_advance_all(ftdmchan); + ftdm_channel_advance_states(ftdmchan, ftdm_r2_state_advance); r2chan = call->r2chan; openr2_chan_process_signaling(r2chan); - ftdm_r2_state_advance_all(ftdmchan); + ftdm_channel_advance_states(ftdmchan, ftdm_r2_state_advance); if (!call->accepted) { /* if the call is not accepted we do not want users reading */ diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 30fe6ca4f5..ff129636d9 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -777,11 +777,17 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan); /*! \brief Indicate a new condition in an incoming call + * * \note Every indication request will result in FTDM_SIGEVENT_INDICATION_COMPLETED event being delivered with - * the proper status that will inform you if the request was successful or not. - * Be aware there is no guarantee of whether the event will arrive after or before your execution thread returns - * from ftdm_channel_call_indicate. This means you could get FTDM_SIGEVENT_INDICATION_COMPLETED even before - * your execution thread returns from the ftdm_channel_call_indicate() API + * the proper status that will inform you if the request was successful or not. The exception is if this + * function returns something different to FTDM_SUCCESS, in which case the request failed right away and no + * further FTDM_SIGEVENT_INDICATION_COMPLETED will be delivered + * Be aware there is no guarantee of whether the completion event will arrive after or before your execution + * thread returns from ftdm_channel_call_indicate. This means you could get FTDM_SIGEVENT_INDICATION_COMPLETED + * even before your execution thread returns from the ftdm_channel_call_indicate() API + * + * \note You cannot send more than one indication at the time. You must wait for the completed event before + * calling this function again (unless the return code was different than FTDM_SUCCESS) */ #define ftdm_channel_call_indicate(ftdmchan, indication) _ftdm_channel_call_indicate(__FILE__, __FUNCTION__, __LINE__, (ftdmchan), (indication)) diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h index 2e41281baf..88a76930f7 100644 --- a/libs/freetdm/src/include/ftdm_declare.h +++ b/libs/freetdm/src/include/ftdm_declare.h @@ -192,6 +192,7 @@ typedef enum { FTDM_EINVAL, /*!< Invalid argument */ FTDM_ECANCELED, /*!< Operation cancelled */ + FTDM_EBUSY, /*!< Device busy */ } ftdm_status_t; /*! \brief FreeTDM bool type. */ diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 8f97456fb7..605ab8df15 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -583,7 +583,7 @@ FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap); FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void); FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan); -FT_DECLARE(void) ftdm_ack_indication(const ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_status_t status); +FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_status_t status); /*! * \brief Retrieves an event from the span diff --git a/libs/freetdm/src/include/private/ftdm_state.h b/libs/freetdm/src/include/private/ftdm_state.h index 79a3df07e9..36dcc2bef8 100644 --- a/libs/freetdm/src/include/private/ftdm_state.h +++ b/libs/freetdm/src/include/private/ftdm_state.h @@ -138,8 +138,11 @@ FT_DECLARE(int) ftdm_check_state_all(ftdm_span_t *span, ftdm_channel_state_t sta typedef enum { FTDM_STATE_STATUS_NEW, FTDM_STATE_STATUS_PROCESSED, - FTDM_STATE_STATUS_COMPLETED + FTDM_STATE_STATUS_COMPLETED, + FTDM_STATE_STATUS_INVALID } ftdm_state_status_t; +#define CHANNEL_STATE_STATUS_STRINGS "NEW", "PROCESSED", "COMPLETED", "INVALID" +FTDM_STR2ENUM_P(ftdm_str2ftdm_state_status, ftdm_state_status2str, ftdm_state_status_t) typedef enum { ZSM_NONE, From c854fe518adb53683cb0336a9f1f722b9208e42c Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 29 Dec 2010 14:04:31 -0500 Subject: [PATCH 194/244] freetdm: update 2008 freetdm vcproj to include ftdm_state header and C file --- libs/freetdm/msvc/freetdm.2008.vcproj | 152 ++++++++++++++------------ 1 file changed, 80 insertions(+), 72 deletions(-) diff --git a/libs/freetdm/msvc/freetdm.2008.vcproj b/libs/freetdm/msvc/freetdm.2008.vcproj index c72891e525..0539ff3f42 100644 --- a/libs/freetdm/msvc/freetdm.2008.vcproj +++ b/libs/freetdm/msvc/freetdm.2008.vcproj @@ -94,78 +94,6 @@ Name="VCPostBuildEventTool" /> - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -452,6 +456,10 @@ RelativePath="..\src\ftdm_sched.c" > + + From 6fb1e5d9c1221d4943b52a284668c7435596268f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 29 Dec 2010 14:08:18 -0500 Subject: [PATCH 195/244] freetdm: free the iterator when setting channels to non-block --- libs/freetdm/src/ftdm_io.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 0c25054816..5c900b91dd 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1902,6 +1902,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_blocking_mode(const ftdm_span_t *span, f ftdm_set_flag_locked(fchan, FTDM_CHANNEL_NONBLOCK); } } + ftdm_iterator_free(citer); return FTDM_SUCCESS; } From 650393fb90f79cfbbe9bc4b89f0d0dbdd9e9c3da Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 29 Dec 2010 13:15:14 -0600 Subject: [PATCH 196/244] add recovery_refresh app and api and use it in mod_conference to send a message to the channel telling it to sync its recovery snapshot --- src/include/switch_types.h | 1 + .../applications/mod_commands/mod_commands.c | 36 +++++++++++++++++++ .../mod_conference/mod_conference.c | 6 ++++ .../applications/mod_dptools/mod_dptools.c | 12 +++++++ src/mod/endpoints/mod_sofia/mod_sofia.c | 2 ++ 5 files changed, 57 insertions(+) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 830ea409e8..bb5f59865f 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -791,6 +791,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_UDPTL_MODE, SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, SWITCH_MESSAGE_INDICATE_JITTER_BUFFER, + SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH, SWITCH_MESSAGE_INVALID } switch_core_session_message_types_t; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 1c2e3ebfb9..8daaace7f3 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2226,6 +2226,40 @@ SWITCH_STANDARD_API(uuid_deflect) return SWITCH_STATUS_SUCCESS; } +#define UUID_RECOVERY_REFRESH_SYNTAX " " +SWITCH_STANDARD_API(uuid_recovery_refresh) +{ + switch_core_session_t *tsession = NULL; + char *uuid = NULL, *text = NULL; + + if (!zstr(cmd) && (uuid = strdup(cmd))) { + if ((text = strchr(uuid, ' '))) { + *text++ = '\0'; + } + } + + if (zstr(uuid) || zstr(text)) { + stream->write_function(stream, "-USAGE: %s\n", UUID_RECOVERY_REFRESH_SYNTAX); + } else { + if ((tsession = switch_core_session_locate(uuid))) { + switch_core_session_message_t msg = { 0 }; + + /* Tell the channel to recovery_refresh the call */ + msg.from = __FILE__; + msg.string_arg = text; + msg.message_id = SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH; + switch_core_session_receive_message(tsession, &msg); + stream->write_function(stream, "+OK:%s\n", msg.string_reply); + switch_core_session_rwunlock(tsession); + } else { + stream->write_function(stream, "-ERR No Such Channel %s!\n", uuid); + } + } + + switch_safe_free(uuid); + return SWITCH_STATUS_SUCCESS; +} + #define SCHED_TRANSFER_SYNTAX "[+] diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 3317436133..f145210e4f 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -52,8 +52,8 @@ typedef struct cdr_fd cdr_fd_t; const char *default_template = "\"${local_ip_v4}\",\"${caller_id_name}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${start_stamp}\"," - "\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${uuid}\",\"${bleg_uuid}\", \"${accountcode}\"," - "\"${read_codec}\", \"${write_codec}\"\n"; + "\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${uuid}\",\"${bleg_uuid}\",\"${accountcode}\"," + "\"${read_codec}\",\"${write_codec}\"\n"; static struct { switch_memory_pool_t *pool; @@ -65,9 +65,8 @@ static struct { int rotate; int debug; cdr_leg_t legs; - char *a_table; - char *g_table; char *db_info; + char *db_table; PGconn *db_connection; int db_online; switch_mutex_t *db_mutex; @@ -185,7 +184,7 @@ static void write_cdr(const char *path, const char *log_line) switch_mutex_unlock(fd->mutex); } -static int save_cdr(const char * const table, const char * const template, const char * const cdr) +static switch_status_t save_cdr(const char * const table, const char * const template, const char * const cdr) { char *columns, *values; char *p, *q; @@ -197,7 +196,7 @@ static int save_cdr(const char * const table, const char * const template, const if (!table || !*table || !template || !*template || !cdr || !*cdr) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Bad parameter\n"); - return 0; + return SWITCH_STATUS_FALSE; } /* Build comma-separated list of field names by dropping $ { } ; chars */ @@ -212,7 +211,8 @@ static int save_cdr(const char * const table, const char * const template, const } *q = '\0'; - /* In the expanded vars, replace double quotes (") with single quotes (') + /* + * In the expanded vars, replace double quotes (") with single quotes (') * for corect PostgreSQL syntax, and replace semi-colon with space to * prevent SQL injection attacks. */ @@ -248,7 +248,6 @@ static int save_cdr(const char * const table, const char * const template, const nullCounter++; } - charCounter = 0; nullCounter *= 4; vlen += nullCounter; nullValues = (char *) malloc(strlen(values) + nullCounter + 1); @@ -335,7 +334,7 @@ static int save_cdr(const char * const table, const char * const template, const globals.db_online = 0; switch_mutex_unlock(globals.db_mutex); free(query); - return 0; + return SWITCH_STATUS_FALSE; } res = PQexec(globals.db_connection, query); @@ -346,21 +345,21 @@ static int save_cdr(const char * const table, const char * const template, const globals.db_online = 0; switch_mutex_unlock(globals.db_mutex); free(query); - return 0; + return SWITCH_STATUS_FALSE; } PQclear(res); free(query); switch_mutex_unlock(globals.db_mutex); - return 1; + return SWITCH_STATUS_SUCCESS; } static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_SUCCESS; - const char *log_dir = NULL, *accountcode = NULL, *a_template_str = NULL, *g_template_str = NULL; + const char *log_dir = NULL, *template_str = NULL; char *log_line, *path = NULL; int saved = 0; @@ -402,44 +401,20 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) } } - g_template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template); + template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template); - if ((accountcode = switch_channel_get_variable(channel, "ACCOUNTCODE"))) { - a_template_str = (const char *) switch_core_hash_find(globals.template_hash, accountcode); + if (!template_str) { + template_str = default_template; } - if (!g_template_str) { - g_template_str = "\"${accountcode}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${caller_id}\",\"${channel_name}\",\"${bridge_channel}\",\"${last_app}\",\"${last_arg}\",\"${start_stamp}\",\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${amaflags}\",\"${uuid}\",\"${userfield}\";"; - } - - if (!a_template_str) { - a_template_str = g_template_str; - } - - log_line = switch_channel_expand_variables(channel, a_template_str); - - saved = 1; // save_cdr(globals.a_table, a_template_str, log_line); - - if (!saved && accountcode) { - path = switch_mprintf("%s%s%s.csv", log_dir, SWITCH_PATH_SEPARATOR, accountcode); - assert(path); - write_cdr(path, log_line); - free(path); - } - - if (g_template_str != a_template_str) { - if (log_line != a_template_str) { - switch_safe_free(log_line); - } - log_line = switch_channel_expand_variables(channel, g_template_str); - } + log_line = switch_channel_expand_variables(channel, template_str); if (!log_line) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating cdr\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error expanding CDR variables.\n"); return SWITCH_STATUS_FALSE; } - saved = save_cdr(globals.g_table, g_template_str, log_line); + saved = save_cdr(globals.db_table, template_str, log_line); if (!saved) { path = switch_mprintf("%s%sMaster.csv", log_dir, SWITCH_PATH_SEPARATOR); @@ -448,7 +423,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) free(path); } - if (log_line != g_template_str) { + if (log_line != template_str) { free(log_line); } @@ -545,14 +520,12 @@ static switch_status_t load_config(switch_memory_pool_t *pool) globals.log_dir = switch_core_sprintf(pool, "%s%scdr-pg-csv", val, SWITCH_PATH_SEPARATOR); } else if (!strcasecmp(var, "rotate-on-hup")) { globals.rotate = switch_true(val); - } else if (!strcasecmp(var, "default-template")) { - globals.default_template = switch_core_strdup(pool, val); - } else if (!strcasecmp(var, "a-table")) { - globals.a_table = switch_core_strdup(pool, val); - } else if (!strcasecmp(var, "g-table")) { - globals.g_table = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "db-info")) { globals.db_info = switch_core_strdup(pool, val); + } else if (!strcasecmp(var, "db-table") || !strcasecmp(var, "g-table")) { + globals.db_table = switch_core_strdup(pool, val); + } else if (!strcasecmp(var, "default-template")) { + globals.default_template = switch_core_strdup(pool, val); } } } @@ -578,26 +551,22 @@ static switch_status_t load_config(switch_memory_pool_t *pool) switch_xml_free(xml); } + if (!globals.log_dir) { + globals.log_dir = switch_core_sprintf(pool, "%s%scdr-pg-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); + } + + if (zstr(globals.db_info)) { + globals.db_info = switch_core_strdup(pool, "dbname=cdr"); + } + + if (zstr(globals.db_table)) { + globals.db_table = switch_core_strdup(pool, "cdr"); + } if (zstr(globals.default_template)) { globals.default_template = switch_core_strdup(pool, "default"); } - if (!globals.log_dir) { - globals.log_dir = switch_core_sprintf(pool, "%s%scdr-pg-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR); - } - - if (zstr(globals.a_table)) { - globals.a_table = switch_core_strdup(pool, "a"); - } - - if (zstr(globals.g_table)) { - globals.g_table = switch_core_strdup(pool, "g"); - } - - if (zstr(globals.db_info)) { - globals.db_info = switch_core_strdup(pool, "dbname = cdr"); - } return status; } From 2be3175ae91924a3e7460f67f0aecd927d6f2661 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Fri, 31 Dec 2010 20:54:20 +0100 Subject: [PATCH 221/244] mod_cdr_pg_csv now spools the attempted SQL to disk if DB insert fails, instead of writing CSV. This should make it simpler to import any failed inserts. --- .../mod_cdr_pg_csv/mod_cdr_pg_csv.c | 79 +++++++++---------- .../mod_cdr_sqlite/mod_cdr_sqlite.c | 2 +- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index f145210e4f..275fec1396 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -53,7 +53,7 @@ typedef struct cdr_fd cdr_fd_t; const char *default_template = "\"${local_ip_v4}\",\"${caller_id_name}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${start_stamp}\"," "\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${uuid}\",\"${bleg_uuid}\",\"${accountcode}\"," - "\"${read_codec}\",\"${write_codec}\"\n"; + "\"${read_codec}\",\"${write_codec}\""; static struct { switch_memory_pool_t *pool; @@ -184,17 +184,17 @@ static void write_cdr(const char *path, const char *log_line) switch_mutex_unlock(fd->mutex); } -static switch_status_t save_cdr(const char * const table, const char * const template, const char * const cdr) +static switch_status_t save_cdr(const char * const template, const char * const cdr, const char * const log_dir) { char *columns, *values; char *p, *q; unsigned vlen; - char *query; - PGresult *res; char *nullValues, *temp, *tp; int nullCounter = 0, charCounter = 0; + char *sql = NULL, *path = NULL; + PGresult *res; - if (!table || !*table || !template || !*template || !cdr || !*cdr) { + if (!template || !*template || !cdr || !*cdr) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Bad parameter\n"); return SWITCH_STATUS_FALSE; } @@ -311,13 +311,13 @@ static switch_status_t save_cdr(const char * const table, const char * const tem //----------------------------- END_OF_PATCH ------------------------------- - query = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", table, columns, values); - assert(query); + sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);\n", globals.db_table, columns, values); + assert(sql); free(columns); free(values); if (globals.debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Query: \"%s\"\n", query); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Query: \"%s\"\n", sql); } switch_mutex_lock(globals.db_mutex); @@ -330,29 +330,40 @@ static switch_status_t save_cdr(const char * const table, const char * const tem globals.db_online = 1; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection to database failed: %s", PQerrorMessage(globals.db_connection)); - PQfinish(globals.db_connection); - globals.db_online = 0; - switch_mutex_unlock(globals.db_mutex); - free(query); - return SWITCH_STATUS_FALSE; + goto error; } - res = PQexec(globals.db_connection, query); + res = PQexec(globals.db_connection, sql); if (PQresultStatus(res) != PGRES_COMMAND_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "INSERT command failed: %s", PQresultErrorMessage(res)); PQclear(res); - PQfinish(globals.db_connection); - globals.db_online = 0; - switch_mutex_unlock(globals.db_mutex); - free(query); - return SWITCH_STATUS_FALSE; + goto error; } + PQclear(res); - free(query); + free(sql); switch_mutex_unlock(globals.db_mutex); return SWITCH_STATUS_SUCCESS; + + + error: + + PQfinish(globals.db_connection); + globals.db_online = 0; + switch_mutex_unlock(globals.db_mutex); + + /* SQL INSERT failed for whatever reason. Spool the attempted query to disk */ + path = switch_mprintf("%s%scdr-spool.sql", log_dir, SWITCH_PATH_SEPARATOR); + assert(path); + write_cdr(path, sql); + + free(path); + free(sql); + + return SWITCH_STATUS_FALSE; + } static switch_status_t my_on_reporting(switch_core_session_t *session) @@ -360,8 +371,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_SUCCESS; const char *log_dir = NULL, *template_str = NULL; - char *log_line, *path = NULL; - int saved = 0; + char *expanded_vars = NULL; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; @@ -407,24 +417,17 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) template_str = default_template; } - log_line = switch_channel_expand_variables(channel, template_str); + expanded_vars = switch_channel_expand_variables(channel, template_str); - if (!log_line) { + if (!expanded_vars) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error expanding CDR variables.\n"); return SWITCH_STATUS_FALSE; } - saved = save_cdr(globals.db_table, template_str, log_line); + save_cdr(template_str, expanded_vars, log_dir); - if (!saved) { - path = switch_mprintf("%s%sMaster.csv", log_dir, SWITCH_PATH_SEPARATOR); - assert(path); - write_cdr(path, log_line); - free(path); - } - - if (log_line != template_str) { - free(log_line); + if (expanded_vars != template_str) { + free(expanded_vars); } return status; @@ -535,13 +538,7 @@ static switch_status_t load_config(switch_memory_pool_t *pool) char *var = (char *) switch_xml_attr(param, "name"); if (var) { char *tpl; - size_t len = strlen(param->txt) + 2; - if (end_of(param->txt) != '\n') { - tpl = switch_core_alloc(pool, len); - switch_snprintf(tpl, len, "%s\n", param->txt); - } else { - tpl = switch_core_strdup(pool, param->txt); - } + tpl = switch_core_strdup(pool, param->txt); switch_core_hash_insert(globals.template_hash, var, tpl); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var); diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index ca928182ba..534f18f2ca 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -113,7 +113,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_SUCCESS; const char *template_str = NULL; - char *expanded_vars, *sql = NULL; + char *expanded_vars = NULL, *sql = NULL; if (globals.shutdown) { return SWITCH_STATUS_SUCCESS; From 6f5a0e9ff5984aed4b99b7a04a6cb1339b86e3b1 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 31 Dec 2010 15:06:49 -0500 Subject: [PATCH 222/244] freetdm: typo --- libs/freetdm/src/ftdm_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index a1c5ceea88..e55839a784 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4234,7 +4234,7 @@ static void print_core_usage(ftdm_stream_handle_t *stream) stream->write_function(stream, "--------------------------------------------------------------------------------\n" "ftdm core state [!] - List all channels in or not in the given state\n" - "ftdm core flag - List all channels with the fiven flag value set\n" + "ftdm core flag - List all channels with the given flag value set\n" "ftdm core calls - List all known calls to the FreeTDM core\n" "--------------------------------------------------------------------------------\n"); } From ec57dc7ab76e5765bbd50905e47a1cac2aad38ba Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sun, 2 Jan 2011 19:30:00 +0800 Subject: [PATCH 223/244] Added missing error codes when an ECM FAX is abandoned with the T30_ERR message --- libs/spandsp/src/t30.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 45387b8585..aba4eef0eb 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -4275,6 +4275,7 @@ static void process_state_iv_eor(t30_state_t *s, const uint8_t *msg, int len) break; case T30_ERR: /* TODO: Continue with the next message if MPS or EOM? */ + s->current_status = T30_ERR_RETRYDCN; s->timer_t5 = 0; send_dcn(s); break; @@ -4319,6 +4320,7 @@ static void process_state_iv_eor_rnr(t30_state_t *s, const uint8_t *msg, int len break; case T30_ERR: /* TODO: Continue with the next message if MPS or EOM? */ + s->current_status = T30_ERR_RETRYDCN; s->timer_t5 = 0; send_dcn(s); break; From ced63c35167d5f6c52583b5e70da1b2cf669c8ef Mon Sep 17 00:00:00 2001 From: cypromis Date: Mon, 3 Jan 2011 11:40:49 +0100 Subject: [PATCH 224/244] added postgresql cdr module to modules.conf.in (commented out ) added sqlite cdr module to modules.conf.in (built by default) --- build/modules.conf.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/modules.conf.in b/build/modules.conf.in index bd5d49a7ad..69d90a8dd4 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -73,6 +73,8 @@ endpoints/mod_loopback #event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_cdr_csv +event_handlers/mod_cdr_sqlite +#event_handlers/mod_cdr_pg_csv #event_handlers/mod_radius_cdr #event_handlers/mod_erlang_event formats/mod_native_file From 45a32dda3d09878fe07659002fd192ed8dca3575 Mon Sep 17 00:00:00 2001 From: cypromis Date: Mon, 3 Jan 2011 11:58:15 +0100 Subject: [PATCH 225/244] added -lgpg-error to sun compiler CXXFLAGS for iksemel library and tools to be build corretly in libiksemel configure.ac --- libs/iksemel/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac index f7687922c2..1b8af13683 100644 --- a/libs/iksemel/configure.ac +++ b/libs/iksemel/configure.ac @@ -84,7 +84,7 @@ AC_ARG_ENABLE(64, if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then if test "${enable_64}" = "yes"; then CFLAGS="$CFLAGS -m64" - CXXFLAGS="$CXXFLAGS -m64" + CXXFLAGS="$CXXFLAGS -m64 -lgpg-error" fi fi From 09e6fd3f4ee5069491034fb150405fe7ad61fe3f Mon Sep 17 00:00:00 2001 From: Leon de Rooij Date: Mon, 3 Jan 2011 12:20:06 +0100 Subject: [PATCH 226/244] Make dbh:connected accessible from Lua - thanks Grmt --- src/mod/languages/mod_lua/freeswitch.i | 3 ++- src/mod/languages/mod_lua/freeswitch_lua.cpp | 15 +++++++---- src/mod/languages/mod_lua/freeswitch_lua.h | 3 ++- src/mod/languages/mod_lua/mod_lua_wrap.cpp | 26 ++++++++++++++++++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index 54bdb7bdc9..cea764d9d6 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -82,12 +82,13 @@ class Session : public CoreSession { class Dbh { private: switch_cache_db_handle_t *dbh; - bool connected; + bool m_connected; static int query_callback(void *pArg, int argc, char **argv, char **cargv); public: Dbh(char *dsn, char *user = NULL, char *pass = NULL); ~Dbh(); bool release(); + bool connected(); bool query(char *sql, SWIGLUA_FN lua_fun); }; diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index d60ae737a8..aad87fa6c1 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -318,9 +318,9 @@ Dbh::Dbh(char *dsn, char *user, char *pass) options.odbc_options.pass = pass; if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) == SWITCH_STATUS_SUCCESS) { - connected = true; + m_connected = true; } else { - connected = false; + m_connected = false; } } @@ -331,14 +331,19 @@ Dbh::~Dbh() bool Dbh::release() { - if (connected) { + if (m_connected) { switch_cache_db_release_db_handle(&dbh); - connected = false; + m_connected = false; return true; } return false; } +bool Dbh::connected() +{ + return m_connected; +} + int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv) { SWIGLUA_FN *lua_fun = (SWIGLUA_FN *)pArg; @@ -366,7 +371,7 @@ int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv) bool Dbh::query(char *sql, SWIGLUA_FN lua_fun) { - if (connected) { + if (m_connected) { if (lua_fun.L) { if (switch_cache_db_execute_sql_callback(dbh, sql, query_callback, &lua_fun, NULL) == SWITCH_STATUS_SUCCESS) { return true; diff --git a/src/mod/languages/mod_lua/freeswitch_lua.h b/src/mod/languages/mod_lua/freeswitch_lua.h index a0780b1537..3c43ebdd9f 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.h +++ b/src/mod/languages/mod_lua/freeswitch_lua.h @@ -55,12 +55,13 @@ namespace LUA { class Dbh { protected: switch_cache_db_handle_t *dbh; - bool connected; + bool m_connected; static int query_callback(void *pArg, int argc, char **argv, char **cargv); public: Dbh(char *dsn, char *user = NULL, char *pass = NULL); ~Dbh(); bool release(); + bool connected(); bool query(char *sql, SWIGLUA_FN lua_fun); }; } diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index d32646654c..4e2971098b 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -7229,6 +7229,31 @@ fail: } +static int _wrap_Dbh_connected(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + bool result; + + SWIG_check_num_args("connected",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("connected",1,"LUA::Dbh *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_connected",1,SWIGTYPE_p_LUA__Dbh); + } + + result = (bool)(arg1)->connected(); + SWIG_arg=0; + lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + static int _wrap_Dbh_query(lua_State* L) { int SWIG_arg = -1; LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; @@ -7277,6 +7302,7 @@ delete arg1; } static swig_lua_method swig_LUA_Dbh_methods[] = { {"release", _wrap_Dbh_release}, + {"connected", _wrap_Dbh_connected}, {"query", _wrap_Dbh_query}, {0,0} }; From 2632af929d8c63447a482e16ca92f6d2c5dc1ebf Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 12:52:11 +0100 Subject: [PATCH 227/244] FS-2953 --- src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 275fec1396..45951f68bf 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -213,7 +213,7 @@ static switch_status_t save_cdr(const char * const template, const char * const /* * In the expanded vars, replace double quotes (") with single quotes (') - * for corect PostgreSQL syntax, and replace semi-colon with space to + * for correct PostgreSQL syntax, and replace semi-colon with space to * prevent SQL injection attacks. */ values = strdup(cdr); @@ -231,7 +231,7 @@ static switch_status_t save_cdr(const char * const template, const char * const /* * Patch for changing empty strings ('') in the expanded variables to - * Postgresql null + * PostgreSQL null */ for (p = values; *p; ++p) { if (*p == ',') { From 8ecf30807556ee3f614f4f2e5181dc5bbfbfdf81 Mon Sep 17 00:00:00 2001 From: cypromis Date: Mon, 3 Jan 2011 13:06:25 +0100 Subject: [PATCH 228/244] fix basops32.c make the file contain something even if ifdefs fail (which makes suncc fail) --- libs/libg722_1/src/basop32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/libg722_1/src/basop32.c b/libs/libg722_1/src/basop32.c index 210e1296ec..3a51f45eee 100644 --- a/libs/libg722_1/src/basop32.c +++ b/libs/libg722_1/src/basop32.c @@ -17,9 +17,10 @@ #include #endif +#include + #if defined(G722_1_USE_FIXED_POINT) -#include #include #include From 935f2c42141eb78c3fd13ace50900bd99b905dd0 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 13:25:46 +0100 Subject: [PATCH 229/244] mod_cdr_sqlite has no need for (yet) for SIGHUP --- src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index 534f18f2ca..1eae1ab12f 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -173,10 +173,6 @@ static void event_handler(switch_event_t *event) if (globals.shutdown) { return; } - - if (sig && !strcmp(sig, "HUP")) { - /* Should we do something on SIG_HUP? */ - } } From 93bbbe96af98a6e4ab2ae5a48e68690b44bc103c Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 13:36:20 +0100 Subject: [PATCH 230/244] Remove event_handler() altogether, since it was doing nothing anyway --- .../mod_cdr_sqlite/mod_cdr_sqlite.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index 1eae1ab12f..efb544e049 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -166,16 +166,6 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) } -static void event_handler(switch_event_t *event) -{ - const char *sig = switch_event_get_header(event, "Trapped-Signal"); - - if (globals.shutdown) { - return; - } -} - - static switch_state_handler_table_t state_handlers = { /*.on_init */ NULL, /*.on_routing */ NULL, @@ -290,11 +280,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_sqlite_load) load_config(pool); - if ((status = switch_event_bind(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); - return status; - } - switch_core_add_state_handler(&state_handlers); *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -305,7 +290,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_sqlite_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cdr_sqlite_shutdown) { globals.shutdown = 1; - switch_event_unbind_callback(event_handler); switch_core_remove_state_handler(&state_handlers); return SWITCH_STATUS_SUCCESS; From aab453f52a37cfc43230e67c713ff7d605e7dd16 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 14:01:08 +0100 Subject: [PATCH 231/244] tweak create.sql and config file --- conf/autoload_configs/cdr_pg_csv.conf.xml | 7 +++-- .../event_handlers/mod_cdr_pg_csv/create.sql | 26 ++----------------- .../mod_cdr_pg_csv/mod_cdr_pg_csv.c | 1 - 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/conf/autoload_configs/cdr_pg_csv.conf.xml b/conf/autoload_configs/cdr_pg_csv.conf.xml index bddd387b70..e17809780c 100644 --- a/conf/autoload_configs/cdr_pg_csv.conf.xml +++ b/conf/autoload_configs/cdr_pg_csv.conf.xml @@ -1,8 +1,5 @@ - - - @@ -10,6 +7,9 @@ + + + @@ -17,4 +17,3 @@ - diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/create.sql b/src/mod/event_handlers/mod_cdr_pg_csv/create.sql index 83cfec1ec7..9a39b0b57f 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/create.sql +++ b/src/mod/event_handlers/mod_cdr_pg_csv/create.sql @@ -1,5 +1,6 @@ +-- Sample CDR table schema -create table a ( +create table cdr ( id serial primary key, local_ip_v4 inet not null, caller_id_name varchar, @@ -20,26 +21,3 @@ create table a ( sip_hangup_disposition varchar, ani varchar ); - -create table g ( - id serial primary key, - local_ip_v4 inet not null, - caller_id_name varchar, - caller_id_number varchar, - destination_number varchar not null, - context varchar not null, - start_stamp timestamp with time zone not null, - answer_stamp timestamp with time zone, - end_stamp timestamp with time zone not null, - duration int not null, - billsec int not null, - hangup_cause varchar not null, - uuid uuid not null, - bleg_uuid uuid, - accountcode varchar, - read_codec varchar, - write_codec varchar, - sip_hangup_disposition varchar, - ani varchar -); - diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 45951f68bf..9da7c9dfcb 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -457,7 +457,6 @@ static void event_handler(switch_event_t *event) PQfinish(globals.db_connection); globals.db_online = 0; } - } } From 80f3281c095f772b32eb1e042d267a089204b8e5 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 15:05:24 +0100 Subject: [PATCH 232/244] whitespace fixups --- .../mod_cdr_sqlite/mod_cdr_sqlite.c | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index efb544e049..b3334fea97 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -38,8 +38,8 @@ typedef enum { } cdr_leg_t; static char default_create_sql[] = - "CREATE TABLE %s (\n" - " caller_id_name VARCHAR,\n" + "CREATE TABLE %s (\n" + " caller_id_name VARCHAR,\n" " caller_id_number VARCHAR,\n" " destination_number VARCHAR,\n" " context VARCHAR,\n" @@ -77,8 +77,8 @@ SWITCH_MODULE_DEFINITION(mod_cdr_sqlite, mod_cdr_sqlite_load, mod_cdr_sqlite_shu switch_cache_db_handle_t *cdr_get_db_handle(void) { - switch_cache_db_connection_options_t options = { {0} }; - switch_cache_db_handle_t *dbh = NULL; + switch_cache_db_connection_options_t options = { {0} }; + switch_cache_db_handle_t *dbh = NULL; options.core_db_options.db_path = globals.db_name; if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS) @@ -89,22 +89,22 @@ switch_cache_db_handle_t *cdr_get_db_handle(void) static switch_status_t write_cdr(char *sql) { - switch_cache_db_handle_t *dbh = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; + switch_cache_db_handle_t *dbh = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; - if (!(dbh = cdr_get_db_handle())) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); - goto end; - } + if (!(dbh = cdr_get_db_handle())) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + goto end; + } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing SQL to DB: %s\n", sql); - status = switch_cache_db_execute_sql(dbh, sql, NULL); + status = switch_cache_db_execute_sql(dbh, sql, NULL); end: - switch_cache_db_release_db_handle(&dbh); + switch_cache_db_release_db_handle(&dbh); - return status; + return status; } From 7b28994121b820e24c48e80c11ff5149f16245d3 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 3 Jan 2011 10:44:28 -0600 Subject: [PATCH 233/244] FS-502: gateway not identified when extension-in-contact is set --- src/mod/endpoints/mod_sofia/sofia.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 94eab68858..9e412bbbb7 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6844,11 +6844,19 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (sip->sip_request->rq_url->url_params) { - gw_name = sofia_glue_find_parameter(sip->sip_request->rq_url->url_params, "gw="); + gw_name = sofia_glue_find_parameter_value(session, sip->sip_request->rq_url->url_params, "gw="); } if (strstr(destination_number, "gw+")) { - gw_name = destination_number + 3; + if (sofia_test_pflag(profile, PFLAG_FULL_ID)) { + char *tmp; + gw_name = switch_core_session_strdup(session, destination_number + 3); + if ((tmp = strchr(gw_name, '@'))) { + *tmp = '\0'; + } + } else { + gw_name = destination_number + 3; + } } if (gw_name) { From a3d66bb4f075cb8b073aac6a84f3651ebec9aadd Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 18:59:41 +0100 Subject: [PATCH 234/244] mod_cdr_pg_csv: make disk spool format user-selectable --- conf/autoload_configs/cdr_pg_csv.conf.xml | 2 + .../mod_cdr_pg_csv/mod_cdr_pg_csv.c | 53 ++++++++++++------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/conf/autoload_configs/cdr_pg_csv.conf.xml b/conf/autoload_configs/cdr_pg_csv.conf.xml index e17809780c..2f2efa9b26 100644 --- a/conf/autoload_configs/cdr_pg_csv.conf.xml +++ b/conf/autoload_configs/cdr_pg_csv.conf.xml @@ -9,6 +9,8 @@ + + diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 9da7c9dfcb..fba5f86728 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -67,6 +67,7 @@ static struct { cdr_leg_t legs; char *db_info; char *db_table; + char *spool_format; PGconn *db_connection; int db_online; switch_mutex_t *db_mutex; @@ -141,6 +142,7 @@ static void do_rotate(cdr_fd_t *fd) static void write_cdr(const char *path, const char *log_line) { cdr_fd_t *fd = NULL; + char *log_line_lf = NULL; unsigned int bytes_in, bytes_out; int loops = 0; @@ -154,8 +156,17 @@ static void write_cdr(const char *path, const char *log_line) switch_core_hash_insert(globals.fd_hash, path, fd); } + if (end_of(log_line) != '\n') { + size_t len = strlen(log_line) + 2; + log_line_lf = switch_core_alloc(globals.pool, len); + switch_snprintf(log_line_lf, len, "%s\n", log_line); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Adding LF to log_line.\n"); + } else { + log_line_lf = switch_core_strdup(globals.pool, log_line); + } + switch_mutex_lock(fd->mutex); - bytes_out = (unsigned) strlen(log_line); + bytes_out = (unsigned) strlen(log_line_lf); if (fd->fd < 0) { do_reopen(fd); @@ -169,7 +180,7 @@ static void write_cdr(const char *path, const char *log_line) do_rotate(fd); } - while ((bytes_in = write(fd->fd, log_line, bytes_out)) != bytes_out && ++loops < 10) { + while ((bytes_in = write(fd->fd, log_line_lf, bytes_out)) != bytes_out && ++loops < 10) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write error to file %s %d/%d\n", path, (int) bytes_in, (int) bytes_out); do_rotate(fd); switch_yield(250000); @@ -184,7 +195,7 @@ static void write_cdr(const char *path, const char *log_line) switch_mutex_unlock(fd->mutex); } -static switch_status_t save_cdr(const char * const template, const char * const cdr, const char * const log_dir) +static switch_status_t save_cdr(const char * const template, const char * const cdr) { char *columns, *values; char *p, *q; @@ -214,7 +225,7 @@ static switch_status_t save_cdr(const char * const template, const char * const /* * In the expanded vars, replace double quotes (") with single quotes (') * for correct PostgreSQL syntax, and replace semi-colon with space to - * prevent SQL injection attacks. + * prevent SQL injection attacks */ values = strdup(cdr); for (p = values; *p; ++p) { @@ -309,9 +320,7 @@ static switch_status_t save_cdr(const char * const template, const char * const values = nullValues; free(tp); - //----------------------------- END_OF_PATCH ------------------------------- - - sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);\n", globals.db_table, columns, values); + sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", globals.db_table, columns, values); assert(sql); free(columns); free(values); @@ -355,22 +364,27 @@ static switch_status_t save_cdr(const char * const template, const char * const switch_mutex_unlock(globals.db_mutex); /* SQL INSERT failed for whatever reason. Spool the attempted query to disk */ - path = switch_mprintf("%s%scdr-spool.sql", log_dir, SWITCH_PATH_SEPARATOR); - assert(path); - write_cdr(path, sql); + if (!strcasecmp(globals.spool_format, "sql")) { + path = switch_mprintf("%s%scdr-spool.sql", globals.log_dir, SWITCH_PATH_SEPARATOR); + assert(path); + write_cdr(path, sql); + } else { + path = switch_mprintf("%s%scdr-spool.csv", globals.log_dir, SWITCH_PATH_SEPARATOR); + assert(path); + write_cdr(path, cdr); + } free(path); free(sql); return SWITCH_STATUS_FALSE; - } static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_status_t status = SWITCH_STATUS_SUCCESS; - const char *log_dir = NULL, *template_str = NULL; + const char *template_str = NULL; char *expanded_vars = NULL; if (globals.shutdown) { @@ -389,12 +403,8 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) } } - if (!(log_dir = switch_channel_get_variable(channel, "cdr_pg_csv_base"))) { - log_dir = globals.log_dir; - } - - if (switch_dir_make_recursive(log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", log_dir); + if (switch_dir_make_recursive(globals.log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.log_dir); return SWITCH_STATUS_FALSE; } @@ -424,7 +434,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) return SWITCH_STATUS_FALSE; } - save_cdr(template_str, expanded_vars, log_dir); + save_cdr(template_str, expanded_vars); if (expanded_vars != template_str) { free(expanded_vars); @@ -528,6 +538,8 @@ static switch_status_t load_config(switch_memory_pool_t *pool) globals.db_table = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "default-template")) { globals.default_template = switch_core_strdup(pool, val); + } else if (!strcasecmp(var, "spool-format")) { + globals.spool_format = switch_core_strdup(pool, val); } } } @@ -563,6 +575,9 @@ static switch_status_t load_config(switch_memory_pool_t *pool) globals.default_template = switch_core_strdup(pool, "default"); } + if (zstr(globals.spool_format)) { + globals.spool_format = switch_core_strdup(pool, "csv"); + } return status; } From 66ce95a93049404324a382d307730c3aa4a1e443 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 19:10:15 +0100 Subject: [PATCH 235/244] removing my debug :o --- src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index fba5f86728..9f4260ddbb 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -160,7 +160,6 @@ static void write_cdr(const char *path, const char *log_line) size_t len = strlen(log_line) + 2; log_line_lf = switch_core_alloc(globals.pool, len); switch_snprintf(log_line_lf, len, "%s\n", log_line); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Adding LF to log_line.\n"); } else { log_line_lf = switch_core_strdup(globals.pool, log_line); } From df090a2a6b1042b8c575ecce241c021e16a792be Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 21:39:36 +0100 Subject: [PATCH 236/244] free() -> switch_safe_free() --- .../mod_cdr_pg_csv/mod_cdr_pg_csv.c | 18 +++++++++--------- .../mod_cdr_sqlite/mod_cdr_sqlite.c | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 9f4260ddbb..e515f8db19 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -121,7 +121,7 @@ static void do_rotate(cdr_fd_t *fd) p = switch_mprintf("%s.%s", fd->path, date); assert(p); switch_file_rename(fd->path, p, globals.pool); - free(p); + switch_safe_free(p); } do_reopen(fd); @@ -317,12 +317,12 @@ static switch_status_t save_cdr(const char * const template, const char * const *tp = 0; tp = values; values = nullValues; - free(tp); + switch_safe_free(tp); sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", globals.db_table, columns, values); assert(sql); - free(columns); - free(values); + switch_safe_free(columns); + switch_safe_free(values); if (globals.debug) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Query: \"%s\"\n", sql); @@ -349,7 +349,7 @@ static switch_status_t save_cdr(const char * const template, const char * const } PQclear(res); - free(sql); + switch_safe_free(sql); switch_mutex_unlock(globals.db_mutex); @@ -373,8 +373,8 @@ static switch_status_t save_cdr(const char * const template, const char * const write_cdr(path, cdr); } - free(path); - free(sql); + switch_safe_free(path); + switch_safe_free(sql); return SWITCH_STATUS_FALSE; } @@ -416,7 +416,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) switch_assert(buf); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf); switch_event_destroy(&event); - free(buf); + switch_safe_free(buf); } } @@ -436,7 +436,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) save_cdr(template_str, expanded_vars); if (expanded_vars != template_str) { - free(expanded_vars); + switch_safe_free(expanded_vars); } return status; diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index b3334fea97..1b91f1242a 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -140,7 +140,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) switch_assert(buf); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf); switch_event_destroy(&event); - free(buf); + switch_safe_free(buf); } } @@ -160,7 +160,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) sql = switch_mprintf("INSERT INTO %s VALUES (%s)", globals.db_table, expanded_vars); assert(sql); write_cdr(sql); - free(sql); + switch_safe_free(sql); return status; } @@ -264,8 +264,8 @@ static switch_status_t load_config(switch_memory_pool_t *pool) /* Check if table exists (try SELECT FROM ...) and create table if query fails */ switch_cache_db_test_reactive(dbh, select_sql, NULL, create_sql); - free(select_sql); - free(create_sql); + switch_safe_free(select_sql); + switch_safe_free(create_sql); switch_cache_db_release_db_handle(&dbh); } From 8b7fd76d3de084e581e994ffa171d1f6653a4d55 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Mon, 3 Jan 2011 22:09:46 +0100 Subject: [PATCH 237/244] use switch_zmalloc() instead of apr pools for short term storage, rename a couple of funcs to be clearer as to their purpose --- .../mod_cdr_pg_csv/mod_cdr_pg_csv.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index e515f8db19..9cc1d8cf2c 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -139,7 +139,7 @@ static void do_rotate(cdr_fd_t *fd) } -static void write_cdr(const char *path, const char *log_line) +static void spool_cdr(const char *path, const char *log_line) { cdr_fd_t *fd = NULL; char *log_line_lf = NULL; @@ -157,12 +157,11 @@ static void write_cdr(const char *path, const char *log_line) } if (end_of(log_line) != '\n') { - size_t len = strlen(log_line) + 2; - log_line_lf = switch_core_alloc(globals.pool, len); - switch_snprintf(log_line_lf, len, "%s\n", log_line); + log_line_lf = switch_mprintf("%s\n", log_line); } else { - log_line_lf = switch_core_strdup(globals.pool, log_line); + switch_strdup(log_line_lf, log_line); } + assert(log_line_lf); switch_mutex_lock(fd->mutex); bytes_out = (unsigned) strlen(log_line_lf); @@ -192,9 +191,10 @@ static void write_cdr(const char *path, const char *log_line) end: switch_mutex_unlock(fd->mutex); + switch_safe_free(log_line_lf); } -static switch_status_t save_cdr(const char * const template, const char * const cdr) +static switch_status_t insert_cdr(const char * const template, const char * const cdr) { char *columns, *values; char *p, *q; @@ -210,7 +210,7 @@ static switch_status_t save_cdr(const char * const template, const char * const } /* Build comma-separated list of field names by dropping $ { } ; chars */ - columns = strdup(template); + switch_strdup(columns, template); for (p = columns, q = columns; *p; ++p) { switch (*p) { case '$': case '"': case '{': case '}': case ';': @@ -226,7 +226,7 @@ static switch_status_t save_cdr(const char * const template, const char * const * for correct PostgreSQL syntax, and replace semi-colon with space to * prevent SQL injection attacks */ - values = strdup(cdr); + switch_strdup(values, cdr); for (p = values; *p; ++p) { switch(*p) { case '"': @@ -260,7 +260,7 @@ static switch_status_t save_cdr(const char * const template, const char * const nullCounter *= 4; vlen += nullCounter; - nullValues = (char *) malloc(strlen(values) + nullCounter + 1); + switch_zmalloc(nullValues, strlen(values) + nullCounter + 1); charCounter = 0; temp = nullValues; tp = nullValues; @@ -366,11 +366,11 @@ static switch_status_t save_cdr(const char * const template, const char * const if (!strcasecmp(globals.spool_format, "sql")) { path = switch_mprintf("%s%scdr-spool.sql", globals.log_dir, SWITCH_PATH_SEPARATOR); assert(path); - write_cdr(path, sql); + spool_cdr(path, sql); } else { path = switch_mprintf("%s%scdr-spool.csv", globals.log_dir, SWITCH_PATH_SEPARATOR); assert(path); - write_cdr(path, cdr); + spool_cdr(path, cdr); } switch_safe_free(path); @@ -433,7 +433,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) return SWITCH_STATUS_FALSE; } - save_cdr(template_str, expanded_vars); + insert_cdr(template_str, expanded_vars); if (expanded_vars != template_str) { switch_safe_free(expanded_vars); From fc77d19b7bc6c64eadbd37f9715a79431f897379 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 3 Jan 2011 16:40:49 -0600 Subject: [PATCH 238/244] presence.... again.... --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia_reg.c | 29 ++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 5fd6cd7963..8c6b1e0830 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -1035,6 +1035,7 @@ void sofia_profile_destroy(sofia_profile_t *profile); switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream); const char *sofia_gateway_status_name(sofia_gateway_status_t status); void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase); +uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const char *host); void sofia_glue_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session); switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *session, const char *r_sdp); char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 961eaa3ea0..1589eeb8e1 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -817,6 +817,19 @@ void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_safe_free(auth_str); } +uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const char *host) +{ + char buf[32] = ""; + char *sql; + + sql = switch_mprintf("select count(*) from sip_registrations where profile_name='%q' and " + "sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", profile->name, user, host, host); + + sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); + switch_safe_free(sql); + return atoi(buf); +} + uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event, const char *is_nat) { @@ -1298,6 +1311,12 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } + if (sofia_reg_reg_count(profile, to_user, reg_host) == 1) { + sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' and profile_name='%q' and open_closed='closed'", + to_user, reg_host, profile->name); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DELETE PRESENCE SQL: %s\n", sql); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } switch_mutex_unlock(profile->ireg_mutex); @@ -1361,8 +1380,16 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } else { + int send = 1; - if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { + if (multi_reg) { + if (sofia_reg_reg_count(profile, to_user, sub_host) > 0) { + send = 0; + } + } + + + if (send && switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url); From e6070feeab6940a3566a59a7802f003fa4181093 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 3 Jan 2011 16:48:10 -0600 Subject: [PATCH 239/244] cleanup --- src/mod/endpoints/mod_sofia/sofia_presence.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 68296052e6..04d5b0142e 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2645,14 +2645,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !open) { - char buf[32] = ""; - - sql = switch_mprintf("select count(*) from sip_registrations where " - "sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", from_user, from_host, from_host); - - sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); - switch_safe_free(sql); - count = atoi(buf); + count = sofia_reg_reg_count(profile, from_user, from_host); } From 4a6b4e86f16a25074cc0f77fc7ddbda36f5cbfc4 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 4 Jan 2011 09:30:49 -0500 Subject: [PATCH 240/244] freetdm: add non-locking answer function to handle answer indication export ftdm_current_time_in_ms to users update testr2 to test non-blocking API (no waiting on indications) --- libs/freetdm/src/ftdm_io.c | 49 +++--- libs/freetdm/src/include/ftdm_os.h | 5 + libs/freetdm/src/include/private/ftdm_core.h | 1 - libs/freetdm/src/include/private/ftdm_types.h | 2 - libs/freetdm/src/testr2.c | 144 ++++++++++++++---- 5 files changed, 147 insertions(+), 54 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index e55839a784..b60e72f605 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2032,22 +2032,22 @@ FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *fchan, ftdm_channel_indicat ftdm_span_send_signal(fchan->span, &msg); } -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) +/*! \brief Answer call without locking the channel. The caller must have locked first + * \note This function was added because ftdm_channel_call_indicate needs to answer the call + * when its already locking the channel, ftdm_channel_set_state cannot be called with the same + * lock locked once or more (recursive lock) and wait for the result */ +static ftdm_status_t _ftdm_channel_call_answer_nl(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { ftdm_status_t status = FTDM_SUCCESS; - ftdm_channel_lock(ftdmchan); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + status = FTDM_EINVAL; + goto done; + } if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call is already TERMINATING\n"); status = FTDM_ECANCELED; - ftdm_ack_indication(ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, status); - goto done; - } - - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - status = FTDM_EINVAL; - ftdm_ack_indication(ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, status); goto done; } @@ -2059,7 +2059,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, status); + status = FTDM_ECANCELED; goto done; } } @@ -2068,14 +2068,13 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n"); status = FTDM_ECANCELED; - ftdm_ack_indication(ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, status); goto done; } if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, status); + status = FTDM_ECANCELED; goto done; } } @@ -2084,23 +2083,35 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n"); status = FTDM_ECANCELED; - ftdm_ack_indication(ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, status); goto done; } } status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1); if (status != FTDM_SUCCESS) { - ftdm_ack_indication(ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER, status); + status = FTDM_ECANCELED; + goto done; } done: + + return status; +} + +FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) +{ + ftdm_status_t status = FTDM_SUCCESS; + + ftdm_channel_lock(ftdmchan); + + status = _ftdm_channel_call_answer_nl(file, func, line, ftdmchan); + ftdm_channel_unlock(ftdmchan); return status; } /* lock must be acquired by the caller! */ -static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line) +static ftdm_status_t _ftdm_channel_call_hangup_nl(ftdm_channel_t *chan, const char *file, const char *func, int line) { ftdm_status_t status = FTDM_SUCCESS; @@ -2139,7 +2150,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, ftdmchan->caller_data.hangup_cause = cause; - status = call_hangup(ftdmchan, file, func, line); + status = _ftdm_channel_call_hangup_nl(ftdmchan, file, func, line); ftdm_channel_unlock(ftdmchan); return status; @@ -2153,7 +2164,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; - status = call_hangup(ftdmchan, file, func, line); + status = _ftdm_channel_call_hangup_nl(ftdmchan, file, func, line); ftdm_channel_unlock(ftdmchan); return status; @@ -2288,7 +2299,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch break; case FTDM_CHANNEL_INDICATE_ANSWER: /* _ftdm_channel_call_answer takes care of the indication ack */ - status = _ftdm_channel_call_answer(file, func, line, ftdmchan); + status = _ftdm_channel_call_answer_nl(file, func, line, ftdmchan); break; default: ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Do not know how to indicate %d\n", indication); @@ -5292,7 +5303,7 @@ static void execute_safety_hangup(void *data) fchan->hangup_timer = 0; if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER); - call_hangup(fchan, __FILE__, __FUNCTION__, __LINE__); + _ftdm_channel_call_hangup_nl(fchan, __FILE__, __FUNCTION__, __LINE__); } else { ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state)); } diff --git a/libs/freetdm/src/include/ftdm_os.h b/libs/freetdm/src/include/ftdm_os.h index f3ebee9ea2..a4605c3371 100644 --- a/libs/freetdm/src/include/ftdm_os.h +++ b/libs/freetdm/src/include/ftdm_os.h @@ -51,6 +51,9 @@ extern "C" { #include #endif +/*! \brief time data type */ +typedef uint64_t ftdm_time_t; + /*! \brief sleep x amount of milliseconds */ #ifdef __WINDOWS__ #define ftdm_sleep(x) Sleep(x) @@ -114,6 +117,8 @@ FT_DECLARE(char *) ftdm_strdup(const char *str); /*! \brief Duplicate string with limit */ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen); +/*! \brief Get the current time in milliseconds */ +FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void); #ifdef __cplusplus } /* extern C */ diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 55fb8ba032..a5862e5d15 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -556,7 +556,6 @@ FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_sdmf(ftdm_fsk_data_state_t *state, c FT_DECLARE(ftdm_status_t) ftdm_channel_send_fsk_data(ftdm_channel_t *ftdmchan, ftdm_fsk_data_state_t *fsk_data, float db_level); FT_DECLARE(ftdm_status_t) ftdm_span_load_tones(ftdm_span_t *span, const char *mapname); -FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void); FT_DECLARE(ftdm_status_t) ftdm_channel_use(ftdm_channel_t *ftdmchan); diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 41711f743d..2d683e3098 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -69,8 +69,6 @@ extern "C" { #define FTDM_END -1 #define FTDM_ANY_STATE -1 -typedef uint64_t ftdm_time_t; - typedef enum { FTDM_ENDIAN_BIG = 1, FTDM_ENDIAN_LITTLE = -1 diff --git a/libs/freetdm/src/testr2.c b/libs/freetdm/src/testr2.c index 8ac90c59fd..72d98020bc 100644 --- a/libs/freetdm/src/testr2.c +++ b/libs/freetdm/src/testr2.c @@ -2,78 +2,158 @@ #include #include -static int R = 0; -static ftdm_mutex_t *mutex = NULL; +static volatile int running = 0; +static ftdm_mutex_t *the_mutex = NULL; +static ftdm_channel_t *fchan = NULL; +static ftdm_channel_indication_t indication = FTDM_CHANNEL_INDICATE_NONE; static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) { int chanid = ftdm_channel_get_ph_id(sigmsg->channel); - ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel\n", ftdm_signal_event2str(sigmsg->event_id), chanid); - return FTDM_SUCCESS; + ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel\n", ftdm_signal_event2str(sigmsg->event_id), chanid); + switch (sigmsg->event_id) { + case FTDM_SIGEVENT_START: + { + ftdm_mutex_lock(the_mutex); + if (!fchan) { + fchan = sigmsg->channel; + indication = FTDM_CHANNEL_INDICATE_PROCEED; + } + ftdm_mutex_unlock(the_mutex); + } + break; + case FTDM_SIGEVENT_INDICATION_COMPLETED: + { + ftdm_channel_indication_t ind = FTDM_CHANNEL_INDICATE_NONE; + if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROCEED) { + ftdm_log(FTDM_LOG_DEBUG, "Proceed indication result = %d\n", sigmsg->ev_data.indication_completed.status); + ind = FTDM_CHANNEL_INDICATE_PROGRESS; + } else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROGRESS) { + ftdm_log(FTDM_LOG_DEBUG, "Progress indication result = %d\n", sigmsg->ev_data.indication_completed.status); + ind = FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA; + } else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA) { + ftdm_log(FTDM_LOG_DEBUG, "Progress media indication result = %d\n", sigmsg->ev_data.indication_completed.status); + ind = FTDM_CHANNEL_INDICATE_ANSWER; + } else if (sigmsg->ev_data.indication_completed.indication == FTDM_CHANNEL_INDICATE_ANSWER) { + ftdm_log(FTDM_LOG_DEBUG, "Answer indication result = %d\n", sigmsg->ev_data.indication_completed.status); + } else { + ftdm_log(FTDM_LOG_DEBUG, "Unexpected indication, result = %d\n", sigmsg->ev_data.indication_completed.status); + exit(1); + } + ftdm_mutex_lock(the_mutex); + if (fchan) { + indication = ind; + } + ftdm_mutex_unlock(the_mutex); + } + break; + case FTDM_SIGEVENT_STOP: + { + ftdm_channel_call_hangup(sigmsg->channel); + } + break; + case FTDM_SIGEVENT_RELEASED: + { + ftdm_mutex_lock(the_mutex); + if (fchan && fchan == sigmsg->channel) { + fchan = NULL; + } + ftdm_mutex_unlock(the_mutex); + } + break; + default: + break; + } + return FTDM_SUCCESS; } -static void handle_SIGINT(int sig) +static void stop_test(int sig) { - ftdm_mutex_lock(mutex); - R = 0; - ftdm_mutex_unlock(mutex); - return; + running = 0; } int main(int argc, char *argv[]) { ftdm_span_t *span; - ftdm_mutex_create(&mutex); - - ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); + ftdm_conf_parameter_t parameters[20]; + + ftdm_mutex_create(&the_mutex); if (argc < 2) { printf("umm no\n"); - exit(-1); + exit(1); } + ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); + if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); - exit(-1); + exit(1); } + ftdm_global_configuration(); + printf("FreeTDM loaded\n"); - if (ftdm_span_find(atoi(argv[1]), &span) != FTDM_SUCCESS) { - fprintf(stderr, "Error finding FreeTDM span\n"); + if (ftdm_span_find_by_name(argv[1], &span) != FTDM_SUCCESS) { + fprintf(stderr, "Error finding FreeTDM span %s\n", argv[1]); goto done; } + /* testing non-blocking operation */ + //ftdm_span_set_blocking_mode(span, FTDM_FALSE); + parameters[0].var = "variant"; + parameters[0].val = "br"; - if (ftdm_configure_span(span, "r2", on_r2_signal, - "variant", "mx", - "max_ani", 10, - "max_dnis", 4, - "logging", "all", - FTDM_TAG_END) == FTDM_SUCCESS) { - + parameters[1].var = "max_ani"; + parameters[1].val = "4"; + parameters[2].var = "max_dnis"; + parameters[2].val = "4"; + + parameters[3].var = "logging"; + parameters[3].val = "all"; + + parameters[4].var = NULL; + parameters[4].val = NULL; + + if (ftdm_configure_span_signaling(span, "r2", on_r2_signal, parameters) == FTDM_SUCCESS) { ftdm_span_start(span); } else { fprintf(stderr, "Error starting R2 span\n"); goto done; } - signal(SIGINT, handle_SIGINT); - ftdm_mutex_lock(mutex); - R = 1; - ftdm_mutex_unlock(mutex); - while(R) { - ftdm_sleep(1 * 1000); + running = 1; + signal(SIGINT, stop_test); + while(running) { + ftdm_sleep(20); + if (fchan && indication != FTDM_CHANNEL_INDICATE_NONE) { + ftdm_channel_t *lchan = NULL; + ftdm_channel_indication_t ind = FTDM_CHANNEL_INDICATE_NONE; + ftdm_time_t start, stop, diff; + + ftdm_mutex_lock(the_mutex); + ind = indication; + indication = FTDM_CHANNEL_INDICATE_NONE; + lchan = fchan; + ftdm_mutex_unlock(the_mutex); + + start = ftdm_current_time_in_ms(); + ftdm_channel_call_indicate(lchan, ind); + stop = ftdm_current_time_in_ms(); + diff = stop - start; + ftdm_log(FTDM_LOG_DEBUG, "Setting indication %s took %llums\n", + ftdm_channel_indication2str(ind), diff); + } } - done: +done: ftdm_global_destroy(); - return 1; - + return 0; } /* For Emacs: From 5c02639b5acf48ead80045f50e841c1c43f36d34 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 4 Jan 2011 10:37:20 -0500 Subject: [PATCH 241/244] freetdm: update ftmod_sangoma_ss7 to use new state advance API --- .../ftmod_sangoma_ss7_main.c | 20 +++++++------------ .../ftmod_sangoma_ss7_main.h | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 05a325b913..9016771671 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -46,7 +46,6 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data; /* PROTOTYPES *****************************************************************/ static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj); -void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event); static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span); @@ -308,9 +307,7 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) ftdm_mutex_lock(ftdmchan->mutex); /* process state changes for this channel until they are all done */ - while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change (ftdmchan); - } + ftdm_channel_advance_states(ftdmchan); /* unlock the channel */ ftdm_mutex_unlock (ftdmchan->mutex); @@ -403,9 +400,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev ftdm_mutex_lock(ftdmchan->mutex); /* while there's a state change present on this channel process it */ - while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change(ftdmchan); - } + ftdm_channel_advance_states(ftdmchan); /* figure out the type of event and send it to the right handler */ switch (sngss7_event->event_id) { @@ -468,9 +463,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev } /* switch (sngss7_event->event_id) */ /* while there's a state change present on this channel process it */ - while (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - ftdm_sangoma_ss7_process_state_change(ftdmchan); - } + ftdm_channel_advance_states(ftdmchan); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -479,7 +472,7 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev } /******************************************************************************/ -void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) +ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) { sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; sng_isup_inf_t *isup_intf = NULL; @@ -495,7 +488,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state)); /* clear the state change flag...since we might be setting a new state */ - ftdm_clear_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE); + ftdm_channel_complete_state(ftdmchan); /*check what state we are supposed to be in */ switch (ftdmchan->state) { @@ -1212,7 +1205,7 @@ suspend_goto_restart: /**************************************************************************/ }/*switch (ftdmchan->state) */ - return; + return FTDM_SUCCESS; } /******************************************************************************/ @@ -1476,6 +1469,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) span->get_channel_sig_status = ftdm_sangoma_ss7_get_sig_status; span->set_channel_sig_status = ftdm_sangoma_ss7_set_sig_status; span->state_map = &sangoma_ss7_state_map; + span->state_processor = ftdm_sangoma_ss7_process_state_change; span->signal_data = ss7_span_info; /* set the flag to indicate that this span uses channel state change queues */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index fe4b6f45c4..f28547f9fe 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -452,7 +452,7 @@ extern int cmbLinkSetId; /* PROTOTYPES *****************************************************************/ /* in ftmod_sangoma_ss7_main.c */ -void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); +ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); /* in ftmod_sangoma_ss7_logger.c */ void handle_sng_log(uint8_t level, char *fmt,...); From 47c1b6d96ab853341efea272efe0ae5a60e97634 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 4 Jan 2011 14:23:25 -0500 Subject: [PATCH 242/244] freetdm: add validation to ftdm_span_start and ftdm_span_stop --- libs/freetdm/src/ftdm_io.c | 48 ++++++++++++++++--- libs/freetdm/src/include/private/ftdm_types.h | 2 +- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index efd52542a6..21354c4442 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -733,11 +733,28 @@ static void ftdm_span_add(ftdm_span_t *span) FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span) { - ftdm_status_t status = FTDM_FAIL; - if (span->stop) { - status = span->stop(span); - span->stop = NULL; + ftdm_status_t status = FTDM_SUCCESS; + + ftdm_mutex_lock(span->mutex); + + if (!ftdm_test_flag(span, FTDM_SPAN_STARTED)) { + status = FTDM_EINVAL; + goto done; } + + if (!span->stop) { + status = FTDM_ENOSYS; + goto done; + } + + status = span->stop(span); + if (FTDM_SUCCESS == status) { + ftdm_clear_flag(span, FTDM_SPAN_STARTED); + } + +done: + ftdm_mutex_unlock(span->mutex); + return status; } @@ -5063,11 +5080,28 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span) { - if (span->start) { - return span->start(span); + ftdm_status_t status = FTDM_FAIL; + + ftdm_mutex_lock(span->mutex); + + if (ftdm_test_flag(span, FTDM_SPAN_STARTED)) { + status = FTDM_EINVAL; + goto done; } - return FTDM_FAIL; + if (!span->start) { + status = FTDM_ENOSYS; + goto done; + } + + status = span->start(span); + if (status == FTDM_SUCCESS) { + ftdm_set_flag_locked(span, FTDM_SPAN_STARTED); + } + +done: + ftdm_mutex_unlock(span->mutex); + return status; } FT_DECLARE(ftdm_status_t) ftdm_channel_add_to_group(const char* name, ftdm_channel_t* ftdmchan) diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 2d683e3098..d79835733b 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -168,7 +168,7 @@ typedef enum { typedef enum { FTDM_SPAN_CONFIGURED = (1 << 0), - FTDM_SPAN_READY = (1 << 1), + FTDM_SPAN_STARTED = (1 << 1), FTDM_SPAN_STATE_CHANGE = (1 << 2), FTDM_SPAN_SUSPENDED = (1 << 3), FTDM_SPAN_IN_THREAD = (1 << 4), From a390e046b7d9e67e2fac8adcfd6c47c1011c01bb Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Tue, 4 Jan 2011 20:07:22 -0200 Subject: [PATCH 243/244] freetdm: ftmod_r2 - now locking the channel on main loop start and finish replaced calls to ftdm_mutex_lock() with ftdm_channel_lock() --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index f1ef61ce9f..79850a3c1f 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1862,10 +1862,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) } for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { ftdmchan = ftdm_iterator_current(citer); + ftdm_channel_lock(ftdmchan); r2chan = R2CALL(ftdmchan)->r2chan; openr2_chan_set_span_id(r2chan, span->span_id); openr2_chan_set_idle(r2chan); openr2_chan_process_cas_signaling(r2chan); + ftdm_channel_unlock(ftdmchan); ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &txqueue_size); } @@ -1947,7 +1949,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) for ( ; citer; citer = ftdm_iterator_next(citer)) { ftdmchan = ftdm_iterator_current(citer); - ftdm_mutex_lock(ftdmchan->mutex); + ftdm_channel_lock(ftdmchan); call = R2CALL(ftdmchan); @@ -1969,7 +1971,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_set_flag(ftdmchan, FTDM_CHANNEL_TX_DISABLED); } - ftdm_mutex_unlock(ftdmchan->mutex); + ftdm_channel_unlock(ftdmchan); } } @@ -1977,8 +1979,10 @@ done: citer = ftdm_span_get_chan_iterator(span, chaniter); for ( ; citer; citer = ftdm_iterator_next(citer)) { ftdmchan = ftdm_iterator_current(citer); + ftdm_channel_lock(ftdmchan); r2chan = R2CALL(ftdmchan)->r2chan; openr2_chan_set_blocked(r2chan); + ftdm_channel_unlock(ftdmchan); } ftdm_iterator_free(chaniter); From f574db09583479fb85dbbbfb9a376843c700669b Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 5 Jan 2011 12:23:09 -0500 Subject: [PATCH 244/244] freetdm: clear blocking flag when failing to wait for state change --- libs/freetdm/src/ftdm_state.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index 0221fa2a1e..f6c2c2320c 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -338,6 +338,7 @@ end: ftdm_mutex_lock(ftdmchan->mutex); if (status != FTDM_SUCCESS) { + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_BLOCKING); ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "state change from %s to %s was most likely not completed after aprox %dms\n", ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME);