diff --git a/.gitignore b/.gitignore index c53d07d8a9..2480b83823 100644 --- a/.gitignore +++ b/.gitignore @@ -46,45 +46,47 @@ core.* !/w32/Console/FreeSwitchConsole.vcproj.user !/w32/Setup/inno_setup/vcredist_x64.exe !/w32/Setup/inno_setup/vcredist_x86.exe -/.version -/AUTHORS -/COPYING -/ChangeLog -/Makefile -/Makefile.in -/NEWS -/README -/TAGS +.version +AUTHORS +COPYING +ChangeLog +Makefile +Makefile.in +NEWS +README +TAGS aclocal.m4 autom4te.cache -/build/Makefile -/build/Makefile.in -/build/config/compile -/build/config/config.guess -/build/config/depcomp -/build/config/install-sh -/build/config/ltmain.sh -/build/config/missing -/build/freeswitch.pc -/build/getlib.sh -/build/getsounds.sh -/build/modmake.rules +build/Makefile +build/Makefile.in +build/config/compile +build/config/config.guess +build/config/depcomp +build/config/install-sh +build/config/ltmain.sh +build/config/missing +build/freeswitch.pc +build/getlib.sh +build/getsounds.sh +build/modmake.rules +build/getg729.sh config.cache config.log config.status -/configure +configure configure.lineno -/freeswitch -/fs_cli -/fs_encode -/fs_ivrd -/libtool -/modules.conf -/quiet_libtool -/tone2wav -/scripts/fsxs -/scripts/gentls_cert -/a.out.dSYM +freeswitch +fs_cli +fs_encode +fs_ivrd +libtool +noreg +modules.conf +quiet_libtool +tone2wav +scripts/fsxs +scripts/gentls_cert +a.out.dSYM src/mod/applications/mod_easyroute/Makefile src/mod/applications/mod_lcr/Makefile src/mod/applications/mod_nibblebill/Makefile @@ -102,6 +104,7 @@ src/mod/say/mod_say_th/Makefile src/mod/say/mod_say_zh/Makefile libs/curl/lib/ca-bundle.h libs/g729/ +libs/fsg729-*-installer src/mod/codecs/mod_com_g729/ src/mod/languages/mod_lua/mod_lua_wrap.cpp.orig src/mod/languages/mod_perl/mod_perl_wrap.cpp.orig diff --git a/build/getg729.sh.in b/build/getg729.sh.in new file mode 100755 index 0000000000..c8a7227425 --- /dev/null +++ b/build/getg729.sh.in @@ -0,0 +1,34 @@ +#!/bin/sh + +TAR=@TAR@ +ZCAT=@ZCAT@ +WGET=@WGET@ +CURL=@CURL@ + +if [ -f "$WGET" ] ; then + DOWNLOAD_CMD=$WGET +else + if [ -f "$CURL" ] ; then + DOWNLOAD_CMD="$CURL -O" + fi +fi + +base=http://files.freeswitch.org/g729/ +tarfile=$1 +url=`echo $tarfile | grep "://"` + +if [ ! -z $url ] ; then + base=$tarfile/ + tarfile=$2 +fi + +if [ ! -f $tarfile ] ; then + $DOWNLOAD_CMD $base$tarfile + if [ ! -f $tarfile ] ; then + echo cannot find $tarfile + exit 1 + fi +fi + +exit 0 + diff --git a/build/modules.conf.in b/build/modules.conf.in index 8d3dfaa85a..63a0ab491e 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -42,6 +42,7 @@ codecs/mod_amr #codecs/mod_silk #codecs/mod_codec2 codecs/mod_g729 +#codecs/mod_com_g729 codecs/mod_h26x codecs/mod_bv codecs/mod_ilbc diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index 44893b931a..95c43331e4 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -94,6 +94,8 @@ + + diff --git a/conf/jingle_profiles/client.xml b/conf/jingle_profiles/client.xml index 66c34929a3..cac70692e8 100644 --- a/conf/jingle_profiles/client.xml +++ b/conf/jingle_profiles/client.xml @@ -24,7 +24,7 @@ - + diff --git a/configure.in b/configure.in index d91cf11419..a0c9418751 100644 --- a/configure.in +++ b/configure.in @@ -730,6 +730,8 @@ AC_PATH_PROGS(WGET, wget) AC_PATH_PROGS(CURL, curl) GETLIB="cd $switch_srcdir/libs && ${SHELL} $switch_builddir/build/getlib.sh" AC_SUBST(GETLIB) +GETG729="cd $switch_srcdir/libs && ${SHELL} $switch_builddir/build/getg729.sh" +AC_SUBST(GETG729) GETSOUNDS="${SHELL} $switch_builddir/build/getsounds.sh" AC_SUBST(GETSOUNDS) @@ -916,6 +918,7 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_osp/Makefile src/mod/applications/mod_stress/Makefile src/mod/applications/mod_hash/Makefile + src/mod/codecs/mod_com_g729/Makefile src/mod/endpoints/mod_portaudio/Makefile src/mod/endpoints/mod_skinny/Makefile src/mod/endpoints/mod_skypopen/Makefile @@ -930,6 +933,7 @@ AC_CONFIG_FILES([Makefile src/include/switch_am_config.h build/getsounds.sh build/getlib.sh + build/getg729.sh build/freeswitch.pc build/modmake.rules libs/xmlrpc-c/include/xmlrpc-c/config.h @@ -1023,6 +1027,7 @@ AC_OUTPUT ## ## Registering for ClueCon ## +if ! test -f noreg ; then echo "" echo "" echo $ECHO_N "Registering you for ClueCon http://www.cluecon.com $ECHO_C" 1>&6 @@ -1040,6 +1045,7 @@ sleep 1 AC_MSG_RESULT([ See you in August. ;-)]) sleep 2 echo "" +fi ## ## Configuration summary diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index ef945cf629..4dc6cfcfd2 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1552,6 +1552,8 @@ 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); + switch_channel_set_variable_printf(channel, "freetdm_screening_ind", ftdm_screening2str(channel_caller_data->screen)); + switch_channel_set_variable_printf(channel, "freetdm_presentation_ind", ftdm_presentation2str(channel_caller_data->pres)); if (globals.sip_headers) { switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel)); @@ -1580,21 +1582,13 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session if (channel_caller_data->raw_data_len) { switch_channel_set_variable_printf(channel, "freetdm_custom_call_data", "%s", channel_caller_data->raw_data); } - /* Add any channel variable to the dial plan */ - iter = ftdm_channel_get_var_iterator(sigmsg->channel, NULL); - for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { - 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); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value); } ftdm_iterator_free(iter); @@ -2149,8 +2143,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal) switch(sigmsg->event_id) { case FTDM_SIGEVENT_START: { - 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; @@ -2698,7 +2690,7 @@ static switch_status_t load_config(void) ftdm_conf_parameter_t spanparameters[30]; char *id = (char *) switch_xml_attr(myspan, "id"); char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "config"); + char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); ftdm_span_t *span = NULL; uint32_t span_id = 0; unsigned paramindex = 0; diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 01125e2f61..260892ada0 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -65,7 +65,6 @@ 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_channel_t *fchan, 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; @@ -2633,7 +2632,6 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_buffer_destroy(&ftdmchan->pre_buffer); ftdmchan->pre_buffer_size = 0; ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - ftdm_channel_clear_vars(ftdmchan); if (ftdmchan->hangup_timer) { ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer); } @@ -4033,20 +4031,13 @@ 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(caller_data->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; + memset(&caller_data->raw_data, 0, sizeof(caller_data->raw_data)); + caller_data->raw_data_len = 0; } FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name) @@ -4058,7 +4049,6 @@ FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, 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; @@ -4125,72 +4115,6 @@ FT_DECLARE(ftdm_status_t) ftdm_call_get_current_var(ftdm_iterator_t *iter, const return FTDM_SUCCESS; } - -static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan) -{ - ftdm_channel_lock(ftdmchan); - - if (ftdmchan->variable_hash) { - hashtable_destroy(ftdmchan->variable_hash); - } - ftdmchan->variable_hash = NULL; - - ftdm_channel_unlock(ftdmchan); - return FTDM_SUCCESS; -} - -FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const char *var_name, const char *value) -{ - char *t_name = 0, *t_val = 0; - - ftdm_status_t status = FTDM_FAIL; - - if (!var_name || !value) { - return FTDM_FAIL; - } - - ftdm_channel_lock(ftdmchan); - - if (!ftdmchan->variable_hash) { - /* initialize on first use */ - ftdmchan->variable_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys); - if (!ftdmchan->variable_hash) { - goto done; - } - } - - t_name = ftdm_strdup(var_name); - t_val = ftdm_strdup(value); - - hashtable_insert(ftdmchan->variable_hash, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE); - - status = FTDM_SUCCESS; - -done: - ftdm_channel_unlock(ftdmchan); - - return status; -} - - -FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name) -{ - const char *var = NULL; - - ftdm_channel_lock(ftdmchan); - - if (!ftdmchan->variable_hash || !var_name) { - goto done; - } - - var = (const char *)hashtable_search(ftdmchan->variable_hash, (void *)var_name); - -done: - ftdm_channel_unlock(ftdmchan); - - return var; -} - static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter) { int allocated = 0; @@ -4215,25 +4139,6 @@ static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t return iter; } -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter) -{ - ftdm_hash_iterator_t *hashiter = NULL; - ftdm_channel_lock(ftdmchan); - hashiter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); - ftdm_channel_unlock(ftdmchan); - - - if (hashiter == NULL) { - return NULL; - } - - if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) { - return NULL; - } - iter->pvt.hashiter = hashiter; - return iter; -} - FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter) { if (!(iter = get_iterator(FTDM_ITERATOR_CHANS, iter))) { @@ -4244,24 +4149,6 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *spa return iter; } -FT_DECLARE(ftdm_status_t) ftdm_channel_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; -} - FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter) { ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); 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 06b0b2183e..918b284de1 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 @@ -299,7 +299,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) ftdmchan->caller_data.dnis.digits, iam.cdPtyNum.natAddrInd.val); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -379,7 +379,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -403,7 +403,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -438,7 +438,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -461,7 +461,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -482,7 +482,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -503,7 +503,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -524,7 +524,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -545,7 +545,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -567,7 +567,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -588,7 +588,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -609,7 +609,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -654,7 +654,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -688,7 +688,7 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_grs.range)); - ftdm_call_clear_vars(&ftdmchan->caller_data); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -737,7 +737,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -787,7 +787,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -838,7 +838,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); + ftdm_call_clear_data(&ftdmchan->caller_data); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } @@ -889,7 +889,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); + ftdm_call_clear_data(&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 77abf6ab3e..ef7843e5cc 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -1369,34 +1369,12 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data */ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t datasize, ftdm_size_t *datalen); -/*! \brief Add a custom variable to the channel - * \note This variables may be used by signaling modules to override signaling parameters - * \todo Document which signaling variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const char *var_name, const char *value); - -/*! \brief Get a custom variable from the channel. - * \note The variable pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. */ -FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name); - -/*! \brief Get an iterator to iterate over the channel variables - * \param ftdmchan The channel structure containing the variables - * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. - * \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. - * This iterator is completely non-thread safe, if you are adding variables or removing variables while iterating - * results are unpredictable - */ -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter); - /*! \brief Get iterator current value (depends on the iterator type) * \note Channel iterators return a pointer to ftdm_channel_t * Variable iterators return a pointer to the variable name (not the variable value) */ FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter); -/*! \brief Get variable name and value for the current iterator position */ -FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val); - /*! \brief Advance iterator */ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter); @@ -1427,23 +1405,6 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_call_get_var_iterator(const ftdm_caller_data_ /*! \brief Get variable name and value for the current iterator position */ FT_DECLARE(ftdm_status_t) ftdm_call_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val); -/*! \brief Clear all variables attached to the call - * \note Variables are cleared at the end of each call back, so it is not necessary for the user to call this function. - * \todo Document which signaling variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data); - -/*! \brief Remove a variable attached to the call - * \note Removes a variable that was attached to the call. - * \todo Document which call variables are available - * */ -FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name); - -/*! \brief Clears all the temporary data attached to this call - * \note Clears caller_data->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 7b26d655c5..0de52727da 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -451,7 +451,6 @@ struct ftdm_channel { struct ftdm_caller_data caller_data; struct ftdm_span *span; struct ftdm_io_interface *fio; - ftdm_hash_t *variable_hash; unsigned char rx_cas_bits; uint32_t pre_buffer_size; uint8_t rxgain_table[FTDM_GAINS_TABLE_SIZE]; @@ -629,6 +628,24 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan); FT_DECLARE(void) ftdm_set_echocancel_call_end(ftdm_channel_t *chan); +/*! \brief Clear all variables attached to the call + * \note Variables are cleared at the end of each call back, so it is not necessary for the user to call this function. + * \todo Document which signaling variables are available + * */ +FT_DECLARE(ftdm_status_t) ftdm_call_clear_vars(ftdm_caller_data_t *caller_data); + +/*! \brief Remove a variable attached to the call + * \note Removes a variable that was attached to the call. + * \todo Document which call variables are available + * */ +FT_DECLARE(ftdm_status_t) ftdm_call_remove_var(ftdm_caller_data_t *caller_data, const char *var_name); + +/*! \brief Clears all the temporary data attached to this call + * \note Clears caller_data->variables and caller_data->raw_data. + * */ +FT_DECLARE(void) ftdm_call_clear_data(ftdm_caller_data_t *caller_data); + + /*! \brief Assert condition */ diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 05cd24d230..f8c6a794b9 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -236,6 +236,7 @@ struct switch_runtime { char *odbc_dsn; char *odbc_user; char *odbc_pass; + char *dbname; uint32_t debug_level; uint32_t runlevel; uint32_t tipping_point; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 69b06420a3..984b54fac7 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2227,6 +2227,11 @@ SWITCH_DECLARE(const char *) switch_core_banner(void); SWITCH_DECLARE(switch_bool_t) switch_core_session_in_thread(switch_core_session_t *session); SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number); +SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires, + const char *network_ip, const char *network_port, const char *network_proto); +SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, const char *realm, const char *token); +SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/mod/Makefile.am b/src/mod/Makefile.am index e655cf7f05..5af782d12d 100644 --- a/src/mod/Makefile.am +++ b/src/mod/Makefile.am @@ -21,7 +21,7 @@ $(OUR_MODULES) $(OUR_CLEAN_MODULES) $(OUR_INSTALL_MODULES) $(OUR_UNINSTALL_MODUL fi ; \ fi ; \ if test -z "$$target" ; then target="all" ; fi ; \ - if ! test -f $$moddir/$$modname.c && ! test -f $$moddir/$$modname.cpp ; \ + if ! test -f $$moddir/$$modname.c && ! test -f $$moddir/$$modname.cpp && test $$modname != "mod_com_g729" ; \ then echo ; echo "WARNING $$modname is not a valid FreeSWITCH module dir, skipping it..." ; else \ echo ;\ echo making $$target $$modname ;\ @@ -35,6 +35,9 @@ $(OUR_MODULES) $(OUR_CLEAN_MODULES) $(OUR_INSTALL_MODULES) $(OUR_UNINSTALL_MODUL fi; \ test -z "$$fail" ; +mod_com_g729-activate: + cd $(switch_builddir)/src/mod/codecs/mod_com_g729 && $(MAKE) $(AM_MAKEFLAGS) activate + .DEFAULT: @if test -z "`echo $@ | grep all`"; then $(MAKE) $(AM_MAKEFLAGS) $@-all ; else echo Unknown target `echo $@ | sed -e 's|-all||'`; exit 1; fi diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 61305bbbb5..9d9feed0aa 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1384,6 +1384,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent", "%s", h->agent_name); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent_type", "%s", h->agent_type); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true"); + /* Force loopback to remain live, if not, the loop will detect the actual channel to gone */ + switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "loopback_bowout", "false"); t_agent_called = switch_epoch_time_now(NULL); dialstr = switch_mprintf("%s", h->originate_string); @@ -2080,6 +2082,32 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj return NULL; } +struct moh_dtmf_helper { + const char *queue_name; + char dtmf; +}; + +static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) { + struct moh_dtmf_helper *h = (struct moh_dtmf_helper *) buf; + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + /* Just laywork for people who want to get some DTMF actions */ + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + if (strchr("#", dtmf->digit)) { + h->dtmf = dtmf->digit; + return SWITCH_STATUS_BREAK; + } + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + #define CC_DESC "callcenter" #define CC_USAGE "queue_name" @@ -2226,8 +2254,6 @@ SWITCH_STANDARD_APP(callcenter_function) switch_thread_create(&thread, thd_attr, cc_member_thread_run, h, h->pool); /* Playback MOH */ - /* TODO Add DTMF callback support */ - /* TODO add MOH infitite loop */ if (cc_moh_override) { cur_moh = switch_core_session_strdup(member_session, cc_moh_override); } else { @@ -2237,6 +2263,12 @@ SWITCH_STANDARD_APP(callcenter_function) while (switch_channel_ready(member_channel)) { switch_input_args_t args = { 0 }; + struct moh_dtmf_helper ht; + + ht.dtmf = '\0'; + args.input_callback = moh_on_dtmf; + args.buf = (void *) &ht; + args.buflen = sizeof(h); /* An agent was found, time to exit and let the bridge do it job */ if ((agent_uuid = switch_channel_get_variable(member_channel, "cc_agent_uuid"))) { @@ -2260,6 +2292,8 @@ SWITCH_STANDARD_APP(callcenter_function) switch_ivr_collect_digits_callback(session, &args, 0, 0); } + switch_yield(1000); + } /* Stop Member Thread */ diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 4dff2f88a0..6db8c046f6 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -45,6 +45,149 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_commands_shutdown); SWITCH_MODULE_DEFINITION(mod_commands, mod_commands_load, mod_commands_shutdown, NULL); + +struct cb_helper { + uint32_t row_process; + switch_stream_handle_t *stream; +}; + +static int url_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + struct cb_helper *cb = (struct cb_helper *) pArg; + + cb->row_process++; + + if (!zstr(argv[0])) { + cb->stream->write_function(cb->stream, "%s,", argv[0]); + } + + return 0; +} + +static switch_status_t select_url(const char *user, + const char *domain, + const char *concat, + const char *exclude_contact, + switch_stream_handle_t *stream) +{ + struct cb_helper cb; + char *sql, *errmsg = NULL; + switch_core_flag_t cflags = switch_core_flags(); + switch_cache_db_handle_t *db = NULL; + + if (!(cflags & SCF_USE_SQL)) { + stream->write_function(stream, "-ERR SQL DISABLED NO DATA AVAILABLE!\n"); + return SWITCH_STATUS_SUCCESS; + } + + if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "%s", "-ERR Databse Error!\n"); + return SWITCH_STATUS_SUCCESS; + } + + cb.row_process = 0; + cb.stream = stream; + + if (exclude_contact) { + sql = switch_mprintf("select url, '%q' " + "from registrations where user='%q' and realm='%q' " + "and url not like '%%%s%%'", (concat != NULL) ? concat : "", user, domain, exclude_contact); + } else { + sql = switch_mprintf("select url, '%q' " + "from registrations where user='%q' and realm='%q'", + (concat != NULL) ? concat : "", user, domain); + } + + switch_assert(sql); + switch_cache_db_execute_sql_callback(db, sql, url_callback, &cb, &errmsg); + + if (errmsg) { + stream->write_function(stream, "-ERR SQL Error [%s]\n", errmsg); + free(errmsg); + errmsg = NULL; + } + + switch_safe_free(sql); + + if (db) { + switch_cache_db_release_db_handle(&db); + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_STANDARD_API(reg_url_function) +{ + char *data; + char *user = NULL; + char *domain = NULL, *dup_domain = NULL; + char *concat = NULL; + const char *exclude_contact = NULL; + char *reply = "error/facility_not_subscribed"; + switch_stream_handle_t mystream = { 0 }; + + + if (!cmd) { + stream->write_function(stream, "%s", ""); + return SWITCH_STATUS_SUCCESS; + } + + if (session) { + switch_channel_t *channel = switch_core_session_get_channel(session); + exclude_contact = switch_channel_get_variable(channel, "sip_exclude_contact"); + } + + + data = strdup(cmd); + switch_assert(data); + + user = data; + + if ((domain = strchr(user, '@'))) { + *domain++ = '\0'; + if ((concat = strchr(domain, '/'))) { + *concat++ = '\0'; + } + } else { + if ((concat = strchr(user, '/'))) { + *concat++ = '\0'; + } + } + + if (zstr(domain)) { + dup_domain = switch_core_get_variable_dup("domain"); + domain = dup_domain; + } + + if (!user) goto end; + + + SWITCH_STANDARD_STREAM(mystream); + switch_assert(mystream.data); + + select_url(user, domain, concat, exclude_contact, &mystream); + reply = mystream.data; + + + end: + + if (zstr(reply)) { + reply = "error/user_not_registered"; + } else if (end_of(reply) == ',') { + end_of(reply) = '\0'; + } + + stream->write_function(stream, "%s", reply); + reply = NULL; + + switch_safe_free(mystream.data); + + switch_safe_free(data); + switch_safe_free(dup_domain); + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_STANDARD_API(banner_function) { stream->write_function(stream, "%s", switch_core_banner()); @@ -3738,6 +3881,14 @@ SWITCH_STANDARD_API(show_function) as = argv[3]; } } + } else if (!strcasecmp(command, "registrations")) { + sprintf(sql, "select * from registrations where hostname='%s'", hostname); + if (argv[1] && !strcasecmp(argv[1], "count")) { + holder.justcount = 1; + if (argv[3] && !strcasecmp(argv[2], "as")) { + as = argv[3]; + } + } } else if (!strcasecmp(command, "channels") && argv[1] && !strcasecmp(argv[1], "like")) { if (argv[2]) { char *p; @@ -4890,6 +5041,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "tone_detect", "Start Tone Detection on a channel", tone_detect_session_function, TONE_DETECT_SYNTAX); SWITCH_ADD_API(commands_api_interface, "unload", "Unload Module", unload_function, UNLOAD_SYNTAX); SWITCH_ADD_API(commands_api_interface, "unsched_api", "Unschedule an api command", unsched_api_function, UNSCHED_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "reg_url", "", reg_url_function, "@"); SWITCH_ADD_API(commands_api_interface, "url_decode", "url decode a string", url_decode_function, ""); SWITCH_ADD_API(commands_api_interface, "url_encode", "url encode a string", url_encode_function, ""); SWITCH_ADD_API(commands_api_interface, "user_data", "find user data", user_data_function, "@ [var|param|attr] "); @@ -5000,6 +5152,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add show management"); switch_console_set_complete("add show modules"); switch_console_set_complete("add show nat_map"); + switch_console_set_complete("add show registrations"); switch_console_set_complete("add show say"); switch_console_set_complete("add show timer"); switch_console_set_complete("add shutdown"); diff --git a/src/mod/asr_tts/mod_tts_commandline/mod_tts_commandline.c b/src/mod/asr_tts/mod_tts_commandline/mod_tts_commandline.c index 6b261f1d96..0f3bc41f14 100644 --- a/src/mod/asr_tts/mod_tts_commandline/mod_tts_commandline.c +++ b/src/mod/asr_tts/mod_tts_commandline/mod_tts_commandline.c @@ -120,6 +120,11 @@ static switch_status_t tts_commandline_speech_close(switch_speech_handle_t *sh, tts_commandline_t *info = (tts_commandline_t *) sh->private_info; assert(info != NULL); + if (switch_test_flag(info->fh, SWITCH_FILE_OPEN)) { + switch_core_file_close(info->fh); + unlink(info->file); + } + return SWITCH_STATUS_SUCCESS; } @@ -130,6 +135,11 @@ static switch_status_t tts_commandline_speech_feed_tts(switch_speech_handle_t *s assert(info != NULL); + if (switch_test_flag(info->fh, SWITCH_FILE_OPEN)) { + switch_core_file_close(info->fh); + unlink(info->file); + } + message = switch_core_strdup(sh->memory_pool, globals.command); tmp = switch_util_quote_shell_arg(text); @@ -152,7 +162,7 @@ static switch_status_t tts_commandline_speech_feed_tts(switch_speech_handle_t *s } if (switch_core_file_open(info->fh, info->file, 0, //number_of_channels, - 0, //samples_per_second, + info->rate, //samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file: %s\n", info->file); return SWITCH_STATUS_FALSE; @@ -171,11 +181,14 @@ static switch_status_t tts_commandline_speech_read_tts(switch_speech_handle_t *s assert(info != NULL); if (switch_core_file_read(info->fh, data, &my_datalen) != SWITCH_STATUS_SUCCESS) { - *datalen = my_datalen * 2; + switch_core_file_close(info->fh); + unlink(info->file); return SWITCH_STATUS_FALSE; } *datalen = my_datalen * 2; if (datalen == 0) { + switch_core_file_close(info->fh); + unlink(info->file); return SWITCH_STATUS_BREAK; } else { return SWITCH_STATUS_SUCCESS; diff --git a/src/mod/codecs/mod_com_g729/Makefile.am b/src/mod/codecs/mod_com_g729/Makefile.am new file mode 100644 index 0000000000..7b631386d3 --- /dev/null +++ b/src/mod/codecs/mod_com_g729/Makefile.am @@ -0,0 +1,39 @@ +include $(top_srcdir)/build/modmake.rulesam + +MODNAME=mod_com_g729 +VERSION=193 + +if ISLINUX + +G729INSTALLER = $(top_srcdir)/libs/fsg729-$(VERSION)-installer +LICSERVER=/usr/sbin/freeswitch_licence_server +VALIDATOR=$(bindir)/validator +MOD=$(moddir)/mod_com_g729.so +BUILT_SOURCES = $(G729INSTALLER) + +install: $(LICSERVER) $(VALIDATOR) $(MOD) + +$(LICSERVER) $(VALIDATOR) $(MOD): $(G729INSTALLER) + $(SHELL) $(G729INSTALLER) $(bindir) $(moddir) nobanner + $(ECHO) + $(ECHO) + $(ECHO) Now you can activate your license by running $(MAKE) mod_com_g729-activate + $(ECHO) + $(ECHO) + +$(G729INSTALLER): + rm -f $(top_srcdir)/libs/fsg729-*-installer* + $(GETG729) fsg729-$(VERSION)-installer + chmod 755 $(G729INSTALLER) + +clean: + rm -f $(top_srcdir)/libs/fsg729-*-installer* + rm -rf /tmp/fsg729 + +activate: $(LICSERVER) $(VALIDATOR) $(MOD) + $(VALIDATOR) + +uninstall: clean + rm -f $(LICSERVER) $(VALIDATOR) $(MOD) + +endif diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 8e31e13864..5ce681880c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1366,7 +1366,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (s && !strcmp(s, "off")) { s = NULL; } - switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s); + status = switch_rtp_debug_jitter_buffer(tech_pvt->rtp_session, s); goto end; } @@ -3314,6 +3314,7 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName return 0; } + static int sql2str_callback(void *pArg, int argc, char **argv, char **columnNames) { struct cb_helper_sql2str *cbt = (struct cb_helper_sql2str *) pArg; diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 631cbdb14b..5109e0bc72 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -877,6 +877,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand const char *agent = "unknown"; const char *pres_on_reg = NULL; int send_pres = 0; + int is_tls = 0, is_tcp = 0; delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG); @@ -944,8 +945,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand char *path_encoded = NULL; int path_encoded_len = 0; const char *proto = "sip"; - int is_tls = 0, is_tcp = 0; - if (switch_stristr("transport=tls", sip->sip_contact->m_url->url_params)) { is_tls += 1; @@ -1292,6 +1291,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand char guess_ip4[256]; const char *username = "unknown"; const char *realm = reg_host; + char *url = NULL; + char *contact = NULL; if (auth_params) { username = switch_event_get_header(auth_params, "sip_auth_username"); @@ -1327,7 +1328,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET); + contact = sofia_glue_get_url_from_contact(contact_str, 1); + url = switch_mprintf("sofia/%q/sip:%q", profile->name, sofia_glue_strip_proto(contact)); + switch_core_add_registration(to_user, reg_host, call_id, url, (long) switch_epoch_time_now(NULL) + (long) exptime + 60, + network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp"); + + switch_safe_free(url); + switch_safe_free(contact); + sql = switch_mprintf("insert into sip_registrations " "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires," "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm," @@ -1534,6 +1543,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } } } else { + switch_core_del_registration(to_user, reg_host, call_id); + if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user); 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 1462e4ec54..2bb1d453a0 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 @@ -1783,6 +1783,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even switch_mutex_lock(listener->filter_mutex); if (!listener->filters) { switch_event_create_plain(&listener->filters, SWITCH_EVENT_CLONE); + switch_clear_flag(listener->filters, EF_UNIQ_HEADERS); } if (!strcasecmp(header_name, "delete") && header_val) { diff --git a/src/switch_channel.c b/src/switch_channel.c index f750496323..9e3064b625 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -184,7 +184,7 @@ struct switch_callstate_table { const char *name; switch_channel_callstate_t callstate; }; -static struct switch_callstate_table STATE_CHART[] = { +static struct switch_callstate_table CALLSTATE_CHART[] = { {"DOWN", CCS_DOWN}, {"DIALING", CCS_DIALING}, {"RINGING", CCS_RINGING}, @@ -228,9 +228,9 @@ SWITCH_DECLARE(const char *) switch_channel_callstate2str(switch_channel_callsta uint8_t x; const char *str = "UNKNOWN"; - for (x = 0; x < (sizeof(STATE_CHART) / sizeof(struct switch_cause_table)) - 1; x++) { - if (STATE_CHART[x].callstate == callstate) { - str = STATE_CHART[x].name; + for (x = 0; x < (sizeof(CALLSTATE_CHART) / sizeof(struct switch_cause_table)) - 1; x++) { + if (CALLSTATE_CHART[x].callstate == callstate) { + str = CALLSTATE_CHART[x].name; break; } } @@ -238,6 +238,7 @@ SWITCH_DECLARE(const char *) switch_channel_callstate2str(switch_channel_callsta return str; } + SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2callstate(const char *str) { uint8_t x; @@ -246,9 +247,9 @@ SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2callstate(const char *str if (*str > 47 && *str < 58) { callstate = atoi(str); } else { - for (x = 0; x < (sizeof(STATE_CHART) / sizeof(struct switch_callstate_table)) - 1 && STATE_CHART[x].name; x++) { - if (!strcasecmp(STATE_CHART[x].name, str)) { - callstate = STATE_CHART[x].callstate; + for (x = 0; x < (sizeof(CALLSTATE_CHART) / sizeof(struct switch_callstate_table)) - 1 && CALLSTATE_CHART[x].name; x++) { + if (!strcasecmp(CALLSTATE_CHART[x].name, str)) { + callstate = CALLSTATE_CHART[x].callstate; break; } } @@ -1606,6 +1607,7 @@ static const char *state_names[] = { "CS_HANGUP", "CS_REPORTING", "CS_DESTROY", + "CS_NONE", NULL }; diff --git a/src/switch_core.c b/src/switch_core.c index 4e9648dd82..d9bbfc8da0 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1301,6 +1301,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION; runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION; runtime.odbc_dbtype = DBTYPE_DEFAULT; + runtime.dbname = NULL; /* INIT APR and Create the pool context */ if (apr_initialize() != SWITCH_STATUS_SUCCESS) { @@ -1647,6 +1648,8 @@ static void switch_load_core_config(const char *file) switch_rtp_set_start_port((switch_port_t) atoi(val)); } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) { switch_rtp_set_end_port((switch_port_t) atoi(val)); + } else if (!strcasecmp(var, "core-db-name") && !zstr(val)) { + runtime.dbname = switch_core_strdup(runtime.memory_pool, val); } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) { if (switch_odbc_available()) { runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val); diff --git a/src/switch_core_io.c b/src/switch_core_io.c index decb587ef7..4e1c7075b5 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -318,11 +318,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_codec_t *use_codec = read_frame->codec; if (do_bugs) { switch_thread_rwlock_wrlock(session->bug_rwlock); + if (!session->bugs) { + do_bugs = 0; + switch_thread_rwlock_unlock(session->bug_rwlock); + goto done; + } + if (!switch_core_codec_ready(&session->bug_codec)) { switch_core_codec_copy(read_frame->codec, &session->bug_codec, NULL); } use_codec = &session->bug_codec; switch_thread_rwlock_unlock(session->bug_rwlock); + + switch_thread_rwlock_wrlock(session->bug_rwlock); + if (!session->bugs) { + do_bugs = 0; + } + switch_thread_rwlock_unlock(session->bug_rwlock); + if (!do_bugs) goto done; } if (switch_test_flag(read_frame, SFF_PLC)) { diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 73890a1e4f..f135e9586d 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -74,7 +74,11 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); } else { - options.core_db_options.db_path = SWITCH_CORE_DB; + if (runtime.dbname) { + options.core_db_options.db_path = runtime.dbname; + } else { + options.core_db_options.db_path = SWITCH_CORE_DB; + } r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } @@ -87,6 +91,7 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t #define SQL_CACHE_TIMEOUT 120 +#define SQL_REG_TIMEOUT 15 static void sql_close(time_t prune) { @@ -906,7 +911,7 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *thread, void *obj) { - int sec = 0; + int sec = 0, reg_sec = 0;; sql_manager.db_thread_running = 1; @@ -916,6 +921,11 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *threa wake_thread(0); sec = 0; } + + if (++reg_sec == SQL_REG_TIMEOUT) { + switch_core_expire_registration(0); + reg_sec = 0; + } switch_yield(1000000); } @@ -1616,6 +1626,108 @@ static char create_nat_sql[] = " hostname VARCHAR(256)\n" ");\n"; + +static char create_registrations_sql[] = + "CREATE TABLE registrations (\n" + " reg_user VARCHAR(256),\n" + " realm VARCHAR(256),\n" + " token VARCHAR(256),\n" + " url TEXT,\n" + " expires INTEGER,\n" + " network_ip VARCHAR(256),\n" + " network_port VARCHAR(256),\n" + " network_proto VARCHAR(256),\n" + " hostname VARCHAR(256)\n" + ");\n" + "create index regindex1 on registrations (reg_user,realm,hostname);\n"; + + +SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires, + const char *network_ip, const char *network_port, const char *network_proto) +{ + switch_cache_db_handle_t *dbh; + char *sql; + + if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); + return SWITCH_STATUS_FALSE; + } + + sql = switch_mprintf("delete from registrations where hostname='%q' and (url='%q' or token='%q')", switch_core_get_hostname(), url, switch_str_nil(token)); + switch_cache_db_execute_sql(dbh, sql, NULL); + free(sql); + + sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) " + "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')", + switch_str_nil(user), + switch_str_nil(realm), + switch_str_nil(token), + switch_str_nil(url), + expires, + switch_str_nil(network_ip), + switch_str_nil(network_port), + switch_str_nil(network_proto), + switch_core_get_hostname() + ); + + switch_cache_db_execute_sql(dbh, sql, NULL); + switch_cache_db_release_db_handle(&dbh); + + free(sql); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, const char *realm, const char *token) +{ + + switch_cache_db_handle_t *dbh; + char *sql; + + if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); + return SWITCH_STATUS_FALSE; + } + + sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_hostname()); + + switch_cache_db_execute_sql(dbh, sql, NULL); + switch_cache_db_release_db_handle(&dbh); + + free(sql); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force) +{ + + switch_cache_db_handle_t *dbh; + char *sql; + switch_time_t now; + + if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); + return SWITCH_STATUS_FALSE; + } + + now = switch_epoch_time_now(NULL); + + if (force) { + sql = switch_mprintf("delete from registrations where hostname='%q'", switch_core_get_hostname()); + } else { + sql = switch_mprintf("delete from registrations where expires <= %ld and hostname='%q'", now, switch_core_get_hostname()); + } + + switch_cache_db_execute_sql(dbh, sql, NULL); + switch_cache_db_release_db_handle(&dbh); + + free(sql); + + return SWITCH_STATUS_SUCCESS; + +} + switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage) { switch_threadattr_t *thd_attr; @@ -1690,6 +1802,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_cache_db_test_reactive(dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); switch_cache_db_test_reactive(dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); switch_cache_db_test_reactive(dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); + switch_cache_db_test_reactive(dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + "DROP TABLE registrations", create_registrations_sql); switch (dbh->type) { @@ -1706,6 +1820,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ } switch_cache_db_test_reactive(dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); + switch_cache_db_test_reactive(dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + "DROP TABLE registrations", create_registrations_sql); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { switch_cache_db_execute_sql(dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4df867aa64..faa79e35a2 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1875,7 +1875,7 @@ static void jb_logger(const char *file, const char *func, int line, int level, c SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name) { - if (!switch_rtp_ready(rtp_session)) { + if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) { return SWITCH_STATUS_FALSE; } @@ -2808,7 +2808,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ goto end; } - if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && + if (bytes && rtp_session->recv_msg.header.version == 2 && + !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) &&