From 34e44f92a193291a4a7303cd6f3e0b96e79ab080 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 6 Dec 2010 23:24:39 -0500 Subject: [PATCH 001/146] freetdm: OPENZAP-121 - ftmod_sangoma_ss7 compile error --- .../freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index 4a9c863b12..8a24f971ed 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -1976,7 +1976,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i return FTDM_FAIL; } - strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-route"); + strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-rt"); g_ftdm_sngss7_data.cfg.mtpRoute[0].id = 0; g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc = spc; From 9350fb96265961fd87c1bcecdb4e0123cf77234f Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 7 Dec 2010 00:19:49 -0600 Subject: [PATCH 002/146] skypopen: added a second timer on read from Skype client (timer_read_srv), so not to depend anymore from select on that socket --- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 20 +++++++++++++++++++ src/mod/endpoints/mod_skypopen/skypopen.h | 5 +++-- .../mod_skypopen/skypopen_protocol.c | 10 ++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 1263e5f81a..65c1b120fd 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -526,6 +526,10 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session) switch_core_timer_destroy(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_destroy(&tech_pvt->timer_read_srv); + } + if (tech_pvt->timer_write.timer_interface && tech_pvt->timer_write.timer_interface->timer_next) { switch_core_timer_destroy(&tech_pvt->timer_write); } @@ -1121,6 +1125,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -1146,6 +1153,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -1168,6 +1178,9 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -2168,6 +2181,13 @@ int start_audio_threads(private_t *tech_pvt) switch_core_timer_sync(&tech_pvt->timer_read); + if (switch_core_timer_init(&tech_pvt->timer_read_srv, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) { + ERRORA("setup timer failed\n", SKYPOPEN_P_LOG); + return SWITCH_STATUS_FALSE; + } + + switch_core_timer_sync(&tech_pvt->timer_read_srv); + if (switch_core_timer_init(&tech_pvt->timer_write, "soft", MS_SKYPOPEN, SAMPLES_PER_FRAME, skypopen_module_pool) != SWITCH_STATUS_SUCCESS) { ERRORA("setup timer failed\n", SKYPOPEN_P_LOG); return SWITCH_STATUS_FALSE; diff --git a/src/mod/endpoints/mod_skypopen/skypopen.h b/src/mod/endpoints/mod_skypopen/skypopen.h index 4ff2b012c6..2f1c8e48e9 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/skypopen.h @@ -76,8 +76,8 @@ #define SAMPLERATE_SKYPOPEN 16000 #define MS_SKYPOPEN 20 -#define SAMPLES_PER_FRAME SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN) -#define BYTES_PER_FRAME SAMPLES_PER_FRAME * sizeof(short) +#define SAMPLES_PER_FRAME (SAMPLERATE_SKYPOPEN/(1000/MS_SKYPOPEN)) +#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * sizeof(short)) #ifdef SKYPOPEN_C_VER #ifdef MODSKYPOPEN_C_VER @@ -341,6 +341,7 @@ struct private_object { chat_t chats[MAX_CHATS]; uint32_t report_incoming_chatmessages; switch_timer_t timer_read; + switch_timer_t timer_read_srv; switch_timer_t timer_write; int begin_to_write; int begin_to_read; diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c index ef06bfac1e..391a23caaf 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c @@ -547,6 +547,9 @@ int skypopen_signaling_read(private_t *tech_pvt) if (tech_pvt->timer_read.timer_interface && tech_pvt->timer_read.timer_interface->timer_next) { switch_core_timer_sync(&tech_pvt->timer_read); } + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_sync(&tech_pvt->timer_read_srv); + } switch_mutex_unlock(tech_pvt->mutex_audio_srv); } @@ -878,7 +881,7 @@ void *skypopen_do_tcp_srv_thread_func(void *obj) || tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) { unsigned int fdselect; - int rt; + int rt=1; fd_set fs; struct timeval to; int nospace; @@ -891,7 +894,10 @@ void *skypopen_do_tcp_srv_thread_func(void *obj) to.tv_usec = MS_SKYPOPEN * 1000 * 3; to.tv_sec = 0; - rt = select(fdselect + 1, &fs, NULL, NULL, &to); + if (tech_pvt->timer_read_srv.timer_interface && tech_pvt->timer_read_srv.timer_interface->timer_next) { + switch_core_timer_next(&tech_pvt->timer_read_srv); + } + //rt = select(fdselect + 1, &fs, NULL, NULL, &to); if (rt > 0) { if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { From 6a36b8f33faa20d4c4b1aa516feb0c6bf30be429 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 7 Dec 2010 09:59:56 -0500 Subject: [PATCH 003/146] freetdm: isdn stack and testsangomaboost warning fix --- .../ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 2 -- libs/freetdm/src/testsangomaboost.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) 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 16b22a5da1..086354a993 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 @@ -328,8 +328,6 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; - sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; ISDN_FUNC_TRACE_ENTER(__FUNCTION__); diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index 85b5332635..61b7c47ddd 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -48,7 +48,7 @@ #include #include #include -#ifdef __linux__ +#if defined(__linux__) && !defined(__USE_BSD) #define __USE_BSD #include #endif From 60cb91b042cf62186a9f967ab668dfc6c919f6ae Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Tue, 7 Dec 2010 20:06:48 +0100 Subject: [PATCH 004/146] freetdm: ftmod_libpri + ftmod_zt: some DAHDI drivers return an error of ELAST (500) on read()/write() to indicate there are events pending. Fixup zt_read() to handle this case correctly and rework ftmod_libpri's read wrapper function to not fail when the read function returns zero bytes. NOTE: zt_write() has not been changed (some better way to handle these events is needed then) This should fix these log messages: [WARNING] ftdm_io.c:3561 [s1c16][1:16] raw I/O read filed [CRIT] lpwrap_pri.c:125 span 1 D-READ FAIL! [] [CRIT] lpwrap_pri.c:157 span 1 D-WRITE FAIL! [] [ERR] ftmod_libpri.c:131 Short write: -1/6 (Unknown error 500) Signed-off-by: Stefan Knoblich --- .../src/ftmod/ftmod_libpri/lpwrap_pri.c | 17 +++++++------ libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 25 ++++++++++++++----- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index de4fa2b232..fbe6ca0822 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -134,17 +134,18 @@ static int __pri_lpwrap_read(struct pri *pri, void *buf, int buflen) spri->errs = 0; res = (int)len; - memset(&((unsigned char*)buf)[res], 0, 2); - res += 2; - + if (res > 0) { + memset(&((unsigned char*)buf)[res], 0, 2); + res += 2; #ifdef IODEBUG - { - char bb[2048] = { 0 }; + { + char bb[2048] = { 0 }; - print_hex_bytes(buf, res - 2, bb, sizeof(bb)); - ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2); - } + print_hex_bytes(buf, res - 2, bb, sizeof(bb)); + ftdm_log(FTDM_LOG_DEBUG, "READ %d\n", res - 2); + } #endif + } return res; } diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 9247edc72e..7320934a49 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -35,6 +35,11 @@ #include "private/ftdm_core.h" #include "ftmod_zt.h" +/* used by dahdi to indicate there is no data available, but events to read */ +#ifndef ELAST +#define ELAST 500 +#endif + /** * \brief Zaptel globals */ @@ -1081,7 +1086,6 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) } return FTDM_FAIL; - } /** @@ -1100,12 +1104,19 @@ static FIO_READ_FUNCTION(zt_read) if ((r = read(ftdmchan->sockfd, data, *datalen)) > 0) { break; } - ftdm_sleep(10); - if (r == 0) { - errs--; + else if (r == 0) { + ftdm_sleep(10); + if (errs) errs--; + } + else { + if (errno == EAGAIN || errno == EINTR) + continue; + if (errno == ELAST) + break; + + ftdm_log(FTDM_LOG_ERROR, "read failed: %s\n", strerror(errno)); } } - if (r > 0) { *datalen = r; if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { @@ -1113,7 +1124,9 @@ static FIO_READ_FUNCTION(zt_read) } return FTDM_SUCCESS; } - + else if (errno == ELAST) { + return FTDM_SUCCESS; + } return r == 0 ? FTDM_TIMEOUT : FTDM_FAIL; } From 37cdd5b93466811988b6a413165d579a9fa548f0 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 7 Dec 2010 18:31:32 -0500 Subject: [PATCH 005/146] freetdm: more analog changes to attempt to make the state transitions more similar to other signaling modules --- libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c | 5 +++-- .../src/ftmod/ftmod_analog_em/ftmod_analog_em.c | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 95002e3e70..f07f48b0d6 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -491,9 +491,10 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL); } - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && + 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_RING)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); } else { ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; 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 199bba43a3..886c4a8fec 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 @@ -329,8 +329,8 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) { if (state_counter > 500) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && - (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE - || ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) { + (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE + || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); } else { ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; @@ -340,7 +340,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) } break; case FTDM_CHANNEL_STATE_UP: - case FTDM_CHANNEL_STATE_IDLE: + case FTDM_CHANNEL_STATE_RING: { ftdm_sleep(interval); continue; @@ -386,7 +386,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_use(ftdmchan); } break; - case FTDM_CHANNEL_STATE_IDLE: + case FTDM_CHANNEL_STATE_RING: { ftdm_channel_use(ftdmchan); @@ -421,7 +421,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_command(ftdmchan, FTDM_COMMAND_WINK, NULL); } break; - case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: { ftdm_buffer_zero(dt_buffer); teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]); @@ -477,7 +477,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) { ftdm_log(FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING); last_digit = 0; collecting = 0; } From 72bcc01b1d975c6d2667cd4762addcff50f1b140 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 7 Dec 2010 22:32:38 -0600 Subject: [PATCH 006/146] FS-2210 Add support for auto completion for uuid_simplify --- .../applications/mod_commands/mod_commands.c | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index c7edfd5420..eacde59949 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2491,24 +2491,47 @@ SWITCH_STANDARD_API(uuid_display_function) #define SIMPLIFY_SYNTAX "" SWITCH_STANDARD_API(uuid_simplify_function) { + char *mydata = NULL, *argv[2] = { 0 }; + int argc = 0; + switch_status_t status = SWITCH_STATUS_FALSE; if (zstr(cmd)) { - stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX); - } else { + goto error; + } + + mydata = strdup(cmd); + switch_assert(mydata); + + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc < 1) { + goto error; + } + if (argv[0]) { switch_core_session_message_t msg = { 0 }; switch_core_session_t *lsession = NULL; msg.message_id = SWITCH_MESSAGE_INDICATE_SIMPLIFY; - msg.string_arg = cmd; + msg.string_arg = argv[0]; msg.from = __FILE__; - if ((lsession = switch_core_session_locate(cmd))) { + 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", SIMPLIFY_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 { @@ -4853,6 +4876,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_session_heartbeat ::console::list_uuid"); switch_console_set_complete("add uuid_setvar_multi ::console::list_uuid"); switch_console_set_complete("add uuid_setvar ::console::list_uuid"); + switch_console_set_complete("add uuid_simplify ::console::list_uuid"); switch_console_set_complete("add uuid_transfer ::console::list_uuid"); switch_console_set_complete("add uuid_dual_transfer ::console::list_uuid"); switch_console_set_complete("add version"); From 972500fcc93f816e0a70fa7b64da6636607167e4 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 8 Dec 2010 12:36:26 -0500 Subject: [PATCH 007/146] return failure from make if build failed --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index aeb31eca01..e701494a2e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,6 +90,8 @@ $(RECURSIVE_TARGETS): fi; \ if test -z "$$fail" ; then \ cd $(top_builddir)/build && $(MAKE) $(AM_MAKEFLAGS) $$target || exit 1; \ + else \ + exit 1; \ fi ; CORE_CFLAGS = `$(switch_builddir)/libs/apr/apr-1-config --cflags --cppflags --includes` From 997151838426d4f2de8c6f81a836fd0323cad17d Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 8 Dec 2010 13:59:56 -0600 Subject: [PATCH 008/146] VS2010 add missing files freetdm --- .../mod_freetdm/mod_freetdm.2010.vcxproj | 217 ++++++++++++++++++ .../mod_freetdm.2010.vcxproj.filters | 14 ++ 2 files changed, 231 insertions(+) create mode 100644 libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj create mode 100644 libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj new file mode 100644 index 0000000000..ec69333410 --- /dev/null +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj @@ -0,0 +1,217 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_freetdm + {FE3540C5-3303-46E0-A69E-D92F775687F1} + mod_freetdm + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + false + + + $(OutDir)mod_freetdm.lib + MachineX86 + + + + + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + true + true + UseLinkTimeCodeGeneration + false + + + $(OutDir)mod_freetdm.lib + MachineX86 + + + + + X64 + + + Disabled + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + false + + + $(OutDir)mod_freetdm.lib + MachineX64 + + + + + X64 + + + ../../../src/include;../src/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + true + true + UseLinkTimeCodeGeneration + false + + + $(OutDir)mod_freetdm.lib + MachineX64 + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters new file mode 100644 index 0000000000..92ac5ead47 --- /dev/null +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2010.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file From 648a124c3f777bd79635ddf8e1d57b6c4c741cfc Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 15:12:10 -0500 Subject: [PATCH 009/146] freetdm: improve core flag command --- libs/freetdm/src/ftdm_io.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 758681fdd5..249d8580b5 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4073,7 +4073,7 @@ static struct { ftdm_io_interface_t *pika_interface; } interfaces; -static void print_channels_by_flag(ftdm_stream_handle_t *stream, uint32_t flag, int not, int *count) +static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval, int not, int *count) { ftdm_hash_iterator_t *i = NULL; ftdm_span_t *span; @@ -4082,6 +4082,7 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, uint32_t flag, ftdm_iterator_t *curr = NULL; const void *key = NULL; void *val = NULL; + uint32_t flag = (1 << flagval); *count = 0; @@ -4103,13 +4104,13 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, uint32_t flag, stream->write_function(stream, "[s%dc%d][%d:%d] has not flag %d\n", fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, - flag); + flagval); (*count)++; } else if (!not && ftdm_test_flag(fchan, flag)) { stream->write_function(stream, "[s%dc%d][%d:%d] has flag %d\n", fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, - flag); + flagval); (*count)++; } } @@ -4219,7 +4220,7 @@ static char *handle_core_command(const char *cmd) } flagval = atoi(flag); print_channels_by_flag(&stream, flagval, not, &count); - stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "without flag" : "with flag", flagval, count); + stream.write_function(&stream, "\nTotal channels %s %d: %d\n", not ? "without flag" : "with flag", flagval, count); } else { stream.write_function(&stream, "invalid core command %s\n", argv[0]); } From 14113f23b187bd1d25122544033b52c94d0ad905 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Wed, 8 Dec 2010 13:33:34 -0800 Subject: [PATCH 010/146] Update ChangeLog through Dec 7 --- docs/ChangeLog | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/ChangeLog b/docs/ChangeLog index 6037c14ec7..96066b6e8c 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -32,6 +32,7 @@ freeswitch (1.0.7) config: default example to resolve some issues with SCA in cases where host and ip are mixed causing the phone to be confused. (r:0279261b) 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) 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 @@ -134,6 +135,16 @@ freeswitch (1.0.7) core: Better handling of progress and answering to prevent sip profile from locking up at higher volumes (r:04e57577/FS-2801) core: ACL for IPv6 address and swigall to boot (r:db91f0e8/FS-2842) core: add intercept_unanswered_only var akin to intercept_unbridged_only (r:68f18efe) + core: switch_odbc_handle_exec_string duplication SQLExecute (r:8b0e7d24/FS-2880) + core: Fix timeout while bridge is waiting for CF_BRIDGED flag (r:2572621b/FS-2368) + core: don't parse events for b legs from a leg thread in case they are using a monolothic python script as a group_confirm exec over socket to send it messages while the call is ringing (r:ed5266d3) + core: add new function to check when messages need parsing to improve performance on parsing messages during originate (r:8b0421ff) + core: run execute_on_answer on_media _on_ring apps async (r:ef4a4ed0) + core: add switch_ivr_insert_file to insert one file into another at an arbitrary sample point (r:82394b37) + core: Slow reload cause calls to hang (r:1ba98b02/FS-2852) + 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) 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) @@ -151,6 +162,7 @@ freeswitch (1.0.7) libesl: Fix SEGV when using serialize function without any arguments (r:910729b5/ESL-44) 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) 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) @@ -189,7 +201,8 @@ freeswitch (1.0.7) mod_callcenter: Fix invalid update of agent field (r:426a448f/FS-2738) mod_callcenter: Allow to get queue info via api (r:70d592ae) mod_callcenter: Fix bad return type so it compile on archlinux, thx bougyman (r:3a475986) - mod_callcenter: Make callcenter_config agent get return the value of the item requested. Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x ammount of second before it kicked out of the queue rather than get rejected automaticly. (r:81a03869) + mod_callcenter: Make callcenter_config agent get return the value of the item requested. Also added queue param max-wait-time-with-no-agent-time-reached: If the max-wai-time-with-no-agent is already reached for the queue, then new caller can wait for x amount of second before it kicked out of the queue rather than get rejected automatically. (r:81a03869) + mod_callcenter: Add new event socket agent-offering. Plus some documentation and better handling of bad agent type -- FS-2869 (r:80174cf3/FS-2869) mod_cidlookup: null xml is bad (r:095815f8) mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53) mod_commands: make break uuid_break and add cascade flag @@ -205,6 +218,8 @@ freeswitch (1.0.7) mod_commands: ***BEHAVIOUR CHANGE*** reloadacl, load , reload will now explicitly call reloadxml (r:42c9df72) mod_commands: add nat_map usage (r:7577b8aa) 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_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 @@ -221,6 +236,8 @@ freeswitch (1.0.7) mod_dingaling: make dingaling work with google voice inbound too (r:4ee68141) mod_dingaling: Fix crash when testing the new gv-dingaling with around 24 concurrent calls (r:73e1ec5e/FSCORE-667) mod_dingaling: Fix NULL pointer (r:e3eff816/FS-1103) + mod_dingaling: fix leak in chat_send (r:eb109a85) + mod_dingaling: use the login as message source when not in component mode. (chat_send) (r:58c28aab) mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f) mod_distributor: Add mod_distributor to VS2010 - not built by default (r:bac79ba1) mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012) @@ -279,8 +296,10 @@ freeswitch (1.0.7) mod_freetdm: lock the channel when placing call (r:705dd237) mod_freetdm: created cmake files for freetdm (r:fc55997b) mod_freetdm: ss7 - added support to control mtp2, mtp3, and isup timers via freetdm.conf.xml (r:4455d581) + mod_freetdm: made ftmod_r2 use FTDM_SPAN_USE_SIGNALS_QUEUE and properly send FTDM_SIGEVENT_SIGSTATUS_CHANGED (r:af5f0a4a) mod_gsmopen: copy from branch mod_gsmopen: fix FS-2793, compilation stops (r:355c0dbb/FS-2793) + mod_gsmopen: retry serial initialization if failed, zeroing audio buffers, slower retry on soundcard busy (EAGAIN) (r:c7aefe93) mod_hash: free all hashtables on shutdown (r:e76d7d92) mod_hash: remove unneeded initializer (r:10d468a6) mod_hash: begin working on remote support (r:c5ad49da) @@ -324,6 +343,7 @@ freeswitch (1.0.7) mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0) mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165) mod_managed: add additional support (r:5be58aac) + mod_managed: add mono 2.8 patch file see FS-2774 (r:6a948bd9/FS-2774) mod_mp4v: MP4V-ES passthru for washibechi on IRC mod_mp4: New module. Supports playback of MP4 files. Depends on libmp4v2 (originally compiled against v1.6.1) mod_nibblebill: free allocated mem at shutdown; free properly if using custom_sql @@ -472,6 +492,14 @@ freeswitch (1.0.7) mod_sofia: fix missing name and potential segfault in gateway status (r:40ac860a) mod_sofia: Add missing RTP info for early SDP in bypass media (r:10119e9e/FS-2824) mod_sofia: add manual_rtp_bugs to profile and chan var and 3 new RTP bugs SEND_LINEAR_TIMESTAMPS|START_SEQ_AT_ZERO|NEVER_SEND_MARKER (r:b278dd23) + mod_sofia: apparently some sip device vendors did not read the RFC (who knew?) adding verbose_sdp=true var to add needless a= lines for standard iana codecs that explicitly do not require them (r:6c4f49a8) + mod_sofia: Fix registering a gateway, sofia always places a Via header with ext-sip-ip, even if this gateway is local (r:cf398e1a/FS-535) + mod_sofia: add presence-probe-on-register sofia param to send a probe on register instead of presence to deal with some broken phones and add some general improvements to allow multi homed presence (r:14394994) + mod_sofia: Fix issue when fs_path is used so we pick the correct media IP in our outbound invite this was soemthing that wouldn't work correctly over ATT on the iphone. (r:a669f76f) + mod_sofia: Default T38 Options (r:92f43440/FS-2892) + 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_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) @@ -508,6 +536,8 @@ freeswitch (1.0.7) mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62) mod_xml_rpc: Fix crash if unauthorized XML RPC is attempted (r:9835395c/FS-184) scripts: added honeypot.pl and blacklist.pl which add extra SIP security options (r:b6a81ba7) + scripts: do simple verification to make sure we are getting IP addresses from VoIP abuse blacklist (r:b0049160) + scripts: add_user - cmd line utility that lets admin create new users very easily. (r:ec8f2c2b) sofia-sip: fix null derefernce segfault in soa (r:f356c5e6) sofia-sip: extend timeout for session expires on short timeouts to be 90% of timeout instead of 1/3 to handle devices that do not refresh in time such as polycom (r:a7f48928/SFSIP-212) tools: Add fs_encode tool (r:89b17601) From 5aba96e382793c2c4440a658f7c1797b6c8c2809 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 8 Dec 2010 20:38:16 -0600 Subject: [PATCH 011/146] FS-2910 --- src/switch_odbc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/switch_odbc.c b/src/switch_odbc.c index a1c476e4a1..5a88ba7690 100644 --- a/src/switch_odbc.c +++ b/src/switch_odbc.c @@ -160,11 +160,6 @@ static int db_is_up(switch_odbc_handle_t *handle) strcpy((char *) sql, "select 1"); } - if (stmt) { - SQLFreeHandle(SQL_HANDLE_STMT, stmt); - stmt = NULL; - } - if (SQLAllocHandle(SQL_HANDLE_STMT, handle->con, &stmt) != SQL_SUCCESS) { code = __LINE__; goto error; @@ -229,6 +224,11 @@ static int db_is_up(switch_odbc_handle_t *handle) goto done; } + if (stmt) { + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + stmt = NULL; + } + switch_safe_free(err_str); switch_yield(1000000); goto top; From b02682bdbee84142708b4a8b97ca67ad4131ac9e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 22:55:43 -0500 Subject: [PATCH 012/146] 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 515e0ad175bbf5ec847669b3bd50fd46c9bdeea8 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 8 Dec 2010 23:04:29 -0500 Subject: [PATCH 013/146] freetdm: fix testsangomaboost --- libs/freetdm/src/testsangomaboost.c | 1 - 1 file changed, 1 deletion(-) 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 499eafb2e02f7d5359dc7d09aa635c7f4dbd3c69 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 9 Dec 2010 07:19:31 -0500 Subject: [PATCH 014/146] freetdm: check for dump enabled before writing to file --- libs/freetdm/src/ftdm_io.c | 19 +++++++++++++++++-- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 249d8580b5..ef290964d4 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -128,8 +128,15 @@ static void write_chan_io_dump(ftdm_io_dump_t *dump, char *dataptr, int dlen) static void dump_chan_io_to_file(ftdm_channel_t *fchan, ftdm_io_dump_t *dump, FILE *file) { /* write the saved audio buffer */ - size_t rc = 0; - size_t towrite = dump->size - dump->windex; + ftdm_size_t rc = 0; + ftdm_size_t towrite = 0; + + if (!dump->buffer) { + return; + } + + towrite = dump->size - dump->windex; + if (dump->wrapped) { rc = fwrite(&dump->buffer[dump->windex], 1, towrite, file); if (rc != towrite) { @@ -2821,6 +2828,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co if (!obj) { GOTO_STATUS(done, FTDM_FAIL); } + if (!ftdmchan->rxdump.buffer) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped input to file %p, input dump is not enabled\n", obj); + GOTO_STATUS(done, FTDM_FAIL); + } dump_chan_io_to_file(ftdmchan, &ftdmchan->rxdump, obj); ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Dumped input of size %d to file %p\n", ftdmchan->rxdump.size, obj); GOTO_STATUS(done, FTDM_SUCCESS); @@ -2833,6 +2844,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co if (!obj) { GOTO_STATUS(done, FTDM_FAIL); } + if (!ftdmchan->txdump.buffer) { + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Not dumped output to file %p, output dump is not enabled\n", obj); + 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); GOTO_STATUS(done, FTDM_SUCCESS); diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index ab85d2b4d6..37070c45a1 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -29,6 +29,11 @@ * 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: + * + * Arnaldo Pereira + * */ #ifdef __linux__ From 87bb33ae3a79c7c6abb61d3e7b74c84b3562f30e Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 08:44:55 -0600 Subject: [PATCH 015/146] 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 e680c821297c26530b118ab4ef77f030b1f6e365 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 08:59:06 -0600 Subject: [PATCH 016/146] 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 017/146] 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 018/146] 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 3c747978f4b1dc395846e90f613fbf2acb6324db Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 13:20:05 -0500 Subject: [PATCH 019/146] freetdm: support for call variables --- libs/freetdm/mod_freetdm/mod_freetdm.c | 42 +++-- libs/freetdm/src/ftdm_io.c | 129 ++++++++++++++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 31 +++- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 8 +- .../ftmod_sangoma_isdn_stack_hndl.c | 9 +- .../ftmod_sangoma_isdn_stack_out.c | 26 ++- .../ftmod_sangoma_isdn_support.c | 151 ++++++++++++++++-- .../ftmod_sangoma_ss7_handle.c | 4 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c | 42 ++--- libs/freetdm/src/include/freetdm.h | 57 ++++++- libs/freetdm/src/include/private/ftdm_core.h | 1 + 11 files changed, 428 insertions(+), 72 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 7ea6bb6d37..38197bb2f0 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -429,7 +429,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) 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); return SWITCH_STATUS_SUCCESS; } @@ -1329,7 +1329,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi char *v = h->name + FREETDM_VAR_PREFIX_LEN; if (!zstr(v)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id); - ftdm_channel_add_var(ftdmchan, v, h->value); + ftdm_call_add_var(&caller_data, v, h->value); } } } @@ -1528,6 +1528,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid); switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability); switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1); + if (globals.sip_headers) { switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel)); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid); @@ -1561,8 +1562,18 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session ftdm_channel_get_current_var(curr, &var_name, &var_value); snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); switch_channel_set_variable_printf(channel, name, "%s", var_value); + } + + /* Add any call variable to the dial plan */ + iter = ftdm_call_get_var_iterator(channel_caller_data, iter); + for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { + ftdm_call_get_current_var(curr, &var_name, &var_value); + snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); + switch_channel_set_variable_printf(channel, name, "%s", var_value); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s=%s\n", name, var_value); } ftdm_iterator_free(iter); + switch_channel_set_state(channel, CS_INIT); if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { @@ -1661,11 +1672,11 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) ftdm_status_t status; uint32_t spanid; uint32_t chanid; - ftdm_caller_data_t *callerdata; + ftdm_caller_data_t *caller_data; spanid = ftdm_channel_get_span_id(sigmsg->channel); chanid = ftdm_channel_get_id(sigmsg->channel); - callerdata = ftdm_channel_get_caller_data(sigmsg->channel); + caller_data = ftdm_channel_get_caller_data(sigmsg->channel); ftdm_log(FTDM_LOG_DEBUG, "got FXO sig %d:%d [%s]\n", spanid, chanid, ftdm_signal_event2str(sigmsg->event_id)); @@ -1688,7 +1699,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) switch_set_flag_locked(tech_pvt, TFLAG_DEAD); ftdm_channel_clear_token(sigmsg->channel, 0); channel = switch_core_session_get_channel(session); - switch_channel_hangup(channel, callerdata->hangup_cause); + switch_channel_hangup(channel, caller_data->hangup_cause); ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session)); switch_core_session_rwunlock(session); } @@ -1712,8 +1723,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) } } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; - + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + default: { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n", @@ -1767,7 +1778,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) } } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + case FTDM_SIGEVENT_STOP: { private_t *tech_pvt = NULL; @@ -1991,8 +2003,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_r2_signal) } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; - + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + /* on DNIS received from the R2 forward side, return status == FTDM_BREAK to stop requesting DNIS */ case FTDM_SIGEVENT_COLLECTED_DIGIT: { @@ -2104,14 +2116,14 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) switch(sigmsg->event_id) { case FTDM_SIGEVENT_START: { - ftdm_channel_add_var(sigmsg->channel, "screening_ind", ftdm_screening2str(caller_data->screen)); - ftdm_channel_add_var(sigmsg->channel, "presentation_ind", ftdm_presentation2str(caller_data->pres)); + ftdm_call_add_var(caller_data, "screening_ind", ftdm_screening2str(caller_data->screen)); + ftdm_call_add_var(caller_data, "presentation_ind", ftdm_presentation2str(caller_data->pres)); return ftdm_channel_from_event(sigmsg, &session); } break; - case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; - + case FTDM_SIGEVENT_RELEASED: { /* twiddle */ } break; + case FTDM_SIGEVENT_STOP: case FTDM_SIGEVENT_RESTART: { @@ -2176,7 +2188,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) } break; case FTDM_SIGEVENT_PROCEED: - case FTDM_SIGEVENT_MSG: + case FTDM_SIGEVENT_FACILITY: /* FS does not have handlers for these messages, so ignore them for now */ break; default: diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index ef290964d4..7355c8497c 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -61,6 +61,8 @@ struct tm *localtime_r(const time_t *clock, struct tm *result); 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 int time_is_init = 0; static void time_init(void) @@ -1893,7 +1895,9 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan) if (!ftdmchan->dtmf_off) { 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)) { @@ -2432,6 +2436,27 @@ done: return FTDM_SUCCESS; } +FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_sigmsg_t *sigmsg) +{ + ftdm_status_t status = FTDM_FAIL; + 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); + if (ftdmchan->span->send_msg) { + status = ftdmchan->span->send_msg(ftdmchan, sigmsg); + } else { + status = FTDM_NOTIMPL; + ftdm_log(FTDM_LOG_ERROR, "send_msg method not implemented in this span!\n"); + } + ftdm_channel_unlock(ftdmchan); + return status; +} + 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; @@ -3878,6 +3903,100 @@ done: return status; } +FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data) +{ + ftdm_call_clear_vars(caller_data); + memset(caller_data.raw_data, 0, sizeof(raw_data)); + caller_data->raw_data_len = 0; + return; +} + +FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data) +{ + if (caller_data->variables) { + hashtable_destroy(caller_data->variables); + } + caller_data->variables = NULL; + return FTDM_SUCCESS; +} + +FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name) +{ + if (caller_data->variables) { + hashtable_remove(caller_data->variables, (void *)var_name); + } + + return FTDM_SUCCESS; +} + + +FT_DECLARE(ftdm_status_t) ftdm_call_add_var(ftdm_caller_data_t *caller_data, const char *var_name, const char *value) +{ + char *t_name = 0, *t_val = 0; + + if (!var_name || !value) { + return FTDM_FAIL; + } + + if (!caller_data->variables) { + /* initialize on first use */ + caller_data->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); + ftdm_assert_return(caller_data->variables, FTDM_FAIL, "Failed to create hash table\n"); + } + + t_name = ftdm_strdup(var_name); + t_val = ftdm_strdup(value); + hashtable_insert(caller_data->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); + return FTDM_SUCCESS; +} + +FT_DECLARE(const char *) ftdm_call_get_var(ftdm_caller_data_t *caller_data, const char *var_name) +{ + const char *var = NULL; + + if (!caller_data->variables || !var_name) { + return NULL; + } + + var = (const char *)hashtable_search(((struct hashtable*)caller_data->variables), (void *)var_name); + return var; +} + +FT_DECLARE(ftdm_iterator_t *) ftdm_call_get_var_iterator(const ftdm_caller_data_t *caller_data, ftdm_iterator_t *iter) +{ + ftdm_hash_iterator_t *hashiter = NULL; + hashiter = caller_data->variables == NULL ? NULL : hashtable_first(caller_data->variables); + + if (hashiter == NULL) { + return NULL; + } + + if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) { + return NULL; + } + iter->pvt.hashiter = hashiter; + return iter; +} + +FT_DECLARE(ftdm_status_t) ftdm_call_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val) +{ + const void *key = NULL; + void *val = NULL; + + *var_name = NULL; + *var_val = NULL; + + ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_VARS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); + + hashtable_this(iter->pvt.hashiter, &key, NULL, &val); + + *var_name = key; + *var_val = val; + + return FTDM_SUCCESS; +} + + static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan) { ftdm_channel_lock(ftdmchan); @@ -3924,6 +4043,7 @@ done: return status; } + FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name) { const char *var = NULL; @@ -5157,7 +5277,11 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { - return span->signal_cb(sigmsg); + ftdm_status_t status = span->signal_cb(sigmsg); + if (sigmsg->channel) { + ftdm_call_clear_data(&(sigmsg->channel->caller_data)); + } + return status; } static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) @@ -5261,6 +5385,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t } done: + if (sigmsg->channel) { ftdm_mutex_unlock(sigmsg->channel->mutex); } 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 03b5a5fb1d..96f1a2b430 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 @@ -626,8 +626,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_GET_CALLERID: { if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { + /* By default, we do not send a progress indicator in the proceed */ + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; + sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); - sngisdn_snd_proceed(ftdmchan); + sngisdn_snd_proceed(ftdmchan, prog_ind); } /* Wait in this state until we get FACILITY msg */ } @@ -666,8 +669,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) ftdm_span_send_signal(ftdmchan->span, &sigev); } else { if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { + /* By default, we do not send a progress indicator in the proceed */ + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; + sngisdn_set_flag(sngisdn_info, FLAG_SENT_PROCEED); - sngisdn_snd_proceed(ftdmchan); + sngisdn_snd_proceed(ftdmchan, prog_ind); } } } @@ -851,6 +857,26 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) return; } +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; + default: + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unsupported signalling msg requested\n"); + status = FTDM_BREAK; + } + ftdm_call_clear_data(&ftdmchan->caller_data); + return status; +} + static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call) { sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; @@ -1030,6 +1056,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) span->stop = ftdm_sangoma_isdn_stop; span->signal_type = FTDM_SIGTYPE_ISDN; span->outgoing_call = ftdm_sangoma_isdn_outgoing_call; + span->send_msg = ftdm_sangoma_isdn_send_msg; span->channel_request = NULL; span->signal_cb = sig_cb; span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status; 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 b9ab3395ae..f15eff9200 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 @@ -363,7 +363,7 @@ void stack_pst_init(Pst *pst); /* Outbound Call Control functions */ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan); void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan); -void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan); +void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind); void sngisdn_snd_connect(ftdm_channel_t *ftdmchan); @@ -436,6 +436,7 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...); void sngisdn_rcv_sng_assert(char *message); ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); +ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb); ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display); @@ -443,16 +444,17 @@ ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *us ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad); ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd); ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); -ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len); +ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len); ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); +ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); 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_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); -ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len); +ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len); uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability); 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 086354a993..cb9f6d33e1 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 @@ -123,12 +123,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) break; } -#if 0 - /* Export ftdmchan variables here if we need to */ - ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); -#endif /* Fill in call information */ get_calling_num(ftdmchan, &conEvnt->cgPtyNmb); + get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2); get_called_num(ftdmchan, &conEvnt->cdPtyNmb); get_redir_num(ftdmchan, &conEvnt->redirNmb); get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad); @@ -757,14 +754,14 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) { ftdm_sigmsg_t sigev; if (facEvnt->facElmt.facStr.pres) { - get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len); + get_facility_ie_str(ftdmchan, &facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len-2); } memset(&sigev, 0, sizeof(sigev)); sigev.chan_id = ftdmchan->chan_id; sigev.span_id = ftdmchan->span_id; sigev.channel = ftdmchan; - sigev.event_id = FTDM_SIGEVENT_MSG; + sigev.event_id = FTDM_SIGEVENT_FACILITY; ftdm_span_send_signal(ftdmchan->span, &sigev); } break; 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 38bbdb6968..297c59c3b7 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 @@ -128,6 +128,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) set_called_num(ftdmchan, &conEvnt.cdPtyNmb); set_calling_num(ftdmchan, &conEvnt.cgPtyNmb); + set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2); set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad); set_redir_num(ftdmchan, &conEvnt.redirNmb); set_calling_name(ftdmchan, &conEvnt); @@ -262,10 +263,9 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan) } -void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan) +void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind) { CnStEvnt cnStEvnt; - sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; @@ -310,7 +310,9 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan) cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; } + 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); @@ -343,6 +345,7 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ memset(&cnStEvnt, 0, sizeof(cnStEvnt)); 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 PROGRESS (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); if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) { @@ -369,6 +372,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind 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 ALERT (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); @@ -428,6 +432,7 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) 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 CONNECT (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); if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { @@ -450,10 +455,17 @@ void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan) memset(&facEvnt, 0, sizeof(facEvnt)); - set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (ftdm_size_t*)&facEvnt.facElmt.facStr.len); + if (set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (uint8_t*)&facEvnt.facElmt.facStr.len) != FTDM_SUCCESS) { + /* No point in sending a FACILITY message if there is no Facility IE to transmit */ + return; + } + ftdm_call_clear_data(&ftdmchan->caller_data); + facEvnt.facElmt.eh.pres = PRSNT_NODEF; + facEvnt.facElmt.facStr.pres = PRSNT_NODEF; facEvnt.facElmt.facStr.val[0] = 0x1C; - facEvnt.facElmt.facStr.val[1] = facEvnt.facElmt.facStr.len; + facEvnt.facElmt.facStr.val[1] = (uint8_t)facEvnt.facElmt.facStr.len; + facEvnt.facElmt.facStr.len +=2; /* Need to include the size of identifier + len */ ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (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); @@ -481,6 +493,8 @@ void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan) //ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ\n"); + ftdm_call_clear_data(&ftdmchan->caller_data); + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, signal_data->dchan_id, sngisdn_info->ces)) { @@ -501,6 +515,8 @@ void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan) memset(&staEvnt, 0, sizeof(StaEvnt)); + ftdm_call_clear_data(&ftdmchan->caller_data); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Status ENQ request\n"); @@ -539,6 +555,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan) discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT; set_facility_ie(ftdmchan, &discEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) { @@ -585,6 +602,7 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare) } set_facility_ie(ftdmchan, &relEvnt.facilityStr); + ftdm_call_clear_data(&ftdmchan->caller_data); ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId); 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 fae25c9ad6..76d11d6d34 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 @@ -185,6 +185,39 @@ ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) return FTDM_SUCCESS; } +ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) +{ + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + if (cgPtyNmb->eh.pres != PRSNT_NODEF) { + return FTDM_FAIL; + } + + if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.screen_ind", ftdm_screening2str(cgPtyNmb->screenInd.val)); + } + + if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.presentation_ind", ftdm_presentation2str(cgPtyNmb->presInd0.val)); + } + + if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.npi", ftdm_npi2str(cgPtyNmb->nmbPlanId.val)); + } + + if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) { + ftdm_call_add_var(caller_data, "isdn.cg_pty2.ton", ftdm_ton2str(cgPtyNmb->typeNmb1.val)); + } + + if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) { + char digits_string [32]; + memcpy(digits_string, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len); + digits_string[cgPtyNmb->nmbDigits.len] = '\0'; + ftdm_call_add_var(caller_data, "isdn.cg_pty2.digits", digits_string); + } + memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani)); + return FTDM_SUCCESS; +} + ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; @@ -278,7 +311,7 @@ ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len); subaddress[cgPtySad->sadInfo.len] = '\0'; - ftdm_channel_add_var(ftdmchan, "isdn.calling_subaddr", subaddress); + ftdm_call_add_var(&ftdmchan->caller_data, "isdn.calling_subaddr", subaddress); return FTDM_SUCCESS; } @@ -291,17 +324,16 @@ ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len); } -ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t data_len) +ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) { - if (data_len > sizeof(caller_data->raw_data)-2) { - ftdm_log(FTDM_LOG_CRIT, "Length of Facility IE exceeds maximum length\n"); - return FTDM_FAIL; - } - + /* size of facilityStr->facilityStr.len is a uint8_t so no need to check + for overflow here as facilityStr->facilityStr.len will always be smaller + than sizeof(caller_data->raw_data) */ + memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data)); /* Always include Facility IE identifier + len so this can be used as a sanity check by the user */ caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID; @@ -348,7 +380,7 @@ ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd) val = SNGISDN_PROGIND_DESCR_INVALID; break; } - ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val)); + ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val)); } if (progInd->location.pres) { @@ -379,7 +411,7 @@ ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd) val = SNGISDN_PROGIND_LOC_INVALID; break; } - ftdm_channel_add_var(ftdmchan, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val)); + ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val)); } return FTDM_SUCCESS; } @@ -423,6 +455,89 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) return FTDM_SUCCESS; } +ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) +{ + const char* string = NULL; + uint8_t len,val; + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.digits"); + if ((string == NULL) || !(*string)) { + return FTDM_FAIL; + } + + cgPtyNmb->eh.pres = PRSNT_NODEF; + + len = strlen(string); + cgPtyNmb->nmbDigits.len = len; + + cgPtyNmb->nmbDigits.pres = PRSNT_NODEF; + memcpy(cgPtyNmb->nmbDigits.val, string, len); + + /* Screening Indicator */ + cgPtyNmb->screenInd.pres = PRSNT_NODEF; + + val = FTDM_SCREENING_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.screening_ind"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_screening(string); + } + + /* isdn.cg_pty2.screen_ind does not exist or we could not parse its value */ + if (val == FTDM_SCREENING_INVALID) { + /* default to caller data screening ind */ + cgPtyNmb->screenInd.val = caller_data->screen; + } else { + cgPtyNmb->screenInd.val = val; + } + + /* Presentation Indicator */ + cgPtyNmb->presInd0.pres = PRSNT_NODEF; + + val = FTDM_PRES_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.presentation_ind"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_presentation(string); + } + + if (val == FTDM_PRES_INVALID) { + cgPtyNmb->presInd0.val = caller_data->pres; + } else { + cgPtyNmb->presInd0.val = val; + } + + /* Numbering Plan Indicator */ + cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF; + + val = FTDM_NPI_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.npi"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_npi(string); + } + + if (val == FTDM_NPI_INVALID) { + cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan; + } else { + cgPtyNmb->nmbPlanId.val = val; + } + + cgPtyNmb->typeNmb1.pres = PRSNT_NODEF; + + /* Type of Number */ + val = FTDM_TON_INVALID; + string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.ton"); + if ((string != NULL) && (*string)) { + val = ftdm_str2ftdm_ton(string); + } + + if (val == FTDM_TON_INVALID) { + cgPtyNmb->typeNmb1.val = caller_data->cid_num.type; + } else { + cgPtyNmb->typeNmb1.val = val; + } + return FTDM_SUCCESS; +} + ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; @@ -544,7 +659,7 @@ ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt) ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) { const char* clg_subaddr = NULL; - clg_subaddr = ftdm_channel_get_var(ftdmchan, "isdn.calling_subaddr"); + clg_subaddr = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.calling_subaddr"); if ((clg_subaddr != NULL) && (*clg_subaddr)) { unsigned len = strlen (clg_subaddr); cgPtySad->eh.pres = PRSNT_NODEF; @@ -565,7 +680,7 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad) ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr) { ftdm_status_t status; - status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (ftdm_size_t*)&facilityStr->facilityStr.len); + status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (uint8_t*)&(facilityStr->facilityStr.len)); if (status == FTDM_SUCCESS) { facilityStr->eh.pres = PRSNT_NODEF; facilityStr->facilityStr.pres = PRSNT_NODEF; @@ -573,13 +688,15 @@ ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr return status; } -ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, ftdm_size_t *data_len) +ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len) { + int len; ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) { - *data_len = caller_data->raw_data[1]; - memcpy(data, &caller_data->raw_data[2], *data_len); + len = caller_data->raw_data[1]; + memcpy(data, &caller_data->raw_data[2], len); + *data_len = len; return FTDM_SUCCESS; } return FTDM_FAIL; @@ -591,7 +708,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s int descr = prog_ind.descr; int loc = prog_ind.loc; - str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.descr"); + str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.descr"); if (str && *str) { /* User wants to override progress indicator */ descr = ftdm_str2ftdm_sngisdn_progind_descr(str); @@ -602,8 +719,8 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s return FTDM_SUCCESS; } - str = ftdm_channel_get_var(ftdmchan, "isdn.prog_ind.loc"); - if (str && *str) { + str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.loc"); + if (str && *str) { loc = ftdm_str2ftdm_sngisdn_progind_loc(str); } if (loc == SNGISDN_PROGIND_LOC_INVALID) { 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 72e4bacf52..7517ee42a0 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 @@ -211,10 +211,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* add any special variables for the dialplan */ sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val); - ftdm_channel_add_var(ftdmchan, "ss7_clg_nadi", nadi); + ftdm_call_add_var(&ftdmchan->caller_data, "ss7_clg_nadi", nadi); sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val); - ftdm_channel_add_var(ftdmchan, "ss7_cld_nadi", nadi); + ftdm_call_add_var(&ftdmchan->caller_data, "ss7_cld_nadi", nadi); /* check if a COT test is requested */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 008265b9a4..ec8d7df12a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -187,7 +187,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); /* check if the user would like a custom NADI value for the calling Pty Num */ - clg_nadi = ftdm_channel_get_var(ftdmchan, "ss7_clg_nadi"); + clg_nadi = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_clg_nadi"); if ((clg_nadi != NULL) && (*clg_nadi)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi); iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi); @@ -196,7 +196,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val); } - cld_nadi = ftdm_channel_get_var(ftdmchan, "ss7_cld_nadi"); + cld_nadi = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_cld_nadi"); if ((cld_nadi != NULL) && (*cld_nadi)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi); iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi); @@ -206,7 +206,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) } /* check if the user would like us to send a clg_sub-address */ - clg_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_clg_subaddr"); + clg_subAddr = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_clg_subaddr"); if ((clg_subAddr != NULL) && (*clg_subAddr)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr); @@ -245,7 +245,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) } /* check if the user would like us to send a cld_sub-address */ - cld_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_cld_subaddr"); + cld_subAddr = ftdm_call_get_var(&ftdmchan->caller_data, "ss7_cld_subaddr"); if ((cld_subAddr != NULL) && (*cld_subAddr)) { SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr); @@ -298,7 +298,8 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.cgPtyNum.natAddrInd.val, ftdmchan->caller_data.dnis.digits, iam.cdPtyNum.natAddrInd.val); - + + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -379,7 +380,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) ADDRCMPLT); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -403,7 +404,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) 5); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -438,7 +439,7 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n", sngss7_info->circuit->cic, ftdmchan->caller_data.hangup_cause ); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -461,7 +462,7 @@ void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan) &rlc); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -482,7 +483,7 @@ void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -503,7 +504,7 @@ void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -524,7 +525,7 @@ void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -545,7 +546,7 @@ void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -567,7 +568,7 @@ ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -588,7 +589,7 @@ void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -609,7 +610,7 @@ void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan) NULL); SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -654,6 +655,7 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan) sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->rx_grs.range)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -686,7 +688,8 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_grs.range)); - + + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -735,7 +738,7 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t)); - + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -785,6 +788,7 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -835,6 +839,7 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -885,6 +890,7 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan) /* clean out the saved data */ memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t)); + ftdm_call_clear_vars(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 41e7f50ed8..4ee6ff5f52 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -272,6 +272,8 @@ typedef struct { 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 */ @@ -286,12 +288,13 @@ typedef struct ftdm_caller_data { char collected[25]; /*!< 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 */ + uint32_t raw_data_len; /*!< Raw data length */ /* these 2 are undocumented right now, only used by boost: */ /* bearer capability */ ftdm_bearer_cap_t bearer_capability; /* user information layer 1 protocol */ ftdm_user_layer1_prot_t bearer_layer1; + ftdm_variable_container_t variables; /*!variables and caller_data->raw_data. + * */ +FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data); + /*! \brief Get the span pointer associated to the channel */ FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan); diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index a1e1c02439..deabafd537 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -503,6 +503,7 @@ struct ftdm_span { teletone_multi_tone_t tone_finder[FTDM_TONEMAP_INVALID+1]; ftdm_channel_t *channels[FTDM_MAX_CHANNELS_SPAN+1]; fio_channel_outgoing_call_t outgoing_call; + fio_channel_send_msg_t send_msg; fio_channel_set_sig_status_t set_channel_sig_status; fio_channel_get_sig_status_t get_channel_sig_status; fio_span_set_sig_status_t set_span_sig_status; From 5ab19aaa23dac4771baadd1f2a2b874c8c630154 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 13:47:40 -0500 Subject: [PATCH 020/146] freetdm: fix compilation --- 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 7355c8497c..605f13c0bc 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -3906,7 +3906,7 @@ done: FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data) { ftdm_call_clear_vars(caller_data); - memset(caller_data.raw_data, 0, sizeof(raw_data)); + memset(&caller_data->raw_data, 0, sizeof(caller_data->raw_data)); caller_data->raw_data_len = 0; return; } From 8016813234b471e5636bcff963f5a4ed3391d972 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 14:03:09 -0600 Subject: [PATCH 021/146] 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 022/146] 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 fced79a4933560500a5710af3c48019da700948b Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 17:13:34 -0500 Subject: [PATCH 023/146] fix not handling disconnect when in RINGING state --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 6 ++++++ 1 file changed, 6 insertions(+) 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 cb9f6d33e1..fb65d20cab 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 @@ -407,6 +407,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) } break; case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: @@ -447,6 +448,7 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event) ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: @@ -537,6 +539,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_UP: case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: /* If we previously had a glare on this channel, this RELEASE could be for the previous call. Confirm whether call_data has not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */ @@ -881,6 +884,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n"); sngisdn_snd_disconnect(ftdmchan); @@ -899,6 +903,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_RINGING: /* T310 timer has expired */ ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val; ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n"); @@ -935,6 +940,7 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; case 9: /* Remote switch is in "Incoming call proceeding" state */ switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_GET_CALLERID: From 86c484c134ca46edd572c3b46c6480ac9011292b Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 9 Dec 2010 18:01:31 -0500 Subject: [PATCH 024/146] freetdm: added support for skip states, used by sangoma_isdn module --- libs/freetdm/src/ftdm_io.c | 40 +++++++++---------- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 1 + libs/freetdm/src/include/private/ftdm_types.h | 3 ++ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 605f13c0bc..eaa25e3da5 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2213,31 +2213,31 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char goto done; } -#ifndef FREETDM_SKIP_SIG_STATES - /* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn - * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so - * remove this only in netborder branch for now while we update the sig modules */ + if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) { + /* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn + * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so + * use FTDM_SPAN_USE_SKIP_STATESfor now while we update the sig modules */ - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1); - } + 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; + } - if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); - } + if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 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 UP\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 UP\n"); + goto done; + } } -#endif ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1); done: 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 96f1a2b430..e20d3ae7e0 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 @@ -1067,6 +1067,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE); + ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES); if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || span->trunk_type == FTDM_TRUNK_BRI) { diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index df747021b2..313044abc4 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -184,6 +184,9 @@ typedef enum { FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10), /* If this flag is set, channel will be moved to proceed state when calls goes to routing */ FTDM_SPAN_USE_PROCEED_STATE = (1 << 11), + /* If this flag is set, the signalling module supports jumping directly to state up, without + going through PROGRESS/PROGRESS_MEDIA */ + FTDM_SPAN_USE_SKIP_STATES = (1 << 12), } ftdm_span_flag_t; /*! \brief Channel supported features */ From 3406d05ba7fafb8e20f69bede72db3564bf8b198 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 9 Dec 2010 23:05:49 -0600 Subject: [PATCH 025/146] 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 002181e143e5c56c554abeeb37c7611dcdad8536 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Dec 2010 06:52:04 -0500 Subject: [PATCH 026/146] freetdm: fix serious mem leak in R2 module iterator usage --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 34 ++++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 37070c45a1..e95a74bc25 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1644,6 +1644,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) int index = 0; struct timeval start, end; ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *citer = NULL; uint32_t txqueue_size = 4; short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count); @@ -1654,8 +1655,12 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_log(FTDM_LOG_DEBUG, "OpenR2 monitor thread %lu started.\n", r2data->monitor_thread_id); r2chan = NULL; chaniter = ftdm_span_get_chan_iterator(span, NULL); - for (i = 1; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) { - ftdmchan = ftdm_iterator_current(chaniter); + if (!chaniter) { + ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); + goto done; + } + for (i = 1, citer = chaniter; citer; citer = ftdm_iterator_next(citer), i++) { + ftdmchan = ftdm_iterator_current(citer); r2chan = R2CALL(ftdmchan)->r2chan; openr2_chan_set_span_id(r2chan, span->span_id); openr2_chan_set_idle(r2chan); @@ -1694,9 +1699,13 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) /* 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); - chaniter = ftdm_span_get_chan_iterator(span, chaniter); - for (i = 0; chaniter; chaniter = ftdm_iterator_next(chaniter), i++) { - ftdmchan = ftdm_iterator_current(chaniter); + citer = ftdm_span_get_chan_iterator(span, chaniter); + if (!citer) { + ftdm_log(FTDM_LOG_CRIT, "Failed to allocate channel iterator for span %s!\n", span->name); + goto done; + } + for (i = 0; citer; citer = ftdm_iterator_next(citer), i++) { + ftdmchan = ftdm_iterator_current(citer); r2chan = R2CALL(ftdmchan)->r2chan; poll_events[i] = POLLPRI; if (openr2_chan_get_read_enabled(r2chan)) { @@ -1737,9 +1746,9 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) /* this main loop takes care of MF and CAS signaling during call setup and tear down * for every single channel in the span, do not perform blocking operations here! */ - chaniter = ftdm_span_get_chan_iterator(span, chaniter); - for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) { - ftdmchan = ftdm_iterator_current(chaniter); + citer = ftdm_span_get_chan_iterator(span, chaniter); + for ( ; citer; citer = ftdm_iterator_next(citer)) { + ftdmchan = ftdm_iterator_current(citer); ftdm_mutex_lock(ftdmchan->mutex); @@ -1766,10 +1775,11 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj) ftdm_mutex_unlock(ftdmchan->mutex); } } - - chaniter = ftdm_span_get_chan_iterator(span, chaniter); - for ( ; chaniter; chaniter = ftdm_iterator_next(chaniter)) { - ftdmchan = ftdm_iterator_current(chaniter); + +done: + citer = ftdm_span_get_chan_iterator(span, chaniter); + for ( ; citer; citer = ftdm_iterator_next(citer)) { + ftdmchan = ftdm_iterator_current(citer); r2chan = R2CALL(ftdmchan)->r2chan; openr2_chan_set_blocked(r2chan); } From 8c057921f3e5c889cd148e461ffb67932dd78fbb Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Dec 2010 08:32:36 -0500 Subject: [PATCH 027/146] ftmod_wanpipe - fix idle frame stats --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 1c0baa731f..e1b6658945 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -811,13 +811,14 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t ftdm_clear_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL); } - if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_number_of_frames_in_queue) { - ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets; + if (ftdmchan->iostats.tx.idle_packets < tx_stats->wp_api_tx_hdr_tx_idle_packets) { /* HDLC channels do not always transmit, so its ok for drivers to fill with idle * also do not report idle warning when we just started transmitting */ if (ftdmchan->iostats.tx.packets && FTDM_IS_VOICE_CHANNEL(ftdmchan)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle: %d\n", ftdmchan->iostats.tx.idle_packets); + ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle changed from %d to %d\n", + ftdmchan->iostats.tx.idle_packets, tx_stats->wp_api_tx_hdr_tx_idle_packets); } + ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets; } if (!ftdmchan->iostats.tx.packets) { @@ -941,7 +942,6 @@ static FIO_WRITE_FUNCTION(wanpipe_write) { int bsent = 0; int err = 0; - ftdm_time_t ms = 0; wp_tdm_api_tx_hdr_t hdrframe; /* Do we even need the headerframe here? on windows, we don't even pass it to the driver */ From e96d8f163012d52314a966128dc9f63cc2430538 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 10 Dec 2010 13:42:47 -0500 Subject: [PATCH 028/146] freetdm: fix windows warning in ftmod_r2 --- 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 e95a74bc25..d1a46d8f1d 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -900,7 +900,7 @@ static int ftdm_r2_io_write(openr2_chan_t *r2chan, const void *buf, int size) if (FTDM_FAIL == status) { return -1; } - return outsize; + return (int)outsize; } static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size) @@ -911,7 +911,7 @@ static int ftdm_r2_io_read(openr2_chan_t *r2chan, const void *buf, int size) if (FTDM_FAIL == status) { return -1; } - return outsize; + return (int)outsize; } static int ftdm_r2_io_wait(openr2_chan_t *r2chan, int *flags, int block) From 98ed05cc9800c205389b0f286afddea923cab757 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Fri, 10 Dec 2010 14:30:47 -0500 Subject: [PATCH 029/146] 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 030/146] 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 666e9fc2c652ffac2c13a2959ee04f9bd34d5082 Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Fri, 10 Dec 2010 18:48:04 -0200 Subject: [PATCH 031/146] freetdm: ftmod_r2 - reject collect calls when allow_collect_calls isn't true --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 9 ++++++++- 1 file changed, 8 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 d1a46d8f1d..7439ddd3d7 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -515,13 +515,20 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Call offered with ANI = %s, DNIS = %s, Category = (%d)\n", ani, dnis, category); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); /* 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); } + + /* check if this is a collect call and if we should accept it */ + if (!r2data->allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Rejecting collect call\n"); + openr2_chan_disconnect_call(r2chan, OR2_CAUSE_COLLECT_CALL_REJECTED); + } else { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); + } } /* From 6fdba3452a737d0385085ad7abe89b299d6f301c Mon Sep 17 00:00:00 2001 From: Konrad Hammel Date: Wed, 8 Dec 2010 17:32:52 -0500 Subject: [PATCH 032/146] freetdm: ss7 - added suport for per isup interface min_digits ss7 - fixed strcpy bugs and compile warnings --- .../ftmod_sangoma_ss7_main.c | 11 ++--- .../ftmod_sangoma_ss7_main.h | 4 +- .../ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c | 46 +++++++++++++------ 3 files changed, 40 insertions(+), 21 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 304e9d6ce3..5c171a9f6b 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 @@ -502,6 +502,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_COLLECT: /* IAM received but wating on digits */ + isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; + if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); break; @@ -521,8 +523,8 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); - } else if (i >= g_ftdm_sngss7_data.min_digits) { - SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, g_ftdm_sngss7_data.min_digits); + } else if (i >= isup_intf->min_digits) { + SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, isup_intf->min_digits); /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); @@ -532,7 +534,7 @@ void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) { SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n", i, - g_ftdm_sngss7_data.min_digits, + isup_intf->min_digits, ftdmchan->caller_data.dnis.digits); /* start ISUP t35 */ @@ -1520,9 +1522,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) /* initalize the global gen_config flag */ g_ftdm_sngss7_data.gen_config = 0; - /* min. number of digitis to wait for */ - g_ftdm_sngss7_data.min_digits = 7; - /* function trace initizalation */ g_ftdm_sngss7_data.function_trace = 1; g_ftdm_sngss7_data.function_trace_level = 7; 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 378b50e0ad..fe4b6f45c4 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 @@ -50,7 +50,7 @@ /******************************************************************************/ /* DEFINES ********************************************************************/ -#define MAX_NAME_LEN 10 +#define MAX_NAME_LEN 25 #define MAX_PATH 255 #define MAX_CIC_LENGTH 5 @@ -224,6 +224,7 @@ typedef struct sng_isup_intf { uint32_t isap; uint32_t clg_nadi; uint32_t cld_nadi; + uint32_t min_digits; uint16_t t4; uint32_t t10; uint32_t t11; @@ -326,7 +327,6 @@ typedef struct sng_ss7_cfg { typedef struct ftdm_sngss7_data { sng_ss7_cfg_t cfg; int gen_config; - int min_digits; int function_trace; int function_trace_level; int message_trace; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index 8a24f971ed..d4fd1ca9b3 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -142,7 +142,7 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa if (!strcasecmp(var, "ch_map")) { /**********************************************************************/ - strcpy(isupCkt.ch_map, val); + strncpy(isupCkt.ch_map, val, MAX_CIC_MAP_LENGTH-1); SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map); /**********************************************************************/ } else if (!strcasecmp(var, "typeCntrl")) { @@ -393,7 +393,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) for (i = 0; i < num_parms; i++) { /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strcpy((char *)mtpLinkSet.name, parm->val); + strncpy((char *)mtpLinkSet.name, parm->val, MAX_NAME_LEN-1); SS7_DEBUG("\tFound an \"mtp_linkset\" named = %s\n", mtpLinkSet.name); /**********************************************************************/ } else if (!strcasecmp(parm->var, "apc")) { @@ -508,7 +508,7 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t * /* try to match the parameter to what we expect */ /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strcpy((char *)mtpLink->name, parm->val); + strncpy((char *)mtpLink->name, parm->val, MAX_NAME_LEN-1); SS7_DEBUG("\tFound an \"mtp_link\" named = %s\n", mtpLink->name); /**********************************************************************/ } else if (!strcasecmp(parm->var, "span")) { @@ -827,7 +827,7 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) /* try to match the parameter to what we expect */ /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strcpy((char *)mtpRoute.name, parm->val); + strncpy((char *)mtpRoute.name, parm->val, MAX_NAME_LEN-1); SS7_DEBUG("\tFound an \"mtp_route\" named = %s\n", mtpRoute.name); /**********************************************************************/ } else if (!strcasecmp(parm->var, "dpc")) { @@ -999,7 +999,7 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) /* try to match the parameter to what we expect */ /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strcpy((char *)sng_isup.name, parm->val); + strncpy((char *)sng_isup.name, parm->val, MAX_NAME_LEN-1); SS7_DEBUG("\tFound an \"isup_interface\" named = %s\n", sng_isup.name); /**********************************************************************/ } else if (!strcasecmp(parm->var, "spc")) { @@ -1047,6 +1047,11 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) SS7_DEBUG("\tFound MTP3 Route = %s\n", parm->val); } /**********************************************************************/ + } else if (!strcasecmp(parm->var, "min_digits")) { + sng_isup.min_digits = atoi(parm->val); + + SS7_DEBUG("\tFound min_digits = %d\n", sng_isup.min_digits); + /**********************************************************************/ } else if (!strcasecmp(parm->var, "ssf")) { if (!strcasecmp(parm->val, "nat")) { sng_isup.ssf = SSF_NAT; @@ -1067,8 +1072,8 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) /**********************************************************************/ } else if (!strcasecmp(parm->var, "license")) { /**********************************************************************/ - strcpy(g_ftdm_sngss7_data.cfg.license, parm->val); - strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val); + strncpy(g_ftdm_sngss7_data.cfg.license, parm->val, MAX_PATH-1); + strncpy(g_ftdm_sngss7_data.cfg.signature, parm->val, MAX_PATH-1); strcat(g_ftdm_sngss7_data.cfg.signature, ".sig"); SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license); SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature); @@ -1304,6 +1309,13 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) sng_isup.clg_nadi = 0x03; } + /* check if the user requested min_digits value */ + if (sng_isup.min_digits == 0) { + /* default to 7 */ + sng_isup.min_digits = 7; + } + + /* trickle down the SPC to all sub entities */ linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId; @@ -1359,7 +1371,7 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) } /* fill in the information */ - strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name); + strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name, MAX_NAME_LEN-1); g_ftdm_sngss7_data.cfg.mtpLink[i].id = mtpLink->id; @@ -1521,7 +1533,7 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) { int i = mtpLinkSet->id; - strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name); + strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name, MAX_NAME_LEN-1); g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc; @@ -1559,7 +1571,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) SS7_DEBUG("found existing mtp3_route, id is = %d\n", mtp3_route->id); } - strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name); + strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name, MAX_NAME_LEN-1); g_ftdm_sngss7_data.cfg.mtpRoute[i].id = mtp3_route->id; g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc; @@ -1693,7 +1705,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) SS7_DEBUG("found existing isup interface, id is = %d\n", sng_isup->id); } - strcpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name); + strncpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name, MAX_NAME_LEN-1); g_ftdm_sngss7_data.cfg.isupIntf[i].id = sng_isup->id; g_ftdm_sngss7_data.cfg.isupIntf[i].mtpRouteId = sng_isup->mtpRouteId; @@ -1705,6 +1717,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap; g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi; g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi; + g_ftdm_sngss7_data.cfg.isupIntf[i].min_digits = sng_isup->min_digits; g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options; if (sng_isup->t4 != 0) { g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4; @@ -1976,7 +1989,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i return FTDM_FAIL; } - strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-rt"); + strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[0].name, "self-route", MAX_NAME_LEN-1); g_ftdm_sngss7_data.cfg.mtpRoute[0].id = 0; g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc = spc; @@ -2230,7 +2243,7 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot) int lower; int upper; char tmp[5]; /*KONRAD FIX ME*/ - char new_ch_map[MAX_CIC_LENGTH]; + char new_ch_map[MAX_CIC_MAP_LENGTH]; memset(&tmp[0], '\0', sizeof(tmp)); memset(&new_ch_map[0], '\0', sizeof(new_ch_map)); @@ -2337,7 +2350,9 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot) /* the the rest of ch_map to new_ch_map */ strncat(new_ch_map, &ch_map[x], strlen(&ch_map[x])); + /* set the new cic map to ch_map*/ + memset(ch_map, '\0', sizeof(ch_map)); strcpy(ch_map, new_ch_map); } else if (ch_map[x] == ',') { @@ -2345,16 +2360,21 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot) x++; /* copy the rest of the list to new_ch_map */ + memset(new_ch_map, '\0', sizeof(new_ch_map)); strcpy(new_ch_map, &ch_map[x]); /* copy the new_ch_map over the old one */ + memset(ch_map, '\0', sizeof(ch_map)); strcpy(ch_map, new_ch_map); } else if (ch_map[x] == '\0') { + /* we're at the end of the string...copy the rest of the list to new_ch_map */ + memset(new_ch_map, '\0', sizeof(new_ch_map)); strcpy(new_ch_map, &ch_map[x]); /* set the new cic map to ch_map*/ + memset(ch_map, '\0', sizeof(ch_map)); strcpy(ch_map, new_ch_map); } else { /* nothing to do */ From 1347983883fa8bc90400878af68b31f80242363c Mon Sep 17 00:00:00 2001 From: Arnaldo Pereira Date: Fri, 10 Dec 2010 19:31:11 -0200 Subject: [PATCH 033/146] freetdm: ftmod_r2 - handle FTDM_CHANNEL_STATE_RINGING, just printing a debug message --- 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 7439ddd3d7..654e68ad9e 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -1605,6 +1605,13 @@ static int ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) } 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)); From bbf1cd1f437d4a90b2b8bf7b9017c3786b2777f5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 9 Dec 2010 14:09:38 -0600 Subject: [PATCH 034/146] 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 035/146] 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 036/146] 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 037/146] 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 038/146] 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 039/146] 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 040/146] 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 041/146] 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 042/146] 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 043/146] 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 044/146] 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 045/146] 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 046/146] 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 047/146] 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 048/146] 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 049/146] 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 050/146] 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 051/146] 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 052/146] 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 053/146] 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 054/146] 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 055/146] 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 056/146] 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 057/146] 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 058/146] 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 059/146] 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 060/146] 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 061/146] 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 062/146] 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 063/146] 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 064/146] 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 065/146] 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 066/146] 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 067/146] 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 068/146] 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 069/146] 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 070/146] 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 071/146] 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 072/146] 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 073/146] 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 074/146] 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 075/146] 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 076/146] 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 077/146] 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 078/146] 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 079/146] 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 080/146] 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 081/146] 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 082/146] 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 083/146] 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 084/146] 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 085/146] 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 086/146] 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 087/146] 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 088/146] 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 089/146] 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 090/146] 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 091/146] 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 092/146] 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 093/146] 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 094/146] 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 095/146] 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 096/146] 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 097/146] 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 098/146] 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 099/146] 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 100/146] 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 101/146] 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 102/146] 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 103/146] 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 104/146] 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 105/146] 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 106/146] 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 107/146] 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 108/146] 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 109/146] 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 110/146] 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 111/146] 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 112/146] 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 113/146] 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 114/146] 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 115/146] 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 116/146] 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 117/146] 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 118/146] 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 119/146] 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 120/146] 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 121/146] 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 122/146] 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 123/146] 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 124/146] 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 125/146] 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 126/146] 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 127/146] 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 128/146] 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 129/146] 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 130/146] 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 131/146] 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 132/146] 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 133/146] 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 134/146] 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 135/146] 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 136/146] 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 137/146] 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 138/146] 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 139/146] 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 140/146] 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 b5b2f6134dcc06ba994b1f71d619b8b4a5626b1e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 20 Dec 2010 14:06:54 -0500 Subject: [PATCH 141/146] 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 38968d15fe3250bb86751ebb099fd6844c6346d3 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 20 Dec 2010 16:15:41 -0500 Subject: [PATCH 142/146] 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 092d22a2142e00245c93f9a5a6592176c00188a8 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 20 Dec 2010 16:57:01 -0500 Subject: [PATCH 143/146] 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 1d7a1bd1311fe633669c7d48ba65e51ccbff24db Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 21 Dec 2010 08:57:11 -0500 Subject: [PATCH 144/146] 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 145/146] 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 146/146] 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; }