From 927c646dc7354c8a503a4f25e04398d73c7223ba Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Sep 2012 10:14:32 -0500 Subject: [PATCH 001/512] update error message to explain more --- src/mod/endpoints/mod_sofia/sofia.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ddbbead883..01fe061f88 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2491,7 +2491,9 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void TAG_END()); /* Last tag should always finish the sequence */ if (!profile->nua) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s\n", profile->name); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s\n" + "The likely causes for this are:\n" "1) Another application is already listening on the specified address.\n" + "2) The IP the profile is attempting to bind to is not local to this system.", profile->name); sofia_profile_start_failure(profile, profile->name); sofia_glue_del_profile(profile); goto end; From 3cf238fc9a1370a45d362c2193b8d3634ccd1d11 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Sep 2012 10:49:50 -0500 Subject: [PATCH 002/512] add skip_cdr_causes variable to list call hangup causes that should not trigger cdr processing --- src/include/switch_types.h | 1 + src/switch_core_state_machine.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 9fa47ac2b8..5f3a4fa258 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -163,6 +163,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_API_REPORTING_HOOK_VARIABLE "api_reporting_hook" #define SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE "session_in_hangup_hook" #define SWITCH_PROCESS_CDR_VARIABLE "process_cdr" +#define SWITCH_SKIP_CDR_CAUSES_VARIABLE "skip_cdr_causes" #define SWITCH_FORCE_PROCESS_CDR_VARIABLE "force_process_cdr" #define SWITCH_BRIDGE_CHANNEL_VARIABLE "bridge_channel" #define SWITCH_CHANNEL_NAME_VARIABLE "channel_name" diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index a3c7079dbb..0288df11a6 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -662,6 +662,7 @@ SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t * int silly = 0; int index = 0; const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE); + const char *skip_var = switch_channel_get_variable(session->channel, SWITCH_SKIP_CDR_CAUSES_VARIABLE); const char *hook_var; int use_session = 0; switch_event_t *event; @@ -695,6 +696,22 @@ SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t * } } + + if (!zstr(skip_var)) { + int x, ttl = 0; + char *list[128] = { 0 }; + char *dup = switch_core_session_strdup(session, skip_var); + + ttl = switch_split(dup, '|', list); + + for(x = 0; x < ttl; x++) { + if (switch_channel_str2cause(list[x]) == cause) { + do_extra_handlers = 0; + break; + } + } + } + if (switch_channel_test_flag(session->channel, CF_NO_CDR)) { do_extra_handlers = 0; } From cba999b551ae77a0feb015f708f9f80bfc1f70c7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Sep 2012 11:47:53 -0500 Subject: [PATCH 003/512] FS-4598 reasonable req --- src/mod/endpoints/mod_sofia/sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 01fe061f88..304ac668dd 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1723,6 +1723,7 @@ void sofia_event_callback(nua_event_t event, private_object_t *tech_pvt = switch_core_session_get_private(session); if (status == 403) { + switch_channel_set_flag(channel, CF_NO_CDR); switch_channel_hangup(channel, SWITCH_CAUSE_CALL_REJECTED); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid); From 35a141c457bb402db50e142cfab4d67583098ccf Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 19 Sep 2012 13:36:06 -0400 Subject: [PATCH 004/512] add support to RPM spec file for Spanish and Portugese language modules --- freeswitch.spec | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/freeswitch.spec b/freeswitch.spec index f4e3399715..66a989882c 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -1118,6 +1118,22 @@ Requires: %{name} = %{version}-%{release} %description lang-he Hebrew language phrases module and directory structure for say module and voicemail +%package lang-es +Summary: Provides Spanish language dependend modules and speech config for the FreeSWITCH Open Source telephone platform. +Group: System/Libraries +Requires: %{name} = %{version}-%{release} + +%description lang-es +Spanish language phrases module and directory structure for say module and voicemail + +%package lang-pt +Summary: Provides Portugese language dependend modules and speech config for the FreeSWITCH Open Source telephone platform. +Group: System/Libraries +Requires: %{name} = %{version}-%{release} + +%description lang-pt +Hebrew language phrases module and directory structure for say module and voicemail + ###################################################################################################################### # FreeSWITCH Timer Modules ###################################################################################################################### @@ -1733,6 +1749,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/mongo.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/nibblebill.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/opal.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/oreka.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/osp.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/pocketsphinx.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/portaudio.conf.xml @@ -2296,6 +2313,30 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/he/dir/*.xml %{MODINSTDIR}/mod_say_he.so* +%files lang-es +%defattr(-, freeswitch, daemon) +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es/demo +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es/vm +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/es/dir +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/demo/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/vm/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/dir/*.xml +%{MODINSTDIR}/mod_say_en.so* + +%files lang-en +%defattr(-, freeswitch, daemon) +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt/demo +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt/vm +%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt/dir +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/demo/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/vm/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/dir/*.xml +%{MODINSTDIR}/mod_say_en.so* + ###################################################################################################################### # # Timer Modules @@ -2332,6 +2373,8 @@ fi # ###################################################################################################################### %changelog +* Thu Sep 19 2012 - krice@freeswitch.org +- Add support for Spanish and Portugese say language modules * Thu Jan 26 2012 - krice@freeswitch.org - complete rework of spec file * Tue Jun 14 2011 - michal.bielicki@seventhsignal.de From cf480c8b3a46b9abfd76e2f7a918593c103ad6bc Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 19 Sep 2012 13:40:13 -0400 Subject: [PATCH 005/512] misssed a spec in the spec file --- freeswitch.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freeswitch.spec b/freeswitch.spec index 66a989882c..4e77fc5e4a 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -2325,7 +2325,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/dir/*.xml %{MODINSTDIR}/mod_say_en.so* -%files lang-en +%files lang-pt %defattr(-, freeswitch, daemon) %dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt %dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt/demo From cd6ead9178556b295b8f842d1a44a83d212602c3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Sep 2012 12:44:26 -0500 Subject: [PATCH 006/512] add libks (kitchen sink) as a new lib to collect random cool cross platform BSD licensed C funcs --- libs/libks/Makefile | 26 + libs/libks/src/include/cc.h | 2 + libs/libks/src/include/ks.h | 371 +++ libs/libks/src/include/ks_buffer.h | 146 + libs/libks/src/include/ks_config.h | 178 + libs/libks/src/include/ks_json.h | 127 + libs/libks/src/include/ks_threadmutex.h | 58 + libs/libks/src/include/mpool.h | 463 +++ libs/libks/src/include/mpool_loc.h | 116 + libs/libks/src/include/simclist.h | 980 ++++++ libs/libks/src/include/table.h | 1372 ++++++++ libs/libks/src/include/table_loc.h | 229 ++ libs/libks/src/ks.c | 739 ++++ libs/libks/src/ks_buffer.c | 353 ++ libs/libks/src/ks_config.c | 256 ++ libs/libks/src/ks_json.c | 529 +++ libs/libks/src/ks_threadmutex.c | 239 ++ libs/libks/src/mpool.c | 1768 ++++++++++ libs/libks/src/simclist.c | 1525 +++++++++ libs/libks/src/table.c | 4079 +++++++++++++++++++++++ libs/libks/src/table_util.c | 295 ++ 21 files changed, 13851 insertions(+) create mode 100644 libs/libks/Makefile create mode 100644 libs/libks/src/include/cc.h create mode 100644 libs/libks/src/include/ks.h create mode 100644 libs/libks/src/include/ks_buffer.h create mode 100644 libs/libks/src/include/ks_config.h create mode 100755 libs/libks/src/include/ks_json.h create mode 100644 libs/libks/src/include/ks_threadmutex.h create mode 100644 libs/libks/src/include/mpool.h create mode 100644 libs/libks/src/include/mpool_loc.h create mode 100755 libs/libks/src/include/simclist.h create mode 100644 libs/libks/src/include/table.h create mode 100644 libs/libks/src/include/table_loc.h create mode 100644 libs/libks/src/ks.c create mode 100644 libs/libks/src/ks_buffer.c create mode 100644 libs/libks/src/ks_config.c create mode 100644 libs/libks/src/ks_json.c create mode 100644 libs/libks/src/ks_threadmutex.c create mode 100644 libs/libks/src/mpool.c create mode 100755 libs/libks/src/simclist.c create mode 100644 libs/libks/src/table.c create mode 100644 libs/libks/src/table_util.c diff --git a/libs/libks/Makefile b/libs/libks/Makefile new file mode 100644 index 0000000000..250280766f --- /dev/null +++ b/libs/libks/Makefile @@ -0,0 +1,26 @@ +PWD=$(shell pwd) +INCS=-I$(PWD)/src/include +DEBUG=-g -ggdb +BASE_FLAGS=$(INCS) $(DEBUG) -I$(LIBEDIT_DIR)/src/ -fPIC +PICKY=-O2 +CFLAGS=$(BASE_FLAGS) $(PICKY) +CXXFLAGS=$(BASE_FLAGS) +MYLIB=libks.a +LIBS=-lncurses -lks -lpthread -lm +LDFLAGS=-L. +OBJS=src/ks.o src/ks_threadmutex.o src/ks_config.o src/ks_json.o src/ks_buffer.o src/mpool.o src/table.o src/table_util.o src/simclist.o +SRC=src/ks.c src/ks_json.c src/ks_threadmutex.c src/ks_config.c src/ks_json.c src/ks_buffer.c src/mpool.c src/table.c src/table_util.c src/simclist.c +HEADERS=src/include/ks_config.h src/include/ks.h src/include/ks_threadmutex.h src/include/ks_json.h src/include/ks_buffer.h src/include/mpool.h src/include/mpool_loc.h src/include/table.h src/include/table_loc.h src/include/simclist.h +SOLINK=-shared -Xlinker -x + +all: $(MYLIB) + +$(MYLIB): $(OBJS) $(HEADERS) $(SRC) + ar rcs $(MYLIB) $(OBJS) + ranlib $(MYLIB) + +%.o: %.c $(HEADERS) + $(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@ + +clean: + rm -f *.o src/*.o libks.a *~ src/*~ src/include/*~ diff --git a/libs/libks/src/include/cc.h b/libs/libks/src/include/cc.h new file mode 100644 index 0000000000..44666193c6 --- /dev/null +++ b/libs/libks/src/include/cc.h @@ -0,0 +1,2 @@ +const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; + diff --git a/libs/libks/src/include/ks.h b/libs/libks/src/include/ks.h new file mode 100644 index 0000000000..c581544d85 --- /dev/null +++ b/libs/libks/src/include/ks.h @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2007-2012, 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. + */ + +#ifndef _KS_H_ +#define _KS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#define ks_copy_string(_x, _y, _z) strncpy(_x, _y, _z - 1) +#define ks_set_string(_x, _y) ks_copy_string(_x, _y, sizeof(_x)) +#define KS_VA_NONE "%s", "" + + +typedef enum { + KS_POLL_READ = (1 << 0), + KS_POLL_WRITE = (1 << 1), + KS_POLL_ERROR = (1 << 2) +} ks_poll_t; + +#ifdef WIN32 +#define KS_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY +#define KS_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE +#define KS_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY +#define KS_SEQ_BRED FOREGROUND_RED +#define KS_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY +#define KS_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED +#define KS_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY +#define KS_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE +#define KS_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY +#define KS_SEQ_BGREEN FOREGROUND_GREEN +#define KS_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY +#define KS_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN +#define KS_SEQ_DEFAULT_COLOR KS_SEQ_FWHITE +#define KS_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY +#define KS_SEQ_BBLUE FOREGROUND_BLUE +#define KS_SEQ_FBLACK 0 | FOREGROUND_INTENSITY +#define KS_SEQ_BBLACK 0 +#else +#define KS_SEQ_ESC "\033[" +/* Ansi Control character suffixes */ +#define KS_SEQ_HOME_CHAR 'H' +#define KS_SEQ_HOME_CHAR_STR "H" +#define KS_SEQ_CLEARLINE_CHAR '1' +#define KS_SEQ_CLEARLINE_CHAR_STR "1" +#define KS_SEQ_CLEARLINEEND_CHAR "K" +#define KS_SEQ_CLEARSCR_CHAR0 '2' +#define KS_SEQ_CLEARSCR_CHAR1 'J' +#define KS_SEQ_CLEARSCR_CHAR "2J" +#define KS_SEQ_DEFAULT_COLOR KS_SEQ_ESC KS_SEQ_END_COLOR /* Reset to Default fg/bg color */ +#define KS_SEQ_AND_COLOR ";" /* To add multiple color definitions */ +#define KS_SEQ_END_COLOR "m" /* To end color definitions */ +/* Foreground colors values */ +#define KS_SEQ_F_BLACK "30" +#define KS_SEQ_F_RED "31" +#define KS_SEQ_F_GREEN "32" +#define KS_SEQ_F_YELLOW "33" +#define KS_SEQ_F_BLUE "34" +#define KS_SEQ_F_MAGEN "35" +#define KS_SEQ_F_CYAN "36" +#define KS_SEQ_F_WHITE "37" +/* Background colors values */ +#define KS_SEQ_B_BLACK "40" +#define KS_SEQ_B_RED "41" +#define KS_SEQ_B_GREEN "42" +#define KS_SEQ_B_YELLOW "43" +#define KS_SEQ_B_BLUE "44" +#define KS_SEQ_B_MAGEN "45" +#define KS_SEQ_B_CYAN "46" +#define KS_SEQ_B_WHITE "47" +/* Preset escape sequences - Change foreground colors only */ +#define KS_SEQ_FBLACK KS_SEQ_ESC KS_SEQ_F_BLACK KS_SEQ_END_COLOR +#define KS_SEQ_FRED KS_SEQ_ESC KS_SEQ_F_RED KS_SEQ_END_COLOR +#define KS_SEQ_FGREEN KS_SEQ_ESC KS_SEQ_F_GREEN KS_SEQ_END_COLOR +#define KS_SEQ_FYELLOW KS_SEQ_ESC KS_SEQ_F_YELLOW KS_SEQ_END_COLOR +#define KS_SEQ_FBLUE KS_SEQ_ESC KS_SEQ_F_BLUE KS_SEQ_END_COLOR +#define KS_SEQ_FMAGEN KS_SEQ_ESC KS_SEQ_F_MAGEN KS_SEQ_END_COLOR +#define KS_SEQ_FCYAN KS_SEQ_ESC KS_SEQ_F_CYAN KS_SEQ_END_COLOR +#define KS_SEQ_FWHITE KS_SEQ_ESC KS_SEQ_F_WHITE KS_SEQ_END_COLOR +#define KS_SEQ_BBLACK KS_SEQ_ESC KS_SEQ_B_BLACK KS_SEQ_END_COLOR +#define KS_SEQ_BRED KS_SEQ_ESC KS_SEQ_B_RED KS_SEQ_END_COLOR +#define KS_SEQ_BGREEN KS_SEQ_ESC KS_SEQ_B_GREEN KS_SEQ_END_COLOR +#define KS_SEQ_BYELLOW KS_SEQ_ESC KS_SEQ_B_YELLOW KS_SEQ_END_COLOR +#define KS_SEQ_BBLUE KS_SEQ_ESC KS_SEQ_B_BLUE KS_SEQ_END_COLOR +#define KS_SEQ_BMAGEN KS_SEQ_ESC KS_SEQ_B_MAGEN KS_SEQ_END_COLOR +#define KS_SEQ_BCYAN KS_SEQ_ESC KS_SEQ_B_CYAN KS_SEQ_END_COLOR +#define KS_SEQ_BWHITE KS_SEQ_ESC KS_SEQ_B_WHITE KS_SEQ_END_COLOR +/* Preset escape sequences */ +#define KS_SEQ_HOME KS_SEQ_ESC KS_SEQ_HOME_CHAR_STR +#define KS_SEQ_CLEARLINE KS_SEQ_ESC KS_SEQ_CLEARLINE_CHAR_STR +#define KS_SEQ_CLEARLINEEND KS_SEQ_ESC KS_SEQ_CLEARLINEEND_CHAR +#define KS_SEQ_CLEARSCR KS_SEQ_ESC KS_SEQ_CLEARSCR_CHAR KS_SEQ_HOME +#endif + +#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) +#define _XOPEN_SOURCE 600 +#endif + +#ifndef HAVE_STRINGS_H +#define HAVE_STRINGS_H 1 +#endif +#ifndef HAVE_SYS_SOCKET_H +#define HAVE_SYS_SOCKET_H 1 +#endif + +#ifndef __WINDOWS__ +#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) +#define __WINDOWS__ +#endif +#endif + +#ifdef _MSC_VER +#ifndef __inline__ +#define __inline__ __inline +#endif +#if (_MSC_VER >= 1400) /* VC8+ */ +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif +#endif +#ifndef strcasecmp +#define strcasecmp(s1, s2) _stricmp(s1, s2) +#endif +#ifndef strncasecmp +#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) +#endif +#ifndef snprintf +#define snprintf _snprintf +#endif +#ifndef S_IRUSR +#define S_IRUSR _S_IREAD +#endif +#ifndef S_IWUSR +#define S_IWUSR _S_IWRITE +#endif +#undef HAVE_STRINGS_H +#undef HAVE_SYS_SOCKET_H +#endif + +#include +#ifndef WIN32 +#include +#endif + +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif +#include + +#if (_MSC_VER >= 1400) // VC8+ +#define ks_assert(expr) assert(expr);__analysis_assume( expr ) +#endif + +#ifndef ks_assert +#define ks_assert(_x) assert(_x) +#endif + +#define ks_safe_free(_x) if (_x) free(_x); _x = NULL +#define ks_strlen_zero(s) (!s || *(s) == '\0') +#define ks_strlen_zero_buf(s) (*(s) == '\0') +#define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1) + +#ifdef WIN32 +#include +#include +typedef SOCKET ks_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 ks_ssize_t; +typedef int ks_filehandle_t; +#define KS_SOCK_INVALID INVALID_SOCKET +#define strerror_r(num, buf, size) strerror_s(buf, size, num) +#if defined(KS_DECLARE_STATIC) +#define KS_DECLARE(type) type __stdcall +#define KS_DECLARE_NONSTD(type) type __cdecl +#define KS_DECLARE_DATA +#elif defined(KS_EXPORTS) +#define KS_DECLARE(type) __declspec(dllexport) type __stdcall +#define KS_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl +#define KS_DECLARE_DATA __declspec(dllexport) +#else +#define KS_DECLARE(type) __declspec(dllimport) type __stdcall +#define KS_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl +#define KS_DECLARE_DATA __declspec(dllimport) +#endif +#else +#define KS_DECLARE(type) type +#define KS_DECLARE_NONSTD(type) type +#define KS_DECLARE_DATA +#include +#include +#include +#include +#include +#include +#include +#define KS_SOCK_INVALID -1 +typedef int ks_socket_t; +typedef ssize_t ks_ssize_t; +typedef int ks_filehandle_t; +#endif + +#include "math.h" +#include "ks_json.h" + +typedef int16_t ks_port_t; +typedef size_t ks_size_t; + +typedef enum { + KS_SUCCESS, + KS_FAIL, + KS_BREAK, + KS_DISCONNECTED, + KS_GENERR +} ks_status_t; + +#define BUF_CHUNK 65536 * 50 +#define BUF_START 65536 * 100 + +#include +#include + +#define ks_test_flag(obj, flag) ((obj)->flags & flag) +#define ks_set_flag(obj, flag) (obj)->flags |= (flag) +#define ks_clear_flag(obj, flag) (obj)->flags &= ~(flag) + +/*! \brief Used internally for truth test */ +typedef enum { + KS_TRUE = 1, + KS_FALSE = 0 +} ks_bool_t; + +#ifndef __FUNCTION__ +#define __FUNCTION__ (const char *)__func__ +#endif + +#define KS_PRE __FILE__, __FUNCTION__, __LINE__ +#define KS_LOG_LEVEL_DEBUG 7 +#define KS_LOG_LEVEL_INFO 6 +#define KS_LOG_LEVEL_NOTICE 5 +#define KS_LOG_LEVEL_WARNING 4 +#define KS_LOG_LEVEL_ERROR 3 +#define KS_LOG_LEVEL_CRIT 2 +#define KS_LOG_LEVEL_ALERT 1 +#define KS_LOG_LEVEL_EMERG 0 + +#define KS_LOG_DEBUG KS_PRE, KS_LOG_LEVEL_DEBUG +#define KS_LOG_INFO KS_PRE, KS_LOG_LEVEL_INFO +#define KS_LOG_NOTICE KS_PRE, KS_LOG_LEVEL_NOTICE +#define KS_LOG_WARNING KS_PRE, KS_LOG_LEVEL_WARNING +#define KS_LOG_ERROR KS_PRE, KS_LOG_LEVEL_ERROR +#define KS_LOG_CRIT KS_PRE, KS_LOG_LEVEL_CRIT +#define KS_LOG_ALERT KS_PRE, KS_LOG_LEVEL_ALERT +#define KS_LOG_EMERG KS_PRE, KS_LOG_LEVEL_EMERG +typedef void (*ks_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...); +typedef void (*ks_listen_callback_t)(ks_socket_t server_sock, ks_socket_t client_sock, struct sockaddr_in *addr); + + +KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap); + +KS_DECLARE_DATA extern ks_logger_t ks_log; + +/*! Sets the logger for libks. Default is the null_logger */ +KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger); +/*! Sets the default log level for libks */ +KS_DECLARE(void) ks_global_set_default_logger(int level); + + +#include "ks_threadmutex.h" +#include "ks_config.h" +#include "ks_buffer.h" +#include "mpool.h" +#include "simclist.h" +#include "table.h" + +KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len); +KS_DECLARE(char *)ks_url_decode(char *s); +KS_DECLARE(const char *)ks_stristr(const char *instr, const char *str); +KS_DECLARE(int) ks_toupper(int c); +KS_DECLARE(int) ks_tolower(int c); +KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...); + + +KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags); + +KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen); + +#define ks_recv(_h) ks_recv_event(_h, 0, NULL) +#define ks_recv_timed(_h, _ms) ks_recv_event_timed(_h, _ms, 0, NULL) + +static __inline__ int ks_safe_strcasecmp(const char *s1, const char *s2) +{ + if (!(s1 && s2)) { + return 1; + } + + return strcasecmp(s1, s2); +} + +#ifdef __cplusplus +} +#endif /* defined(__cplusplus) */ + + +#endif /* defined(_KS_H_) */ + +/* 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/libks/src/include/ks_buffer.h b/libs/libks/src/include/ks_buffer.h new file mode 100644 index 0000000000..83426c9885 --- /dev/null +++ b/libs/libks/src/include/ks_buffer.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2010-2012, 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 "ks.h" +#ifndef KS_BUFFER_H +#define KS_BUFFER_H +/** + * @defgroup ks_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 ks_buffer; +typedef struct ks_buffer ks_buffer_t; + +/*! \brief Allocate a new dynamic ks_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 + */ +KS_DECLARE(ks_status_t) ks_buffer_create(ks_buffer_t **buffer, ks_size_t blocksize, ks_size_t start_len, ks_size_t max_len); + +/*! \brief Get the length of a ks_buffer_t + * \param buffer any buffer of type ks_buffer_t + * \return int size of the buffer. + */ +KS_DECLARE(ks_size_t) ks_buffer_len(ks_buffer_t *buffer); + +/*! \brief Get the freespace of a ks_buffer_t + * \param buffer any buffer of type ks_buffer_t + * \return int freespace in the buffer. + */ +KS_DECLARE(ks_size_t) ks_buffer_freespace(ks_buffer_t *buffer); + +/*! \brief Get the in use amount of a ks_buffer_t + * \param buffer any buffer of type ks_buffer_t + * \return int ammount of buffer curently in use + */ +KS_DECLARE(ks_size_t) ks_buffer_inuse(ks_buffer_t *buffer); + +/*! \brief Read data from a ks_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer. + * \param buffer any buffer of type ks_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 + */ +KS_DECLARE(ks_size_t) ks_buffer_read(ks_buffer_t *buffer, void *data, ks_size_t datalen); + +KS_DECLARE(ks_size_t) ks_buffer_read_packet(ks_buffer_t *buffer, void *data, ks_size_t maxlen); +KS_DECLARE(ks_size_t) ks_buffer_packet_count(ks_buffer_t *buffer); + +/*! \brief Read data endlessly from a ks_buffer_t + * \param buffer any buffer of type ks_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. + */ +KS_DECLARE(ks_size_t) ks_buffer_read_loop(ks_buffer_t *buffer, void *data, ks_size_t datalen); + +/*! \brief Assign a number of loops to read + * \param buffer any buffer of type ks_buffer_t + * \param loops the number of loops (-1 for infinite) + */ +KS_DECLARE(void) ks_buffer_set_loops(ks_buffer_t *buffer, int32_t loops); + +/*! \brief Write data into a ks_buffer_t up to the length of datalen + * \param buffer any buffer of type ks_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 + */ +KS_DECLARE(ks_size_t) ks_buffer_write(ks_buffer_t *buffer, const void *data, ks_size_t datalen); + +/*! \brief Remove data from the buffer + * \param buffer any buffer of type ks_buffer_t + * \param datalen amount of data to be removed + * \return int size of buffer, or 0 if unable to toss that much data + */ +KS_DECLARE(ks_size_t) ks_buffer_toss(ks_buffer_t *buffer, ks_size_t datalen); + +/*! \brief Remove all data from the buffer + * \param buffer any buffer of type ks_buffer_t + */ +KS_DECLARE(void) ks_buffer_zero(ks_buffer_t *buffer); + +/*! \brief Destroy the buffer + * \param buffer buffer to destroy + * \note only neccessary on dynamic buffers (noop on pooled ones) + */ +KS_DECLARE(void) ks_buffer_destroy(ks_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 + */ +KS_DECLARE(ks_size_t) ks_buffer_seek(ks_buffer_t *buffer, ks_size_t datalen); + +/** @} */ + +KS_DECLARE(ks_size_t) ks_buffer_zwrite(ks_buffer_t *buffer, const void *data, ks_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: + */ diff --git a/libs/libks/src/include/ks_config.h b/libs/libks/src/include/ks_config.h new file mode 100644 index 0000000000..0a90bde078 --- /dev/null +++ b/libs/libks/src/include/ks_config.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2007-2012, 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. + */ + +/** + * @defgroup config Config File Parser + * @ingroup config + * This module implements a basic interface and file format parser + * + *
+ *
+ * EXAMPLE 
+ * 
+ * [category1]
+ * var1 => val1
+ * var2 => val2
+ * \# lines that begin with \# are comments
+ * \#var3 => val3
+ * 
+ * @{ + */ + +#ifndef KS_CONFIG_H +#define KS_CONFIG_H + +#include "ks.h" + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + + +#define KS_URL_SEPARATOR "://" + + +#ifdef WIN32 +#define KS_PATH_SEPARATOR "\\" +#ifndef KS_CONFIG_DIR +#define KS_CONFIG_DIR "c:\\openks" +#endif +#define ks_is_file_path(file) (*(file +1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR)) +#else +#define KS_PATH_SEPARATOR "/" +#ifndef KS_CONFIG_DIR +#define KS_CONFIG_DIR "/etc/openks" +#endif +#define ks_is_file_path(file) ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR)) +#endif + +/*! + \brief Evaluate the truthfullness of a string expression + \param expr a string expression + \return true or false +*/ +#define ks_true(expr)\ +(expr && ( !strcasecmp(expr, "yes") ||\ +!strcasecmp(expr, "on") ||\ +!strcasecmp(expr, "true") ||\ +!strcasecmp(expr, "enabled") ||\ +!strcasecmp(expr, "active") ||\ +!strcasecmp(expr, "allow") ||\ +atoi(expr))) ? 1 : 0 + +/*! + \brief Evaluate the falsefullness of a string expression + \param expr a string expression + \return true or false +*/ +#define ks_false(expr)\ +(expr && ( !strcasecmp(expr, "no") ||\ +!strcasecmp(expr, "off") ||\ +!strcasecmp(expr, "false") ||\ +!strcasecmp(expr, "disabled") ||\ +!strcasecmp(expr, "inactive") ||\ +!strcasecmp(expr, "disallow") ||\ +!atoi(expr))) ? 1 : 0 + +typedef struct ks_config ks_config_t; + +/*! \brief A simple file handle representing an open configuration file **/ +struct ks_config { + /*! FILE stream buffer to the opened file */ + FILE *file; + /*! path to the file */ + char path[512]; + /*! current category */ + char category[256]; + /*! current section */ + char section[256]; + /*! buffer of current line being read */ + char buf[1024]; + /*! current line number in file */ + int lineno; + /*! current category number in file */ + int catno; + /*! current section number in file */ + int sectno; + + int lockto; +}; + +/*! + \brief Open a configuration file + \param cfg (ks_config_t *) config handle to use + \param file_path path to the file + \return 1 (true) on success 0 (false) on failure +*/ +KS_DECLARE(int) ks_config_open_file(ks_config_t * cfg, const char *file_path); + +/*! + \brief Close a previously opened configuration file + \param cfg (ks_config_t *) config handle to use +*/ +KS_DECLARE(void) ks_config_close_file(ks_config_t * cfg); + +/*! + \brief Retrieve next name/value pair from configuration file + \param cfg (ks_config_t *) config handle to use + \param var pointer to aim at the new variable name + \param val pointer to aim at the new value +*/ +KS_DECLARE(int) ks_config_next_pair(ks_config_t * cfg, char **var, char **val); + +/*! + \brief Retrieve the CAS bits from a configuration string value + \param strvalue pointer to the configuration string value (expected to be in format whatever:xxxx) + \param outbits pointer to aim at the CAS bits +*/ +KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits); + + +/** @} */ + +#ifdef __cplusplus +} +#endif /* defined(__cplusplus) */ + +#endif /* defined(KS_CONFIG_H) */ + +/* 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/libks/src/include/ks_json.h b/libs/libks/src/include/ks_json.h new file mode 100755 index 0000000000..1ad116e980 --- /dev/null +++ b/libs/libks/src/include/ks_json.h @@ -0,0 +1,127 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +#include "ks.h" +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON { + struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ +} cJSON; + +typedef struct cJSON_Hooks { + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +KS_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks); + + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ +KS_DECLARE(cJSON *)cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ +KS_DECLARE(char *)cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ +KS_DECLARE(char *)cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +KS_DECLARE(void) cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +KS_DECLARE(int) cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +KS_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item); +/* Get item "string" from object. Case insensitive. */ +KS_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +KS_DECLARE(const char *)cJSON_GetErrorPtr(); + +/* These calls create a cJSON item of the appropriate type. */ +KS_DECLARE(cJSON *)cJSON_CreateNull(); +KS_DECLARE(cJSON *)cJSON_CreateTrue(); +KS_DECLARE(cJSON *)cJSON_CreateFalse(); +KS_DECLARE(cJSON *)cJSON_CreateBool(int b); +KS_DECLARE(cJSON *)cJSON_CreateNumber(double num); +KS_DECLARE(cJSON *)cJSON_CreateString(const char *string); +KS_DECLARE(cJSON *)cJSON_CreateArray(); +KS_DECLARE(cJSON *)cJSON_CreateObject(); + +/* These utilities create an Array of count items. */ +KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count); +KS_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count); +KS_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count); +KS_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count); + +/* Append item to the specified array/object. */ +KS_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); +KS_DECLARE(void) cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +KS_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +KS_DECLARE(void) cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +KS_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which); +KS_DECLARE(void) cJSON_DeleteItemFromArray(cJSON *array,int which); +KS_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string); +KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string); + +/* Update array items. */ +KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); +KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); + +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libks/src/include/ks_threadmutex.h b/libs/libks/src/include/ks_threadmutex.h new file mode 100644 index 0000000000..2b12acaccd --- /dev/null +++ b/libs/libks/src/include/ks_threadmutex.h @@ -0,0 +1,58 @@ +/* + * Cross Platform Thread/Mutex abstraction + * Copyright(C) 2007 Michael Jerris + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so. + * + * This work is provided under this license on an "as is" basis, without warranty of any kind, + * either expressed or implied, including, without limitation, warranties that the covered code + * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire + * risk as to the quality and performance of the covered code is with you. Should any covered + * code prove defective in any respect, you (not the initial developer or any other contributor) + * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty + * constitutes an essential part of this license. No use of any covered code is authorized hereunder + * except under this disclaimer. + * + */ + + +#ifndef _KS_THREADMUTEX_H +#define _KS_THREADMUTEX_H + +#include "ks.h" + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +typedef struct ks_mutex ks_mutex_t; +typedef struct ks_thread ks_thread_t; +typedef void *(*ks_thread_function_t) (ks_thread_t *, void *); + +KS_DECLARE(ks_status_t) ks_thread_create_detached(ks_thread_function_t func, void *data); +ks_status_t ks_thread_create_detached_ex(ks_thread_function_t func, void *data, size_t stack_size); +void ks_thread_override_default_stacksize(size_t size); +KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex); +KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex); +KS_DECLARE(ks_status_t) ks_mutex_lock(ks_mutex_t *mutex); +KS_DECLARE(ks_status_t) ks_mutex_trylock(ks_mutex_t *mutex); +KS_DECLARE(ks_status_t) ks_mutex_unlock(ks_mutex_t *mutex); + +#ifdef __cplusplus +} +#endif /* defined(__cplusplus) */ + +#endif /* defined(_KS_THREADMUTEX_H) */ + +/* 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/libks/src/include/mpool.h b/libs/libks/src/include/mpool.h new file mode 100644 index 0000000000..23ac93fb91 --- /dev/null +++ b/libs/libks/src/include/mpool.h @@ -0,0 +1,463 @@ +/* + * Memory pool defines. + * + * Copyright 1996 by Gray Watson. + * + * This file is part of the mpool package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: mpool.h,v 1.4 2006/05/31 20:26:11 gray Exp $ + */ + +#ifndef __MPOOL_H__ +#define __MPOOL_H__ + +#include + +/* + * mpool flags to mpool_alloc or mpool_set_attr + */ + +/* + * Choose a best fit algorithm not first fit. This takes more CPU + * time but will result in a tighter heap. + */ +#define MPOOL_FLAG_BEST_FIT (1<<0) + +/* + * By default the library adds 2 bytes onto all allocations to insert + * a magic number that it can look for to determine how large a freed + * memory chunk is. This flag indicates that few if any frees are + * going to be performed on the pool and to not waste memory on these + * bytes. + */ +#define MPOOL_FLAG_NO_FREE (1<<1) + +/* + * This enables very heavy packing at the possible expense of CPU. + * This affects a number of parts of the library. + * + * By default the 1st page of memory is reserved for the main mpool + * structure. This flag will cause the rest of the 1st block to be + * available for use as user memory. + * + * By default the library looks through the memory when freed looking + * for a magic value. There is an internal max size that it will look + * and then it will give up. This flag forces it to look until it + * finds it. + */ +#define MPOOL_FLAG_HEAVY_PACKING (1<<2) + +/* + * Use sbrk not mmap to allocate pages. This is not recommended for + * normal use. + */ +#define MPOOL_FLAG_USE_SBRK (1<<3) + +/* + * Mpool error codes + */ +#define MPOOL_ERROR_NONE 1 /* no error */ +#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */ +#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */ +#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */ +#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */ +#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */ +#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */ +#define MPOOL_ERROR_NO_MEM 8 /* no memory available */ +#define MPOOL_ERROR_MMAP 9 /* problems with mmap */ +#define MPOOL_ERROR_SIZE 10 /* error processing requested size */ +#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */ +#define MPOOL_ERROR_MEM 12 /* invalid memory address */ +#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */ +#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */ +#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */ +#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */ +#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */ +#define MPOOL_ERROR_SBRK_CONTIG 18 /* sbrk did not return contiguous mem*/ +#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */ +#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */ +#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */ + +/* + * Mpool function IDs for the mpool_log_func callback function. + */ +#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */ +#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */ +#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */ +#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */ +#define MPOOL_FUNC_FREE 5 /* mpool_free function called */ +#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */ + +/* + * void mpool_log_func_t + * + * DESCRIPTION: + * + * Mpool transaction log function. + * + * RETURNS: + * + * None. + * + * ARGUMENT: + * + * mp_p -> Associated mpool address. + * + * func_id -> Integer function ID which identifies which mpool + * function is being called. + * + * byte_size -> Optionally specified byte size. + * + * ele_n -> Optionally specified element number. For mpool_calloc + * only. + * + * new_addr -> Optionally specified new address. For mpool_alloc, + * mpool_calloc, and mpool_resize only. + * + * old_addr -> Optionally specified old address. For mpool_resize and + * mpool_free only. + * + * old_byte_size -> Optionally specified old byte size. For + * mpool_resize only. + */ +typedef void (*mpool_log_func_t)(const void *mp_p, + const int func_id, + const unsigned long byte_size, + const unsigned long ele_n, + const void *old_addr, const void *new_addr, + const unsigned long old_byte_size); + +#ifdef MPOOL_MAIN + +#include "mpool_loc.h" + +#else + +/* generic mpool type */ +typedef void mpool_t; + +#endif + +/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ + +/* + * mpool_t *mpool_open + * + * DESCRIPTION: + * + * Open/allocate a new memory pool. + * + * RETURNS: + * + * Success - Pool pointer which must be passed to mpool_close to + * deallocate. + * + * Failure - NULL + * + * ARGUMENTS: + * + * flags -> Flags to set attributes of the memory pool. See the top + * of mpool.h. + * + * page_size -> Set the internal memory page-size. This must be a + * multiple of the getpagesize() value. Set to 0 for the default. + * + * start_addr -> Starting address to try and allocate memory pools. + * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, + void *start_addr, int *error_p); + +/* + * int mpool_close + * + * DESCRIPTION: + * + * Close/free a memory allocation pool previously opened with + * mpool_open. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +extern +int mpool_close(mpool_t *mp_p); + +/* + * int mpool_clear + * + * DESCRIPTION: + * + * Wipe an opened memory pool clean so we can start again. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +extern +int mpool_clear(mpool_t *mp_p); + +/* + * void *mpool_alloc + * + * DESCRIPTION: + * + * Allocate space for bytes inside of an already open memory pool. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal malloc. + * + * byte_size -> Number of bytes to allocate in the pool. Must be >0. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, + int *error_p); + +/* + * void *mpool_calloc + * + * DESCRIPTION: + * + * Allocate space for elements of bytes in the memory pool and zero + * the space afterwards. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal calloc. + * + * ele_n -> Number of elements to allocate. + * + * ele_size -> Number of bytes per element being allocated. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, + const unsigned long ele_size, int *error_p); + +/* + * int mpool_free + * + * DESCRIPTION: + * + * Free an address from a memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal free. + * + * addr <-> Address to free. + * + * size -> Size of the address being freed. + */ +extern +int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size); + +/* + * void *mpool_resize + * + * DESCRIPTION: + * + * Reallocate an address in a mmeory pool to a new size. This is + * different from realloc in that it needs the old address' size. If + * you don't have it then you need to allocate new space, copy the + * data, and free the old pointer yourself. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal realloc. + * + * old_addr -> Previously allocated address. + * + * old_byte_size -> Size of the old address. Must be known, cannot be + * 0. + * + * new_byte_size -> New size of the allocation. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +extern +void *mpool_resize(mpool_t *mp_p, void *old_addr, + const unsigned long old_byte_size, + const unsigned long new_byte_size, + int *error_p); + +/* + * int mpool_stats + * + * DESCRIPTION: + * + * Return stats from the memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p -> Pointer to the memory pool. + * + * page_size_p <- Pointer to an unsigned integer which, if not NULL, + * will be set to the page-size of the pool. + * + * num_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of pointers currently allocated in pool. + * + * user_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of user bytes allocated in this pool. + * + * max_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the maximum number of user bytes that have been + * allocated in this pool. + * + * tot_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the total amount of space (including administrative + * overhead) used by the pool. + */ +extern +int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, + unsigned long *num_alloced_p, + unsigned long *user_alloced_p, + unsigned long *max_alloced_p, + unsigned long *tot_alloced_p); + +/* + * int mpool_set_log_func + * + * DESCRIPTION: + * + * Set a logging callback function to be called whenever there was a + * memory transaction. See mpool_log_func_t. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * log_func -> Log function (defined in mpool.h) which will be called + * with each mpool transaction. + */ +extern +int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func); + +/* + * int mpool_set_max_pages + * + * DESCRIPTION: + * + * Set the maximum number of pages that the library will use. Once it + * hits the limit it will return MPOOL_ERROR_NO_PAGES. + * + * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages + * value will include the page with the mpool header structure in it. + * If the flag is _not_ set then the max-pages will not include this + * first page. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * max_pages -> Maximum number of pages used by the library. + */ +extern +int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages); + +/* + * const char *mpool_strerror + * + * DESCRIPTION: + * + * Return the corresponding string for the error number. + * + * RETURNS: + * + * Success - String equivalient of the error. + * + * Failure - String "invalid error code" + * + * ARGUMENTS: + * + * error -> Error number that we are converting. + */ +extern +const char *mpool_strerror(const int error); + +/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ + +#endif /* ! __MPOOL_H__ */ diff --git a/libs/libks/src/include/mpool_loc.h b/libs/libks/src/include/mpool_loc.h new file mode 100644 index 0000000000..3d33f5d927 --- /dev/null +++ b/libs/libks/src/include/mpool_loc.h @@ -0,0 +1,116 @@ +/* + * Memory pool local defines. + * + * Copyright 1996 by Gray Watson. + * + * This file is part of the mpool package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: mpool_loc.h,v 1.2 2005/05/20 20:08:54 gray Exp $ + */ + +#ifndef __MPOOL_LOC_H__ +#define __MPOOL_LOC_H__ + +#define MPOOL_MAGIC 0xABACABA /* magic for struct */ +#define BLOCK_MAGIC 0xB1B1007 /* magic for blocks */ +#define FENCE_MAGIC0 (unsigned char)(0xFAU) /* 1st magic mem byte */ +#define FENCE_MAGIC1 (unsigned char)(0xD3U) /* 2nd magic mem byte */ + +#define FENCE_SIZE 2 /* fence space */ +#define MIN_ALLOCATION (sizeof(mpool_free_t)) /* min alloc */ +#define MAX_FREE_SEARCH 10240 /* max size to search */ +#define MAX_FREE_LIST_SEARCH 100 /* max looking for free mem */ + +/* + * bitflag tools for Variable and a Flag + */ +#define BIT_FLAG(x) (1 << (x)) +#define BIT_SET(v,f) (v) |= (f) +#define BIT_CLEAR(v,f) (v) &= ~(f) +#define BIT_IS_SET(v,f) ((v) & (f)) +#define BIT_TOGGLE(v,f) (v) ^= (f) + +#define SET_POINTER(pnt, val) \ + do { \ + if ((pnt) != NULL) { \ + (*(pnt)) = (val); \ + } \ + } while(0) + +#define BLOCK_FLAG_USED BIT_FLAG(0) /* block is used */ +#define BLOCK_FLAG_FREE BIT_FLAG(1) /* block is free */ + +#define DEFAULT_PAGE_MULT 16 /* pagesize = this * getpagesize*/ + +/* How many pages SIZE bytes resides in. We add in the block header. */ +#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \ + (mp_p)->mp_page_size - 1) / \ + (mp_p)->mp_page_size) +#define SIZE_OF_PAGES(mp_p, page_n) ((page_n) * (mp_p)->mp_page_size) +#define MAX_BITS 30 /* we only can allocate 1gb chunks */ + +#define MAX_BLOCK_USER_MEMORY(mp_p) ((mp_p)->mp_page_size - \ + sizeof(mpool_block_t)) +#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \ + sizeof(mpool_block_t)) +#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \ + ((char *)(block_p) + \ + sizeof(mpool_block_t))) + +typedef struct { + unsigned int mp_magic; /* magic number for struct */ + unsigned int mp_flags; /* flags for the struct */ + unsigned long mp_alloc_c; /* number of allocations */ + unsigned long mp_user_alloc; /* user bytes allocated */ + unsigned long mp_max_alloc; /* maximum user bytes allocated */ + unsigned int mp_page_c; /* number of pages allocated */ + unsigned int mp_max_pages; /* maximum number of pages to use */ + unsigned int mp_page_size; /* page-size of our system */ + int mp_fd; /* fd for /dev/zero if mmap-ing */ + off_t mp_top; /* top of our allocations in fd */ + mpool_log_func_t mp_log_func; /* log callback function */ + void *mp_addr; /* current address for mmaping */ + void *mp_min_p; /* min address in pool for checks */ + void *mp_bounds_p; /* max address in pool for checks */ + struct mpool_block_st *mp_first_p; /* first memory block we are using */ + struct mpool_block_st *mp_last_p; /* last memory block we are using */ + struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */ + unsigned int mp_magic2; /* upper magic for overwrite sanity */ +} mpool_t; + +/* for debuggers to be able to interrogate the generic type in the .h file */ +typedef mpool_t mpool_ext_t; + +/* + * Block header structure. This structure *MUST* be long-word + * aligned. + */ +typedef struct mpool_block_st { + unsigned int mb_magic; /* magic number for block header */ + void *mb_bounds_p; /* block boundary location */ + struct mpool_block_st *mb_next_p; /* linked list next pointer */ + unsigned int mb_magic2; /* upper magic for overwrite sanity */ +} mpool_block_t; + +/* + * Free list structure. + */ +typedef struct { + void *mf_next_p; /* pointer to the next free address */ + unsigned long mf_size; /* size of the free block */ +} mpool_free_t; + +#endif /* ! __MPOOL_LOC_H__ */ diff --git a/libs/libks/src/include/simclist.h b/libs/libks/src/include/simclist.h new file mode 100755 index 0000000000..2ce9d491ad --- /dev/null +++ b/libs/libks/src/include/simclist.h @@ -0,0 +1,980 @@ +/* + * Copyright (c) 2007,2008 Mij + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/* + * SimCList library. See http://mij.oltrelinux.com/devel/simclist + */ + + +#ifndef SIMCLIST_H +#define SIMCLIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#ifndef SIMCLIST_NO_DUMPRESTORE +# ifndef _WIN32 +# include /* list_dump_info_t's struct timeval */ +# else +# include +# endif +#endif + + +/* Be friend of both C90 and C99 compilers */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + /* "inline" and "restrict" are keywords */ +#else +# define inline /* inline */ +# define restrict /* restrict */ +#endif + + +/** + * Type representing list hashes. + * + * This is a signed integer value. + */ +typedef int32_t list_hash_t; + +#ifndef SIMCLIST_NO_DUMPRESTORE +typedef struct { + uint16_t version; /* dump version */ + struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */ + uint32_t list_size; + uint32_t list_numels; + list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */ + uint32_t dumpsize; + int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */ +} list_dump_info_t; +#endif + +/** + * a comparator of elements. + * + * A comparator of elements is a function that: + * -# receives two references to elements a and b + * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively + * + * It is responsability of the function to handle possible NULL values. + */ +typedef int (*element_comparator)(const void *a, const void *b); + +/** + * a seeker of elements. + * + * An element seeker is a function that: + * -# receives a reference to an element el + * -# receives a reference to some indicator data + * -# returns non-0 if the element matches the indicator, 0 otherwise + * + * It is responsability of the function to handle possible NULL values in any + * argument. + */ +typedef int (*element_seeker)(const void *el, const void *indicator); + +/** + * an element lenght meter. + * + * An element meter is a function that: + * -# receives the reference to an element el + * -# returns its size in bytes + * + * It is responsability of the function to handle possible NULL values. + */ +typedef size_t (*element_meter)(const void *el); + +/** + * a function computing the hash of elements. + * + * An hash computing function is a function that: + * -# receives the reference to an element el + * -# returns a hash value for el + * + * It is responsability of the function to handle possible NULL values. + */ +typedef list_hash_t (*element_hash_computer)(const void *el); + +/** + * a function for serializing an element. + * + * A serializer function is one that gets a reference to an element, + * and returns a reference to a buffer that contains its serialization + * along with the length of this buffer. + * It is responsability of the function to handle possible NULL values, + * returning a NULL buffer and a 0 buffer length. + * + * These functions have 3 goals: + * -# "freeze" and "flatten" the memory representation of the element + * -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations + * -# possibly extract a compressed representation of the element + * + * @param el reference to the element data + * @param serialize_buffer reference to fill with the length of the buffer + * @return reference to the buffer with the serialized data + */ +typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len); + +/** + * a function for un-serializing an element. + * + * An unserializer function accomplishes the inverse operation of the + * serializer function. An unserializer function is one that gets a + * serialized representation of an element and turns it backe to the original + * element. The serialized representation is passed as a reference to a buffer + * with its data, and the function allocates and returns the buffer containing + * the original element, and it sets the length of this buffer into the + * integer passed by reference. + * + * @param data reference to the buffer with the serialized representation of the element + * @param data_len reference to the location where to store the length of the data in the buffer returned + * @return reference to a buffer with the original, unserialized representation of the element + */ +typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len); + +/* [private-use] list entry -- olds actual user datum */ +struct list_entry_s { + void *data; + + /* doubly-linked list service references */ + struct list_entry_s *next; + struct list_entry_s *prev; +}; + +/* [private-use] list attributes */ +struct list_attributes_s { + /* user-set routine for comparing list elements */ + element_comparator comparator; + /* user-set routing for seeking elements */ + element_seeker seeker; + /* user-set routine for determining the length of an element */ + element_meter meter; + int copy_data; + /* user-set routine for computing the hash of an element */ + element_hash_computer hasher; + /* user-set routine for serializing an element */ + element_serializer serializer; + /* user-set routine for unserializing an element */ + element_unserializer unserializer; +}; + +/** list object */ +typedef struct { + struct list_entry_s *head_sentinel; + struct list_entry_s *tail_sentinel; + struct list_entry_s *mid; + + unsigned int numels; + + /* array of spare elements */ + struct list_entry_s **spareels; + unsigned int spareelsnum; + +#ifdef SIMCLIST_WITH_THREADS + /* how many threads are currently running */ + unsigned int threadcount; +#endif + + /* service variables for list iteration */ + int iter_active; + unsigned int iter_pos; + struct list_entry_s *iter_curentry; + + /* list attributes */ + struct list_attributes_s attrs; +} list_t; + +/** + * initialize a list object for use. + * + * @param l must point to a user-provided memory location + * @return 0 for success. -1 for failure + */ +int list_init(list_t *restrict l); + +/** + * completely remove the list from memory. + * + * This function is the inverse of list_init(). It is meant to be called when + * the list is no longer going to be used. Elements and possible memory taken + * for internal use are freed. + * + * @param l list to destroy + */ +void list_destroy(list_t *restrict l); + +/** + * set the comparator function for list elements. + * + * Comparator functions are used for searching and sorting. If NULL is passed + * as reference to the function, the comparator is disabled. + * + * @param l list to operate + * @param comparator_fun pointer to the actual comparator function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_comparator() + */ +int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun); + +/** + * set a seeker function for list elements. + * + * Seeker functions are used for finding elements. If NULL is passed as reference + * to the function, the seeker is disabled. + * + * @param l list to operate + * @param seeker_fun pointer to the actual seeker function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_seeker() + */ +int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun); + +/** + * require to free element data when list entry is removed (default: don't free). + * + * [ advanced preference ] + * + * By default, when an element is removed from the list, it disappears from + * the list by its actual data is not free()d. With this option, every + * deletion causes element data to be freed. + * + * It is responsability of this function to correctly handle NULL values, if + * NULL elements are inserted into the list. + * + * @param l list to operate + * @param metric_fun pointer to the actual metric function + * @param copy_data 0: do not free element data (default); non-0: do free + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_meter() + * @see list_meter_int8_t() + * @see list_meter_int16_t() + * @see list_meter_int32_t() + * @see list_meter_int64_t() + * @see list_meter_uint8_t() + * @see list_meter_uint16_t() + * @see list_meter_uint32_t() + * @see list_meter_uint64_t() + * @see list_meter_float() + * @see list_meter_double() + * @see list_meter_string() + */ +int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data); + +/** + * set the element hash computing function for the list elements. + * + * [ advanced preference ] + * + * An hash can be requested depicting the list status at a given time. An hash + * only depends on the elements and their order. By default, the hash of an + * element is only computed on its reference. With this function, the user can + * set a custom function computing the hash of an element. If such function is + * provided, the list_hash() function automatically computes the list hash using + * the custom function instead of simply referring to element references. + * + * @param l list to operate + * @param hash_computer_fun pointer to the actual hash computing function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_hash_computer() + */ +int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun); + +/** + * set the element serializer function for the list elements. + * + * [ advanced preference ] + * + * Serialize functions are used for dumping the list to some persistent + * storage. The serializer function is called for each element; it is passed + * a reference to the element and a reference to a size_t object. It will + * provide (and return) the buffer with the serialization of the element and + * fill the size_t object with the length of this serialization data. + * + * @param l list to operate + * @param serializer_fun pointer to the actual serializer function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_serializer() + * @see list_dump_filedescriptor() + * @see list_restore_filedescriptor() + */ +int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun); + +/** + * set the element unserializer function for the list elements. + * + * [ advanced preference ] + * + * Unserialize functions are used for restoring the list from some persistent + * storage. The unserializer function is called for each element segment read + * from the storage; it is passed the segment and a reference to an integer. + * It shall allocate and return a buffer compiled with the resumed memory + * representation of the element, and set the integer value to the length of + * this buffer. + * + * @param l list to operate + * @param unserializer_fun pointer to the actual unserializer function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_unserializer() + * @see list_dump_filedescriptor() + * @see list_restore_filedescriptor() + */ +int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun); + +/** + * append data at the end of the list. + * + * This function is useful for adding elements with a FIFO/queue policy. + * + * @param l list to operate + * @param data pointer to user data to append + * + * @return 1 for success. < 0 for failure + */ +int list_append(list_t *restrict l, const void *data); + +/** + * insert data in the head of the list. + * + * This function is useful for adding elements with a LIFO/Stack policy. + * + * @param l list to operate + * @param data pointer to user data to append + * + * @return 1 for success. < 0 for failure + */ +int list_prepend(list_t *restrict l, const void *restrict data); + +/** + * extract the element in the top of the list. + * + * This function is for using a list with a FIFO/queue policy. + * + * @param l list to operate + * @return reference to user datum, or NULL on errors + */ +void *list_fetch(list_t *restrict l); + +/** + * retrieve an element at a given position. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element wanted + * @return reference to user datum, or NULL on errors + */ +void *list_get_at(const list_t *restrict l, unsigned int pos); + +/** + * return the maximum element of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * Returns the maximum element with respect to the comparator function output. + * + * @see list_attributes_comparator() + * + * @param l list to operate + * @return the reference to the element, or NULL + */ +void *list_get_max(const list_t *restrict l); + +/** + * return the minimum element of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * Returns the minimum element with respect to the comparator function output. + * + * @see list_attributes_comparator() + * + * @param l list to operate + * @return the reference to the element, or NULL + */ +void *list_get_min(const list_t *restrict l); + +/** + * retrieve and remove from list an element at a given position. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element wanted + * @return reference to user datum, or NULL on errors + */ +void *list_extract_at(list_t *restrict l, unsigned int pos); + +/** + * insert an element at a given position. + * + * @param l list to operate + * @param data reference to data to be inserted + * @param pos [0,size-1] position index to insert the element at + * @return positive value on success. Negative on failure + */ +int list_insert_at(list_t *restrict l, const void *data, unsigned int pos); + +/** + * expunge the first found given element from the list. + * + * Inspects the given list looking for the given element; if the element + * is found, it is removed. Only the first occurence is removed. + * If a comparator function was not set, elements are compared by reference. + * Otherwise, the comparator is used to match the element. + * + * @param l list to operate + * @param data reference of the element to search for + * @return 0 on success. Negative value on failure + * + * @see list_attributes_comparator() + * @see list_delete_at() + */ +int list_delete(list_t *restrict l, const void *data); + +/** + * expunge an element at a given position from the list. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element to be deleted + * @return 0 on success. Negative value on failure + */ +int list_delete_at(list_t *restrict l, unsigned int pos); + +/** + * expunge an array of elements from the list, given their position range. + * + * @param l list to operate + * @param posstart [0,size-1] position index of the first element to be deleted + * @param posend [posstart,size-1] position of the last element to be deleted + * @return the number of elements successfully removed on success, <0 on error + */ +int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend); + +/** + * clear all the elements off of the list. + * + * The element datums will not be freed. + * + * @see list_delete_range() + * @see list_size() + * + * @param l list to operate + * @return the number of elements removed on success, <0 on error + */ +int list_clear(list_t *restrict l); + +/** + * inspect the number of elements in the list. + * + * @param l list to operate + * @return number of elements currently held by the list + */ +unsigned int list_size(const list_t *restrict l); + +/** + * inspect whether the list is empty. + * + * @param l list to operate + * @return 0 iff the list is not empty + * + * @see list_size() + */ +int list_empty(const list_t *restrict l); + +/** + * find the position of an element in a list. + * + * @warning Requires a comparator function to be set for the list. + * + * Inspects the given list looking for the given element; if the element + * is found, its position into the list is returned. + * Elements are inspected comparing references if a comparator has not been + * set. Otherwise, the comparator is used to find the element. + * + * @param l list to operate + * @param data reference of the element to search for + * @return position of element in the list, or <0 if not found + * + * @see list_attributes_comparator() + * @see list_get_at() + */ +int list_locate(const list_t *restrict l, const void *data); + +/** + * returns an element given an indicator. + * + * @warning Requires a seeker function to be set for the list. + * + * Inspect the given list looking with the seeker if an element matches + * an indicator. If such element is found, the reference to the element + * is returned. + * + * @param l list to operate + * @param indicator indicator data to pass to the seeker along with elements + * @return reference to the element accepted by the seeker, or NULL if none found + */ +void *list_seek(list_t *restrict l, const void *indicator); + +/** + * inspect whether some data is member of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * By default, a per-reference comparison is accomplished. That is, + * the data is in list if any element of the list points to the same + * location of data. + * A "semantic" comparison is accomplished, otherwise, if a comparator + * function has been set previously, with list_attributes_comparator(); + * in which case, the given data reference is believed to be in list iff + * comparator_fun(elementdata, userdata) == 0 for any element in the list. + * + * @param l list to operate + * @param data reference to the data to search + * @return 0 iff the list does not contain data as an element + * + * @see list_attributes_comparator() + */ +int list_contains(const list_t *restrict l, const void *data); + +/** + * concatenate two lists + * + * Concatenates one list with another, and stores the result into a + * user-provided list object, which must be different from both the + * lists to concatenate. Attributes from the original lists are not + * cloned. + * The destination list referred is threated as virgin room: if it + * is an existing list containing elements, memory leaks will happen. + * It is OK to specify the same list twice as source, for "doubling" + * it in the destination. + * + * @param l1 base list + * @param l2 list to append to the base + * @param dest reference to the destination list + * @return 0 for success, -1 for errors + */ +int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest); + +/** + * sort list elements. + * + * @warning Requires a comparator function to be set for the list. + * + * Sorts the list in ascending or descending order as specified by the versus + * flag. The algorithm chooses autonomously what algorithm is best suited for + * sorting the list wrt its current status. + * + * @param l list to operate + * @param versus positive: order small to big; negative: order big to small + * @return 0 iff sorting was successful + * + * @see list_attributes_comparator() + */ +int list_sort(list_t *restrict l, int versus); + +/** + * start an iteration session. + * + * This function prepares the list to be iterated. + * + * @param l list to operate + * @return 0 if the list cannot be currently iterated. >0 otherwise + * + * @see list_iterator_stop() + */ +int list_iterator_start(list_t *restrict l); + +/** + * return the next element in the iteration session. + * + * @param l list to operate + * @return element datum, or NULL on errors + */ +void *list_iterator_next(list_t *restrict l); + +/** + * inspect whether more elements are available in the iteration session. + * + * @param l list to operate + * @return 0 iff no more elements are available. + */ +int list_iterator_hasnext(const list_t *restrict l); + +/** + * end an iteration session. + * + * @param l list to operate + * @return 0 iff the iteration session cannot be stopped + */ +int list_iterator_stop(list_t *restrict l); + +/** + * return the hash of the current status of the list. + * + * @param l list to operate + * @param hash where the resulting hash is put + * + * @return 0 for success; <0 for failure + */ +int list_hash(const list_t *restrict l, list_hash_t *restrict hash); + +#ifndef SIMCLIST_NO_DUMPRESTORE +/** + * get meta informations on a list dump on filedescriptor. + * + * [ advanced function ] + * + * Extracts the meta information from a SimCList dump located in a file + * descriptor. The file descriptor must be open and positioned at the + * beginning of the SimCList dump block. + * + * @param fd file descriptor to get metadata from + * @param info reference to a dump metainformation structure to fill + * @return 0 for success; <0 for failure + * + * @see list_dump_filedescriptor() + */ +int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info); + +/** + * get meta informations on a list dump on file. + * + * [ advanced function ] + * + * Extracts the meta information from a SimCList dump located in a file. + * + * @param filename filename of the file to fetch from + * @param info reference to a dump metainformation structure to fill + * @return 0 for success; <0 for failure + * + * @see list_dump_filedescriptor() + */ +int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info); + +/** + * dump the list into an open, writable file descriptor. + * + * This function "dumps" the list to a persistent storage so it can be + * preserved across process terminations. + * When called, the file descriptor must be open for writing and positioned + * where the serialized data must begin. It writes its serialization of the + * list in a form which is portable across different architectures. Dump can + * be safely performed on stream-only (non seekable) descriptors. The file + * descriptor is not closed at the end of the operations. + * + * To use dump functions, either of these conditions must be satisfied: + * -# a metric function has been specified with list_attributes_copy() + * -# a serializer function has been specified with list_attributes_serializer() + * + * If a metric function has been specified, each element of the list is dumped + * as-is from memory, copying it from its pointer for its length down to the + * file descriptor. This might have impacts on portability of the dump to + * different architectures. + * + * If a serializer function has been specified, its result for each element is + * dumped to the file descriptor. + * + * + * @param l list to operate + * @param fd file descriptor to write to + * @param len location to store the resulting length of the dump (bytes), or NULL + * + * @return 0 if successful; -1 otherwise + * + * @see element_serializer() + * @see list_attributes_copy() + * @see list_attributes_serializer() + */ +int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len); + +/** + * dump the list to a file name. + * + * This function creates a filename and dumps the current content of the list + * to it. If the file exists it is overwritten. The number of bytes written to + * the file can be returned in a specified argument. + * + * @param l list to operate + * @param filename filename to write to + * @param len location to store the resulting length of the dump (bytes), or NULL + * + * @return 0 if successful; -1 otherwise + * + * @see list_attributes_copy() + * @see element_serializer() + * @see list_attributes_serializer() + * @see list_dump_filedescriptor() + * @see list_restore_file() + * + * This function stores a representation of the list + */ +int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len); + +/** + * restore the list from an open, readable file descriptor to memory. + * + * This function is the "inverse" of list_dump_filedescriptor(). It restores + * the list content from a (open, read-ready) file descriptor to memory. An + * unserializer might be needed to restore elements from the persistent + * representation back into memory-consistent format. List attributes can not + * be restored and must be set manually. + * + * @see list_dump_filedescriptor() + * @see list_attributes_serializer() + * @see list_attributes_unserializer() + * + * @param l list to restore to + * @param fd file descriptor to read from. + * @param len location to store the length of the dump read (bytes), or NULL + * @return 0 if successful; -1 otherwise + */ +int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len); + +/** + * restore the list from a file name. + * + * This function restores the content of a list from a file into memory. It is + * the inverse of list_dump_file(). + * + * @see element_unserializer() + * @see list_attributes_unserializer() + * @see list_dump_file() + * @see list_restore_filedescriptor() + * + * @param l list to restore to + * @param filename filename to read data from + * @param len location to store the length of the dump read (bytes), or NULL + * @return 0 if successful; -1 otherwise + */ +int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len); +#endif + +/* ready-made comparators, meters and hash computers */ + /* comparator functions */ +/** + * ready-made comparator for int8_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_int8_t(const void *a, const void *b); + +/** + * ready-made comparator for int16_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_int16_t(const void *a, const void *b); + +/** + * ready-made comparator for int32_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_int32_t(const void *a, const void *b); + +/** + * ready-made comparator for int64_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_int64_t(const void *a, const void *b); + +/** + * ready-made comparator for uint8_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_uint8_t(const void *a, const void *b); + +/** + * ready-made comparator for uint16_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_uint16_t(const void *a, const void *b); + +/** + * ready-made comparator for uint32_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_uint32_t(const void *a, const void *b); + +/** + * ready-made comparator for uint64_t elements. + * @see list_attributes_comparator() + */ +int list_comparator_uint64_t(const void *a, const void *b); + +/** + * ready-made comparator for float elements. + * @see list_attributes_comparator() + */ +int list_comparator_float(const void *a, const void *b); + +/** + * ready-made comparator for double elements. + * @see list_attributes_comparator() + */ +int list_comparator_double(const void *a, const void *b); + +/** + * ready-made comparator for string elements. + * @see list_attributes_comparator() + */ +int list_comparator_string(const void *a, const void *b); + + /* metric functions */ +/** + * ready-made metric function for int8_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_int8_t(const void *el); + +/** + * ready-made metric function for int16_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_int16_t(const void *el); + +/** + * ready-made metric function for int32_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_int32_t(const void *el); + +/** + * ready-made metric function for int64_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_int64_t(const void *el); + +/** + * ready-made metric function for uint8_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_uint8_t(const void *el); + +/** + * ready-made metric function for uint16_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_uint16_t(const void *el); + +/** + * ready-made metric function for uint32_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_uint32_t(const void *el); + +/** + * ready-made metric function for uint64_t elements. + * @see list_attributes_copy() + */ +size_t list_meter_uint64_t(const void *el); + +/** + * ready-made metric function for float elements. + * @see list_attributes_copy() + */ +size_t list_meter_float(const void *el); + +/** + * ready-made metric function for double elements. + * @see list_attributes_copy() + */ +size_t list_meter_double(const void *el); + +/** + * ready-made metric function for string elements. + * @see list_attributes_copy() + */ +size_t list_meter_string(const void *el); + + /* hash functions */ +/** + * ready-made hash function for int8_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_int8_t(const void *el); + +/** + * ready-made hash function for int16_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_int16_t(const void *el); + +/** + * ready-made hash function for int32_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_int32_t(const void *el); + +/** + * ready-made hash function for int64_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_int64_t(const void *el); + +/** + * ready-made hash function for uint8_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_uint8_t(const void *el); + +/** + * ready-made hash function for uint16_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_uint16_t(const void *el); + +/** + * ready-made hash function for uint32_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_uint32_t(const void *el); + +/** + * ready-made hash function for uint64_t elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_uint64_t(const void *el); + +/** + * ready-made hash function for float elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_float(const void *el); + +/** + * ready-made hash function for double elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_double(const void *el); + +/** + * ready-made hash function for string elements. + * @see list_attributes_hash_computer() + */ +list_hash_t list_hashcomputer_string(const void *el); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/libs/libks/src/include/table.h b/libs/libks/src/include/table.h new file mode 100644 index 0000000000..687358683d --- /dev/null +++ b/libs/libks/src/include/table.h @@ -0,0 +1,1372 @@ +/* + * Generic table defines... + * + * Copyright 2000 by Gray Watson. + * + * This file is part of the table package. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, + * and that the name of Gray Watson not be used in advertising or + * publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: table.h,v 1.11 2000/03/09 03:30:42 gray Exp $ + */ + +#ifndef __TABLE_H__ +#define __TABLE_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * To build a "key" in any of the below routines, pass in a pointer to + * the key and its size [i.e. sizeof(int), etc]. With any of the + * "key" or "data" arguments, if their size is < 0, it will do an + * internal strlen of the item and add 1 for the \0. + * + * If you are using firstkey() and nextkey() functions, be careful if, + * after starting your firstkey loop, you use delete or insert, it + * will not crash but may produce interesting results. If you are + * deleting from firstkey to NULL it will work fine. + */ + +/* return types for table functions */ +#define TABLE_ERROR_NONE 1 /* no error from function */ +#define TABLE_ERROR_PNT 2 /* bad table pointer */ +#define TABLE_ERROR_ARG_NULL 3 /* buffer args were null */ +#define TABLE_ERROR_SIZE 4 /* size of data was bad */ +#define TABLE_ERROR_OVERWRITE 5 /* key exists and we cant overwrite */ +#define TABLE_ERROR_NOT_FOUND 6 /* key does not exist */ +#define TABLE_ERROR_ALLOC 7 /* memory allocation error */ +#define TABLE_ERROR_LINEAR 8 /* no linear access started */ +#define TABLE_ERROR_OPEN 9 /* could not open file */ +#define TABLE_ERROR_SEEK 10 /* could not seek to pos in file */ +#define TABLE_ERROR_READ 11 /* could not read from file */ +#define TABLE_ERROR_WRITE 12 /* could not write to file */ +#define TABLE_ERROR_MMAP_NONE 13 /* no mmap support */ +#define TABLE_ERROR_MMAP 14 /* could not mmap file */ +#define TABLE_ERROR_MMAP_OP 15 /* can't perform operation on mmap */ +#define TABLE_ERROR_EMPTY 16 /* table is empty */ +#define TABLE_ERROR_NOT_EMPTY 17 /* table contains data */ +#define TABLE_ERROR_ALIGNMENT 18 /* invalid alignment value */ +#define TABLE_ERROR_COMPARE 19 /* problems with internal comparison */ +#define TABLE_ERROR_FREE 20 /* memory free error */ + +/* + * Table flags set with table_attr. + */ + +/* + * Automatically adjust the number of table buckets on the fly. + * Whenever the number of entries gets above some threshold, the + * number of buckets is realloced to a new size and each entry is + * re-hashed. Although this may take some time when it re-hashes, the + * table will perform better over time. + */ +#define TABLE_FLAG_AUTO_ADJUST (1<<0) + +/* + * If the above auto-adjust flag is set, also adjust the number of + * table buckets down as we delete entries. + */ +#define TABLE_FLAG_ADJUST_DOWN (1<<1) + +/* structure to walk through the fields in a linear order */ +typedef struct { + unsigned int tl_magic; /* magic structure to ensure correct init */ + unsigned int tl_bucket_c; /* where in the table buck array we are */ + unsigned int tl_entry_c; /* in the bucket, which entry we are on */ +} table_linear_t; + +/* + * int (*table_compare_t) + * + * DESCRIPTION + * + * Comparison function which compares two key/data pairs for table + * order. + * + * RETURNS: + * + * -1, 0, or 1 if key1 is <, ==, or > than key2. + * + * ARGUMENTS: + * + * key1 - Pointer to the first key entry. + * + * key1_size - Pointer to the size of the first key entry. + * + * data1 - Pointer to the first data entry. + * + * data1_size - Pointer to the size of the first data entry. + * + * key2 - Pointer to the second key entry. + * + * key2_size - Pointer to the size of the second key entry. + * + * data2 - Pointer to the second data entry. + * + * data2_size - Pointer to the size of the second data entry. + */ +typedef int (*table_compare_t)(const void *key1, const int key1_size, + const void *data1, const int data1_size, + const void *key2, const int key2_size, + const void *data2, const int data2_size); + +/* + * int (*table_mem_alloc_t) + * + * DESCRIPTION + * + * Function to override the table's allocation function. + * + * RETURNS: + * + * Success - Newly allocated pointer. + * + * Failure - NULL + * + * ARGUMENTS: + * + * pool_p <-> Pointer to our memory pool. If no pool is set then this + * will be NULL. + * + * size -> Number of bytes that needs to be allocated. + */ +typedef void *(*table_mem_alloc_t)(void *pool_p, const unsigned long size); + +/* + * int (*table_mem_resize_t) + * + * DESCRIPTION + * + * Function to override the table's memory resize function. The + * difference between this and realloc is that this provides the + * previous allocation size. You can specify NULL for this function + * in which cause the library will allocate, copy, and free itself. + * + * RETURNS: + * + * Success - Newly allocated pointer. + * + * Failure - NULL + * + * ARGUMENTS: + * + * pool_p <-> Pointer to our memory pool. If no pool is set then this + * will be NULL. + * + * old_addr -> Previously allocated address. + * + * old_size -> Size of the old address. Since the system is + * lightweight, it does not store size information on the pointer. + * + * new_size -> New size of the allocation. + */ +typedef void *(*table_mem_resize_t)(void *pool_p, void *old_addr, + const unsigned long old_size, + const unsigned long new_size); + +/* + * int (*table_mem_free_t) + * + * DESCRIPTION + * + * Function to override the table's free function. + * + * RETURNS: + * + * Success - 1 + * + * Failure - 0 + * + * ARGUMENTS: + * + * pool_p <-> Pointer to our memory pool. If no pool is set then this + * will be NULL. + * + * addr -> Address that we are freeing. + * + * min_size -> Minimum size of the address being freed or 0 if not + * known. This can also be the exact size if known. + */ +typedef int (*table_mem_free_t)(void *pool_p, void *addr, + const unsigned long min_size); + +#ifdef TABLE_MAIN + +#include "table_loc.h" + +#else + +/* generic table type */ +typedef void table_t; + +/* generic table entry type */ +typedef void table_entry_t; + +#endif + +/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ + +/* + * table_t *table_alloc + * + * DESCRIPTION: + * + * Allocate a new table structure. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_free to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * bucket_n - Number of buckets for the hash table. Our current hash + * value works best with base two numbers. Set to 0 to take the + * library default of 1024. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +extern +table_t *table_alloc(const unsigned int bucket_n, int *error_p); + +/* + * table_t *table_alloc_in_pool + * + * DESCRIPTION: + * + * Allocate a new table structure in a memory pool or using + * alternative allocation and free functions. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_free to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * bucket_n - Number of buckets for the hash table. Our current hash + * value works best with base two numbers. Set to 0 to take the + * library default of 1024. + * + * mem_pool <-> Memory pool to associate with the table. Can be NULL. + * + * alloc_func -> Allocate function we are overriding malloc() with. + * + * resize_func -> Resize function we are overriding the standard + * memory resize/realloc with. This can be NULL in which cause the + * library will allocate, copy, and free itself. + * + * free_func -> Free function we are overriding free() with. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +extern +table_t *table_alloc_in_pool(const unsigned int bucket_n, + void *mem_pool, + table_mem_alloc_t alloc_func, + table_mem_resize_t resize_func, + table_mem_free_t free_func, int *error_p); + +/* + * int table_attr + * + * DESCRIPTION: + * + * Set the attributes for the table. The available attributes are + * specified at the top of table.h. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to a table structure which we will be altering. + * + * attr - Attribute(s) that we will be applying to the table. + */ +extern +int table_attr(table_t *table_p, const int attr); + +/* + * int table_set_data_alignment + * + * DESCRIPTION: + * + * Set the alignment for the data in the table. This is used when you + * want to store binary data types and refer to them directly out of + * the table storage. For instance if you are storing integers as + * data in the table and want to be able to retrieve the location of + * the interger and then increment it as (*loc_p)++. Otherwise you + * would have to memcpy it out to an integer, increment it, and memcpy + * it back. If you are storing character data, no alignment is + * necessary. + * + * For most data elements, sizeof(long) is recommended unless you use + * smaller data types exclusively. + * + * WARNING: If necessary, you must set the data alignment before any + * data gets put into the table. Otherwise a TABLE_ERROR_NOT_EMPTY + * error will be returned. + * + * NOTE: there is no way to set the key data alignment although it + * should automatically be long aligned. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to a table structure which we will be altering. + * + * alignment - Alignment requested for the data. Must be a power of + * 2. Set to 0 for none. + */ +extern +int table_set_data_alignment(table_t *table_p, const int alignment); + +/* + * int table_clear + * + * DESCRIPTION: + * + * Clear out and free all elements in a table structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer that we will be clearing. + */ +extern +int table_clear(table_t *table_p); + +/* + * int table_free + * + * DESCRIPTION: + * + * Deallocates a table structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer that we will be freeing. + */ +extern +int table_free(table_t *table_p); + +/* + * int table_insert_kd + * + * DESCRIPTION: + * + * Like table_insert except it passes back a pointer to the key and + * the data buffers after they have been inserted into the table + * structure. + * + * This routine adds a key/data pair both of which are made up of a + * buffer of bytes and an associated size. Both the key and the data + * will be copied into buffers allocated inside the table. If the key + * exists already, the associated data will be replaced if the + * overwrite flag is set, otherwise an error is returned. + * + * NOTE: be very careful changing the values since the table library + * provides the pointers to its memory. The key can _never_ be + * changed otherwise you will not find it again. The data can be + * changed but its length can never be altered unless you delete and + * re-insert it into the table. + * + * WARNING: The pointers to the key and data are not in any specific + * alignment. Accessing the key and/or data as an short, integer, or + * long pointer directly can cause problems. + * + * WARNING: Replacing a data cell (not inserting) will cause the table + * linked list to be temporarily invalid. Care must be taken with + * multiple threaded programs which are relying on the first/next + * linked list to be always valid. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be inserting a + * new key/data pair. + * + * key_buf - Buffer of bytes of the key that we are inserting. If you + * are storing an (int) as the key (for example) then key_buf should + * be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are storing an (int) as the key (for example) then key_size should + * be sizeof(int). + * + * data_buf - Buffer of bytes of the data that we are inserting. If + * it is NULL then the library will allocate space for the data in the + * table without copying in any information. If data_buf is NULL and + * data_size is 0 then the library will associate a NULL data pointer + * with the key. If you are storing a (long) as the data (for + * example) then data_buf should be a (long *). + * + * data_size - Size of the data_buf buffer. If set to < 0 then the + * library will do a strlen of data_buf and add 1 for the '\0'. If + * you are storing an (long) as the key (for example) then key_size + * should be sizeof(long). + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the key storage that was allocated in the table. If you are + * storing an (int) as the key (for example) then key_buf_p should be + * (int **) i.e. the address of a (int *). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table. If you are + * storing an (long) as the data (for example) then data_buf_p should + * be (long **) i.e. the address of a (long *). + * + * overwrite - Flag which, if set to 1, will allow the overwriting of + * the data in the table with the new data if the key already exists + * in the table. + */ +extern +int table_insert_kd(table_t *table_p, + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **key_buf_p, void **data_buf_p, + const char overwrite_b); + +/* + * int table_insert + * + * DESCRIPTION: + * + * Exactly the same as table_insert_kd except it does not pass back a + * pointer to the key after they have been inserted into the table + * structure. This is still here for backwards compatibility. + * + * See table_insert_kd for more information. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be inserting a + * new key/data pair. + * + * key_buf - Buffer of bytes of the key that we are inserting. If you + * are storing an (int) as the key (for example) then key_buf should + * be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are storing an (int) as the key (for example) then key_size should + * be sizeof(int). + * + * data_buf - Buffer of bytes of the data that we are inserting. If + * it is NULL then the library will allocate space for the data in the + * table without copying in any information. If data_buf is NULL and + * data_size is 0 then the library will associate a NULL data pointer + * with the key. If you are storing a (long) as the data (for + * example) then data_buf should be a (long *). + * + * data_size - Size of the data_buf buffer. If set to < 0 then the + * library will do a strlen of data_buf and add 1 for the '\0'. If + * you are storing an (long) as the key (for example) then key_size + * should be sizeof(long). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table. If you are + * storing an (long) as the data (for example) then data_buf_p should + * be (long **) i.e. the address of a (long *). + * + * overwrite - Flag which, if set to 1, will allow the overwriting of + * the data in the table with the new data if the key already exists + * in the table. + */ +extern +int table_insert(table_t *table_p, + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **data_buf_p, const char overwrite_b); + +/* + * int table_retrieve + * + * DESCRIPTION: + * + * This routine looks up a key made up of a buffer of bytes and an + * associated size in the table. If found then it returns the + * associated data information. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be searching + * for the key. + * + * key_buf - Buffer of bytes of the key that we are searching for. If + * you are looking for an (int) as the key (for example) then key_buf + * should be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are looking for an (int) as the key (for example) then key_size + * should be sizeof(int). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that is + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data stored in the table that is associated with + * the key. + */ +extern +int table_retrieve(table_t *table_p, + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p); + +/* + * int table_delete + * + * DESCRIPTION: + * + * This routine looks up a key made up of a buffer of bytes and an + * associated size in the table. If found then it will be removed + * from the table. The associated data can be passed back to the user + * if requested. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * NOTE: this could be an allocation error if the library is to return + * the data to the user. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we will be deleteing + * the key. + * + * key_buf - Buffer of bytes of the key that we are searching for to + * delete. If you are deleting an (int) key (for example) then + * key_buf should be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are deleting an (int) key (for example) then key_size should be + * sizeof(int). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that was + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). If a pointer is passed in, the caller is responsible for + * freeing it after use. If data_buf_p is NULL then the library will + * free up the data allocation itself. + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that was stored in the table and that was + * associated with the key. + */ +extern +int table_delete(table_t *table_p, + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p); + +/* + * int table_delete_first + * + * DESCRIPTION: + * + * This is like the table_delete routines except it deletes the first + * key/data pair in the table instead of an entry corresponding to a + * particular key. The associated key and data information can be + * passed back to the user if requested. This routines is handy to + * clear out a table. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * NOTE: this could be an allocation error if the library is to return + * the data to the user. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we will be deleteing + * the first key. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that was allocated in the table. + * If an (int) was stored as the first key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). If a + * pointer is passed in, the caller is responsible for freeing it + * after use. If key_buf_p is NULL then the library will free up the + * key allocation itself. + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that was stored in the table and that was + * associated with the key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that was + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). If a pointer is passed in, the caller is responsible for + * freeing it after use. If data_buf_p is NULL then the library will + * free up the data allocation itself. + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that was stored in the table and that was + * associated with the key. + */ +extern +int table_delete_first(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * int table_info + * + * DESCRIPTION: + * + * Get some information about a table_p structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting + * information. + * + * num_buckets_p - Pointer to an integer which, if not NULL, will + * contain the number of buckets in the table. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries stored in the table. + */ +extern +int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p); + +/* + * int table_adjust + * + * DESCRIPTION: + * + * Set the number of buckets in a table to a certain value. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer of which we are adjusting. + * + * bucket_n - Number buckets to adjust the table to. Set to 0 to + * adjust the table to its number of entries. + */ +extern +int table_adjust(table_t *table_p, const int bucket_n); + +/* + * int table_type_size + * + * DESCRIPTION: + * + * Return the size of the internal table type. + * + * RETURNS: + * + * The size of the table_t type. + * + * ARGUMENTS: + * + * None. + */ +extern +int table_type_size(void); + +/* + * int table_first + * + * DESCRIPTION: + * + * Find first element in a table and pass back information about the + * key/data pair. If any of the key/data pointers are NULL then they + * are ignored. + * + * NOTE: This function is not reentrant. More than one thread cannot + * be doing a first and next on the same table at the same time. Use + * the table_first_r version below for this. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * first element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that is allocated in the table. If + * an (int) is stored as the first key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the first key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the first key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the first key. + */ +extern +int table_first(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * int table_next + * + * DESCRIPTION: + * + * Find the next element in a table and pass back information about + * the key/data pair. If any of the key/data pointers are NULL then + * they are ignored. + * + * NOTE: This function is not reentrant. More than one thread cannot + * be doing a first and next on the same table at the same time. Use + * the table_next_r version below for this. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * next element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the next key that is allocated in the table. If + * an (int) is stored as the next key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the next key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the next key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the next key. + */ +extern +int table_next(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * int table_this + * + * DESCRIPTION: + * + * Find the current element in a table and pass back information about + * the key/data pair. If any of the key/data pointers are NULL then + * they are ignored. + * + * NOTE: This function is not reentrant. Use the table_current_r + * version below. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * current element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the current key that is allocated in the table. + * If an (int) is stored as the current key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the current key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the current key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the current key. + */ +extern +int table_this(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * int table_first_r + * + * DESCRIPTION: + * + * Reetrant version of the table_first routine above. Find first + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * first element. + * + * linear_p - Pointer to a table linear structure which is initialized + * here. The same pointer should then be passed to table_next_r + * below. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that is allocated in the table. If + * an (int) is stored as the first key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the first key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the first key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the first key. + */ +extern +int table_first_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * int table_next_r + * + * DESCRIPTION: + * + * Reetrant version of the table_next routine above. Find next + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * next element. + * + * linear_p - Pointer to a table linear structure which is incremented + * here. The same pointer must have been passed to table_first_r + * first so that it can be initialized. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the next key that is allocated in the table. If + * an (int) is stored as the next key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL will be set + * to the size of the key that is stored in the table and that is + * associated with the next key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the next key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the next key. + */ +extern +int table_next_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * int table_this_r + * + * DESCRIPTION: + * + * Reetrant version of the table_this routine above. Find current + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * current element. + * + * linear_p - Pointer to a table linear structure which is accessed + * here. The same pointer must have been passed to table_first_r + * first so that it can be initialized. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the current key that is allocated in the table. + * If an (int) is stored as the current key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the current key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the current key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the current key. + */ +extern +int table_this_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * table_t *table_mmap + * + * DESCRIPTION: + * + * Mmap a table from a file that had been written to disk earlier via + * table_write. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_munmap to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * path - Table file to mmap in. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +extern +table_t *table_mmap(const char *path, int *error_p); + +/* + * int table_munmap + * + * DESCRIPTION: + * + * Unmmap a table that was previously mmapped using table_mmap. + * + * RETURNS: + * + * Returns table error codes. + * + * ARGUMENTS: + * + * table_p - Mmaped table pointer to unmap. + */ +extern +int table_munmap(table_t *table_p); + +/* + * int table_read + * + * DESCRIPTION: + * + * Read in a table from a file that had been written to disk earlier + * via table_write. + * + * RETURNS: + * + * Success - Pointer to the new table structure which must be passed + * to table_free to be deallocated. + * + * Failure - NULL + * + * ARGUMENTS: + * + * path - Table file to read in. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +extern +table_t *table_read(const char *path, int *error_p); + +/* + * int table_write + * + * DESCRIPTION: + * + * Write a table from memory to file. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are writing to the file. + * + * path - Table file to write out to. + * + * mode - Mode of the file. This argument is passed on to open when + * the file is created. + */ +extern +int table_write(const table_t *table_p, const char *path, const int mode); + +/* + * table_entry_t *table_order + * + * DESCRIPTION: + * + * Order a table by building an array of table entry pointers and then + * sorting this array using the qsort function. To retrieve the + * sorted entries, you can then use the table_entry routine to access + * each entry in order. + * + * NOTE: This routine is thread safe and makes use of an internal + * status qsort function. + * + * RETURNS: + * + * Success - An allocated list of table-linear structures which must + * be freed by table_order_free later. + * + * Failure - NULL + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are ordering. + * + * compare - Comparison function defined by the user. Its definition + * is at the top of the table.h file. If this is NULL then it will + * order the table my memcmp-ing the keys. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries in the returned entry pointer array. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +extern +table_entry_t **table_order(table_t *table_p, table_compare_t compare, + int *num_entries_p, int *error_p); + +/* + * int table_order_free + * + * DESCRIPTION: + * + * Free the pointer returned by the table_order or table_order_pos + * routines. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table. + * + * table_entries - Allocated list of entry pointers returned by + * table_order. + * + * entry_n - Number of entries in the array as passed back by + * table_order or table_order_pos in num_entries_p. + */ +extern +int table_order_free(table_t *table_p, table_entry_t **table_entries, + const int entry_n); + +/* + * int table_entry + * + * DESCRIPTION: + * + * Get information about an element. The element is one from the + * array returned by the table_order function. If any of the key/data + * pointers are NULL then they are ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * element. + * + * entry_p - Pointer to a table entry from the array returned by the + * table_order function. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of this entry that is allocated in the table. If an + * (int) is stored as this entry (for example) then key_buf_p should + * be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage of this entry that is allocated in the table. + * If a (long) is stored as this entry data (for example) then + * data_buf_p should be (long **) i.e. the address of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table. + */ +extern +int table_entry(table_t *table_p, table_entry_t *entry_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * table_linear_t *table_order_pos + * + * DESCRIPTION: + * + * Order a table by building an array of table linear structures and + * then sorting this array using the qsort function. To retrieve the + * sorted entries, you can then use the table_entry_pos routine to + * access each entry in order. + * + * NOTE: This routine is thread safe and makes use of an internal + * status qsort function. + * + * RETURNS: + * + * Success - An allocated list of table-linear structures which must + * be freed by table_order_pos_free later. + * + * Failure - NULL + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are ordering. + * + * compare - Comparison function defined by the user. Its definition + * is at the top of the table.h file. If this is NULL then it will + * order the table my memcmp-ing the keys. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries in the returned entry pointer array. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +extern +table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare, + int *num_entries_p, int *error_p); + +/* + * int table_order_pos_free + * + * DESCRIPTION: + * + * Free the pointer returned by the table_order or table_order_pos + * routines. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table. + * + * table_entries - Allocated list of entry pointers returned by + * table_order_pos. + * + * entry_n - Number of entries in the array as passed back by + * table_order or table_order_pos in num_entries_p. + */ +extern +int table_order_pos_free(table_t *table_p, table_linear_t *table_entries, + const int entry_n); + +/* + * int table_entry_pos + * + * DESCRIPTION: + * + * Get information about an element. The element is one from the + * array returned by the table_order function. If any of the key/data + * pointers are NULL then they are ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * element. + * + * linear_p - Pointer to a table linear structure from the array + * returned by the table_order function. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of this entry that is allocated in the table. If an + * (int) is stored as this entry (for example) then key_buf_p should + * be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage of this entry that is allocated in the table. + * If a (long) is stored as this entry data (for example) then + * data_buf_p should be (long **) i.e. the address of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table. + */ +extern +int table_entry_pos(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); + +/* + * const char *table_strerror + * + * DESCRIPTION: + * + * Return the corresponding string for the error number. + * + * RETURNS: + * + * Success - String equivalient of the error. + * + * Failure - String "invalid error code" + * + * ARGUMENTS: + * + * error - Error number that we are converting. + */ +extern +const char *table_strerror(const int error); + +/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ! __TABLE_H__ */ diff --git a/libs/libks/src/include/table_loc.h b/libs/libks/src/include/table_loc.h new file mode 100644 index 0000000000..02514c8211 --- /dev/null +++ b/libs/libks/src/include/table_loc.h @@ -0,0 +1,229 @@ +/* + * local defines for the table module + * + * Copyright 2000 by Gray Watson. + * + * This file is part of the table package. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, + * and that the name of Gray Watson not be used in advertising or + * publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: table_loc.h,v 1.11 2000/03/09 03:30:42 gray Exp $ + */ + +#ifndef __TABLE_LOC_H__ +#define __TABLE_LOC_H__ + +#ifndef unix +#define NO_MMAP +#endif + +#ifndef BITSPERBYTE +#define BITSPERBYTE 8 +#endif +#ifndef BITS +#define BITS(type) (BITSPERBYTE * (int)sizeof(type)) +#endif + +#define TABLE_MAGIC 0xBADF00D /* very magic magicness */ +#define LINEAR_MAGIC 0xAD00D00 /* magic value for linear struct */ +#define DEFAULT_SIZE 1024 /* default table size */ +#define MAX_ALIGNMENT 128 /* max alignment value */ + +/* + * Maximum number of splits. This should mean that these routines can + * handle at least 2^128 different values (that's _quite_ a few). And + * then you can always increase the value. + */ +#define MAX_QSORT_SPLITS 128 + +/* + * Maximum number of entries that must be in list for it to be + * partitioned. If there are fewer elements then just do our + * insertion sort. + */ +#define MAX_QSORT_MANY 8 + +/* + * Macros. + */ + +/* returns 1 when we should grow or shrink the table */ +#define SHOULD_TABLE_GROW(tab) ((tab)->ta_entry_n > (tab)->ta_bucket_n * 2) +#define SHOULD_TABLE_SHRINK(tab) ((tab)->ta_entry_n < (tab)->ta_bucket_n / 2) + +/* + * void HASH_MIX + * + * DESCRIPTION: + * + * Mix 3 32-bit values reversibly. For every delta with one or two + * bits set, and the deltas of all three high bits or all three low + * bits, whether the original value of a,b,c is almost all zero or is + * uniformly distributed. + * + * If HASH_MIX() is run forward or backward, at least 32 bits in a,b,c + * have at least 1/4 probability of changing. If mix() is run + * forward, every bit of c will change between 1/3 and 2/3 of the + * time. (Well, 22/100 and 78/100 for some 2-bit deltas.) + * + * HASH_MIX() takes 36 machine instructions, but only 18 cycles on a + * superscalar machine (like a Pentium or a Sparc). No faster mixer + * seems to work, that's the result of my brute-force search. There + * were about 2^68 hashes to choose from. I only tested about a + * billion of those. + */ +#define HASH_MIX(a, b, c) \ + do { \ + a -= b; a -= c; a ^= (c >> 13); \ + b -= c; b -= a; b ^= (a << 8); \ + c -= a; c -= b; c ^= (b >> 13); \ + a -= b; a -= c; a ^= (c >> 12); \ + b -= c; b -= a; b ^= (a << 16); \ + c -= a; c -= b; c ^= (b >> 5); \ + a -= b; a -= c; a ^= (c >> 3); \ + b -= c; b -= a; b ^= (a << 10); \ + c -= a; c -= b; c ^= (b >> 15); \ + } while(0) + +#define SET_POINTER(pnt, val) \ + do { \ + if ((pnt) != NULL) { \ + (*(pnt)) = (val); \ + } \ + } while(0) + +/* + * The following macros take care of the mmap case. When we are + * mmaping a table from a disk file, all of the pointers in the table + * structures are replaced with offsets into the file. The following + * macro, for each pointer, adds the starting address of the mmaped + * section onto each pointer/offset turning it back into a legitimate + * pointer. + */ +#ifdef NO_MMAP + +#define TABLE_POINTER(table, type, pnt) (pnt) + +#else + +#define TABLE_POINTER(tab_p, type, pnt) \ + ((tab_p)->ta_mmap == NULL || (pnt) == NULL ? (pnt) : \ + (type)((char *)((tab_p)->ta_mmap) + (long)(pnt))) + +#endif + +/* + * Macros to get at the key and the data pointers + */ +#define ENTRY_KEY_BUF(entry_p) ((entry_p)->te_key_buf) +#define ENTRY_DATA_BUF(tab_p, entry_p) \ + (ENTRY_KEY_BUF(entry_p) + (entry_p)->te_key_size) + +/* + * Table structures... + */ + +/* + * HACK: this should be equiv as the table_entry_t without the key_buf + * char. We use this with the ENTRY_SIZE() macro above which solves + * the problem with the lack of the [0] GNU hack. We use the + * table_entry_t structure to better map the memory and make things + * faster. + */ +typedef struct table_shell_st { + unsigned int te_key_size; /* size of data */ + unsigned int te_data_size; /* size of data */ + struct table_shell_st *te_next_p; /* pointer to next in the list */ + /* NOTE: this does not have the te_key_buf field here */ +} table_shell_t; + +/* + * Elements in the bucket linked-lists. The key[1] is the start of + * the key with the rest of the key and all of the data information + * packed in memory directly after the end of this structure. + * + * NOTE: if this structure is changed, the table_shell_t must be + * changed to match. + */ +typedef struct table_entry_st { + unsigned int te_key_size; /* size of data */ + unsigned int te_data_size; /* size of data */ + struct table_entry_st *te_next_p; /* pointer to next in the list */ + unsigned char te_key_buf[1]; /* 1st byte of key buf */ +} table_entry_t; + +/* external structure for debuggers be able to see void */ +typedef table_entry_t table_entry_ext_t; + +/* main table structure */ +typedef struct table_st { + unsigned int ta_magic; /* magic number */ + unsigned int ta_flags; /* table's flags defined in table.h */ + unsigned int ta_bucket_n; /* num of buckets, should be 2^X */ + unsigned int ta_entry_n; /* num of entries in all buckets */ + unsigned int ta_data_align; /* data alignment value */ + table_entry_t **ta_buckets; /* array of linked lists */ + table_linear_t ta_linear; /* linear tracking */ + struct table_st *ta_mmap; /* mmaped table */ + unsigned long ta_file_size; /* size of on-disk space */ + + void *ta_mem_pool; /* pointer to some memory pool */ + table_mem_alloc_t ta_alloc_func; /* memory allocation function */ + table_mem_resize_t ta_resize_func; /* memory resize function */ + table_mem_free_t ta_free_func; /* memory free function */ +} table_t; + +/* external table structure for debuggers */ +typedef table_t table_ext_t; + +/* local comparison functions */ +typedef int (*compare_t)(const void *element1_p, const void *element2_p, + table_compare_t user_compare, + const table_t *table_p, int *err_bp); + +/* + * to map error to string + */ +typedef struct { + int es_error; /* error number */ + char *es_string; /* assocaited string */ +} error_str_t; + +static error_str_t errors[] = { + { TABLE_ERROR_NONE, "no error" }, + { TABLE_ERROR_PNT, "invalid table pointer" }, + { TABLE_ERROR_ARG_NULL, "buffer argument is null" }, + { TABLE_ERROR_SIZE, "incorrect size argument" }, + { TABLE_ERROR_OVERWRITE, "key exists and no overwrite" }, + { TABLE_ERROR_NOT_FOUND, "key does not exist" }, + { TABLE_ERROR_ALLOC, "error allocating memory" }, + { TABLE_ERROR_LINEAR, "linear access not in progress" }, + { TABLE_ERROR_OPEN, "could not open file" }, + { TABLE_ERROR_SEEK, "could not seek to position in file" }, + { TABLE_ERROR_READ, "could not read from file" }, + { TABLE_ERROR_WRITE, "could not write to file" }, + { TABLE_ERROR_MMAP_NONE, "no mmap support compiled in library" }, + { TABLE_ERROR_MMAP, "could not mmap the file" }, + { TABLE_ERROR_MMAP_OP, "operation not valid on mmap files" }, + { TABLE_ERROR_EMPTY, "table is empty" }, + { TABLE_ERROR_NOT_EMPTY, "table contains data" }, + { TABLE_ERROR_ALIGNMENT, "invalid alignment value" }, + { TABLE_ERROR_COMPARE, "problems with internal comparison" }, + { TABLE_ERROR_FREE, "memory free error" }, + { 0 } +}; + +#define INVALID_ERROR "invalid error code" + +#endif /* ! __TABLE_LOC_H__ */ diff --git a/libs/libks/src/ks.c b/libs/libks/src/ks.c new file mode 100644 index 0000000000..b328f36798 --- /dev/null +++ b/libs/libks/src/ks.c @@ -0,0 +1,739 @@ +/* + * Copyright (c) 2007-2012, 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. + */ + + +/* Use select on windows and poll everywhere else. + Select is the devil. Especially if you are doing a lot of small socket connections. + If your FD number is bigger than 1024 you will silently create memory corruption. + + If you have build errors on your platform because you don't have poll find a way to detect it and #define KS_USE_SELECT and #undef KS_USE_POLL + All of this will be upgraded to autoheadache eventually. +*/ + +/* TBD for win32 figure out how to tell if you have WSAPoll (vista or higher) and use it when available by #defining KS_USE_WSAPOLL (see below) */ + +#ifdef _MSC_VER +#define FD_SETSIZE 8192 +#define KS_USE_SELECT +#else +#define KS_USE_POLL +#endif + +#include +#ifndef WIN32 +#define closesocket(x) shutdown(x, 2); close(x) +#include +#include +#else +#pragma warning (disable:6386) +/* These warnings need to be ignored warning in sdk header */ +#include +#include +#ifndef errno +#define errno WSAGetLastError() +#endif +#ifndef EINTR +#define EINTR WSAEINTR +#endif +#pragma warning (default:6386) +#endif + +#ifdef KS_USE_POLL +#include +#endif + +#ifndef KS_MIN +#define KS_MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef KS_MAX +#define KS_MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef KS_CLAMP +#define KS_CLAMP(min,max,val) (KS_MIN(max,KS_MAX(val,min))) +#endif + + +/* Written by Marc Espie, public domain */ +#define KS_CTYPE_NUM_CHARS 256 + +const short _ks_C_toupper_[1 + KS_CTYPE_NUM_CHARS] = { + EOF, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +const short *_ks_toupper_tab_ = _ks_C_toupper_; + +KS_DECLARE(int) ks_toupper(int c) +{ + if ((unsigned int)c > 255) + return(c); + if (c < -1) + return EOF; + return((_ks_toupper_tab_ + 1)[c]); +} + +const short _ks_C_tolower_[1 + KS_CTYPE_NUM_CHARS] = { + EOF, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +const short *_ks_tolower_tab_ = _ks_C_tolower_; + +KS_DECLARE(int) ks_tolower(int c) +{ + if ((unsigned int)c > 255) + return(c); + if (c < -1) + return EOF; + return((_ks_tolower_tab_ + 1)[c]); +} + +KS_DECLARE(const char *)ks_stristr(const char *instr, const char *str) +{ +/* +** Rev History: 16/07/97 Greg Thayer Optimized +** 07/04/95 Bob Stout ANSI-fy +** 02/03/94 Fred Cole Original +** 09/01/03 Bob Stout Bug fix (lines 40-41) per Fred Bulback +** +** Hereby donated to public domain. +*/ + const char *pptr, *sptr, *start; + + if (!str || !instr) + return NULL; + + for (start = str; *start; start++) { + /* find start of pattern in string */ + for (; ((*start) && (ks_toupper(*start) != ks_toupper(*instr))); start++); + + if (!*start) + return NULL; + + pptr = instr; + sptr = start; + + while (ks_toupper(*sptr) == ks_toupper(*pptr)) { + sptr++; + pptr++; + + /* if end of pattern then pattern was found */ + if (!*pptr) + return (start); + + if (!*sptr) + return NULL; + } + } + return NULL; +} + +#ifdef WIN32 +#ifndef vsnprintf +#define vsnprintf _vsnprintf +#endif +#endif + + +int vasprintf(char **ret, const char *format, va_list ap); + +KS_DECLARE(int) ks_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 +} + + + + +KS_DECLARE(int) ks_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 int ks_log_level = 7; + +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 > ks_log_level) { + return; + } + + fp = cut_path(file); + + va_start(ap, fmt); + + ret = ks_vasprintf(&data, fmt, ap); + + if (ret != -1) { + fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data); + free(data); + } + + va_end(ap); + +} + +ks_logger_t ks_log = null_logger; + +KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger) +{ + if (logger) { + ks_log = logger; + } else { + ks_log = null_logger; + } +} + +KS_DECLARE(void) ks_global_set_default_logger(int level) +{ + if (level < 0 || level > 7) { + level = 7; + } + + ks_log = default_logger; + ks_log_level = level; +} + +KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len) +{ + const char *p; + size_t x = 0; + const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}"; + const char hex[] = "0123456789ABCDEF"; + + if (!buf) { + return 0; + } + + if (!url) { + return 0; + } + + len--; + + for (p = url; *p; p++) { + if (x >= len) { + break; + } + if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) { + if ((x + 3) >= len) { + break; + } + buf[x++] = '%'; + buf[x++] = hex[*p >> 4]; + buf[x++] = hex[*p & 0x0f]; + } else { + buf[x++] = *p; + } + } + buf[x] = '\0'; + + return x; +} + +KS_DECLARE(char *)ks_url_decode(char *s) +{ + char *o; + unsigned int tmp; + + for (o = s; *s; s++, o++) { + if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) { + *o = (char) tmp; + s += 2; + } else { + *o = *s; + } + } + *o = '\0'; + return s; +} + + +static int ks_socket_reuseaddr(ks_socket_t socket) +{ +#ifdef WIN32 + BOOL reuse_addr = TRUE; + return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr, sizeof(reuse_addr)); +#else + int reuse_addr = 1; + return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr)); +#endif +} + + +struct thread_handler { + ks_listen_callback_t callback; + ks_socket_t server_sock; + ks_socket_t client_sock; + struct sockaddr_in addr; +}; + +static void *client_thread(ks_thread_t *me, void *obj) +{ + struct thread_handler *handler = (struct thread_handler *) obj; + + handler->callback(handler->server_sock, handler->client_sock, &handler->addr); + free(handler); + + return NULL; + +} + +KS_DECLARE(ks_status_t) ks_listen(const char *host, ks_port_t port, ks_listen_callback_t callback) +{ + ks_socket_t server_sock = KS_SOCK_INVALID; + struct sockaddr_in addr; + ks_status_t status = KS_SUCCESS; + + if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return KS_FAIL; + } + + ks_socket_reuseaddr(server_sock); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + + if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + status = KS_FAIL; + goto end; + } + + if (listen(server_sock, 10000) < 0) { + status = KS_FAIL; + goto end; + } + + for (;;) { + int client_sock; + struct sockaddr_in echoClntAddr; +#ifdef WIN32 + int clntLen; +#else + unsigned int clntLen; +#endif + + clntLen = sizeof(echoClntAddr); + + if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == KS_SOCK_INVALID) { + status = KS_FAIL; + goto end; + } + + callback(server_sock, client_sock, &echoClntAddr); + } + + end: + + if (server_sock != KS_SOCK_INVALID) { + closesocket(server_sock); + server_sock = KS_SOCK_INVALID; + } + + return status; + +} + +KS_DECLARE(ks_status_t) ks_listen_threaded(const char *host, ks_port_t port, ks_listen_callback_t callback, int max) +{ + ks_socket_t server_sock = KS_SOCK_INVALID; + struct sockaddr_in addr; + ks_status_t status = KS_SUCCESS; + struct thread_handler *handler = NULL; + + if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + return KS_FAIL; + } + + ks_socket_reuseaddr(server_sock); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + + if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + status = KS_FAIL; + goto end; + } + + if (listen(server_sock, max) < 0) { + status = KS_FAIL; + goto end; + } + + for (;;) { + int client_sock; + struct sockaddr_in echoClntAddr; +#ifdef WIN32 + int clntLen; +#else + unsigned int clntLen; +#endif + + clntLen = sizeof(echoClntAddr); + + if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == KS_SOCK_INVALID) { + status = KS_FAIL; + goto end; + } + + handler = malloc(sizeof(*handler)); + ks_assert(handler); + + memset(handler, 0, sizeof(*handler)); + handler->callback = callback; + handler->server_sock = server_sock; + handler->client_sock = client_sock; + handler->addr = echoClntAddr; + + ks_thread_create_detached(client_thread, handler); + } + + end: + + if (server_sock != KS_SOCK_INVALID) { + closesocket(server_sock); + server_sock = KS_SOCK_INVALID; + } + + return status; + +} + + +/* USE WSAPoll on vista or higher */ +#ifdef KS_USE_WSAPOLL +KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags) +{ +} +#endif + + +#ifdef KS_USE_SELECT +#ifdef WIN32 +#pragma warning( push ) +#pragma warning( disable : 6262 ) /* warning C6262: Function uses '98348' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap */ +#endif +KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags) +{ + int s = 0, r = 0; + fd_set rfds; + fd_set wfds; + fd_set efds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + +#ifndef WIN32 + /* Wouldn't you rather know?? */ + assert(sock <= FD_SETSIZE); +#endif + + if ((flags & KS_POLL_READ)) { + +#ifdef WIN32 +#pragma warning( push ) +#pragma warning( disable : 4127 ) + FD_SET(sock, &rfds); +#pragma warning( pop ) +#else + FD_SET(sock, &rfds); +#endif + } + + if ((flags & KS_POLL_WRITE)) { + +#ifdef WIN32 +#pragma warning( push ) +#pragma warning( disable : 4127 ) + FD_SET(sock, &wfds); +#pragma warning( pop ) +#else + FD_SET(sock, &wfds); +#endif + } + + if ((flags & KS_POLL_ERROR)) { + +#ifdef WIN32 +#pragma warning( push ) +#pragma warning( disable : 4127 ) + FD_SET(sock, &efds); +#pragma warning( pop ) +#else + FD_SET(sock, &efds); +#endif + } + + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * ms; + + s = select(sock + 1, (flags & KS_POLL_READ) ? &rfds : NULL, (flags & KS_POLL_WRITE) ? &wfds : NULL, (flags & KS_POLL_ERROR) ? &efds : NULL, &tv); + + if (s < 0) { + r = s; + } else if (s > 0) { + if ((flags & KS_POLL_READ) && FD_ISSET(sock, &rfds)) { + r |= KS_POLL_READ; + } + + if ((flags & KS_POLL_WRITE) && FD_ISSET(sock, &wfds)) { + r |= KS_POLL_WRITE; + } + + if ((flags & KS_POLL_ERROR) && FD_ISSET(sock, &efds)) { + r |= KS_POLL_ERROR; + } + } + + return r; + +} +#ifdef WIN32 +#pragma warning( pop ) +#endif +#endif + +#ifdef KS_USE_POLL +KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags) +{ + struct pollfd pfds[2] = { { 0 } }; + int s = 0, r = 0; + + pfds[0].fd = sock; + + if ((flags & KS_POLL_READ)) { + pfds[0].events |= POLLIN; + } + + if ((flags & KS_POLL_WRITE)) { + pfds[0].events |= POLLOUT; + } + + if ((flags & KS_POLL_ERROR)) { + pfds[0].events |= POLLERR; + } + + s = poll(pfds, 1, ms); + + if (s < 0) { + r = s; + } else if (s > 0) { + if ((pfds[0].revents & POLLIN)) { + r |= KS_POLL_READ; + } + if ((pfds[0].revents & POLLOUT)) { + r |= KS_POLL_WRITE; + } + if ((pfds[0].revents & POLLERR)) { + r |= KS_POLL_ERROR; + } + } + + return r; + +} +#endif + + +KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen) +{ + unsigned int count = 0; + char *d; + size_t dlen = strlen(delim); + + array[count++] = buf; + + while (count < arraylen && array[count - 1]) { + if ((d = strstr(array[count - 1], delim))) { + *d = '\0'; + d += dlen; + array[count++] = d; + } else + break; + } + + return count; +} + diff --git a/libs/libks/src/ks_buffer.c b/libs/libks/src/ks_buffer.c new file mode 100644 index 0000000000..469296a3a9 --- /dev/null +++ b/libs/libks/src/ks_buffer.c @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2010-2012, 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 "ks_buffer.h" + +static unsigned buffer_id = 0; + +struct ks_buffer { + unsigned char *data; + unsigned char *head; + ks_size_t used; + ks_size_t actually_used; + ks_size_t datalen; + ks_size_t max_len; + ks_size_t blocksize; + unsigned id; + int loops; +}; + + +KS_DECLARE(ks_status_t) ks_buffer_create(ks_buffer_t **buffer, ks_size_t blocksize, ks_size_t start_len, ks_size_t max_len) +{ + ks_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 KS_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 KS_SUCCESS; + } + + return KS_FAIL; +} + +KS_DECLARE(ks_size_t) ks_buffer_len(ks_buffer_t *buffer) +{ + + ks_assert(buffer != NULL); + + return buffer->datalen; + +} + + +KS_DECLARE(ks_size_t) ks_buffer_freespace(ks_buffer_t *buffer) +{ + ks_assert(buffer != NULL); + + if (buffer->max_len) { + return (ks_size_t) (buffer->max_len - buffer->used); + } + return 1000000; + +} + +KS_DECLARE(ks_size_t) ks_buffer_inuse(ks_buffer_t *buffer) +{ + ks_assert(buffer != NULL); + + return buffer->used; +} + +KS_DECLARE(ks_size_t) ks_buffer_seek(ks_buffer_t *buffer, ks_size_t datalen) +{ + ks_size_t reading = 0; + + ks_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; +} + +KS_DECLARE(ks_size_t) ks_buffer_toss(ks_buffer_t *buffer, ks_size_t datalen) +{ + ks_size_t reading = 0; + + ks_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; +} + +KS_DECLARE(void) ks_buffer_set_loops(ks_buffer_t *buffer, int loops) +{ + buffer->loops = loops; +} + +KS_DECLARE(ks_size_t) ks_buffer_read_loop(ks_buffer_t *buffer, void *data, ks_size_t datalen) +{ + ks_size_t len; + if ((len = ks_buffer_read(buffer, data, datalen)) < datalen) { + if (buffer->loops == 0) { + return len; + } + buffer->head = buffer->data; + buffer->used = buffer->actually_used; + len = ks_buffer_read(buffer, (char*)data + len, datalen - len); + buffer->loops--; + } + return len; +} + +KS_DECLARE(ks_size_t) ks_buffer_read(ks_buffer_t *buffer, void *data, ks_size_t datalen) +{ + ks_size_t reading = 0; + + ks_assert(buffer != NULL); + ks_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; +} + + +KS_DECLARE(ks_size_t) ks_buffer_packet_count(ks_buffer_t *buffer) +{ + char *pe, *p, *e, *head = (char *) buffer->head; + ks_size_t x = 0; + + ks_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; +} + +KS_DECLARE(ks_size_t) ks_buffer_read_packet(ks_buffer_t *buffer, void *data, ks_size_t maxlen) +{ + char *pe, *p, *e, *head = (char *) buffer->head; + ks_size_t datalen = 0; + + ks_assert(buffer != NULL); + ks_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 ks_buffer_read(buffer, data, datalen); +} + +KS_DECLARE(ks_size_t) ks_buffer_write(ks_buffer_t *buffer, const void *data, ks_size_t datalen) +{ + ks_size_t freespace, actual_freespace; + + ks_assert(buffer != NULL); + ks_assert(data != NULL); + ks_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) { + ks_size_t new_size, new_block_size; + void *data1; + + 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; + data1 = realloc(buffer->data, new_size); + if (!data1) { + return 0; + } + buffer->data = data1; + 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; +} + +KS_DECLARE(void) ks_buffer_zero(ks_buffer_t *buffer) +{ + ks_assert(buffer != NULL); + ks_assert(buffer->data != NULL); + + buffer->used = 0; + buffer->actually_used = 0; + buffer->head = buffer->data; +} + +KS_DECLARE(ks_size_t) ks_buffer_zwrite(ks_buffer_t *buffer, const void *data, ks_size_t datalen) +{ + ks_size_t w; + + if (!(w = ks_buffer_write(buffer, data, datalen))) { + ks_buffer_zero(buffer); + return ks_buffer_write(buffer, data, datalen); + } + + return w; +} + +KS_DECLARE(void) ks_buffer_destroy(ks_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/libks/src/ks_config.c b/libs/libks/src/ks_config.c new file mode 100644 index 0000000000..efe410ce2c --- /dev/null +++ b/libs/libks/src/ks_config.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2007-2012, 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 "ks.h" +#include "ks_config.h" + +KS_DECLARE(int) ks_config_open_file(ks_config_t *cfg, const char *file_path) +{ + FILE *f; + const char *path = NULL; + char path_buf[1024]; + + if (file_path[0] == '/') { + path = file_path; + } else { + ks_snprintf(path_buf, sizeof(path_buf), "%s%s%s", KS_CONFIG_DIR, KS_PATH_SEPARATOR, file_path); + path = path_buf; + } + + if (!path) { + return 0; + } + + memset(cfg, 0, sizeof(*cfg)); + cfg->lockto = -1; + ks_log(KS_LOG_DEBUG, "Configuration file is %s.\n", path); + f = fopen(path, "r"); + + if (!f) { + if (file_path[0] != '/') { + int last = -1; + char *var, *val; + + ks_snprintf(path_buf, sizeof(path_buf), "%s%sopenks.conf", KS_CONFIG_DIR, KS_PATH_SEPARATOR); + path = path_buf; + + if ((f = fopen(path, "r")) == 0) { + return 0; + } + + cfg->file = f; + ks_set_string(cfg->path, path); + + while (ks_config_next_pair(cfg, &var, &val)) { + if ((cfg->sectno != last) && !strcmp(cfg->section, file_path)) { + cfg->lockto = cfg->sectno; + return 1; + } + } + + ks_config_close_file(cfg); + memset(cfg, 0, sizeof(*cfg)); + return 0; + } + + return 0; + } else { + cfg->file = f; + ks_set_string(cfg->path, path); + return 1; + } +} + +KS_DECLARE(void) ks_config_close_file(ks_config_t *cfg) +{ + + if (cfg->file) { + fclose(cfg->file); + } + + memset(cfg, 0, sizeof(*cfg)); +} + + + +KS_DECLARE(int) ks_config_next_pair(ks_config_t *cfg, char **var, char **val) +{ + int ret = 0; + char *p, *end; + + *var = *val = NULL; + + if (!cfg || !cfg->file) { + return 0; + } + + for (;;) { + cfg->lineno++; + + if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { + ret = 0; + break; + } + *var = cfg->buf; + + if (**var == '[' && (end = strchr(*var, ']')) != 0) { + *end = '\0'; + (*var)++; + if (**var == '+') { + (*var)++; + ks_copy_string(cfg->section, *var, sizeof(cfg->section)); + cfg->sectno++; + + if (cfg->lockto > -1 && cfg->sectno != cfg->lockto) { + break; + } + cfg->catno = 0; + cfg->lineno = 0; + *var = (char *) ""; + *val = (char *) ""; + return 1; + } else { + ks_copy_string(cfg->category, *var, sizeof(cfg->category)); + cfg->catno++; + } + continue; + } + + + + if (**var == '#' || **var == ';' || **var == '\n' || **var == '\r') { + continue; + } + + if (!strncmp(*var, "__END__", 7)) { + break; + } + + + if ((end = strchr(*var, ';')) && *(end+1) == *end) { + *end = '\0'; + end--; + } else if ((end = strchr(*var, '\n')) != 0) { + if (*(end - 1) == '\r') { + end--; + } + *end = '\0'; + } + + p = *var; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *var = p; + + + if ((*val = strchr(*var, '=')) == 0) { + ret = -1; + /* log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); */ + continue; + } else { + p = *val - 1; + *(*val) = '\0'; + (*val)++; + if (*(*val) == '>') { + *(*val) = '\0'; + (*val)++; + } + + while ((*p == ' ' || *p == '\t') && p != *var) { + *p = '\0'; + p--; + } + + p = *val; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *val = p; + ret = 1; + break; + } + } + + + return ret; + +} + +KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits) +{ + char cas_bits[5]; + unsigned char bit = 0x8; + char *double_colon = strchr(strvalue, ':'); + int x = 0; + + if (!double_colon) { + ks_log(KS_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon); + return -1; + } + + double_colon++; + *outbits = 0; + cas_bits[4] = 0; + + if (sscanf(double_colon, "%c%c%c%c", &cas_bits[0], &cas_bits[1], &cas_bits[2], &cas_bits[3]) != 4) { + ks_log(KS_LOG_ERROR, "Invalid CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon); + return -1; + } + + ks_log(KS_LOG_DEBUG, "CAS bits specification found: %s\n", cas_bits); + + for (; cas_bits[x]; x++) { + if ('1' == cas_bits[x]) { + *outbits |= bit; + } else if ('0' != cas_bits[x]) { + ks_log(KS_LOG_ERROR, "Invalid CAS pattern specified: %s, just 0 or 1 allowed for each bit\n"); + return -1; + } + bit >>= 1; + } + return 0; +} + +/* 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/libks/src/ks_json.c b/libs/libks/src/ks_json.c new file mode 100644 index 0000000000..ffa965a609 --- /dev/null +++ b/libs/libks/src/ks_json.c @@ -0,0 +1,529 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +#include +#include +#include +#include +#include +#include +#include +#include "ks_json.h" +#include "ks.h" + +static const char *ep; + +KS_DECLARE(const char *)cJSON_GetErrorPtr() {return ep;} + +static int cJSON_strcasecmp(const char *s1,const char *s2) +{ + if (!s1) return (s1==s2)?0:1;if (!s2) return 1; + for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; + return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); +} + +static void *glue_malloc(size_t theSize) +{ + return(malloc(theSize)); +} + +static void glue_free(void *thePtr) +{ + free(thePtr); +} + +static void *(*cJSON_malloc)(size_t sz) = glue_malloc; +static void (*cJSON_free)(void *ptr) = glue_free; + +static char* cJSON_strdup(const char* str) +{ + size_t len; + char* copy; + const char *s = str ? str : ""; + + len = strlen(s) + 1; + if (!(copy = (char*)cJSON_malloc(len))) return 0; + memcpy(copy,s,len); + return copy; +} + +KS_DECLARE(void)cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; + cJSON_free = (hooks->free_fn)?hooks->free_fn:free; +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item() +{ + cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + if (node) memset(node,0,sizeof(cJSON)); + return node; +} + +/* Delete a cJSON structure. */ +KS_DECLARE(void)cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) + { + next=c->next; + if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); + if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); + if (c->string) cJSON_free(c->string); + cJSON_free(c); + c=next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +static const char *parse_number(cJSON *item,const char *num) +{ + double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; + + /* Could use sscanf for this? */ + if (*num=='-') sign=-1,num++; /* Has sign? */ + if (*num=='0') num++; /* is zero */ + if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ + if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ + if (*num=='e' || *num=='E') /* Exponent? */ + { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ + while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ + } + + n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble=n; + item->valueint=(int)n; + item->type=cJSON_Number; + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char *print_number(cJSON *item) +{ + char *str; + double d=item->valuedouble; + if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) + { + str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) sprintf(str,"%d",item->valueint); + } + else + { + str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) + { + if (fabs(floor(d)-d)<=DBL_EPSILON) sprintf(str,"%.0f",d); + else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); + else sprintf(str,"%f",d); + } + } + return str; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char *parse_string(cJSON *item,const char *str) +{ + const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; + if (*str!='\"') {ep=str;return 0;} /* not a string! */ + + while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ + + out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ + if (!out) return 0; + + ptr=str+1;ptr2=out; + while (*ptr!='\"' && *ptr) + { + if (*ptr!='\\') *ptr2++=*ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++='\b'; break; + case 'f': *ptr2++='\f'; break; + case 'n': *ptr2++='\n'; break; + case 'r': *ptr2++='\r'; break; + case 't': *ptr2++='\t'; break; + case 'u': /* transcode utf16 to utf8. */ + if (sscanf(ptr+1,"%4x",&uc) < 1) break; + + ptr+=4; /* get the unicode char. */ + + if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid. + + if (uc>=0xD800 && uc<=0xDBFF) // UTF16 surrogate pairs. + { + if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate. + if (sscanf(ptr+3,"%4x",&uc2) < 1) break; + ptr+=6; + if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate. + uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF); + } + + len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; + + switch (len) { + case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 1: *--ptr2 =(char)(uc | firstByteMark[len]); + } + ptr2+=len; + break; + default: *ptr2++=*ptr; break; + } + ptr++; + } + } + *ptr2=0; + if (*ptr=='\"') ptr++; + item->valuestring=out; + item->type=cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char *print_string_ptr(const char *str) +{ + const char *ptr;char *ptr2,*out;int len=0;unsigned char token; + + if (!str) return cJSON_strdup(""); + ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} + + out=(char*)cJSON_malloc(len+3); + if (!out) return 0; + + ptr2=out;ptr=str; + *ptr2++='\"'; + while (*ptr) + { + if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; + else + { + *ptr2++='\\'; + switch (token=*ptr++) + { + case '\\': *ptr2++='\\'; break; + case '\"': *ptr2++='\"'; break; + case '\b': *ptr2++='b'; break; + case '\f': *ptr2++='f'; break; + case '\n': *ptr2++='n'; break; + case '\r': *ptr2++='r'; break; + case '\t': *ptr2++='t'; break; + default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ + } + } + } + *ptr2++='\"';*ptr2++=0; + return out; +} +/* Invote print_string_ptr (which is useful) on an item. */ +static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item,const char *value); +static char *print_value(cJSON *item,int depth,int fmt); +static const char *parse_array(cJSON *item,const char *value); +static char *print_array(cJSON *item,int depth,int fmt); +static const char *parse_object(cJSON *item,const char *value); +static char *print_object(cJSON *item,int depth,int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} + +/* Parse an object - create a new root, and populate. */ +KS_DECLARE(cJSON *)cJSON_Parse(const char *value) +{ + cJSON *c=cJSON_New_Item(); + ep=0; + if (!c) return 0; /* memory fail */ + + if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;} + return c; +} + +/* Render a cJSON item/entity/structure to text. */ +KS_DECLARE(char *) cJSON_Print(cJSON *item) {return print_value(item,0,1);} +KS_DECLARE(char *) cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);} + +/* Parser core - when encountering text, process appropriately. */ +static const char *parse_value(cJSON *item,const char *value) +{ + if (!value) return 0; /* Fail on null. */ + if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } + if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } + if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } + if (*value=='\"') { return parse_string(item,value); } + if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } + if (*value=='[') { return parse_array(item,value); } + if (*value=='{') { return parse_object(item,value); } + + ep=value;return 0; /* failure. */ +} + +/* Render a value to text. */ +static char *print_value(cJSON *item,int depth,int fmt) +{ + char *out=0; + if (!item) return 0; + switch ((item->type)&255) + { + case cJSON_NULL: out=cJSON_strdup("null"); break; + case cJSON_False: out=cJSON_strdup("false");break; + case cJSON_True: out=cJSON_strdup("true"); break; + case cJSON_Number: out=print_number(item);break; + case cJSON_String: out=print_string(item);break; + case cJSON_Array: out=print_array(item,depth,fmt);break; + case cJSON_Object: out=print_object(item,depth,fmt);break; + } + return out; +} + +/* Build an array from input text. */ +static const char *parse_array(cJSON *item,const char *value) +{ + cJSON *child; + if (*value!='[') {ep=value;return 0;} /* not an array! */ + + item->type=cJSON_Array; + value=skip(value+1); + if (*value==']') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; /* memory fail */ + value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_value(child,skip(value+1))); + if (!value) return 0; /* memory fail */ + } + + if (*value==']') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an array to text */ +static char *print_array(cJSON *item,int depth,int fmt) +{ + char **entries; + char *out=0,*ptr,*ret;int len=5; + cJSON *child=item->child; + int numentries=0,i=0,fail=0; + + /* How many entries in the array? */ + while (child) numentries++,child=child->next; + /* Allocate an array to hold the values for each */ + entries=(char**)cJSON_malloc(numentries*sizeof(char*)); + if (!entries) return 0; + memset(entries,0,numentries*sizeof(char*)); + /* Retrieve all the results: */ + child=item->child; + while (child && !fail) + { + ret=print_value(child,depth+1,fmt); + entries[i++]=ret; + if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; + child=child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + /* If that fails, we fail. */ + if (!out) fail=1; + + /* Handle failure. */ + if (fail) + { + for (i=0;itype=cJSON_Object; + value=skip(value+1); + if (*value=='}') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; + value=skip(parse_string(child,skip(value))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_string(child,skip(value+1))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + } + + if (*value=='}') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char *print_object(cJSON *item,int depth,int fmt) +{ + char **entries=0,**names=0; + char *out=0,*ptr,*ret,*str;int len=7,i=0,j; + cJSON *child=item->child; + int numentries=0,fail=0; + /* Count the number of entries. */ + while (child) numentries++,child=child->next; + /* Allocate space for the names and the objects */ + entries=(char**)cJSON_malloc(numentries*sizeof(char*)); + if (!entries) return 0; + names=(char**)cJSON_malloc(numentries*sizeof(char*)); + if (!names) {cJSON_free(entries);return 0;} + memset(entries,0,sizeof(char*)*numentries); + memset(names,0,sizeof(char*)*numentries); + + /* Collect all the results into our arrays: */ + child=item->child;depth++;if (fmt) len+=depth; + while (child) + { + names[i]=str=print_string_ptr(child->string); + entries[i++]=ret=print_value(child,depth,fmt); + if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; + child=child->next; + } + + /* Try to allocate the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + if (!out) fail=1; + + /* Handle failure */ + if (fail) + { + for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} +KS_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} +KS_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} +/* Utility for handling references. */ +static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} + +/* Add item to array/object. */ +KS_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} +KS_DECLARE(void) cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} +KS_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} +KS_DECLARE(void) cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} + +KS_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; + if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} +KS_DECLARE(void) cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} +KS_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} +KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} + +/* Replace array/object items with new ones. */ +KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; + newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; + if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} +KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} + +/* Create basic types: */ +KS_DECLARE(cJSON *)cJSON_CreateNull() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} +KS_DECLARE(cJSON *)cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} +KS_DECLARE(cJSON *)cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} +KS_DECLARE(cJSON *)cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} +KS_DECLARE(cJSON *)cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} +KS_DECLARE(cJSON *)cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} +KS_DECLARE(cJSON *)cJSON_CreateArray() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} +KS_DECLARE(cJSON *)cJSON_CreateObject() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} + +/* Create Arrays: */ +KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;} +KS_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;} +KS_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;} +KS_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;} diff --git a/libs/libks/src/ks_threadmutex.c b/libs/libks/src/ks_threadmutex.c new file mode 100644 index 0000000000..a23c02f762 --- /dev/null +++ b/libs/libks/src/ks_threadmutex.c @@ -0,0 +1,239 @@ +/* + * Cross Platform Thread/Mutex abstraction + * Copyright(C) 2007 Michael Jerris + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so. + * + * This work is provided under this license on an "as is" basis, without warranty of any kind, + * either expressed or implied, including, without limitation, warranties that the covered code + * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire + * risk as to the quality and performance of the covered code is with you. Should any covered + * code prove defective in any respect, you (not the initial developer or any other contributor) + * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty + * constitutes an essential part of this license. No use of any covered code is authorized hereunder + * except under this disclaimer. + * + */ + +#ifdef WIN32 +/* required for TryEnterCriticalSection definition. Must be defined before windows.h include */ +#define _WIN32_WINNT 0x0400 +#endif + +#include "ks.h" +#include "ks_threadmutex.h" + +#ifdef WIN32 +#include + +#define KS_THREAD_CALLING_CONVENTION __stdcall + +struct ks_mutex { + CRITICAL_SECTION mutex; +}; + +#else + +#include + +#define KS_THREAD_CALLING_CONVENTION + +struct ks_mutex { + pthread_mutex_t mutex; +}; + +#endif + +struct ks_thread { +#ifdef WIN32 + void *handle; +#else + pthread_t handle; +#endif + void *private_data; + ks_thread_function_t function; + size_t stack_size; +#ifndef WIN32 + pthread_attr_t attribute; +#endif +}; + +size_t thread_default_stacksize = 240 * 1024; + +void ks_thread_override_default_stacksize(size_t size) +{ + thread_default_stacksize = size; +} + +static void * KS_THREAD_CALLING_CONVENTION thread_launch(void *args) +{ + void *exit_val; + ks_thread_t *thread = (ks_thread_t *)args; + exit_val = thread->function(thread, thread->private_data); +#ifndef WIN32 + pthread_attr_destroy(&thread->attribute); +#endif + free(thread); + + return exit_val; +} + +KS_DECLARE(ks_status_t) ks_thread_create_detached(ks_thread_function_t func, void *data) +{ + return ks_thread_create_detached_ex(func, data, thread_default_stacksize); +} + +ks_status_t ks_thread_create_detached_ex(ks_thread_function_t func, void *data, size_t stack_size) +{ + ks_thread_t *thread = NULL; + ks_status_t status = KS_FAIL; + + if (!func || !(thread = (ks_thread_t *)malloc(sizeof(ks_thread_t)))) { + goto done; + } + + thread->private_data = data; + thread->function = func; + thread->stack_size = stack_size; + +#if defined(WIN32) + thread->handle = (void *)_beginthreadex(NULL, (unsigned)thread->stack_size, (unsigned int (__stdcall *)(void *))thread_launch, thread, 0, NULL); + if (!thread->handle) { + goto fail; + } + CloseHandle(thread->handle); + + status = KS_SUCCESS; + goto done; +#else + + if (pthread_attr_init(&thread->attribute) != 0) goto fail; + + if (pthread_attr_setdetachstate(&thread->attribute, PTHREAD_CREATE_DETACHED) != 0) goto failpthread; + + if (thread->stack_size && pthread_attr_setstacksize(&thread->attribute, thread->stack_size) != 0) goto failpthread; + + if (pthread_create(&thread->handle, &thread->attribute, thread_launch, thread) != 0) goto failpthread; + + status = KS_SUCCESS; + goto done; + + failpthread: + + pthread_attr_destroy(&thread->attribute); +#endif + + fail: + if (thread) { + free(thread); + } + done: + return status; +} + + +KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex) +{ + ks_status_t status = KS_FAIL; +#ifndef WIN32 + pthread_mutexattr_t attr; +#endif + ks_mutex_t *check = NULL; + + check = (ks_mutex_t *)malloc(sizeof(**mutex)); + if (!check) + goto done; +#ifdef WIN32 + InitializeCriticalSection(&check->mutex); +#else + if (pthread_mutexattr_init(&attr)) + goto done; + + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) + goto fail; + + if (pthread_mutex_init(&check->mutex, &attr)) + goto fail; + + goto success; + + fail: + pthread_mutexattr_destroy(&attr); + goto done; + + success: +#endif + *mutex = check; + status = KS_SUCCESS; + + done: + return status; +} + +KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex) +{ + ks_mutex_t *mp = *mutex; + *mutex = NULL; + if (!mp) { + return KS_FAIL; + } +#ifdef WIN32 + DeleteCriticalSection(&mp->mutex); +#else + if (pthread_mutex_destroy(&mp->mutex)) + return KS_FAIL; +#endif + free(mp); + return KS_SUCCESS; +} + +KS_DECLARE(ks_status_t) ks_mutex_lock(ks_mutex_t *mutex) +{ +#ifdef WIN32 + EnterCriticalSection(&mutex->mutex); +#else + if (pthread_mutex_lock(&mutex->mutex)) + return KS_FAIL; +#endif + return KS_SUCCESS; +} + +KS_DECLARE(ks_status_t) ks_mutex_trylock(ks_mutex_t *mutex) +{ +#ifdef WIN32 + if (!TryEnterCriticalSection(&mutex->mutex)) + return KS_FAIL; +#else + if (pthread_mutex_trylock(&mutex->mutex)) + return KS_FAIL; +#endif + return KS_SUCCESS; +} + +KS_DECLARE(ks_status_t) ks_mutex_unlock(ks_mutex_t *mutex) +{ +#ifdef WIN32 + LeaveCriticalSection(&mutex->mutex); +#else + if (pthread_mutex_unlock(&mutex->mutex)) + return KS_FAIL; +#endif + return KS_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/libs/libks/src/mpool.c b/libs/libks/src/mpool.c new file mode 100644 index 0000000000..72c5b6b108 --- /dev/null +++ b/libs/libks/src/mpool.c @@ -0,0 +1,1768 @@ +/* + * Memory pool routines. + * + * Copyright 1996 by Gray Watson. + * + * This file is part of the mpool package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $ + */ + +/* + * Memory-pool allocation routines. I got sick of the GNU mmalloc + * library which was close to what we needed but did not exactly do + * what I wanted. + * + * The following uses mmap from /dev/zero. It allows a number of + * allocations to be made inside of a memory pool then with a clear or + * close the pool can be reset without any memory fragmentation and + * growth problems. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef DMALLOC +#include "dmalloc.h" +#endif + +#define MPOOL_MAIN + +#include "mpool.h" +#include "mpool_loc.h" + +#ifdef __GNUC__ +#ident "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $" +#else +static char *rcs_id = "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $"; +#endif + +/* version */ +static char *version = "mpool library version 2.1.0"; + +/* local variables */ +static int enabled_b = 0; /* lib initialized? */ +static unsigned int min_bit_free_next = 0; /* min size of next pnt */ +static unsigned int min_bit_free_size = 0; /* min size of next + size */ +static unsigned long bit_array[MAX_BITS + 1]; /* size -> bit */ + +/****************************** local utilities ******************************/ + +/* + * static void startup + * + * DESCRIPTION: + * + * Perform any library level initialization. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * None. + */ +static void startup(void) +{ + int bit_c; + unsigned long size = 1; + + if (enabled_b) { + return; + } + + /* allocate our free bit array list */ + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + bit_array[bit_c] = size; + + /* + * Note our minimum number of bits that can store a pointer. This + * is smallest address that we can have a linked list for. + */ + if (min_bit_free_next == 0 && size >= sizeof(void *)) { + min_bit_free_next = bit_c; + } + /* + * Note our minimum number of bits that can store a pointer and + * the size of the block. + */ + if (min_bit_free_size == 0 && size >= sizeof(mpool_free_t)) { + min_bit_free_size = bit_c; + } + + size *= 2; + } + + enabled_b = 1; +} + +/* + * static int size_to_bits + * + * DESCRIPTION: + * + * Calculate the number of bits in a size. + * + * RETURNS: + * + * Number of bits. + * + * ARGUMENTS: + * + * size -> Size of memory of which to calculate the number of bits. + */ +static int size_to_bits(const unsigned long size) +{ + int bit_c = 0; + + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + if (size <= bit_array[bit_c]) { + break; + } + } + + return bit_c; +} + +/* + * static int size_to_free_bits + * + * DESCRIPTION: + * + * Calculate the number of bits in a size going on the free list. + * + * RETURNS: + * + * Number of bits. + * + * ARGUMENTS: + * + * size -> Size of memory of which to calculate the number of bits. + */ +static int size_to_free_bits(const unsigned long size) +{ + int bit_c = 0; + + if (size == 0) { + return 0; + } + + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + if (size < bit_array[bit_c]) { + break; + } + } + + return bit_c - 1; +} + +/* + * static int bits_to_size + * + * DESCRIPTION: + * + * Calculate the size represented by a number of bits. + * + * RETURNS: + * + * Number of bits. + * + * ARGUMENTS: + * + * bit_n -> Number of bits + */ +static unsigned long bits_to_size(const int bit_n) +{ + if (bit_n > MAX_BITS) { + return bit_array[MAX_BITS]; + } + else { + return bit_array[bit_n]; + } +} + +/* + * static void *alloc_pages + * + * DESCRIPTION: + * + * Allocate space for a number of memory pages in the memory pool. + * + * RETURNS: + * + * Success - New pages of memory + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + * + * page_n -> Number of pages to alloc. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n, + int *error_p) +{ + void *mem, *fill_mem; + unsigned long size, fill; + int state; + + /* are we over our max-pages? */ + if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) { + SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES); + return NULL; + } + + size = SIZE_OF_PAGES(mp_p, page_n); + +#ifdef DEBUG + (void)printf("allocating %u pages or %lu bytes\n", page_n, size); +#endif + + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { + mem = sbrk(size); + if (mem == (void *)-1) { + SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); + return NULL; + } + fill = (unsigned long)mem % mp_p->mp_page_size; + + if (fill > 0) { + fill = mp_p->mp_page_size - fill; + fill_mem = sbrk(fill); + if (fill_mem == (void *)-1) { + SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); + return NULL; + } + if ((char *)fill_mem != (char *)mem + size) { + SET_POINTER(error_p, MPOOL_ERROR_SBRK_CONTIG); + return NULL; + } + mem = (char *)mem + fill; + } + } + else { + state = MAP_PRIVATE; +#ifdef MAP_FILE + state |= MAP_FILE; +#endif +#ifdef MAP_VARIABLE + state |= MAP_VARIABLE; +#endif + + /* mmap from /dev/zero */ + mem = mmap((caddr_t)mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state, + mp_p->mp_fd, mp_p->mp_top); + if (mem == (void *)MAP_FAILED) { + if (errno == ENOMEM) { + SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); + } + else { + SET_POINTER(error_p, MPOOL_ERROR_MMAP); + } + return NULL; + } + mp_p->mp_top += size; + if (mp_p->mp_addr != NULL) { + mp_p->mp_addr = (char *)mp_p->mp_addr + size; + } + } + + mp_p->mp_page_c += page_n; + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return mem; +} + +/* + * static int free_pages + * + * DESCRIPTION: + * + * Free previously allocated pages of memory. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * pages <-> Pointer to memory pages that we are freeing. + * + * size -> Size of the block that we are freeing. + * + * sbrk_b -> Set to one if the pages were allocated with sbrk else mmap. + */ +static int free_pages(void *pages, const unsigned long size, + const int sbrk_b) +{ + if (! sbrk_b) { + (void)munmap((caddr_t)pages, size); + } + + return MPOOL_ERROR_NONE; +} + +/* + * static int check_magic + * + * DESCRIPTION: + * + * Check for the existance of the magic ID in a memory pointer. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * addr -> Address inside of the block that we are tryign to locate. + * + * size -> Size of the block. + */ +static int check_magic(const void *addr, const unsigned long size) +{ + const unsigned char *mem_p; + + /* set our starting point */ + mem_p = (unsigned char *)addr + size; + + if (*mem_p == FENCE_MAGIC0 && *(mem_p + 1) == FENCE_MAGIC1) { + return MPOOL_ERROR_NONE; + } + else { + return MPOOL_ERROR_PNT_OVER; + } +} + +/* + * static void write_magic + * + * DESCRIPTION: + * + * Write the magic ID to the address. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * addr -> Address where to write the magic. + */ +static void write_magic(const void *addr) +{ + *(unsigned char *)addr = FENCE_MAGIC0; + *((unsigned char *)addr + 1) = FENCE_MAGIC1; +} + +/* + * static void free_pointer + * + * DESCRIPTION: + * + * Moved a pointer into our free lists. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * addr <-> Address where to write the magic. We may write a next + * pointer to it. + * + * size -> Size of the address space. + */ +static int free_pointer(mpool_t *mp_p, void *addr, + const unsigned long size) +{ + unsigned int bit_n; + unsigned long real_size; + mpool_free_t free_pnt; + +#ifdef DEBUG + (void)printf("freeing a block at %lx of %lu bytes\n", (long)addr, size); +#endif + + if (size == 0) { + return MPOOL_ERROR_NONE; + } + + /* + * if the user size is larger then can fit in an entire block then + * we change the size + */ + if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { + real_size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, size)) - + sizeof(mpool_block_t); + } + else { + real_size = size; + } + + /* + * We use a specific free bits calculation here because if we are + * freeing 10 bytes then we will be putting it into the 8-byte free + * list and not the 16 byte list. size_to_bits(10) will return 4 + * instead of 3. + */ + bit_n = size_to_free_bits(real_size); + + /* + * Minimal error checking. We could go all the way through the + * list however this might be prohibitive. + */ + if (mp_p->mp_free[bit_n] == addr) { + return MPOOL_ERROR_IS_FREE; + } + + /* add the freed pointer to the free list */ + if (bit_n < min_bit_free_next) { + /* + * Yes we know this will lose 99% of the allocations but what else + * can we do? No space for a next pointer. + */ + if (mp_p->mp_free[bit_n] == NULL) { + mp_p->mp_free[bit_n] = addr; + } + } + else if (bit_n < min_bit_free_size) { + /* we copy, not assign, to maintain the free list */ + memcpy(addr, mp_p->mp_free + bit_n, sizeof(void *)); + mp_p->mp_free[bit_n] = addr; + } + else { + + /* setup our free list structure */ + free_pnt.mf_next_p = mp_p->mp_free[bit_n]; + free_pnt.mf_size = real_size; + + /* we copy the structure in since we don't know about alignment */ + memcpy(addr, &free_pnt, sizeof(free_pnt)); + mp_p->mp_free[bit_n] = addr; + } + + return MPOOL_ERROR_NONE; +} + +/* + * static int split_block + * + * DESCRIPTION: + * + * When freeing space in a multi-block chunk we have to create new + * blocks out of the upper areas being freed. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * free_addr -> Address that we are freeing. + * + * size -> Size of the space that we are taking from address. + */ +static int split_block(mpool_t *mp_p, void *free_addr, + const unsigned long size) +{ + mpool_block_t *block_p, *new_block_p; + int ret, page_n; + void *end_p; + + /* + * 1st we find the block pointer from our free addr. At this point + * the pointer must be the 1st one in the block if it is spans + * multiple blocks. + */ + block_p = (mpool_block_t *)((char *)free_addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + page_n = PAGES_IN_SIZE(mp_p, size); + + /* we are creating a new block structure for the 2nd ... */ + new_block_p = (mpool_block_t *)((char *)block_p + + SIZE_OF_PAGES(mp_p, page_n)); + new_block_p->mb_magic = BLOCK_MAGIC; + /* New bounds is 1st block bounds. The 1st block's is reset below. */ + new_block_p->mb_bounds_p = block_p->mb_bounds_p; + /* Continue the linked list. The 1st block will point to us below. */ + new_block_p->mb_next_p = block_p->mb_next_p; + new_block_p->mb_magic2 = BLOCK_MAGIC; + + /* bounds for the 1st block are reset to the 1st page only */ + block_p->mb_bounds_p = (char *)new_block_p; + /* the next block pointer for the 1st block is now the new one */ + block_p->mb_next_p = new_block_p; + + /* only free the space in the 1st block if it is only 1 block in size */ + if (page_n == 1) { + /* now free the rest of the 1st block block */ + end_p = (char *)free_addr + size; + ret = free_pointer(mp_p, end_p, + (char *)block_p->mb_bounds_p - (char *)end_p); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + } + + /* now free the rest of the block */ + ret = free_pointer(mp_p, FIRST_ADDR_IN_BLOCK(new_block_p), + MEMORY_IN_BLOCK(new_block_p)); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + + return MPOOL_ERROR_NONE; +} + +/* + * static void *get_space + * + * DESCRIPTION: + * + * Moved a pointer into our free lists. + * + * RETURNS: + * + * Success - New address that we can use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * byte_size -> Size of the address space that we need. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +static void *get_space(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) +{ + mpool_block_t *block_p; + mpool_free_t free_pnt; + int ret; + unsigned long size; + unsigned int bit_c, page_n, left; + void *free_addr = NULL, *free_end; + + size = byte_size; + while ((size & (sizeof(void *) - 1)) > 0) { + size++; + } + + /* + * First we check the free lists looking for something with enough + * pages. Maybe we should only look X bits higher in the list. + * + * XXX: this is where we'd do the best fit. We'd look for the + * closest match. We then could put the rest of the allocation that + * we did not use in a lower free list. Have a define which states + * how deep in the free list to go to find the closest match. + */ + for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) { + if (mp_p->mp_free[bit_c] != NULL) { + free_addr = mp_p->mp_free[bit_c]; + break; + } + } + + /* + * If we haven't allocated any blocks or if the last block doesn't + * have enough memory then we need a new block. + */ + if (bit_c > MAX_BITS) { + + /* we need to allocate more space */ + + page_n = PAGES_IN_SIZE(mp_p, size); + + /* now we try and get the pages we need/want */ + block_p = alloc_pages(mp_p, page_n, error_p); + if (block_p == NULL) { + /* error_p set in alloc_pages */ + return NULL; + } + + /* init the block header */ + block_p->mb_magic = BLOCK_MAGIC; + block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n); + block_p->mb_next_p = mp_p->mp_first_p; + block_p->mb_magic2 = BLOCK_MAGIC; + + /* + * We insert it into the front of the queue. We could add it to + * the end but there is not much use. + */ + mp_p->mp_first_p = block_p; + if (mp_p->mp_last_p == NULL) { + mp_p->mp_last_p = block_p; + } + + free_addr = FIRST_ADDR_IN_BLOCK(block_p); + +#ifdef DEBUG + (void)printf("had to allocate space for %lx of %lu bytes\n", + (long)free_addr, size); +#endif + + free_end = (char *)free_addr + size; + left = (char *)block_p->mb_bounds_p - (char *)free_end; + } + else { + + if (bit_c < min_bit_free_next) { + mp_p->mp_free[bit_c] = NULL; + /* calculate the number of left over bytes */ + left = bits_to_size(bit_c) - size; + } + else if (bit_c < min_bit_free_next) { + /* grab the next pointer from the freed address into our list */ + memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *)); + /* calculate the number of left over bytes */ + left = bits_to_size(bit_c) - size; + } + else { + /* grab the free structure from the address */ + memcpy(&free_pnt, free_addr, sizeof(free_pnt)); + mp_p->mp_free[bit_c] = free_pnt.mf_next_p; + + /* are we are splitting up a multiblock chunk into fewer blocks? */ + if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) { + ret = split_block(mp_p, free_addr, size); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + /* left over memory was taken care of in split_block */ + left = 0; + } + else { + /* calculate the number of left over bytes */ + left = free_pnt.mf_size - size; + } + } + +#ifdef DEBUG + (void)printf("found a free block at %lx of %lu bytes\n", + (long)free_addr, left + size); +#endif + + free_end = (char *)free_addr + size; + } + + /* + * If we have memory left over then we free it so someone else can + * use it. We do not free the space if we just allocated a + * multi-block chunk because we need to have every allocation easily + * find the start of the block. Every user address % page-size + * should take us to the start of the block. + */ + if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) { + /* free the rest of the block */ + ret = free_pointer(mp_p, free_end, left); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + } + + /* update our bounds */ + if (free_addr > mp_p->mp_bounds_p) { + mp_p->mp_bounds_p = free_addr; + } + else if (free_addr < mp_p->mp_min_p) { + mp_p->mp_min_p = free_addr; + } + + return free_addr; +} + +/* + * static void *alloc_mem + * + * DESCRIPTION: + * + * Allocate space for bytes inside of an already open memory pool. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal malloc. + * + * byte_size -> Number of bytes to allocate in the pool. Must be >0. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) +{ + unsigned long size, fence; + void *addr; + + /* make sure we have enough bytes */ + if (byte_size < MIN_ALLOCATION) { + size = MIN_ALLOCATION; + } + else { + size = byte_size; + } + + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else { + fence = FENCE_SIZE; + } + + /* get our free space + the space for the fence post */ + addr = get_space(mp_p, size + fence, error_p); + if (addr == NULL) { + /* error_p set in get_space */ + return NULL; + } + + if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + write_magic((char *)addr + size); + } + + /* maintain our stats */ + mp_p->mp_alloc_c++; + mp_p->mp_user_alloc += size; + if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) { + mp_p->mp_max_alloc = mp_p->mp_user_alloc; + } + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return addr; +} + +/* + * static int free_mem + * + * DESCRIPTION: + * + * Free an address from a memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal free. + * + * addr <-> Address to free. + * + * size -> Size of the address being freed. + */ +static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) +{ + unsigned long old_size, fence; + int ret; + mpool_block_t *block_p; + + /* + * If the size is larger than a block then the allocation must be at + * the front of the block. + */ + if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { + block_p = (mpool_block_t *)((char *)addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + } + + /* make sure we have enough bytes */ + if (size < MIN_ALLOCATION) { + old_size = MIN_ALLOCATION; + } + else { + old_size = size; + } + + /* if we are packing the pool smaller */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else { + /* find the user's magic numbers if they were written */ + ret = check_magic(addr, old_size); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + fence = FENCE_SIZE; + } + + /* now we free the pointer */ + ret = free_pointer(mp_p, addr, old_size + fence); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + mp_p->mp_user_alloc -= old_size; + + /* adjust our stats */ + mp_p->mp_alloc_c--; + + return MPOOL_ERROR_NONE; +} + +/***************************** exported routines *****************************/ + +/* + * mpool_t *mpool_open + * + * DESCRIPTION: + * + * Open/allocate a new memory pool. + * + * RETURNS: + * + * Success - Pool pointer which must be passed to mpool_close to + * deallocate. + * + * Failure - NULL + * + * ARGUMENTS: + * + * flags -> Flags to set attributes of the memory pool. See the top + * of mpool.h. + * + * page_size -> Set the internal memory page-size. This must be a + * multiple of the getpagesize() value. Set to 0 for the default. + * + * start_addr -> Starting address to try and allocate memory pools. + * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, + void *start_addr, int *error_p) +{ + mpool_block_t *block_p; + int page_n, ret; + mpool_t mp, *mp_p; + void *free_addr; + + if (! enabled_b) { + startup(); + } + + /* zero our temp struct */ + memset(&mp, 0, sizeof(mp)); + + mp.mp_magic = MPOOL_MAGIC; + mp.mp_flags = flags; + mp.mp_alloc_c = 0; + mp.mp_user_alloc = 0; + mp.mp_max_alloc = 0; + mp.mp_page_c = 0; + /* mp.mp_page_size set below */ + /* mp.mp_blocks_bit_n set below */ + /* mp.mp_fd set below */ + /* mp.mp_top set below */ + /* mp.mp_addr set below */ + mp.mp_log_func = NULL; + mp.mp_min_p = NULL; + mp.mp_bounds_p = NULL; + mp.mp_first_p = NULL; + mp.mp_last_p = NULL; + mp.mp_magic2 = MPOOL_MAGIC; + + /* get and sanity check our page size */ + if (page_size > 0) { + mp.mp_page_size = page_size; + if (mp.mp_page_size % getpagesize() != 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + } + else { + mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT; + if (mp.mp_page_size % 1024 != 0) { + SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE); + return NULL; + } + } + + if (BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)) { + mp.mp_fd = -1; + mp.mp_addr = NULL; + mp.mp_top = 0; + } + else { + /* open dev-zero for our mmaping */ + mp.mp_fd = open("/dev/zero", O_RDWR, 0); + if (mp.mp_fd < 0) { + SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO); + return NULL; + } + mp.mp_addr = start_addr; + /* we start at the front of the file */ + mp.mp_top = 0; + } + + /* + * Find out how many pages we need for our mpool structure. + * + * NOTE: this adds possibly unneeded space for mpool_block_t which + * may not be in this block. + */ + page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t)); + + /* now allocate us space for the actual struct */ + mp_p = alloc_pages(&mp, page_n, error_p); + if (mp_p == NULL) { + if (mp.mp_fd >= 0) { + (void)close(mp.mp_fd); + mp.mp_fd = -1; + } + return NULL; + } + + /* + * NOTE: we do not normally free the rest of the block here because + * we want to lesson the chance of an allocation overwriting the + * main structure. + */ + if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) { + + /* we add a block header to the front of the block */ + block_p = (mpool_block_t *)mp_p; + + /* init the block header */ + block_p->mb_magic = BLOCK_MAGIC; + block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n); + block_p->mb_next_p = NULL; + block_p->mb_magic2 = BLOCK_MAGIC; + + /* the mpool pointer is then the 2nd thing in the block */ + mp_p = FIRST_ADDR_IN_BLOCK(block_p); + free_addr = (char *)mp_p + sizeof(mpool_t); + + /* free the rest of the block */ + ret = free_pointer(&mp, free_addr, + (char *)block_p->mb_bounds_p - (char *)free_addr); + if (ret != MPOOL_ERROR_NONE) { + if (mp.mp_fd >= 0) { + (void)close(mp.mp_fd); + mp.mp_fd = -1; + } + /* NOTE: after this line mp_p will be invalid */ + (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n), + BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)); + SET_POINTER(error_p, ret); + return NULL; + } + + /* + * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool + * header is not on the block linked list. + */ + + /* now copy our tmp structure into our new memory area */ + memcpy(mp_p, &mp, sizeof(mpool_t)); + + /* we setup min/max to our current address which is as good as any */ + mp_p->mp_min_p = block_p; + mp_p->mp_bounds_p = block_p->mb_bounds_p; + } + else { + /* now copy our tmp structure into our new memory area */ + memcpy(mp_p, &mp, sizeof(mpool_t)); + + /* we setup min/max to our current address which is as good as any */ + mp_p->mp_min_p = mp_p; + mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n); + } + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return mp_p; +} + +/* + * int mpool_close + * + * DESCRIPTION: + * + * Close/free a memory allocation pool previously opened with + * mpool_open. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +int mpool_close(mpool_t *mp_p) +{ + mpool_block_t *block_p, *next_p; + void *addr; + unsigned long size; + int ret, final = MPOOL_ERROR_NONE; + + /* special case, just return no-error */ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLOSE, 0, 0, NULL, NULL, 0); + } + + /* + * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool + * header is not on the linked list. + */ + + /* free/invalidate the blocks */ + for (block_p = mp_p->mp_first_p; block_p != NULL; block_p = next_p) { + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + final = MPOOL_ERROR_POOL_OVER; + break; + } + block_p->mb_magic = 0; + block_p->mb_magic2 = 0; + /* record the next pointer because it might be invalidated below */ + next_p = block_p->mb_next_p; + ret = free_pages(block_p, (char *)block_p->mb_bounds_p - (char *)block_p, + BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)); + if (ret != MPOOL_ERROR_NONE) { + final = ret; + } + } + + /* close /dev/zero if necessary */ + if (mp_p->mp_fd >= 0) { + (void)close(mp_p->mp_fd); + mp_p->mp_fd = -1; + } + + /* invalidate the mpool before we ditch it */ + mp_p->mp_magic = 0; + mp_p->mp_magic2 = 0; + + /* last we munmap the mpool pointer itself */ + if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { + + /* if we are heavy packing then we need to free the 1st block later */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { + addr = (char *)mp_p - sizeof(mpool_block_t); + } + else { + addr = mp_p; + } + size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, sizeof(mpool_t))); + + (void)munmap((caddr_t)addr, size); + } + + return final; +} + +/* + * int mpool_clear + * + * DESCRIPTION: + * + * Wipe an opened memory pool clean so we can start again. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to our memory pool. + */ +int mpool_clear(mpool_t *mp_p) +{ + mpool_block_t *block_p; + int final = MPOOL_ERROR_NONE, bit_n, ret; + void *first_p; + + /* special case, just return no-error */ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLEAR, 0, 0, NULL, NULL, 0); + } + + /* reset all of our free lists */ + for (bit_n = 0; bit_n <= MAX_BITS; bit_n++) { + mp_p->mp_free[bit_n] = NULL; + } + + /* free the blocks */ + for (block_p = mp_p->mp_first_p; + block_p != NULL; + block_p = block_p->mb_next_p) { + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + final = MPOOL_ERROR_POOL_OVER; + break; + } + + first_p = FIRST_ADDR_IN_BLOCK(block_p); + + /* free the memory */ + ret = free_pointer(mp_p, first_p, MEMORY_IN_BLOCK(block_p)); + if (ret != MPOOL_ERROR_NONE) { + final = ret; + } + } + + return final; +} + +/* + * void *mpool_alloc + * + * DESCRIPTION: + * + * Allocate space for bytes inside of an already open memory pool. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal malloc. + * + * byte_size -> Number of bytes to allocate in the pool. Must be >0. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) +{ + void *addr; + + if (mp_p == NULL) { + /* special case -- do a normal malloc */ + addr = (void *)malloc(byte_size); + if (addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ALLOC); + return NULL; + } + else { + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return addr; + } + } + + if (mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + + if (byte_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + + addr = alloc_mem(mp_p, byte_size, error_p); + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_ALLOC, byte_size, 0, addr, NULL, 0); + } + + return addr; +} + +/* + * void *mpool_calloc + * + * DESCRIPTION: + * + * Allocate space for elements of bytes in the memory pool and zero + * the space afterwards. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal calloc. + * + * ele_n -> Number of elements to allocate. + * + * ele_size -> Number of bytes per element being allocated. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, + const unsigned long ele_size, int *error_p) +{ + void *addr; + unsigned long byte_size; + + if (mp_p == NULL) { + /* special case -- do a normal calloc */ + addr = (void *)calloc(ele_n, ele_size); + if (addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ALLOC); + return NULL; + } + else { + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return addr; + } + + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + + if (ele_n == 0 || ele_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + + byte_size = ele_n * ele_size; + addr = alloc_mem(mp_p, byte_size, error_p); + if (addr != NULL) { + memset(addr, 0, byte_size); + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CALLOC, ele_size, ele_n, addr, NULL, 0); + } + + /* NOTE: error_p set above */ + return addr; +} + +/* + * int mpool_free + * + * DESCRIPTION: + * + * Free an address from a memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal free. + * + * addr <-> Address to free. + * + * size -> Size of the address being freed. + */ +int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size) +{ + if (mp_p == NULL) { + /* special case -- do a normal free */ + free(addr); + return MPOOL_ERROR_NONE; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_FREE, size, 0, NULL, addr, 0); + } + + if (addr == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (size == 0) { + return MPOOL_ERROR_ARG_INVALID; + } + + return free_mem(mp_p, addr, size); +} + +/* + * void *mpool_resize + * + * DESCRIPTION: + * + * Reallocate an address in a mmeory pool to a new size. This is + * different from realloc in that it needs the old address' size. If + * you don't have it then you need to allocate new space, copy the + * data, and free the old pointer yourself. + * + * RETURNS: + * + * Success - Pointer to the address to use. + * + * Failure - NULL + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. If NULL then it will do a + * normal realloc. + * + * old_addr -> Previously allocated address. + * + * old_byte_size -> Size of the old address. Must be known, cannot be + * 0. + * + * new_byte_size -> New size of the allocation. + * + * error_p <- Pointer to integer which, if not NULL, will be set with + * a mpool error code. + */ +void *mpool_resize(mpool_t *mp_p, void *old_addr, + const unsigned long old_byte_size, + const unsigned long new_byte_size, + int *error_p) +{ + unsigned long copy_size, new_size, old_size, fence; + void *new_addr; + mpool_block_t *block_p; + int ret; + + if (mp_p == NULL) { + /* special case -- do a normal realloc */ + new_addr = (void *)realloc(old_addr, new_byte_size); + if (new_addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ALLOC); + return NULL; + } + else { + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return new_addr; + } + } + + if (mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + + if (old_addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_NULL); + return NULL; + } + if (old_byte_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + + /* + * If the size is larger than a block then the allocation must be at + * the front of the block. + */ + if (old_byte_size > MAX_BLOCK_USER_MEMORY(mp_p)) { + block_p = (mpool_block_t *)((char *)old_addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + } + + /* make sure we have enough bytes */ + if (old_byte_size < MIN_ALLOCATION) { + old_size = MIN_ALLOCATION; + } + else { + old_size = old_byte_size; + } + + /* verify that the size matches exactly if we can */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else if (old_size > 0) { + ret = check_magic(old_addr, old_size); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + fence = FENCE_SIZE; + } + + /* make sure we have enough bytes */ + if (new_byte_size < MIN_ALLOCATION) { + new_size = MIN_ALLOCATION; + } + else { + new_size = new_byte_size; + } + + /* + * NOTE: we could here see if the size is the same or less and then + * use the current memory and free the space above. This is harder + * than it sounds if we are changing the block size of the + * allocation. + */ + + /* we need to get another address */ + new_addr = alloc_mem(mp_p, new_byte_size, error_p); + if (new_addr == NULL) { + /* error_p set in mpool_alloc */ + return NULL; + } + + if (new_byte_size > old_byte_size) { + copy_size = old_byte_size; + } + else { + copy_size = new_byte_size; + } + memcpy(new_addr, old_addr, copy_size); + + /* free the old address */ + ret = free_mem(mp_p, old_addr, old_byte_size); + if (ret != MPOOL_ERROR_NONE) { + /* if the old free failed, try and free the new address */ + (void)free_mem(mp_p, new_addr, new_byte_size); + SET_POINTER(error_p, ret); + return NULL; + } + + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_RESIZE, new_byte_size, + 0, new_addr, old_addr, old_byte_size); + } + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return new_addr; +} + +/* + * int mpool_stats + * + * DESCRIPTION: + * + * Return stats from the memory pool. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p -> Pointer to the memory pool. + * + * page_size_p <- Pointer to an unsigned integer which, if not NULL, + * will be set to the page-size of the pool. + * + * num_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of pointers currently allocated in pool. + * + * user_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the number of user bytes allocated in this pool. + * + * max_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the maximum number of user bytes that have been + * allocated in this pool. + * + * tot_alloced_p <- Pointer to an unsigned long which, if not NULL, + * will be set to the total amount of space (including administrative + * overhead) used by the pool. + */ +int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, + unsigned long *num_alloced_p, + unsigned long *user_alloced_p, + unsigned long *max_alloced_p, + unsigned long *tot_alloced_p) +{ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + SET_POINTER(page_size_p, mp_p->mp_page_size); + SET_POINTER(num_alloced_p, mp_p->mp_alloc_c); + SET_POINTER(user_alloced_p, mp_p->mp_user_alloc); + SET_POINTER(max_alloced_p, mp_p->mp_max_alloc); + SET_POINTER(tot_alloced_p, SIZE_OF_PAGES(mp_p, mp_p->mp_page_c)); + + return MPOOL_ERROR_NONE; +} + +/* + * int mpool_set_log_func + * + * DESCRIPTION: + * + * Set a logging callback function to be called whenever there was a + * memory transaction. See mpool_log_func_t. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * log_func -> Log function (defined in mpool.h) which will be called + * with each mpool transaction. + */ +int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func) +{ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + mp_p->mp_log_func = log_func; + + return MPOOL_ERROR_NONE; +} + +/* + * int mpool_set_max_pages + * + * DESCRIPTION: + * + * Set the maximum number of pages that the library will use. Once it + * hits the limit it will return MPOOL_ERROR_NO_PAGES. + * + * NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages + * value will include the page with the mpool header structure in it. + * If the flag is _not_ set then the max-pages will not include this + * first page. + * + * RETURNS: + * + * Success - MPOOL_ERROR_NONE + * + * Failure - Mpool error code + * + * ARGUMENTS: + * + * mp_p <-> Pointer to the memory pool. + * + * max_pages -> Maximum number of pages used by the library. + */ +int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages) +{ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } + + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { + mp_p->mp_max_pages = max_pages; + } + else { + /* + * If we are not heavy-packing the pool then we don't count the + * 1st page allocated which holds the mpool header structure. + */ + mp_p->mp_max_pages = max_pages + 1; + } + + return MPOOL_ERROR_NONE; +} + +/* + * const char *mpool_strerror + * + * DESCRIPTION: + * + * Return the corresponding string for the error number. + * + * RETURNS: + * + * Success - String equivalient of the error. + * + * Failure - String "invalid error code" + * + * ARGUMENTS: + * + * error -> Error number that we are converting. + */ +const char *mpool_strerror(const int error) +{ + switch (error) { + case MPOOL_ERROR_NONE: + return "no error"; + break; + case MPOOL_ERROR_ARG_NULL: + return "function argument is null"; + break; + case MPOOL_ERROR_ARG_INVALID: + return "function argument is invalid"; + break; + case MPOOL_ERROR_PNT: + return "invalid mpool pointer"; + break; + case MPOOL_ERROR_POOL_OVER: + return "mpool structure was overwritten"; + break; + case MPOOL_ERROR_PAGE_SIZE: + return "could not get system page-size"; + break; + case MPOOL_ERROR_OPEN_ZERO: + return "could not open /dev/zero"; + break; + case MPOOL_ERROR_NO_MEM: + return "no memory available"; + break; + case MPOOL_ERROR_MMAP: + return "problems with mmap"; + break; + case MPOOL_ERROR_SIZE: + return "error processing requested size"; + break; + case MPOOL_ERROR_TOO_BIG: + return "allocation exceeds pool max size"; + break; + case MPOOL_ERROR_MEM: + return "invalid memory address"; + break; + case MPOOL_ERROR_MEM_OVER: + return "memory lower bounds overwritten"; + break; + case MPOOL_ERROR_NOT_FOUND: + return "memory block not found in pool"; + break; + case MPOOL_ERROR_IS_FREE: + return "memory address has already been freed"; + break; + case MPOOL_ERROR_BLOCK_STAT: + return "invalid internal block status"; + break; + case MPOOL_ERROR_FREE_ADDR: + return "invalid internal free address"; + break; + case MPOOL_ERROR_SBRK_CONTIG: + return "sbrk did not return contiguous memory"; + break; + case MPOOL_ERROR_NO_PAGES: + return "no available pages left in pool"; + break; + case MPOOL_ERROR_ALLOC: + return "system alloc function failed"; + break; + case MPOOL_ERROR_PNT_OVER: + return "user pointer admin space overwritten"; + break; + default: + break; + } + + return "invalid error code"; +} diff --git a/libs/libks/src/simclist.c b/libs/libks/src/simclist.c new file mode 100755 index 0000000000..c8d36f5ff4 --- /dev/null +++ b/libs/libks/src/simclist.c @@ -0,0 +1,1525 @@ +/* + * Copyright (c) 2007,2008,2009,2010,2011 Mij + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/* + * SimCList library. See http://mij.oltrelinux.com/devel/simclist + */ + +/* SimCList implementation, version 1.6 */ + +#include +#include +#include /* for setting errno */ +#include +#ifndef _WIN32 + /* not in Windows! */ +# include +# include +#endif +#ifndef SIMCLIST_NO_DUMPRESTORE + /* includes for dump/restore */ +# include +# include /* for READ_ERRCHECK() and write() */ +# include /* for open() etc */ +# ifndef _WIN32 +# include /* for htons() on UNIX */ +# else +# include /* for htons() on Windows */ +# endif +#endif + +/* disable asserts */ +#ifndef SIMCLIST_DEBUG +#define NDEBUG +#endif + +#include + + +#include /* for open()'s access modes S_IRUSR etc */ +#include + +#if defined(_MSC_VER) || defined(__MINGW32__) +/* provide gettimeofday() missing in Windows */ +int gettimeofday(struct timeval *tp, void *tzp) { + DWORD t; + + /* XSI says: "If tzp is not a null pointer, the behavior is unspecified" */ + assert(tzp == NULL); + + t = timeGetTime(); + tp->tv_sec = t / 1000; + tp->tv_usec = t % 1000; + return 0; +} +#endif + + +/* work around lack of inttypes.h support in broken Microsoft Visual Studio compilers */ +#if !defined(_WIN32) || !defined(_MSC_VER) +# include /* (u)int*_t */ +#else +# include +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef ULONG32 uint32_t; +typedef UINT64 uint64_t; +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef LONG32 int32_t; +typedef INT64 int64_t; +#endif + + +/* define some commodity macros for Dump/Restore functionality */ +#ifndef SIMCLIST_NO_DUMPRESTORE +/* write() decorated with error checking logic */ +#define WRITE_ERRCHECK(fd, msgbuf, msglen) do { \ + if (write(fd, msgbuf, msglen) < 0) return -1; \ + } while (0); +/* READ_ERRCHECK() decorated with error checking logic */ +#define READ_ERRCHECK(fd, msgbuf, msglen) do { \ + if (read(fd, msgbuf, msglen) != msglen) { \ + /*errno = EPROTO;*/ \ + return -1; \ + } \ + } while (0); + +/* convert 64bit integers from host to network format */ +#define hton64(x) (\ + htons(1) == 1 ? \ + (uint64_t)x /* big endian */ \ + : /* little endian */ \ + ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ + (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) \ + ) + +/* convert 64bit integers from network to host format */ +#define ntoh64(x) (hton64(x)) +#endif + +/* some OSes don't have EPROTO (eg OpenBSD) */ +#ifndef EPROTO +#define EPROTO EIO +#endif + +#ifdef SIMCLIST_WITH_THREADS +/* limit (approx) to the number of threads running + * for threaded operations. Only meant when + * SIMCLIST_WITH_THREADS is defined */ +#define SIMCLIST_MAXTHREADS 2 +#endif + +/* + * how many elems to keep as spare. During a deletion, an element + * can be saved in a "free-list", not free()d immediately. When + * latter insertions are performed, spare elems can be used instead + * of malloc()ing new elems. + * + * about this param, some values for appending + * 10 million elems into an empty list: + * (#, time[sec], gain[%], gain/no[%]) + * 0 2,164 0,00 0,00 <-- feature disabled + * 1 1,815 34,9 34,9 + * 2 1,446 71,8 35,9 <-- MAX gain/no + * 3 1,347 81,7 27,23 + * 5 1,213 95,1 19,02 + * 8 1,064 110,0 13,75 + * 10 1,015 114,9 11,49 <-- MAX gain w/ likely sol + * 15 1,019 114,5 7,63 + * 25 0,985 117,9 4,72 + * 50 1,088 107,6 2,15 + * 75 1,016 114,8 1,53 + * 100 0,988 117,6 1,18 + * 150 1,022 114,2 0,76 + * 200 0,939 122,5 0,61 <-- MIN time + */ +#ifndef SIMCLIST_MAX_SPARE_ELEMS +#define SIMCLIST_MAX_SPARE_ELEMS 5 +#endif + + +#ifdef SIMCLIST_WITH_THREADS +#include +#endif + +#include "simclist.h" + + +/* minumum number of elements for sorting with quicksort instead of insertion */ +#define SIMCLIST_MINQUICKSORTELS 24 + + +/* list dump declarations */ +#define SIMCLIST_DUMPFORMAT_VERSION 1 /* (short integer) version of fileformat managed by _dump* and _restore* functions */ + +#define SIMCLIST_DUMPFORMAT_HEADERLEN 30 /* length of the header */ + +/* header for a list dump */ +struct list_dump_header_s { + uint16_t ver; /* version */ + int32_t timestamp_sec; /* dump timestamp, seconds since UNIX Epoch */ + int32_t timestamp_usec; /* dump timestamp, microseconds since timestamp_sec */ + int32_t rndterm; /* random value terminator -- terminates the data sequence */ + + uint32_t totlistlen; /* sum of every element' size, bytes */ + uint32_t numels; /* number of elements */ + uint32_t elemlen; /* bytes length of an element, for constant-size lists, <= 0 otherwise */ + int32_t listhash; /* hash of the list at the time of dumping, or 0 if to be ignored */ +}; + + + +/* deletes tmp from list, with care wrt its position (head, tail, middle) */ +static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos); + +/* set default values for initialized lists */ +static int list_attributes_setdefaults(list_t *restrict l); + +#ifndef NDEBUG +/* check whether the list internal REPresentation is valid -- Costs O(n) */ +static int list_repOk(const list_t *restrict l); + +/* check whether the list attribute set is valid -- Costs O(1) */ +static int list_attrOk(const list_t *restrict l); +#endif + +/* do not inline, this is recursive */ +static void list_sort_quicksort(list_t *restrict l, int versus, + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel); + +static inline void list_sort_selectionsort(list_t *restrict l, int versus, + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel); + +static void *list_get_minmax(const list_t *restrict l, int versus); + +static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart); + +/* + * Random Number Generator + * + * The user is expected to seed the RNG (ie call srand()) if + * SIMCLIST_SYSTEM_RNG is defined. + * + * Otherwise, a self-contained RNG based on LCG is used; see + * http://en.wikipedia.org/wiki/Linear_congruential_generator . + * + * Facts pro local RNG: + * 1. no need for the user to call srand() on his own + * 2. very fast, possibly faster than OS + * 3. avoid interference with user's RNG + * + * Facts pro system RNG: + * 1. may be more accurate (irrelevant for SimCList randno purposes) + * 2. why reinvent the wheel + * + * Default to local RNG for user's ease of use. + */ + +#ifdef SIMCLIST_SYSTEM_RNG +/* keep track whether we initialized already (non-0) or not (0) */ +static unsigned random_seed = 0; + +/* use local RNG */ +static inline void seed_random(void) { + if (random_seed == 0) + random_seed = (unsigned)getpid() ^ (unsigned)time(NULL); +} + +static inline long get_random(void) { + random_seed = (1664525 * random_seed + 1013904223); + return random_seed; +} + +#else +/* use OS's random generator */ +# define seed_random() +# define get_random() (rand()) +#endif + + +/* list initialization */ +int list_init(list_t *restrict l) { + if (l == NULL) return -1; + + seed_random(); + + l->numels = 0; + + /* head/tail sentinels and mid pointer */ + l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + l->head_sentinel->next = l->tail_sentinel; + l->tail_sentinel->prev = l->head_sentinel; + l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL; + l->head_sentinel->data = l->tail_sentinel->data = NULL; + + /* iteration attributes */ + l->iter_active = 0; + l->iter_pos = 0; + l->iter_curentry = NULL; + + /* free-list attributes */ + l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *)); + l->spareelsnum = 0; + +#ifdef SIMCLIST_WITH_THREADS + l->threadcount = 0; +#endif + + list_attributes_setdefaults(l); + + assert(list_repOk(l)); + assert(list_attrOk(l)); + + return 0; +} + +void list_destroy(list_t *restrict l) { + unsigned int i; + + list_clear(l); + for (i = 0; i < l->spareelsnum; i++) { + free(l->spareels[i]); + } + free(l->spareels); + free(l->head_sentinel); + free(l->tail_sentinel); +} + +int list_attributes_setdefaults(list_t *restrict l) { + l->attrs.comparator = NULL; + l->attrs.seeker = NULL; + + /* also free() element data when removing and element from the list */ + l->attrs.meter = NULL; + l->attrs.copy_data = 0; + + l->attrs.hasher = NULL; + + /* serializer/unserializer */ + l->attrs.serializer = NULL; + l->attrs.unserializer = NULL; + + assert(list_attrOk(l)); + + return 0; +} + +/* setting list properties */ +int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun) { + if (l == NULL) return -1; + + l->attrs.comparator = comparator_fun; + + assert(list_attrOk(l)); + + return 0; +} + +int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) { + if (l == NULL) return -1; + + l->attrs.seeker = seeker_fun; + assert(list_attrOk(l)); + + return 0; +} + +int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data) { + if (l == NULL || (metric_fun == NULL && copy_data != 0)) return -1; + + l->attrs.meter = metric_fun; + l->attrs.copy_data = copy_data; + + assert(list_attrOk(l)); + + return 0; +} + +int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun) { + if (l == NULL) return -1; + + l->attrs.hasher = hash_computer_fun; + assert(list_attrOk(l)); + return 0; +} + +int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun) { + if (l == NULL) return -1; + + l->attrs.serializer = serializer_fun; + assert(list_attrOk(l)); + return 0; +} + +int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun) { + if (l == NULL) return -1; + + l->attrs.unserializer = unserializer_fun; + assert(list_attrOk(l)); + return 0; +} + +int list_append(list_t *restrict l, const void *data) { + return list_insert_at(l, data, l->numels); +} + +int list_prepend(list_t *restrict l, const void *data) { + return list_insert_at(l, data, 0); +} + +void *list_fetch(list_t *restrict l) { + return list_extract_at(l, 0); +} + +void *list_get_at(const list_t *restrict l, unsigned int pos) { + struct list_entry_s *tmp; + + tmp = list_findpos(l, pos); + + return (tmp != NULL ? tmp->data : NULL); +} + +void *list_get_max(const list_t *restrict l) { + return list_get_minmax(l, +1); +} + +void *list_get_min(const list_t *restrict l) { + return list_get_minmax(l, -1); +} + +/* REQUIRES {list->numels >= 1} + * return the min (versus < 0) or max value (v > 0) in l */ +static void *list_get_minmax(const list_t *restrict l, int versus) { + void *curminmax; + struct list_entry_s *s; + + if (l->attrs.comparator == NULL || l->numels == 0) + return NULL; + + curminmax = l->head_sentinel->next->data; + for (s = l->head_sentinel->next->next; s != l->tail_sentinel; s = s->next) { + if (l->attrs.comparator(curminmax, s->data) * versus > 0) + curminmax = s->data; + } + + return curminmax; +} + +/* set tmp to point to element at index posstart in l */ +static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart) { + struct list_entry_s *ptr; + float x; + int i; + + /* accept 1 slot overflow for fetching head and tail sentinels */ + if (posstart < -1 || posstart > (int)l->numels) return NULL; + + x = (float)(posstart+1) / l->numels; + if (x <= 0.25) { + /* first quarter: get to posstart from head */ + for (i = -1, ptr = l->head_sentinel; i < posstart; ptr = ptr->next, i++); + } else if (x < 0.5) { + /* second quarter: get to posstart from mid */ + for (i = (l->numels-1)/2, ptr = l->mid; i > posstart; ptr = ptr->prev, i--); + } else if (x <= 0.75) { + /* third quarter: get to posstart from mid */ + for (i = (l->numels-1)/2, ptr = l->mid; i < posstart; ptr = ptr->next, i++); + } else { + /* fourth quarter: get to posstart from tail */ + for (i = l->numels, ptr = l->tail_sentinel; i > posstart; ptr = ptr->prev, i--); + } + + return ptr; +} + +void *list_extract_at(list_t *restrict l, unsigned int pos) { + struct list_entry_s *tmp; + void *data; + + if (l->iter_active || pos >= l->numels) return NULL; + + tmp = list_findpos(l, pos); + data = tmp->data; + + tmp->data = NULL; /* save data from list_drop_elem() free() */ + list_drop_elem(l, tmp, pos); + l->numels--; + + assert(list_repOk(l)); + + return data; +} + +int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) { + struct list_entry_s *lent, *succ, *prec; + + if (l->iter_active || pos > l->numels) return -1; + + /* this code optimizes malloc() with a free-list */ + if (l->spareelsnum > 0) { + lent = l->spareels[l->spareelsnum-1]; + l->spareelsnum--; + } else { + lent = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + if (lent == NULL) + return -1; + } + + if (l->attrs.copy_data) { + /* make room for user' data (has to be copied) */ + size_t datalen = l->attrs.meter(data); + lent->data = (struct list_entry_s *)malloc(datalen); + memcpy(lent->data, data, datalen); + } else { + lent->data = (void*)data; + } + + /* actually append element */ + prec = list_findpos(l, pos-1); + succ = prec->next; + + prec->next = lent; + lent->prev = prec; + lent->next = succ; + succ->prev = lent; + + l->numels++; + + /* fix mid pointer */ + if (l->numels == 1) { /* first element, set pointer */ + l->mid = lent; + } else if (l->numels % 2) { /* now odd */ + if (pos >= (l->numels-1)/2) l->mid = l->mid->next; + } else { /* now even */ + if (pos <= (l->numels-1)/2) l->mid = l->mid->prev; + } + + assert(list_repOk(l)); + + return 1; +} + +int list_delete(list_t *restrict l, const void *data) { + int pos, r; + + pos = list_locate(l, data); + if (pos < 0) + return -1; + + r = list_delete_at(l, pos); + if (r < 0) + return -1; + + assert(list_repOk(l)); + + return 0; +} + +int list_delete_at(list_t *restrict l, unsigned int pos) { + struct list_entry_s *delendo; + + + if (l->iter_active || pos >= l->numels) return -1; + + delendo = list_findpos(l, pos); + + list_drop_elem(l, delendo, pos); + + l->numels--; + + + assert(list_repOk(l)); + + return 0; +} + +int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) { + struct list_entry_s *lastvalid, *tmp, *tmp2; + unsigned int numdel, midposafter, i; + int movedx; + + if (l->iter_active || posend < posstart || posend >= l->numels) return -1; + + numdel = posend - posstart + 1; + if (numdel == l->numels) return list_clear(l); + + tmp = list_findpos(l, posstart); /* first el to be deleted */ + lastvalid = tmp->prev; /* last valid element */ + + midposafter = (l->numels-1-numdel)/2; + + midposafter = midposafter < posstart ? midposafter : midposafter+numdel; + movedx = midposafter - (l->numels-1)/2; + + if (movedx > 0) { /* move right */ + for (i = 0; i < (unsigned int)movedx; l->mid = l->mid->next, i++); + } else { /* move left */ + movedx = -movedx; + for (i = 0; i < (unsigned int)movedx; l->mid = l->mid->prev, i++); + } + + assert(posstart == 0 || lastvalid != l->head_sentinel); + i = posstart; + if (l->attrs.copy_data) { + /* also free element data */ + for (; i <= posend; i++) { + tmp2 = tmp; + tmp = tmp->next; + if (tmp2->data != NULL) free(tmp2->data); + if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { + l->spareels[l->spareelsnum++] = tmp2; + } else { + free(tmp2); + } + } + } else { + /* only free containers */ + for (; i <= posend; i++) { + tmp2 = tmp; + tmp = tmp->next; + if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { + l->spareels[l->spareelsnum++] = tmp2; + } else { + free(tmp2); + } + } + } + assert(i == posend+1 && (posend != l->numels || tmp == l->tail_sentinel)); + + lastvalid->next = tmp; + tmp->prev = lastvalid; + + l->numels -= posend - posstart + 1; + + assert(list_repOk(l)); + + return numdel; +} + +int list_clear(list_t *restrict l) { + struct list_entry_s *s; + unsigned int numels; + + /* will be returned */ + numels = l->numels; + + if (l->iter_active) return -1; + + if (l->attrs.copy_data) { /* also free user data */ + /* spare a loop conditional with two loops: spareing elems and freeing elems */ + for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { + /* move elements as spares as long as there is room */ + if (s->data != NULL) free(s->data); + l->spareels[l->spareelsnum++] = s; + } + while (s != l->tail_sentinel) { + /* free the remaining elems */ + if (s->data != NULL) free(s->data); + s = s->next; + free(s->prev); + } + l->head_sentinel->next = l->tail_sentinel; + l->tail_sentinel->prev = l->head_sentinel; + } else { /* only free element containers */ + /* spare a loop conditional with two loops: spareing elems and freeing elems */ + for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { + /* move elements as spares as long as there is room */ + l->spareels[l->spareelsnum++] = s; + } + while (s != l->tail_sentinel) { + /* free the remaining elems */ + s = s->next; + free(s->prev); + } + l->head_sentinel->next = l->tail_sentinel; + l->tail_sentinel->prev = l->head_sentinel; + } + l->numels = 0; + l->mid = NULL; + + assert(list_repOk(l)); + + return numels; +} + +unsigned int list_size(const list_t *restrict l) { + return l->numels; +} + +int list_empty(const list_t *restrict l) { + return (l->numels == 0); +} + +int list_locate(const list_t *restrict l, const void *data) { + struct list_entry_s *el; + int pos = 0; + + if (l->attrs.comparator != NULL) { + /* use comparator */ + for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) { + if (l->attrs.comparator(data, el->data) == 0) break; + } + } else { + /* compare references */ + for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) { + if (el->data == data) break; + } + } + if (el == l->tail_sentinel) return -1; + + return pos; +} + +void *list_seek(list_t *restrict l, const void *indicator) { + const struct list_entry_s *iter; + + if (l->attrs.seeker == NULL) return NULL; + + for (iter = l->head_sentinel->next; iter != l->tail_sentinel; iter = iter->next) { + if (l->attrs.seeker(iter->data, indicator) != 0) return iter->data; + } + + return NULL; +} + +int list_contains(const list_t *restrict l, const void *data) { + return (list_locate(l, data) >= 0); +} + +int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) { + struct list_entry_s *el, *srcel; + unsigned int cnt; + int err; + + + if (l1 == NULL || l2 == NULL || dest == NULL || l1 == dest || l2 == dest) + return -1; + + list_init(dest); + + dest->numels = l1->numels + l2->numels; + if (dest->numels == 0) + return 0; + + /* copy list1 */ + srcel = l1->head_sentinel->next; + el = dest->head_sentinel; + while (srcel != l1->tail_sentinel) { + el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + el->next->prev = el; + el = el->next; + el->data = srcel->data; + srcel = srcel->next; + } + dest->mid = el; /* approximate position (adjust later) */ + /* copy list 2 */ + srcel = l2->head_sentinel->next; + while (srcel != l2->tail_sentinel) { + el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + el->next->prev = el; + el = el->next; + el->data = srcel->data; + srcel = srcel->next; + } + el->next = dest->tail_sentinel; + dest->tail_sentinel->prev = el; + + /* fix mid pointer */ + err = l2->numels - l1->numels; + if ((err+1)/2 > 0) { /* correct pos RIGHT (err-1)/2 moves */ + err = (err+1)/2; + for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->next; + } else if (err/2 < 0) { /* correct pos LEFT (err/2)-1 moves */ + err = -err/2; + for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->prev; + } + + assert(!(list_repOk(l1) && list_repOk(l2)) || list_repOk(dest)); + + return 0; +} + +int list_sort(list_t *restrict l, int versus) { + if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */ + return -1; + + if (l->numels <= 1) + return 0; + list_sort_quicksort(l, versus, 0, l->head_sentinel->next, l->numels-1, l->tail_sentinel->prev); + assert(list_repOk(l)); + return 0; +} + +#ifdef SIMCLIST_WITH_THREADS +struct list_sort_wrappedparams { + list_t *restrict l; + int versus; + unsigned int first, last; + struct list_entry_s *fel, *lel; +}; + +static void *list_sort_quicksort_threadwrapper(void *wrapped_params) { + struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)wrapped_params; + list_sort_quicksort(wp->l, wp->versus, wp->first, wp->fel, wp->last, wp->lel); + free(wp); + pthread_exit(NULL); + return NULL; +} +#endif + +static inline void list_sort_selectionsort(list_t *restrict l, int versus, + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel) { + struct list_entry_s *cursor, *toswap, *firstunsorted; + void *tmpdata; + + if (last <= first) /* <= 1-element lists are always sorted */ + return; + + for (firstunsorted = fel; firstunsorted != lel; firstunsorted = firstunsorted->next) { + /* find min or max in the remainder of the list */ + for (toswap = firstunsorted, cursor = firstunsorted->next; cursor != lel->next; cursor = cursor->next) + if (l->attrs.comparator(toswap->data, cursor->data) * -versus > 0) toswap = cursor; + if (toswap != firstunsorted) { /* swap firstunsorted with toswap */ + tmpdata = firstunsorted->data; + firstunsorted->data = toswap->data; + toswap->data = tmpdata; + } + } +} + +static void list_sort_quicksort(list_t *restrict l, int versus, + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel) { + unsigned int pivotid; + unsigned int i; + register struct list_entry_s *pivot; + struct list_entry_s *left, *right; + void *tmpdata; +#ifdef SIMCLIST_WITH_THREADS + pthread_t tid; + int traised; +#endif + + + if (last <= first) /* <= 1-element lists are always sorted */ + return; + + if (last - first+1 <= SIMCLIST_MINQUICKSORTELS) { + list_sort_selectionsort(l, versus, first, fel, last, lel); + return; + } + + /* base of iteration: one element list */ + if (! (last > first)) return; + + pivotid = (get_random() % (last - first + 1)); + /* pivotid = (last - first + 1) / 2; */ + + /* find pivot */ + if (pivotid < (last - first + 1)/2) { + for (i = 0, pivot = fel; i < pivotid; pivot = pivot->next, i++); + } else { + for (i = last - first, pivot = lel; i > pivotid; pivot = pivot->prev, i--); + } + + /* smaller PIVOT bigger */ + left = fel; + right = lel; + /* iterate --- left ---> PIV <--- right --- */ + while (left != pivot && right != pivot) { + for (; left != pivot && (l->attrs.comparator(left->data, pivot->data) * -versus <= 0); left = left->next); + /* left points to a smaller element, or to pivot */ + for (; right != pivot && (l->attrs.comparator(right->data, pivot->data) * -versus >= 0); right = right->prev); + /* right points to a bigger element, or to pivot */ + if (left != pivot && right != pivot) { + /* swap, then move iterators */ + tmpdata = left->data; + left->data = right->data; + right->data = tmpdata; + + left = left->next; + right = right->prev; + } + } + + /* now either left points to pivot (end run), or right */ + if (right == pivot) { /* left part longer */ + while (left != pivot) { + if (l->attrs.comparator(left->data, pivot->data) * -versus > 0) { + tmpdata = left->data; + left->data = pivot->prev->data; + pivot->prev->data = pivot->data; + pivot->data = tmpdata; + pivot = pivot->prev; + pivotid--; + if (pivot == left) break; + } else { + left = left->next; + } + } + } else { /* right part longer */ + while (right != pivot) { + if (l->attrs.comparator(right->data, pivot->data) * -versus < 0) { + /* move current right before pivot */ + tmpdata = right->data; + right->data = pivot->next->data; + pivot->next->data = pivot->data; + pivot->data = tmpdata; + pivot = pivot->next; + pivotid++; + if (pivot == right) break; + } else { + right = right->prev; + } + } + } + + /* sort sublists A and B : |---A---| pivot |---B---| */ + +#ifdef SIMCLIST_WITH_THREADS + traised = 0; + if (pivotid > 0) { + /* prepare wrapped args, then start thread */ + if (l->threadcount < SIMCLIST_MAXTHREADS-1) { + struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)malloc(sizeof(struct list_sort_wrappedparams)); + l->threadcount++; + traised = 1; + wp->l = l; + wp->versus = versus; + wp->first = first; + wp->fel = fel; + wp->last = first+pivotid-1; + wp->lel = pivot->prev; + if (pthread_create(&tid, NULL, list_sort_quicksort_threadwrapper, wp) != 0) { + free(wp); + traised = 0; + list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev); + } + } else { + list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev); + } + } + if (first + pivotid < last) list_sort_quicksort(l, versus, first+pivotid+1, pivot->next, last, lel); + if (traised) { + pthread_join(tid, (void **)NULL); + l->threadcount--; + } +#else + if (pivotid > 0) list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev); + if (first + pivotid < last) list_sort_quicksort(l, versus, first+pivotid+1, pivot->next, last, lel); +#endif +} + +int list_iterator_start(list_t *restrict l) { + if (l->iter_active) return 0; + l->iter_pos = 0; + l->iter_active = 1; + l->iter_curentry = l->head_sentinel->next; + return 1; +} + +void *list_iterator_next(list_t *restrict l) { + void *toret; + + if (! l->iter_active) return NULL; + + toret = l->iter_curentry->data; + l->iter_curentry = l->iter_curentry->next; + l->iter_pos++; + + return toret; +} + +int list_iterator_hasnext(const list_t *restrict l) { + if (! l->iter_active) return 0; + return (l->iter_pos < l->numels); +} + +int list_iterator_stop(list_t *restrict l) { + if (! l->iter_active) return 0; + l->iter_pos = 0; + l->iter_active = 0; + return 1; +} + +int list_hash(const list_t *restrict l, list_hash_t *restrict hash) { + struct list_entry_s *x; + list_hash_t tmphash; + + assert(hash != NULL); + + tmphash = l->numels * 2 + 100; + if (l->attrs.hasher == NULL) { +#ifdef SIMCLIST_ALLOW_LOCATIONBASED_HASHES + /* ENABLE WITH CARE !! */ +#warning "Memlocation-based hash is consistent only for testing modification in the same program run." + int i; + + /* only use element references */ + for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { + for (i = 0; i < sizeof(x->data); i++) { + tmphash += (tmphash ^ (uintptr_t)x->data); + } + tmphash += tmphash % l->numels; + } +#else + return -1; +#endif + } else { + /* hash each element with the user-given function */ + for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { + tmphash += tmphash ^ l->attrs.hasher(x->data); + tmphash += tmphash % l->numels; + } + } + + *hash = tmphash; + + return 0; +} + +#ifndef SIMCLIST_NO_DUMPRESTORE +int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) { + int32_t terminator_head, terminator_tail; + uint32_t elemlen; + off_t hop; + + + /* version */ + READ_ERRCHECK(fd, & info->version, sizeof(info->version)); + info->version = ntohs(info->version); + if (info->version > SIMCLIST_DUMPFORMAT_VERSION) { + errno = EILSEQ; + return -1; + } + + /* timestamp.tv_sec and timestamp.tv_usec */ + READ_ERRCHECK(fd, & info->timestamp.tv_sec, sizeof(info->timestamp.tv_sec)); + info->timestamp.tv_sec = ntohl(info->timestamp.tv_sec); + READ_ERRCHECK(fd, & info->timestamp.tv_usec, sizeof(info->timestamp.tv_usec)); + info->timestamp.tv_usec = ntohl(info->timestamp.tv_usec); + + /* list terminator (to check thereafter) */ + READ_ERRCHECK(fd, & terminator_head, sizeof(terminator_head)); + terminator_head = ntohl(terminator_head); + + /* list size */ + READ_ERRCHECK(fd, & info->list_size, sizeof(info->list_size)); + info->list_size = ntohl(info->list_size); + + /* number of elements */ + READ_ERRCHECK(fd, & info->list_numels, sizeof(info->list_numels)); + info->list_numels = ntohl(info->list_numels); + + /* length of each element (for checking for consistency) */ + READ_ERRCHECK(fd, & elemlen, sizeof(elemlen)); + elemlen = ntohl(elemlen); + + /* list hash */ + READ_ERRCHECK(fd, & info->list_hash, sizeof(info->list_hash)); + info->list_hash = ntohl(info->list_hash); + + /* check consistency */ + if (elemlen > 0) { + /* constant length, hop by size only */ + hop = info->list_size; + } else { + /* non-constant length, hop by size + all element length blocks */ + hop = info->list_size + elemlen*info->list_numels; + } + if (lseek(fd, hop, SEEK_CUR) == -1) { + return -1; + } + + /* read the trailing value and compare with terminator_head */ + READ_ERRCHECK(fd, & terminator_tail, sizeof(terminator_tail)); + terminator_tail = ntohl(terminator_tail); + + if (terminator_head == terminator_tail) + info->consistent = 1; + else + info->consistent = 0; + + return 0; +} + +int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info) { + int fd, ret; + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) return -1; + + ret = list_dump_getinfo_filedescriptor(fd, info); + close(fd); + + return ret; +} + +int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) { + struct list_entry_s *x; + void *ser_buf; + uint32_t bufsize; + struct timeval timeofday; + struct list_dump_header_s header; + + if (l->attrs.meter == NULL && l->attrs.serializer == NULL) { + errno = ENOTTY; + return -1; + } + + /**** DUMP FORMAT **** + + [ ver timestamp | totlen numels elemlen hash | DATA ] + + where DATA can be: + @ for constant-size list (element size is constant; elemlen > 0) + [ elem elem ... elem ] + @ for other lists (element size dictated by element_meter each time; elemlen <= 0) + [ size elem size elem ... size elem ] + + all integers are encoded in NETWORK BYTE FORMAT + *****/ + + + /* prepare HEADER */ + /* version */ + header.ver = htons( SIMCLIST_DUMPFORMAT_VERSION ); + + /* timestamp */ + gettimeofday(&timeofday, NULL); + header.timestamp_sec = htonl(timeofday.tv_sec); + header.timestamp_usec = htonl(timeofday.tv_usec); + + header.rndterm = htonl((int32_t)get_random()); + + /* total list size is postprocessed afterwards */ + + /* number of elements */ + header.numels = htonl(l->numels); + + /* include an hash, if possible */ + if (l->attrs.hasher != NULL) { + if (htonl(list_hash(l, & header.listhash)) != 0) { + /* could not compute list hash! */ + return -1; + } + } else { + header.listhash = htonl(0); + } + + header.totlistlen = header.elemlen = 0; + + /* leave room for the header at the beginning of the file */ + if (lseek(fd, SIMCLIST_DUMPFORMAT_HEADERLEN, SEEK_SET) < 0) { + /* errno set by lseek() */ + return -1; + } + + /* write CONTENT */ + if (l->numels > 0) { + /* SPECULATE that the list has constant element size */ + + if (l->attrs.serializer != NULL) { /* user user-specified serializer */ + /* get preliminary length of serialized element in header.elemlen */ + ser_buf = l->attrs.serializer(l->head_sentinel->next->data, & header.elemlen); + free(ser_buf); + /* request custom serialization of each element */ + for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { + ser_buf = l->attrs.serializer(x->data, &bufsize); + header.totlistlen += bufsize; + if (header.elemlen != 0) { /* continue on speculation */ + if (header.elemlen != bufsize) { + free(ser_buf); + /* constant element length speculation broken! */ + header.elemlen = 0; + header.totlistlen = 0; + x = l->head_sentinel; + if (lseek(fd, SIMCLIST_DUMPFORMAT_HEADERLEN, SEEK_SET) < 0) { + /* errno set by lseek() */ + return -1; + } + /* restart from the beginning */ + continue; + } + /* speculation confirmed */ + WRITE_ERRCHECK(fd, ser_buf, bufsize); + } else { /* speculation found broken */ + WRITE_ERRCHECK(fd, & bufsize, sizeof(size_t)); + WRITE_ERRCHECK(fd, ser_buf, bufsize); + } + free(ser_buf); + } + } else if (l->attrs.meter != NULL) { + header.elemlen = (uint32_t)l->attrs.meter(l->head_sentinel->next->data); + + /* serialize the element straight from its data */ + for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { + bufsize = l->attrs.meter(x->data); + header.totlistlen += bufsize; + if (header.elemlen != 0) { + if (header.elemlen != bufsize) { + /* constant element length speculation broken! */ + header.elemlen = 0; + header.totlistlen = 0; + x = l->head_sentinel; + /* restart from the beginning */ + continue; + } + WRITE_ERRCHECK(fd, x->data, bufsize); + } else { + WRITE_ERRCHECK(fd, &bufsize, sizeof(size_t)); + WRITE_ERRCHECK(fd, x->data, bufsize); + } + } + } + /* adjust endianness */ + header.elemlen = htonl(header.elemlen); + header.totlistlen = htonl(header.totlistlen); + } + + /* write random terminator */ + WRITE_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm)); /* list terminator */ + + + /* write header */ + lseek(fd, 0, SEEK_SET); + + WRITE_ERRCHECK(fd, & header.ver, sizeof(header.ver)); /* version */ + WRITE_ERRCHECK(fd, & header.timestamp_sec, sizeof(header.timestamp_sec)); /* timestamp seconds */ + WRITE_ERRCHECK(fd, & header.timestamp_usec, sizeof(header.timestamp_usec)); /* timestamp microseconds */ + WRITE_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm)); /* random terminator */ + + WRITE_ERRCHECK(fd, & header.totlistlen, sizeof(header.totlistlen)); /* total length of elements */ + WRITE_ERRCHECK(fd, & header.numels, sizeof(header.numels)); /* number of elements */ + WRITE_ERRCHECK(fd, & header.elemlen, sizeof(header.elemlen)); /* size of each element, or 0 for independent */ + WRITE_ERRCHECK(fd, & header.listhash, sizeof(header.listhash)); /* list hash, or 0 for "ignore" */ + + + /* possibly store total written length in "len" */ + if (len != NULL) { + *len = sizeof(header) + ntohl(header.totlistlen); + } + + return 0; +} + +int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len) { + struct list_dump_header_s header; + unsigned long cnt; + void *buf; + uint32_t elsize, totreadlen, totmemorylen; + + memset(& header, 0, sizeof(header)); + + /* read header */ + + /* version */ + READ_ERRCHECK(fd, &header.ver, sizeof(header.ver)); + header.ver = ntohs(header.ver); + if (header.ver != SIMCLIST_DUMPFORMAT_VERSION) { + errno = EILSEQ; + return -1; + } + + /* timestamp */ + READ_ERRCHECK(fd, & header.timestamp_sec, sizeof(header.timestamp_sec)); + header.timestamp_sec = ntohl(header.timestamp_sec); + READ_ERRCHECK(fd, & header.timestamp_usec, sizeof(header.timestamp_usec)); + header.timestamp_usec = ntohl(header.timestamp_usec); + + /* list terminator */ + READ_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm)); + + header.rndterm = ntohl(header.rndterm); + + /* total list size */ + READ_ERRCHECK(fd, & header.totlistlen, sizeof(header.totlistlen)); + header.totlistlen = ntohl(header.totlistlen); + + /* number of elements */ + READ_ERRCHECK(fd, & header.numels, sizeof(header.numels)); + header.numels = ntohl(header.numels); + + /* length of every element, or '0' = variable */ + READ_ERRCHECK(fd, & header.elemlen, sizeof(header.elemlen)); + header.elemlen = ntohl(header.elemlen); + + /* list hash, or 0 = 'ignore' */ + READ_ERRCHECK(fd, & header.listhash, sizeof(header.listhash)); + header.listhash = ntohl(header.listhash); + + + /* read content */ + totreadlen = totmemorylen = 0; + if (header.elemlen > 0) { + /* elements have constant size = header.elemlen */ + if (l->attrs.unserializer != NULL) { + /* use unserializer */ + buf = malloc(header.elemlen); + for (cnt = 0; cnt < header.numels; cnt++) { + READ_ERRCHECK(fd, buf, header.elemlen); + list_append(l, l->attrs.unserializer(buf, & elsize)); + totmemorylen += elsize; + } + } else { + /* copy verbatim into memory */ + for (cnt = 0; cnt < header.numels; cnt++) { + buf = malloc(header.elemlen); + READ_ERRCHECK(fd, buf, header.elemlen); + list_append(l, buf); + } + totmemorylen = header.numels * header.elemlen; + } + totreadlen = header.numels * header.elemlen; + } else { + /* elements have variable size. Each element is preceded by its size */ + if (l->attrs.unserializer != NULL) { + /* use unserializer */ + for (cnt = 0; cnt < header.numels; cnt++) { + READ_ERRCHECK(fd, & elsize, sizeof(elsize)); + buf = malloc((size_t)elsize); + READ_ERRCHECK(fd, buf, elsize); + totreadlen += elsize; + list_append(l, l->attrs.unserializer(buf, & elsize)); + totmemorylen += elsize; + } + } else { + /* copy verbatim into memory */ + for (cnt = 0; cnt < header.numels; cnt++) { + READ_ERRCHECK(fd, & elsize, sizeof(elsize)); + buf = malloc(elsize); + READ_ERRCHECK(fd, buf, elsize); + totreadlen += elsize; + list_append(l, buf); + } + totmemorylen = totreadlen; + } + } + + READ_ERRCHECK(fd, &elsize, sizeof(elsize)); /* read list terminator */ + elsize = ntohl(elsize); + + /* possibly verify the list consistency */ + /* wrt hash */ + /* don't do that + if (header.listhash != 0 && header.listhash != list_hash(l)) { + errno = ECANCELED; + return -1; + } + */ + + /* wrt header */ + if (totreadlen != header.totlistlen && (int32_t)elsize == header.rndterm) { + errno = EPROTO; + return -1; + } + + /* wrt file */ + if (lseek(fd, 0, SEEK_CUR) != lseek(fd, 0, SEEK_END)) { + errno = EPROTO; + return -1; + } + + if (len != NULL) { + *len = totmemorylen; + } + + return 0; +} + +int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) { + int fd, oflag, mode; + +#ifndef _WIN32 + oflag = O_RDWR | O_CREAT | O_TRUNC; + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; +#else + oflag = _O_RDWR | _O_CREAT | _O_TRUNC; + mode = _S_IRUSR | _S_IWUSR | _S_IRGRP | _S_IROTH; +#endif + fd = open(filename, oflag, mode); + if (fd < 0) return -1; + + list_dump_filedescriptor(l, fd, len); + close(fd); + + return 0; +} + +int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) { + int fd; + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) return -1; + + list_restore_filedescriptor(l, fd, len); + close(fd); + + return 0; +} +#endif /* ifndef SIMCLIST_NO_DUMPRESTORE */ + + +static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos) { + if (tmp == NULL) return -1; + + /* fix mid pointer. This is wrt the PRE situation */ + if (l->numels % 2) { /* now odd */ + /* sort out the base case by hand */ + if (l->numels == 1) l->mid = NULL; + else if (pos >= l->numels/2) l->mid = l->mid->prev; + } else { /* now even */ + if (pos < l->numels/2) l->mid = l->mid->next; + } + + tmp->prev->next = tmp->next; + tmp->next->prev = tmp->prev; + + /* free what's to be freed */ + if (l->attrs.copy_data && tmp->data != NULL) + free(tmp->data); + + if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { + l->spareels[l->spareelsnum++] = tmp; + } else { + free(tmp); + } + + return 0; +} + +/* ready-made comparators and meters */ +#define SIMCLIST_NUMBER_COMPARATOR(type) int list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); } + +SIMCLIST_NUMBER_COMPARATOR(int8_t) +SIMCLIST_NUMBER_COMPARATOR(int16_t) +SIMCLIST_NUMBER_COMPARATOR(int32_t) +SIMCLIST_NUMBER_COMPARATOR(int64_t) + +SIMCLIST_NUMBER_COMPARATOR(uint8_t) +SIMCLIST_NUMBER_COMPARATOR(uint16_t) +SIMCLIST_NUMBER_COMPARATOR(uint32_t) +SIMCLIST_NUMBER_COMPARATOR(uint64_t) + +SIMCLIST_NUMBER_COMPARATOR(float) +SIMCLIST_NUMBER_COMPARATOR(double) + +int list_comparator_string(const void *a, const void *b) { return strcmp((const char *)b, (const char *)a); } + +/* ready-made metric functions */ +#define SIMCLIST_METER(type) size_t list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); } + +SIMCLIST_METER(int8_t) +SIMCLIST_METER(int16_t) +SIMCLIST_METER(int32_t) +SIMCLIST_METER(int64_t) + +SIMCLIST_METER(uint8_t) +SIMCLIST_METER(uint16_t) +SIMCLIST_METER(uint32_t) +SIMCLIST_METER(uint64_t) + +SIMCLIST_METER(float) +SIMCLIST_METER(double) + +size_t list_meter_string(const void *el) { return strlen((const char *)el) + 1; } + +/* ready-made hashing functions */ +#define SIMCLIST_HASHCOMPUTER(type) list_hash_t list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); } + +SIMCLIST_HASHCOMPUTER(int8_t) +SIMCLIST_HASHCOMPUTER(int16_t) +SIMCLIST_HASHCOMPUTER(int32_t) +SIMCLIST_HASHCOMPUTER(int64_t) + +SIMCLIST_HASHCOMPUTER(uint8_t) +SIMCLIST_HASHCOMPUTER(uint16_t) +SIMCLIST_HASHCOMPUTER(uint32_t) +SIMCLIST_HASHCOMPUTER(uint64_t) + +SIMCLIST_HASHCOMPUTER(float) +SIMCLIST_HASHCOMPUTER(double) + +list_hash_t list_hashcomputer_string(const void *el) { + size_t l; + list_hash_t hash = 123; + const char *str = (const char *)el; + char plus; + + for (l = 0; str[l] != '\0'; l++) { + if (l) plus = hash ^ str[l]; + else plus = hash ^ (str[l] - str[0]); + hash += (plus << (CHAR_BIT * (l % sizeof(list_hash_t)))); + } + + return hash; +} + + +#ifndef NDEBUG +static int list_repOk(const list_t *restrict l) { + int ok, i; + struct list_entry_s *s; + + ok = (l != NULL) && ( + /* head/tail checks */ + (l->head_sentinel != NULL && l->tail_sentinel != NULL) && + (l->head_sentinel != l->tail_sentinel) && (l->head_sentinel->prev == NULL && l->tail_sentinel->next == NULL) && + /* empty list */ + (l->numels > 0 || (l->mid == NULL && l->head_sentinel->next == l->tail_sentinel && l->tail_sentinel->prev == l->head_sentinel)) && + /* spare elements checks */ + l->spareelsnum <= SIMCLIST_MAX_SPARE_ELEMS + ); + + if (!ok) return 0; + + if (l->numels >= 1) { + /* correct referencing */ + for (i = -1, s = l->head_sentinel; i < (int)(l->numels-1)/2 && s->next != NULL; i++, s = s->next) { + if (s->next->prev != s) break; + } + ok = (i == (int)(l->numels-1)/2 && l->mid == s); + if (!ok) return 0; + for (; s->next != NULL; i++, s = s->next) { + if (s->next->prev != s) break; + } + ok = (i == (int)l->numels && s == l->tail_sentinel); + } + + return ok; +} + +static int list_attrOk(const list_t *restrict l) { + int ok; + + ok = (l->attrs.copy_data == 0 || l->attrs.meter != NULL); + return ok; +} + +#endif + diff --git a/libs/libks/src/table.c b/libs/libks/src/table.c new file mode 100644 index 0000000000..4e28556eb9 --- /dev/null +++ b/libs/libks/src/table.c @@ -0,0 +1,4079 @@ +/* + * Generic hash table handler... + * + * Copyright 2000 by Gray Watson. + * + * This file is part of the table package. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies, and that the name of Gray Watson not be used in advertising + * or publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: table.c,v 1.19 2000/03/09 03:30:41 gray Exp $ + */ + +/* + * Handles basic hash-table manipulations. This is an implementation + * of open hashing with an array of buckets holding linked lists of + * elements. Each element has a key and a data. The user indexes on + * the key to find the data. See the typedefs in table_loc.h for more + * information. + */ + +#include +#include +#include +#include + +#ifdef unix + +#include + +#else + +#include +#include +#define NO_MMAP +#define open _open + +#endif + +#ifndef NO_MMAP + +#include +#include + +#ifndef MAP_FAILED +#define MAP_FAILED (caddr_t)0L +#endif + +#endif + +#define TABLE_MAIN + +#include "table.h" +#include "table_loc.h" + +#ifdef DMALLOC +#include "dmalloc.h" +#endif + +static char *rcs_id = + "$Id: table.c,v 1.19 2000/03/09 03:30:41 gray Exp $"; + +/* + * Version id for the library. You also need to add an entry to the + * NEWS and ChangeLog files. + */ +static char *version_id = "$TableVersion: 4.3.0 March 8, 2000 $"; + +/****************************** local functions ******************************/ + +/* + * static table_entry_t *first_entry + * + * DESCRIPTION: + * + * Return the first entry in the table. It will set the linear + * structure counter to the position of the first entry. + * + * RETURNS: + * + * Success: A pointer to the first entry in the table. + * + * Failure: NULL if there is no first entry. + * + * ARGUMENTS: + * + * table_p -> Table whose next entry we are finding. + * + * linear_p <-> Pointer to a linear structure which we will advance + * and then find the corresponding entry. + */ +static table_entry_t *first_entry(const table_t *table_p, + table_linear_t *linear_p) +{ + table_entry_t *entry_p; + unsigned int bucket_c = 0; + + /* look for the first non-empty bucket */ + for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) { + entry_p = table_p->ta_buckets[bucket_c]; + if (entry_p != NULL) { + if (linear_p != NULL) { + linear_p->tl_bucket_c = bucket_c; + linear_p->tl_entry_c = 0; + } + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } + } + + return NULL; +} + +/* + * static table_entry_t *next_entry + * + * DESCRIPTION: + * + * Return the next entry in the table which is past the position in + * our linear pointer. It will advance the linear structure counters. + * + * RETURNS: + * + * Success: A pointer to the next entry in the table. + * + * Failure: NULL. + * + * ARGUMENTS: + * + * table_p -> Table whose next entry we are finding. + * + * linear_p <-> Pointer to a linear structure which we will advance + * and then find the corresponding entry. + * + * error_p <- Pointer to an integer which when the routine returns + * will contain a table error code. + */ +static table_entry_t *next_entry(const table_t *table_p, + table_linear_t *linear_p, int *error_p) +{ + table_entry_t *entry_p; + int entry_c; + + /* can't next if we haven't first-ed */ + if (linear_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_LINEAR); + return NULL; + } + + if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } + + linear_p->tl_entry_c++; + + /* find the entry which is the nth in the list */ + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + /* NOTE: we swap the order here to be more efficient */ + for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) { + /* did we reach the end of the list? */ + if (entry_p == NULL) { + break; + } + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; + } + + /* did we find an entry in the current bucket? */ + if (entry_p != NULL) { + SET_POINTER(error_p, TABLE_ERROR_NONE); + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } + + /* find the first entry in the next non-empty bucket */ + + linear_p->tl_entry_c = 0; + for (linear_p->tl_bucket_c++; linear_p->tl_bucket_c < table_p->ta_bucket_n; + linear_p->tl_bucket_c++) { + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + if (entry_p != NULL) { + SET_POINTER(error_p, TABLE_ERROR_NONE); + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } + } + + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; +} + +/* + * static table_entry_t *this_entry + * + * DESCRIPTION: + * + * Return the entry pointer in the table which is currently being + * indicated by our linear pointer. + * + * RETURNS: + * + * Success: A pointer to the next entry in the table. + * + * Failure: NULL. + * + * ARGUMENTS: + * + * table_p -> Table whose next entry we are finding. + * + * linear_p -> Pointer to a linear structure which we will find the + * corresponding entry. + * + * error_p <- Pointer to an integer which when the routine returns + * will contain a table error code. + */ +static table_entry_t *this_entry(const table_t *table_p, + const table_linear_t *linear_p, + int *error_p) +{ + table_entry_t *entry_p; + int entry_c; + + /* can't next if we haven't first-ed */ + if (linear_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_LINEAR); + return NULL; + } + + if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } + + /* find the entry which is the nth in the list */ + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + + /* NOTE: we swap the order here to be more efficient */ + for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) { + /* did we reach the end of the list? */ + if (entry_p == NULL) { + break; + } + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; + } + + /* did we find an entry in the current bucket? */ + if (entry_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } + else { + SET_POINTER(error_p, TABLE_ERROR_NONE); + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } +} + +/* + * static unsigned int hash + * + * DESCRIPTION: + * + * Hash a variable-length key into a 32-bit value. Every bit of the + * key affects every bit of the return value. Every 1-bit and 2-bit + * delta achieves avalanche. About (6 * len + 35) instructions. The + * best hash table sizes are powers of 2. There is no need to use mod + * (sooo slow!). If you need less than 32 bits, use a bitmask. For + * example, if you need only 10 bits, do h = (h & hashmask(10)); In + * which case, the hash table should have hashsize(10) elements. + * + * By Bob Jenkins, 1996. bob_jenkins@compuserve.com. You may use + * this code any way you wish, private, educational, or commercial. + * It's free. See + * http://ourworld.compuserve.com/homepages/bob_jenkins/evahash.htm + * Use for hash table lookup, or anything where one collision in 2^^32 + * is acceptable. Do NOT use for cryptographic purposes. + * + * RETURNS: + * + * Returns a 32-bit hash value. + * + * ARGUMENTS: + * + * key - Key (the unaligned variable-length array of bytes) that we + * are hashing. + * + * length - Length of the key in bytes. + * + * init_val - Initialization value of the hash if you need to hash a + * number of strings together. For instance, if you are hashing N + * strings (unsigned char **)keys, do it like this: + * + * for (i=0, h=0; i= 12; len -= 12) { + a += (key_p[0] + + ((unsigned int)key_p[1] << 8) + + ((unsigned int)key_p[2] << 16) + + ((unsigned int)key_p[3] << 24)); + b += (key_p[4] + + ((unsigned int)key_p[5] << 8) + + ((unsigned int)key_p[6] << 16) + + ((unsigned int)key_p[7] << 24)); + c += (key_p[8] + + ((unsigned int)key_p[9] << 8) + + ((unsigned int)key_p[10] << 16) + + ((unsigned int)key_p[11] << 24)); + HASH_MIX(a,b,c); + key_p += 12; + } + + c += length; + + /* all the case statements fall through to the next */ + switch(len) { + case 11: + c += ((unsigned int)key_p[10] << 24); + case 10: + c += ((unsigned int)key_p[9] << 16); + case 9: + c += ((unsigned int)key_p[8] << 8); + /* the first byte of c is reserved for the length */ + case 8: + b += ((unsigned int)key_p[7] << 24); + case 7: + b += ((unsigned int)key_p[6] << 16); + case 6: + b += ((unsigned int)key_p[5] << 8); + case 5: + b += key_p[4]; + case 4: + a += ((unsigned int)key_p[3] << 24); + case 3: + a += ((unsigned int)key_p[2] << 16); + case 2: + a += ((unsigned int)key_p[1] << 8); + case 1: + a += key_p[0]; + /* case 0: nothing left to add */ + } + HASH_MIX(a, b, c); + + return c; +} + +/* + * static int entry_size + * + * DESCRIPTION: + * + * Calculates the appropriate size of an entry to include the key and + * data sizes as well as any associated alignment to the data. + * + * RETURNS: + * + * The associated size of the entry. + * + * ARGUMENTS: + * + * table_p - Table associated with the entries whose size we are + * determining. + * + * key_size - Size of the entry key. + * + * data - Size of the entry data. + */ +static int entry_size(const table_t *table_p, const unsigned int key_size, + const unsigned int data_size) +{ + int size, left; + + /* initial size -- key is already aligned if right after struct */ + size = sizeof(struct table_shell_st) + key_size; + + /* if there is no alignment then it is easy */ + if (table_p->ta_data_align == 0) { + return size + data_size; + } + + /* add in our alignement */ + left = size & (table_p->ta_data_align - 1); + if (left > 0) { + size += table_p->ta_data_align - left; + } + + /* we add the data size here after the alignment */ + size += data_size; + + return size; +} + +/* + * static unsigned char *entry_data_buf + * + * DESCRIPTION: + * + * Companion to the ENTRY_DATA_BUF macro but this handles any + * associated alignment to the data in the entry. + * + * NOTE: we assume here that the data-alignment is > 0. + * + * RETURNS: + * + * Pointer to the data segment of the entry. + * + * ARGUMENTS: + * + * table_p - Table associated with the entry. + * + * entry_p - Entry whose data pointer we are determining. + */ +static unsigned char *entry_data_buf(const table_t *table_p, + const table_entry_t *entry_p) +{ + const unsigned char *buf_p; + unsigned int size, pad; + + buf_p = entry_p->te_key_buf + entry_p->te_key_size; + + /* we need the size of the space before the data */ + size = sizeof(struct table_shell_st) + entry_p->te_key_size; + + /* add in our alignment */ + pad = size & (table_p->ta_data_align - 1); + if (pad > 0) { + pad = table_p->ta_data_align - pad; + } + + return (unsigned char *)buf_p + pad; +} + +/******************************* sort routines *******************************/ + +/* + * static int local_compare + * + * DESCRIPTION: + * + * Compare two entries by calling user's compare program or by using + * memcmp. + * + * RETURNS: + * + * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2. + * + * ARGUMENTS: + * + * p1 - First entry pointer to compare. + * + * p2 - Second entry pointer to compare. + * + * compare - User comparison function. Ignored. + * + * table_p - Associated table being ordered. Ignored. + * + * err_bp - Pointer to an integer which will be set with 1 if an error + * has occurred. It cannot be NULL. + */ +static int local_compare(const void *p1, const void *p2, + table_compare_t compare, const table_t *table_p, + int *err_bp) +{ + const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; + int cmp; + unsigned int size; + + /* compare as many bytes as we can */ + size = (*ent1_p)->te_key_size; + if ((*ent2_p)->te_key_size < size) { + size = (*ent2_p)->te_key_size; + } + cmp = memcmp(ENTRY_KEY_BUF(*ent1_p), ENTRY_KEY_BUF(*ent2_p), size); + /* if common-size equal, then if next more bytes, it is larger */ + if (cmp == 0) { + cmp = (*ent1_p)->te_key_size - (*ent2_p)->te_key_size; + } + + *err_bp = 0; + return cmp; +} + +/* + * static int local_compare_pos + * + * DESCRIPTION: + * + * Compare two entries by calling user's compare program or by using + * memcmp. + * + * RETURNS: + * + * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2. + * + * ARGUMENTS: + * + * p1 - First entry pointer to compare. + * + * p2 - Second entry pointer to compare. + * + * compare - User comparison function. Ignored. + * + * table_p - Associated table being ordered. + * + * err_bp - Pointer to an integer which will be set with 1 if an error + * has occurred. It cannot be NULL. + */ +static int local_compare_pos(const void *p1, const void *p2, + table_compare_t compare, + const table_t *table_p, int *err_bp) +{ + const table_linear_t *lin1_p = p1, *lin2_p = p2; + const table_entry_t *ent1_p, *ent2_p; + int cmp, ret; + unsigned int size; + + /* get entry pointers */ + ent1_p = this_entry(table_p, lin1_p, &ret); + ent2_p = this_entry(table_p, lin2_p, &ret); + if (ent1_p == NULL || ent2_p == NULL) { + *err_bp = 1; + return 0; + } + + /* compare as many bytes as we can */ + size = ent1_p->te_key_size; + if (ent2_p->te_key_size < size) { + size = ent2_p->te_key_size; + } + cmp = memcmp(ENTRY_KEY_BUF(ent1_p), ENTRY_KEY_BUF(ent2_p), size); + /* if common-size equal, then if next more bytes, it is larger */ + if (cmp == 0) { + cmp = ent1_p->te_key_size - ent2_p->te_key_size; + } + + *err_bp = 0; + return cmp; +} + +/* + * static int external_compare + * + * DESCRIPTION: + * + * Compare two entries by calling user's compare program or by using + * memcmp. + * + * RETURNS: + * + * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2. + * + * ARGUMENTS: + * + * p1 - First entry pointer to compare. + * + * p2 - Second entry pointer to compare. + * + * user_compare - User comparison function. + * + * table_p - Associated table being ordered. + * + * err_bp - Pointer to an integer which will be set with 1 if an error + * has occurred. It cannot be NULL. + */ +static int external_compare(const void *p1, const void *p2, + table_compare_t user_compare, + const table_t *table_p, int *err_bp) +{ + const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; + /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size, + ENTRY_DATA_BUF(table_p, *ent1_p), + (*ent1_p)->te_data_size, + ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size, + ENTRY_DATA_BUF(table_p, *ent2_p), + (*ent2_p)->te_data_size); +} + +/* + * static int external_compare_pos + * + * DESCRIPTION: + * + * Compare two entries by calling user's compare program or by using + * memcmp. + * + * RETURNS: + * + * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2. + * + * ARGUMENTS: + * + * p1 - First entry pointer to compare. + * + * p2 - Second entry pointer to compare. + * + * user_compare - User comparison function. + * + * table_p - Associated table being ordered. + * + * err_bp - Pointer to an integer which will be set with 1 if an error + * has occurred. It cannot be NULL. +*/ +static int external_compare_pos(const void *p1, const void *p2, + table_compare_t user_compare, + const table_t *table_p, int *err_bp) +{ + const table_linear_t *lin1_p = p1, *lin2_p = p2; + const table_entry_t *ent1_p, *ent2_p; + int ret; + + /* get entry pointers */ + ent1_p = this_entry(table_p, lin1_p, &ret); + ent2_p = this_entry(table_p, lin2_p, &ret); + if (ent1_p == NULL || ent2_p == NULL) { + *err_bp = 1; + return 0; + } + + /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(ent1_p), (ent1_p)->te_key_size, + ENTRY_DATA_BUF(table_p, ent1_p), ent1_p->te_data_size, + ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size, + ENTRY_DATA_BUF(table_p, ent2_p), ent2_p->te_data_size); +} + +/* + * static int external_compare_align + * + * DESCRIPTION: + * + * Compare two entries by calling user's compare program or by using + * memcmp. Alignment information is necessary. + * + * RETURNS: + * + * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2. + * + * ARGUMENTS: + * + * p1 - First entry pointer to compare. + * + * p2 - Second entry pointer to compare. + * + * user_compare - User comparison function. + * + * table_p - Associated table being ordered. + * + * err_bp - Pointer to an integer which will be set with 1 if an error + * has occurred. It cannot be NULL. + */ +static int external_compare_align(const void *p1, const void *p2, + table_compare_t user_compare, + const table_t *table_p, int *err_bp) +{ + const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; + /* since we are aligned we have to use the entry_data_buf function */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size, + entry_data_buf(table_p, *ent1_p), + (*ent1_p)->te_data_size, + ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size, + entry_data_buf(table_p, *ent2_p), + (*ent2_p)->te_data_size); +} + +/* + * static int external_compare_align_pos + * + * DESCRIPTION: + * + * Compare two entries by calling user's compare program or by using + * memcmp. Alignment information is necessary. + * + * RETURNS: + * + * < 0, == 0, or > 0 depending on whether p1 is > p2, == p2, < p2. + * + * ARGUMENTS: + * + * p1 - First entry pointer to compare. + * + * p2 - Second entry pointer to compare. + * + * user_compare - User comparison function. + * + * table_p - Associated table being ordered. + * + * err_bp - Pointer to an integer which will be set with 1 if an error + * has occurred. It cannot be NULL. + */ +static int external_compare_align_pos(const void *p1, const void *p2, + table_compare_t user_compare, + const table_t *table_p, int *err_bp) +{ + const table_linear_t *lin1_p = p1, *lin2_p = p2; + const table_entry_t *ent1_p, *ent2_p; + int ret; + + /* get entry pointers */ + ent1_p = this_entry(table_p, lin1_p, &ret); + ent2_p = this_entry(table_p, lin2_p, &ret); + if (ent1_p == NULL || ent2_p == NULL) { + *err_bp = 1; + return 0; + } + + /* since we are aligned we have to use the entry_data_buf function */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(ent1_p), ent1_p->te_key_size, + entry_data_buf(table_p, ent1_p), ent1_p->te_data_size, + ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size, + entry_data_buf(table_p, ent2_p), ent2_p->te_data_size); +} + +/* + * static void swap_bytes + * + * DESCRIPTION: + * + * Swap the values between two items of a specified size. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * item1_p -> Pointer to the first item. + * + * item2_p -> Pointer to the first item. + * + * ele_size -> Size of the two items. + */ +static void swap_bytes(unsigned char *item1_p, unsigned char *item2_p, + int ele_size) +{ + unsigned char char_temp; + + for (; ele_size > 0; ele_size--) { + char_temp = *item1_p; + *item1_p = *item2_p; + *item2_p = char_temp; + item1_p++; + item2_p++; + } +} + +/* + * static void insert_sort + * + * DESCRIPTION: + * + * Do an insertion sort which is faster for small numbers of items and + * better if the items are already sorted. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * first_p <-> Start of the list that we are splitting. + * + * last_p <-> Last entry in the list that we are splitting. + * + * holder_p <-> Location of hold area we can store an entry. + * + * ele_size -> Size of the each element in the list. + * + * compare -> Our comparison function. + * + * user_compare -> User comparison function. Could be NULL if we are + * just using a local comparison function. + * + * table_p -> Associated table being sorted. + */ +static int insert_sort(unsigned char *first_p, unsigned char *last_p, + unsigned char *holder_p, + const unsigned int ele_size, compare_t compare, + table_compare_t user_compare, table_t *table_p) +{ + unsigned char *inner_p, *outer_p; + int ret, err_b; + + for (outer_p = first_p + ele_size; outer_p <= last_p; ) { + + /* look for the place to insert the entry */ + for (inner_p = outer_p - ele_size; + inner_p >= first_p; + inner_p -= ele_size) { + ret = compare(outer_p, inner_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret >= 0) { + break; + } + } + inner_p += ele_size; + + /* do we need to insert the entry in? */ + if (outer_p != inner_p) { + /* + * Now we shift the entry down into its place in the already + * sorted list. + */ + memcpy(holder_p, outer_p, ele_size); + memmove(inner_p + ele_size, inner_p, outer_p - inner_p); + memcpy(inner_p, holder_p, ele_size); + } + + outer_p += ele_size; + } + + return TABLE_ERROR_NONE; +} + +/* + * static int split + * + * DESCRIPTION: + * + * This sorts an array of longs via the quick sort algorithm (it's + * pretty quick) + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * first_p -> Start of the list that we are splitting. + * + * last_p -> Last entry in the list that we are splitting. + * + * ele_size -> Size of the each element in the list. + * + * compare -> Our comparison function. + * + * user_compare -> User comparison function. Could be NULL if we are + * just using a local comparison function. + * + * table_p -> Associated table being sorted. + */ +static int split(unsigned char *first_p, unsigned char *last_p, + const unsigned int ele_size, compare_t compare, + table_compare_t user_compare, table_t *table_p) +{ + unsigned char *left_p, *right_p, *pivot_p, *left_last_p, *right_first_p; + unsigned char *firsts[MAX_QSORT_SPLITS], *lasts[MAX_QSORT_SPLITS], *pivot; + unsigned int width, split_c = 0; + int size1, size2, min_qsort_size; + int ret, err_b; + + /* + * Allocate some space for our pivot value. We also use this as + * holder space for our insert sort. + */ + pivot = alloca(ele_size); + if (pivot == NULL) { + /* what else can we do? */ + abort(); + } + + min_qsort_size = MAX_QSORT_MANY * ele_size; + + while (1) { + + /* find the left, right, and mid point */ + left_p = first_p; + right_p = last_p; + /* is there a faster way to find this? */ + width = (last_p - first_p) / ele_size; + pivot_p = first_p + ele_size * (width >> 1); + + /* + * Find which of the left, middle, and right elements is the + * median (Knuth vol3 p123). + */ + ret = compare(first_p, pivot_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret > 0) { + swap_bytes(first_p, pivot_p, ele_size); + } + ret = compare(pivot_p, last_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret > 0) { + swap_bytes(pivot_p, last_p, ele_size); + ret = compare(first_p, pivot_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret > 0) { + swap_bytes(first_p, pivot_p, ele_size); + } + } + + /* + * save our pivot so we don't have to worry about hitting and + * swapping it elsewhere while we iterate across the list below. + */ + memcpy(pivot, pivot_p, ele_size); + + do { + + /* shift the left side up until we reach the pivot value */ + while (1) { + ret = compare(left_p, pivot, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret >= 0) { + break; + } + left_p += ele_size; + } + /* shift the right side down until we reach the pivot value */ + while (1) { + ret = compare(pivot, right_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret >= 0) { + break; + } + right_p -= ele_size; + } + + /* if we met in the middle then we are done */ + if (left_p == right_p) { + left_p += ele_size; + right_p -= ele_size; + break; + } + else if (left_p < right_p) { + /* + * swap the left and right since they both were on the wrong + * size of the pivot and continue + */ + swap_bytes(left_p, right_p, ele_size); + left_p += ele_size; + right_p -= ele_size; + } + } while (left_p <= right_p); + + /* Rename variables to make more sense. This will get optimized out. */ + right_first_p = left_p; + left_last_p = right_p; + + /* determine the size of the left and right hand parts */ + size1 = left_last_p - first_p; + size2 = last_p - right_first_p; + + /* is the 1st half small enough to just insert-sort? */ + if (size1 < min_qsort_size) { + + /* use the pivot as our temporary space */ + ret = insert_sort(first_p, left_last_p, pivot, ele_size, compare, + user_compare, table_p); + if (ret != TABLE_ERROR_NONE) { + return ret; + } + + /* is the 2nd part small as well? */ + if (size2 < min_qsort_size) { + + /* use the pivot as our temporary space */ + ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare, + user_compare, table_p); + if (ret != TABLE_ERROR_NONE) { + return ret; + } + + /* pop a partition off our stack */ + if (split_c == 0) { + /* we are done */ + return TABLE_ERROR_NONE; + } + split_c--; + first_p = firsts[split_c]; + last_p = lasts[split_c]; + } + else { + /* we can just handle the right side immediately */ + first_p = right_first_p; + /* last_p = last_p */ + } + } + else if (size2 < min_qsort_size) { + + /* use the pivot as our temporary space */ + ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare, + user_compare, table_p); + if (ret != TABLE_ERROR_NONE) { + return ret; + } + + /* we can just handle the left side immediately */ + /* first_p = first_p */ + last_p = left_last_p; + } + else { + /* + * neither partition is small, we'll have to push the larger one + * of them on the stack + */ + if (split_c >= MAX_QSORT_SPLITS) { + /* sanity check here -- we should never get here */ + abort(); + } + if (size1 > size2) { + /* push the left partition on the stack */ + firsts[split_c] = first_p; + lasts[split_c] = left_last_p; + split_c++; + /* continue handling the right side */ + first_p = right_first_p; + /* last_p = last_p */ + } + else { + /* push the right partition on the stack */ + firsts[split_c] = right_first_p; + lasts[split_c] = last_p; + split_c++; + /* continue handling the left side */ + /* first_p = first_p */ + last_p = left_last_p; + } + } + } + + return TABLE_ERROR_NONE; +} + +/*************************** exported routines *******************************/ + +/* + * table_t *table_alloc + * + * DESCRIPTION: + * + * Allocate a new table structure. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_free to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * bucket_n - Number of buckets for the hash table. Our current hash + * value works best with base two numbers. Set to 0 to take the + * library default of 1024. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +table_t *table_alloc(const unsigned int bucket_n, int *error_p) +{ + table_t *table_p = NULL; + unsigned int buck_n; + + /* allocate a table structure */ + table_p = malloc(sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } + + if (bucket_n > 0) { + buck_n = bucket_n; + } + else { + buck_n = DEFAULT_SIZE; + } + + /* allocate the buckets which are NULLed */ + table_p->ta_buckets = (table_entry_t **)calloc(buck_n, + sizeof(table_entry_t *)); + if (table_p->ta_buckets == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + free(table_p); + return NULL; + } + + /* initialize structure */ + table_p->ta_magic = TABLE_MAGIC; + table_p->ta_flags = 0; + table_p->ta_bucket_n = buck_n; + table_p->ta_entry_n = 0; + table_p->ta_data_align = 0; + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; + table_p->ta_mmap = NULL; + table_p->ta_file_size = 0; + table_p->ta_mem_pool = NULL; + table_p->ta_alloc_func = NULL; + table_p->ta_resize_func = NULL; + table_p->ta_free_func = NULL; + + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; +} + +/* + * table_t *table_alloc_in_pool + * + * DESCRIPTION: + * + * Allocate a new table structure in a memory pool or using + * alternative allocation and free functions. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_free to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * bucket_n - Number of buckets for the hash table. Our current hash + * value works best with base two numbers. Set to 0 to take the + * library default of 1024. + * + * mem_pool <-> Memory pool to associate with the table. Can be NULL. + * + * alloc_func -> Allocate function we are overriding malloc() with. + * + * resize_func -> Resize function we are overriding the standard + * memory resize/realloc with. This can be NULL in which cause the + * library will allocate, copy, and free itself. + * + * free_func -> Free function we are overriding free() with. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +table_t *table_alloc_in_pool(const unsigned int bucket_n, + void *mem_pool, + table_mem_alloc_t alloc_func, + table_mem_resize_t resize_func, + table_mem_free_t free_func, int *error_p) +{ + table_t *table_p = NULL; + unsigned int buck_n, size; + + /* make sure we have real functions, mem_pool and resize_func can be NULL */ + if (alloc_func == NULL || free_func == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); + return NULL; + } + + /* allocate a table structure */ + table_p = alloc_func(mem_pool, sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } + + if (bucket_n > 0) { + buck_n = bucket_n; + } + else { + buck_n = DEFAULT_SIZE; + } + + /* allocate the buckets which are NULLed */ + size = buck_n * sizeof(table_entry_t *); + table_p->ta_buckets = (table_entry_t **)alloc_func(mem_pool, size); + if (table_p->ta_buckets == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + (void)free_func(mem_pool, table_p, sizeof(table_t)); + return NULL; + } + /* + * We zero it ourselves to save the necessity of having a + * table_mem_calloc_t memory override function. + */ + memset(table_p->ta_buckets, 0, size); + + /* initialize structure */ + table_p->ta_magic = TABLE_MAGIC; + table_p->ta_flags = 0; + table_p->ta_bucket_n = buck_n; + table_p->ta_entry_n = 0; + table_p->ta_data_align = 0; + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; + table_p->ta_mmap = NULL; + table_p->ta_file_size = 0; + table_p->ta_mem_pool = mem_pool; + table_p->ta_alloc_func = alloc_func; + table_p->ta_resize_func = resize_func; + table_p->ta_free_func = free_func; + + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; +} + +/* + * int table_attr + * + * DESCRIPTION: + * + * Set the attributes for the table. The available attributes are + * specified at the top of table.h. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to a table structure which we will be altering. + * + * attr - Attribute(s) that we will be applying to the table. + */ +int table_attr(table_t *table_p, const int attr) +{ + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + + table_p->ta_flags = attr; + + return TABLE_ERROR_NONE; +} + +/* + * int table_set_data_alignment + * + * DESCRIPTION: + * + * Set the alignment for the data in the table. This is used when you + * want to store binary data types and refer to them directly out of + * the table storage. For instance if you are storing integers as + * data in the table and want to be able to retrieve the location of + * the interger and then increment it as (*loc_p)++. Otherwise you + * would have to memcpy it out to an integer, increment it, and memcpy + * it back. If you are storing character data, no alignment is + * necessary. + * + * For most data elements, sizeof(long) is recommended unless you use + * smaller data types exclusively. + * + * WARNING: If necessary, you must set the data alignment before any + * data gets put into the table. Otherwise a TABLE_ERROR_NOT_EMPTY + * error will be returned. + * + * NOTE: there is no way to set the key data alignment although it + * should automatically be long aligned. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to a table structure which we will be altering. + * + * alignment - Alignment requested for the data. Must be a power of + * 2. Set to 0 for none. + */ +int table_set_data_alignment(table_t *table_p, const int alignment) +{ + int val; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_entry_n > 0) { + return TABLE_ERROR_NOT_EMPTY; + } + + /* defaults */ + if (alignment < 2) { + table_p->ta_data_align = 0; + } + else { + /* verify we have a base 2 number */ + for (val = 2; val < MAX_ALIGNMENT; val *= 2) { + if (val == alignment) { + break; + } + } + if (val >= MAX_ALIGNMENT) { + return TABLE_ERROR_ALIGNMENT; + } + table_p->ta_data_align = alignment; + } + + return TABLE_ERROR_NONE; +} + +/* + * int table_clear + * + * DESCRIPTION: + * + * Clear out and free all elements in a table structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer that we will be clearing. + */ +int table_clear(table_t *table_p) +{ + int final = TABLE_ERROR_NONE; + table_entry_t *entry_p, *next_p; + table_entry_t **bucket_p, **bounds_p; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + +#ifndef NO_MMAP + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } +#endif + + /* free the table allocation and table structure */ + bounds_p = table_p->ta_buckets + table_p->ta_bucket_n; + for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) { + for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) { + /* record the next pointer before we free */ + next_p = entry_p->te_next_p; + if (table_p->ta_free_func == NULL) { + free(entry_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + entry_size(table_p, + entry_p->te_key_size, + entry_p->te_data_size))) { + final = TABLE_ERROR_FREE; + } + } + + /* clear the bucket entry after we free its entries */ + *bucket_p = NULL; + } + + /* reset table state info */ + table_p->ta_entry_n = 0; + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; + + return final; +} + +/* + * int table_free + * + * DESCRIPTION: + * + * Deallocates a table structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer that we will be freeing. + */ +int table_free(table_t *table_p) +{ + int ret; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + +#ifndef NO_MMAP + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } +#endif + + ret = table_clear(table_p); + + if (table_p->ta_buckets != NULL) { + if (table_p->ta_free_func == NULL) { + free(table_p->ta_buckets); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, + table_p->ta_buckets, + table_p->ta_bucket_n * + sizeof(table_entry_t *))) { + return TABLE_ERROR_FREE; + } + } + table_p->ta_magic = 0; + if (table_p->ta_free_func == NULL) { + free(table_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, table_p, + sizeof(table_t))) { + if (ret == TABLE_ERROR_NONE) { + ret = TABLE_ERROR_FREE; + } + } + + return ret; +} + +/* + * int table_insert_kd + * + * DESCRIPTION: + * + * Like table_insert except it passes back a pointer to the key and + * the data buffers after they have been inserted into the table + * structure. + * + * This routine adds a key/data pair both of which are made up of a + * buffer of bytes and an associated size. Both the key and the data + * will be copied into buffers allocated inside the table. If the key + * exists already, the associated data will be replaced if the + * overwrite flag is set, otherwise an error is returned. + * + * NOTE: be very careful changing the values since the table library + * provides the pointers to its memory. The key can _never_ be + * changed otherwise you will not find it again. The data can be + * changed but its length can never be altered unless you delete and + * re-insert it into the table. + * + * WARNING: The pointers to the key and data are not in any specific + * alignment. Accessing the key and/or data as an short, integer, or + * long pointer directly can cause problems. + * + * WARNING: Replacing a data cell (not inserting) will cause the table + * linked list to be temporarily invalid. Care must be taken with + * multiple threaded programs which are relying on the first/next + * linked list to be always valid. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be inserting a + * new key/data pair. + * + * key_buf - Buffer of bytes of the key that we are inserting. If you + * are storing an (int) as the key (for example) then key_buf should + * be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are storing an (int) as the key (for example) then key_size should + * be sizeof(int). + * + * data_buf - Buffer of bytes of the data that we are inserting. If + * it is NULL then the library will allocate space for the data in the + * table without copying in any information. If data_buf is NULL and + * data_size is 0 then the library will associate a NULL data pointer + * with the key. If you are storing a (long) as the data (for + * example) then data_buf should be a (long *). + * + * data_size - Size of the data_buf buffer. If set to < 0 then the + * library will do a strlen of data_buf and add 1 for the '\0'. If + * you are storing an (long) as the key (for example) then key_size + * should be sizeof(long). + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the key storage that was allocated in the table. If you are + * storing an (int) as the key (for example) then key_buf_p should be + * (int **) i.e. the address of a (int *). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table. If you are + * storing an (long) as the data (for example) then data_buf_p should + * be (long **) i.e. the address of a (long *). + * + * overwrite - Flag which, if set to 1, will allow the overwriting of + * the data in the table with the new data if the key already exists + * in the table. + */ +int table_insert_kd(table_t *table_p, + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **key_buf_p, void **data_buf_p, + const char overwrite_b) +{ + int bucket; + unsigned int ksize, dsize, new_size, old_size, copy_size; + table_entry_t *entry_p, *last_p, *new_entry_p; + void *key_copy_p, *data_copy_p; + + /* check the arguments */ + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (key_buf == NULL) { + return TABLE_ERROR_ARG_NULL; + } + /* data_buf can be null but size must be >= 0, if it isn't null size != 0 */ + if ((data_buf == NULL && data_size < 0) + || (data_buf != NULL && data_size == 0)) { + return TABLE_ERROR_SIZE; + } + +#ifndef NO_MMAP + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } +#endif + + /* determine sizes of key and data */ + if (key_size < 0) { + ksize = strlen((char *)key_buf) + sizeof(char); + } + else { + ksize = key_size; + } + if (data_size < 0) { + dsize = strlen((char *)data_buf) + sizeof(char); + } + else { + dsize = data_size; + } + + /* get the bucket number via a hash function */ + bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; + + /* look for the entry in this bucket, only check keys of the same size */ + last_p = NULL; + for (entry_p = table_p->ta_buckets[bucket]; + entry_p != NULL; + last_p = entry_p, entry_p = entry_p->te_next_p) { + if (entry_p->te_key_size == ksize + && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { + break; + } + } + + /* did we find it? then we are in replace mode. */ + if (entry_p != NULL) { + + /* can we not overwrite existing data? */ + if (! overwrite_b) { + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + return TABLE_ERROR_OVERWRITE; + } + + /* re-alloc entry's data if the new size != the old */ + if (dsize != entry_p->te_data_size) { + + /* + * First we delete it from the list to keep the list whole. + * This properly preserves the linked list in case we have a + * thread marching through the linked list while we are + * inserting. Maybe this is an unnecessary protection but it + * should not harm that much. + */ + if (last_p == NULL) { + table_p->ta_buckets[bucket] = entry_p->te_next_p; + } + else { + last_p->te_next_p = entry_p->te_next_p; + } + + /* + * Realloc the structure which may change its pointer. NOTE: + * this may change any previous data_key_p and data_copy_p + * pointers. + */ + new_size = entry_size(table_p, entry_p->te_key_size, dsize); + if (table_p->ta_resize_func == NULL) { + /* if the alloc function has not been overriden do realloc */ + if (table_p->ta_alloc_func == NULL) { + entry_p = (table_entry_t *)realloc(entry_p, new_size); + if (entry_p == NULL) { + return TABLE_ERROR_ALLOC; + } + } + else { + old_size = new_size - dsize + entry_p->te_data_size; + /* + * if the user did override alloc but not resize, assume + * that the user's allocation functions can't grok realloc + * and do it ourselves the hard way. + */ + new_entry_p = + (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, + new_size); + if (new_entry_p == NULL) { + return TABLE_ERROR_ALLOC; + } + if (new_size > old_size) { + copy_size = old_size; + } + else { + copy_size = new_size; + } + memcpy(new_entry_p, entry_p, copy_size); + if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + old_size)) { + return TABLE_ERROR_FREE; + } + entry_p = new_entry_p; + } + } + else { + old_size = new_size - dsize + entry_p->te_data_size; + entry_p = (table_entry_t *) + table_p->ta_resize_func(table_p->ta_mem_pool, entry_p, + old_size, new_size); + if (entry_p == NULL) { + return TABLE_ERROR_ALLOC; + } + } + + /* add it back to the front of the list */ + entry_p->te_data_size = dsize; + entry_p->te_next_p = table_p->ta_buckets[bucket]; + table_p->ta_buckets[bucket] = entry_p; + } + + /* copy or replace data in storage */ + if (dsize > 0) { + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + if (data_buf != NULL) { + memcpy(data_copy_p, data_buf, dsize); + } + } + else { + data_copy_p = NULL; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(data_buf_p, data_copy_p); + + /* returning from the section where we were overwriting table data */ + return TABLE_ERROR_NONE; + } + + /* + * It is a new entry. + */ + + /* allocate a new entry */ + new_size = entry_size(table_p, ksize, dsize); + if (table_p->ta_alloc_func == NULL) { + entry_p = (table_entry_t *)malloc(new_size); + } + else { + entry_p = + (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, new_size); + } + if (entry_p == NULL) { + return TABLE_ERROR_ALLOC; + } + + /* copy key into storage */ + entry_p->te_key_size = ksize; + key_copy_p = ENTRY_KEY_BUF(entry_p); + memcpy(key_copy_p, key_buf, ksize); + + /* copy data in */ + entry_p->te_data_size = dsize; + if (dsize > 0) { + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + if (data_buf != NULL) { + memcpy(data_copy_p, data_buf, dsize); + } + } + else { + data_copy_p = NULL; + } + + SET_POINTER(key_buf_p, key_copy_p); + SET_POINTER(data_buf_p, data_copy_p); + + /* insert into list, no need to append */ + entry_p->te_next_p = table_p->ta_buckets[bucket]; + table_p->ta_buckets[bucket] = entry_p; + + table_p->ta_entry_n++; + + /* do we need auto-adjust? */ + if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) + && SHOULD_TABLE_GROW(table_p)) { + return table_adjust(table_p, table_p->ta_entry_n); + } + + return TABLE_ERROR_NONE; +} + +/* + * int table_insert + * + * DESCRIPTION: + * + * Exactly the same as table_insert_kd except it does not pass back a + * pointer to the key after they have been inserted into the table + * structure. This is still here for backwards compatibility. + * + * See table_insert_kd for more information. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be inserting a + * new key/data pair. + * + * key_buf - Buffer of bytes of the key that we are inserting. If you + * are storing an (int) as the key (for example) then key_buf should + * be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are storing an (int) as the key (for example) then key_size should + * be sizeof(int). + * + * data_buf - Buffer of bytes of the data that we are inserting. If + * it is NULL then the library will allocate space for the data in the + * table without copying in any information. If data_buf is NULL and + * data_size is 0 then the library will associate a NULL data pointer + * with the key. If you are storing a (long) as the data (for + * example) then data_buf should be a (long *). + * + * data_size - Size of the data_buf buffer. If set to < 0 then the + * library will do a strlen of data_buf and add 1 for the '\0'. If + * you are storing an (long) as the key (for example) then key_size + * should be sizeof(long). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table. If you are + * storing an (long) as the data (for example) then data_buf_p should + * be (long **) i.e. the address of a (long *). + * + * overwrite - Flag which, if set to 1, will allow the overwriting of + * the data in the table with the new data if the key already exists + * in the table. + */ +int table_insert(table_t *table_p, + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **data_buf_p, const char overwrite_b) +{ + return table_insert_kd(table_p, key_buf, key_size, data_buf, data_size, + NULL, data_buf_p, overwrite_b); +} + +/* + * int table_retrieve + * + * DESCRIPTION: + * + * This routine looks up a key made up of a buffer of bytes and an + * associated size in the table. If found then it returns the + * associated data information. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be searching + * for the key. + * + * key_buf - Buffer of bytes of the key that we are searching for. If + * you are looking for an (int) as the key (for example) then key_buf + * should be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are looking for an (int) as the key (for example) then key_size + * should be sizeof(int). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that is + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data stored in the table that is associated with + * the key. + */ +int table_retrieve(table_t *table_p, + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p) +{ + int bucket; + unsigned int ksize; + table_entry_t *entry_p, **buckets; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (key_buf == NULL) { + return TABLE_ERROR_ARG_NULL; + } + + /* find key size */ + if (key_size < 0) { + ksize = strlen((char *)key_buf) + sizeof(char); + } + else { + ksize = key_size; + } + + /* get the bucket number via a has function */ + bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; + + /* look for the entry in this bucket, only check keys of the same size */ + buckets = table_p->ta_buckets; + for (entry_p = buckets[bucket]; + entry_p != NULL; + entry_p = entry_p->te_next_p) { + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p); + if (entry_p->te_key_size == ksize + && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { + break; + } + } + + /* not found? */ + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } + + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/* + * int table_delete + * + * DESCRIPTION: + * + * This routine looks up a key made up of a buffer of bytes and an + * associated size in the table. If found then it will be removed + * from the table. The associated data can be passed back to the user + * if requested. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * NOTE: this could be an allocation error if the library is to return + * the data to the user. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we will be deleteing + * the key. + * + * key_buf - Buffer of bytes of the key that we are searching for to + * delete. If you are deleting an (int) key (for example) then + * key_buf should be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are deleting an (int) key (for example) then key_size should be + * sizeof(int). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that was + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). If a pointer is passed in, the caller is responsible for + * freeing it after use. If data_buf_p is NULL then the library will + * free up the data allocation itself. + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that was stored in the table and that was + * associated with the key. + */ +int table_delete(table_t *table_p, + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p) +{ + int bucket; + unsigned int ksize; + unsigned char *data_copy_p; + table_entry_t *entry_p, *last_p; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (key_buf == NULL) { + return TABLE_ERROR_ARG_NULL; + } + +#ifndef NO_MMAP + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } +#endif + + /* get the key size */ + if (key_size < 0) { + ksize = strlen((char *)key_buf) + sizeof(char); + } + else { + ksize = key_size; + } + + /* find our bucket */ + bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; + + /* look for the entry in this bucket, only check keys of the same size */ + for (last_p = NULL, entry_p = table_p->ta_buckets[bucket]; + entry_p != NULL; + last_p = entry_p, entry_p = entry_p->te_next_p) { + if (entry_p->te_key_size == ksize + && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { + break; + } + } + + /* did we find it? */ + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } + + /* + * NOTE: we may want to adjust the linear counters here if the entry + * we are deleting is the one we are pointing on or is ahead of the + * one in the bucket list + */ + + /* remove entry from the linked list */ + if (last_p == NULL) { + table_p->ta_buckets[bucket] = entry_p->te_next_p; + } + else { + last_p->te_next_p = entry_p->te_next_p; + } + + /* free entry */ + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + /* + * if we were storing it compacted, we now need to malloc some + * space if the user wants the value after the delete. + */ + if (table_p->ta_alloc_func == NULL) { + *data_buf_p = malloc(entry_p->te_data_size); + } + else { + *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, + entry_p->te_data_size); + } + if (*data_buf_p == NULL) { + return TABLE_ERROR_ALLOC; + } + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size); + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + if (table_p->ta_free_func == NULL) { + free(entry_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + entry_size(table_p, + entry_p->te_key_size, + entry_p->te_data_size))) { + return TABLE_ERROR_FREE; + } + + table_p->ta_entry_n--; + + /* do we need auto-adjust down? */ + if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) + && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN) + && SHOULD_TABLE_SHRINK(table_p)) { + return table_adjust(table_p, table_p->ta_entry_n); + } + + return TABLE_ERROR_NONE; +} + +/* + * int table_delete_first + * + * DESCRIPTION: + * + * This is like the table_delete routines except it deletes the first + * key/data pair in the table instead of an entry corresponding to a + * particular key. The associated key and data information can be + * passed back to the user if requested. This routines is handy to + * clear out a table. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * NOTE: this could be an allocation error if the library is to return + * the data to the user. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we will be deleteing + * the first key. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that was allocated in the table. + * If an (int) was stored as the first key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). If a + * pointer is passed in, the caller is responsible for freeing it + * after use. If key_buf_p is NULL then the library will free up the + * key allocation itself. + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that was stored in the table and that was + * associated with the key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that was + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). If a pointer is passed in, the caller is responsible for + * freeing it after use. If data_buf_p is NULL then the library will + * free up the data allocation itself. + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that was stored in the table and that was + * associated with the key. + */ +int table_delete_first(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + unsigned char *data_copy_p; + table_entry_t *entry_p; + table_linear_t linear; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + +#ifndef NO_MMAP + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } +#endif + + /* take the first entry */ + entry_p = first_entry(table_p, &linear); + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } + + /* + * NOTE: we may want to adjust the linear counters here if the entry + * we are deleting is the one we are pointing on or is ahead of the + * one in the bucket list + */ + + /* remove entry from the linked list */ + table_p->ta_buckets[linear.tl_bucket_c] = entry_p->te_next_p; + + /* free entry */ + if (key_buf_p != NULL) { + if (entry_p->te_key_size == 0) { + *key_buf_p = NULL; + } + else { + /* + * if we were storing it compacted, we now need to malloc some + * space if the user wants the value after the delete. + */ + if (table_p->ta_alloc_func == NULL) { + *key_buf_p = malloc(entry_p->te_key_size); + } + else { + *key_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, + entry_p->te_key_size); + } + if (*key_buf_p == NULL) { + return TABLE_ERROR_ALLOC; + } + memcpy(*key_buf_p, ENTRY_KEY_BUF(entry_p), entry_p->te_key_size); + } + } + SET_POINTER(key_size_p, entry_p->te_key_size); + + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + /* + * if we were storing it compacted, we now need to malloc some + * space if the user wants the value after the delete. + */ + if (table_p->ta_alloc_func == NULL) { + *data_buf_p = malloc(entry_p->te_data_size); + } + else { + *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, + entry_p->te_data_size); + } + if (*data_buf_p == NULL) { + return TABLE_ERROR_ALLOC; + } + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size); + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + if (table_p->ta_free_func == NULL) { + free(entry_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + entry_size(table_p, + entry_p->te_key_size, + entry_p->te_data_size))) { + return TABLE_ERROR_FREE; + } + + table_p->ta_entry_n--; + + /* do we need auto-adjust down? */ + if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) + && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN) + && SHOULD_TABLE_SHRINK(table_p)) { + return table_adjust(table_p, table_p->ta_entry_n); + } + + return TABLE_ERROR_NONE; +} + +/* + * int table_info + * + * DESCRIPTION: + * + * Get some information about a table_p structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting + * information. + * + * num_buckets_p - Pointer to an integer which, if not NULL, will + * contain the number of buckets in the table. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries stored in the table. + */ +int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p) +{ + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + + SET_POINTER(num_buckets_p, table_p->ta_bucket_n); + SET_POINTER(num_entries_p, table_p->ta_entry_n); + + return TABLE_ERROR_NONE; +} + +/* + * int table_adjust + * + * DESCRIPTION: + * + * Set the number of buckets in a table to a certain value. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer of which we are adjusting. + * + * bucket_n - Number buckets to adjust the table to. Set to 0 to + * adjust the table to its number of entries. + */ +int table_adjust(table_t *table_p, const int bucket_n) +{ + table_entry_t *entry_p, *next_p; + table_entry_t **buckets, **bucket_p, **bounds_p; + int bucket; + unsigned int buck_n, bucket_size; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + +#ifndef NO_MMAP + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } +#endif + + /* + * NOTE: we walk through the entries and rehash them. If we stored + * the hash value as a full int in the table-entry, all we would + * have to do is remod it. + */ + + /* normalize to the number of entries */ + if (bucket_n == 0) { + buck_n = table_p->ta_entry_n; + } + else { + buck_n = bucket_n; + } + + /* we must have at least 1 bucket */ + if (buck_n == 0) { + buck_n = 1; + } + + (void)printf("growing table to %d\n", buck_n); + + /* make sure we have something to do */ + if (buck_n == table_p->ta_bucket_n) { + return TABLE_ERROR_NONE; + } + + /* allocate a new bucket list */ + bucket_size = buck_n * sizeof(table_entry_t *); + if (table_p->ta_alloc_func == NULL) { + buckets = (table_entry_t **)malloc(bucket_size); + } + else { + buckets = + (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, + bucket_size); + } + if (buckets == NULL) { + return TABLE_ERROR_ALLOC; + } + /* + * We zero it ourselves to save the necessity of having a + * table_mem_calloc_t memory override function. + */ + memset(buckets, 0, bucket_size); + + /* + * run through each of the items in the current table and rehash + * them into the newest bucket sizes + */ + bounds_p = table_p->ta_buckets + table_p->ta_bucket_n; + for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) { + for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) { + + /* hash the old data into the new table size */ + bucket = hash(ENTRY_KEY_BUF(entry_p), entry_p->te_key_size, 0) % buck_n; + + /* record the next one now since we overwrite next below */ + next_p = entry_p->te_next_p; + + /* insert into new list, no need to append */ + entry_p->te_next_p = buckets[bucket]; + buckets[bucket] = entry_p; + + /* + * NOTE: we may want to adjust the bucket_c linear entry here to + * keep it current + */ + } + /* remove the old table pointers as we go by */ + *bucket_p = NULL; + } + + /* replace the table buckets with the new ones */ + if (table_p->ta_free_func == NULL) { + free(table_p->ta_buckets); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, + table_p->ta_buckets, + table_p->ta_bucket_n * + sizeof(table_entry_t *))) { + return TABLE_ERROR_FREE; + } + table_p->ta_buckets = buckets; + table_p->ta_bucket_n = buck_n; + + return TABLE_ERROR_NONE; +} + +/* + * int table_type_size + * + * DESCRIPTION: + * + * Return the size of the internal table type. + * + * RETURNS: + * + * The size of the table_t type. + * + * ARGUMENTS: + * + * None. + */ +int table_type_size(void) +{ + return sizeof(table_t); +} + +/************************* linear access routines ****************************/ + +/* + * int table_first + * + * DESCRIPTION: + * + * Find first element in a table and pass back information about the + * key/data pair. If any of the key/data pointers are NULL then they + * are ignored. + * + * NOTE: This function is not reentrant. More than one thread cannot + * be doing a first and next on the same table at the same time. Use + * the table_first_r version below for this. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * first element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that is allocated in the table. If + * an (int) is stored as the first key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the first key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the first key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the first key. + */ +int table_first(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + table_entry_t *entry_p; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + + /* initialize our linear magic number */ + table_p->ta_linear.tl_magic = LINEAR_MAGIC; + + entry_p = first_entry(table_p, &table_p->ta_linear); + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/* + * int table_next + * + * DESCRIPTION: + * + * Find the next element in a table and pass back information about + * the key/data pair. If any of the key/data pointers are NULL then + * they are ignored. + * + * NOTE: This function is not reentrant. More than one thread cannot + * be doing a first and next on the same table at the same time. Use + * the table_next_r version below for this. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * next element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the next key that is allocated in the table. If + * an (int) is stored as the next key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the next key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the next key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the next key. + */ +int table_next(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + table_entry_t *entry_p; + int error; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } + + /* move to the next entry */ + entry_p = next_entry(table_p, &table_p->ta_linear, &error); + if (entry_p == NULL) { + return error; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/* + * int table_this + * + * DESCRIPTION: + * + * Find the current element in a table and pass back information about + * the key/data pair. If any of the key/data pointers are NULL then + * they are ignored. + * + * NOTE: This function is not reentrant. Use the table_current_r + * version below. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * current element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the current key that is allocated in the table. + * If an (int) is stored as the current key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the current key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the current key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the current key. + */ +int table_this(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + table_entry_t *entry_p = NULL; + int entry_c; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } + + /* if we removed an item that shorted the bucket list, we may get this */ + if (table_p->ta_linear.tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + return TABLE_ERROR_NOT_FOUND; + } + + /* find the entry which is the nth in the list */ + entry_p = table_p->ta_buckets[table_p->ta_linear.tl_bucket_c]; + /* NOTE: we swap the order here to be more efficient */ + for (entry_c = table_p->ta_linear.tl_entry_c; entry_c > 0; entry_c--) { + /* did we reach the end of the list? */ + if (entry_p == NULL) { + break; + } + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; + } + + /* is this a NOT_FOUND or a LINEAR error */ + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/* + * int table_first_r + * + * DESCRIPTION: + * + * Reetrant version of the table_first routine above. Find first + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * first element. + * + * linear_p - Pointer to a table linear structure which is initialized + * here. The same pointer should then be passed to table_next_r + * below. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that is allocated in the table. If + * an (int) is stored as the first key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the first key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the first key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the first key. + */ +int table_first_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + table_entry_t *entry_p; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + + /* initialize our linear magic number */ + linear_p->tl_magic = LINEAR_MAGIC; + + entry_p = first_entry(table_p, linear_p); + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/* + * int table_next_r + * + * DESCRIPTION: + * + * Reetrant version of the table_next routine above. Find next + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * next element. + * + * linear_p - Pointer to a table linear structure which is incremented + * here. The same pointer must have been passed to table_first_r + * first so that it can be initialized. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the next key that is allocated in the table. If + * an (int) is stored as the next key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL will be set + * to the size of the key that is stored in the table and that is + * associated with the next key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the next key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the next key. + */ +int table_next_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + table_entry_t *entry_p; + int error; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (linear_p->tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } + + /* move to the next entry */ + entry_p = next_entry(table_p, linear_p, &error); + if (entry_p == NULL) { + return error; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/* + * int table_this_r + * + * DESCRIPTION: + * + * Reetrant version of the table_this routine above. Find current + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * current element. + * + * linear_p - Pointer to a table linear structure which is accessed + * here. The same pointer must have been passed to table_first_r + * first so that it can be initialized. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the current key that is allocated in the table. + * If an (int) is stored as the current key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the current key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the current key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the current key. + */ +int table_this_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + table_entry_t *entry_p; + int entry_c; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p->tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } + + /* if we removed an item that shorted the bucket list, we may get this */ + if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + return TABLE_ERROR_NOT_FOUND; + } + + /* find the entry which is the nth in the list */ + for (entry_c = linear_p->tl_entry_c, + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + entry_p != NULL && entry_c > 0; + entry_c--, entry_p = TABLE_POINTER(table_p, table_entry_t *, + entry_p)->te_next_p) { + } + + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/******************************* mmap routines *******************************/ + +/* + * table_t *table_mmap + * + * DESCRIPTION: + * + * Mmap a table from a file that had been written to disk earlier via + * table_write. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_munmap to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * path - Table file to mmap in. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +table_t *table_mmap(const char *path, int *error_p) +{ +#ifdef NO_MMAP + + /* no mmap support so immediate error */ + SET_POINTER(error_p, TABLE_ERROR_MMAP_NONE); + return NULL; + +#else + + table_t *table_p; + struct stat sbuf; + int fd, state; + + table_p = (table_t *)malloc(sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } + + /* open the mmap file */ + fd = open(path, O_RDONLY, 0); + if (fd < 0) { + free(table_p); + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; + } + + /* get the file size */ + if (fstat(fd, &sbuf) != 0) { + free(table_p); + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; + } + + /* mmap the space and close the file */ +#ifdef __alpha + state = (MAP_SHARED | MAP_FILE | MAP_VARIABLE); +#else + state = MAP_SHARED; +#endif + + table_p->ta_mmap = (table_t *)mmap((caddr_t)0, sbuf.st_size, PROT_READ, + state, fd, 0); + (void)close(fd); + + if (table_p->ta_mmap == (table_t *)MAP_FAILED) { + SET_POINTER(error_p, TABLE_ERROR_MMAP); + return NULL; + } + + /* is the mmap file contain bad info or maybe another system type? */ + if (table_p->ta_mmap->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } + + /* sanity check on the file size */ + if (table_p->ta_mmap->ta_file_size != sbuf.st_size) { + SET_POINTER(error_p, TABLE_ERROR_SIZE); + return NULL; + } + + /* copy the fields out of the mmap file into our memory version */ + table_p->ta_magic = TABLE_MAGIC; + table_p->ta_flags = table_p->ta_mmap->ta_flags; + table_p->ta_bucket_n = table_p->ta_mmap->ta_bucket_n; + table_p->ta_entry_n = table_p->ta_mmap->ta_entry_n; + table_p->ta_data_align = table_p->ta_mmap->ta_data_align; + table_p->ta_buckets = TABLE_POINTER(table_p, table_entry_t **, + table_p->ta_mmap->ta_buckets); + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; + /* mmap is already set */ + table_p->ta_file_size = table_p->ta_mmap->ta_file_size; + + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; + +#endif +} + +/* + * int table_munmap + * + * DESCRIPTION: + * + * Unmmap a table that was previously mmapped using table_mmap. + * + * RETURNS: + * + * Returns table error codes. + * + * ARGUMENTS: + * + * table_p - Mmaped table pointer to unmap. + */ +int table_munmap(table_t *table_p) +{ +#ifdef NO_MMAP + + /* no mmap support so immediate error */ + return TABLE_ERROR_MMAP_NONE; + +#else + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_mmap == NULL) { + return TABLE_ERROR_PNT; + } + + (void)munmap((caddr_t)table_p->ta_mmap, table_p->ta_file_size); + table_p->ta_magic = 0; + free(table_p); + return TABLE_ERROR_NONE; + +#endif +} + +/******************************* file routines *******************************/ + +/* + * int table_read + * + * DESCRIPTION: + * + * Read in a table from a file that had been written to disk earlier + * via table_write. + * + * RETURNS: + * + * Success - Pointer to the new table structure which must be passed + * to table_free to be deallocated. + * + * Failure - NULL + * + * ARGUMENTS: + * + * path - Table file to read in. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +table_t *table_read(const char *path, int *error_p) +{ + unsigned int size; + int fd, ent_size; + FILE *infile; + table_entry_t entry, **bucket_p, *entry_p = NULL, *last_p; + unsigned long pos; + table_t *table_p; + + /* open the file */ + fd = open(path, O_RDONLY, 0); + if (fd < 0) { + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; + } + + /* allocate a table structure */ + table_p = malloc(sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } + + /* now open the fd to get buffered i/o */ + infile = fdopen(fd, "r"); + if (infile == NULL) { + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; + } + + /* read the main table struct */ + if (fread(table_p, sizeof(table_t), 1, infile) != 1) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p); + return NULL; + } + table_p->ta_file_size = 0; + + /* is the mmap file contain bad info or maybe another system type? */ + if (table_p->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } + + /* allocate the buckets */ + table_p->ta_buckets = (table_entry_t **)calloc(table_p->ta_bucket_n, + sizeof(table_entry_t *)); + if (table_p->ta_buckets == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + free(table_p); + return NULL; + } + + if (fread(table_p->ta_buckets, sizeof(table_entry_t *), table_p->ta_bucket_n, + infile) != (size_t)table_p->ta_bucket_n) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p->ta_buckets); + free(table_p); + return NULL; + } + + /* read in the entries */ + for (bucket_p = table_p->ta_buckets; + bucket_p < table_p->ta_buckets + table_p->ta_bucket_n; + bucket_p++) { + + /* skip null buckets */ + if (*bucket_p == NULL) { + continue; + } + + /* run through the entry list */ + last_p = NULL; + for (pos = *(unsigned long *)bucket_p;; + pos = (unsigned long)entry_p->te_next_p) { + + /* read in the entry */ + if (fseek(infile, pos, SEEK_SET) != 0) { + SET_POINTER(error_p, TABLE_ERROR_SEEK); + free(table_p->ta_buckets); + free(table_p); + if (entry_p != NULL) { + free(entry_p); + } + /* the other table elements will not be freed */ + return NULL; + } + if (fread(&entry, sizeof(struct table_shell_st), 1, infile) != 1) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p->ta_buckets); + free(table_p); + if (entry_p != NULL) { + free(entry_p); + } + /* the other table elements will not be freed */ + return NULL; + } + + /* make a new entry */ + ent_size = entry_size(table_p, entry.te_key_size, entry.te_data_size); + entry_p = (table_entry_t *)malloc(ent_size); + if (entry_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + free(table_p->ta_buckets); + free(table_p); + /* the other table elements will not be freed */ + return NULL; + } + entry_p->te_key_size = entry.te_key_size; + entry_p->te_data_size = entry.te_data_size; + entry_p->te_next_p = entry.te_next_p; + + if (last_p == NULL) { + *bucket_p = entry_p; + } + else { + last_p->te_next_p = entry_p; + } + + /* determine how much more we have to read */ + size = ent_size - sizeof(struct table_shell_st); + if (fread(ENTRY_KEY_BUF(entry_p), sizeof(char), size, infile) != size) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p->ta_buckets); + free(table_p); + free(entry_p); + /* the other table elements will not be freed */ + return NULL; + } + + /* we are done if the next pointer is null */ + if (entry_p->te_next_p == (unsigned long)0) { + break; + } + last_p = entry_p; + } + } + + (void)fclose(infile); + + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; +} + +/* + * int table_write + * + * DESCRIPTION: + * + * Write a table from memory to file. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are writing to the file. + * + * path - Table file to write out to. + * + * mode - Mode of the file. This argument is passed on to open when + * the file is created. + */ +int table_write(const table_t *table_p, const char *path, const int mode) +{ + int fd, rem, ent_size; + unsigned int bucket_c, bucket_size; + unsigned long size; + table_entry_t *entry_p, **buckets, **bucket_p, *next_p; + table_t main_tab; + FILE *outfile; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + + fd = open(path, O_WRONLY | O_CREAT, mode); + if (fd < 0) { + return TABLE_ERROR_OPEN; + } + + outfile = fdopen(fd, "w"); + if (outfile == NULL) { + return TABLE_ERROR_OPEN; + } + + /* allocate a block of sizes for each bucket */ + bucket_size = sizeof(table_entry_t *) * table_p->ta_bucket_n; + if (table_p->ta_alloc_func == NULL) { + buckets = (table_entry_t **)malloc(bucket_size); + } + else { + buckets = + (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, + bucket_size); + } + if (buckets == NULL) { + return TABLE_ERROR_ALLOC; + } + + /* make a copy of the main struct */ + main_tab = *table_p; + + /* start counting the bytes */ + size = 0; + size += sizeof(table_t); + + /* buckets go right after main struct */ + main_tab.ta_buckets = (table_entry_t **)size; + size += sizeof(table_entry_t *) * table_p->ta_bucket_n; + + /* run through and count the buckets */ + for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) { + bucket_p = table_p->ta_buckets + bucket_c; + if (*bucket_p == NULL) { + buckets[bucket_c] = NULL; + continue; + } + buckets[bucket_c] = (table_entry_t *)size; + for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) { + size += entry_size(table_p, entry_p->te_key_size, entry_p->te_data_size); + /* + * We now have to round the file to the nearest long so the + * mmaping of the longs in the entry structs will work. + */ + rem = size & (sizeof(long) - 1); + if (rem > 0) { + size += sizeof(long) - rem; + } + } + } + /* add a \0 at the end to fill the last section */ + size++; + + /* set the main fields */ + main_tab.ta_linear.tl_magic = 0; + main_tab.ta_linear.tl_bucket_c = 0; + main_tab.ta_linear.tl_entry_c = 0; + main_tab.ta_mmap = NULL; + main_tab.ta_file_size = size; + + /* + * Now we can start the writing because we got the bucket offsets. + */ + + /* write the main table struct */ + size = 0; + if (fwrite(&main_tab, sizeof(table_t), 1, outfile) != 1) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size); + } + return TABLE_ERROR_WRITE; + } + size += sizeof(table_t); + if (fwrite(buckets, sizeof(table_entry_t *), table_p->ta_bucket_n, + outfile) != (size_t)table_p->ta_bucket_n) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size); + } + return TABLE_ERROR_WRITE; + } + size += sizeof(table_entry_t *) * table_p->ta_bucket_n; + + /* write out the entries */ + for (bucket_p = table_p->ta_buckets; + bucket_p < table_p->ta_buckets + table_p->ta_bucket_n; + bucket_p++) { + for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) { + + ent_size = entry_size(table_p, entry_p->te_key_size, + entry_p->te_data_size); + size += ent_size; + /* round to nearest long here so we can write copy */ + rem = size & (sizeof(long) - 1); + if (rem > 0) { + size += sizeof(long) - rem; + } + next_p = entry_p->te_next_p; + if (next_p != NULL) { + entry_p->te_next_p = (table_entry_t *)size; + } + + /* now write to disk */ + if (fwrite(entry_p, ent_size, 1, outfile) != 1) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, + bucket_size); + } + return TABLE_ERROR_WRITE; + } + + /* restore the next pointer */ + if (next_p != NULL) { + entry_p->te_next_p = next_p; + } + + /* now write the padding information */ + if (rem > 0) { + rem = sizeof(long) - rem; + /* + * NOTE: this won't leave fseek'd space at the end but we + * don't care there because there is no accessed memory + * afterwards. We write 1 \0 at the end to make sure. + */ + if (fseek(outfile, rem, SEEK_CUR) != 0) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, + bucket_size); + } + return TABLE_ERROR_SEEK; + } + } + } + } + /* + * Write a \0 at the end of the file to make sure that the last + * fseek filled with nulls. + */ + (void)fputc('\0', outfile); + + (void)fclose(outfile); + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, buckets, + bucket_size)) { + return TABLE_ERROR_FREE; + } + + return TABLE_ERROR_NONE; +} + +/******************************** table order ********************************/ + +/* + * table_entry_t *table_order + * + * DESCRIPTION: + * + * Order a table by building an array of table entry pointers and then + * sorting this array using the qsort function. To retrieve the + * sorted entries, you can then use the table_entry routine to access + * each entry in order. + * + * NOTE: This routine is thread safe and makes use of an internal + * status qsort function. + * + * RETURNS: + * + * Success - An allocated list of table-linear structures which must + * be freed by table_order_free later. + * + * Failure - NULL + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are ordering. + * + * compare - Comparison function defined by the user. Its definition + * is at the top of the table.h file. If this is NULL then it will + * order the table my memcmp-ing the keys. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries in the returned entry pointer array. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +table_entry_t **table_order(table_t *table_p, table_compare_t compare, + int *num_entries_p, int *error_p) +{ + table_entry_t *entry_p, **entries, **entries_p; + table_linear_t linear; + compare_t comp_func; + unsigned int entries_size; + int ret; + + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); + return NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } + + /* there must be at least 1 element in the table for this to work */ + if (table_p->ta_entry_n == 0) { + SET_POINTER(error_p, TABLE_ERROR_EMPTY); + return NULL; + } + + entries_size = table_p->ta_entry_n * sizeof(table_entry_t *); + if (table_p->ta_alloc_func == NULL) { + entries = (table_entry_t **)malloc(entries_size); + } + else { + entries = + (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, + entries_size); + } + if (entries == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } + + /* get a pointer to all entries */ + entry_p = first_entry(table_p, &linear); + if (entry_p == NULL) { + if (table_p->ta_free_func == NULL) { + free(entries); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); + } + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } + + /* add all of the entries to the array */ + for (entries_p = entries; + entry_p != NULL; + entry_p = next_entry(table_p, &linear, &ret)) { + *entries_p++ = entry_p; + } + + if (ret != TABLE_ERROR_NOT_FOUND) { + if (table_p->ta_free_func == NULL) { + free(entries); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); + } + SET_POINTER(error_p, ret); + return NULL; + } + + if (compare == NULL) { + /* this is regardless of the alignment */ + comp_func = local_compare; + } + else if (table_p->ta_data_align == 0) { + comp_func = external_compare; + } + else { + comp_func = external_compare_align; + } + + /* now qsort the entire entries array from first to last element */ + ret = split((unsigned char *)entries, + (unsigned char *)(entries + table_p->ta_entry_n - 1), + sizeof(table_entry_t *), comp_func, compare, table_p); + if (ret != TABLE_ERROR_NONE) { + if (table_p->ta_free_func == NULL) { + free(entries); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); + } + SET_POINTER(error_p, ret); + return NULL; + } + + SET_POINTER(num_entries_p, table_p->ta_entry_n); + + SET_POINTER(error_p, TABLE_ERROR_NONE); + return entries; +} + +/* + * int table_order_free + * + * DESCRIPTION: + * + * Free the pointer returned by the table_order or table_order_pos + * routines. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table. + * + * table_entries - Allocated list of entry pointers returned by + * table_order. + * + * entry_n - Number of entries in the array as passed back by + * table_order or table_order_pos in num_entries_p. + */ +int table_order_free(table_t *table_p, table_entry_t **table_entries, + const int entry_n) +{ + int ret, final = TABLE_ERROR_NONE; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + + if (table_p->ta_free_func == NULL) { + free(table_entries); + } + else { + ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries, + sizeof(table_entry_t *) * entry_n); + if (ret != 1) { + final = TABLE_ERROR_FREE; + } + } + + return final; +} + +/* + * int table_entry + * + * DESCRIPTION: + * + * Get information about an element. The element is one from the + * array returned by the table_order function. If any of the key/data + * pointers are NULL then they are ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * element. + * + * entry_p - Pointer to a table entry from the array returned by the + * table_order function. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of this entry that is allocated in the table. If an + * (int) is stored as this entry (for example) then key_buf_p should + * be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage of this entry that is allocated in the table. + * If a (long) is stored as this entry data (for example) then + * data_buf_p should be (long **) i.e. the address of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table. + */ +int table_entry(table_t *table_p, table_entry_t *entry_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (entry_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + + return TABLE_ERROR_NONE; +} + +/* + * table_linear_t *table_order_pos + * + * DESCRIPTION: + * + * Order a table by building an array of table linear structures and + * then sorting this array using the qsort function. To retrieve the + * sorted entries, you can then use the table_entry_pos routine to + * access each entry in order. + * + * NOTE: This routine is thread safe and makes use of an internal + * status qsort function. + * + * RETURNS: + * + * Success - An allocated list of table-linear structures which must + * be freed by table_order_pos_free later. + * + * Failure - NULL + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are ordering. + * + * compare - Comparison function defined by the user. Its definition + * is at the top of the table.h file. If this is NULL then it will + * order the table my memcmp-ing the keys. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries in the returned entry pointer array. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ +table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare, + int *num_entries_p, int *error_p) +{ + table_entry_t *entry_p; + table_linear_t linear, *linears, *linears_p; + compare_t comp_func; + int ret; + + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); + return NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } + + /* there must be at least 1 element in the table for this to work */ + if (table_p->ta_entry_n == 0) { + SET_POINTER(error_p, TABLE_ERROR_EMPTY); + return NULL; + } + + if (table_p->ta_alloc_func == NULL) { + linears = (table_linear_t *)malloc(table_p->ta_entry_n * + sizeof(table_linear_t)); + } + else { + linears = + (table_linear_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, + table_p->ta_entry_n * + sizeof(table_linear_t)); + } + if (linears == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } + + /* get a pointer to all entries */ + entry_p = first_entry(table_p, &linear); + if (entry_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } + + /* add all of the entries to the array */ + for (linears_p = linears; + entry_p != NULL; + entry_p = next_entry(table_p, &linear, &ret)) { + *linears_p++ = linear; + } + + if (ret != TABLE_ERROR_NOT_FOUND) { + SET_POINTER(error_p, ret); + return NULL; + } + + if (compare == NULL) { + /* this is regardless of the alignment */ + comp_func = local_compare_pos; + } + else if (table_p->ta_data_align == 0) { + comp_func = external_compare_pos; + } + else { + comp_func = external_compare_align_pos; + } + + /* now qsort the entire entries array from first to last element */ + split((unsigned char *)linears, + (unsigned char *)(linears + table_p->ta_entry_n - 1), + sizeof(table_linear_t), comp_func, compare, table_p); + + if (num_entries_p != NULL) { + *num_entries_p = table_p->ta_entry_n; + } + + SET_POINTER(error_p, TABLE_ERROR_NONE); + return linears; +} + +/* + * int table_order_pos_free + * + * DESCRIPTION: + * + * Free the pointer returned by the table_order or table_order_pos + * routines. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table. + * + * table_entries - Allocated list of entry pointers returned by + * table_order_pos. + * + * entry_n - Number of entries in the array as passed back by + * table_order or table_order_pos in num_entries_p. + */ +int table_order_pos_free(table_t *table_p, table_linear_t *table_entries, + const int entry_n) +{ + int ret, final = TABLE_ERROR_NONE; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + + if (table_p->ta_free_func == NULL) { + free(table_entries); + } + else { + ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries, + sizeof(table_linear_t) * entry_n); + if (ret != 1) { + final = TABLE_ERROR_FREE; + } + } + + return final; +} + +/* + * int table_entry_pos + * + * DESCRIPTION: + * + * Get information about an element. The element is one from the + * array returned by the table_order function. If any of the key/data + * pointers are NULL then they are ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * element. + * + * linear_p - Pointer to a table linear structure from the array + * returned by the table_order function. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of this entry that is allocated in the table. If an + * (int) is stored as this entry (for example) then key_buf_p should + * be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage of this entry that is allocated in the table. + * If a (long) is stored as this entry data (for example) then + * data_buf_p should be (long **) i.e. the address of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table. + */ +int table_entry_pos(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) +{ + table_entry_t *entry_p; + int ret; + + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + + /* find the associated entry */ + entry_p = this_entry(table_p, linear_p, &ret); + if (entry_p == NULL) { + return ret; + } + + if (key_buf_p != NULL) { + *key_buf_p = ENTRY_KEY_BUF(entry_p); + } + if (key_size_p != NULL) { + *key_size_p = entry_p->te_key_size; + } + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + if (data_size_p != NULL) { + *data_size_p = entry_p->te_data_size; + } + + return TABLE_ERROR_NONE; +} + +/* + * const char *table_strerror + * + * DESCRIPTION: + * + * Return the corresponding string for the error number. + * + * RETURNS: + * + * Success - String equivalient of the error. + * + * Failure - String "invalid error code" + * + * ARGUMENTS: + * + * error - Error number that we are converting. + */ +const char *table_strerror(const int error) +{ + error_str_t *err_p; + + for (err_p = errors; err_p->es_error != 0; err_p++) { + if (err_p->es_error == error) { + return err_p->es_string; + } + } + + return INVALID_ERROR; +} diff --git a/libs/libks/src/table_util.c b/libs/libks/src/table_util.c new file mode 100644 index 0000000000..2fcfda3778 --- /dev/null +++ b/libs/libks/src/table_util.c @@ -0,0 +1,295 @@ +/* + * Hash table utility program. + * + * Copyright 2000 by Gray Watson + * + * This file is part of the table package. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, + * and that the name of Gray Watson not be used in advertising or + * publicity pertaining to distribution of the document or software + * without specific, written prior permission. + * + * Gray Watson makes no representations about the suitability of the + * software described herein for any purpose. It is provided "as is" + * without express or implied warranty. + * + * The author may be reached via http://256.com/gray/ + * + * $Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $ + */ + +#include +#include +#include + +#include "table.h" + +static char *rcs_id = + "$Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $"; + +#define WRITE_MODE 0640 /* mode to write out table */ +#define SPECIAL_CHARS "e\033^^\"\"''\\\\n\nr\rt\tb\bf\fa\007" + +/* + * expand_chars + * + * DESCRIPTION: + * + * Copies a buffer into a output buffer while translates + * non-printables into %03o octal values. If it can, it will also + * translate certain \ characters (\r, \n, etc.) into \\%c. The + * routine is useful for printing out binary values. + * + * NOTE: It does _not_ add a \0 at the end of the output buffer. + * + * RETURNS: + * + * Returns the number of characters added to the output buffer. + * + * ARGUMENTS: + * + * buf - the buffer to convert. + * + * buf_size - size of the buffer. If < 0 then it will expand till it + * sees a \0 character. + * + * out - destination buffer for the convertion. + * + * out_size - size of the output buffer. + */ +int expand_chars(const void *buf, const int buf_size, + char *out, const int out_size) +{ + int buf_c; + const unsigned char *buf_p, *spec_p; + char *max_p, *out_p = out; + + /* setup our max pointer */ + max_p = out + out_size; + + /* run through the input buffer, counting the characters as we go */ + for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) { + + /* did we reach the end of the buffer? */ + if (buf_size < 0) { + if (*buf_p == '\0') { + break; + } + } + else { + if (buf_c >= buf_size) { + break; + } + } + + /* search for special characters */ + for (spec_p = (unsigned char *)SPECIAL_CHARS + 1; + *(spec_p - 1) != '\0'; + spec_p += 2) { + if (*spec_p == *buf_p) { + break; + } + } + + /* did we find one? */ + if (*(spec_p - 1) != '\0') { + if (out_p + 2 >= max_p) { + break; + } + (void)sprintf(out_p, "\\%c", *(spec_p - 1)); + out_p += 2; + continue; + } + + /* print out any 7-bit printable characters */ + if (*buf_p < 128 && isprint(*buf_p)) { + if (out_p + 1 >= max_p) { + break; + } + *out_p = *(char *)buf_p; + out_p += 1; + } + else { + if (out_p + 4 >= max_p) { + break; + } + (void)sprintf(out_p, "\\%03o", *buf_p); + out_p += 4; + } + } + + return out_p - out; +} + +/* + * dump_table + * + * DESCRIPTION: + * + * Dump a table file to the screen. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * tab_p - a table pointer that we are dumping. + */ +static void dump_table(table_t *tab_p) +{ + char buf[10240]; + void *key_p, *data_p; + int ret, key_size, data_size, len, entry_c; + + for (ret = table_first(tab_p, (void **)&key_p, &key_size, + (void **)&data_p, &data_size), entry_c = 0; + ret == TABLE_ERROR_NONE; + ret = table_next(tab_p, (void **)&key_p, &key_size, + (void **)&data_p, &data_size), entry_c++) { + /* expand the key */ + len = expand_chars(key_p, key_size, buf, sizeof(buf)); + (void)printf("%d: key '%.*s' (%d), ", entry_c, len, buf, len); + /* now dump the data */ + len = expand_chars(data_p, data_size, buf, sizeof(buf)); + (void)printf("data '%.*s' (%d)\n", len, buf, len); + } +} + +/* + * usage + * + * DESCRIPTION: + * + * Print the usage message to stderr. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * tab_p - a table pointer that we are dumping. + */ +static void usage(void) +{ + (void)fprintf(stderr, + "Usage: table_util\n" + " [-b number] or --buckets num buckets to adjust table\n" + " [-o file] or --out-file output filename\n" + " [-v] or --verbose verbose messages\n" + " file input table filename\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + table_t *tab_p; + char do_write = 0, verbose = 0; + char *out_file = NULL, *in_file; + int ret, entry_n, bucket_n, num_buckets = 0; + + /* process the args */ + for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) { + + switch (*(*argv + 1)) { + + case 'b': + argc--, argv++; + if (argc == 0) { + usage(); + } + num_buckets = atoi(*argv); + break; + + case 'o': + argc--, argv++; + if (argc == 0) { + usage(); + } + out_file = *argv; + break; + + case 'v': + verbose = 1; + break; + + default: + usage(); + break; + } + } + + if (argc != 1) { + usage(); + } + + /* take the last argument as the input file */ + in_file = *argv; + + /* read in the table from disk */ + tab_p = table_read(in_file, &ret); + if (tab_p == NULL) { + (void)fprintf(stderr, "table_util: unable to table_read from '%s': %s\n", + in_file, table_strerror(ret)); + exit(1); + } + + /* get info about the table */ + ret = table_info(tab_p, &bucket_n, &entry_n); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, + "table_util: unable to get info on table in '%s': %s\n", + in_file, table_strerror(ret)); + exit(1); + } + + (void)printf("Read table of %d buckets and %d entries from '%s'\n", + bucket_n, entry_n, in_file); + + if (verbose) { + dump_table(tab_p); + } + + if (num_buckets > 0) { + /* adjust the table's buckets */ + ret = table_adjust(tab_p, num_buckets); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, + "table_util: unable to adjust table to %d buckets: %s\n", + num_buckets, table_strerror(ret)); + exit(1); + } + do_write = 1; + } + + /* did we modify the table at all */ + if (do_write) { + if (out_file == NULL) { + out_file = in_file; + } + + /* write out our table */ + ret = table_write(tab_p, out_file, WRITE_MODE); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, "table_util: unable to write table to '%s': %s\n", + out_file, table_strerror(ret)); + exit(1); + } + + (void)printf("Wrote table to '%s'\n", out_file); + } + + /* free the table */ + ret = table_free(tab_p); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, "table_util: unable to free table: %s\n", + table_strerror(ret)); + /* NOTE: not a critical error */ + } + + exit(0); +} From d22e0caf15d1132e88bc1af43d97e422503d7521 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Sep 2012 13:06:33 -0500 Subject: [PATCH 007/512] trigger update on sofia lib for new patch --- libs/sofia-sip/.update | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 142a1e1a97..f85cfc8001 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Aug 15 22:51:21 CDT 2012 +Wed Sep 19 13:06:07 CDT 2012 From 7018a15bf19b2ff10cade312843e1f114a4e33e4 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Wed, 19 Sep 2012 15:25:38 -0400 Subject: [PATCH 008/512] fix for compile warning --- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 801febda14..7fb2f119a0 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 @@ -273,7 +273,7 @@ static ftdm_status_t parse_trunkgroup(const char *_trunkgroup) { int i; char *p, *name, *dchan_span, *backup_span, *trunkgroup; - uint8_t num_spans; + uint8_t num_spans = 0; ftdm_status_t ret = FTDM_SUCCESS; trunkgroup = ftdm_strdup(_trunkgroup); From 08e95e6ee134ecef4774d0eb20653720db992bf9 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 19 Sep 2012 14:44:42 -0500 Subject: [PATCH 009/512] fix 7960/40 reboot --- src/mod/endpoints/mod_sofia/sofia_reg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index d710602107..1142534401 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -588,6 +588,8 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *callid, const c event = "reboot_now"; } else if (switch_stristr("spa", user_agent)) { event = "reboot"; + } else if (switch_stristr("Cisco-CP7960G", user_agent) || switch_stristr("Cisco-CP7940G", user_agent)) { + event = "check-sync"; } else if (switch_stristr("cisco", user_agent)) { event = "service-control"; contenttype = "text/plain"; From 98063854c6181837b5af34f939356e03ab52f27f Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 19 Sep 2012 15:54:38 -0500 Subject: [PATCH 010/512] This already has a new line in it --- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 34b4150ac0..da9a3024eb 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 @@ -1091,7 +1091,7 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...) switch (level) { case SNG_LOGLEVEL_DEBUG: - ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s\n", data); + ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s", data); break; case SNG_LOGLEVEL_WARN: if ( strncmp(data, "Invalid Q.921/Q.931 frame", 25) ) { From 72f0cf476d55f08f49c85af192792f6b67624fdb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Sep 2012 16:34:22 -0500 Subject: [PATCH 011/512] add conference-create and conference-destroy action events --- .../applications/mod_conference/mod_conference.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 0b1adcab57..0bdf28822b 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1910,7 +1910,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v int32_t z = 0; int member_score_sum = 0; int divisor = 0; - + if (!(divisor = conference->rate / 8000)) { divisor = 1; } @@ -1932,6 +1932,13 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v conference->is_recording = 0; conference->record_count = 0; + + + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT); + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create"); + switch_event_fire(&event); + while (globals.running && !switch_test_flag(conference, CFLAG_DESTRUCT)) { switch_size_t file_sample_len = samples; switch_size_t file_data_len = samples * 2; @@ -2448,6 +2455,11 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v } } + + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT); + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-destroy"); + switch_event_fire(&event); switch_core_timer_destroy(&timer); switch_mutex_lock(globals.hash_mutex); From fff6e50a9bd76676ea23a49e0102cda77bdabeca Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 19 Sep 2012 20:02:30 -0400 Subject: [PATCH 012/512] freetdm: Fix E&M answer procedure for DAHDI --- libs/freetdm/mod_freetdm/mod_freetdm.c | 1 + libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 271f532a70..06dc587a4b 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2285,6 +2285,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal) } break; case FTDM_SIGEVENT_SIGSTATUS_CHANGED: + case FTDM_SIGEVENT_COLLECTED_DIGIT: /* Analog E&M */ break; default: { diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 2569ea49fd..363dcee7c5 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -737,6 +737,7 @@ static FIO_COMMAND_FUNCTION(zt_command) ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "OFFHOOK Failed"); return FTDM_FAIL; } + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel is now offhook\n"); ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); } break; @@ -747,6 +748,7 @@ static FIO_COMMAND_FUNCTION(zt_command) ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "ONHOOK Failed"); return FTDM_FAIL; } + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Channel is now onhook\n"); ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK); } break; @@ -1084,7 +1086,10 @@ static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan, case ZT_EVENT_RINGOFFHOOK: { if (fchan->type == FTDM_CHAN_TYPE_FXS || (fchan->type == FTDM_CHAN_TYPE_EM && fchan->state != FTDM_CHANNEL_STATE_UP)) { - ftdm_set_flag_locked(fchan, FTDM_CHANNEL_OFFHOOK); + if (fchan->type != FTDM_CHAN_TYPE_EM) { + /* In E&M we're supposed to set this flag when the tx side goes offhook, not the rx */ + ftdm_set_flag_locked(fchan, FTDM_CHANNEL_OFFHOOK); + } *event_id = FTDM_OOB_OFFHOOK; } else if (fchan->type == FTDM_CHAN_TYPE_FXO) { *event_id = FTDM_OOB_RING_START; From 45bda533616d6b2ea866b1cbb3707851fe876627 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 20 Sep 2012 06:43:54 +0000 Subject: [PATCH 013/512] Add new modules to debian packaging --- debian/control-modules | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/debian/control-modules b/debian/control-modules index 5b76bd5d26..a41e858513 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -147,6 +147,11 @@ Description: Nibblebill This module allows for real-time accounting of a cash balance and using that information for call routing. +Module: applications/mod_oreka +Description: Media recording with Oreka + This module provides media recording with the Oreka cross-platfor + audio stream recording and retrieval system. + Module: applications/mod_osp Description: Open Settlement Protocol This module adds support for the Open Settlement Protocol (OSP). @@ -192,6 +197,11 @@ Module: applications/mod_snom Description: SNOM specific features This module implements features specific to SNOM phones. +Module: applications/mod_sonar +Description: Sonar ping timer + This module measures the latency on an audio link by sending audible + audio sonar pings. + Module: applications/mod_soundtouch Description: Soundtouch This module implements example media bugs. @@ -335,6 +345,10 @@ Module: codecs/mod_voipcodecs Description: mod_voipcodecs Adds mod_voipcodecs. +Module: codecs/mod_vp8 +Description: VP8 video codec + This module adds the VP8 video codec, also known as WebM. + ## mod/dialplans Module: dialplans/mod_dialplan_asterisk @@ -376,6 +390,10 @@ Description: mod_h323 Adds mod_h323. Build-Depends: libopenh323-dev, libpt-dev +Module: endpoints/mod_html5 +Description: HTML5 endpoint module + This module adds support for HTML5 technologies such as WebRTC. + Module: endpoints/mod_khomp Description: mod_khomp Adds mod_khomp. @@ -651,6 +669,10 @@ Description: mod_xml_ldap Adds mod_xml_ldap. Build-Depends: libsasl2-dev +Module: xml_int/mod_xml_radius +Description: mod_xml_radius + Adds mod_xml_radius + Module: xml_int/mod_xml_rpc Description: mod_xml_rpc Adds mod_xml_rpc. From 1dd2e0f6b0294019f0a62ce3b0e7c658c9e2de66 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 20 Sep 2012 06:48:07 +0000 Subject: [PATCH 014/512] Avoid new modules in debian except mod_vp8 --- debian/bootstrap.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index a724948577..5ba909b851 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -12,9 +12,11 @@ avoid_mods=( applications/mod_limit applications/mod_mongo applications/mod_mp4 + applications/mod_oreka applications/mod_osp applications/mod_rad_auth applications/mod_skel + applications/mod_sonar applications/mod_soundtouch asr_tts/mod_cepstral asr_tts/mod_flite @@ -26,6 +28,7 @@ avoid_mods=( codecs/mod_voipcodecs endpoints/mod_gsmopen endpoints/mod_h323 + endpoints/mod_html5 endpoints/mod_khomp endpoints/mod_opal endpoints/mod_reference @@ -35,6 +38,7 @@ avoid_mods=( languages/mod_spidermonkey sdk/autotools xml_int/mod_xml_ldap + xml_int/mod_xml_radius ) avoid_mods_sid=( endpoints/mod_portaudio From eca14d46011a416db288a8e87d00dee47be70002 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 20 Sep 2012 07:03:30 +0000 Subject: [PATCH 015/512] Fix format string for actual type of apr_time_t This was causing the build to fail if mod_sonar was configured to build. --- src/mod/applications/mod_sonar/mod_sonar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_sonar/mod_sonar.c b/src/mod/applications/mod_sonar/mod_sonar.c index 5cdcd35188..8f6e424eb3 100644 --- a/src/mod/applications/mod_sonar/mod_sonar.c +++ b/src/mod/applications/mod_sonar/mod_sonar.c @@ -61,7 +61,7 @@ switch_bool_t sonar_ping_callback(switch_core_session_t *session, const char *ap end = switch_time_now(); diff = end - start; start = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Sonar ping took %lu milliseconds\n", diff / 1000); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Sonar ping took %ld milliseconds\n", (long)diff / 1000); return SWITCH_TRUE; } From c6e75490552a500fb8dddc6889e14b6229489c0f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Sep 2012 09:48:47 -0500 Subject: [PATCH 016/512] FS-4634 --resolve --- src/switch_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core.c b/src/switch_core.c index 30f1ef3bae..2a9bec7dee 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1692,7 +1692,7 @@ static void switch_load_core_config(const char *file) switch_core_session_ctl(SCSC_LOGLEVEL, &level); } #ifdef HAVE_SETRLIMIT - } else if (!strcasecmp(var, "dump-cores")) { + } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) { struct rlimit rlp; memset(&rlp, 0, sizeof(rlp)); rlp.rlim_cur = RLIM_INFINITY; From 0dac49008655ea222318ab056ea5a82548bb6d73 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Sep 2012 09:53:53 -0500 Subject: [PATCH 017/512] FS-4315 --resolve --- src/mod/applications/mod_spy/mod_spy.c | 113 ++++++++++++++++--------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c index 12c42ba15c..a5cb3c92c0 100644 --- a/src/mod/applications/mod_spy/mod_spy.c +++ b/src/mod/applications/mod_spy/mod_spy.c @@ -46,22 +46,39 @@ struct mod_spy_globals { uint32_t spy_count; } globals; +typedef struct spy { + const char *uuid; + struct spy *next; +} spy_t; + + static switch_status_t spy_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); + const char *data = switch_channel_get_private(channel, "_userspy_"); + const char *uuid = switch_core_session_get_uuid(session); + spy_t *spy = NULL, *p = NULL, *prev = NULL; - char *data = switch_channel_get_private(channel, "_userspy_"); switch_thread_rwlock_wrlock(globals.spy_hash_lock); - if ((switch_core_hash_delete(globals.spy_hash, data) != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No such key in userspy: %s \n", data); - - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Userspy deactivated on %s\n", data); - globals.spy_count--; + spy = switch_core_hash_find(globals.spy_hash, data); + for (p = spy; p; p = p->next) { + if (p->uuid == uuid) { + if (prev) { + prev->next = p->next; + } else { + spy = p->next; + } + globals.spy_count--; + break; + } + prev = p; } + switch_core_hash_insert(globals.spy_hash, data, spy); + switch_thread_rwlock_unlock(globals.spy_hash_lock); + return SWITCH_STATUS_SUCCESS; } @@ -115,12 +132,20 @@ SWITCH_STANDARD_API(dump_hash) switch_hash_index_t *hi; const void *key; void *val; + spy_t *spy; switch_thread_rwlock_rdlock(globals.spy_hash_lock); for (hi = switch_hash_first(NULL, globals.spy_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &key, NULL, &val); - stream->write_function(stream, "%s : %s\n", (char *) key, (const char *) val); + spy = (spy_t *) val; + + stream->write_function(stream, "%s :"); + while (spy) { + stream->write_function(stream, " %s", spy->uuid); + spy = spy->next; + } + stream->write_function(stream, "\n"); } stream->write_function(stream, "\n%d total spy\n", globals.spy_count); @@ -130,9 +155,10 @@ SWITCH_STANDARD_API(dump_hash) static switch_status_t process_event(switch_event_t *event) { + switch_status_t status = SWITCH_STATUS_SUCCESS; switch_core_session_t *session = NULL; - char *username[3] = { 0 }; - char *domain[3] = { 0 }; + char *username[3] = { NULL }; + char *domain[3] = { NULL }; char key[512]; char *uuid = NULL, *my_uuid = NULL; int i; @@ -147,8 +173,8 @@ static switch_status_t process_event(switch_event_t *event) username[0] = switch_event_get_header(event, "Caller-Username"); domain[0] = switch_event_get_header(event, "variable_domain_name"); - domain[1] = switch_event_get_header(event, "variable_dialed_domain"); username[1] = switch_event_get_header(event, "variable_dialed_user"); + domain[1] = switch_event_get_header(event, "variable_dialed_domain"); username[2] = switch_event_get_header(event, "variable_user_name"); domain[2] = switch_event_get_header(event, "variable_domain_name"); @@ -156,35 +182,39 @@ static switch_status_t process_event(switch_event_t *event) for (i = 0; i < 3; i++) { if (username[i] && domain[i]) { + spy_t *spy = NULL; switch_snprintf(key, sizeof(key), "%s@%s", username[i], domain[i]); - if ((uuid = switch_core_hash_find(globals.spy_hash, key))) { + if ((spy = switch_core_hash_find(globals.spy_hash, key))) { + while (spy) { + if ((session = switch_core_session_locate(spy->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_channel_set_variable(channel, "spy_uuid", my_uuid); + + switch_channel_set_state(channel, CS_EXCHANGE_MEDIA); + switch_channel_set_flag(channel, CF_BREAK); + + switch_core_session_rwunlock(session); + } + spy = spy->next; + } break; + } else { + /* not found */ + status = SWITCH_STATUS_FALSE; } } } - + + done: switch_thread_rwlock_unlock(globals.spy_hash_lock); + return status; - if (!uuid) { - return SWITCH_STATUS_FALSE; - } - - 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_channel_set_variable(channel, "spy_uuid", my_uuid); - - switch_channel_set_state(channel, CS_EXCHANGE_MEDIA); - switch_channel_set_flag(channel, CF_BREAK); - - switch_core_session_rwunlock(session); - } - return SWITCH_STATUS_SUCCESS; } @@ -233,20 +263,20 @@ SWITCH_STANDARD_APP(userspy_function) if (!zstr(data) && (params = switch_core_session_strdup(session, data))) { if ((argc = switch_separate_string(params, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) { - switch_channel_t *channel = switch_core_session_get_channel(session); char *uuid = switch_core_session_get_uuid(session); switch_status_t status; + spy_t *spy = NULL; + + spy = switch_core_session_alloc(session, sizeof(spy_t)); + switch_assert(spy != NULL); + spy->uuid = uuid; switch_thread_rwlock_wrlock(globals.spy_hash_lock); - if (switch_core_hash_find(globals.spy_hash, argv[0])) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Spy already exists for %s\n", argv[0]); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - switch_thread_rwlock_unlock(globals.spy_hash_lock); - return; - } - status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) uuid); + spy->next = (spy_t *) switch_core_hash_find(globals.spy_hash, argv[0]); + + status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) spy); if ((status != SWITCH_STATUS_SUCCESS)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't insert to spy hash\n"); @@ -270,11 +300,10 @@ SWITCH_STANDARD_APP(userspy_function) } switch_channel_set_state(channel, CS_PARK); - return; } - return; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", USERSPY_SYNTAX); } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", USERSPY_SYNTAX); } SWITCH_MODULE_LOAD_FUNCTION(mod_spy_load) From a39ba84f5e5cf1c318bd57a41bfc649c0a79776b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Sep 2012 09:55:47 -0500 Subject: [PATCH 018/512] FS-4458 --resolve --- .../mod_erlang_event/mod_erlang_event.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 0aeaece8dd..9b34bfa8fc 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -812,7 +812,6 @@ static void handle_exit(listener_t *listener, erlang_pid * pid) } - if (listener->log_process.type == ERLANG_PID && !ei_compare_pids(&listener->log_process.pid, pid)) { void *pop; @@ -1477,15 +1476,14 @@ SWITCH_STANDARD_APP(erlang_outbound_function) int argc = 0, argc2 = 0; char *argv[80] = { 0 }, *argv2[80] = { 0 }; char *mydata, *myarg; - char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1]; session_elem_t *session_element = NULL; + switch_channel_t *channel = switch_core_session_get_channel(session); /* process app arguments */ if (data && (mydata = switch_core_session_strdup(session, data))) { argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } /* XXX else? */ - memcpy(uuid, switch_core_session_get_uuid(session), SWITCH_UUID_FORMATTED_LENGTH); if (argc < 2) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error - need registered name and node!\n"); @@ -1518,6 +1516,13 @@ SWITCH_STANDARD_APP(erlang_outbound_function) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "enter erlang_outbound_function %s %s\n", argv[0], node); + + if (switch_channel_test_flag(channel, CF_CONTROLLED)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is already under control\n"); + return; + } + + /* first work out if there is a listener already talking to the node we want to talk to */ listener = find_listener(node); /* if there is no listener, then create one */ @@ -1551,7 +1556,7 @@ SWITCH_STANDARD_APP(erlang_outbound_function) switch_thread_rwlock_unlock(globals.listener_rwlock); } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "exit erlang_outbound_function\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "exit erlang_outbound_function\n"); } From 07ed03c45845901c997c3d999d5603c85e44cc9d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Sep 2012 09:57:58 -0500 Subject: [PATCH 019/512] FS-4625 --resolve --- src/mod/applications/mod_dptools/mod_dptools.c | 17 +++++++++++++++++ src/switch_channel.c | 2 +- src/switch_ivr_async.c | 11 +---------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index b481ca9f05..4fec5c3269 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -567,6 +567,22 @@ SWITCH_STANDARD_APP(mkdir_function) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s MKDIR: %s\n", switch_channel_get_name(switch_core_session_get_channel(session)), data); } +#define RENAME_SYNTAX " " +SWITCH_STANDARD_APP(rename_function) +{ + char *argv[2] = { 0 }; + char *lbuf = NULL; + + if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data)) + && switch_split(lbuf, ' ', argv) == 2) { + switch_file_rename(argv[0], argv[1], switch_core_session_get_pool(session)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RENAME: %s %s\n", + switch_channel_get_name(switch_core_session_get_channel(session)), argv[0], argv[1]); + + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", RENAME_SYNTAX); + } +} #define SOFT_HOLD_SYNTAX " [] []" SWITCH_STANDARD_APP(soft_hold_function) @@ -5103,6 +5119,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "enable_heartbeat", "Enable Media Heartbeat", "Enable Media Heartbeat", heartbeat_function, HEARTBEAT_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "mkdir", "Create a directory", "Create a directory", mkdir_function, MKDIR_SYNTAX, SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "rename", "Rename file", "Rename file", rename_function, RENAME_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "soft_hold", "Put a bridged channel on hold", "Put a bridged channel on hold", soft_hold_function, SOFT_HOLD_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "bind_meta_app", "Bind a key to an application", "Bind a key to an application", dtmf_bind_function, BIND_SYNTAX, diff --git a/src/switch_channel.c b/src/switch_channel.c index f823b22e49..5606d81fe0 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -3274,7 +3274,7 @@ static void do_execute_on(switch_channel_t *channel, const char *variable) app = switch_core_session_strdup(channel->session, variable); for(p = app; p && *p; p++) { - if (*p == ' ') { + if (*p == ' ' || (*p == ':' && (*(p+1) != ':'))) { *p++ = '\0'; arg = p; break; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 03f9839f78..314b41a5ed 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1083,16 +1083,7 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s switch_event_fire(&event); } - if ((var = switch_channel_get_variable(channel, "record_post_process_exec_app"))) { - char *app = switch_core_session_strdup(session, var); - char *data; - - if ((data = strchr(app, ':'))) { - *data++ = '\0'; - } - - switch_core_session_execute_application(session, app, data); - } + switch_channel_execute_on(channel, "record_post_process_exec_app"); if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) { char *cmd = switch_core_session_strdup(session, var); From dfa83799d0921b0b2486267c9634d17130ad337e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Sep 2012 09:59:50 -0500 Subject: [PATCH 020/512] FS-4624 --resolve --- .../applications/mod_dptools/mod_dptools.c | 58 ++++++++++++++----- src/switch_ivr_async.c | 2 +- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 4fec5c3269..fae029bc61 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4419,7 +4419,7 @@ struct file_string_context { typedef struct file_string_context file_string_context_t; -static int next_file(switch_file_handle_t *handle) +static switch_status_t next_file(switch_file_handle_t *handle) { file_string_context_t *context = handle->private_info; char *file; @@ -4434,7 +4434,7 @@ static int next_file(switch_file_handle_t *handle) } if (context->index >= context->argc) { - return 0; + return SWITCH_STATUS_FALSE; } @@ -4450,8 +4450,23 @@ static int next_file(switch_file_handle_t *handle) file = switch_core_sprintf(handle->memory_pool, "%s%s%s", prefix, SWITCH_PATH_SEPARATOR, context->argv[context->index]); } - if (switch_core_file_open(&context->fh, - file, handle->channels, handle->samplerate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { + char *path = switch_core_strdup(handle->memory_pool, file); + char *p; + + if ((p = strrchr(path, *SWITCH_PATH_SEPARATOR))) { + *p = '\0'; + if (switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS, handle->memory_pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", path); + return SWITCH_STATUS_FALSE; + } + + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error finding the folder path section in '%s'\n", path); + } + + } + if (switch_core_file_open(&context->fh, file, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { goto top; } @@ -4477,7 +4492,7 @@ static int next_file(switch_file_handle_t *handle) } } - return 1; + return SWITCH_STATUS_SUCCESS; } @@ -4503,11 +4518,6 @@ static switch_status_t file_string_file_open(switch_file_handle_t *handle, const file_string_context_t *context; char *file_dup; - if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing!\n"); - return SWITCH_STATUS_FALSE; - } - context = switch_core_alloc(handle->memory_pool, sizeof(*context)); file_dup = switch_core_strdup(handle->memory_pool, path); @@ -4516,7 +4526,7 @@ static switch_status_t file_string_file_open(switch_file_handle_t *handle, const handle->private_info = context; - return next_file(handle) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; + return next_file(handle); } static switch_status_t file_string_file_close(switch_file_handle_t *handle) @@ -4549,16 +4559,35 @@ static switch_status_t file_string_file_read(switch_file_handle_t *handle, void } if (status != SWITCH_STATUS_SUCCESS) { - if (!next_file(handle)) { - return SWITCH_STATUS_FALSE; + if ((status = next_file(handle)) != SWITCH_STATUS_SUCCESS) { + return status; } *len = llen; status = switch_core_file_read(&context->fh, data, len); } - return SWITCH_STATUS_SUCCESS; + return status; } +static switch_status_t file_string_file_write(switch_file_handle_t *handle, void *data, size_t *len) +{ + file_string_context_t *context = handle->private_info; + switch_status_t status; + size_t llen = *len; + + status = switch_core_file_write(&context->fh, data, len); + + if (status != SWITCH_STATUS_SUCCESS) { + if ((status = next_file(handle)) != SWITCH_STATUS_SUCCESS) { + return status; + } + *len = llen; + status = switch_core_file_write(&context->fh, data, len); + } + return status; +} + + /* Registration */ static char *file_string_supported_formats[SWITCH_MAX_CODECS] = { 0 }; @@ -4979,6 +5008,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) file_interface->file_open = file_string_file_open; file_interface->file_close = file_string_file_close; file_interface->file_read = file_string_file_read; + file_interface->file_write = file_string_file_write; file_interface->file_seek = file_string_file_seek; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 314b41a5ed..a9ebc4b352 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1825,7 +1825,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t file_path = switch_core_session_strdup(session, file); } - if (file_path) { + if (file_path && !strstr(file_path, SWITCH_URL_SEPARATOR)) { char *p; char *path = switch_core_session_strdup(session, file_path); From 54289f2a6596db634c17ca2f0620273255cec4ef Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Thu, 20 Sep 2012 08:46:01 -0700 Subject: [PATCH 021/512] FreeSWITCH ChangeLog for 1.2.1 and 1.2.2 --- docs/ChangeLog | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/ChangeLog b/docs/ChangeLog index e0de248e87..562fe03d5f 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -1,3 +1,25 @@ +freeswitch (1.2.2) + configuration: Add language config files for es-ES,es-MX,pt-BR,pt-PT (Thanks Francois Delawarde) (r:9cde99b4/FS-3003) + core: move recovery engine up into the core (r:66677c94) + core: add ignore_early_media=consume to ivr_originate (r:13dab11c) + core: add timestamps for on and off hold times to put in xml cdrs (r:b0e49d3e) + libtiff: update to 4.0.2 (r:a2b5af56) + mod_commands: add uuid_answer and uuid_pre_answer (r:ce88d572) + mod_commands: add uuid_early_ok (r:35f0e2ff) + mod_commands: add uuid_media_reneg api command to tell a channel to send a re-invite with optional list of new codecs (r:bfc46567) + mod_dptools: mutex app (r:212953bc) + mod_httapi: add cache param (r:a8b89bcc) + mod_shout: add mp3 codec for mp4 (r:084dac25) + mod_sofia: change mod_sofia to use new core based recovery engine (r:2a8841ab) + mod_sofia: fire-message-events profile param (r:9c06cb34) + mod_spidermonkey: add email function to js (r:37b36aea) + +freeswitch (1.2.1) + libapr: Updating in tree apr for 1.4.6 (r:4029614e) + libwebsockets: Initial commit (r:6fa2fd36) + mod_sofia: add rtp endpoint contributed by sangoma (r:ef5c1256) + mod_spidermonkey: add javascript chatplan app (r:61839229) + freeswitch (1.2.0) build: Automated builds for CI testing/Jenkins (r:2aff535a) build: add debian source package building script (r:c164aae9) From caaa5726b07e717ed02229993b520e5e6fa2f42f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Sep 2012 10:49:39 -0500 Subject: [PATCH 022/512] fold over use-server to be alias for nameserver param and support back compat with legacy configs --- src/mod/applications/mod_enum/mod_enum.c | 68 ++++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/mod/applications/mod_enum/mod_enum.c b/src/mod/applications/mod_enum/mod_enum.c index c40e6443f0..ae19bdb791 100644 --- a/src/mod/applications/mod_enum/mod_enum.c +++ b/src/mod/applications/mod_enum/mod_enum.c @@ -67,7 +67,6 @@ static switch_event_node_t *NODE = NULL; static struct { char *root; - char *server; char *isn_root; enum_route_t *route_order; switch_memory_pool_t *pool; @@ -79,7 +78,6 @@ static struct { } globals; SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_root, globals.root); -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_server, globals.server); SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_isn_root, globals.isn_root); static void add_route(char *service, char *regex, char *replace) @@ -126,8 +124,6 @@ static switch_status_t load_config(void) const char *val = switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "default-root")) { set_global_root(val); - } else if (!strcasecmp(var, "use-server")) { - set_global_server(val); } else if (!strcasecmp(var, "auto-reload")) { globals.auto_reload = switch_true(val); } else if (!strcasecmp(var, "query-timeout")) { @@ -140,7 +136,7 @@ static switch_status_t load_config(void) globals.random = switch_true(val); } else if (!strcasecmp(var, "default-isn-root")) { set_global_isn_root(val); - } else if (!strcasecmp(var, "nameserver")) { + } else if (!strcasecmp(var, "nameserver") || !strcasecmp(var, "use-server")) { if ( inameserver < ENUM_MAXNAMESERVERS ) { globals.nameserver[inameserver] = (char *) val; inameserver++; @@ -560,6 +556,7 @@ static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results int argc; int x = 0; char *enum_nameserver_dup; + const char *enum_nameserver = NULL; *results = NULL; @@ -577,41 +574,45 @@ static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results /* Empty the server array */ for(inameserver=0; inameserver Date: Thu, 20 Sep 2012 09:53:34 -0700 Subject: [PATCH 023/512] FreeSWITCH ChangeLog for 1.2.3 --- docs/ChangeLog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/ChangeLog b/docs/ChangeLog index 562fe03d5f..ae69a26e4c 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -1,3 +1,12 @@ +freeswitch (1.2.3) + core: add hold_events variable with start and stop times for each hold (r:9a193a9c) + core: update json lib in core and ESL and re-apply old patches (r:5a956890) + core: add skip_cdr_causes variable to list call hangup causes that should not trigger cdr processing (r:3cf238fc) + formats: add mod_mp4v2 for mp4 recording, most things are hardcodec, but it should work with 8000hz audio and H264 video (r:7e01bd10) + libsofia: Fix DoS vulnerability in processing Route Header (r:016550f2/FS-4627) + libtpl: add tpl to tree (r:4985a41f) + mod_sofia: add transfer_to variable for call processing (r:1b2b4565) + freeswitch (1.2.2) configuration: Add language config files for es-ES,es-MX,pt-BR,pt-PT (Thanks Francois Delawarde) (r:9cde99b4/FS-3003) core: move recovery engine up into the core (r:66677c94) @@ -12,6 +21,7 @@ freeswitch (1.2.2) mod_shout: add mp3 codec for mp4 (r:084dac25) mod_sofia: change mod_sofia to use new core based recovery engine (r:2a8841ab) mod_sofia: fire-message-events profile param (r:9c06cb34) + mod_sofia: add send-display-update profile param to disable the update method (r:8f0c726b) mod_spidermonkey: add email function to js (r:37b36aea) freeswitch (1.2.1) From 363749c0dd7456b292be59b4ed0cfe810d730423 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Thu, 20 Sep 2012 11:47:39 -0700 Subject: [PATCH 024/512] Additional 1.2.3 ChangeLog entries (Thanks Moy) --- docs/ChangeLog | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/ChangeLog b/docs/ChangeLog index ae69a26e4c..9e03975eb9 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -3,10 +3,14 @@ freeswitch (1.2.3) core: update json lib in core and ESL and re-apply old patches (r:5a956890) core: add skip_cdr_causes variable to list call hangup causes that should not trigger cdr processing (r:3cf238fc) formats: add mod_mp4v2 for mp4 recording, most things are hardcodec, but it should work with 8000hz audio and H264 video (r:7e01bd10) + freetdm: M2UA Signaling gateway support (SIGTRAN) + freetdm: New TDM endpoint for raw IO access to boards (controllable channel) + freetdm: New dialplan paramters and SIP X headers to set ISUP message information elements + freetdm: Misc ISUP bug fixes libsofia: Fix DoS vulnerability in processing Route Header (r:016550f2/FS-4627) libtpl: add tpl to tree (r:4985a41f) mod_sofia: add transfer_to variable for call processing (r:1b2b4565) - + freeswitch (1.2.2) configuration: Add language config files for es-ES,es-MX,pt-BR,pt-PT (Thanks Francois Delawarde) (r:9cde99b4/FS-3003) core: move recovery engine up into the core (r:66677c94) From 5ecccf539da049a785808096a0641160555246a6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Sep 2012 15:57:08 -0500 Subject: [PATCH 025/512] FS-4637 please test and repost log --- src/mod/endpoints/mod_sofia/sofia.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 304ac668dd..f7f7bddead 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5845,9 +5845,9 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status sofia_clear_flag(tech_pvt, TFLAG_T38_PASSTHRU); } - if (switch_channel_test_flag(channel, CF_PROXY_MODE) || - switch_channel_test_flag(channel, CF_PROXY_MEDIA) || - (sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && (has_t38 || status > 299))) { + if (status > 199 && (switch_channel_test_flag(channel, CF_PROXY_MODE) || + switch_channel_test_flag(channel, CF_PROXY_MEDIA) || + (sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && (has_t38 || status > 299)))) { if (sofia_test_flag(tech_pvt, TFLAG_SENT_UPDATE)) { sofia_clear_flag_locked(tech_pvt, TFLAG_SENT_UPDATE); From 1a586474502925d4938fe7be3348b814adae38df Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Thu, 20 Sep 2012 16:24:26 -0700 Subject: [PATCH 026/512] ChangeLog update (thanks Seven Du\!) --- docs/ChangeLog | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/ChangeLog b/docs/ChangeLog index 9e03975eb9..d73e3630af 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -22,7 +22,6 @@ freeswitch (1.2.2) mod_commands: add uuid_media_reneg api command to tell a channel to send a re-invite with optional list of new codecs (r:bfc46567) mod_dptools: mutex app (r:212953bc) mod_httapi: add cache param (r:a8b89bcc) - mod_shout: add mp3 codec for mp4 (r:084dac25) mod_sofia: change mod_sofia to use new core based recovery engine (r:2a8841ab) mod_sofia: fire-message-events profile param (r:9c06cb34) mod_sofia: add send-display-update profile param to disable the update method (r:8f0c726b) From 142374eaabcf5c7e88234c3cad5d5b5ebcdb4c93 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 20 Sep 2012 21:04:39 -0500 Subject: [PATCH 027/512] mod_enum windows fix for last commit --- src/mod/applications/mod_enum/mod_enum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_enum/mod_enum.c b/src/mod/applications/mod_enum/mod_enum.c index ae19bdb791..9835fda46d 100644 --- a/src/mod/applications/mod_enum/mod_enum.c +++ b/src/mod/applications/mod_enum/mod_enum.c @@ -163,7 +163,7 @@ static switch_status_t load_config(void) done: #ifdef _MSC_VER - if (!globals.server) { + if (!globals.nameserver[0]) { HKEY hKey; DWORD data_sz; char* buf; @@ -183,7 +183,7 @@ static switch_status_t load_config(void) buf[data_sz] = 0; } switch_replace_char(buf, ' ', 0, SWITCH_FALSE); /* only use the first entry ex "192.168.1.1 192.168.1.2" */ - globals.server = buf; + globals.nameserver[0] = buf; } } } From 1050d443a65ba4db724e5a934f0d2a1971c720a9 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Fri, 21 Sep 2012 10:37:26 +0200 Subject: [PATCH 028/512] test, please ignore --- src/mod/endpoints/mod_skypopen/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skypopen/README b/src/mod/endpoints/mod_skypopen/README index ba5b0d9271..90314cda68 100644 --- a/src/mod/endpoints/mod_skypopen/README +++ b/src/mod/endpoints/mod_skypopen/README @@ -5,4 +5,4 @@ tricks and tweaks, possible problems at: http://wiki.freeswitch.org/wiki/Mod_skypopen_Skype_Endpoint_and_Trunk -< gmaruzz at gmail dot com > +mail to: < gmaruzz at gmail dot com > From ef9af7dc94b562901e138adf92fbd2f8f4701194 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 21 Sep 2012 10:15:45 -0500 Subject: [PATCH 029/512] FS-4636 --resolve I think this is an ok change so we'll push it. --- src/switch_ivr_originate.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 0b02d2ba2c..7cb296b1c6 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1216,24 +1216,28 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, originate_st } if (!ringback->asis) { + switch_codec_implementation_t peer_read_impl = { 0 }; + if (switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) { switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_WARNING, "%s Ringback not supported in passthrough codec mode.\n", switch_channel_get_name(caller_channel)); switch_goto_status(SWITCH_STATUS_GENERR, end); } + switch_core_session_get_read_impl(originate_status[0].peer_session, &peer_read_impl); + if (switch_core_codec_init(write_codec, "L16", NULL, - read_codec->implementation->actual_samples_per_second, - read_codec->implementation->microseconds_per_packet / 1000, + peer_read_impl.actual_samples_per_second, + peer_read_impl.microseconds_per_packet / 1000, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(oglobals->session)) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals->session), SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", - read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); + peer_read_impl.actual_samples_per_second, peer_read_impl.microseconds_per_packet / 1000); write_frame->codec = write_codec; write_frame->datalen = read_codec->implementation->decoded_bytes_per_packet; write_frame->samples = write_frame->datalen / 2; From 9c97ae3cccf96fcfb302c520afad7eb1f607d536 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 21 Sep 2012 14:45:30 -0500 Subject: [PATCH 030/512] FS-4640 please test --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index aa3f3207d5..b7450e4e47 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2600,7 +2600,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_ANSWER); } } else { - if (msg->numeric_arg) { + if (msg->numeric_arg && !(switch_channel_test_flag(channel, CF_ANSWERED) && code == 488)) { if (code > 399) { switch_call_cause_t cause = sofia_glue_sip_cause_to_freeswitch(code); if (code == 401 || cause == 407) cause = SWITCH_CAUSE_USER_CHALLENGE; From 3439d1b3b4f4b561f45eed1d67fc709ced1c107b Mon Sep 17 00:00:00 2001 From: William King Date: Sat, 22 Sep 2012 18:53:27 -0700 Subject: [PATCH 031/512] FS-4305: --resolve When libvlc is unable to decode the audio fast enough for the local stream player, use multiple very quick 1 sample chunks of silence to fill in while libvlc catches up. --- src/mod/formats/mod_vlc/mod_vlc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index 592acb1ff0..d5b5ec336d 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -275,8 +275,8 @@ static switch_status_t vlc_file_read(switch_file_handle_t *handle, void *data, s if (!read && (status == 5 || status == 6)) { return SWITCH_STATUS_FALSE; } else if (!read) { - read = 2000; - memset(data, 255, read); + read = 2; + memset(data, 0, read); } if (read) From 72baa97369618698ec649fece8629d12afae46de Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 21 Sep 2012 18:04:41 +0000 Subject: [PATCH 032/512] Condense the humanized FS version string Old: FreeSWITCH Version 1.3.0+git~20120916T192130Z~3b5aa066c7 (1.3.0; git at commit 3b5aa066c7 on Sun, 16 Sep 2012 19:21:30 Z) New: FreeSWITCH Version 1.3.0+git~20120916T192130Z~3b5aa066c7 (git 3b5aa06 2012-09-16 19:21:30Z) --- build/print_git_revision.c | 10 +++++----- src/include/switch_version.h.cmake | 2 +- src/include/switch_version.h.template | 2 +- src/mod/applications/mod_commands/mod_commands.c | 2 +- src/switch.c | 2 +- src/switch_core.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/print_git_revision.c b/build/print_git_revision.c index 0f8e680b37..974ba6ca3a 100644 --- a/build/print_git_revision.c +++ b/build/print_git_revision.c @@ -69,15 +69,15 @@ static int print_human_version(void) { if ((sys1(xdate,sizeof(xdate),"git log -n1 --format='%ct' HEAD"))) return 1; xdate_t=(time_t)atoi(xdate); if (!(xdate_tm=gmtime(&xdate_t))) return 1; - strftime(xfdate,sizeof(xfdate),"%a, %d %b %Y %H:%M:%S Z",xdate_tm); - if ((sys1(xcommit,sizeof(xcommit),"git rev-list -n1 --abbrev=10 --abbrev-commit HEAD"))) + strftime(xfdate,sizeof(xfdate),"%Y-%m-%d %H:%M:%SZ",xdate_tm); + if ((sys1(xcommit,sizeof(xcommit),"git rev-list -n1 --abbrev=7 --abbrev-commit HEAD"))) return 1; - snprintf(xver,sizeof(xver),"; git at commit %s on %s",xcommit,xfdate); + snprintf(xver,sizeof(xver),"git %s %s",xcommit,xfdate); if (show_unclean && (sys(NULL,0,"git diff-index --quiet HEAD"))) { char buf[256], now[256]; time_t now_t=time(NULL); struct tm *now_tm; if (!(now_tm=gmtime(&now_t))) return 1; - strftime(now,sizeof(now),"%a, %d %b %Y %H:%M:%S Z",now_tm); - snprintf(buf,sizeof(buf),"%s; unclean git build on %s",xver,now); + strftime(now,sizeof(now),"%Y-%m-%d %H:%M:%SZ",now_tm); + snprintf(buf,sizeof(buf),"%s unclean %s",xver,now); strncpy(xver,buf,sizeof(xver)); } printf("%s\n",xver); diff --git a/src/include/switch_version.h.cmake b/src/include/switch_version.h.cmake index c722c2221d..6e7f2036e6 100644 --- a/src/include/switch_version.h.cmake +++ b/src/include/switch_version.h.cmake @@ -43,7 +43,7 @@ extern "C" { #define SWITCH_VERSION_REVISION "@Project_WC_REVISION@" #define SWITCH_VERSION_REVISION_HUMAN "@Project_WC_REVISION@" #define SWITCH_VERSION_FULL SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO SWITCH_VERSION_REVISION -#define SWITCH_VERSION_FULL_HUMAN SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO SWITCH_VERSION_REVISION_HUMAN +#define SWITCH_VERSION_FULL_HUMAN SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO " " SWITCH_VERSION_REVISION_HUMAN #ifdef __cplusplus } diff --git a/src/include/switch_version.h.template b/src/include/switch_version.h.template index dfec6e091e..2e253dc69f 100644 --- a/src/include/switch_version.h.template +++ b/src/include/switch_version.h.template @@ -43,7 +43,7 @@ extern "C" { #define SWITCH_VERSION_REVISION "@SWITCH_VERSION_REVISION@" #define SWITCH_VERSION_REVISION_HUMAN "@SWITCH_VERSION_REVISION_HUMAN@" #define SWITCH_VERSION_FULL SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO SWITCH_VERSION_REVISION -#define SWITCH_VERSION_FULL_HUMAN SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO SWITCH_VERSION_REVISION_HUMAN +#define SWITCH_VERSION_FULL_HUMAN SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO " " SWITCH_VERSION_REVISION_HUMAN #ifdef __cplusplus } diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 0a6c1d08ce..d823af7194 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -286,7 +286,7 @@ SWITCH_STANDARD_API(shutdown_function) SWITCH_STANDARD_API(version_function) { - stream->write_function(stream, "FreeSWITCH Version %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_FULL_HUMAN); + stream->write_function(stream, "FreeSWITCH Version %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN); return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch.c b/src/switch.c index e1b602356e..4f8678a97f 100644 --- a/src/switch.c +++ b/src/switch.c @@ -577,7 +577,7 @@ int main(int argc, char *argv[]) } else if (!strcmp(local_argv[x], "-version")) { - fprintf(stdout, "FreeSWITCH version: %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_FULL_HUMAN); + fprintf(stdout, "FreeSWITCH version: %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN); exit(EXIT_SUCCESS); } #endif diff --git a/src/switch_core.c b/src/switch_core.c index 2a9bec7dee..ec313ea2fb 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2013,7 +2013,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nFreeSWITCH Version %s (%s) Started.\nMax Sessions[%u]\nSession Rate[%d]\nSQL [%s]\n", - SWITCH_VERSION_FULL, SWITCH_VERSION_FULL_HUMAN, + SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN, switch_core_session_limit(0), switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); From d98bb16b3dbcd30a8cb22806ec43ef4dbee2794f Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 21 Sep 2012 18:22:48 +0000 Subject: [PATCH 033/512] debian: Ensure date is calculated in UTC --- debian/util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/util.sh b/debian/util.sh index b270dbd2f8..b15d918378 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -140,7 +140,7 @@ get_last_release_ver () { get_nightly_version () { local commit="$(git rev-list -n1 --abbrev=10 --abbrev-commit HEAD)" - echo "$(get_last_release_ver)+git~$(date +%Y%m%dT%H%M%SZ)~$commit" + echo "$(get_last_release_ver)+git~$(date -u +%Y%m%dT%H%M%SZ)~$commit" } create_orig () { From 5fd7643ab125d20b2268371373cf2444deb8a712 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 07:47:57 +0000 Subject: [PATCH 034/512] debian: style --- debian/util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/util.sh b/debian/util.sh index b15d918378..717a78364e 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -140,7 +140,7 @@ get_last_release_ver () { get_nightly_version () { local commit="$(git rev-list -n1 --abbrev=10 --abbrev-commit HEAD)" - echo "$(get_last_release_ver)+git~$(date -u +%Y%m%dT%H%M%SZ)~$commit" + echo "$(get_last_release_ver)+git~$(date -u '+%Y%m%dT%H%M%SZ')~$commit" } create_orig () { From 53c24a93e08ab9db9b7514c6a0bb17cc4e8e32d5 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 21 Sep 2012 18:27:13 +0000 Subject: [PATCH 035/512] debian: Add support for humanized version string --- build/set-fs-version.sh | 3 ++- debian/util.sh | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/build/set-fs-version.sh b/build/set-fs-version.sh index 6743b58b5f..acac71db60 100755 --- a/build/set-fs-version.sh +++ b/build/set-fs-version.sh @@ -8,9 +8,10 @@ sdir="." check_pwd check_input_ver_build $@ in_ver="$1" +in_hrev="$2" if [ "$in_ver" = "auto" ]; then in_ver="$(cat build/next-release.txt)" fi eval $(parse_version "$in_ver") -set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev" +set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev" "$in_hrev" diff --git a/debian/util.sh b/debian/util.sh index 717a78364e..43278c2920 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -143,11 +143,15 @@ get_nightly_version () { echo "$(get_last_release_ver)+git~$(date -u '+%Y%m%dT%H%M%SZ')~$commit" } +get_nightly_revision_human () { + echo "git $(git rev-list -n1 --abbrev=7 --abbrev-commit HEAD) $(date -u '+%Y-%m-%d %H:%M:%SZ')" +} + create_orig () { { set -e local OPTIND OPTARG - local uver="" bundle_deps=false zl=9e + local uver="" hrev="" bundle_deps=false zl=9e while getopts 'bnv:z:' o "$@"; do case "$o" in b) bundle_deps=true;; @@ -157,8 +161,10 @@ create_orig () { esac done shift $(($OPTIND-1)) - [ -z "$uver" ] || [ "$uver" = "nightly" ] \ - && uver="$(get_nightly_version)" + if [ -z "$uver" ] || [ "$uver" = "nightly" ]; then + uver="$(get_nightly_version)" + hrev="$(get_nightly_revision_human)" + fi local treeish="$1" dver="$(mk_dver "$uver")" local orig="../freeswitch_$dver.orig.tar.xz" [ -n "$treeish" ] || treeish="HEAD" @@ -175,7 +181,7 @@ create_orig () { (cd libs && getlibs) git add -f libs fi - ./build/set-fs-version.sh "$uver" && git add configure.in + ./build/set-fs-version.sh "$uver" "$hrev" && git add configure.in echo "$uver" > .version && git add -f .version git commit --allow-empty -m "nightly v$uver" git archive -v \ From fb2ffbafe29beaf5c2b148e0131307e8569886ef Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 22 Sep 2012 19:05:18 +0000 Subject: [PATCH 036/512] Add configure flags to moderate the ClueCon nags The default remains the same: we show the huge ClueCon nag banner on startup and in fs_cli. However, if you pass --disable-huge-cluecon-nag, no banner will be shown. If you pass --enable-modest-cluecon-nag, a modest text-based ClueCon reminder will be shown instead. --- Makefile.am | 18 ++++++++++-------- build/Makefile.am | 4 ++-- configure.in | 22 +++++++++++++++++++++- libs/esl/fs_cli.c | 10 +++++----- libs/esl/src/include/cc.h | 6 ++++++ src/include/cc.h | 6 ++++++ src/switch_core.c | 6 +++++- 7 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Makefile.am b/Makefile.am index e7f1f799a5..cdf20f55c0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -311,7 +311,7 @@ bin_PROGRAMS = freeswitch fs_cli fs_ivrd tone2wav fs_encode ## 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_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include -include src/include/switch_private.h fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm if HAVE_LIBEDIT @@ -660,13 +660,15 @@ sofia-reconf: cd libs/sofia-sip && ./configure --prefix=$(prefix) --with-pic --with-glib=no --disable-shared cluecon: - @clear - @echo Thank you for updating. This is going to take a while so relax. - @echo Now would be a good time to register for ClueCon! - @cat cluecon2.tmpl - @echo - @echo http://www.cluecon.com - @sleep 5 + @if $(ENABLE_CLUECON_NAG); then \ + clear; \ + echo "Thank you for updating. This is going to take a while so relax."; \ + echo "Now would be a good time to register for ClueCon!"; \ + cat cluecon2.tmpl; \ + echo; \ + echo "http://www.cluecon.com"; \ + sleep 5; \ + fi current: cluecon update-clean is-scm $(MAKE) update $(MAKE) all diff --git a/build/Makefile.am b/build/Makefile.am index 3feb22157d..fa5a257a5f 100644 --- a/build/Makefile.am +++ b/build/Makefile.am @@ -11,7 +11,7 @@ all: @echo " + http://www.cluecon.com +" @echo " + +" @echo " +-----------------------------------------------+" - @cat ../cluecon2.tmpl + @-$(ENABLE_CLUECON_NAG) && cat ../cluecon2.tmpl install: @echo " +---------- FreeSWITCH install Complete ----------+" @@ -69,7 +69,7 @@ install: @echo " + http://www.cluecon.com +" @echo " + +" @echo " +-------------------------------------------------+" - @cat ../cluecon2.tmpl + @-$(ENABLE_CLUECON_NAG) && cat ../cluecon2.tmpl .PHONY: check dvi html info install-data \ diff --git a/configure.in b/configure.in index 5a97b86ace..926706ed78 100644 --- a/configure.in +++ b/configure.in @@ -330,6 +330,26 @@ if test "x${enable_visibility}" != "xno" ; then fi fi +# Enable ClueCon nag banner (default: on) +AC_ARG_ENABLE(huge-cluecon-nag, +[AC_HELP_STRING([--disable-huge-cluecon-nag],[build without huge ClueCon banners])], +[enable_huge_cluecon_nag="$enableval"],[enable_huge_cluecon_nag="yes"]) + +AC_ARG_ENABLE(modest-cluecon-nag, +[AC_HELP_STRING([--enable-modest-cluecon-nag],[build with modest ClueCon announcements])], +[enable_modest_cluecon_nag="$enableval"],[enable_modest_cluecon_nag="no"]) + +if test "${enable_modest_cluecon_nag}" = "yes"; then + enable_huge_cluecon_nag="no" + AC_DEFINE([SHOW_MODEST_CLUECON_NAG],[1],[Show modest ClueCon nag messages.]) + AC_SUBST([ENABLE_CLUECON_NAG],[false]) +elif test "${enable_huge_cluecon_nag}" = "yes"; then + AC_DEFINE([SHOW_HUGE_CLUECON_NAG],[1],[Show huge ClueCon nag messages.]) + AC_SUBST([ENABLE_CLUECON_NAG],[true]) +else + AC_SUBST([ENABLE_CLUECON_NAG],[false]) +fi + # Enable debugging (default: on) # (rename option if the default is changed) AC_ARG_ENABLE(debug, @@ -1115,7 +1135,7 @@ AC_OUTPUT ## ## Registering for ClueCon ## -if ! test -f noreg ; then +if ! test -f noreg && test "${enable_huge_cluecon_nag}" = "yes" ; then echo "" echo "" echo $ECHO_N "Registering you for ClueCon http://www.cluecon.com $ECHO_C" 1>&6 diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 95629da76e..03d8e351d1 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -931,17 +931,17 @@ static void print_banner(FILE *stream) WriteFile(hStdout, banner, (DWORD) strlen(banner), NULL, NULL); WriteFile(hStdout, cc, (DWORD) strlen(cc), NULL, NULL); SetConsoleTextAttribute(hStdout, wOldColorAttrs); - /* Print the rest info in default colors */ fprintf(stream, "\n%s\n", inf); -#else - fprintf(stream, - "%s%s%s%s%s%s\n%s\n", +#elif SHOW_HUGE_CLUECON_NAG + fprintf(stream, "%s%s%s%s%s%s\n%s\n", ESL_SEQ_DEFAULT_COLOR, ESL_SEQ_FYELLOW, ESL_SEQ_BBLUE, banner, cc, ESL_SEQ_DEFAULT_COLOR, inf); - + fprintf(stream, "%s", output_text_color); +#else + fprintf(stream, "%s%s%s\n%s\n", ESL_SEQ_DEFAULT_COLOR, banner, cc, inf); fprintf(stream, "%s", output_text_color); #endif } diff --git a/libs/esl/src/include/cc.h b/libs/esl/src/include/cc.h index 44666193c6..6387209c6b 100644 --- a/libs/esl/src/include/cc.h +++ b/libs/esl/src/include/cc.h @@ -1,2 +1,8 @@ +#ifdef SHOW_HUGE_CLUECON_NAG const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; +#elif SHOW_MODEST_CLUECON_NAG +const char *cc = "Come to ClueCon '13 August 6-8th, 2013, Chicago, USA\nwww.cluecon.com\n"; +#else +const char *cc = ""; +#endif diff --git a/src/include/cc.h b/src/include/cc.h index 44666193c6..6387209c6b 100644 --- a/src/include/cc.h +++ b/src/include/cc.h @@ -1,2 +1,8 @@ +#ifdef SHOW_HUGE_CLUECON_NAG const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; +#elif SHOW_MODEST_CLUECON_NAG +const char *cc = "Come to ClueCon '13 August 6-8th, 2013, Chicago, USA\nwww.cluecon.com\n"; +#else +const char *cc = ""; +#endif diff --git a/src/switch_core.c b/src/switch_core.c index ec313ea2fb..27e1717916 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2002,12 +2002,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t #ifdef WIN32 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), cc); -#else +#elif SHOW_HUGE_CLUECON_NAG switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", SWITCH_SEQ_DEFAULT_COLOR, SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE, switch_core_banner(), cc, SWITCH_SEQ_DEFAULT_COLOR); +#else + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s\n\n", + SWITCH_SEQ_DEFAULT_COLOR, + switch_core_banner(), cc); #endif From 6f9467992ac8d8435d312a3d78091e66578ab6a6 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 22 Sep 2012 19:07:30 +0000 Subject: [PATCH 037/512] Use the modest ClueCon nag for Debian builds --- debian/rules | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/rules b/debian/rules index cd7934e439..8c9f284341 100755 --- a/debian/rules +++ b/debian/rules @@ -64,6 +64,7 @@ override_dh_auto_clean: --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \ --with-gnu-ld --with-python --with-erlang --with-openssl \ --enable-core-odbc-support --enable-zrtp \ + --enable-modest-cluecon-nag \ --prefix=/usr --localstatedir=/var \ --sysconfdir=/etc/freeswitch \ --with-modinstdir=/usr/lib/freeswitch/mod \ From 59d3823ed25c0173665aff871cfe20f02fcefbf1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 22 Sep 2012 22:46:36 +0000 Subject: [PATCH 038/512] Update .gitignore --- libs/.gitignore | 16 ++++++++++++++++ src/mod/.gitignore | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/libs/.gitignore b/libs/.gitignore index 5b0f00bde8..1bc99bcab9 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -341,6 +341,19 @@ opal /libsndfile/tests/test_wrapper.sh /libsndfile/Win32/Makefile /libsndfile/Win32/Makefile.in +/libwebsockets/Makefile +/libwebsockets/Makefile.in +/libwebsockets/config.h +/libwebsockets/lib/Makefile +/libwebsockets/lib/Makefile.in +/libwebsockets/m4/libtool.m4 +/libwebsockets/m4/ltoptions.m4 +/libwebsockets/m4/ltsugar.m4 +/libwebsockets/m4/ltversion.m4 +/libwebsockets/m4/lt~obsolete.m4 +/libwebsockets/stamp-h1 +/libwebsockets/test-server/Makefile +/libwebsockets/test-server/Makefile.in /mongo-cxx-driver-v*/ /mpg123/ /openldap-*/ @@ -678,6 +691,9 @@ opal /srtp/Makefile.in /srtp/test/Makefile /srtp/test/Makefile.in +/tiff-*/build/Makefile +/tiff-*/build/Makefile.in +/tiff-*/tools/tiffcrop /tiff-*/contrib/acorn/Makefile /tiff-*/contrib/acorn/Makefile.in /tiff-*/contrib/addtiffo/addtiffo diff --git a/src/mod/.gitignore b/src/mod/.gitignore index af97a2c162..1aa253520e 100644 --- a/src/mod/.gitignore +++ b/src/mod/.gitignore @@ -16,6 +16,7 @@ /applications/mod_fsv/Makefile /applications/mod_httapi/Makefile /applications/mod_limit/Makefile +/applications/mod_random/Makefile /applications/mod_sms/Makefile /applications/mod_spandsp/Makefile /applications/mod_spandsp/Makefile.in @@ -29,6 +30,8 @@ /asr_tts/mod_unimrcp/Makefile.in /asr_tts/mod_unimrcp/mod_unimrcp.log /asr_tts/mod_flite/*/*/mod_flite_manifest.rc +/codecs/mod_skel_codec/Makefile +/codecs/mod_vp8/Makefile /dialplans/mod_dialplan_asterisk/Makefile /dialplans/mod_dialplan_xml/Makefile /endpoints/mod_portaudio/Makefile @@ -66,6 +69,7 @@ /loggers/mod_logfile/Makefile /loggers/mod_syslog/Makefile /say/mod_say_en/Makefile +/say/mod_say_fa/Makefile /say/mod_say_ja/Makefile /say/mod_say_ru/Makefile /timers/mod_posix_timer/Makefile From 2dc709981b3084a071cc22cd3b56c0ec61296080 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 00:01:29 +0000 Subject: [PATCH 039/512] Add configure option to skip subdirectories If you pass --enable-skip-subdirectories then configure will skip configuring or reconfiguring libraries and simply configure the FS core itself. --- configure.in | 68 ++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/configure.in b/configure.in index 926706ed78..fdef3735ca 100644 --- a/configure.in +++ b/configure.in @@ -330,6 +330,11 @@ if test "x${enable_visibility}" != "xno" ; then fi fi +# Option to skip configuration of subdirectories +AC_ARG_ENABLE(skip-subdirectories, +[AC_HELP_STRING([--enable-skip-subdirectories],[skip configuration of subdirectories])], +[enable_skip_subdirectories="$enableval"],[enable_skip_subdirectories="no"]) + # Enable ClueCon nag banner (default: on) AC_ARG_ENABLE(huge-cluecon-nag, [AC_HELP_STRING([--disable-huge-cluecon-nag],[build without huge ClueCon banners])], @@ -1089,39 +1094,40 @@ ac_configure_args="$ac_configure_args CONFIGURE_CFLAGS='$CFLAGS' CONFIGURE_CXXFL # --localstatedir='$localstatedir' --datadir='$datadir'" # Run configure in all the subdirs -AC_CONFIG_SUBDIRS([libs/srtp]) -AC_CONFIG_SUBDIRS([libs/sqlite]) -if test "$enable_core_libedit_support" = "yes" ; then - AC_CONFIG_SUBDIRS([libs/libedit]) +if ! test "${enable_skip_subdirectories}" = "yes"; then + AC_CONFIG_SUBDIRS([libs/srtp]) + AC_CONFIG_SUBDIRS([libs/sqlite]) + if test "$enable_core_libedit_support" = "yes" ; then + AC_CONFIG_SUBDIRS([libs/libedit]) + fi + AC_CONFIG_SUBDIRS([libs/pcre]) + AC_CONFIG_SUBDIRS([libs/apr]) + AC_CONFIG_SUBDIRS([libs/apr-util]) + AC_CONFIG_SUBDIRS([libs/ilbc]) + AC_CONFIG_SUBDIRS([libs/curl]) + AC_CONFIG_SUBDIRS([libs/iksemel]) + AC_CONFIG_SUBDIRS([libs/js/nsprpub]) + AC_CONFIG_SUBDIRS([libs/js]) + AC_CONFIG_SUBDIRS([libs/libdingaling]) + AC_CONFIG_SUBDIRS([libs/libsndfile]) + AC_CONFIG_SUBDIRS([libs/sofia-sip]) + AC_CONFIG_SUBDIRS([libs/speex]) + AC_CONFIG_SUBDIRS([libs/portaudio]) + AC_CONFIG_SUBDIRS([libs/openzap]) + AC_CONFIG_SUBDIRS([libs/freetdm]) + AC_CONFIG_SUBDIRS([libs/unimrcp]) + AC_CONFIG_SUBDIRS([libs/tiff-4.0.2]) + AC_CONFIG_SUBDIRS([libs/spandsp]) + AC_CONFIG_SUBDIRS([libs/broadvoice]) + AC_CONFIG_SUBDIRS([libs/libg722_1]) + AC_CONFIG_SUBDIRS([libs/silk]) + AC_CONFIG_SUBDIRS([libs/libcodec2]) + if test "x${enable_zrtp}" = "xyes"; then + AC_CONFIG_SUBDIRS([libs/libzrtp/projects/gnu]) + fi + AC_CONFIG_SUBDIRS([libs/libwebsockets]) fi -AC_CONFIG_SUBDIRS([libs/pcre]) -AC_CONFIG_SUBDIRS([libs/apr]) -AC_CONFIG_SUBDIRS([libs/apr-util]) -AC_CONFIG_SUBDIRS([libs/ilbc]) -AC_CONFIG_SUBDIRS([libs/curl]) -AC_CONFIG_SUBDIRS([libs/iksemel]) -AC_CONFIG_SUBDIRS([libs/js/nsprpub]) -AC_CONFIG_SUBDIRS([libs/js]) -AC_CONFIG_SUBDIRS([libs/libdingaling]) -AC_CONFIG_SUBDIRS([libs/libsndfile]) -AC_CONFIG_SUBDIRS([libs/sofia-sip]) -AC_CONFIG_SUBDIRS([libs/speex]) -AC_CONFIG_SUBDIRS([libs/portaudio]) -AC_CONFIG_SUBDIRS([libs/openzap]) -AC_CONFIG_SUBDIRS([libs/freetdm]) -AC_CONFIG_SUBDIRS([libs/unimrcp]) -AC_CONFIG_SUBDIRS([libs/tiff-4.0.2]) -AC_CONFIG_SUBDIRS([libs/spandsp]) -AC_CONFIG_SUBDIRS([libs/broadvoice]) -AC_CONFIG_SUBDIRS([libs/libg722_1]) -AC_CONFIG_SUBDIRS([libs/silk]) -AC_CONFIG_SUBDIRS([libs/libcodec2]) -if test "x${enable_zrtp}" = "xyes"; then - AC_CONFIG_SUBDIRS([libs/libzrtp/projects/gnu]) -fi -AC_CONFIG_SUBDIRS([libs/libwebsockets]) - case $host in *-openbsd*) # libtool won't link static libs against shared ones on OpenBSD unless we tell it not to be stupid From da5b0b38872bd7478ba919957ed061489398fcf0 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 00:33:52 +0000 Subject: [PATCH 040/512] debian: Remove config for mod_fax --- debian/bootstrap.sh | 1 - debian/control-modules | 4 ---- 2 files changed, 5 deletions(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 5ba909b851..736d7a4895 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -8,7 +8,6 @@ fs_description="FreeSWITCH is a scalable open source cross-platform telephony pl mod_build_depends="." supported_distros="squeeze wheezy sid" avoid_mods=( - applications/mod_fax applications/mod_limit applications/mod_mongo applications/mod_mp4 diff --git a/debian/control-modules b/debian/control-modules index a41e858513..b2d15db8b5 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -79,10 +79,6 @@ Module: applications/mod_expr Description: Expr This module adds expr support for expression evaluation. -Module: applications/mod_fax -Description: Fax - This module adds fax support provided by Steve Underwood's SpanDSP. - Module: applications/mod_fifo Description: FIFO This module adds a first-in first-out queue system. From 6f056ef7673bd71636e4cdf0dd727ddba70aeeee Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 03:49:40 +0000 Subject: [PATCH 041/512] debian: Enable mod_oreka --- debian/bootstrap.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 736d7a4895..41c0897f3a 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -11,7 +11,6 @@ avoid_mods=( applications/mod_limit applications/mod_mongo applications/mod_mp4 - applications/mod_oreka applications/mod_osp applications/mod_rad_auth applications/mod_skel From 0b0a916fdead12768c0c574ff66932fcb8450753 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 03:50:09 +0000 Subject: [PATCH 042/512] debian: Enable mod_sonar --- debian/bootstrap.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 41c0897f3a..e91a7609b8 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -14,7 +14,6 @@ avoid_mods=( applications/mod_osp applications/mod_rad_auth applications/mod_skel - applications/mod_sonar applications/mod_soundtouch asr_tts/mod_cepstral asr_tts/mod_flite From 2a665f409477eaa02384bfc05350fe663e0a3e5b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 03:51:15 +0000 Subject: [PATCH 043/512] debian: Enable mod_html5 --- debian/bootstrap.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index e91a7609b8..a4164082a9 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -25,7 +25,6 @@ avoid_mods=( codecs/mod_voipcodecs endpoints/mod_gsmopen endpoints/mod_h323 - endpoints/mod_html5 endpoints/mod_khomp endpoints/mod_opal endpoints/mod_reference From df04ec4b12407cf37ab4920cf1ff3ef0d5e12a5f Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 03:56:19 +0000 Subject: [PATCH 044/512] debian: Enable mod_soundtouch --- debian/bootstrap.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index a4164082a9..69068334c9 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -14,7 +14,6 @@ avoid_mods=( applications/mod_osp applications/mod_rad_auth applications/mod_skel - applications/mod_soundtouch asr_tts/mod_cepstral asr_tts/mod_flite codecs/mod_com_g729 From 882e184a89ac7aa77bee9368dce25b12a3390eab Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 04:34:52 +0000 Subject: [PATCH 045/512] debian: Provide system FLAC/Ogg/Vorbis for mod_sndfile --- debian/control-modules | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control-modules b/debian/control-modules index b2d15db8b5..b9f0a5772a 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -511,6 +511,7 @@ Build-Depends: libogg-dev, libvorbis-dev Module: formats/mod_sndfile Description: mod_sndfile Adds mod_sndfile. +Build-Depends: libflac-dev, libogg-dev, libvorbis-dev Module: formats/mod_tone_stream Description: mod_tone_stream From 447a2c6279a64d435412a651e17d884d6d277c02 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 05:25:40 +0000 Subject: [PATCH 046/512] Improve startup cosmetics --- src/switch_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core.c b/src/switch_core.c index 27e1717916..a82df1a0e6 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2016,7 +2016,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, - "\nFreeSWITCH Version %s (%s) Started.\nMax Sessions[%u]\nSession Rate[%d]\nSQL [%s]\n", + "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN, switch_core_session_limit(0), switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); From 91a8356d4d38d345c3e45201e0d92b0c5364b896 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 06:38:34 +0000 Subject: [PATCH 047/512] debian: Add isac and vp8 to meta-codecs --- debian/bootstrap.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 69068334c9..6b0dc67614 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -332,12 +332,14 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-g723-1 (= \${binary:Version}), freeswitch-mod-g729 (= \${binary:Version}), freeswitch-mod-h26x (= \${binary:Version}), + freeswitch-mod-isac (= \${binary:Version}), freeswitch-mod-mp4v (= \${binary:Version}), freeswitch-mod-opus (= \${binary:Version}), freeswitch-mod-silk (= \${binary:Version}), freeswitch-mod-spandsp (= \${binary:Version}), freeswitch-mod-speex (= \${binary:Version}), - freeswitch-mod-theora (= \${binary:Version}) + freeswitch-mod-theora (= \${binary:Version}), + freeswitch-mod-vp8 (= \${binary:Version}) Suggests: freeswitch-mod-ilbc (= \${binary:Version}), freeswitch-mod-siren (= \${binary:Version}) From b8e3c1d524a4c1eca9830b2067af2fef811e6a36 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 23 Sep 2012 07:33:51 +0000 Subject: [PATCH 048/512] debian: Add meta-sorbet and meta-all --- debian/bootstrap.sh | 201 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 6b0dc67614..9b3e9687fd 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -321,6 +321,207 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch This is a metapackage which depends on the packages needed for running the FreeSWITCH vanilla example configuration. +Package: freeswitch-meta-sorbet +Architecture: any +Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), +Recommends: + freeswitch-init (= \${binary:Version}), + freeswitch-meta-codecs (= \${binary:Version}), + freeswitch-music (= \${binary:Version}), + freeswitch-sounds (= \${binary:Version}), + freeswitch-mod-abstraction (= \${binary:Version}), + freeswitch-mod-avmd (= \${binary:Version}), + freeswitch-mod-blacklist (= \${binary:Version}), + freeswitch-mod-callcenter (= \${binary:Version}), + freeswitch-mod-cidlookup (= \${binary:Version}), + freeswitch-mod-commands (= \${binary:Version}), + freeswitch-mod-conference (= \${binary:Version}), + freeswitch-mod-curl (= \${binary:Version}), + freeswitch-mod-db (= \${binary:Version}), + freeswitch-mod-directory (= \${binary:Version}), + freeswitch-mod-distributor (= \${binary:Version}), + freeswitch-mod-dptools (= \${binary:Version}), + freeswitch-mod-easyroute (= \${binary:Version}), + freeswitch-mod-enum (= \${binary:Version}), + freeswitch-mod-esf (= \${binary:Version}), + freeswitch-mod-esl (= \${binary:Version}), + freeswitch-mod-expr (= \${binary:Version}), + freeswitch-mod-fifo (= \${binary:Version}), + freeswitch-mod-fsk (= \${binary:Version}), + freeswitch-mod-fsv (= \${binary:Version}), + freeswitch-mod-hash (= \${binary:Version}), + freeswitch-mod-httapi (= \${binary:Version}), + freeswitch-mod-http-cache (= \${binary:Version}), + freeswitch-mod-lcr (= \${binary:Version}), + freeswitch-mod-nibblebill (= \${binary:Version}), + freeswitch-mod-oreka (= \${binary:Version}), + freeswitch-mod-random (= \${binary:Version}), + freeswitch-mod-redis (= \${binary:Version}), + freeswitch-mod-rss (= \${binary:Version}), + freeswitch-mod-sms (= \${binary:Version}), + freeswitch-mod-snapshot (= \${binary:Version}), + freeswitch-mod-snom (= \${binary:Version}), + freeswitch-mod-sonar (= \${binary:Version}), + freeswitch-mod-soundtouch (= \${binary:Version}), + freeswitch-mod-spandsp (= \${binary:Version}), + freeswitch-mod-spy (= \${binary:Version}), + freeswitch-mod-stress (= \${binary:Version}), + freeswitch-mod-valet-parking (= \${binary:Version}), + freeswitch-mod-vmd (= \${binary:Version}), + freeswitch-mod-voicemail (= \${binary:Version}), + freeswitch-mod-voicemail-ivr (= \${binary:Version}), + freeswitch-mod-pocketsphinx (= \${binary:Version}), + freeswitch-mod-tts-commandline (= \${binary:Version}), + freeswitch-mod-dialplan-xml (= \${binary:Version}), + freeswitch-mod-html5 (= \${binary:Version}), + freeswitch-mod-loopback (= \${binary:Version}), + freeswitch-mod-rtmp (= \${binary:Version}), + freeswitch-mod-skinny (= \${binary:Version}), + freeswitch-mod-sofia (= \${binary:Version}), + freeswitch-mod-cdr-csv (= \${binary:Version}), + freeswitch-mod-cdr-sqlite (= \${binary:Version}), + freeswitch-mod-event-socket (= \${binary:Version}), + freeswitch-mod-json-cdr (= \${binary:Version}), + freeswitch-mod-local-stream (= \${binary:Version}), + freeswitch-mod-native-file (= \${binary:Version}), + freeswitch-mod-shell-stream (= \${binary:Version}), + freeswitch-mod-sndfile (= \${binary:Version}), + freeswitch-mod-tone-stream (= \${binary:Version}), + freeswitch-mod-lua (= \${binary:Version}), + freeswitch-mod-console (= \${binary:Version}), + freeswitch-mod-logfile (= \${binary:Version}), + freeswitch-mod-syslog (= \${binary:Version}), + freeswitch-mod-say-en (= \${binary:Version}), + freeswitch-mod-posix-timer (= \${binary:Version}), + freeswitch-mod-timerfd (= \${binary:Version}), + freeswitch-mod-xml-cdr (= \${binary:Version}), + freeswitch-mod-xml-curl (= \${binary:Version}), +Description: Cross-Platform Scalable Multi-Protocol Soft Switch + $(debian_wrap "${fs_description}") + . + This is a metapackage which recommends most packaged FreeSWITCH + modules except a few which aren't recommended. + +Package: freeswitch-meta-all +Architecture: any +Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), +Recommends: + freeswitch-init (= \${binary:Version}), + freeswitch-meta-codecs (= \${binary:Version}), + freeswitch-music (= \${binary:Version}), + freeswitch-sounds (= \${binary:Version}), + freeswitch-mod-abstraction (= \${binary:Version}), + freeswitch-mod-avmd (= \${binary:Version}), + freeswitch-mod-blacklist (= \${binary:Version}), + freeswitch-mod-callcenter (= \${binary:Version}), + freeswitch-mod-cidlookup (= \${binary:Version}), + freeswitch-mod-cluechoo (= \${binary:Version}), + freeswitch-mod-commands (= \${binary:Version}), + freeswitch-mod-conference (= \${binary:Version}), + freeswitch-mod-curl (= \${binary:Version}), + freeswitch-mod-db (= \${binary:Version}), + freeswitch-mod-directory (= \${binary:Version}), + freeswitch-mod-distributor (= \${binary:Version}), + freeswitch-mod-dptools (= \${binary:Version}), + freeswitch-mod-easyroute (= \${binary:Version}), + freeswitch-mod-enum (= \${binary:Version}), + freeswitch-mod-esf (= \${binary:Version}), + freeswitch-mod-esl (= \${binary:Version}), + freeswitch-mod-expr (= \${binary:Version}), + freeswitch-mod-fifo (= \${binary:Version}), + freeswitch-mod-fsk (= \${binary:Version}), + freeswitch-mod-fsv (= \${binary:Version}), + freeswitch-mod-hash (= \${binary:Version}), + freeswitch-mod-httapi (= \${binary:Version}), + freeswitch-mod-http-cache (= \${binary:Version}), + freeswitch-mod-ladspa (= \${binary:Version}), + freeswitch-mod-lcr (= \${binary:Version}), + freeswitch-mod-memcache (= \${binary:Version}), + freeswitch-mod-nibblebill (= \${binary:Version}), + freeswitch-mod-oreka (= \${binary:Version}), + freeswitch-mod-random (= \${binary:Version}), + freeswitch-mod-redis (= \${binary:Version}), + freeswitch-mod-rss (= \${binary:Version}), + freeswitch-mod-sms (= \${binary:Version}), + freeswitch-mod-snapshot (= \${binary:Version}), + freeswitch-mod-snipe-hunt (= \${binary:Version}), + freeswitch-mod-snom (= \${binary:Version}), + freeswitch-mod-sonar (= \${binary:Version}), + freeswitch-mod-soundtouch (= \${binary:Version}), + freeswitch-mod-spandsp (= \${binary:Version}), + freeswitch-mod-spy (= \${binary:Version}), + freeswitch-mod-stress (= \${binary:Version}), + freeswitch-mod-valet-parking (= \${binary:Version}), + freeswitch-mod-vmd (= \${binary:Version}), + freeswitch-mod-voicemail (= \${binary:Version}), + freeswitch-mod-voicemail-ivr (= \${binary:Version}), + freeswitch-mod-pocketsphinx (= \${binary:Version}), + freeswitch-mod-tts-commandline (= \${binary:Version}), + freeswitch-mod-dialplan-asterisk (= \${binary:Version}), + freeswitch-mod-dialplan-directory (= \${binary:Version}), + freeswitch-mod-dialplan-xml (= \${binary:Version}), + freeswitch-mod-ldap (= \${binary:Version}), + freeswitch-mod-alsa (= \${binary:Version}), + freeswitch-mod-dingaling (= \${binary:Version}), + freeswitch-mod-html5 (= \${binary:Version}), + freeswitch-mod-loopback (= \${binary:Version}), + freeswitch-mod-rtmp (= \${binary:Version}), + freeswitch-mod-skinny (= \${binary:Version}), + freeswitch-mod-sofia (= \${binary:Version}), + freeswitch-mod-cdr-csv (= \${binary:Version}), + freeswitch-mod-cdr-mongodb (= \${binary:Version}), + freeswitch-mod-cdr-pg-csv (= \${binary:Version}), + freeswitch-mod-cdr-sqlite (= \${binary:Version}), + freeswitch-mod-erlang-event (= \${binary:Version}), + freeswitch-mod-event-multicast (= \${binary:Version}), + freeswitch-mod-event-socket (= \${binary:Version}), + freeswitch-mod-event-test (= \${binary:Version}), + freeswitch-mod-event-zmq (= \${binary:Version}), + freeswitch-mod-json-cdr (= \${binary:Version}), + freeswitch-mod-radius-cdr (= \${binary:Version}), + freeswitch-mod-snmp (= \${binary:Version}), + freeswitch-mod-local-stream (= \${binary:Version}), + freeswitch-mod-native-file (= \${binary:Version}), + freeswitch-mod-shell-stream (= \${binary:Version}), + freeswitch-mod-sndfile (= \${binary:Version}), + freeswitch-mod-tone-stream (= \${binary:Version}), + freeswitch-mod-java (= \${binary:Version}), + freeswitch-mod-lua (= \${binary:Version}), + freeswitch-mod-perl (= \${binary:Version}), + freeswitch-mod-python (= \${binary:Version}), + freeswitch-mod-yaml (= \${binary:Version}), + freeswitch-mod-console (= \${binary:Version}), + freeswitch-mod-logfile (= \${binary:Version}), + freeswitch-mod-syslog (= \${binary:Version}), + freeswitch-mod-say-en (= \${binary:Version}), + freeswitch-mod-posix-timer (= \${binary:Version}), + freeswitch-mod-timerfd (= \${binary:Version}), + freeswitch-mod-xml-cdr (= \${binary:Version}), + freeswitch-mod-xml-curl (= \${binary:Version}), + freeswitch-mod-xml-rpc (= \${binary:Version}), + freeswitch-mod-xml-scgi (= \${binary:Version}), +Suggests: + freeswitch-mod-vlc (= \${binary:Version}), + freeswitch-mod-say-de (= \${binary:Version}), + freeswitch-mod-say-es (= \${binary:Version}), + freeswitch-mod-say-fa (= \${binary:Version}), + freeswitch-mod-say-fr (= \${binary:Version}), + freeswitch-mod-say-he (= \${binary:Version}), + freeswitch-mod-say-hr (= \${binary:Version}), + freeswitch-mod-say-hu (= \${binary:Version}), + freeswitch-mod-say-it (= \${binary:Version}), + freeswitch-mod-say-ja (= \${binary:Version}), + freeswitch-mod-say-nl (= \${binary:Version}), + freeswitch-mod-say-pt (= \${binary:Version}), + freeswitch-mod-say-ru (= \${binary:Version}), + freeswitch-mod-say-th (= \${binary:Version}), + freeswitch-mod-say-zh (= \${binary:Version}), +Description: Cross-Platform Scalable Multi-Protocol Soft Switch + $(debian_wrap "${fs_description}") + . + This is a metapackage which recommends or suggests all packaged + FreeSWITCH modules. + Package: freeswitch-meta-codecs Architecture: any Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), From d565fdece5152a252252d4d95813ab0040004907 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 24 Sep 2012 15:35:35 -0400 Subject: [PATCH 049/512] revert 6f9467992ac8d8435d312a3d78091e66578ab6a6 --- debian/rules | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/rules b/debian/rules index 8c9f284341..cd7934e439 100755 --- a/debian/rules +++ b/debian/rules @@ -64,7 +64,6 @@ override_dh_auto_clean: --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \ --with-gnu-ld --with-python --with-erlang --with-openssl \ --enable-core-odbc-support --enable-zrtp \ - --enable-modest-cluecon-nag \ --prefix=/usr --localstatedir=/var \ --sysconfdir=/etc/freeswitch \ --with-modinstdir=/usr/lib/freeswitch/mod \ From 4ff9b2f102ab000f8d04aae01ad108bc7ea600fd Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 24 Sep 2012 15:38:06 -0400 Subject: [PATCH 050/512] revert fb2ffbafe29beaf5c2b148e0131307e8569886ef --- Makefile.am | 18 ++++++++---------- build/Makefile.am | 4 ++-- configure.in | 22 +--------------------- libs/esl/fs_cli.c | 10 +++++----- libs/esl/src/include/cc.h | 6 ------ src/include/cc.h | 6 ------ src/switch_core.c | 6 +----- 7 files changed, 17 insertions(+), 55 deletions(-) diff --git a/Makefile.am b/Makefile.am index cdf20f55c0..e7f1f799a5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -311,7 +311,7 @@ bin_PROGRAMS = freeswitch fs_cli fs_ivrd tone2wav fs_encode ## 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 -include src/include/switch_private.h +fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm if HAVE_LIBEDIT @@ -660,15 +660,13 @@ sofia-reconf: cd libs/sofia-sip && ./configure --prefix=$(prefix) --with-pic --with-glib=no --disable-shared cluecon: - @if $(ENABLE_CLUECON_NAG); then \ - clear; \ - echo "Thank you for updating. This is going to take a while so relax."; \ - echo "Now would be a good time to register for ClueCon!"; \ - cat cluecon2.tmpl; \ - echo; \ - echo "http://www.cluecon.com"; \ - sleep 5; \ - fi + @clear + @echo Thank you for updating. This is going to take a while so relax. + @echo Now would be a good time to register for ClueCon! + @cat cluecon2.tmpl + @echo + @echo http://www.cluecon.com + @sleep 5 current: cluecon update-clean is-scm $(MAKE) update $(MAKE) all diff --git a/build/Makefile.am b/build/Makefile.am index fa5a257a5f..3feb22157d 100644 --- a/build/Makefile.am +++ b/build/Makefile.am @@ -11,7 +11,7 @@ all: @echo " + http://www.cluecon.com +" @echo " + +" @echo " +-----------------------------------------------+" - @-$(ENABLE_CLUECON_NAG) && cat ../cluecon2.tmpl + @cat ../cluecon2.tmpl install: @echo " +---------- FreeSWITCH install Complete ----------+" @@ -69,7 +69,7 @@ install: @echo " + http://www.cluecon.com +" @echo " + +" @echo " +-------------------------------------------------+" - @-$(ENABLE_CLUECON_NAG) && cat ../cluecon2.tmpl + @cat ../cluecon2.tmpl .PHONY: check dvi html info install-data \ diff --git a/configure.in b/configure.in index fdef3735ca..9fa01e4aba 100644 --- a/configure.in +++ b/configure.in @@ -335,26 +335,6 @@ AC_ARG_ENABLE(skip-subdirectories, [AC_HELP_STRING([--enable-skip-subdirectories],[skip configuration of subdirectories])], [enable_skip_subdirectories="$enableval"],[enable_skip_subdirectories="no"]) -# Enable ClueCon nag banner (default: on) -AC_ARG_ENABLE(huge-cluecon-nag, -[AC_HELP_STRING([--disable-huge-cluecon-nag],[build without huge ClueCon banners])], -[enable_huge_cluecon_nag="$enableval"],[enable_huge_cluecon_nag="yes"]) - -AC_ARG_ENABLE(modest-cluecon-nag, -[AC_HELP_STRING([--enable-modest-cluecon-nag],[build with modest ClueCon announcements])], -[enable_modest_cluecon_nag="$enableval"],[enable_modest_cluecon_nag="no"]) - -if test "${enable_modest_cluecon_nag}" = "yes"; then - enable_huge_cluecon_nag="no" - AC_DEFINE([SHOW_MODEST_CLUECON_NAG],[1],[Show modest ClueCon nag messages.]) - AC_SUBST([ENABLE_CLUECON_NAG],[false]) -elif test "${enable_huge_cluecon_nag}" = "yes"; then - AC_DEFINE([SHOW_HUGE_CLUECON_NAG],[1],[Show huge ClueCon nag messages.]) - AC_SUBST([ENABLE_CLUECON_NAG],[true]) -else - AC_SUBST([ENABLE_CLUECON_NAG],[false]) -fi - # Enable debugging (default: on) # (rename option if the default is changed) AC_ARG_ENABLE(debug, @@ -1141,7 +1121,7 @@ AC_OUTPUT ## ## Registering for ClueCon ## -if ! test -f noreg && test "${enable_huge_cluecon_nag}" = "yes" ; then +if ! test -f noreg ; then echo "" echo "" echo $ECHO_N "Registering you for ClueCon http://www.cluecon.com $ECHO_C" 1>&6 diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 03d8e351d1..95629da76e 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -931,17 +931,17 @@ static void print_banner(FILE *stream) WriteFile(hStdout, banner, (DWORD) strlen(banner), NULL, NULL); WriteFile(hStdout, cc, (DWORD) strlen(cc), NULL, NULL); SetConsoleTextAttribute(hStdout, wOldColorAttrs); + /* Print the rest info in default colors */ fprintf(stream, "\n%s\n", inf); -#elif SHOW_HUGE_CLUECON_NAG - fprintf(stream, "%s%s%s%s%s%s\n%s\n", +#else + fprintf(stream, + "%s%s%s%s%s%s\n%s\n", ESL_SEQ_DEFAULT_COLOR, ESL_SEQ_FYELLOW, ESL_SEQ_BBLUE, banner, cc, ESL_SEQ_DEFAULT_COLOR, inf); - fprintf(stream, "%s", output_text_color); -#else - fprintf(stream, "%s%s%s\n%s\n", ESL_SEQ_DEFAULT_COLOR, banner, cc, inf); + fprintf(stream, "%s", output_text_color); #endif } diff --git a/libs/esl/src/include/cc.h b/libs/esl/src/include/cc.h index 6387209c6b..44666193c6 100644 --- a/libs/esl/src/include/cc.h +++ b/libs/esl/src/include/cc.h @@ -1,8 +1,2 @@ -#ifdef SHOW_HUGE_CLUECON_NAG const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; -#elif SHOW_MODEST_CLUECON_NAG -const char *cc = "Come to ClueCon '13 August 6-8th, 2013, Chicago, USA\nwww.cluecon.com\n"; -#else -const char *cc = ""; -#endif diff --git a/src/include/cc.h b/src/include/cc.h index 6387209c6b..44666193c6 100644 --- a/src/include/cc.h +++ b/src/include/cc.h @@ -1,8 +1,2 @@ -#ifdef SHOW_HUGE_CLUECON_NAG const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; -#elif SHOW_MODEST_CLUECON_NAG -const char *cc = "Come to ClueCon '13 August 6-8th, 2013, Chicago, USA\nwww.cluecon.com\n"; -#else -const char *cc = ""; -#endif diff --git a/src/switch_core.c b/src/switch_core.c index a82df1a0e6..30b94232c4 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2002,16 +2002,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t #ifdef WIN32 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), cc); -#elif SHOW_HUGE_CLUECON_NAG +#else switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", SWITCH_SEQ_DEFAULT_COLOR, SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE, switch_core_banner(), cc, SWITCH_SEQ_DEFAULT_COLOR); -#else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s\n\n", - SWITCH_SEQ_DEFAULT_COLOR, - switch_core_banner(), cc); #endif From 236bfeeaa3440e157fe7f4a07a16264441ad1f0b Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 24 Sep 2012 15:39:52 -0400 Subject: [PATCH 051/512] revert 2dc709981b3084a071cc22cd3b56c0ec61296080 --- configure.in | 68 ++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/configure.in b/configure.in index 9fa01e4aba..5a97b86ace 100644 --- a/configure.in +++ b/configure.in @@ -330,11 +330,6 @@ if test "x${enable_visibility}" != "xno" ; then fi fi -# Option to skip configuration of subdirectories -AC_ARG_ENABLE(skip-subdirectories, -[AC_HELP_STRING([--enable-skip-subdirectories],[skip configuration of subdirectories])], -[enable_skip_subdirectories="$enableval"],[enable_skip_subdirectories="no"]) - # Enable debugging (default: on) # (rename option if the default is changed) AC_ARG_ENABLE(debug, @@ -1074,40 +1069,39 @@ ac_configure_args="$ac_configure_args CONFIGURE_CFLAGS='$CFLAGS' CONFIGURE_CXXFL # --localstatedir='$localstatedir' --datadir='$datadir'" # Run configure in all the subdirs -if ! test "${enable_skip_subdirectories}" = "yes"; then - AC_CONFIG_SUBDIRS([libs/srtp]) - AC_CONFIG_SUBDIRS([libs/sqlite]) - if test "$enable_core_libedit_support" = "yes" ; then - AC_CONFIG_SUBDIRS([libs/libedit]) - fi - AC_CONFIG_SUBDIRS([libs/pcre]) - AC_CONFIG_SUBDIRS([libs/apr]) - AC_CONFIG_SUBDIRS([libs/apr-util]) - AC_CONFIG_SUBDIRS([libs/ilbc]) - AC_CONFIG_SUBDIRS([libs/curl]) - AC_CONFIG_SUBDIRS([libs/iksemel]) - AC_CONFIG_SUBDIRS([libs/js/nsprpub]) - AC_CONFIG_SUBDIRS([libs/js]) - AC_CONFIG_SUBDIRS([libs/libdingaling]) - AC_CONFIG_SUBDIRS([libs/libsndfile]) - AC_CONFIG_SUBDIRS([libs/sofia-sip]) - AC_CONFIG_SUBDIRS([libs/speex]) - AC_CONFIG_SUBDIRS([libs/portaudio]) - AC_CONFIG_SUBDIRS([libs/openzap]) - AC_CONFIG_SUBDIRS([libs/freetdm]) - AC_CONFIG_SUBDIRS([libs/unimrcp]) - AC_CONFIG_SUBDIRS([libs/tiff-4.0.2]) - AC_CONFIG_SUBDIRS([libs/spandsp]) - AC_CONFIG_SUBDIRS([libs/broadvoice]) - AC_CONFIG_SUBDIRS([libs/libg722_1]) - AC_CONFIG_SUBDIRS([libs/silk]) - AC_CONFIG_SUBDIRS([libs/libcodec2]) - if test "x${enable_zrtp}" = "xyes"; then - AC_CONFIG_SUBDIRS([libs/libzrtp/projects/gnu]) - fi - AC_CONFIG_SUBDIRS([libs/libwebsockets]) +AC_CONFIG_SUBDIRS([libs/srtp]) +AC_CONFIG_SUBDIRS([libs/sqlite]) +if test "$enable_core_libedit_support" = "yes" ; then + AC_CONFIG_SUBDIRS([libs/libedit]) fi +AC_CONFIG_SUBDIRS([libs/pcre]) +AC_CONFIG_SUBDIRS([libs/apr]) +AC_CONFIG_SUBDIRS([libs/apr-util]) +AC_CONFIG_SUBDIRS([libs/ilbc]) +AC_CONFIG_SUBDIRS([libs/curl]) +AC_CONFIG_SUBDIRS([libs/iksemel]) +AC_CONFIG_SUBDIRS([libs/js/nsprpub]) +AC_CONFIG_SUBDIRS([libs/js]) +AC_CONFIG_SUBDIRS([libs/libdingaling]) +AC_CONFIG_SUBDIRS([libs/libsndfile]) +AC_CONFIG_SUBDIRS([libs/sofia-sip]) +AC_CONFIG_SUBDIRS([libs/speex]) +AC_CONFIG_SUBDIRS([libs/portaudio]) +AC_CONFIG_SUBDIRS([libs/openzap]) +AC_CONFIG_SUBDIRS([libs/freetdm]) +AC_CONFIG_SUBDIRS([libs/unimrcp]) +AC_CONFIG_SUBDIRS([libs/tiff-4.0.2]) +AC_CONFIG_SUBDIRS([libs/spandsp]) +AC_CONFIG_SUBDIRS([libs/broadvoice]) +AC_CONFIG_SUBDIRS([libs/libg722_1]) +AC_CONFIG_SUBDIRS([libs/silk]) +AC_CONFIG_SUBDIRS([libs/libcodec2]) +if test "x${enable_zrtp}" = "xyes"; then + AC_CONFIG_SUBDIRS([libs/libzrtp/projects/gnu]) +fi +AC_CONFIG_SUBDIRS([libs/libwebsockets]) + case $host in *-openbsd*) # libtool won't link static libs against shared ones on OpenBSD unless we tell it not to be stupid From daa97613a710c69be11f6ee22864631a69f61946 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Sep 2012 12:28:11 -0500 Subject: [PATCH 052/512] FS-4641 --resolve --- src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c index 7b1cf2a6a9..a50616f708 100644 --- a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c +++ b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c @@ -560,15 +560,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_json_cdr_load) } else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) { globals.enable_cacert_check = 1; } else if (!strcasecmp(var, "ssl-cert-path")) { - globals.ssl_cert_file = val; + globals.ssl_cert_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-key-path")) { - globals.ssl_key_file = val; + globals.ssl_key_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-key-password")) { - globals.ssl_key_password = val; + globals.ssl_key_password = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-version")) { - globals.ssl_version = val; + globals.ssl_version = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-cacert-file")) { - globals.ssl_cacert_file = val; + globals.ssl_cacert_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) { globals.enable_ssl_verifyhost = 1; } else if (!strcasecmp(var, "auth-scheme")) { From f8760a1fa890352452439d428602caac4849b0cb Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 24 Sep 2012 16:58:31 -0500 Subject: [PATCH 053/512] FS-4641 apply same fix to mod_xml_cdr --- src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 28f4ae2e44..8779caa6f3 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -548,15 +548,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load) } else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) { globals.enable_cacert_check = 1; } else if (!strcasecmp(var, "ssl-cert-path")) { - globals.ssl_cert_file = val; + globals.ssl_cert_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-key-path")) { - globals.ssl_key_file = val; + globals.ssl_key_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-key-password")) { - globals.ssl_key_password = val; + globals.ssl_key_password = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-version")) { - globals.ssl_version = val; + globals.ssl_version = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "ssl-cacert-file")) { - globals.ssl_cacert_file = val; + globals.ssl_cacert_file = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) { globals.enable_ssl_verifyhost = 1; } else if (!strcasecmp(var, "auth-scheme")) { From 03c981bf72ffc17f310220547d4652fd60199426 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Sep 2012 14:59:02 -0500 Subject: [PATCH 054/512] add smaller banner for teeny tiny terminals --- build/cc.sh | 10 ++++++++++ cc.sh | 2 ++ cluecon2_small.tmpl | 10 ++++++++++ cluecon_small.tmpl | 8 ++++++++ libs/esl/fs_cli.c | 39 +++++++++++++++++++++++++++++++++++-- libs/esl/src/include/cc.h | 4 +++- src/include/cc.h | 4 +++- src/switch_core.c | 41 +++++++++++++++++++++++++++++++++++++-- 8 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 build/cc.sh create mode 100644 cluecon2_small.tmpl create mode 100644 cluecon_small.tmpl diff --git a/build/cc.sh b/build/cc.sh new file mode 100644 index 0000000000..2eb7634b13 --- /dev/null +++ b/build/cc.sh @@ -0,0 +1,10 @@ +#!/bin/sh +s=(`stty size`) +c=${s[1]} + + +if [ $c -gt 99 ] ; then + cat ../cluecon2.tmpl +else + cat ../cluecon2_small.tmpl +fi diff --git a/cc.sh b/cc.sh index 85ab418e26..323b877db8 100755 --- a/cc.sh +++ b/cc.sh @@ -1,8 +1,10 @@ cc=`cat cluecon.tmpl | sed 's/\\\\/\\\\\\\\/g' | awk '{printf "%s\\\\n", $0}' ` +cc_s=`cat cluecon_small.tmpl | sed 's/\\\\/\\\\\\\\/g' | awk '{printf "%s\\\\n", $0}' ` cat < src/include/cc.h const char *cc = "$cc"; +const char *cc_s = "$cc_s"; EOF diff --git a/cluecon2_small.tmpl b/cluecon2_small.tmpl new file mode 100644 index 0000000000..7e81f074dc --- /dev/null +++ b/cluecon2_small.tmpl @@ -0,0 +1,10 @@ + +.===============================================================. +| _ | +| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ | +| / __| | | | |/ _ \/ __/ _ \| '_ \ / __/ _ \| '_ ` _ \ | +| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | | +| \___|_|\__,_|\___|\___\___/|_| |_| (_) \___\___/|_| |_| |_| | +| | +.===============================================================. + diff --git a/cluecon_small.tmpl b/cluecon_small.tmpl new file mode 100644 index 0000000000..e6ceb6d837 --- /dev/null +++ b/cluecon_small.tmpl @@ -0,0 +1,8 @@ +.===============================================================. +| _ | +| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ | +| / __| | | | |/ _ \/ __/ _ \| '_ \ / __/ _ \| '_ ` _ \ | +| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | | +| \___|_|\__,_|\___|\___\___/|_| |_| (_) \___\___/|_| |_| |_| | +| | +.===============================================================. diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 95629da76e..bde78f183b 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -116,6 +116,31 @@ static void clear_cli(void) { fflush(stdout); } +static void screen_size(int *x, int *y) +{ + +#ifdef WIN32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + int ret; + + if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) { + if (x) *x = csbi.dwSize.X; + if (y) *y = csbi.dwSize.Y; + } + +#elif TIOCGWINSZ + struct winsize w; + ioctl(0, TIOCGWINSZ, &w); + + if (x) *x = w.ws_col; + if (y) *y = w.ws_row; +#else + if (x) *x = 24; + if (x) *x = 80; +#endif + +} + /* If a fnkey is configured then process the command */ static unsigned char console_fnkey_pressed(int i) { @@ -923,13 +948,19 @@ static const char *inf = "Type /help to see a list of commands\n\n\n"; static void print_banner(FILE *stream) { + int x; + const char *use = NULL; #include + screen_size(&x, NULL); + + use = (x > 100) ? cc : cc_s; + #ifdef WIN32 /* Print banner in yellow with blue background */ SetConsoleTextAttribute(hStdout, ESL_SEQ_FYELLOW | BACKGROUND_BLUE); WriteFile(hStdout, banner, (DWORD) strlen(banner), NULL, NULL); - WriteFile(hStdout, cc, (DWORD) strlen(cc), NULL, NULL); + WriteFile(hStdout, use, (DWORD) strlen(use), NULL, NULL); SetConsoleTextAttribute(hStdout, wOldColorAttrs); /* Print the rest info in default colors */ @@ -940,10 +971,14 @@ static void print_banner(FILE *stream) ESL_SEQ_DEFAULT_COLOR, ESL_SEQ_FYELLOW, ESL_SEQ_BBLUE, banner, - cc, ESL_SEQ_DEFAULT_COLOR, inf); + use, ESL_SEQ_DEFAULT_COLOR, inf); fprintf(stream, "%s", output_text_color); #endif + + if (x < 160) { + fprintf(stream, "\n[This app Best viewed at 160x60 or more..]\n"); + } } static void set_fn_keys(cli_profile_t *profile) diff --git a/libs/esl/src/include/cc.h b/libs/esl/src/include/cc.h index 44666193c6..965aa9cbac 100644 --- a/libs/esl/src/include/cc.h +++ b/libs/esl/src/include/cc.h @@ -1,2 +1,4 @@ -const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; + +const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; +const char *cc_s = ".===============================================================.\n| _ |\n| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.===============================================================.\n"; diff --git a/src/include/cc.h b/src/include/cc.h index 44666193c6..965aa9cbac 100644 --- a/src/include/cc.h +++ b/src/include/cc.h @@ -1,2 +1,4 @@ -const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; + +const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n"; +const char *cc_s = ".===============================================================.\n| _ |\n| ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.===============================================================.\n"; diff --git a/src/switch_core.c b/src/switch_core.c index 30b94232c4..a747a9dc27 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -186,6 +186,31 @@ SWITCH_DECLARE(FILE *) switch_core_get_console(void) return runtime.console; } +SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) +{ + +#ifdef WIN32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + int ret; + + if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) { + if (x) *x = csbi.dwSize.X; + if (y) *y = csbi.dwSize.Y; + } + +#elif TIOCGWINSZ + struct winsize w; + ioctl(0, TIOCGWINSZ, &w); + + if (x) *x = w.ws_col; + if (y) *y = w.ws_row; +#else + if (x) *x = 24; + if (x) *x = 80; +#endif + +} + SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel) { FILE *handle = stdout; @@ -1964,6 +1989,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t { switch_event_t *event; char *cmd; + int x = 0; + const char *use = NULL; #include "cc.h" @@ -2000,14 +2027,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t switch_event_fire(&event); } + switch_core_screen_size(&x, NULL); + + use = (x > 100) ? cc : cc_s; + #ifdef WIN32 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), cc); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use); #else switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", SWITCH_SEQ_DEFAULT_COLOR, SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE, switch_core_banner(), - cc, SWITCH_SEQ_DEFAULT_COLOR); + use, SWITCH_SEQ_DEFAULT_COLOR); + #endif @@ -2017,6 +2049,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t switch_core_session_limit(0), switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); + + if (x < 160) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n"); + } + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); if ((cmd = switch_core_get_variable_dup("api_on_startup"))) { From b9897750854d1ddc68bd256b938078629a5dd178 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Sep 2012 17:07:55 -0500 Subject: [PATCH 055/512] followup for cent5 --- src/switch_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/switch_core.c b/src/switch_core.c index a747a9dc27..7bd11609d3 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -186,6 +186,9 @@ SWITCH_DECLARE(FILE *) switch_core_get_console(void) return runtime.console; } +#ifdef HAVE_SYS_IOCTL_H +#include +#endif SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) { From 614ba049b182dc753b2d0543075da6128e481c99 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Sep 2012 17:53:23 -0500 Subject: [PATCH 056/512] add proto --- src/include/switch_core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index b340078f41..4f26719d32 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -139,6 +139,7 @@ struct switch_core_port_allocator; ///\{ +SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y); SWITCH_DECLARE(void) switch_core_session_sched_heartbeat(switch_core_session_t *session, uint32_t seconds); SWITCH_DECLARE(void) switch_core_session_unsched_heartbeat(switch_core_session_t *session); From f997cc25d1bb2d370f119213acb2f710fed17281 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 24 Sep 2012 22:35:08 -0500 Subject: [PATCH 057/512] remove trailing backlash from windows temp paths - mostly cosmetic --- src/switch_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_core.c b/src/switch_core.c index 7bd11609d3..20dfd9b411 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -661,6 +661,7 @@ SWITCH_DECLARE(void) switch_core_set_globals(void) #else #ifdef WIN32 GetTempPath(dwBufSize, lpPathBuffer); + lpPathBuffer[strlen(lpPathBuffer)-1] = 0; switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer); #else switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp"); From 176d60beb337d91618942ee45afef8f1538e92fa Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 25 Sep 2012 08:55:44 -0500 Subject: [PATCH 058/512] FS-4645 does this help --- src/switch_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core.c b/src/switch_core.c index 20dfd9b411..86804f09b7 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -201,7 +201,7 @@ SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) if (y) *y = csbi.dwSize.Y; } -#elif TIOCGWINSZ +#elif defined(TIOCGWINSZ) struct winsize w; ioctl(0, TIOCGWINSZ, &w); From ee50ed23ab213b24946ecf1ae87ba79a767f0487 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 25 Sep 2012 14:19:00 -0400 Subject: [PATCH 059/512] FS-4645: --resolve fix build error in fs_cli --- libs/esl/fs_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index bde78f183b..8b9a065a60 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -128,7 +128,7 @@ static void screen_size(int *x, int *y) if (y) *y = csbi.dwSize.Y; } -#elif TIOCGWINSZ +#elif defined(TIOCGWINSZ) struct winsize w; ioctl(0, TIOCGWINSZ, &w); From 0fe6aa4d0a1c8ab58430c7b4c2530fe80c9bb69b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 25 Sep 2012 16:08:45 -0500 Subject: [PATCH 060/512] switch another file parsing function to use buffered read --- src/switch_console.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/switch_console.c b/src/switch_console.c index 41d308e339..3945baec7c 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -203,7 +203,7 @@ SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_stream_write(switch_stream SWITCH_DECLARE(switch_status_t) switch_stream_write_file_contents(switch_stream_handle_t *stream, const char *path) { char *dpath = NULL; - int fd; + FILE *fd = NULL; switch_status_t status = SWITCH_STATUS_FALSE; if (!switch_is_file_path(path)) { @@ -211,12 +211,14 @@ SWITCH_DECLARE(switch_status_t) switch_stream_write_file_contents(switch_stream_ path = dpath; } - if ((fd = open(path, O_RDONLY)) > -1) { - char buf[2048] = { 0 }; - while (switch_fd_read_line(fd, buf, sizeof(buf))) { - stream->write_function(stream, "%s", buf); + if ((fd = fopen(path, "r"))) { + char *line_buf = NULL; + switch_size_t llen = 0; + + while (switch_fp_read_dline(fd, &line_buf, &llen)) { + stream->write_function(stream, "%s", line_buf); } - close(fd); + fclose(fd); status = SWITCH_STATUS_SUCCESS; } @@ -246,7 +248,7 @@ SWITCH_DECLARE(char *) switch_console_expand_alias(char *cmd, char *arg) return NULL; } - if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); return NULL; } @@ -682,7 +684,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch #endif #endif - if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); return CC_ERROR; } @@ -1774,7 +1776,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) SWITCH_STANDARD_STREAM(mystream); - if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); free(mystream.data); free(mydata); @@ -1857,7 +1859,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string) switch_cache_db_handle_t *db = NULL; char *sql = NULL; - if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); free(mydata); return SWITCH_STATUS_FALSE; From dbf5153fb7d1b4d5a09f8c139b3d288c17656e74 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 25 Sep 2012 16:12:23 -0500 Subject: [PATCH 061/512] speed improvements: change scheduler to SCHED_FIFO, Disable realtime throttling, use in-memory db for sqlite core channels table (set core-db-name to 'core' in switch.conf.xml for previous behaviour of using the core sqlite file, now only aliases will be in the persistant db) --- src/include/switch_core.h | 3 +++ src/switch_core.c | 22 ++++++++++++++++++- src/switch_core_sqldb.c | 45 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 4f26719d32..507f18a166 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2303,6 +2303,9 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); #define switch_core_recovery_db_handle(_a) _switch_core_recovery_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) +SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); +#define switch_core_persist_db_handle(_a) _switch_core_persist_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) + SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_handle_t *db, const char *test_sql, const char *drop_sql, const char *reactive_sql); SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries); diff --git a/src/switch_core.c b/src/switch_core.c index 86804f09b7..257c37a646 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -731,16 +731,36 @@ SWITCH_DECLARE(int32_t) set_realtime_priority(void) * Try to use a round-robin scheduler * with a fallback if that does not work */ + int fd; + const char *rt = "/proc/sys/kernel/sched_rt_runtime_us"; + char data[] = "-1\n"; struct sched_param sched = { 0 }; sched.sched_priority = 1; - if (sched_setscheduler(0, SCHED_RR, &sched)) { + if (sched_setscheduler(0, SCHED_FIFO, &sched)) { sched.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, &sched)) { return -1; } } + + if ((fd = open(rt, O_WRONLY)) > 0) { + int r; + + if (!(r = write(fd, data, sizeof(data)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Disablling RT limits [%s][%d]\n", rt, r); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Disabling RT throttling.\n"); + } + close(fd); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening %s\n", rt); + } + + #endif + + #ifdef HAVE_SETPRIORITY /* * setpriority() works on FreeBSD (6.2), nice() doesn't diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 200ed3507e..b0f52b6150 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -176,7 +176,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user } -#define SWITCH_CORE_DB "core" +#define SWITCH_CORE_DB "file:scoreboard?mode=memory&cache=shared" /*! \brief Open the default system database */ @@ -218,6 +218,49 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t return r; } +#define SWITCH_CORE_PERSIST_DB "core" +/*! + \brief Open the default system database +*/ +SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) +{ + switch_cache_db_connection_options_t options = { {0} }; + switch_status_t r; + + if (!sql_manager.manage) { + return SWITCH_STATUS_FALSE; + } + + if (zstr(runtime.odbc_dsn)) { + if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) { + return SWITCH_STATUS_FALSE; + } + + if (runtime.dbname) { + options.core_db_options.db_path = runtime.dbname; + } else { + options.core_db_options.db_path = SWITCH_CORE_PERSIST_DB; + } + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); + + } else { + options.odbc_options.dsn = runtime.odbc_dsn; + options.odbc_options.user = runtime.odbc_user; + options.odbc_options.pass = runtime.odbc_pass; + + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + } + + /* I *think* we can do without this now, if not let me know + if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { + (*dbh)->io_mutex = sql_manager.io_mutex; + } + */ + + return r; +} + + #define SWITCH_CORE_RECOVERY_DB "core_recovery" SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { From 817439d76a5fc268a71efc32d0b6607f8bcd610d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 25 Sep 2012 16:12:51 -0500 Subject: [PATCH 062/512] check for SCHED_FIFO in configure --- configure.in | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 5a97b86ace..92a88048fd 100644 --- a/configure.in +++ b/configure.in @@ -532,6 +532,12 @@ AC_CHECK_DECL([SCHED_RR], #include #endif]) +AC_CHECK_DECL([SCHED_FIFO], + [AC_DEFINE([HAVE_SCHED_FIFO],[1],[SCHED_FIFO constant for sched_setscheduler])],, + [#ifdef HAVE_SCHED_H + #include + #endif]) + # # use mlockall only on linux (for now; if available) # @@ -572,7 +578,6 @@ if test "x${ac_cv_func_sched_setscheduler}" = "xyes" -a \ then AC_DEFINE([USE_SCHED_SETSCHEDULER],[1],[Enable round-robin scheduler using sched_setscheduler]) fi - # # xmlrpc-c checks # From b15468d1aaf74fa80573354f2d47a522faa7a08e Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 26 Sep 2012 08:11:08 -0500 Subject: [PATCH 063/512] OPENZAP-192 --resolve --- 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 d99561566c..932ce30aa7 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -4735,7 +4735,7 @@ static void print_core_usage(ftdm_stream_handle_t *stream) static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val) { - int i; + ftdm_size_t i; for (i = 0; i < array_size; i++) { if (!strcasecmp(val_str_table[i].str, str)) { return val_str_table[i].val; @@ -4746,7 +4746,7 @@ static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str) { - int i; + ftdm_size_t i; for (i = 0; i < array_size; i++) { if (val_str_table[i].val == val) { return val_str_table[i].str; From d77dfdbbf2c963125f21d087b764112ac7b7c7a0 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 26 Sep 2012 08:16:28 -0500 Subject: [PATCH 064/512] FS-4219 --resolve windows revision display human thanks Peter --- libs/win32/util.vbs | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/libs/win32/util.vbs b/libs/win32/util.vbs index 2c35dfdcb7..0ce107c4c4 100644 --- a/libs/win32/util.vbs +++ b/libs/win32/util.vbs @@ -314,31 +314,6 @@ Function GetTimeUTC() End Function -Function GetWeekDay(DateTime) - - DayOfWeek = DatePart("w", DateTime) - - Select Case DayOfWeek - Case 1 GetWeekDay = "Sun" - Case 2 GetWeekDay = "Mon" - Case 3 GetWeekDay = "Tue" - Case 4 GetWeekDay = "Wed" - Case 5 GetWeekDay = "Thu" - Case 6 GetWeekDay = "Fri" - Case 7 GetWeekDay = "Sat" - End Select - -End Function - -Function GetMonthName(DateTime) - - Val = MonthName(Month(DateTime), True) - Val = UCase(Left(Val, 1)) & Mid(Val, 2, 4) - - GetMonthName = Val - -End Function - Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest) Dim oExec @@ -364,7 +339,7 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest) If IsNumeric(strFromProc) Then lastChangedDateTime = DateAdd("s", strFromProc, "01/01/1970 00:00:00") strLastCommit = YEAR(lastChangedDateTime) & Pd(Month(lastChangedDateTime), 2) & Pd(DAY(lastChangedDateTime), 2) & "T" & Pd(Hour(lastChangedDateTime), 2) & Pd(Minute(lastChangedDateTime), 2) & Pd(Second(lastChangedDateTime), 2) & "Z" - strLastCommitHuman = GetWeekDay(lastChangedDateTime) & ", " & Pd(DAY(lastChangedDateTime), 2) & " " & GetMonthName(lastChangedDateTime) & " " & YEAR(lastChangedDateTime) & " " & Pd(Hour(lastChangedDateTime), 2) & ":" & Pd(Minute(lastChangedDateTime), 2) & ":" & Pd(Second(lastChangedDateTime), 2) & " Z" + strLastCommitHuman = YEAR(lastChangedDateTime) & "-" & Pd(Month(lastChangedDateTime), 2) & "-" & Pd(DAY(lastChangedDateTime), 2) & " " & Pd(Hour(lastChangedDateTime), 2) & ":" & Pd(Minute(lastChangedDateTime), 2) & ":" & Pd(Second(lastChangedDateTime), 2) & "Z" Else strLastCommit = "" strLastCommitHuman = "" @@ -372,17 +347,19 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest) 'Get revision hash strRevision = ExecAndGetResult(tmpFolder, VersionDir, "git rev-list -n1 --abbrev=10 --abbrev-commit HEAD") + strRevisionHuman = ExecAndGetResult(tmpFolder, VersionDir, "git rev-list -n1 --abbrev=7 --abbrev-commit HEAD") - If strLastCommit <> "" And strLastCommitHuman <> "" And strRevision <> "" Then + If strLastCommit <> "" And strLastCommitHuman <> "" And strRevision <> "" And strRevisionHuman <> "" Then 'Bild version string strGitVer = "+git~" & strLastCommit & "~" & strRevision - strVerHuman = strVerRev & "; git at commit " & strRevision & " on " & strLastCommitHuman + strVerHuman = "git " & strRevisionHuman & " " & strLastCommitHuman 'Check for local changes, if found, append to git revision string If ShowUnclean Then If ExecAndGetExitCode(tmpFolder, VersionDir, "git diff-index --quiet HEAD") <> 0 Then lastChangedDateTime = GetTimeUTC() strGitVer = strGitVer & "+unclean~" & YEAR(lastChangedDateTime) & Pd(Month(lastChangedDateTime), 2) & Pd(DAY(lastChangedDateTime), 2) & "T" & Pd(Hour(lastChangedDateTime), 2) & Pd(Minute(lastChangedDateTime), 2) & Pd(Second(lastChangedDateTime), 2) & "Z" + strVerHuman = strVerHuman & " unclean " & YEAR(lastChangedDateTime) & "-" & Pd(Month(lastChangedDateTime), 2) & "-" & Pd(DAY(lastChangedDateTime), 2) & " " & Pd(Hour(lastChangedDateTime), 2) & ":" & Pd(Minute(lastChangedDateTime), 2) & ":" & Pd(Second(lastChangedDateTime), 2) & "Z" End If End If Else @@ -393,7 +370,7 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest) VERSION=VERSION & strGitVer sLastVersion = "" - Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII) + Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, True, OpenAsASCII) If Not sLastFile.atEndOfStream Then sLastVersion = sLastFile.ReadLine() End If From e50f7a92e9a9c215022ca747747c56201c105e2e Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 26 Sep 2012 16:53:07 +0200 Subject: [PATCH 065/512] gsmopen: FS-4652 , compilation failed with Mobigator --- .../mod_gsmopen/gsmopen_protocol.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c index 6834a1d880..00c83d0640 100644 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c +++ b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/gsmopen_protocol.c @@ -1961,7 +1961,7 @@ int gsmopen_serial_read_AT(private_t * tech_pvt, int look_for_ack, int timeout_u if (tech_pvt->reading_sms_msg > 1 && at_ack == -1) { int c; char sms_body[16000]; - int err = 0; + //int err = 0; memset(sms_body, '\0', sizeof(sms_body)); if (strncmp(tech_pvt->line_array.result[i], "+CMGR", 5) == 0) { /* we are reading the "header" of an SMS */ @@ -2005,10 +2005,10 @@ int gsmopen_serial_read_AT(private_t * tech_pvt, int look_for_ack, int timeout_u if (which_field == 1) { //FIXME why this? err = ucs2_to_utf8(tech_pvt, content, content2, sizeof(content2)); //err = ucs2_to_utf8(tech_pvt, content, content2, sizeof(content2)); - err = 0; + //err = 0; strncpy(content2, content, sizeof(content2)); } else { - err = 0; + //err = 0; strncpy(content2, content, sizeof(content2)); } DEBUGA_GSMOPEN("%d content2=%s\n", GSMOPEN_P_LOG, which_field, content2); @@ -3287,7 +3287,7 @@ int alsa_write(private_t * tech_pvt, short *data, int datalen) static char silencebuf[8000]; static int sizpos = 0; int len = sizpos; - int pos; + //int pos; int res = 0; time_t now_timestamp; /* size_t frames = 0; */ @@ -3313,7 +3313,7 @@ int alsa_write(private_t * tech_pvt, short *data, int datalen) memcpy(sizbuf + sizpos, data, datalen); memset(data, 255, datalen); len += datalen; - pos = 0; + //pos = 0; #ifdef ALSA_MONITOR From 0fc0b999505d1a4664ee566cf28696f597a20f79 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 26 Sep 2012 08:01:25 -0500 Subject: [PATCH 066/512] FS-4654 --resolve --- src/switch_console.c | 4 ++-- src/switch_core_sqldb.c | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/switch_console.c b/src/switch_console.c index 3945baec7c..d461333860 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -684,7 +684,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch #endif #endif - if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); return CC_ERROR; } @@ -1776,7 +1776,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) SWITCH_STANDARD_STREAM(mystream); - if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); free(mystream.data); free(mydata); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b0f52b6150..5a76d0e1ae 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2409,9 +2409,14 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ break; } + { + switch_cache_db_handle_t *db = NULL; + switch_core_persist_db_handle(&db) + switch_cache_db_test_reactive(db, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); + switch_cache_db_release_db_handle(&db); + } switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", "DROP TABLE registrations", create_registrations_sql); From 8075b01569e402ec9eb8d5c7df4214f012ce0a8a Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Wed, 26 Sep 2012 17:19:15 +0200 Subject: [PATCH 067/512] Fix error in switch_core_screen_size() and screen_size() fallback code. Signed-off-by: Stefan Knoblich --- libs/esl/fs_cli.c | 2 +- src/switch_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 8b9a065a60..80388db3a4 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -135,8 +135,8 @@ static void screen_size(int *x, int *y) if (x) *x = w.ws_col; if (y) *y = w.ws_row; #else - if (x) *x = 24; if (x) *x = 80; + if (y) *y = 24; #endif } diff --git a/src/switch_core.c b/src/switch_core.c index 257c37a646..6cce356061 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -208,8 +208,8 @@ SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) if (x) *x = w.ws_col; if (y) *y = w.ws_row; #else - if (x) *x = 24; if (x) *x = 80; + if (y) *y = 24; #endif } From 507de0a7e514cee62c21526e89dfd2b70a7e228c Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 26 Sep 2012 17:23:43 +0200 Subject: [PATCH 068/512] gsmopen: FS-4652 , compilation failed with Mobigator --- .../mod_gsmopen/mod_gsmopen.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c index fdfbca74b8..40c6f51801 100644 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c +++ b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c @@ -1392,9 +1392,9 @@ static switch_status_t load_config(int reload_type) const char *dialplan = "XML"; const char *destination = "5000"; const char *controldevice_name = "/dev/ttyACM0"; - char *digit_timeout = NULL; - char *max_digits = NULL; - char *hotline = NULL; + char *digit_timeout; + char *max_digits; + char *hotline; char *dial_regex = NULL; char *hold_music = NULL; char *fail_dial_regex = NULL; @@ -1469,10 +1469,10 @@ static switch_status_t load_config(int reload_type) #else const char *no_sound = "1"; #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) - const char *portaudiocindex = "1"; - const char *portaudiopindex = "1"; - const char *speexecho = "1"; - const char *speexpreprocess = "1"; + const char *portaudiocindex; + const char *portaudiopindex; + const char *speexecho; + const char *speexpreprocess; uint32_t interface_id = 0; #ifdef WIN32 @@ -2869,7 +2869,7 @@ SWITCH_STANDARD_API(gsmopen_boost_audio_function) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; - private_t *tech_pvt = NULL; + private_t *tech_pvt; if (!zstr(cmd) && (mycmd = strdup(cmd))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); From 3df5c5f2f4efa253067946f62e26c46dff596574 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Wed, 26 Sep 2012 17:44:39 +0200 Subject: [PATCH 069/512] FreeSWITCH: Add missing semicolon Signed-off-by: Stefan Knoblich --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 5a76d0e1ae..d77b432c90 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2411,7 +2411,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ { switch_cache_db_handle_t *db = NULL; - switch_core_persist_db_handle(&db) + switch_core_persist_db_handle(&db); switch_cache_db_test_reactive(db, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); switch_cache_db_release_db_handle(&db); } From f102f7b4c4d3f8e86be80ca7acd8b017a2636f46 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 26 Sep 2012 18:55:54 +0200 Subject: [PATCH 070/512] gsmopen: FS-4652 , compilation failed with Mobigator --- .../alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c index 40c6f51801..2841d2146a 100644 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c +++ b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c @@ -1469,10 +1469,12 @@ static switch_status_t load_config(int reload_type) #else const char *no_sound = "1"; #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO) +#ifdef GSMOPEN_PORTAUDIO const char *portaudiocindex; const char *portaudiopindex; const char *speexecho; const char *speexpreprocess; +#endif// GSMOPEN_PORTAUDIO uint32_t interface_id = 0; #ifdef WIN32 @@ -1620,6 +1622,7 @@ static switch_status_t load_config(int reload_type) alsacname = val; } else if (!strcasecmp(var, "alsapname")) { alsapname = val; +#ifdef GSMOPEN_PORTAUDIO } else if (!strcasecmp(var, "portaudiocindex")) { portaudiocindex = val; } else if (!strcasecmp(var, "portaudiopindex")) { @@ -1628,6 +1631,7 @@ static switch_status_t load_config(int reload_type) speexecho = val; } else if (!strcasecmp(var, "speexpreprocess")) { speexpreprocess = val; +#endif// GSMOPEN_PORTAUDIO } else if (!strcasecmp(var, "at_early_audio")) { at_early_audio = val; } else if (!strcasecmp(var, "at_after_preinit_pause")) { From ed6f040e702844abf0d2db7bde4fc70143e26a9a Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 26 Sep 2012 19:01:08 +0200 Subject: [PATCH 071/512] gsmopen: FS-4652 , compilation failed with Mobigator --- .../alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c index 2841d2146a..17a34e5c6d 100644 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c +++ b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c @@ -2873,7 +2873,7 @@ SWITCH_STANDARD_API(gsmopen_boost_audio_function) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; - private_t *tech_pvt; + //private_t *tech_pvt; if (!zstr(cmd) && (mycmd = strdup(cmd))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -2887,7 +2887,7 @@ SWITCH_STANDARD_API(gsmopen_boost_audio_function) /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */ if (strlen(globals.GSMOPEN_INTERFACES[i].name) && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) { - tech_pvt = &globals.GSMOPEN_INTERFACES[i]; + //tech_pvt = &globals.GSMOPEN_INTERFACES[i]; stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name); found = 1; break; From d0ddd77cdcf26f6388bdd1631b18cb682fb01504 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 26 Sep 2012 19:15:42 +0200 Subject: [PATCH 072/512] gsmopen: FS-4652 , compilation failed with Mobigator --- .../mod_gsmopen/mod_gsmopen.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c index 17a34e5c6d..5e31e76857 100644 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c +++ b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c @@ -1392,13 +1392,13 @@ static switch_status_t load_config(int reload_type) const char *dialplan = "XML"; const char *destination = "5000"; const char *controldevice_name = "/dev/ttyACM0"; - char *digit_timeout; - char *max_digits; - char *hotline; + //char *digit_timeout; + //char *max_digits; + //char *hotline; char *dial_regex = NULL; char *hold_music = NULL; char *fail_dial_regex = NULL; - const char *enable_callerid = "true"; + const char *enable_callerid ; const char *at_dial_pre_number = "ATD"; @@ -1506,12 +1506,12 @@ static switch_status_t load_config(int reload_type) destination = val; } else if (!strcasecmp(var, "controldevice_name")) { controldevice_name = val; - } else if (!strcasecmp(var, "digit_timeout")) { - digit_timeout = val; - } else if (!strcasecmp(var, "max_digits")) { - max_digits = val; - } else if (!strcasecmp(var, "hotline")) { - hotline = val; + //} else if (!strcasecmp(var, "digit_timeout")) { + //digit_timeout = val; + //} else if (!strcasecmp(var, "max_digits")) { + //max_digits = val; + //} else if (!strcasecmp(var, "hotline")) { + //hotline = val; } else if (!strcasecmp(var, "dial_regex")) { dial_regex = val; } else if (!strcasecmp(var, SWITCH_HOLD_MUSIC_VARIABLE)) { From a1d727cab65b779ec5f9df8c8eec6cdf8ac04c64 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Wed, 26 Sep 2012 19:20:27 +0200 Subject: [PATCH 073/512] gsmopen: FS-4652 , compilation failed with Mobigator --- .../alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c index 5e31e76857..fc41a4a1b3 100644 --- a/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c +++ b/src/mod/endpoints/mod_gsmopen/alsa_nogsmlib_nocplusplus/mod_gsmopen/mod_gsmopen.c @@ -1398,7 +1398,7 @@ static switch_status_t load_config(int reload_type) char *dial_regex = NULL; char *hold_music = NULL; char *fail_dial_regex = NULL; - const char *enable_callerid ; + //const char *enable_callerid ; const char *at_dial_pre_number = "ATD"; @@ -1518,8 +1518,8 @@ static switch_status_t load_config(int reload_type) hold_music = val; } else if (!strcasecmp(var, "fail_dial_regex")) { fail_dial_regex = val; - } else if (!strcasecmp(var, "enable_callerid")) { - enable_callerid = val; + //} else if (!strcasecmp(var, "enable_callerid")) { + //enable_callerid = val; } else if (!strcasecmp(var, "at_dial_pre_number")) { at_dial_pre_number = val; } else if (!strcasecmp(var, "at_dial_post_number")) { From 155ecd96506f8d6d33da45ced1ed8856aa50ec29 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 26 Sep 2012 11:25:42 -0500 Subject: [PATCH 074/512] FS-4636 fix regression --- src/switch_ivr_originate.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 7cb296b1c6..0efa8e238e 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1224,7 +1224,11 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, originate_st switch_goto_status(SWITCH_STATUS_GENERR, end); } - switch_core_session_get_read_impl(originate_status[0].peer_session, &peer_read_impl); + if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) { + switch_core_session_get_read_impl(originate_status[0].peer_session, &peer_read_impl); + } else { + switch_core_session_get_read_impl(oglobals->session, &peer_read_impl); + } if (switch_core_codec_init(write_codec, "L16", From 4bb5c93e4ad2ae2ee98126254be4d6c8538267b0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 26 Sep 2012 12:10:37 -0500 Subject: [PATCH 075/512] use a lower level write func for cng packets --- 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 0b966d8ba2..de842c5db7 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -977,7 +977,7 @@ static int check_srtp_and_ice(switch_rtp_t *rtp_session) switch_frame_flag_t frame_flags = SFF_NONE; data[0] = 65; rtp_session->cn++; - rtp_common_write(rtp_session, NULL, (void *) data, 2, rtp_session->cng_pt, 0, &frame_flags); + switch_rtp_write_manual(rtp_session, (void *) data, 2, 0, rtp_session->cng_pt, ntohl(rtp_session->send_msg.header.ts), &frame_flags); } From 9d2aa0cd4cc18d553e1781e9e63b6977227089c3 Mon Sep 17 00:00:00 2001 From: Robert Jongbloed Date: Tue, 25 Sep 2012 12:55:41 +1000 Subject: [PATCH 076/512] Fixed failure to close FS call when H.323 call is closed from remote in early phase. --- src/mod/endpoints/mod_opal/mod_opal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_opal/mod_opal.cpp b/src/mod/endpoints/mod_opal/mod_opal.cpp index 53c504b059..ba0b5c364d 100644 --- a/src/mod/endpoints/mod_opal/mod_opal.cpp +++ b/src/mod/endpoints/mod_opal/mod_opal.cpp @@ -644,7 +644,7 @@ void FSConnection::OnReleased() m_rxAudioOpened.Signal(); // Just in case m_txAudioOpened.Signal(); - if (m_fsChannel == NULL) { + if (m_fsChannel != NULL) { PTRACE(3, "mod_opal\tHanging up FS side"); switch_channel_hangup(m_fsChannel, (switch_call_cause_t)callEndReason.q931); } From cf0f483aabb3a6697011066de7b52ef50c6871de Mon Sep 17 00:00:00 2001 From: Robert Jongbloed Date: Thu, 27 Sep 2012 10:15:24 +1000 Subject: [PATCH 077/512] Assuming, just because it is MSVC, that the standard integers are not defined, is not correct. Need to test for define _STDINT as well as later versions of MSVC (>= VS2010) do have stdint.h --- libs/esl/src/include/esl.h | 2 ++ libs/libdingaling/src/ldl_compat.h | 2 +- libs/libteletone/src/libteletone_generate.h | 2 ++ libs/stfu/stfu.h | 2 +- libs/unimrcp/libs/mpf/codecs/g711/g711.h | 2 ++ src/include/g711.h | 2 ++ src/include/switch_platform.h | 2 +- src/mod/endpoints/mod_opal/mod_opal.h | 24 --------------------- 8 files changed, 11 insertions(+), 27 deletions(-) diff --git a/libs/esl/src/include/esl.h b/libs/esl/src/include/esl.h index 4296175f3a..5e66fe437a 100644 --- a/libs/esl/src/include/esl.h +++ b/libs/esl/src/include/esl.h @@ -221,6 +221,7 @@ typedef enum { #include #include typedef SOCKET esl_socket_t; +#if !defined(_STDINT) && !defined(uint32_t) typedef unsigned __int64 uint64_t; typedef unsigned __int32 uint32_t; typedef unsigned __int16 uint16_t; @@ -229,6 +230,7 @@ typedef __int64 int64_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef __int8 int8_t; +#endif typedef intptr_t esl_ssize_t; typedef int esl_filehandle_t; #define ESL_SOCK_INVALID INVALID_SOCKET diff --git a/libs/libdingaling/src/ldl_compat.h b/libs/libdingaling/src/ldl_compat.h index 2507cd5957..280bf20dc8 100644 --- a/libs/libdingaling/src/ldl_compat.h +++ b/libs/libdingaling/src/ldl_compat.h @@ -42,7 +42,7 @@ extern "C" { #ifdef _MSC_VER -#ifndef uint32_t +#if !defined(_STDINT) && !defined(uint32_t) typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; diff --git a/libs/libteletone/src/libteletone_generate.h b/libs/libteletone/src/libteletone_generate.h index a49e45a658..25d5bf79d7 100644 --- a/libs/libteletone/src/libteletone_generate.h +++ b/libs/libteletone/src/libteletone_generate.h @@ -91,6 +91,7 @@ extern "C" { #define __inline__ __inline #endif +#if !defined(_STDINT) && !defined(uint32_t) typedef unsigned __int64 uint64_t; typedef unsigned __int32 uint32_t; typedef unsigned __int16 uint16_t; @@ -99,6 +100,7 @@ typedef __int64 int64_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef __int8 int8_t; +#endif #else #include #endif diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index 2b21419118..045b644009 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -49,7 +49,7 @@ extern "C" { #endif #ifdef _MSC_VER -#ifndef uint32_t +#if !defined(_STDINT) && !defined(uint32_t) typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; diff --git a/libs/unimrcp/libs/mpf/codecs/g711/g711.h b/libs/unimrcp/libs/mpf/codecs/g711/g711.h index a8a0e92150..ae7e0e44aa 100644 --- a/libs/unimrcp/libs/mpf/codecs/g711/g711.h +++ b/libs/unimrcp/libs/mpf/codecs/g711/g711.h @@ -49,11 +49,13 @@ extern "C" { #ifndef __inline__ #define __inline__ __inline #endif +#if !defined(_STDINT) && !defined(uint32_t) typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef unsigned __int16 uint16_t; #endif +#endif #if defined(__i386__) /*! \brief Find the bit position of the highest set bit in a word diff --git a/src/include/g711.h b/src/include/g711.h index 53f3afc87e..aac82a15ac 100644 --- a/src/include/g711.h +++ b/src/include/g711.h @@ -50,11 +50,13 @@ extern "C" { #ifndef __inline__ #define __inline__ __inline #endif +#if !defined(_STDINT) && !defined(uint32_t) typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef unsigned __int16 uint16_t; #endif +#endif #if defined(__i386__) /*! \brief Find the bit position of the highest set bit in a word diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index a011850748..1140aac8ba 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -88,7 +88,7 @@ SWITCH_BEGIN_EXTERN_C #endif #undef inline #define inline __inline -#ifndef uint32_t +#if !defined(_STDINT) && !defined(uint32_t) typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; diff --git a/src/mod/endpoints/mod_opal/mod_opal.h b/src/mod/endpoints/mod_opal/mod_opal.h index da2ea1fa5b..56ac9b3671 100644 --- a/src/mod/endpoints/mod_opal/mod_opal.h +++ b/src/mod/endpoints/mod_opal/mod_opal.h @@ -49,31 +49,7 @@ #undef strcasecmp #undef strncasecmp - -#ifdef _MSC_VER -/*The following insanity is because libteletone_generate.h defines int8_t in - a slightly different manner to most other cases (SDL, PCAP, Java V8, - VS2010's own stdint.h, etc) and does not provide a mechanism to prevent it's - inclusion. Then, to cap it off, MSVC barfs on the difference. - - Sigh. - */ -#pragma include_alias(, <../../libs/libteletone/src/libteletone.h>) -#pragma include_alias(, <../../libs/libteletone/src/libteletone_generate.h>) -#pragma include_alias(, <../../libs/libteletone/src/libteletone_detect.h>) -#define int8_t signed int8_t -#include -#undef int8_t -#endif // End of insanity - - -#define HAVE_APR -#define uint32_t uint32_t // Avoid conflict in stdint definitions #include -#undef uint32_t - -#include - #define MODNAME "mod_opal" From 5b0115676c5c6cb0762187bdd999fb115aaa2eb9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Sep 2012 09:19:51 -0500 Subject: [PATCH 078/512] add void to declarations --- libs/esl/src/esl_json.c | 14 +++++++------- libs/esl/src/include/esl_json.h | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libs/esl/src/esl_json.c b/libs/esl/src/esl_json.c index 5e7157cfe4..cd0706d6cb 100644 --- a/libs/esl/src/esl_json.c +++ b/libs/esl/src/esl_json.c @@ -35,7 +35,7 @@ static const char *ep; -ESL_DECLARE(const char *)cJSON_GetErrorPtr() {return ep;} +ESL_DECLARE(const char *)cJSON_GetErrorPtr(void) {return ep;} static int cJSON_strcasecmp(const char *s1,const char *s2) { @@ -82,7 +82,7 @@ ESL_DECLARE(void)cJSON_InitHooks(cJSON_Hooks* hooks) } /* Internal constructor. */ -static cJSON *cJSON_New_Item() +static cJSON *cJSON_New_Item(void) { cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); if (node) memset(node,0,sizeof(cJSON)); @@ -513,14 +513,14 @@ ESL_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newite ESL_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} /* Create basic types: */ -ESL_DECLARE(cJSON *)cJSON_CreateNull() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} -ESL_DECLARE(cJSON *)cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} -ESL_DECLARE(cJSON *)cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} +ESL_DECLARE(cJSON *)cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} +ESL_DECLARE(cJSON *)cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} +ESL_DECLARE(cJSON *)cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} ESL_DECLARE(cJSON *)cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} ESL_DECLARE(cJSON *)cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} ESL_DECLARE(cJSON *)cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} -ESL_DECLARE(cJSON *)cJSON_CreateArray() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} -ESL_DECLARE(cJSON *)cJSON_CreateObject() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} +ESL_DECLARE(cJSON *)cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} +ESL_DECLARE(cJSON *)cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} /* Create Arrays: */ ESL_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a!=0 && ichild=n;else suffix_object(p,n);p=n;}return a;} diff --git a/libs/esl/src/include/esl_json.h b/libs/esl/src/include/esl_json.h index 615645597a..d3605cd8c7 100755 --- a/libs/esl/src/include/esl_json.h +++ b/libs/esl/src/include/esl_json.h @@ -79,17 +79,17 @@ ESL_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item); ESL_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string); /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ -ESL_DECLARE(const char *)cJSON_GetErrorPtr(); +ESL_DECLARE(const char *)cJSON_GetErrorPtr(void); /* These calls create a cJSON item of the appropriate type. */ -ESL_DECLARE(cJSON *)cJSON_CreateNull(); -ESL_DECLARE(cJSON *)cJSON_CreateTrue(); -ESL_DECLARE(cJSON *)cJSON_CreateFalse(); +ESL_DECLARE(cJSON *)cJSON_CreateNull(void); +ESL_DECLARE(cJSON *)cJSON_CreateTrue(void); +ESL_DECLARE(cJSON *)cJSON_CreateFalse(void); ESL_DECLARE(cJSON *)cJSON_CreateBool(int b); ESL_DECLARE(cJSON *)cJSON_CreateNumber(double num); ESL_DECLARE(cJSON *)cJSON_CreateString(const char *string); -ESL_DECLARE(cJSON *)cJSON_CreateArray(); -ESL_DECLARE(cJSON *)cJSON_CreateObject(); +ESL_DECLARE(cJSON *)cJSON_CreateArray(void); +ESL_DECLARE(cJSON *)cJSON_CreateObject(void); /* These utilities create an Array of count items. */ ESL_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count); From 7a69d7d47cbb4db5b5ea100e8d9555b701f62b90 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 27 Sep 2012 12:10:13 -0500 Subject: [PATCH 079/512] FS-4638 --resolve add error log for bad codec string --- src/switch_loadable_module.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 15c4739775..d253a75bea 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -2108,6 +2108,8 @@ SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uin *rate = atoi(cur); } else if (strchr(cur, 'b')) { *bit = atoi(cur); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad syntax for codec string. Missing qualifier [h|k|i|b] for part [%s]!\n", cur); } } cur = next; From c7283aaa1a3f9032c9498b575231c986cc0885fd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Sep 2012 13:37:15 -0500 Subject: [PATCH 080/512] force core rebuild when apr and other core libs change --- Makefile.am | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile.am b/Makefile.am index e7f1f799a5..adf412b205 100644 --- a/Makefile.am +++ b/Makefile.am @@ -449,26 +449,32 @@ libs/curl/lib/libcurl.la: libs/curl libs/curl/Makefile @$(TOUCH_TARGET) libs/apr/libapr-1.la: libs/apr libs/apr/.update + touch src/include/switch.h @cd libs/apr && $(MAKE) @$(TOUCH_TARGET) libs/apr-util/libaprutil-1.la: libs/apr-util libs/apr-util/.update libs/apr/libapr-1.la + touch src/include/switch.h @cd libs/apr-util && $(MAKE) @$(TOUCH_TARGET) libs/speex/libspeex/libspeexdsp.la: libs/speex/.update + touch src/include/switch.h @cd libs/speex && $(MAKE) @$(TOUCH_TARGET) libs/sqlite/libsqlite3.la: libs/sqlite libs/sqlite/.update + touch src/include/switch.h @cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)" @$(TOUCH_TARGET) libs/pcre/libpcre.la: libs/pcre libs/pcre/.update + touch src/include/switch.h @cd libs/pcre && $(MAKE) @$(TOUCH_TARGET) libs/srtp/libsrtp.la: libs/srtp libs/srtp/.update + touch src/include/switch.h @cd libs/srtp && $(MAKE) @$(TOUCH_TARGET) From 90f3ab40998de46a0ec962e0e4f707dfa688e157 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Sep 2012 13:37:54 -0500 Subject: [PATCH 081/512] fix thread priority code, this has never worked until today --- libs/apr/.update | 2 +- libs/apr/include/arch/unix/apr_arch_threadproc.h | 1 + libs/apr/threadproc/unix/thread.c | 5 +++++ src/switch_apr.c | 15 +++------------ 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libs/apr/.update b/libs/apr/.update index d5bc43d9d4..4452df8ef3 100644 --- a/libs/apr/.update +++ b/libs/apr/.update @@ -1 +1 @@ -Mon Sep 27 13:15:54 CDT 2010 +Thu Sep 27 13:36:14 CDT 2012 diff --git a/libs/apr/include/arch/unix/apr_arch_threadproc.h b/libs/apr/include/arch/unix/apr_arch_threadproc.h index 6b0180234d..bd9359a49f 100644 --- a/libs/apr/include/arch/unix/apr_arch_threadproc.h +++ b/libs/apr/include/arch/unix/apr_arch_threadproc.h @@ -60,6 +60,7 @@ struct apr_thread_t { struct apr_threadattr_t { apr_pool_t *pool; pthread_attr_t attr; + int priority; }; struct apr_threadkey_t { diff --git a/libs/apr/threadproc/unix/thread.c b/libs/apr/threadproc/unix/thread.c index 28fcef0aef..9a56e55405 100644 --- a/libs/apr/threadproc/unix/thread.c +++ b/libs/apr/threadproc/unix/thread.c @@ -174,6 +174,11 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, } if ((stat = pthread_create((*new)->td, temp, dummy_worker, (*new))) == 0) { + if (attr->priority) { + pthread_t *thread = (*new)->td; + pthread_setschedprio(*thread, attr->priority); + } + return APR_SUCCESS; } else { diff --git a/src/switch_apr.c b/src/switch_apr.c index c854c97617..dfb56d5390 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -633,25 +633,16 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_stacksize_set(switch_threadatt struct apr_threadattr_t { apr_pool_t *pool; pthread_attr_t attr; + int priority; }; #endif SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_increase(switch_threadattr_t *attr) { - int stat = 0; #ifndef WIN32 - struct sched_param param; - struct apr_threadattr_t *myattr = attr; - - pthread_attr_getschedparam(&myattr->attr, ¶m); - param.sched_priority = 1; - stat = pthread_attr_setschedparam(&myattr->attr, ¶m); - - if (stat == 0) { - return SWITCH_STATUS_SUCCESS; - } + attr->priority = 10; #endif - return stat; + return SWITCH_STATUS_SUCCESS; } static char TT_KEY[] = "1"; From 7c840030247382912a87a3362a4497a9e4dda9b1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Sep 2012 11:42:19 -0500 Subject: [PATCH 082/512] bump important threads to realtime priority --- 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 dfb56d5390..49b7a9b5c5 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -640,7 +640,7 @@ struct apr_threadattr_t { SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_increase(switch_threadattr_t *attr) { #ifndef WIN32 - attr->priority = 10; + attr->priority = 99; #endif return SWITCH_STATUS_SUCCESS; } From 06a3266360c2cec7e4b3a450ee6693430a0d0451 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 27 Sep 2012 14:27:28 -0500 Subject: [PATCH 083/512] FS-4655 its not a bug its a behaviour request, try this patch --- src/mod/endpoints/mod_alsa/mod_alsa.c | 2 +- src/mod/endpoints/mod_portaudio/mod_portaudio.c | 2 +- src/mod/endpoints/mod_rtmp/mod_rtmp.c | 2 +- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 2 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 3 ++- src/mod/endpoints/mod_unicall/mod_unicall.c | 2 +- src/switch_core_session.c | 5 +++++ 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_alsa/mod_alsa.c b/src/mod/endpoints/mod_alsa/mod_alsa.c index bafe8bdcc1..13e36ea53d 100644 --- a/src/mod/endpoints/mod_alsa/mod_alsa.c +++ b/src/mod/endpoints/mod_alsa/mod_alsa.c @@ -758,7 +758,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi switch_call_cause_t *cancel_cause) { - if ((*new_session = switch_core_session_request(alsa_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { + if ((*new_session = switch_core_session_request_uuid(alsa_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid"))) != 0) { private_t *tech_pvt; switch_channel_t *channel; switch_caller_profile_t *caller_profile; diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index abc36620dd..f5487486ce 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -1157,7 +1157,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi return retcause; } - if (!(*new_session = switch_core_session_request(portaudio_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool))) { + if (!(*new_session = switch_core_session_request_uuid(portaudio_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid")))) { return retcause; } diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.c b/src/mod/endpoints/mod_rtmp/mod_rtmp.c index 0bdc4531de..844b1483d0 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.c +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.c @@ -590,7 +590,7 @@ switch_call_cause_t rtmp_outgoing_channel(switch_core_session_t *session, switch goto fail; } - if (!(*newsession = switch_core_session_request(rtmp_globals.rtmp_endpoint_interface, flags, SWITCH_CALL_DIRECTION_OUTBOUND, inpool))) { + if (!(*newsession = switch_core_session_request_uuid(rtmp_globals.rtmp_endpoint_interface, flags, SWITCH_CALL_DIRECTION_OUTBOUND, inpool, switch_event_get_header(var_event, "origination_uuid")))) { goto fail; } diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 21dea92d4f..43253a71e9 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -1261,7 +1261,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi switch_call_cause_t *cancel_cause) { private_t *tech_pvt = NULL; - if ((*new_session = switch_core_session_request(skypopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { + if ((*new_session = switch_core_session_request_uuid(skypopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid"))) != 0) { switch_channel_t *channel = NULL; switch_caller_profile_t *caller_profile; char *rdest; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index b7450e4e47..a9721b4c49 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4538,7 +4538,8 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session goto error; } - if (!(nsession = switch_core_session_request(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool))) { + if (!(nsession = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, + flags, pool, switch_event_get_header(var_event, "origination_uuid")))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); goto error; } diff --git a/src/mod/endpoints/mod_unicall/mod_unicall.c b/src/mod/endpoints/mod_unicall/mod_unicall.c index 75680bd243..18cd5d11d5 100644 --- a/src/mod/endpoints/mod_unicall/mod_unicall.c +++ b/src/mod/endpoints/mod_unicall/mod_unicall.c @@ -197,7 +197,7 @@ static switch_call_cause_t unicall_incoming_channel(zap_sigmsg_t *sigmsg, switch *sp = NULL; - if (!(session = switch_core_session_request(openzap_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL))) { + if (!(session = switch_core_session_request_uuid(openzap_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL, switch_event_get_header(var_event, "origination_uuid")))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Initialization Error!\n"); return ZAP_FAIL; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 94edc35488..eb60968f5d 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1682,6 +1682,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_uuid(switch_core_session switch_assert(use_uuid); + if (!strcmp(use_uuid, session->uuid_str)) { + return SWITCH_STATUS_SUCCESS; + } + + switch_mutex_lock(runtime.session_hash_mutex); if (switch_core_hash_find(session_manager.session_table, use_uuid)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Duplicate UUID!\n"); From 15ef8925c31e100e2656408aea2fa7495ebd4b91 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 27 Sep 2012 23:48:18 -0400 Subject: [PATCH 084/512] Fix for Q.921 not always recovering --- .../ftmod_sangoma_isdn_stack_out.c | 16 +++++++++++++--- .../ftmod_sangoma_isdn_support.c | 11 ++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) 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 02b1ce0be8..f6e0d70b41 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 @@ -475,8 +475,16 @@ void sngisdn_snd_restart(ftdm_channel_t *ftdmchan) void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len) { sng_l1_frame_t l1_frame; + ftdm_alarm_flag_t alarmbits = 0; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data; + ftdm_channel_get_alarms(dchan, &alarmbits); + + if (alarmbits) { + ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Dropping incoming data due to L1 alarm\n"); + return; + } + if (len > sizeof(l1_frame.data)) { ftdm_log_chan(dchan, FTDM_LOG_ERROR, "Received frame of %"FTDM_SIZE_FMT" bytes, exceeding max size of %"FTDM_SIZE_FMT" bytes\n", len, sizeof(l1_frame.data)); @@ -548,9 +556,11 @@ void sngisdn_snd_event(sngisdn_span_data_t *signal_data, ftdm_oob_event_t event) case FTDM_OOB_ALARM_CLEAR: l1_event.type = SNG_L1EVENT_ALARM_OFF; sng_isdn_event_ind(signal_data->link_id, &l1_event); - - ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 8000, sngisdn_delayed_dl_req, (void*) signal_data, NULL); - signal_data->dl_request_pending = 1; + + if (!signal_data->dl_request_pending) { + signal_data->dl_request_pending = 1; + ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 8000, sngisdn_delayed_dl_req, (void*) signal_data, NULL); + } break; case FTDM_OOB_ALARM_TRAP: l1_event.type = SNG_L1EVENT_ALARM_ON; 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 246c3190ee..cabf68be77 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 @@ -1214,14 +1214,23 @@ void sngisdn_t3_timeout(void *p_sngisdn_info) void sngisdn_delayed_dl_req(void *p_signal_data) { + ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t *)p_signal_data; ftdm_span_t *span = signal_data->ftdm_span; if (!signal_data->dl_request_pending) { return; } - signal_data->dl_request_pending = 0; + + ftdm_span_get_sig_status(span, &sigstatus); + if (sigstatus == FTDM_SIG_STATE_UP) { + signal_data->dl_request_pending = 0; + return; + } + sngisdn_snd_dl_req(span->channels[1]); + ftdm_sched_timer(signal_data->sched, "delayed_dl_req", 4000, sngisdn_delayed_dl_req, (void*) signal_data, NULL); + return; } From 0cb64960f1378be6883f0c35e2aae5b7a227c6cb Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Fri, 28 Sep 2012 09:45:42 -0700 Subject: [PATCH 085/512] config: improve default directory's dialstring param to handle registrations from any SIP profile --- conf/vanilla/directory/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/vanilla/directory/default.xml b/conf/vanilla/directory/default.xml index 8af7aea135..0dc67412de 100644 --- a/conf/vanilla/directory/default.xml +++ b/conf/vanilla/directory/default.xml @@ -21,7 +21,7 @@ - + From 5259814aee16ede974456490a79e8a98de1d6d2e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 28 Sep 2012 14:05:58 -0500 Subject: [PATCH 086/512] number not true --- 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 de842c5db7..b3b396e619 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1688,7 +1688,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess memset(policy, 0, sizeof(*policy)); - switch_channel_set_variable(channel, "send_silence_when_idle", "true"); + switch_channel_set_variable(channel, "send_silence_when_idle", "400"); switch (crypto_key->type) { case AES_CM_128_HMAC_SHA1_80: From 8d614040168083f0dad5ca4a45bae7c06ed3de7c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 28 Sep 2012 16:17:20 -0500 Subject: [PATCH 087/512] fix issue where dtmf was not being sent on an outbound leg when there was no inbound audio --- src/switch_rtp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index b3b396e619..14fbe1a849 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3492,7 +3492,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK) || !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) || (bytes && bytes < 5) || (!bytes && poll_loop)) { - do_2833(rtp_session, session); bytes = 0; return_cng_frame(); } @@ -3692,6 +3691,8 @@ 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; + do_2833(rtp_session, session); + if (rtp_session->last_cng_ts == rtp_session->last_read_ts + rtp_session->samples_per_interval) { rtp_session->last_cng_ts = 0; } else { From 677d16cfd5b16c0fac4f6f432db027faf068a95f Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Mon, 1 Oct 2012 01:26:20 +0200 Subject: [PATCH 088/512] scripts/trace/sipgrep: correctly interpret option -C (print ANSI colors in debug file only when option -C is defined) --- scripts/trace/sipgrep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/trace/sipgrep b/scripts/trace/sipgrep index 474a2d5c7b..3b3796925e 100755 --- a/scripts/trace/sipgrep +++ b/scripts/trace/sipgrep @@ -286,8 +286,8 @@ sub print_out if(defined $filedebug) { open(DBG, ">>$filedebug"); - $lcolor = 'reset' if(!(defined $debugfilecolors)); - print DBG color $lcolor if(!(defined $debugfilecolors)); + $lcolor = 'reset' if((defined $debugfilecolors)); + print DBG color $lcolor if((defined $debugfilecolors)); print DBG $ltext; close(DBG); } From bf060c6396c8b45b4dff154b00395744fceee2ea Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 1 Oct 2012 08:56:51 -0500 Subject: [PATCH 089/512] FS-4664 --resolve --- src/mod/endpoints/mod_skinny/skinny_server.c | 24 ++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 6c0e01f8a0..652b7954c6 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1198,10 +1198,11 @@ switch_status_t skinny_handle_enbloc_call_message(listener_t *listener, skinny_m switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request) { switch_status_t status = SWITCH_STATUS_SUCCESS; - struct speed_dial_stat_res_message *button = NULL; uint32_t line_instance = 0; uint32_t call_id = 0; switch_core_session_t *session = NULL; + struct speed_dial_stat_res_message *button_speed_dial = NULL; + struct line_stat_res_message *button_line = NULL; skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id)); @@ -1215,10 +1216,10 @@ switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_mess skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); break; case SKINNY_BUTTON_SPEED_DIAL: - skinny_speed_dial_get(listener, request->data.stimulus.instance, &button); - if(strlen(button->line) > 0) { + skinny_speed_dial_get(listener, request->data.stimulus.instance, &button_speed_dial); + if(strlen(button_speed_dial->line) > 0) { skinny_create_incoming_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, button->line, '\0', 0); + skinny_session_process_dest(session, listener, line_instance, button_speed_dial->line, '\0', 0); } break; case SKINNY_BUTTON_HOLD: @@ -1239,6 +1240,21 @@ switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_mess skinny_create_incoming_session(listener, &line_instance, &session); skinny_session_process_dest(session, listener, line_instance, "vmain", '\0', 0); break; + + case SKINNY_BUTTON_LINE: + // Get the button data + skinny_line_get(listener, request->data.stimulus.instance, &button_line); + + // Set the button and try to open the incoming session with this + line_instance = button_line->number; + session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); + + // If session and line match, answer the call + if ( session && line_instance == button_line->number ) { + status = skinny_session_answer(session, listener, line_instance); + } + break; + default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type); } From 8733a2c8950f552de5d239974ca6d6d09d529228 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Oct 2012 11:47:26 -0500 Subject: [PATCH 090/512] some priority queuing tweaks for performance --- src/mod/applications/mod_conference/mod_conference.c | 1 + src/mod/endpoints/mod_sofia/sofia.c | 7 +++++-- src/switch_core.c | 2 +- src/switch_core_io.c | 2 ++ src/switch_core_sqldb.c | 3 ++- src/switch_event.c | 1 + src/switch_time.c | 5 ++++- 7 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 0bdf28822b..d84f3b6f7d 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -7748,6 +7748,7 @@ static void launch_conference_thread(conference_obj_t *conference) switch_set_flag_locked(conference, CFLAG_RUNNING); switch_threadattr_create(&thd_attr, conference->pool); switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_priority_increase(thd_attr); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_mutex_lock(globals.hash_mutex); switch_mutex_unlock(globals.hash_mutex); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f7f7bddead..2793cd7354 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1599,7 +1599,7 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj msg_queue_threads++; switch_mutex_unlock(mod_sofia_globals.mutex); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread %d Started\n", my_id); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MSG Thread %d Started\n", my_id); for(;;) { @@ -1612,12 +1612,13 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj if (pop) { sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop; sofia_process_dispatch_event(&de); + switch_os_yield(); } else { break; } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Ended\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MSG Thread Ended\n"); switch_mutex_lock(mod_sofia_globals.mutex); msg_queue_threads--; @@ -1934,6 +1935,8 @@ void sofia_event_callback(nua_event_t event, if (profile->pres_type) { switch_cond_next(); + } else { + switch_os_yield(); } diff --git a/src/switch_core.c b/src/switch_core.c index 6cce356061..488b755232 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -736,7 +736,7 @@ SWITCH_DECLARE(int32_t) set_realtime_priority(void) char data[] = "-1\n"; struct sched_param sched = { 0 }; sched.sched_priority = 1; - if (sched_setscheduler(0, SCHED_FIFO, &sched)) { + if (sched_setscheduler(0, SCHED_RR, &sched)) { sched.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, &sched)) { return -1; diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 8978306adb..7b9580c0bb 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -112,6 +112,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_assert(session != NULL); + switch_os_yield(); + if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) { switch_mutex_unlock(session->codec_read_mutex); } else { diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index d77b432c90..2e3e71f204 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2539,7 +2539,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - + switch_threadattr_priority_increase(thd_attr); switch_core_sqldb_start_thread(); switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); @@ -2641,6 +2641,7 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting SQL thread.\n"); switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_increase(thd_attr); switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is already running\n"); diff --git a/src/switch_event.c b/src/switch_event.c index 3a02e3a449..175dadf5cf 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -276,6 +276,7 @@ static void *SWITCH_THREAD_FUNC switch_event_dispatch_thread(switch_thread_t *th event = (switch_event_t *) pop; switch_event_deliver(&event); + switch_os_yield(); } diff --git a/src/switch_time.c b/src/switch_time.c index fb9fea1de0..54bf9338ef 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -150,6 +150,7 @@ SWITCH_DECLARE(void) switch_os_yield(void) #if defined(WIN32) SwitchToThread(); #else + usleep(1); sched_yield(); #endif } @@ -672,8 +673,10 @@ static switch_status_t timer_next(switch_timer_t *timer) while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) { check_roll(); + switch_os_yield(); + + if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) { - switch_os_yield(); globals.use_cond_yield = 0; } else { if (globals.use_cond_yield == 1) { From 464155c5cd1c3c8e050e9c59d3990d382cf12658 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Oct 2012 10:20:48 -0500 Subject: [PATCH 091/512] more priority tweaks --- src/include/switch_apr.h | 2 +- src/include/switch_types.h | 7 +++++ .../mod_callcenter/mod_callcenter.c | 2 +- .../mod_conference/mod_conference.c | 2 +- .../mod_voicemail/mod_voicemail.c | 2 +- .../commons/base/system/freeswitch/thread.hpp | 5 +++- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 8 ++--- src/mod/endpoints/mod_sofia/sofia.c | 8 ++--- src/mod/endpoints/mod_sofia/sofia_presence.c | 2 +- src/mod/xml_int/mod_xml_scgi/mod_xml_scgi.c | 2 +- src/switch_apr.c | 29 ++++++++++++------- src/switch_core.c | 4 +-- src/switch_core_session.c | 1 + src/switch_core_sqldb.c | 4 +-- src/switch_event.c | 4 +-- src/switch_loadable_module.c | 1 - 16 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index bd19353991..671052ab30 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -989,7 +989,7 @@ SWITCH_DECLARE(const char *) switch_dir_next_file(switch_dir_t *thedir, char *bu //APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr, switch_size_t stacksize) SWITCH_DECLARE(switch_status_t) switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize); -SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_increase(switch_threadattr_t *attr); +SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_set(switch_threadattr_t *attr, switch_thread_priority_t priority); /** diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 5f3a4fa258..f9d8476454 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2016,6 +2016,13 @@ typedef switch_status_t (*switch_module_shutdown_t) SWITCH_MODULE_SHUTDOWN_ARGS; #define SWITCH_MODULE_RUNTIME_FUNCTION(name) switch_status_t name SWITCH_MODULE_RUNTIME_ARGS #define SWITCH_MODULE_SHUTDOWN_FUNCTION(name) switch_status_t name SWITCH_MODULE_SHUTDOWN_ARGS +typedef enum { + SWITCH_PRI_LOW = 1, + SWITCH_PRI_NORMAL = 10, + SWITCH_PRI_IMPORTANT = 50, + SWITCH_PRI_REALTIME = 99, +} switch_thread_priority_t; + typedef enum { SMODF_NONE = 0, SMODF_GLOBAL_SYMBOLS = (1 << 0) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index df8670f2ee..e6f7ea7945 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -2272,7 +2272,7 @@ void cc_agent_dispatch_thread_start(void) switch_threadattr_create(&thd_attr, globals.pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&thread, thd_attr, cc_agent_dispatch_thread_run, NULL, globals.pool); } diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index d84f3b6f7d..3acb7d6c55 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -7748,7 +7748,7 @@ static void launch_conference_thread(conference_obj_t *conference) switch_set_flag_locked(conference, CFLAG_RUNNING); switch_threadattr_create(&thd_attr, conference->pool); switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_mutex_lock(globals.hash_mutex); switch_mutex_unlock(globals.hash_mutex); diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 51677c5b3f..78eb57a20a 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -3930,7 +3930,7 @@ void vm_event_thread_start(void) switch_threadattr_create(&thd_attr, globals.pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_IMPORTANT); switch_thread_create(&thread, thd_attr, vm_event_thread_run, NULL, globals.pool); } diff --git a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp b/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp index 9e5abc4372..3c61b6a6ec 100644 --- a/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp +++ b/src/mod/endpoints/mod_khomp/commons/base/system/freeswitch/thread.hpp @@ -288,7 +288,10 @@ private: return true; /* - //BUG in Freeswitch + //BUG in Freeswitch + +THANKS FOR NOT REPORTING IT SO WE MUST LIVE WITH A PROBLEM YOU KNOW ABOUT ..... + if(switch_threadattr_priority_increase( (switch_threadattr_t *)_thread_info->_attribute) != 0) return false; diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 43253a71e9..c3b5d81681 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -1741,7 +1741,7 @@ static switch_status_t load_config(int reload_type) switch_threadattr_create(&skypopen_api_thread_attr, skypopen_module_pool); switch_threadattr_detach_set(skypopen_api_thread_attr, 0); switch_threadattr_stacksize_set(skypopen_api_thread_attr, SWITCH_THREAD_STACKSIZE); - //switch_threadattr_priority_increase(skypopen_api_thread_attr); + switch_thread_create(&globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread, skypopen_api_thread_attr, skypopen_do_skypeapi_thread, &globals.SKYPOPEN_INTERFACES[interface_id], skypopen_module_pool); @@ -1751,7 +1751,7 @@ static switch_status_t load_config(int reload_type) switch_threadattr_create(&skypopen_signaling_thread_attr, skypopen_module_pool); switch_threadattr_detach_set(skypopen_signaling_thread_attr, 0); switch_threadattr_stacksize_set(skypopen_signaling_thread_attr, SWITCH_THREAD_STACKSIZE); - //switch_threadattr_priority_increase(skypopen_signaling_thread_attr); + switch_thread_create(&globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread, skypopen_signaling_thread_attr, skypopen_signaling_thread_func, &globals.SKYPOPEN_INTERFACES[interface_id], skypopen_module_pool); @@ -2272,7 +2272,7 @@ int start_audio_threads(private_t *tech_pvt) switch_threadattr_create(&tcp_srv_thread_thd_attr, skypopen_module_pool); switch_threadattr_detach_set(tcp_srv_thread_thd_attr, 0); switch_threadattr_stacksize_set(tcp_srv_thread_thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(tcp_srv_thread_thd_attr); + switch_threadattr_priority_set(tcp_srv_thread_thd_attr, SWITCH_PRI_REALTIME); switch_mutex_lock(tech_pvt->mutex_thread_audio_srv); //DEBUGA_SKYPE("debugging_hangup srv lock\n", SKYPOPEN_P_LOG); if (switch_thread_create(&tech_pvt->tcp_srv_thread, tcp_srv_thread_thd_attr, skypopen_do_tcp_srv_thread, tech_pvt, skypopen_module_pool) == @@ -2290,7 +2290,7 @@ int start_audio_threads(private_t *tech_pvt) switch_threadattr_create(&tcp_cli_thread_thd_attr, skypopen_module_pool); switch_threadattr_detach_set(tcp_cli_thread_thd_attr, 0); switch_threadattr_stacksize_set(tcp_cli_thread_thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(tcp_cli_thread_thd_attr); + switch_threadattr_priority_set(tcp_cli_thread_thd_attr, SWITCH_PRI_REALTIME); switch_mutex_lock(tech_pvt->mutex_thread_audio_cli); //DEBUGA_SKYPE("debugging_hangup cli lock\n", SKYPOPEN_P_LOG); if (switch_thread_create(&tech_pvt->tcp_cli_thread, tcp_cli_thread_thd_attr, skypopen_do_tcp_cli_thread, tech_pvt, skypopen_module_pool) == diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2793cd7354..3b5277647f 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1647,7 +1647,7 @@ void sofia_msg_thread_start(int idx) switch_threadattr_create(&thd_attr, mod_sofia_globals.pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&mod_sofia_globals.msg_queue_thread[i], thd_attr, sofia_msg_thread_run, @@ -2373,7 +2373,7 @@ switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile) switch_threadattr_create(&thd_attr, profile->pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&thread, thd_attr, sofia_profile_worker_thread_run, profile, profile->pool); while (!sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)) { @@ -2753,7 +2753,7 @@ void launch_sofia_profile_thread(sofia_profile_t *profile) switch_threadattr_create(&thd_attr, profile->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&thread, thd_attr, sofia_profile_thread_run, profile, profile->pool); } @@ -6114,7 +6114,6 @@ static void launch_media_on_hold(switch_core_session_t *session) switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); switch_thread_create(&thread, thd_attr, media_on_hold_thread_run, session, switch_core_session_get_pool(session)); } @@ -7198,7 +7197,6 @@ static void launch_nightmare_xfer(nightmare_xfer_helper_t *nhelper) switch_threadattr_create(&thd_attr, nhelper->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); switch_thread_create(&thread, thd_attr, nightmare_xfer_thread_run, nhelper, nhelper->pool); } diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 045ea7a827..10d741bca4 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1577,7 +1577,7 @@ void sofia_presence_event_thread_start(void) switch_threadattr_create(&thd_attr, mod_sofia_globals.pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_IMPORTANT); switch_thread_create(&thread, thd_attr, sofia_presence_event_thread_run, NULL, mod_sofia_globals.pool); } diff --git a/src/mod/xml_int/mod_xml_scgi/mod_xml_scgi.c b/src/mod/xml_int/mod_xml_scgi/mod_xml_scgi.c index 3e39e65407..81b0ef240f 100644 --- a/src/mod/xml_int/mod_xml_scgi/mod_xml_scgi.c +++ b/src/mod/xml_int/mod_xml_scgi/mod_xml_scgi.c @@ -126,7 +126,7 @@ static void launch_monitor_thread(xml_binding_t *binding) switch_threadattr_create(&thd_attr, globals.pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_IMPORTANT); switch_thread_create(&binding->thread, thd_attr, monitor_thread_run, binding, globals.pool); } diff --git a/src/switch_apr.c b/src/switch_apr.c index 49b7a9b5c5..64e066853e 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -614,9 +614,24 @@ SWITCH_DECLARE(const char *) switch_dir_next_file(switch_dir_t *thedir, char *bu /* thread stubs */ +#ifndef WIN32 +struct apr_threadattr_t { + apr_pool_t *pool; + pthread_attr_t attr; + int priority; +}; +#endif + + SWITCH_DECLARE(switch_status_t) switch_threadattr_create(switch_threadattr_t ** new_attr, switch_memory_pool_t *pool) { - return apr_threadattr_create(new_attr, pool); + switch_status_t status; + + if ((status = apr_threadattr_create(new_attr, pool)) == SWITCH_STATUS_SUCCESS) { + (*new_attr)->priority = SWITCH_PRI_NORMAL; + } + + return status; } SWITCH_DECLARE(switch_status_t) switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on) @@ -629,18 +644,10 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_stacksize_set(switch_threadatt return apr_threadattr_stacksize_set(attr, stacksize); } -#ifndef WIN32 -struct apr_threadattr_t { - apr_pool_t *pool; - pthread_attr_t attr; - int priority; -}; -#endif - -SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_increase(switch_threadattr_t *attr) +SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_set(switch_threadattr_t *attr, switch_thread_priority_t priority) { #ifndef WIN32 - attr->priority = 99; + attr->priority = priority; #endif return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core.c b/src/switch_core.c index 488b755232..1d87d9ce2e 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -533,7 +533,7 @@ SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_ ts->objs[0] = obj; ts->objs[1] = thread; switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&thread, thd_attr, func, ts, pool); } @@ -735,7 +735,7 @@ SWITCH_DECLARE(int32_t) set_realtime_priority(void) const char *rt = "/proc/sys/kernel/sched_rt_runtime_us"; char data[] = "-1\n"; struct sched_param sched = { 0 }; - sched.sched_priority = 1; + sched.sched_priority = SWITCH_PRI_REALTIME; if (sched_setscheduler(0, SCHED_RR, &sched)) { sched.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, &sched)) { diff --git a/src/switch_core_session.c b/src/switch_core_session.c index eb60968f5d..6e565dca06 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1554,6 +1554,7 @@ static switch_status_t check_queue(void) switch_threadattr_create(&thd_attr, node->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_LOW); if (switch_thread_create(&thread, thd_attr, switch_core_session_thread_pool_worker, node, node->pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Thread Failure!\n"); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 2e3e71f204..556e3abab2 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2539,7 +2539,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_core_sqldb_start_thread(); switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); @@ -2641,7 +2641,7 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting SQL thread.\n"); switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is already running\n"); diff --git a/src/switch_event.c b/src/switch_event.c index 175dadf5cf..02d23ee8f7 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -545,7 +545,7 @@ SWITCH_DECLARE(void) switch_event_launch_dispatch_threads(uint32_t max) switch_threadattr_create(&thd_attr, pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_increase(thd_attr); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&EVENT_DISPATCH_QUEUE_THREADS[index], thd_attr, switch_event_dispatch_thread, EVENT_DISPATCH_QUEUE, pool); while(--sanity && !EVENT_DISPATCH_QUEUE_RUNNING[index]) switch_yield(10000); @@ -603,7 +603,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) #endif //switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - //switch_threadattr_priority_increase(thd_attr); + switch_queue_create(&EVENT_DISPATCH_QUEUE, DISPATCH_QUEUE_LEN * MAX_DISPATCH, pool); switch_event_launch_dispatch_threads(1); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index d253a75bea..718572612e 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -656,7 +656,6 @@ static void chat_thread_start(int idx) switch_threadattr_create(&thd_attr, chat_globals.pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - //switch_threadattr_priority_increase(thd_attr); switch_thread_create(&chat_globals.msg_queue_thread[i], thd_attr, chat_thread_run, From 0f477d1586a6b31a345ba71b19fe1d7143aa3773 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Oct 2012 12:24:33 -0500 Subject: [PATCH 092/512] increase pri in sofia --- libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c index dfcd9ac901..9899da6f47 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c @@ -263,11 +263,12 @@ int su_pthreaded_port_start(su_port_create_f *create, pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 244); pthread_attr_getschedparam(&attr, ¶m); - param.sched_priority = 1; + param.sched_priority = 99; pthread_attr_setschedparam(&attr, ¶m); pthread_mutex_lock(arg.mutex); if (pthread_create(&tid, &attr, su_pthread_port_clone_main, &arg) == 0) { + pthread_setschedprio(tid, 99); pthread_cond_wait(arg.cv, arg.mutex); thread_created = 1; } From ece61bb7d33b18afb9a81bdb3f3086613bcd7bd8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Oct 2012 12:25:03 -0500 Subject: [PATCH 093/512] bump date to trigger build --- libs/sofia-sip/.update | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index f85cfc8001..ecae8fc840 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Sep 19 13:06:07 CDT 2012 +Mon Oct 1 12:24:45 CDT 2012 From 0995d133a6a2dadf1d4696567581e107e1d0406d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Oct 2012 12:39:16 -0500 Subject: [PATCH 094/512] remove stray goto --- src/mod/languages/mod_spidermonkey/mod_spidermonkey.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index d50030c218..1fa7b4ad5c 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -702,8 +702,6 @@ static JSBool event_chat_execute(JSContext * cx, JSObject * obj, uintN argc, jsv arg = JS_GetStringBytes(JS_ValueToString(cx, argv[1])); } - goto end; - switch_core_execute_chat_app(eo->event, app, arg); *rval = BOOLEAN_TO_JSVAL(JS_TRUE); @@ -711,8 +709,6 @@ static JSBool event_chat_execute(JSContext * cx, JSObject * obj, uintN argc, jsv } } - end: - *rval = BOOLEAN_TO_JSVAL(JS_FALSE); return JS_FALSE; } From 52eff9451c171e4300fefef334d6d2964dee35f0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 1 Oct 2012 12:14:30 -0500 Subject: [PATCH 095/512] wrap fork so we can drop priority in child processes --- src/include/switch_core.h | 3 +++ .../mod_gsmopen/asterisk/celliax_additional.c | 4 +-- .../mod_gsmopen/gsmopen_protocol.cpp | 2 +- .../mod_shell_stream/mod_shell_stream.c | 2 +- .../xml_int/mod_xml_scgi/xml_scgi_server.pl | 2 +- src/switch.c | 2 +- src/switch_core.c | 25 ++++++++++++++++--- src/switch_xml.c | 2 +- 8 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 507f18a166..efd983ded8 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2368,6 +2368,9 @@ SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_recovery_flush(const char *technology, const char *profile_name); + +SWITCH_DECLARE(pid_t) switch_fork(void); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c b/src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c index f72c8d8552..efae699ab7 100644 --- a/src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c +++ b/src/mod/endpoints/mod_gsmopen/asterisk/celliax_additional.c @@ -1185,7 +1185,7 @@ int celliax_serial_getstatus_AT(struct celliax_pvt *p) NOTICA("incoming SMS message:>>>%s<<<\n", CELLIAX_P_LOG, p->sms_message); pipe(fd1); - pid1 = fork(); + pid1 = switch_fork(); if (pid1 == 0) { //child int err; @@ -1735,7 +1735,7 @@ int celliax_serial_read_AT(struct celliax_pvt *p, int look_for_ack, int timeout_ NOTICA("incoming SMS message:>>>%s<<<\n", CELLIAX_P_LOG, p->sms_message); pipe(fd1); - pid1 = fork(); + pid1 = switch_fork(); if (pid1 == 0) { //child int err; diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp index ffa4e3d014..5bdda08f81 100644 --- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp @@ -3101,7 +3101,7 @@ int gsmopen_serial_getstatus_AT(private_t *tech_pvt) DEBUGA_AT("incoming SMS message:---%s---\n", GSMOPEN_P_LOG, p->sms_message); pipe(fd1); - pid1 = fork(); + pid1 = switch_fork(); if (pid1 == 0) { //child int err; diff --git a/src/mod/formats/mod_shell_stream/mod_shell_stream.c b/src/mod/formats/mod_shell_stream/mod_shell_stream.c index 38969c84f6..a682eb424d 100644 --- a/src/mod/formats/mod_shell_stream/mod_shell_stream.c +++ b/src/mod/formats/mod_shell_stream/mod_shell_stream.c @@ -108,7 +108,7 @@ static switch_status_t shell_stream_file_open(switch_file_handle_t *handle, cons if (pipe(context->fds)) { goto error; } else { /* good to go */ - context->pid = fork(); + context->pid = switch_fork(); if (context->pid < 0) { /* ok maybe not */ goto error; diff --git a/src/mod/xml_int/mod_xml_scgi/xml_scgi_server.pl b/src/mod/xml_int/mod_xml_scgi/xml_scgi_server.pl index 0f4af275bc..c10fd515ee 100644 --- a/src/mod/xml_int/mod_xml_scgi/xml_scgi_server.pl +++ b/src/mod/xml_int/mod_xml_scgi/xml_scgi_server.pl @@ -65,7 +65,7 @@ $SIG{CHLD} = "IGNORE"; while (my $request = $scgi->accept) { # fork every new req into its own process (optional) - my $pid = fork(); + my $pid = switch_fork(); if ($pid) { $request->close(); diff --git a/src/switch.c b/src/switch.c index 4f8678a97f..0ddefbc5da 100644 --- a/src/switch.c +++ b/src/switch.c @@ -262,7 +262,7 @@ static void daemonize(int do_wait) } } - pid = fork(); + pid = switch_fork(); switch (pid) { case 0: /* child process */ diff --git a/src/switch_core.c b/src/switch_core.c index 1d87d9ce2e..70d4cd5d0f 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2731,15 +2731,33 @@ SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl) } - #ifdef WIN32 static int switch_system_fork(const char *cmd, switch_bool_t wait) { return switch_system_thread(cmd, wait); } +SWITCH_DECLARE(pid_t) switch_fork(void) +{ + return -1; +} + + #else +SWITCH_DECLARE(pid_t) switch_fork(void) +{ + int i = fork(); + + if (!i) { + set_low_priority(); + } + + return i; +} + + + static int switch_system_fork(const char *cmd, switch_bool_t wait) { int pid; @@ -2747,7 +2765,7 @@ static int switch_system_fork(const char *cmd, switch_bool_t wait) switch_core_set_signal_handlers(); - pid = fork(); + pid = switch_fork(); if (pid) { if (wait) { @@ -2757,7 +2775,6 @@ static int switch_system_fork(const char *cmd, switch_bool_t wait) } else { switch_close_extra_files(NULL, 0); - set_low_priority(); if (system(dcmd) == -1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd); } @@ -2793,7 +2810,7 @@ SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_han if (pipe(fds)) { goto end; } else { /* good to go */ - pid = fork(); + pid = switch_fork(); if (pid < 0) { /* ok maybe not */ close(fds[0]); diff --git a/src/switch_xml.c b/src/switch_xml.c index a4da3ca6cf..f441567cac 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -1238,7 +1238,7 @@ static FILE *preprocess_exec(const char *cwd, const char *command, FILE *write_f if (pipe(fds)) { goto end; } else { /* good to go */ - pid = fork(); + pid = switch_fork(); if (pid < 0) { /* ok maybe not */ close(fds[0]); From 5620d6d063b104502208a46e0c3170de5f74237c Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 1 Oct 2012 20:34:15 -0500 Subject: [PATCH 096/512] windows fixes for priority - needs to be revisited when apr and pthread versions support calls. --- libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c | 3 +++ src/switch_apr.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c index 9899da6f47..90b335d491 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c @@ -268,7 +268,10 @@ int su_pthreaded_port_start(su_port_create_f *create, pthread_mutex_lock(arg.mutex); if (pthread_create(&tid, &attr, su_pthread_port_clone_main, &arg) == 0) { +#ifndef WIN32 + /* this needs to be revisited when pthread for windows supports thread priority settings */ pthread_setschedprio(tid, 99); +#endif pthread_cond_wait(arg.cv, arg.mutex); thread_created = 1; } diff --git a/src/switch_apr.c b/src/switch_apr.c index 64e066853e..2fcb2cd81e 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -620,6 +620,14 @@ struct apr_threadattr_t { pthread_attr_t attr; int priority; }; +#else +/* this needs to be revisited when apr for windows supports thread priority settings */ +/* search for WIN32 in this file */ +struct apr_threadattr_t { + apr_pool_t *pool; + apr_int32_t detach; + apr_size_t stacksize; +}; #endif @@ -628,7 +636,9 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_create(switch_threadattr_t ** switch_status_t status; if ((status = apr_threadattr_create(new_attr, pool)) == SWITCH_STATUS_SUCCESS) { +#ifndef WIN32 (*new_attr)->priority = SWITCH_PRI_NORMAL; +#endif } return status; From bc06155740c409f23527ef1602b36a0426c097c5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2012 07:39:21 -0500 Subject: [PATCH 097/512] more priority tweaks --- src/switch_apr.c | 2 +- src/switch_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_apr.c b/src/switch_apr.c index 2fcb2cd81e..aeb10185a9 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -637,7 +637,7 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_create(switch_threadattr_t ** if ((status = apr_threadattr_create(new_attr, pool)) == SWITCH_STATUS_SUCCESS) { #ifndef WIN32 - (*new_attr)->priority = SWITCH_PRI_NORMAL; + (*new_attr)->priority = SWITCH_PRI_LOW; #endif } diff --git a/src/switch_core.c b/src/switch_core.c index 70d4cd5d0f..4912f0abd8 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -735,7 +735,7 @@ SWITCH_DECLARE(int32_t) set_realtime_priority(void) const char *rt = "/proc/sys/kernel/sched_rt_runtime_us"; char data[] = "-1\n"; struct sched_param sched = { 0 }; - sched.sched_priority = SWITCH_PRI_REALTIME; + sched.sched_priority = SWITCH_PRI_LOW; if (sched_setscheduler(0, SCHED_RR, &sched)) { sched.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, &sched)) { From b97e0cef29aa44ea22687250e306ede822c98a8e Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Tue, 2 Oct 2012 11:54:19 -0400 Subject: [PATCH 098/512] don't disable dial if previously allowed --- src/mod/applications/mod_httapi/mod_httapi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 887dae3891..35427c7b79 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -1970,19 +1970,19 @@ static switch_status_t do_config(void) } else if (!strcasecmp(var, "dial")) { profile->perms.dial.enabled = switch_true(val); } else if (!strcasecmp(var, "dial-set-context")) { - profile->perms.dial.enabled = switch_true(val); + if (switch_true(val)) profile->perms.dial.enabled = SWITCH_TRUE; profile->perms.dial.set_context = switch_true(val); } else if (!strcasecmp(var, "dial-set-dialplan")) { - profile->perms.dial.enabled = switch_true(val); + if (switch_true(val)) profile->perms.dial.enabled = SWITCH_TRUE; profile->perms.dial.set_dp = switch_true(val); } else if (!strcasecmp(var, "dial-set-cid-name")) { - profile->perms.dial.enabled = switch_true(val); + if (switch_true(val)) profile->perms.dial.enabled = SWITCH_TRUE; profile->perms.dial.set_cid_name = switch_true(val); } else if (!strcasecmp(var, "dial-set-cid-number")) { - profile->perms.dial.enabled = switch_true(val); + if (switch_true(val)) profile->perms.dial.enabled = SWITCH_TRUE; profile->perms.dial.set_cid_number = switch_true(val); } else if (!strcasecmp(var, "dial-full-originate")) { - profile->perms.dial.enabled = switch_true(val); + if (switch_true(val)) profile->perms.dial.enabled = SWITCH_TRUE; profile->perms.dial.full_originate = switch_true(val); } else if (!strcasecmp(var, "conference")) { profile->perms.conference.enabled = switch_true(val); From ff3c0139fc9ab48b71b5a2723f6db06c0fd0f054 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2012 09:29:25 -0500 Subject: [PATCH 099/512] auto-answer A leg when B leg is already answered in all conditions not just when A leg is both unanswered and has no media --- src/switch_ivr_bridge.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 590ebcea34..990b121f00 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1304,10 +1304,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_core_session_rwunlock(peer_session); goto done; } + } - if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) { - switch_channel_answer(caller_channel); - } + if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) { + switch_channel_answer(caller_channel); } switch_channel_wait_for_flag(peer_channel, CF_BROADCAST, SWITCH_FALSE, 10000, caller_channel); From 10657f3f5c1fb00d6b8e85d3956c170695b169bd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2012 11:56:21 -0500 Subject: [PATCH 100/512] FS-4675 --resolve --- .../applications/mod_commands/mod_commands.c | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index d823af7194..892d6e7479 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1563,15 +1563,19 @@ SWITCH_STANDARD_API(regex_function) proceed = switch_regex_perform(argv[0], argv[1], &re, ovector, sizeof(ovector) / sizeof(ovector[0])); if (argc > 2) { - len = (strlen(argv[0]) + strlen(argv[2]) + 10) * proceed; - substituted = malloc(len); - switch_assert(substituted); - memset(substituted, 0, len); - switch_replace_char(argv[2], '%', '$', SWITCH_FALSE); - switch_perform_substitution(re, proceed, argv[2], argv[0], substituted, len, ovector); + if (proceed) { + len = (strlen(argv[0]) + strlen(argv[2]) + 10) * proceed; + substituted = malloc(len); + switch_assert(substituted); + memset(substituted, 0, len); + switch_replace_char(argv[2], '%', '$', SWITCH_FALSE); + switch_perform_substitution(re, proceed, argv[2], argv[0], substituted, len, ovector); - stream->write_function(stream, "%s", substituted); - free(substituted); + stream->write_function(stream, "%s", substituted); + free(substituted); + } else { + stream->write_function(stream, "%s", argv[0]); + } } else { stream->write_function(stream, proceed ? "true" : "false"); } From 80c2bd786a6b1f20dd577b6d9d810f7a0cf02d3e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2012 10:30:51 -0500 Subject: [PATCH 101/512] FS-4669 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 22 ++++++++++++++++++++-- src/switch_rtp.c | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 3b5277647f..2a6dc4cc5f 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5839,13 +5839,31 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } - if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && - sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) { + if (sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) { has_t38 = 1; } if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { sofia_clear_flag(tech_pvt, TFLAG_T38_PASSTHRU); + has_t38 = 0; + } + + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && has_t38) { + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_udptl_mode(tech_pvt->rtp_session); + + if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid))) { + if (switch_core_session_compare(session, other_session)) { + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + if (switch_rtp_ready(other_tech_pvt->rtp_session)) { + switch_rtp_udptl_mode(other_tech_pvt->rtp_session); + } + } + switch_core_session_rwunlock(other_session); + } + } + + has_t38 = 0; } if (status > 199 && (switch_channel_test_flag(channel, CF_PROXY_MODE) || diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 14fbe1a849..0acae50c19 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4520,7 +4520,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra send_msg = frame->packet; - if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) { + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && !switch_test_flag(frame, SFF_UDPTL_PACKET)) { if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { send_msg->header.pt = rtp_session->payload; } From 2722f4da194b98de8cb5415c6d1af651b9d5af90 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2012 11:02:42 -0500 Subject: [PATCH 102/512] FS-4674 add loopback_export for a list of channel vars to pass from loopback-a to loopback-b --- src/mod/endpoints/mod_loopback/mod_loopback.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index e2a2c3daab..e8a8ab8c18 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -992,6 +992,24 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } if (switch_event_dup(&clone, var_event) == SWITCH_STATUS_SUCCESS) { + const char *var; + + if ((var = switch_channel_get_variable(channel, "loopback_export"))) { + int argc = 0; + char *argv[128] = { 0 }; + char *dup = switch_core_session_strdup(session, var); + + if ((argc = switch_split(dup, ',', argv))) { + int i; + for (i = 0; i < argc; i++) { + if (!zstr(argv[i])) { + const char *val = switch_channel_get_variable(channel, argv[i]); + switch_event_add_header_string(clone, SWITCH_STACK_BOTTOM, argv[i], val); + } + } + } + } + switch_channel_set_private(channel, "__loopback_vars__", clone); } From 51bdf8522a1a17fc4d09ba78473772cb2c7071e1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2012 12:22:03 -0500 Subject: [PATCH 103/512] FS-4677 --resolve --- .../applications/mod_conference/mod_conference.c | 13 +++++++++---- src/mod/endpoints/mod_sofia/sofia.c | 5 ++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 3acb7d6c55..ada1d84877 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1325,7 +1325,7 @@ static void send_rfc_event(conference_obj_t *conference) -static void send_conference_notify(conference_obj_t *conference, const char *status, switch_bool_t final) +static void send_conference_notify(conference_obj_t *conference, const char *status, const char *call_id, switch_bool_t final) { switch_event_t *event; char *name = NULL, *domain = NULL, *dup_domain = NULL; @@ -1352,6 +1352,7 @@ static void send_conference_notify(conference_obj_t *conference, const char *sta switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-event", "refer"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", call_id); if (final) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "final", "true"); @@ -6566,9 +6567,11 @@ static switch_status_t conference_outcall(conference_obj_t *conference, switch_bool_t have_flags = SWITCH_FALSE; const char *outcall_flags; int track = 0; + const char *call_id; if (var_event && switch_true(switch_event_get_header(var_event, "conference_track_status"))) { track++; + call_id = switch_event_get_header(var_event, "conference_track_call_id"); } *cause = SWITCH_CAUSE_NORMAL_CLEARING; @@ -6613,7 +6616,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference, switch_mutex_unlock(conference->mutex); if (track) { - send_conference_notify(conference, "SIP/2.0 100 Trying\r\n", SWITCH_FALSE); + send_conference_notify(conference, "SIP/2.0 100 Trying\r\n", call_id, SWITCH_FALSE); } @@ -6630,14 +6633,14 @@ static switch_status_t conference_outcall(conference_obj_t *conference, } if (track) { - send_conference_notify(conference, "SIP/2.0 481 Failure\r\n", SWITCH_TRUE); + send_conference_notify(conference, "SIP/2.0 481 Failure\r\n", call_id, SWITCH_TRUE); } goto done; } if (track) { - send_conference_notify(conference, "SIP/2.0 200 OK\r\n", SWITCH_TRUE); + send_conference_notify(conference, "SIP/2.0 200 OK\r\n", call_id, SWITCH_TRUE); } rdlock = 1; @@ -8571,6 +8574,7 @@ static void call_setup_event_handler(switch_event_t *event) char *action = switch_event_get_header(event, "Request-Action"); char *ext = switch_event_get_header(event, "Request-Target-Extension"); char *full_url = switch_event_get_header(event, "full_url"); + char *call_id = switch_event_get_header(event, "Request-Call-ID"); if (!ext) ext = dial_str; @@ -8600,6 +8604,7 @@ static void call_setup_event_handler(switch_event_t *event) switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_invite_uri", dial_uri); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_status", "true"); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_call_id", call_id); if (!strncasecmp(ostr, "url+", 4)) { ostr += 4; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2a6dc4cc5f..a74a490da8 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1326,7 +1326,10 @@ static void our_sofia_event_callback(nua_event_t event, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "full-url", "true"); } - + if (sip->sip_call_id && sip->sip_call_id->i_id) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Call-ID", sip->sip_call_id->i_id); + } + if (!zstr(referred_by)) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Sender", "sofia/%s/%s", profile->name, referred_by); } From d84df73aaa87b46b781c53e8388bae83b33b88dc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2012 17:03:22 -0500 Subject: [PATCH 104/512] FS-4677 oops --- src/mod/applications/mod_conference/mod_conference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index ada1d84877..089879ad40 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -6567,7 +6567,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference, switch_bool_t have_flags = SWITCH_FALSE; const char *outcall_flags; int track = 0; - const char *call_id; + const char *call_id = NULL; if (var_event && switch_true(switch_event_get_header(var_event, "conference_track_status"))) { track++; From 686a89a7984b05a7ee2a7b68619d7a14d0a83366 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 3 Oct 2012 02:15:51 +0000 Subject: [PATCH 105/512] debian: Formatting fix --- debian/README.Debian | 4 ++-- debian/README.source | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/README.Debian b/debian/README.Debian index 72be2ce528..99bf84c567 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -1,5 +1,5 @@ FreeSWITCH for Debian --------------- +--------------------- This debian packaging breaks out every module of freeswitch into a separate package, so be sure to verify that you are actually @@ -23,4 +23,4 @@ recommend doing the following: /etc/init.d/freeswitch start fs_cli - -- Travis Cross , Sat, 5 May 2012 23:41:29 +0000 + -- Travis Cross , Wed, 3 Oct 2012 02:15:32 +0000 diff --git a/debian/README.source b/debian/README.source index f432311158..1f1f054f8e 100644 --- a/debian/README.source +++ b/debian/README.source @@ -1,5 +1,5 @@ FreeSWITCH for Debian --------------- +--------------------- You may be reading this because you're wondering where all the files are in debian/, such as control. You may also be here looking for the @@ -94,4 +94,4 @@ freeswitch-music-*: git clone https://github.com/traviscross/freeswitch-sounds.git cd freeswitch-sounds && cat debian/README.source - -- Travis Cross , Tue, 4 Sep 2012 14:56:52 +0000 + -- Travis Cross , Wed, 3 Oct 2012 02:15:24 +0000 From 03fce657e8ed7ccf2d38b2014dd595d7901d0756 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Oct 2012 07:09:59 -0500 Subject: [PATCH 106/512] FS-4549 --resolve --- .../applications/mod_commands/mod_commands.c | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 892d6e7479..38e85a47c2 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -286,7 +286,28 @@ SWITCH_STANDARD_API(shutdown_function) SWITCH_STANDARD_API(version_function) { - stream->write_function(stream, "FreeSWITCH Version %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN); + int argc; + char *mydata = NULL, *argv[2]; + + if (zstr(cmd)) { + stream->write_function(stream, "FreeSWITCH Version %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN); + goto end; + } + + mydata = strdup(cmd); + switch_assert(mydata); + + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argv[0] && switch_stristr("short", argv[0])) { + stream->write_function(stream, "%s.%s.%s\n", SWITCH_VERSION_MAJOR,SWITCH_VERSION_MINOR,SWITCH_VERSION_MICRO); + } else { + stream->write_function(stream, "FreeSWITCH Version %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_FULL_HUMAN); + } + + switch_safe_free(mydata); + +end: return SWITCH_STATUS_SUCCESS; } @@ -5658,7 +5679,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "fsctl", "control messages", ctl_function, CTL_SYNTAX); SWITCH_ADD_API(commands_api_interface, "...", "shutdown", shutdown_function, ""); SWITCH_ADD_API(commands_api_interface, "shutdown", "shutdown", shutdown_function, ""); - SWITCH_ADD_API(commands_api_interface, "version", "version", version_function, ""); + SWITCH_ADD_API(commands_api_interface, "version", "version", version_function, "[short]"); SWITCH_ADD_API(commands_api_interface, "global_getvar", "global_getvar", global_getvar_function, GLOBAL_GETVAR_SYNTAX); SWITCH_ADD_API(commands_api_interface, "global_setvar", "global_setvar", global_setvar_function, GLOBAL_SETVAR_SYNTAX); SWITCH_ADD_API(commands_api_interface, "group_call", "Generate a dial string to call a group", group_call_function, "[@]"); From ea599992e1fc150f63bc3fa96bcc34d1d570c1ad Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Oct 2012 07:42:05 -0500 Subject: [PATCH 107/512] FS-4656 --resolve with this patch the bug is fixed but also the old behaviour of setting this variable on the A leg expecting it to auto-set it on the B leg is no longer supported. It must be exported or put in the dialstring with {} to put it on the B leg going forward --- src/mod/endpoints/mod_sofia/mod_sofia.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index a9721b4c49..d3a8b8a104 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4909,13 +4909,8 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (session) { const char *vval = NULL; - if ((vval = switch_channel_get_variable(o_channel, "sip_auto_answer")) && switch_true(vval)) { - switch_channel_set_variable_printf(nchannel, "sip_h_Call-Info", ";answer-after=0", profile->sipip); - switch_channel_set_variable(nchannel, "sip_invite_params", "intercom=true"); - } - switch_ivr_transfer_variable(session, nsession, SOFIA_REPLACES_HEADER); - switch_ivr_transfer_variable(session, nsession, "sip_auto_answer"); + if (!(vval = switch_channel_get_variable(o_channel, "sip_copy_custom_headers")) || switch_true(vval)) { switch_ivr_transfer_variable(session, nsession, SOFIA_SIP_HEADER_PREFIX_T); } From 7329787b9a536d0dc9304677ea8980882e2cfe05 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Oct 2012 07:45:39 -0500 Subject: [PATCH 108/512] fix warning --- src/mod/applications/mod_commands/mod_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 38e85a47c2..f1a9953fde 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -299,7 +299,7 @@ SWITCH_STANDARD_API(version_function) argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if (argv[0] && switch_stristr("short", argv[0])) { + if (argc > 0 && switch_stristr("short", argv[0])) { stream->write_function(stream, "%s.%s.%s\n", SWITCH_VERSION_MAJOR,SWITCH_VERSION_MINOR,SWITCH_VERSION_MICRO); } else { stream->write_function(stream, "FreeSWITCH Version %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_FULL_HUMAN); From cefeaee88c0a2127a670a3e5f66c44d4fa856fc3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Oct 2012 07:46:37 -0500 Subject: [PATCH 109/512] FS-4650 --resolve --- .../applications/mod_commands/mod_commands.c | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index f1a9953fde..a4554a7925 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -181,6 +181,141 @@ SWITCH_STANDARD_API(say_string_function) } +static void dump_user(const char *dname, const char* gname, switch_xml_t x_user_tag, switch_stream_handle_t *stream, const char *_context) +{ + switch_xml_t x_vars, x_var; + switch_status_t status; + switch_stream_handle_t apistream = { 0 }; + char *user_context = NULL; + char *effective_caller_id_name = NULL; + char *effective_caller_id_number = NULL; + char *callgroup = NULL; + + if (!x_user_tag) { + return; + } + + if ((x_vars = switch_xml_child(x_user_tag, "variables"))) { + for (x_var = switch_xml_child(x_vars, "variable"); x_var; x_var = x_var->next) { + const char *key = switch_xml_attr_soft(x_var, "name"); + const char *val = switch_xml_attr_soft(x_var, "value"); + + if (!strcasecmp(key, "user_context")) { + user_context = (char*) val; + } else if (!strcasecmp(key, "effective_caller_id_name")) { + effective_caller_id_name = (char*) val; + } else if (!strcasecmp(key, "effective_caller_id_number")) { + effective_caller_id_number = (char*) val; + } else if (!strcasecmp(key, "callgroup")) { + callgroup = (char*) val; + } else { + continue; + } + } + } + + if (_context) { + if (zstr(user_context) || strcasecmp(_context, user_context)) { + return; + } + } + + SWITCH_STANDARD_STREAM(apistream); + if ((status = switch_api_execute("sofia_contact", switch_xml_attr_soft(x_user_tag, "id"), NULL, &apistream)) != SWITCH_STATUS_SUCCESS) { + switch_safe_free(apistream.data); + return; + } + stream->write_function(stream, "%s|%s|%s|%s|%s|%s|%s|%s\n", switch_xml_attr_soft(x_user_tag, "id"), user_context, dname, gname, apistream.data, callgroup, effective_caller_id_name, effective_caller_id_number); + switch_safe_free(apistream.data); + + return; +} + +#define LIST_USERS_SYNTAX "[group ] [domain ] [user ] [context ]" +SWITCH_STANDARD_API(list_users_function) +{ + int argc; + char *pdata, *argv[8]; + int32_t arg = 0; + switch_xml_t xml_root, x_domains, x_domain_tag; + switch_xml_t gts, gt, uts, ut; + char *_user = NULL, *_domain = NULL, *_context = NULL, *_group = NULL; + + + if ((pdata = strdup(cmd))) { + argc = switch_separate_string(pdata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (argc >= 8) { + stream->write_function(stream, "-USAGE: %s\n", LIST_USERS_SYNTAX); + goto done; + } + + for (arg = 0; arg < argc; arg++) { + if (!strcasecmp(argv[arg], "user")) { + _user = argv[arg + 1]; + } + if (!strcasecmp(argv[arg], "domain")) { + _domain = argv[arg + 1]; + } + if (!strcasecmp(argv[arg], "context")) { + _context = argv[arg + 1]; + } + if (!strcasecmp(argv[arg], "group")) { + _group = argv[arg + 1]; + } + } + } + + stream->write_function(stream, "userid|context|domain|group|contact|callgroup|effective_caller_id_name|effective_caller_id_number\n"); + + if (switch_xml_locate("directory", NULL, NULL, NULL, &xml_root, &x_domains, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { + const char *dname = NULL; + const char *gname = NULL; + + for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) { + dname = switch_xml_attr_soft(x_domain_tag, "name"); + + if (_domain && strcasecmp(_domain, dname)) { + continue; + } + + if ((gts = switch_xml_child(x_domain_tag, "groups"))) { + for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) { + gname = switch_xml_attr_soft(gt, "name"); + + if (_group && strcasecmp(_group, gname)) { + continue; + } + + for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) { + for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) { + if (_user && strcasecmp(_user, switch_xml_attr_soft(ut, "id"))) { + continue; + } + dump_user(dname, gname, ut, stream, _context); + } + } + } + } else { + for (uts = switch_xml_child(x_domain_tag, "users"); uts; uts = uts->next) { + for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) { + if (_user && strcasecmp(_user, switch_xml_attr_soft(ut, "id"))) { + continue; + } + dump_user(dname, gname, ut, stream, _context); + } + } + } + } + switch_xml_free(xml_root); + } + + stream->write_function(stream, "\n+OK\n"); + +done: + switch_safe_free(pdata); + return SWITCH_STATUS_SUCCESS; +} SWITCH_STANDARD_API(reg_url_function) { @@ -5695,6 +5830,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "limit_status", "Gets the status of a limit backend", limit_status_function, ""); SWITCH_ADD_API(commands_api_interface, "limit_reset", "Reset the counters of a limit backend", limit_reset_function, ""); SWITCH_ADD_API(commands_api_interface, "limit_interval_reset", "Reset the interval counter for a limited resource", limit_interval_reset_function, LIMIT_INTERVAL_RESET_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "list_users", "List Users configured in Directory", list_users_function, LIST_USERS_SYNTAX); SWITCH_ADD_API(commands_api_interface, "load", "Load Module", load_function, LOAD_SYNTAX); SWITCH_ADD_API(commands_api_interface, "log", "Log", log_function, LOG_SYNTAX); SWITCH_ADD_API(commands_api_interface, "md5", "md5", md5_function, ""); From fd177cdf332a02d84e7ff514afe3883cc5371548 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Oct 2012 09:29:50 -0500 Subject: [PATCH 110/512] FS-4676 going over the traces the only thing I can guess is that you may have some race condition on the speed of your box or something regarding the db, Try this patch that may help --- src/mod/endpoints/mod_sofia/sofia_presence.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 10d741bca4..d7d7a49cf7 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3138,9 +3138,6 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char switch_snprintf(key, sizeof(key), "%s%s", user, host); data = switch_core_hash_find(sh->hash, key); - - data = switch_core_hash_find(sh->hash, key); - if (data) { tmp = switch_core_sprintf(sh->pool, "%s,;appearance-index=*;appearance-state=idle", data, host); } else { @@ -3354,7 +3351,7 @@ static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *t switch_core_hash_init(&sh->hash, sh->pool); sql = switch_mprintf("select sip_from_user,sip_from_host,call_info,call_info_state,uuid from sip_dialogs " - "where call_info_state is not null and call_info_state != '' and hostname='%q' and profile_name='%q' " + "where call_info_state is not null and call_info_state != '' and call_info_state != 'idle' and hostname='%q' and profile_name='%q' " "and ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') " "and profile_name='%q'", mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host, profile->name); From 6d01ad5e38ebc536ad3f7166a024db48b71123ef Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Oct 2012 14:10:22 -0500 Subject: [PATCH 111/512] some more priority tweaks --- src/mod/endpoints/mod_sofia/sofia.c | 4 ++-- src/switch_core.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index a74a490da8..26ff378ee4 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1650,7 +1650,7 @@ void sofia_msg_thread_start(int idx) switch_threadattr_create(&thd_attr, mod_sofia_globals.pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); + //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&mod_sofia_globals.msg_queue_thread[i], thd_attr, sofia_msg_thread_run, @@ -2376,7 +2376,7 @@ switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile) switch_threadattr_create(&thd_attr, profile->pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); + //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_thread_create(&thread, thd_attr, sofia_profile_worker_thread_run, profile, profile->pool); while (!sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)) { diff --git a/src/switch_core.c b/src/switch_core.c index 4912f0abd8..4e47519757 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -736,7 +736,7 @@ SWITCH_DECLARE(int32_t) set_realtime_priority(void) char data[] = "-1\n"; struct sched_param sched = { 0 }; sched.sched_priority = SWITCH_PRI_LOW; - if (sched_setscheduler(0, SCHED_RR, &sched)) { + if (sched_setscheduler(0, SCHED_FIFO, &sched)) { sched.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, &sched)) { return -1; From 61033f420bd0a4a11061b705a415b6007c96be99 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 3 Oct 2012 14:19:34 -0500 Subject: [PATCH 112/512] revert --- src/include/switch_core.h | 3 --- src/switch_console.c | 4 +-- src/switch_core_sqldb.c | 53 ++------------------------------------- 3 files changed, 4 insertions(+), 56 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index efd983ded8..540de6e537 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2303,9 +2303,6 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); #define switch_core_recovery_db_handle(_a) _switch_core_recovery_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) -SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); -#define switch_core_persist_db_handle(_a) _switch_core_persist_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) - SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_handle_t *db, const char *test_sql, const char *drop_sql, const char *reactive_sql); SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries); diff --git a/src/switch_console.c b/src/switch_console.c index d461333860..059ff79d59 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -248,7 +248,7 @@ SWITCH_DECLARE(char *) switch_console_expand_alias(char *cmd, char *arg) return NULL; } - if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); return NULL; } @@ -1859,7 +1859,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string) switch_cache_db_handle_t *db = NULL; char *sql = NULL; - if (switch_core_persist_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); free(mydata); return SWITCH_STATUS_FALSE; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 556e3abab2..b4a58bbd9d 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -176,7 +176,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user } -#define SWITCH_CORE_DB "file:scoreboard?mode=memory&cache=shared" +#define SWITCH_CORE_DB "core" /*! \brief Open the default system database */ @@ -218,49 +218,6 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t return r; } -#define SWITCH_CORE_PERSIST_DB "core" -/*! - \brief Open the default system database -*/ -SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) -{ - switch_cache_db_connection_options_t options = { {0} }; - switch_status_t r; - - if (!sql_manager.manage) { - return SWITCH_STATUS_FALSE; - } - - if (zstr(runtime.odbc_dsn)) { - if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) { - return SWITCH_STATUS_FALSE; - } - - if (runtime.dbname) { - options.core_db_options.db_path = runtime.dbname; - } else { - options.core_db_options.db_path = SWITCH_CORE_PERSIST_DB; - } - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); - - } else { - options.odbc_options.dsn = runtime.odbc_dsn; - options.odbc_options.user = runtime.odbc_user; - options.odbc_options.pass = runtime.odbc_pass; - - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); - } - - /* I *think* we can do without this now, if not let me know - if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager.io_mutex; - } - */ - - return r; -} - - #define SWITCH_CORE_RECOVERY_DB "core_recovery" SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { @@ -2409,13 +2366,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ break; } - { - switch_cache_db_handle_t *db = NULL; - switch_core_persist_db_handle(&db); - switch_cache_db_test_reactive(db, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); - switch_cache_db_release_db_handle(&db); - } - + switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", From 7afd4cae6708fb68accb663c56a639daef8d8178 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Oct 2012 08:02:32 -0500 Subject: [PATCH 113/512] FS-4677 --- src/mod/endpoints/mod_sofia/sofia_presence.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index d7d7a49cf7..eea01d50a5 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -934,7 +934,7 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, " "'%q' as ct,'%q' as pt " " from sip_subscriptions where " - "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'" + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' " "and call_id = '%q' ", switch_sql_concat(), type, @@ -956,10 +956,19 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb); if (switch_true(final)) { - sql = switch_mprintf("delete from sip_subscriptions where " - "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", - mod_sofia_globals.hostname, profile->name, - from_user, from_host, event_str); + if (call_id) { + sql = switch_mprintf("delete from sip_subscriptions where " + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' " + "and call_id = '%q' ", + mod_sofia_globals.hostname, profile->name, + from_user, from_host, event_str, call_id); + + } else { + sql = switch_mprintf("delete from sip_subscriptions where " + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", + mod_sofia_globals.hostname, profile->name, + from_user, from_host, event_str); + } sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } From 3d57cbda984ebad46fa6c1a94dfd8109b130a2b9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 4 Oct 2012 08:29:26 -0500 Subject: [PATCH 114/512] pull this code echo -1 > /proc/sys/kernel/sched_rt_runtime_us yourself if you want to enable this --- src/switch_core.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/switch_core.c b/src/switch_core.c index 4e47519757..95a7b4dbed 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -731,9 +731,6 @@ SWITCH_DECLARE(int32_t) set_realtime_priority(void) * Try to use a round-robin scheduler * with a fallback if that does not work */ - int fd; - const char *rt = "/proc/sys/kernel/sched_rt_runtime_us"; - char data[] = "-1\n"; struct sched_param sched = { 0 }; sched.sched_priority = SWITCH_PRI_LOW; if (sched_setscheduler(0, SCHED_FIFO, &sched)) { @@ -742,21 +739,6 @@ SWITCH_DECLARE(int32_t) set_realtime_priority(void) return -1; } } - - if ((fd = open(rt, O_WRONLY)) > 0) { - int r; - - if (!(r = write(fd, data, sizeof(data)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Disablling RT limits [%s][%d]\n", rt, r); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Disabling RT throttling.\n"); - } - close(fd); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening %s\n", rt); - } - - #endif From 391e7c365b02d9b822bfeb0daa1fd6e9788c6ba1 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Fri, 5 Oct 2012 16:11:12 +0000 Subject: [PATCH 115/512] Rename switch_hash_first() and switch_hash_next() to switch_core_hash_first() and switch_core_hash_next() and deprecate the older versions. --- src/include/switch_core.h | 29 +++++++++++++++++++++++++++-- src/switch_core_hash.c | 25 ++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index efd983ded8..a7c4122759 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1332,14 +1332,14 @@ SWITCH_DECLARE(void *) switch_core_hash_find_rdlock(_In_ switch_hash_t *hash, _I \param hash the hashtable to use \return The element, or NULL if it wasn't found */ -SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *deprecate_me, _In_ switch_hash_t *hash); +SWITCH_DECLARE(switch_hash_index_t *) switch_core_hash_first(_In_ switch_hash_t *hash); /*! \brief Gets the next element of a hashtable \param hi The current element \return The next element, or NULL if there are no more */ -SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(_In_ switch_hash_index_t *hi); +SWITCH_DECLARE(switch_hash_index_t *) switch_core_hash_next(_In_ switch_hash_index_t *hi); /*! \brief Gets the key and value of the current hash element @@ -1348,6 +1348,31 @@ SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(_In_ switch_hash_index_t \param klen [out] the key's size \param val [out] the value */ +SWITCH_DECLARE(void) switch_core_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptrdiff_cap_(klen) + const void **key, _Out_opt_ switch_ssize_t *klen, _Out_ void **val); + +/*! + \brief DEPRECATED in favor of switch_core_hash_first(). Gets the first element of a hashtable. + \param deprecate_me [deprecated] NULL + \param hash the hashtable to use + \return The element, or NULL if it wasn't found +*/ +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *deprecate_me, _In_ switch_hash_t *hash); + +/*! + \brief DEPRECATED in favor of switch_core_hash_next(). Gets the next element of a hashtable. + \param hi The current element + \return The next element, or NULL if there are no more +*/ +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(_In_ switch_hash_index_t *hi); + +/*! + \brief DEPRECATED in favor of switch_core_hash_this(). Gets the key and value of the current hash element. + \param hi The current element + \param key [out] the key + \param klen [out] the key's size + \param val [out] the value +*/ SWITCH_DECLARE(void) switch_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptrdiff_cap_(klen) const void **key, _Out_opt_ switch_ssize_t *klen, _Out_ void **val); diff --git a/src/switch_core_hash.c b/src/switch_core_hash.c index c31a31fa9c..fd9494374a 100644 --- a/src/switch_core_hash.c +++ b/src/switch_core_hash.c @@ -222,17 +222,17 @@ SWITCH_DECLARE(void *) switch_core_hash_find_rdlock(switch_hash_t *hash, const c return val; } -SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *deprecate_me, switch_hash_t *hash) +SWITCH_DECLARE(switch_hash_index_t *) switch_core_hash_first(switch_hash_t *hash) { return (switch_hash_index_t *) sqliteHashFirst(&hash->table); } -SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(switch_hash_index_t *hi) +SWITCH_DECLARE(switch_hash_index_t *) switch_core_hash_next(switch_hash_index_t *hi) { return (switch_hash_index_t *) sqliteHashNext((HashElem *) hi); } -SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t *hi, const void **key, switch_ssize_t *klen, void **val) +SWITCH_DECLARE(void) switch_core_hash_this(switch_hash_index_t *hi, const void **key, switch_ssize_t *klen, void **val) { if (key) { *key = sqliteHashKey((HashElem *) hi); @@ -245,6 +245,25 @@ SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t *hi, const void **key, } } +/* Deprecated */ +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *deprecate_me, switch_hash_t *hash) +{ + (void*)(deprecate_me); + return switch_core_hash_first(hash); +} + +/* Deprecated */ +SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(switch_hash_index_t *hi) +{ + return switch_core_hash_next(hi); +} + +/* Deprecated */ +SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t *hi, const void **key, switch_ssize_t *klen, void **val) +{ + return switch_core_hash_this(hi, key, klen, val); +} + /* For Emacs: * Local Variables: * mode:c From 5bc1f537bc35287ababb1530df9e1ac37a92bf19 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Fri, 5 Oct 2012 16:48:03 +0000 Subject: [PATCH 116/512] Fix compiler warnings. --- src/switch_core_hash.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/switch_core_hash.c b/src/switch_core_hash.c index fd9494374a..4159d8b5fa 100644 --- a/src/switch_core_hash.c +++ b/src/switch_core_hash.c @@ -248,7 +248,6 @@ SWITCH_DECLARE(void) switch_core_hash_this(switch_hash_index_t *hi, const void * /* Deprecated */ SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *deprecate_me, switch_hash_t *hash) { - (void*)(deprecate_me); return switch_core_hash_first(hash); } @@ -261,7 +260,7 @@ SWITCH_DECLARE(switch_hash_index_t *) switch_hash_next(switch_hash_index_t *hi) /* Deprecated */ SWITCH_DECLARE(void) switch_hash_this(switch_hash_index_t *hi, const void **key, switch_ssize_t *klen, void **val) { - return switch_core_hash_this(hi, key, klen, val); + switch_core_hash_this(hi, key, klen, val); } /* For Emacs: From a6602206deca73496d031efaefa5b6b5ec4610d3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Oct 2012 09:00:30 -0500 Subject: [PATCH 117/512] FS-4684 try this, this behaviour is not supported in proxy mode --- src/mod/endpoints/mod_sofia/sofia_glue.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 4c0ae8de1f..a67bc97b36 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1830,6 +1830,9 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt) tech_pvt->video_rm_rate = 90000; tech_pvt->video_codec_ms = 0; switch_snprintf(vport_buf, sizeof(vport_buf), "%u", tech_pvt->adv_sdp_video_port); + if (switch_channel_media_ready(tech_pvt->channel) && !switch_rtp_ready(tech_pvt->video_rtp_session)) { + sofia_glue_activate_rtp(tech_pvt, 0); + } } strncpy(q, p, 8); From 44f78e9e76c4db689a39888bf72b31aaf58b5568 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Oct 2012 09:43:00 -0500 Subject: [PATCH 118/512] FS-4650 --resolve --- .../applications/mod_commands/mod_commands.c | 123 +++++++++++++++--- 1 file changed, 103 insertions(+), 20 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index a4554a7925..f3fad29e43 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -181,20 +181,57 @@ SWITCH_STANDARD_API(say_string_function) } -static void dump_user(const char *dname, const char* gname, switch_xml_t x_user_tag, switch_stream_handle_t *stream, const char *_context) +struct user_struct { + char *dname; + char *gname; + char *effective_caller_id_name; + char *effective_caller_id_number; + char *callgroup; + switch_xml_t x_user_tag; + switch_stream_handle_t *stream; + char *search_context; + char *context; + switch_xml_t x_domain_tag; +}; + +static void dump_user(struct user_struct *us) { - switch_xml_t x_vars, x_var; + switch_xml_t x_vars, x_var, ux, x_user_tag, x_domain_tag; switch_status_t status; - switch_stream_handle_t apistream = { 0 }; - char *user_context = NULL; + switch_stream_handle_t apistream = { 0 }, *stream; + char *user_context = NULL, *search_context = NULL, *context = NULL; char *effective_caller_id_name = NULL; char *effective_caller_id_number = NULL; - char *callgroup = NULL; + char *dname = NULL, *gname = NULL, *callgroup = NULL; + char *utype = NULL, *uname = NULL; + char *apip = NULL; + + x_user_tag = us->x_user_tag; + x_domain_tag = us->x_domain_tag; + effective_caller_id_name = us->effective_caller_id_name; + effective_caller_id_number = us->effective_caller_id_number; + callgroup = us->callgroup; + dname = us->dname; + gname = us->gname; + stream = us->stream; + context = us->context; + search_context = us->search_context; if (!x_user_tag) { return; } + utype = (char *)switch_xml_attr_soft(us->x_user_tag, "type"); + uname = (char *)switch_xml_attr_soft(us->x_user_tag, "id"); + + if (!strcasecmp(utype, "pointer")) { + if (switch_xml_locate_user_in_domain(uname, x_domain_tag, &ux, NULL) == SWITCH_STATUS_SUCCESS) { + x_user_tag = ux; + } + } + + user_context = (char *)context; + if ((x_vars = switch_xml_child(x_user_tag, "variables"))) { for (x_var = switch_xml_child(x_vars, "variable"); x_var; x_var = x_var->next) { const char *key = switch_xml_attr_soft(x_var, "name"); @@ -214,19 +251,28 @@ static void dump_user(const char *dname, const char* gname, switch_xml_t x_user_ } } - if (_context) { - if (zstr(user_context) || strcasecmp(_context, user_context)) { + if (search_context) { + if (zstr(user_context) || strcasecmp(search_context, user_context)) { return; } } + if(zstr(dname)) { + apip = switch_mprintf("%s",switch_xml_attr_soft(x_user_tag, "id")); + } else { + apip = switch_mprintf("%s@%s",switch_xml_attr_soft(x_user_tag, "id"), dname); + } + SWITCH_STANDARD_STREAM(apistream); - if ((status = switch_api_execute("sofia_contact", switch_xml_attr_soft(x_user_tag, "id"), NULL, &apistream)) != SWITCH_STATUS_SUCCESS) { - switch_safe_free(apistream.data); - return; + if ((status = switch_api_execute("sofia_contact", apip, NULL, &apistream)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sofia_contact '%s' failed. status: %d \n", apip, status ); + goto end; } stream->write_function(stream, "%s|%s|%s|%s|%s|%s|%s|%s\n", switch_xml_attr_soft(x_user_tag, "id"), user_context, dname, gname, apistream.data, callgroup, effective_caller_id_name, effective_caller_id_number); + +end: switch_safe_free(apistream.data); + switch_safe_free(apip); return; } @@ -239,7 +285,7 @@ SWITCH_STANDARD_API(list_users_function) int32_t arg = 0; switch_xml_t xml_root, x_domains, x_domain_tag; switch_xml_t gts, gt, uts, ut; - char *_user = NULL, *_domain = NULL, *_context = NULL, *_group = NULL; + char *_user = NULL, *_domain = NULL, *_search_context = NULL, *_group = NULL; if ((pdata = strdup(cmd))) { @@ -258,7 +304,7 @@ SWITCH_STANDARD_API(list_users_function) _domain = argv[arg + 1]; } if (!strcasecmp(argv[arg], "context")) { - _context = argv[arg + 1]; + _search_context = argv[arg + 1]; } if (!strcasecmp(argv[arg], "group")) { _group = argv[arg + 1]; @@ -269,30 +315,64 @@ SWITCH_STANDARD_API(list_users_function) stream->write_function(stream, "userid|context|domain|group|contact|callgroup|effective_caller_id_name|effective_caller_id_number\n"); if (switch_xml_locate("directory", NULL, NULL, NULL, &xml_root, &x_domains, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - const char *dname = NULL; - const char *gname = NULL; + struct user_struct us = { 0 }; for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) { - dname = switch_xml_attr_soft(x_domain_tag, "name"); + switch_xml_t x_vars, x_var; - if (_domain && strcasecmp(_domain, dname)) { + us.dname = (char*)switch_xml_attr_soft(x_domain_tag, "name"); + + if (_domain && strcasecmp(_domain, us.dname)) { continue; } + if ((x_vars = switch_xml_child(x_domain_tag, "variables"))) { + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "user_context", NULL))) { + us.context = (char*)switch_xml_attr_soft(x_var, "value"); + } + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "callgroup", NULL))) { + us.callgroup = (char*)switch_xml_attr_soft(x_var, "value"); + } + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "effective_caller_id_name", NULL))) { + us.effective_caller_id_name = (char*)switch_xml_attr_soft(x_var, "value"); + } + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "effective_caller_id_number", NULL))) { + us.effective_caller_id_number = (char*)switch_xml_attr_soft(x_var, "value"); + } + } + if ((gts = switch_xml_child(x_domain_tag, "groups"))) { for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) { - gname = switch_xml_attr_soft(gt, "name"); + us.gname = (char*)switch_xml_attr_soft(gt, "name"); - if (_group && strcasecmp(_group, gname)) { + if (_group && strcasecmp(_group, us.gname)) { continue; } + if ((x_vars = switch_xml_child(gt, "variables"))) { + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "user_context", NULL))) { + us.context = (char*)switch_xml_attr_soft(x_var, "value"); + } + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "callgroup", NULL))) { + us.callgroup = (char*)switch_xml_attr_soft(x_var, "value"); + } + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "effective_caller_id_name", NULL))) { + us.effective_caller_id_name = (char*)switch_xml_attr_soft(x_var, "value"); + } + if ((x_var = switch_xml_find_child_multi(x_vars, "variable", "name", "effective_caller_id_number", NULL))) { + us.effective_caller_id_number = (char*)switch_xml_attr_soft(x_var, "value"); + } + } + for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) { for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) { if (_user && strcasecmp(_user, switch_xml_attr_soft(ut, "id"))) { continue; } - dump_user(dname, gname, ut, stream, _context); + us.x_user_tag = ut; + us.x_domain_tag = x_domain_tag; + us.stream = stream; + dump_user(&us); } } } @@ -302,7 +382,10 @@ SWITCH_STANDARD_API(list_users_function) if (_user && strcasecmp(_user, switch_xml_attr_soft(ut, "id"))) { continue; } - dump_user(dname, gname, ut, stream, _context); + us.x_user_tag = ut; + us.x_domain_tag = x_domain_tag; + us.stream = stream; + dump_user(&us); } } } From 09b1b8bc7fad6183c844972dbf8d9af3cb0ff62e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Oct 2012 10:14:22 -0500 Subject: [PATCH 119/512] add nohead param to skip over the cache check with HEAD method --- src/mod/applications/mod_httapi/mod_httapi.c | 54 +++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 35427c7b79..845c342f63 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -2530,37 +2530,41 @@ static switch_status_t locate_url_file(http_file_context_t *context, const char lock_file(context, SWITCH_TRUE); - if ((status = fetch_cache_data(context, url, &headers, NULL)) != SWITCH_STATUS_SUCCESS) { - if (status == SWITCH_STATUS_NOTFOUND) { - unreachable = 2; - if (now - context->expires < globals.not_found_expires) { + if (!context->url_params || !switch_true(switch_event_get_header(context->url_params, "nohead"))) { + if ((status = fetch_cache_data(context, url, &headers, NULL)) != SWITCH_STATUS_SUCCESS) { + if (status == SWITCH_STATUS_NOTFOUND) { + unreachable = 2; + if (now - context->expires < globals.not_found_expires) { + switch_goto_status(SWITCH_STATUS_SUCCESS, end); + } + } else { + unreachable = 1; + } + } + + if (switch_file_exists(context->cache_file, context->pool) != SWITCH_STATUS_SUCCESS && unreachable) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File at url [%s] is unreachable!\n", url); + goto end; + } + + if (!unreachable && !zstr(context->metadata)) { + metadata = switch_core_sprintf(context->pool, "%s:%s:%s:%s", + url, + switch_event_get_header_nil(headers, "last-modified"), + switch_event_get_header_nil(headers, "etag"), + switch_event_get_header_nil(headers, "content-length") + ); + + if (!strcmp(metadata, context->metadata)) { + write_meta_file(context, metadata, headers); switch_goto_status(SWITCH_STATUS_SUCCESS, end); } - } else { - unreachable = 1; } + + switch_event_destroy(&headers); } - if (switch_file_exists(context->cache_file, context->pool) != SWITCH_STATUS_SUCCESS && unreachable) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File at url [%s] is unreachable!\n", url); - goto end; - } - if (!unreachable && !zstr(context->metadata)) { - metadata = switch_core_sprintf(context->pool, "%s:%s:%s:%s", - url, - switch_event_get_header_nil(headers, "last-modified"), - switch_event_get_header_nil(headers, "etag"), - switch_event_get_header_nil(headers, "content-length") - ); - - if (!strcmp(metadata, context->metadata)) { - write_meta_file(context, metadata, headers); - switch_goto_status(SWITCH_STATUS_SUCCESS, end); - } - } - - switch_event_destroy(&headers); fetch_cache_data(context, url, &headers, context->cache_file); metadata = switch_core_sprintf(context->pool, "%s:%s:%s:%s", url, From 4dd1591945e4ff8d4ee587796cd0103dc89df407 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Oct 2012 11:49:29 -0500 Subject: [PATCH 120/512] FS-4684 this should help the proxy situation --- src/switch_rtp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0acae50c19..ab7bc29eb1 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4521,7 +4521,8 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra send_msg = frame->packet; if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && !switch_test_flag(frame, SFF_UDPTL_PACKET)) { - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && rtp_session->payload > 0) { send_msg->header.pt = rtp_session->payload; } From 57e9912f8bf82a22828e858747a231b5a19ec9eb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Oct 2012 13:46:57 -0500 Subject: [PATCH 121/512] FS-4650 please try to use an up to date gcc when doing new dev to catch build errs. This is what I get for the one time I did not compile test --- src/mod/applications/mod_commands/mod_commands.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index f3fad29e43..5923860507 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -285,7 +285,7 @@ SWITCH_STANDARD_API(list_users_function) int32_t arg = 0; switch_xml_t xml_root, x_domains, x_domain_tag; switch_xml_t gts, gt, uts, ut; - char *_user = NULL, *_domain = NULL, *_search_context = NULL, *_group = NULL; + char *_user = NULL, *_domain = NULL, *_group = NULL; if ((pdata = strdup(cmd))) { @@ -303,9 +303,7 @@ SWITCH_STANDARD_API(list_users_function) if (!strcasecmp(argv[arg], "domain")) { _domain = argv[arg + 1]; } - if (!strcasecmp(argv[arg], "context")) { - _search_context = argv[arg + 1]; - } + if (!strcasecmp(argv[arg], "group")) { _group = argv[arg + 1]; } From bed72bff7aae829f42a3ce2c954e985624024a78 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 5 Oct 2012 16:43:39 -0500 Subject: [PATCH 122/512] update vid code in dingaling --- .../endpoints/mod_dingaling/mod_dingaling.c | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index e6c2864617..9dd89b0e59 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1098,9 +1098,9 @@ static int activate_audio_rtp(struct private_object *tech_pvt) int r = 1; - if (switch_rtp_ready(tech_pvt->transports[LDL_TPORT_RTP].rtp_session)) { - return 1; - } + //if (switch_rtp_ready(tech_pvt->transports[LDL_TPORT_RTP].rtp_session)) { + // return 1; + //} if (!(tech_pvt->transports[LDL_TPORT_RTP].remote_ip && tech_pvt->transports[LDL_TPORT_RTP].remote_port)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "No valid rtp candidates received!\n"); @@ -1415,9 +1415,10 @@ static int activate_video_rtp(struct private_object *tech_pvt) switch_rtp_activate_ice(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].rtp_session, tech_pvt->transports[LDL_TPORT_VIDEO_RTP].remote_user, tech_pvt->transports[LDL_TPORT_VIDEO_RTP].local_user, - tech_pvt->transports[LDL_TPORT_VIDEO_RTP].remote_pass); + NULL);//tech_pvt->transports[LDL_TPORT_VIDEO_RTP].remote_pass); switch_channel_set_flag(channel, CF_VIDEO); - //switch_rtp_set_default_payload(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].rtp_session, tech_pvt->transports[LDL_TPORT_VIDEO_RTP].r_codec_num); + //switch_rtp_set_default_payload(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].rtp_session, tech_pvt->transports[LDL_TPORT_VIDEO_RTP].codec_num); + //switch_rtp_set_recv_pt(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].rtp_session, tech_pvt->transports[LDL_TPORT_VIDEO_RTP].codec_num); if (tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].remote_port) { @@ -1425,7 +1426,7 @@ static int activate_video_rtp(struct private_object *tech_pvt) switch_rtp_activate_rtcp_ice(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].rtp_session, tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].remote_user, tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].local_user, - tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].remote_pass); + NULL);//tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].remote_pass); } @@ -2236,7 +2237,6 @@ static switch_status_t channel_read_video_frame(switch_core_session_t *session, switch_rtp_zerocopy_read_frame(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].rtp_session, &tech_pvt->transports[LDL_TPORT_VIDEO_RTP].read_frame, flags); } - if (tech_pvt->transports[LDL_TPORT_VIDEO_RTP].read_frame.datalen == 0) { switch_set_flag((&tech_pvt->transports[LDL_TPORT_RTP].read_frame), SFF_CNG); tech_pvt->transports[LDL_TPORT_VIDEO_RTP].read_frame.datalen = 2; @@ -3599,13 +3599,13 @@ static switch_status_t parse_candidates(ldl_session_t *dlsession, switch_core_se if (tech_pvt->transports[ttype].accepted) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already Accepted [%s:%d]\n", tech_pvt->transports[ttype].remote_ip, tech_pvt->transports[ttype].remote_port); - goto end; + //goto end; } if (tech_pvt->transports[ttype].remote_ip) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already picked an IP [%s]\n", tech_pvt->transports[ttype].remote_ip); - goto end; + //goto end; } @@ -3663,17 +3663,20 @@ static switch_status_t parse_candidates(ldl_session_t *dlsession, switch_core_se } } - if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && (ttype == LDL_TPORT_VIDEO_RTP || ttype == LDL_TPORT_VIDEO_RTP) && - tech_pvt->transports[ttype].accepted == 1 && (1||switch_test_flag(tech_pvt, TFLAG_RTP_READY))) { + if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - if (ttype == LDL_TPORT_VIDEO_RTP) { + if (tech_pvt->transports[LDL_TPORT_VIDEO_RTP].accepted && + tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].accepted) { activate_video_rtp(tech_pvt); } - if (ttype == LDL_TPORT_VIDEO_RTP) { + + if (tech_pvt->transports[LDL_TPORT_RTP].accepted && + tech_pvt->transports[LDL_TPORT_RTCP].accepted) { activate_audio_rtp(tech_pvt); } + tech_pvt->transports[ttype].restart_rtp++; } From 90691b36c4f9feaba9d167b2b3efc9786cd50824 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 22 Sep 2012 01:05:51 +0200 Subject: [PATCH 123/512] FreeTDM: Remove trailing whitespace at end of ftdm_{copy,set}_string() Signed-off-by: Stefan Knoblich --- libs/freetdm/src/include/ftdm_os.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/include/ftdm_os.h b/libs/freetdm/src/include/ftdm_os.h index 39afec94be..d9d2b23205 100644 --- a/libs/freetdm/src/include/ftdm_os.h +++ b/libs/freetdm/src/include/ftdm_os.h @@ -64,10 +64,10 @@ typedef uint64_t ftdm_time_t; #endif /*! \brief strncpy replacement */ -#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1) +#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1) /*! \brief strncpy into a fixed-length buffer */ -#define ftdm_set_string(x,y) strncpy(x, y, sizeof(x)-1) +#define ftdm_set_string(x,y) strncpy(x, y, sizeof(x)-1) /*! \brief check for null or zero length string buffer */ #define ftdm_strlen_zero(s) (!s || *s == '\0') From 1d605ef47b77c5dc13de130ebbc8766fd456f68f Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 22 Sep 2012 01:06:34 +0200 Subject: [PATCH 124/512] FreeTDM: Add ftdm_clamp_safe() "Safer" version of ftdm_clamp(), that swaps min/max parameters if vmin happens to be larger than vmax, making sure the output will always satisfy vmin <= x <= vmax. Signed-off-by: Stefan Knoblich --- libs/freetdm/src/include/ftdm_os.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/freetdm/src/include/ftdm_os.h b/libs/freetdm/src/include/ftdm_os.h index d9d2b23205..c34810d241 100644 --- a/libs/freetdm/src/include/ftdm_os.h +++ b/libs/freetdm/src/include/ftdm_os.h @@ -87,6 +87,10 @@ typedef uint64_t ftdm_time_t; /*! \brief Get value that is in range [vmin,vmax] */ #define ftdm_clamp(val,vmin,vmax) ftdm_max(vmin,ftdm_min(val,vmax)) +/*!< \brief Safer version of ftdm_clamp(), that swaps vmin/vmax parameters if vmin > vmax */ +#define ftdm_clamp_safe(val,vmin,vmax) \ + ftdm_clamp(val, ftdm_min(vmin,vmax), ftdm_max(vmin,vmax)) + /*! * \brief Get offset of member in structure * \param[in] type Type of struct From da0ff2d615af009d1e4505b957e39b3dc8ab21da Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 7 Oct 2012 09:40:24 -0500 Subject: [PATCH 125/512] FS-4697 --resolve --- src/switch_core_session.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 6e565dca06..ab8f31059d 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1466,21 +1466,23 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_th if (check_status == SWITCH_STATUS_SUCCESS) { switch_core_session_t *session = (switch_core_session_t *) pop; - + switch_size_t id; + if (!session) break; + id = session->id; switch_mutex_lock(session_manager.mutex); session_manager.busy++; switch_mutex_unlock(session_manager.mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing session %"SWITCH_SIZE_T_FMT" %s\n", - (long) thread, session->id, switch_core_session_get_name(session)); + (long) thread, id, switch_core_session_get_name(session)); switch_core_session_thread(thread, (void *) session); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing session %"SWITCH_SIZE_T_FMT" %s\n", - (long) thread, session->id, switch_core_session_get_name(session)); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing session %"SWITCH_SIZE_T_FMT"\n", + (long) thread, id); switch_mutex_lock(session_manager.mutex); session_manager.busy--; From 0263ce92478ef65ee976d063167db057943088c1 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Mon, 8 Oct 2012 09:03:24 +0800 Subject: [PATCH 126/512] FS-4695 fix apple build, seems there's no pthread_setschedprio on Mac, not sure if windows has the same problem in apr/threadproc/unix/thread.c --- libs/apr/threadproc/unix/thread.c | 2 ++ libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/apr/threadproc/unix/thread.c b/libs/apr/threadproc/unix/thread.c index 9a56e55405..6c6ff8b842 100644 --- a/libs/apr/threadproc/unix/thread.c +++ b/libs/apr/threadproc/unix/thread.c @@ -174,10 +174,12 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, } if ((stat = pthread_create((*new)->td, temp, dummy_worker, (*new))) == 0) { +#ifndef __APPLE__ if (attr->priority) { pthread_t *thread = (*new)->td; pthread_setschedprio(*thread, attr->priority); } +#endif return APR_SUCCESS; } diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c index 90b335d491..db314b28dd 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c @@ -268,8 +268,12 @@ int su_pthreaded_port_start(su_port_create_f *create, pthread_mutex_lock(arg.mutex); if (pthread_create(&tid, &attr, su_pthread_port_clone_main, &arg) == 0) { -#ifndef WIN32 - /* this needs to be revisited when pthread for windows supports thread priority settings */ + +#if defined (WIN32) + /* this needs to be revisited when pthread for Windows supports thread priority settings */ +#elif defined (__APPLE__) + /* no such function on Apple */ +#else pthread_setschedprio(tid, 99); #endif pthread_cond_wait(arg.cv, arg.mutex); From 5cb354dddc142a3e8abf0b0a3cdeac28745238fd Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Sun, 30 Sep 2012 01:48:48 +0000 Subject: [PATCH 127/512] Initial core-pgsql support based on native libpq; FS starts and stops without errors using core-pgsql. --- Makefile.am | 4 +- conf/vanilla/autoload_configs/switch.conf.xml | 2 + conf/vanilla/sip_profiles/internal.xml | 3 + configure.in | 23 + src/include/switch.h | 1 + src/include/switch_core.h | 14 +- src/include/switch_pgsql.h | 162 ++++ src/include/switch_types.h | 4 +- .../mod_cidlookup/mod_cidlookup.c | 32 +- src/mod/applications/mod_db/mod_db.c | 20 +- src/mod/applications/mod_fifo/mod_fifo.c | 20 +- .../mod_voicemail/mod_voicemail.c | 18 +- src/mod/endpoints/mod_sofia/sofia.c | 2 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 18 +- src/switch_core.c | 12 +- src/switch_core_sqldb.c | 268 ++++-- src/switch_pgsql.c | 770 ++++++++++++++++++ 17 files changed, 1283 insertions(+), 90 deletions(-) create mode 100644 src/include/switch_pgsql.h create mode 100644 src/switch_pgsql.c diff --git a/Makefile.am b/Makefile.am index adf412b205..f11f891aac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -207,7 +207,8 @@ library_include_HEADERS = \ libs/libteletone/src/libteletone.h \ libs/libtpl-1.5/src/tpl.h \ src/include/switch_limit.h \ - src/include/switch_odbc.h + src/include/switch_odbc.h \ + src/include/switch_pgsql.h nodist_libfreeswitch_la_SOURCES = \ src/include/switch_frame.h \ @@ -262,6 +263,7 @@ libfreeswitch_la_SOURCES = \ src/switch_config.c \ src/switch_time.c \ src/switch_odbc.c \ + src/switch_pgsql.c \ src/switch_limit.c \ src/g711.c \ src/switch_pcm.c \ diff --git a/conf/vanilla/autoload_configs/switch.conf.xml b/conf/vanilla/autoload_configs/switch.conf.xml index 64f3d6fa71..34bdedcda9 100644 --- a/conf/vanilla/autoload_configs/switch.conf.xml +++ b/conf/vanilla/autoload_configs/switch.conf.xml @@ -144,6 +144,8 @@ + + + + + diff --git a/configure.in b/configure.in index 92a88048fd..4e036b0d81 100644 --- a/configure.in +++ b/configure.in @@ -395,7 +395,30 @@ if test "x$enable_core_odbc_support" != "xno"; then AC_CHECK_LIB([odbc], [SQLDisconnect],, AC_MSG_ERROR([no usable libodbc; please install unixodbc devel package or equivalent])) fi +AC_ARG_ENABLE(core-pgsql-support, + [AS_HELP_STRING([--enable-core-pgsql-support], [Compile with PGSQL Support])],,[enable_core_pgsql_support="no"]) +if test x"$enable_core_pgsql_support" = x"yes" ; then + +AC_PATH_PROG([PG_CONFIG], [pg_config], [no]) +if test "$PG_CONFIG" != "no"; then + AC_MSG_CHECKING([for PostgreSQL libraries]) + POSTGRESQL_CFLAGS="`$PG_CONFIG --cflags` -I`$PG_CONFIG --includedir`" + POSTGRESQL_CXXFLAGS="`$PG_CONFIG --cppflags` -I`$PG_CONFIG --includedir`" + POSTGRESQL_LDFLAGS="`$PG_CONFIG --ldflags` -L`$PG_CONFIG --libdir` -lpq" + POSTGRESQL_VERSION=`$PG_CONFIG --version | sed -e 's#PostgreSQL ##'` + AC_DEFINE([SWITCH_HAVE_PGSQL], [1], [Define to 1 if PostgreSQL libraries are available]) + AC_CHECK_LIB([pq], [PQgetvalue],, AC_MSG_ERROR([no usable libpq; please install PostgreSQL devel package or equivalent])) + AC_MSG_RESULT([yes]) + SWITCH_AM_CFLAGS="$POSTGRESQL_CFLAGS $SWITCH_AM_CFLAGS" + SWITCH_AM_CXXFLAGS="$POSTGRESQL_CXXFLAGS $SWITCH_AM_CXXFLAGS" + SWITCH_AM_LDFLAGS="$POSTGRESQL_LDFLAGS $SWITCH_AM_LDFLAGS" +else + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([Unabled to find pg_config in PATH. Is PostgreSQL installed?]) +fi + +fi AC_ARG_ENABLE(timerfd-wrapper, [AC_HELP_STRING([--enable-timerfd-wrapper],[timerfd is in the kernel but not in your libc])],[enable_timer_fd_wrapper="$enableval"],[enable_timer_fd_wrapper="no"]) diff --git a/src/include/switch.h b/src/include/switch.h index 3e1bfbb77f..1eb45ae48a 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -135,6 +135,7 @@ #include "switch_config.h" #include "switch_nat.h" #include "switch_odbc.h" +#include "switch_pgsql.h" #include "switch_json.h" #include "switch_limit.h" diff --git a/src/include/switch_core.h b/src/include/switch_core.h index fa703eafc0..73607926fa 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2210,12 +2210,14 @@ typedef enum { typedef enum { SCDB_TYPE_CORE_DB, - SCDB_TYPE_ODBC + SCDB_TYPE_ODBC, + SCDB_TYPE_PGSQL } switch_cache_db_handle_type_t; typedef union { switch_core_db_t *core_db_dbh; switch_odbc_handle_t *odbc_dbh; + switch_pgsql_handle_t *pgsql_dbh; } switch_cache_db_native_handle_t; typedef struct { @@ -2228,9 +2230,14 @@ typedef struct { char *pass; } switch_cache_db_odbc_options_t; +typedef struct { + char *dsn; +} switch_cache_db_pgsql_options_t; + typedef union { switch_cache_db_core_db_options_t core_db_options; switch_cache_db_odbc_options_t odbc_options; + switch_cache_db_pgsql_options_t pgsql_options; } switch_cache_db_connection_options_t; struct switch_cache_db_handle; @@ -2241,6 +2248,11 @@ static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_ const char *type_str = "INVALID"; switch (type) { + case SCDB_TYPE_PGSQL: + { + type_str = "PGSQL"; + } + break; case SCDB_TYPE_ODBC: { type_str = "ODBC"; diff --git a/src/include/switch_pgsql.h b/src/include/switch_pgsql.h new file mode 100644 index 0000000000..282172e646 --- /dev/null +++ b/src/include/switch_pgsql.h @@ -0,0 +1,162 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2012, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * 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 + * Eliot Gable + * + * switch_pgsql.h -- PGSQL Driver + * + */ + +#ifndef SWITCH_PGSQL_H +#define SWITCH_PGSQL_H + +#include + +#define DEFAULT_PGSQL_RETRIES 120 + +SWITCH_BEGIN_EXTERN_C + +struct switch_pgsql_handle; +struct switch_pgsql_result; + + +typedef enum { + SWITCH_PGSQL_STATE_INIT, + SWITCH_PGSQL_STATE_DOWN, + SWITCH_PGSQL_STATE_CONNECTED, + SWITCH_PGSQL_STATE_ERROR +} switch_pgsql_state_t; + +typedef enum { + SWITCH_PGSQL_SUCCESS = 0, + SWITCH_PGSQL_FAIL = -1 +} switch_pgsql_status_t; + +/*! + \brief Create a new handle for the PGSQL connection. + \param dsn The DSN of the database to connect to. See documentation for PQconnectdb() at + http://www.postgresql.org/docs/9.0/static/libpq-connect.html. The DSN *MUST* be + prefixed with 'pgsql;' to use the switch_cache_db* functionality. However, the DSN + passed to this function directly *MUST NOT* be prefixed with 'pgsql;'. + \return Returns a pointer to a newly allocated switch_pgsql_handle_t type or NULL on failure. + */ +SWITCH_DECLARE(switch_pgsql_handle_t *) switch_pgsql_handle_new(const char *dsn); + +/*! + \brief Sets the number of retries if the PGSQL connection fails. + \param handle A fully allocated switch_pgsql_handle_t returned from a call to switch_pgsql_handle_new(). + \param num_retries How many times to retry connecting to the database if this connection fails. + */ +SWITCH_DECLARE(void) switch_pgsql_set_num_retries(switch_pgsql_handle_t *handle, int num_retries); + +/*! + \brief Disconnects a PGSQL connection from the database. + \param handle The PGSQL database handle to disconnect. + \return Returns SWITCH_PGSQL_SUCCESS or SWITCH_PGSQL_FAIL. + */ +SWITCH_DECLARE(switch_pgsql_status_t ) switch_pgsql_handle_disconnect(switch_pgsql_handle_t *handle); +#if 0 + ) /* Emacs formatting issue */ +#endif +/*! + \brief Connect to the database specified by the DSN passed to the switch_pgsql_handle_new() call which + initialized this handle. + \param The database handle to connect to the database. + \return Returns SWITCH_PGSQL_SUCCESS or SWITCH_PGSQL_FAIL. + */ +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_connect(switch_pgsql_handle_t *handle); + +/*! + */ +SWITCH_DECLARE(void) switch_pgsql_handle_destroy(switch_pgsql_handle_t **handlep); + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handle_t *handle, const char* sql); + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, const char *func, int line, switch_pgsql_handle_t *handle); +#define switch_pgsql_cancel(handle) switch_pgsql_cancel_real(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle) + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int seconds); +#define switch_pgsql_next_result(h, r) switch_pgsql_next_result_timed(h, r, 10000) + +SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result); + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char *func, int line, switch_pgsql_handle_t *handle); +#define switch_pgsql_finish_results(handle) switch_pgsql_finish_results_real(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle) + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err); + +SWITCH_DECLARE(switch_pgsql_state_t) switch_pgsql_handle_get_state(switch_pgsql_handle_t *handle); +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec(switch_pgsql_handle_t *handle, const char *sql, char **err); +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err); +SWITCH_DECLARE(switch_bool_t) switch_pgsql_available(void); +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLSetAutoCommitAttr(switch_pgsql_handle_t *handle, switch_bool_t on); +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLEndTran(switch_pgsql_handle_t *handle, switch_bool_t commit); + +/*! + \brief Execute the sql query and issue a callback for each row returned + \param file the file from which this function is called + \param func the function from which this function is called + \param line the line from which this function is called + \param handle the PGSQL handle + \param sql the sql string to execute + \param callback the callback function to execute + \param pdata the state data passed on each callback invocation + \return SWITCH_STATUS_SUCCESS if the operation was successful + \note none +*/ +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_callback_exec_detailed(const char *file, const char *func, int line, switch_pgsql_handle_t *handle, + const char *sql, switch_core_db_callback_func_t callback, void *pdata, + char **err); +/*! + \brief Execute the sql query and issue a callback for each row returned + \param handle the PGSQL handle + \param sql the sql string to execute + \param callback the callback function to execute + \param pdata the state data passed on each callback invocation + \return SWITCH_STATUS_SUCCESS if the operation was successful + \note none +*/ +#define switch_pgsql_handle_callback_exec(handle, sql, callback, pdata, err) \ + switch_pgsql_handle_callback_exec_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, \ + handle, sql, callback, pdata, err) + + +SWITCH_DECLARE(char *) switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle); + +SWITCH_DECLARE(int) switch_pgsql_handle_affected_rows(switch_pgsql_handle_t *handle); + +SWITCH_END_EXTERN_C +#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: + */ diff --git a/src/include/switch_types.h b/src/include/switch_types.h index f9d8476454..6f77f32ef4 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -324,7 +324,7 @@ typedef enum { SCF_CLEAR_SQL = (1 << 17), SCF_THREADED_SYSTEM_EXEC = (1 << 18), SCF_SYNC_CLOCK_REQUESTED = (1 << 19), - SCF_CORE_ODBC_REQ = (1 << 20), + SCF_CORE_NON_SQLITE_DB_REQ = (1 << 20), SCF_DEBUG_SQL = (1 << 21), SCF_API_EXPANSION = (1 << 22), SCF_SESSION_THREAD_POOL = (1 << 23) @@ -1833,6 +1833,8 @@ typedef struct switch_buffer switch_buffer_t; typedef struct switch_codec_settings switch_codec_settings_t; typedef struct switch_codec_fmtp switch_codec_fmtp_t; typedef struct switch_odbc_handle switch_odbc_handle_t; +typedef struct switch_pgsql_handle switch_pgsql_handle_t; +typedef struct switch_pgsql_result switch_pgsql_result_t; typedef struct switch_io_routines switch_io_routines_t; typedef struct switch_speech_handle switch_speech_handle_t; diff --git a/src/mod/applications/mod_cidlookup/mod_cidlookup.c b/src/mod/applications/mod_cidlookup/mod_cidlookup.c index 562cea7f5f..d71278dd2f 100755 --- a/src/mod/applications/mod_cidlookup/mod_cidlookup.c +++ b/src/mod/applications/mod_cidlookup/mod_cidlookup.c @@ -94,12 +94,20 @@ static switch_cache_db_handle_t *cidlookup_get_db_handle(void) switch_cache_db_handle_t *dbh = NULL; if (!zstr(globals.odbc_dsn)) { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; + char *dsn; + if ((dsn = strstr(globals.odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } else { + options.odbc_options.dsn = globals.odbc_dsn; + options.odbc_options.user = globals.odbc_user; + options.odbc_options.pass = globals.odbc_pass; + + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } } return dbh; } @@ -112,8 +120,8 @@ static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const switch_cache_db_handle_t *dbh = NULL; - if (!switch_odbc_available()) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC is not compiled in. Do not configure odbc-dsn parameter!\n"); + if (!switch_odbc_available() && !switch_pgsql_available()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC and PGSQL are not compiled in. Do not configure odbc-dsn parameter!\n"); return SWITCH_STATUS_FALSE; } @@ -134,7 +142,7 @@ static switch_status_t config_callback_dsn(switch_xml_config_item_t *data, const switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connecting to dsn: %s\n", globals.odbc_dsn); if (!(dbh = cidlookup_get_db_handle())) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open Database!\n"); switch_goto_status(SWITCH_STATUS_FALSE, done); } } @@ -195,7 +203,7 @@ static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_ca retval = SWITCH_TRUE; } } else { - *err = switch_core_sprintf(cbt->pool, "Unable to get ODBC handle. dsn: %s, dbh is %s\n", globals.odbc_dsn, dbh ? "not null" : "null"); + *err = switch_core_sprintf(cbt->pool, "Unable to get database handle. dsn: %s, dbh is %s\n", globals.odbc_dsn, dbh ? "not null" : "null"); } switch_cache_db_release_db_handle(&dbh); @@ -564,7 +572,7 @@ static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "caller_id_number", number); /* database always wins */ - if (switch_odbc_available() && globals.odbc_dsn && globals.sql) { + if ((switch_odbc_available() || switch_pgsql_available()) && globals.odbc_dsn && globals.sql) { name = do_db_lookup(pool, event, number, globals.sql); if (name) { cid->name = name; @@ -610,7 +618,7 @@ static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event, switch_assert(cid); } /* append area if we can */ - if (!cid->area && !skipcitystate && strlen(number) == 11 && number[0] == '1' && switch_odbc_available() && globals.odbc_dsn && globals.citystate_sql) { + if (!cid->area && !skipcitystate && strlen(number) == 11 && number[0] == '1' && (switch_odbc_available() || switch_pgsql_available()) && globals.odbc_dsn && globals.citystate_sql) { /* yes, this is really area */ name = do_db_lookup(pool, event, number, globals.citystate_sql); @@ -768,7 +776,7 @@ SWITCH_STANDARD_API(cidlookup_function) stream->write_function(stream, " odbc-dsn: %s\n sql: %s\n citystate-sql: %s\n", globals.odbc_dsn ? globals.odbc_dsn : "(null)", globals.sql ? globals.sql : "(null)", globals.citystate_sql ? globals.citystate_sql : "(null)"); - stream->write_function(stream, " ODBC Compiled: %s\n", switch_odbc_available()? "true" : "false"); + stream->write_function(stream, " ODBC Compiled: %s; PGSQL Compiled: %s\n", switch_odbc_available() ? "true" : "false", switch_pgsql_available() ? "true" : "false"); switch_goto_status(SWITCH_STATUS_SUCCESS, done); } diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index 5c64b20c95..69e0522be7 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -92,12 +92,20 @@ switch_cache_db_handle_t *limit_get_db_handle(void) switch_cache_db_handle_t *dbh = NULL; if (!zstr(globals.odbc_dsn)) { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; + char *dsn; + if ((dsn = strstr(globals.odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } else { + options.odbc_options.dsn = globals.odbc_dsn; + options.odbc_options.user = globals.odbc_user; + options.odbc_options.pass = globals.odbc_pass; + + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } return dbh; } else { options.core_db_options.db_path = globals.dbname; @@ -275,7 +283,7 @@ SWITCH_LIMIT_STATUS(limit_status_db) /* INIT / Config */ -static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "[^:]+:[^:]+:.+" }; +static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "^pgsql;|[^:]+:[^:]+:.+" }; static switch_xml_config_item_t config_settings[] = { SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn, diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index f500c4683a..56383a2973 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -731,12 +731,20 @@ switch_cache_db_handle_t *fifo_get_db_handle(void) switch_cache_db_handle_t *dbh = NULL; if (!zstr(globals.odbc_dsn)) { - options.odbc_options.dsn = globals.odbc_dsn; - options.odbc_options.user = globals.odbc_user; - options.odbc_options.pass = globals.odbc_pass; + char *dsn; + if ((dsn = strstr(globals.odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) { - dbh = NULL; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } else { + options.odbc_options.dsn = globals.odbc_dsn; + options.odbc_options.user = globals.odbc_user; + options.odbc_options.pass = globals.odbc_pass; + + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) { + dbh = NULL; + } } return dbh; } else { @@ -4010,7 +4018,7 @@ static switch_status_t load_config(int reload, int del_all) } if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { - if (switch_odbc_available()) { + if (switch_odbc_available() || switch_pgsql_available()) { switch_set_string(globals.odbc_dsn, val); if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { *globals.odbc_user++ = '\0'; diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 78eb57a20a..2e17e5dbf6 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -167,12 +167,20 @@ switch_cache_db_handle_t *vm_get_db_handle(vm_profile_t *profile) switch_cache_db_handle_t *dbh = NULL; if (!zstr(profile->odbc_dsn)) { - options.odbc_options.dsn = profile->odbc_dsn; - options.odbc_options.user = profile->odbc_user; - options.odbc_options.pass = profile->odbc_pass; + char *dsn; + if ((dsn = strstr(profile->odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } else { + options.odbc_options.dsn = profile->odbc_dsn; + options.odbc_options.user = profile->odbc_user; + options.odbc_options.pass = profile->odbc_pass; + + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } return dbh; } else { options.core_db_options.db_path = profile->dbname; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 26ff378ee4..e738cf2fb0 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4414,7 +4414,7 @@ switch_status_t config_sofia(int reload, char *profile_name) sofia_set_flag(profile, TFLAG_CAPTURE); nua_set_params(profile->nua, TPTAG_CAPT(mod_sofia_globals.capture_server), TAG_END()); } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { - if (switch_odbc_available()) { + if (switch_odbc_available() || switch_pgsql_available()) { profile->odbc_dsn = switch_core_strdup(profile->pool, val); if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) { *profile->odbc_user++ = '\0'; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index a67bc97b36..a39a8e9e71 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6367,12 +6367,20 @@ switch_cache_db_handle_t *sofia_glue_get_db_handle(sofia_profile_t *profile) switch_cache_db_handle_t *dbh = NULL; if (!zstr(profile->odbc_dsn)) { - options.odbc_options.dsn = profile->odbc_dsn; - options.odbc_options.user = profile->odbc_user; - options.odbc_options.pass = profile->odbc_pass; + char *dsn; + if ((dsn = strstr(profile->odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) - dbh = NULL; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } else { + options.odbc_options.dsn = profile->odbc_dsn; + options.odbc_options.user = profile->odbc_user; + options.odbc_options.pass = profile->odbc_pass; + + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) != SWITCH_STATUS_SUCCESS) + dbh = NULL; + } return dbh; } else { options.core_db_options.db_path = profile->dbname; diff --git a/src/switch_core.c b/src/switch_core.c index 95a7b4dbed..8e1a6567d7 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1910,7 +1910,7 @@ static void switch_load_core_config(const char *file) } 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()) { + if (switch_odbc_available() || switch_pgsql_available()) { runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val); if ((runtime.odbc_user = strchr(runtime.odbc_dsn, ':'))) { *runtime.odbc_user++ = '\0'; @@ -1919,10 +1919,10 @@ static void switch_load_core_config(const char *file) } } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n"); } } else if (!strcasecmp(var, "core-recovery-db-dsn") && !zstr(val)) { - if (switch_odbc_available()) { + if (switch_odbc_available() || switch_pgsql_available()) { runtime.recovery_odbc_dsn = switch_core_strdup(runtime.memory_pool, val); if ((runtime.recovery_odbc_user = strchr(runtime.recovery_odbc_dsn, ':'))) { *runtime.recovery_odbc_user++ = '\0'; @@ -1931,10 +1931,10 @@ static void switch_load_core_config(const char *file) } } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n"); } - } else if (!strcasecmp(var, "core-odbc-required") && !zstr(val)) { - switch_set_flag((&runtime), SCF_CORE_ODBC_REQ); + } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) { + switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ); } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) { if (!strcasecmp(val, "MSSQL")) { runtime.odbc_dbtype = DBTYPE_MSSQL; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b4a58bbd9d..cbc7a611e3 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -190,7 +190,7 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t } if (zstr(runtime.odbc_dsn)) { - if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) { + if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { return SWITCH_STATUS_FALSE; } @@ -202,11 +202,18 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { - options.odbc_options.dsn = runtime.odbc_dsn; - options.odbc_options.user = runtime.odbc_user; - options.odbc_options.pass = runtime.odbc_pass; + char *dsn; + if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + } else { + options.odbc_options.dsn = runtime.odbc_dsn; + options.odbc_options.user = runtime.odbc_user; + options.odbc_options.pass = runtime.odbc_pass; + + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + } } /* I *think* we can do without this now, if not let me know @@ -218,6 +225,56 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t return r; } +#define SWITCH_CORE_PERSIST_DB "core" +/*! + \brief Open the default system database +*/ +SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) +{ + switch_cache_db_connection_options_t options = { {0} }; + switch_status_t r; + + if (!sql_manager.manage) { + return SWITCH_STATUS_FALSE; + } + + if (zstr(runtime.odbc_dsn)) { + if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { + return SWITCH_STATUS_FALSE; + } + + if (runtime.dbname) { + options.core_db_options.db_path = runtime.dbname; + } else { + options.core_db_options.db_path = SWITCH_CORE_PERSIST_DB; + } + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); + + } else { + char *dsn; + if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); + + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + } else { + options.odbc_options.dsn = runtime.odbc_dsn; + options.odbc_options.user = runtime.odbc_user; + options.odbc_options.pass = runtime.odbc_pass; + + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + } + } + + /* I *think* we can do without this now, if not let me know + if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { + (*dbh)->io_mutex = sql_manager.io_mutex; + } + */ + + return r; +} + + #define SWITCH_CORE_RECOVERY_DB "core_recovery" SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { @@ -229,7 +286,7 @@ SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_ } if (zstr(runtime.recovery_odbc_dsn)) { - if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) { + if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { return SWITCH_STATUS_FALSE; } @@ -241,11 +298,18 @@ SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_ r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { - options.odbc_options.dsn = runtime.recovery_odbc_dsn; - options.odbc_options.user = runtime.recovery_odbc_user; - options.odbc_options.pass = runtime.recovery_odbc_pass; + char *dsn; + if ((dsn = strstr(runtime.recovery_odbc_dsn, "pgsql;")) != NULL) { + options.pgsql_options.dsn = (char*)(dsn + 6); - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + } else { + options.odbc_options.dsn = runtime.recovery_odbc_dsn; + options.odbc_options.user = runtime.recovery_odbc_user; + options.odbc_options.pass = runtime.recovery_odbc_pass; + + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + } } /* I *think* we can do without this now, if not let me know @@ -286,6 +350,11 @@ static void sql_close(time_t prune) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", dbh->name); switch (dbh->type) { + case SCDB_TYPE_PGSQL: + { + switch_pgsql_handle_destroy(&dbh->native_handle.pgsql_dbh); + } + break; case SCDB_TYPE_ODBC: { switch_odbc_handle_destroy(&dbh->native_handle.odbc_dbh); @@ -373,8 +442,8 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h uint32_t yield_len = 100000, total_yield = 0; const char *db_name = NULL; - const char *db_user = NULL; - const char *db_pass = NULL; + const char *odbc_user = NULL; + const char *odbc_pass = NULL; while(runtime.max_db_handles && sql_manager.total_handles >= runtime.max_db_handles && sql_manager.total_used_handles >= sql_manager.total_handles) { if (!waiting++) { @@ -393,18 +462,24 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h } switch (type) { + case SCDB_TYPE_PGSQL: + { + db_name = connection_options->odbc_options.dsn; + odbc_user = NULL; + odbc_pass = NULL; + } case SCDB_TYPE_ODBC: { db_name = connection_options->odbc_options.dsn; - db_user = connection_options->odbc_options.user; - db_pass = connection_options->odbc_options.pass; + odbc_user = connection_options->odbc_options.user; + odbc_pass = connection_options->odbc_options.pass; } break; case SCDB_TYPE_CORE_DB: { db_name = connection_options->core_db_options.db_path; - db_user = ""; - db_pass = ""; + odbc_user = NULL; + odbc_pass = NULL; } break; } @@ -413,8 +488,11 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h return SWITCH_STATUS_FALSE; } - - snprintf(db_str, sizeof(db_str) - 1, "db=\"%s\";user=\"%s\";pass=\"%s\"", db_name, db_user, db_pass); + if (odbc_user || odbc_pass) { + snprintf(db_str, sizeof(db_str) - 1, "db=\"%s\";user=\"%s\";pass=\"%s\"", db_name, odbc_user, odbc_pass); + } else { + snprintf(db_str, sizeof(db_str) - 1, "db=\"%s\"", db_name); + } snprintf(db_callsite_str, sizeof(db_callsite_str) - 1, "%s:%d", file, line); snprintf(thread_str, sizeof(thread_str) - 1, "thread=\"%lu\"", (unsigned long) (intptr_t) self); @@ -424,8 +502,23 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h } else { switch_core_db_t *db = NULL; switch_odbc_handle_t *odbc_dbh = NULL; + switch_pgsql_handle_t *pgsql_dbh = NULL; switch (type) { + case SCDB_TYPE_PGSQL: + { + if (!switch_pgsql_available()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! PGSQL NOT AVAILABLE! Can't connect to DSN %s\n", connection_options->pgsql_options.dsn); + goto end; + } + + if ((pgsql_dbh = switch_pgsql_handle_new(connection_options->pgsql_options.dsn))) { + if (switch_pgsql_handle_connect(pgsql_dbh) != SWITCH_PGSQL_SUCCESS) { + switch_pgsql_handle_destroy(&pgsql_dbh); + } + } + } + break; case SCDB_TYPE_ODBC: { @@ -454,8 +547,8 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h goto end; } - if (!db && !odbc_dbh) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure to connect to %s %s!\n", db?"SQLITE":"ODBC", db?connection_options->core_db_options.db_path:connection_options->odbc_options.dsn); + if (!db && !odbc_dbh && !pgsql_dbh) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure to connect to %s %s!\n", (db ? "SQLITE" : (odbc_dbh ? "ODBC" : "PGSQL")), (db ? connection_options->core_db_options.db_path : (odbc_dbh ? connection_options->odbc_options.dsn : connection_options->pgsql_options.dsn))); goto end; } @@ -466,8 +559,10 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h if (db) { new_dbh->native_handle.core_db_dbh = db; - } else { + } else if (odbc_dbh) { new_dbh->native_handle.odbc_dbh = odbc_dbh; + } else { + new_dbh->native_handle.pgsql_dbh = pgsql_dbh; } add_handle(new_dbh, db_str, db_callsite_str, thread_str); @@ -499,6 +594,11 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t } switch (dbh->type) { + case SCDB_TYPE_PGSQL: + { + status = switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, sql, &errmsg); + } + break; case SCDB_TYPE_ODBC: { status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL, &errmsg); @@ -650,6 +750,11 @@ SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh) return switch_odbc_handle_affected_rows(dbh->native_handle.odbc_dbh); } break; + case SCDB_TYPE_PGSQL: + { + return switch_pgsql_handle_affected_rows(dbh->native_handle.pgsql_dbh); + } + break; } return 0; } @@ -707,6 +812,11 @@ SWITCH_DECLARE(char *) switch_cache_db_execute_sql2str(switch_cache_db_handle_t status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err); } break; + case SCDB_TYPE_PGSQL: + { + status = switch_pgsql_handle_exec_string(dbh->native_handle.pgsql_dbh, sql, str, len, err); + } + break; } end: @@ -784,16 +894,34 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ while (begin_retries > 0) { again = 0; - if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg); - } else { - switch_odbc_status_t result; - - if ((result = switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { - char tmp[100]; - switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); - errmsg = strdup(tmp); + switch(dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg); } + break; + case SCDB_TYPE_ODBC: + { + switch_odbc_status_t result; + + if ((result = switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); + errmsg = strdup(tmp); + } + } + break; + case SCDB_TYPE_PGSQL: + { + switch_pgsql_status_t result; + + if ((result = switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); + errmsg = strdup(tmp); + } + } + break; } if (errmsg) { @@ -807,11 +935,25 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ errmsg = NULL; if (again) { - if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL); - } else { - switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); - switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); + switch(dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL); + } + break; + case SCDB_TYPE_ODBC: + { + switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); + switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); + } + break; + case SCDB_TYPE_PGSQL: + { + switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1); + switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 1); + switch_pgsql_finish_results(dbh->native_handle.pgsql_dbh); + } + break; } goto again; @@ -868,11 +1010,25 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ done: - if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL); - } else { - switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); - switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); + switch(dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL); + } + break; + case SCDB_TYPE_ODBC: + { + switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); + switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); + } + break; + case SCDB_TYPE_PGSQL: + { + switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1); + switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 1); + switch_pgsql_finish_results(dbh->native_handle.pgsql_dbh); + } + break; } if (!zstr(runtime.core_db_post_trans_execute)) { @@ -903,6 +1059,11 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach switch (dbh->type) { + case SCDB_TYPE_PGSQL: + { + status = switch_pgsql_handle_callback_exec(dbh->native_handle.pgsql_dbh, sql, callback, pdata, err); + } + break; case SCDB_TYPE_ODBC: { status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err); @@ -951,6 +1112,17 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand if (io_mutex) switch_mutex_lock(io_mutex); switch (dbh->type) { + case SCDB_TYPE_PGSQL: + { + if (switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, test_sql, NULL) != SWITCH_PGSQL_SUCCESS) { + r = SWITCH_FALSE; + if (drop_sql) { + switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, drop_sql, NULL); + } + switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, reactive_sql, NULL); + } + } + break; case SCDB_TYPE_ODBC: { if (switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, test_sql, NULL, NULL) != SWITCH_ODBC_SUCCESS) { @@ -1057,6 +1229,8 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, switch_mutex_lock(sql_manager.cond_mutex); switch (sql_manager.event_db->type) { + case SCDB_TYPE_PGSQL: + break; case SCDB_TYPE_ODBC: break; case SCDB_TYPE_CORE_DB: @@ -2313,7 +2487,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ if (switch_core_db_handle(&sql_manager.dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) { + if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC IS REQUIRED!\n"); return SWITCH_STATUS_FALSE; } @@ -2336,6 +2510,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n"); switch (sql_manager.dbh->type) { + case SCDB_TYPE_PGSQL: case SCDB_TYPE_ODBC: if (switch_test_flag((&runtime), SCF_CLEAR_SQL)) { char sql[512] = ""; @@ -2376,6 +2551,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch (sql_manager.dbh->type) { + case SCDB_TYPE_PGSQL: case SCDB_TYPE_ODBC: { char *err; @@ -2405,7 +2581,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; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling ODBC\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling non-SQLite support; using SQLite\n"); switch_cache_db_release_db_handle(&sql_manager.dbh); free(err); goto top; @@ -2536,9 +2712,9 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) if (switch_core_recovery_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) { + if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { int arg = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC IS REQUIRED!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC OR PGSQL IS REQUIRED!\n"); switch_core_session_ctl(SCSC_SHUTDOWN_NOW, &arg); } @@ -2562,8 +2738,8 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) if (switch_core_db_handle(&sql_manager.dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - if (switch_test_flag((&runtime), SCF_CORE_ODBC_REQ)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC IS REQUIRED!\n"); + if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC OR PGSQL IS REQUIRED!\n"); goto end; } diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c new file mode 100644 index 0000000000..ead39a7e9f --- /dev/null +++ b/src/switch_pgsql.c @@ -0,0 +1,770 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2012, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * 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 + * Eliot Gable + * + * switch_pgsql.c -- PGSQL Driver + * + */ + +#include +#include + +#ifdef SWITCH_HAVE_PGSQL +#include + + +struct switch_pgsql_handle { + char *dsn; + const char *sql; + PGconn* con; + int sock; + switch_pgsql_state_t state; + int affected_rows; + int num_retries; + switch_bool_t auto_commit; + switch_bool_t in_txn; +}; + +struct switch_pgsql_result { + PGresult *result; + ExecStatusType status; + char *err; + int rows; + int cols; +}; +#endif + +SWITCH_DECLARE(switch_pgsql_handle_t *) switch_pgsql_handle_new(const char *dsn) +{ +#ifdef SWITCH_HAVE_PGSQL + switch_pgsql_handle_t *new_handle; + + if (!(new_handle = malloc(sizeof(*new_handle)))) { + goto err; + } + + memset(new_handle, 0, sizeof(*new_handle)); + + if (!(new_handle->dsn = strdup(dsn))) { + goto err; + } + + new_handle->sock = 0; + new_handle->state = SWITCH_PGSQL_STATE_INIT; + new_handle->con = NULL; + new_handle->affected_rows = 0; + new_handle->num_retries = DEFAULT_PGSQL_RETRIES; + new_handle->auto_commit = SWITCH_TRUE; + new_handle->in_txn = SWITCH_FALSE; + + return new_handle; + + err: + if (new_handle) { + switch_safe_free(new_handle->dsn); + switch_safe_free(new_handle); + } +#endif + return NULL; +} + +SWITCH_DECLARE(void) switch_pgsql_set_num_retries(switch_pgsql_handle_t *handle, int num_retries) +{ +#ifdef SWITCH_HAVE_PGSQL + if (handle) { + handle->num_retries = num_retries; + } +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_disconnect(switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + + if (!handle) { + return SWITCH_PGSQL_FAIL; + } + + if (handle->state == SWITCH_PGSQL_STATE_CONNECTED) { + PQfinish(handle->con); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Disconnected from [%s]\n", handle->dsn); + } + + handle->state = SWITCH_PGSQL_STATE_DOWN; + + return SWITCH_PGSQL_SUCCESS; +#else + return SWITCH_PGSQL_FAIL; +#endif +} + + +#ifdef SWITCH_HAVE_PGSQL + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handle_t *handle, const char* sql) +{ + char *err_str; + + if (!PQsendQuery(handle->con, sql)) { + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str); + switch_pgsql_finish_results(handle); + goto error; + } + handle->sql = sql; + + return SWITCH_PGSQL_SUCCESS; + error: + return SWITCH_PGSQL_FAIL; +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, const char *func, int line, switch_pgsql_handle_t *handle) +{ + char err_buf[256]; + PGcancel *cancel = NULL; + switch_pgsql_status_t ret = SWITCH_PGSQL_SUCCESS; + + memset(err_buf, 0, 256); + cancel = PQgetCancel(handle->con); + if(!PQcancel(cancel, err_buf, 256)) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CRIT, "Failed to cancel long-running query (%s): %s\n", handle->sql, err_buf); + ret = SWITCH_PGSQL_FAIL; + } + PQfreeCancel(cancel); + return ret; +} + + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec) +{ + switch_pgsql_result_t *res; + switch_time_t start; + switch_time_t ctime; + unsigned int usec = msec * 1000; + char *err_str; + fd_set pgset; + struct timeval timeout; + + if(!handle) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n"); + return SWITCH_PGSQL_FAIL; + } + + /* Try to consume input that might be waiting right away */ + if (PQconsumeInput(handle->con)) { + /* And check to see if we have a full result ready for reading */ + if (PQisBusy(handle->con)) { + + /* Wait for a result to become available, up to msec milliseconds */ + start = switch_time_now(); + while((ctime = switch_time_now()) - start <= usec) { + FD_ZERO(&pgset); + FD_SET(handle->sock, &pgset); + + timeout.tv_sec = 0; + timeout.tv_usec = 500; + + /* Wait for the PostgreSQL socket to be ready for data reads. */ + if (select(FD_SETSIZE, &pgset, NULL, NULL, &timeout) > 0) { + /* Then try to consume any input waiting. */ + if (PQconsumeInput(handle->con)) { + /* And check to see if we have a full result ready for reading */ + if (!PQisBusy(handle->con)) { + /* If we can pull a full result without blocking, then break this loop */ + break; + } + } else { + /* If we had an error trying to consume input, report it and cancel the query. */ + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); + switch_safe_free(err_str); + switch_pgsql_cancel(handle); + goto error; + } + } + } + + /* If we broke the loop above because of a timeout, report that and cancel the query. */ + if (ctime - start > usec) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql); + switch_pgsql_cancel(handle); + goto error; + } + + + + } + } else { + /* If we had an error trying to consume input, report it and cancel the query. */ + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); + switch_safe_free(err_str); + switch_pgsql_cancel(handle); + goto error; + } + + + /* At this point, we know we can read a full result without blocking. */ + if(!(res = malloc(sizeof(switch_pgsql_result_t)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Malloc failed!\n"); + goto error; + } + memset(res, 0, sizeof(switch_pgsql_result_t)); + + + res->result = PQgetResult(handle->con); + if (res->result) { + *result_out = res; + res->status = PQresultStatus(res->result); + switch(res->status) { + case PGRES_TUPLES_OK: + { + res->rows = PQntuples(res->result); + handle->affected_rows = res->rows; + res->cols = PQnfields(res->result); + } + break; + case PGRES_COPY_OUT: + case PGRES_COPY_IN: + case PGRES_COMMAND_OK: + break; + case PGRES_EMPTY_QUERY: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_EMPTY_QUERY\n", handle->sql); + case PGRES_BAD_RESPONSE: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_BAD_RESPONSE\n", handle->sql); + case PGRES_NONFATAL_ERROR: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_NONFATAL_ERROR\n", handle->sql); + case PGRES_FATAL_ERROR: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_FATAL_ERROR\n", handle->sql); + res->err = PQresultErrorMessage(res->result); + goto error; + break; + } + } else { + free(res); + res = NULL; + *result_out = NULL; + goto error; + } + + return SWITCH_PGSQL_SUCCESS; + error: + return SWITCH_PGSQL_FAIL; +} + +SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result) +{ + if (!*result) { + return; + } + + if ((*result)->result) { + PQclear((*result)->result); + } + free(*result); + *result = NULL; +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char* func, int line, switch_pgsql_handle_t *handle) +{ + switch_pgsql_result_t *res = NULL; + switch_pgsql_status_t final_status = SWITCH_PGSQL_SUCCESS; + int done = 0; + do { + switch_pgsql_next_result(handle, &res); + if (res && res->err) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error executing query:\n%s\n", res->err); + final_status = SWITCH_PGSQL_FAIL; + } + if (!res) done = 1; + switch_pgsql_free_result(&res); + } while (!done); + return final_status; +} + +static int db_is_up(switch_pgsql_handle_t *handle) +{ + int ret = 0; + switch_event_t *event; + char *err_str = NULL; + int max_tries = DEFAULT_PGSQL_RETRIES; + int code = 0, recon = 0; + + if (handle) { + max_tries = handle->num_retries; + if (max_tries < 1) + max_tries = DEFAULT_PGSQL_RETRIES; + } + + top: + + if (!handle) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n"); + goto done; + } + if (!handle->con) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n"); + goto done; + } + + if (PQstatus(handle->con) == CONNECTION_BAD) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n"); + handle->state = SWITCH_PGSQL_STATE_ERROR; + PQreset(handle->con); + if (PQstatus(handle->con) == CONNECTION_BAD) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n"); + goto error; + } + handle->state = SWITCH_PGSQL_STATE_CONNECTED; + } + +/* if (!PQsendQuery(handle->con, "SELECT 1")) { + code = __LINE__; + goto error; + } + + if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { + code = __LINE__; + goto error; + } + + if (!result || result->status != PGRES_COMMAND_OK) { + code = __LINE__; + goto error; + } + + switch_pgsql_free_result(&result); + switch_pgsql_finish_results(handle); +*/ + ret = 1; + goto done; + + error: + err_str = switch_pgsql_handle_get_error(handle); + + if (PQstatus(handle->con) == CONNECTION_BAD) { + handle->state = SWITCH_PGSQL_STATE_ERROR; + PQreset(handle->con); + if (PQstatus(handle->con) == CONNECTION_OK) { + handle->state = SWITCH_PGSQL_STATE_CONNECTED; + recon = SWITCH_PGSQL_SUCCESS; + } + } + + max_tries--; + + if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Failure-Message", "The sql server is not responding for DSN %s [%s][%d]", + switch_str_nil(handle->dsn), switch_str_nil(err_str), code); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The sql server is not responding for DSN %s [%s][%d]\n", + switch_str_nil(handle->dsn), switch_str_nil(err_str), code); + + if (recon == SWITCH_PGSQL_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection has been re-established"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "The connection has been re-established\n"); + } else { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n"); + } + if (!max_tries) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n"); + } + + switch_event_fire(&event); + } + + if (!max_tries) { + goto done; + } + + switch_safe_free(err_str); + switch_yield(1000000); + goto top; + + done: + + switch_safe_free(err_str); + + return ret; +} +#endif + + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_connect(switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + if (handle->state == SWITCH_PGSQL_STATE_CONNECTED) { + switch_pgsql_handle_disconnect(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Re-connecting %s\n", handle->dsn); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Connecting %s\n", handle->dsn); + + handle->con = PQconnectdb(handle->dsn); + if (PQstatus(handle->con) != CONNECTION_OK) { + char *err_str; + if ((err_str = switch_pgsql_handle_get_error(handle))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err_str); + switch_safe_free(err_str); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to connect to the database [%s]\n", handle->dsn); + switch_pgsql_handle_disconnect(handle); + } + return SWITCH_PGSQL_FAIL; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Connected to [%s]\n", handle->dsn); + handle->state = SWITCH_PGSQL_STATE_CONNECTED; + handle->sock = PQsocket(handle->con); + return SWITCH_PGSQL_SUCCESS; +#else + return SWITCH_PGSQL_FAIL; +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err) +{ +#ifdef SWITCH_HAVE_PGSQL + switch_pgsql_status_t sstatus = SWITCH_PGSQL_SUCCESS; + char *val = NULL; + switch_pgsql_result_t *result = NULL; + + handle->affected_rows = 0; + + if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) { + goto error; + } + + if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { + goto error; + } + + if (!result || result->status != PGRES_COMMAND_OK) { + sstatus = SWITCH_PGSQL_FAIL; + goto done; + } + + if (handle->affected_rows <= 0) { + goto done; + } + + val = PQgetvalue(result->result, 0, 0); + strncpy(resbuf, val, len); + + done: + + switch_pgsql_free_result(&result); + if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { + sstatus = SWITCH_PGSQL_FAIL; + } + + return sstatus; + error: + return SWITCH_PGSQL_FAIL; +#else + return SWITCH_PGSQL_FAIL; +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err) +{ +#ifdef SWITCH_HAVE_PGSQL + char *err_str = NULL; + + handle->affected_rows = 0; + + if (!db_is_up(handle)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not up!\n"); + goto error; + } + + if (handle->auto_commit == SWITCH_FALSE && handle->in_txn == SWITCH_FALSE) { + if (switch_pgsql_send_query(handle, "BEGIN") != SWITCH_PGSQL_SUCCESS) { + switch_pgsql_finish_results(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending BEGIN!\n"); + goto error; + } + + if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending BEGIN!\n"); + goto error; + } + handle->in_txn = SWITCH_TRUE; + } + + if (switch_pgsql_send_query(handle, sql) != SWITCH_PGSQL_SUCCESS) { + switch_pgsql_finish_results(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending query!\n"); + goto error; + } + + return SWITCH_PGSQL_SUCCESS; + + error: + err_str = switch_pgsql_handle_get_error(handle); + + if (zstr(err_str)) { + err_str = strdup((char *)"SQL ERROR!"); + } + + if (err_str) { + if (!switch_stristr("already exists", err_str) && !switch_stristr("duplicate key name", err_str)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); + } + if (err) { + *err = err_str; + } else { + free(err_str); + } + } +#endif + return SWITCH_PGSQL_FAIL; +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec(switch_pgsql_handle_t *handle, const char *sql, char **err) +{ +#ifdef SWITCH_HAVE_PGSQL + if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) { + goto error; + } + + return switch_pgsql_finish_results(handle); + error: +#endif + return SWITCH_PGSQL_FAIL; +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_callback_exec_detailed(const char *file, const char *func, int line, + switch_pgsql_handle_t *handle, + const char *sql, switch_core_db_callback_func_t callback, void *pdata, + char **err) +{ +#ifdef SWITCH_HAVE_PGSQL + char *err_str = NULL; + int row = 0, col = 0, err_cnt = 0; + switch_pgsql_result_t *result = NULL; + + handle->affected_rows = 0; + + switch_assert(callback != NULL); + + if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) { + goto error; + } + + if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { + err_cnt++; + err_str = switch_pgsql_handle_get_error(handle); + if (result && !zstr(result->err)) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(result->err)); + } + if (!zstr(err_str)) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); + } + switch_safe_free(err_str); + err_str = NULL; + } + + while (result != NULL) { + for (row = 0; row < result->rows; ++row) { + char **names; + char **vals; + + names = calloc(result->cols, sizeof(*names)); + vals = calloc(result->cols, sizeof(*vals)); + + switch_assert(names && vals); + + for (col = 0; col < result->cols; ++col) { + char * tmp; + int len; + + tmp = PQfname(result->result, col); + if (tmp) { + len = strlen(tmp); + names[col] = malloc(len+1); + strncpy(names[col], tmp, len); + + len = PQgetlength(result->result, row, col); + vals[col] = malloc(len+1); + tmp = PQgetvalue(result->result, row, col); + strncpy(vals[col], tmp, len); + } else { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: Column number %d out of range\n", col); + } + } + + if (callback(pdata, row, vals, names)) { + break; + } + + for (col = 0; col < result->cols; ++col) { + free(names[col]); + free(vals[col]); + } + free(names); + free(vals); + } + if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { + err_cnt++; + err_str = switch_pgsql_handle_get_error(handle); + if (result && !zstr(result->err)) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(result->err)); + } + if (!zstr(err_str)) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); + } + switch_safe_free(err_str); + err_str = NULL; + } + } + if (err_cnt) { + goto error; + } + + return SWITCH_PGSQL_SUCCESS; + error: +#endif + return SWITCH_PGSQL_FAIL; +} + +SWITCH_DECLARE(void) switch_pgsql_handle_destroy(switch_pgsql_handle_t **handlep) +{ +#ifdef SWITCH_HAVE_PGSQL + + switch_pgsql_handle_t *handle = NULL; + + if (!handlep) { + return; + } + handle = *handlep; + + if (handle) { + switch_pgsql_handle_disconnect(handle); + + switch_safe_free(handle->dsn); + free(handle); + } + *handlep = NULL; +#else + return; +#endif +} + +SWITCH_DECLARE(switch_pgsql_state_t) switch_pgsql_handle_get_state(switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + return handle ? handle->state : SWITCH_PGSQL_STATE_INIT; +#else + return SWITCH_PGSQL_STATE_ERROR; +#endif +} + +SWITCH_DECLARE(char *) switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + char * err_str; + if (!handle) { + return NULL; + }; + switch_strdup(err_str, PQerrorMessage(handle->con)); + return err_str; +#else + return NULL; +#endif +} + +SWITCH_DECLARE(int) switch_pgsql_handle_affected_rows(switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + return handle->affected_rows; +#else + return 0; +#endif +} + +SWITCH_DECLARE(switch_bool_t) switch_pgsql_available(void) +{ +#ifdef SWITCH_HAVE_PGSQL + return SWITCH_TRUE; +#else + return SWITCH_FALSE; +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLSetAutoCommitAttr(switch_pgsql_handle_t *handle, switch_bool_t on) +{ +#ifdef SWITCH_HAVE_PGSQL + if (on) { + handle->auto_commit = SWITCH_TRUE; + } else { + handle->auto_commit = SWITCH_FALSE; + } + return SWITCH_PGSQL_SUCCESS; +#else + return (switch_pgsql_status_t) SWITCH_FALSE; +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLEndTran(switch_pgsql_handle_t *handle, switch_bool_t commit) +{ +#ifdef SWITCH_HAVE_PGSQL + char * err_str = NULL; + if (commit) { + if(!PQsendQuery(handle->con, "COMMIT")) { + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not commit transaction: %s\n", err_str); + switch_safe_free(err_str); + return SWITCH_PGSQL_FAIL; + } + } else { + if(!PQsendQuery(handle->con, "ROLLBACK")) { + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not rollback transaction: %s\n", err_str); + switch_safe_free(err_str); + return SWITCH_PGSQL_FAIL; + } + } + handle->in_txn = SWITCH_FALSE; + return SWITCH_PGSQL_SUCCESS; +#else + return (switch_pgsql_status_t) SWITCH_FALSE; +#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 e08f9ada73cb7a39477c4fe255fe28af7c6bfa92 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Thu, 4 Oct 2012 20:19:38 +0000 Subject: [PATCH 128/512] Abstract the sql_manager and cache_db stuff so that modules can utilize the core functionality to run their own instance of a cached SQL connection. Includes patch to fix some segs in case ODBC does not have password set or if using PGSQL support. --- src/include/switch_core.h | 31 ++- src/include/switch_types.h | 5 + src/switch_core.c | 2 +- src/switch_core_sqldb.c | 543 ++++++++++++++++++++++--------------- 4 files changed, 351 insertions(+), 230 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 73607926fa..d6da431dfc 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2193,7 +2193,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *dest_proto, sw SWITCH_DECLARE(switch_status_t) switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event); SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_session_t *session, const char *cmds); -SWITCH_DECLARE(void) switch_core_sqldb_stop_thread(void); +SWITCH_DECLARE(void) switch_sqldb_stop_thread(switch_sql_manager_t *sql_manager); +#define switch_core_sqldb_stop_thread() switch_sqldb_stop_thread(&switch_cache_db_sql_manager) + +SWITCH_DECLARE(void) switch_sqldb_start_thread(switch_sql_manager_t *sql_manager, void *(SWITCH_THREAD_FUNC * func) (switch_thread_t *, void *), + char **post_connect_sql, int argc); SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void); ///\} @@ -2240,8 +2244,6 @@ typedef union { switch_cache_db_pgsql_options_t pgsql_options; } switch_cache_db_connection_options_t; -struct switch_cache_db_handle; -typedef struct switch_cache_db_handle switch_cache_db_handle_t; static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_t type) { @@ -2281,7 +2283,9 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t other threads until the allocating thread actually terminates. \param [in] The handle */ +SWITCH_DECLARE(void) _switch_cache_db_release_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh); SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t ** dbh); + /*! \brief Gets a new cached handle from the pool, potentially creating a new connection. The connection is bound to the thread until it (the thread) terminates unless @@ -2290,12 +2294,19 @@ SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t \param [in] type - ODBC or SQLLITE \param [in] connection_options (userid, password, etc) */ +SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manager_t *sql_manager, + switch_cache_db_handle_t ** dbh, + switch_cache_db_handle_type_t type, + switch_cache_db_connection_options_t *connection_options, + const char *file, const char *func, int line); SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t ** dbh, switch_cache_db_handle_type_t type, switch_cache_db_connection_options_t *connection_options, const char *file, const char *func, int line); #define switch_cache_db_get_db_handle(_a, _b, _c) _switch_cache_db_get_db_handle(_a, _b, _c, __FILE__, __SWITCH_FUNC__, __LINE__) + + /*! \brief Executes the sql and returns the result as a string \param [in] dbh The handle @@ -2330,15 +2341,21 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach */ SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh); +extern switch_sql_manager_t switch_cache_db_sql_manager; /*! \brief Provides some feedback as to the status of the db connection pool \param [in] stream stream for status */ +SWITCH_DECLARE(void) _switch_cache_db_status(switch_sql_manager_t *sql_manager, switch_stream_handle_t *stream); SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream); +SWITCH_DECLARE(switch_status_t) __switch_core_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); #define switch_core_db_handle(_a) _switch_core_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) -SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); -#define switch_core_recovery_db_handle(_a) _switch_core_recovery_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) +SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); +#define switch_core_recovery_db_handle(_a) _switch_core_recovery_db_handle(&switch_cache_db_sql_manager, _a, __FILE__, __SWITCH_FUNC__, __LINE__) + +SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); +#define switch_core_persist_db_handle(_a) _switch_core_persist_db_handle(&switch_cache_db_sql_manager, _a, __FILE__, __SWITCH_FUNC__, __LINE__) SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_handle_t *db, const char *test_sql, const char *drop_sql, const char *reactive_sql); @@ -2347,7 +2364,9 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ SWITCH_DECLARE(void) switch_core_set_signal_handlers(void); SWITCH_DECLARE(uint32_t) switch_core_debug_level(void); -SWITCH_DECLARE(void) switch_cache_db_flush_handles(void); +SWITCH_DECLARE(void) switch_cache_db_flush_handles(switch_sql_manager_t *sql_manager); +#define switch_core_cache_db_flush_handles() switch_cache_db_flush_handles(&switch_cache_db_sql_manager) + 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); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 6f77f32ef4..ddd66a0a4e 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1836,6 +1836,11 @@ typedef struct switch_odbc_handle switch_odbc_handle_t; typedef struct switch_pgsql_handle switch_pgsql_handle_t; typedef struct switch_pgsql_result switch_pgsql_result_t; +struct switch_cache_db_handle; +typedef struct switch_cache_db_handle switch_cache_db_handle_t; +struct switch_sql_manager; +typedef struct switch_sql_manager switch_sql_manager_t; + typedef struct switch_io_routines switch_io_routines_t; typedef struct switch_speech_handle switch_speech_handle_t; typedef struct switch_asr_handle switch_asr_handle_t; diff --git a/src/switch_core.c b/src/switch_core.c index 8e1a6567d7..9c525a6c1e 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2260,7 +2260,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void * switch_time_calibrate_clock(); break; case SCSC_FLUSH_DB_HANDLES: - switch_cache_db_flush_handles(); + switch_core_cache_db_flush_handles(); break; case SCSC_SEND_SIGHUP: handle_SIGHUP(1); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index cbc7a611e3..23b08ace75 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -26,6 +26,7 @@ * Anthony Minessale II * Michael Jerris * Paul D. Tinsley + * Eliot Gable * * * switch_core_sqldb.c -- Main Core Library (statistics tracker) @@ -55,7 +56,7 @@ struct switch_cache_db_handle { struct switch_cache_db_handle *next; }; -static struct { +struct switch_sql_manager { switch_cache_db_handle_t *event_db; switch_queue_t *sql_queue[2]; switch_memory_pool_t *memory_pool; @@ -73,7 +74,9 @@ static struct { uint32_t total_handles; uint32_t total_used_handles; switch_cache_db_handle_t *dbh; -} sql_manager; +}; + +switch_sql_manager_t switch_cache_db_sql_manager; static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t type) @@ -90,11 +93,11 @@ static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t typ return new_dbh; } -static void add_handle(switch_cache_db_handle_t *dbh, const char *db_str, const char *db_callsite_str, const char *thread_str) +static void add_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t *dbh, const char *db_str, const char *db_callsite_str, const char *thread_str) { switch_ssize_t hlen = -1; - switch_mutex_lock(sql_manager.dbh_mutex); + switch_mutex_lock(sql_manager->dbh_mutex); switch_set_string(dbh->creator, db_callsite_str); @@ -103,37 +106,37 @@ static void add_handle(switch_cache_db_handle_t *dbh, const char *db_str, const dbh->thread_hash = switch_ci_hashfunc_default(thread_str, &hlen); dbh->use_count++; - sql_manager.total_used_handles++; - dbh->next = sql_manager.handle_pool; + sql_manager->total_used_handles++; + dbh->next = sql_manager->handle_pool; - sql_manager.handle_pool = dbh; - sql_manager.total_handles++; + sql_manager->handle_pool = dbh; + sql_manager->total_handles++; switch_mutex_lock(dbh->mutex); - switch_mutex_unlock(sql_manager.dbh_mutex); + switch_mutex_unlock(sql_manager->dbh_mutex); } -static void del_handle(switch_cache_db_handle_t *dbh) +static void del_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t *dbh) { switch_cache_db_handle_t *dbh_ptr, *last = NULL; - switch_mutex_lock(sql_manager.dbh_mutex); - for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { + switch_mutex_lock(sql_manager->dbh_mutex); + for (dbh_ptr = sql_manager->handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { if (dbh_ptr == dbh) { if (last) { last->next = dbh_ptr->next; } else { - sql_manager.handle_pool = dbh_ptr->next; + sql_manager->handle_pool = dbh_ptr->next; } - sql_manager.total_handles--; + sql_manager->total_handles--; break; } last = dbh_ptr; } - switch_mutex_unlock(sql_manager.dbh_mutex); + switch_mutex_unlock(sql_manager->dbh_mutex); } -static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user_str, const char *thread_str) +static switch_cache_db_handle_t *get_handle(switch_sql_manager_t *sql_manager, const char *db_str, const char *user_str, const char *thread_str) { switch_ssize_t hlen = -1; unsigned long hash = 0, thread_hash = 0; @@ -142,9 +145,9 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user hash = switch_ci_hashfunc_default(db_str, &hlen); thread_hash = switch_ci_hashfunc_default(thread_str, &hlen); - switch_mutex_lock(sql_manager.dbh_mutex); + switch_mutex_lock(sql_manager->dbh_mutex); - for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { + for (dbh_ptr = sql_manager->handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { if (dbh_ptr->thread_hash == thread_hash && dbh_ptr->hash == hash && !switch_test_flag(dbh_ptr, CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { r = dbh_ptr; @@ -152,7 +155,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user } if (!r) { - for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { + for (dbh_ptr = sql_manager->handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { if (dbh_ptr->hash == hash && !dbh_ptr->use_count && !switch_test_flag(dbh_ptr, CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { r = dbh_ptr; @@ -163,13 +166,13 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user if (r) { r->use_count++; - sql_manager.total_used_handles++; + sql_manager->total_used_handles++; r->hash = switch_ci_hashfunc_default(db_str, &hlen); r->thread_hash = thread_hash; switch_set_string(r->last_user, user_str); } - switch_mutex_unlock(sql_manager.dbh_mutex); + switch_mutex_unlock(sql_manager->dbh_mutex); return r; @@ -181,11 +184,16 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user \brief Open the default system database */ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) +{ + return __switch_core_db_handle(&switch_cache_db_sql_manager, dbh, file, func, line); +} + +SWITCH_DECLARE(switch_status_t) __switch_core_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { switch_cache_db_connection_options_t options = { {0} }; switch_status_t r; - if (!sql_manager.manage) { + if (!sql_manager->manage) { return SWITCH_STATUS_FALSE; } @@ -199,26 +207,26 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t } 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); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { char *dsn; if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { options.pgsql_options.dsn = (char*)(dsn + 6); - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_PGSQL, &options, file, func, line); } else { options.odbc_options.dsn = runtime.odbc_dsn; options.odbc_options.user = runtime.odbc_user; options.odbc_options.pass = runtime.odbc_pass; - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_ODBC, &options, file, func, line); } } /* I *think* we can do without this now, if not let me know if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager.io_mutex; + (*dbh)->io_mutex = sql_manager->io_mutex; } */ @@ -229,12 +237,12 @@ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t /*! \brief Open the default system database */ -SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) +SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { switch_cache_db_connection_options_t options = { {0} }; switch_status_t r; - if (!sql_manager.manage) { + if (!sql_manager->manage) { return SWITCH_STATUS_FALSE; } @@ -248,26 +256,26 @@ SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_h } else { options.core_db_options.db_path = SWITCH_CORE_PERSIST_DB; } - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { char *dsn; if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { options.pgsql_options.dsn = (char*)(dsn + 6); - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_PGSQL, &options, file, func, line); } else { options.odbc_options.dsn = runtime.odbc_dsn; options.odbc_options.user = runtime.odbc_user; options.odbc_options.pass = runtime.odbc_pass; - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_ODBC, &options, file, func, line); } } /* I *think* we can do without this now, if not let me know if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager.io_mutex; + (*dbh)->io_mutex = sql_manager->io_mutex; } */ @@ -276,12 +284,12 @@ SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_h #define SWITCH_CORE_RECOVERY_DB "core_recovery" -SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) +SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { switch_cache_db_connection_options_t options = { {0} }; switch_status_t r; - if (!sql_manager.manage) { + if (!sql_manager->manage) { return SWITCH_STATUS_FALSE; } @@ -295,26 +303,26 @@ SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_ } else { options.core_db_options.db_path = SWITCH_CORE_RECOVERY_DB; } - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { char *dsn; if ((dsn = strstr(runtime.recovery_odbc_dsn, "pgsql;")) != NULL) { options.pgsql_options.dsn = (char*)(dsn + 6); - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_PGSQL, &options, file, func, line); } else { options.odbc_options.dsn = runtime.recovery_odbc_dsn; options.odbc_options.user = runtime.recovery_odbc_user; options.odbc_options.pass = runtime.recovery_odbc_pass; - r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_ODBC, &options, file, func, line); } } /* I *think* we can do without this now, if not let me know if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager.io_mutex; + (*dbh)->io_mutex = sql_manager->io_mutex; } */ @@ -326,16 +334,16 @@ SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_ #define SQL_REG_TIMEOUT 15 -static void sql_close(time_t prune) +static void sql_close(switch_sql_manager_t *sql_manager, time_t prune) { switch_cache_db_handle_t *dbh = NULL; int locked = 0; - switch_mutex_lock(sql_manager.dbh_mutex); + switch_mutex_lock(sql_manager->dbh_mutex); top: locked = 0; - for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) { + for (dbh = sql_manager->handle_pool; dbh; dbh = dbh->next) { time_t diff = 0; if (prune > 0 && prune > dbh->last_used) { @@ -368,7 +376,7 @@ static void sql_close(time_t prune) break; } - del_handle(dbh); + del_handle(sql_manager, dbh); switch_mutex_unlock(dbh->mutex); switch_core_destroy_memory_pool(&dbh->pool); goto top; @@ -386,7 +394,7 @@ static void sql_close(time_t prune) goto top; } - switch_mutex_unlock(sql_manager.dbh_mutex); + switch_mutex_unlock(sql_manager->dbh_mutex); } @@ -395,16 +403,20 @@ SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_cache_db_get_type(switch_ca return dbh->type; } -SWITCH_DECLARE(void) switch_cache_db_flush_handles(void) +SWITCH_DECLARE(void) switch_cache_db_flush_handles(switch_sql_manager_t *sql_manager) { - sql_close(switch_epoch_time_now(NULL) + SQL_CACHE_TIMEOUT + 1); + sql_close(sql_manager, switch_epoch_time_now(NULL) + SQL_CACHE_TIMEOUT + 1); } - SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh) +{ + _switch_cache_db_release_db_handle(&switch_cache_db_sql_manager, dbh); +} + +SWITCH_DECLARE(void) _switch_cache_db_release_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh) { if (dbh && *dbh) { - switch_mutex_lock(sql_manager.dbh_mutex); + switch_mutex_lock(sql_manager->dbh_mutex); (*dbh)->last_used = switch_epoch_time_now(NULL); (*dbh)->io_mutex = NULL; @@ -415,9 +427,9 @@ SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t } } switch_mutex_unlock((*dbh)->mutex); - sql_manager.total_used_handles--; + sql_manager->total_used_handles--; *dbh = NULL; - switch_mutex_unlock(sql_manager.dbh_mutex); + switch_mutex_unlock(sql_manager->dbh_mutex); } } @@ -428,7 +440,16 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t } -SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh, +SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t ** dbh, + switch_cache_db_handle_type_t type, + switch_cache_db_connection_options_t *connection_options, + const char *file, const char *func, int line) +{ + return __switch_cache_db_get_db_handle(&switch_cache_db_sql_manager, dbh, type, connection_options, file, func, line); +} + +SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manager_t *sql_manager, + switch_cache_db_handle_t **dbh, switch_cache_db_handle_type_t type, switch_cache_db_connection_options_t *connection_options, const char *file, const char *func, int line) @@ -445,7 +466,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h const char *odbc_user = NULL; const char *odbc_pass = NULL; - while(runtime.max_db_handles && sql_manager.total_handles >= runtime.max_db_handles && sql_manager.total_used_handles >= sql_manager.total_handles) { + while(runtime.max_db_handles && sql_manager->total_handles >= runtime.max_db_handles && sql_manager->total_used_handles >= sql_manager->total_handles) { if (!waiting++) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_WARNING, "Max handles %u exceeded, blocking....\n", runtime.max_db_handles); @@ -496,7 +517,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h snprintf(db_callsite_str, sizeof(db_callsite_str) - 1, "%s:%d", file, line); snprintf(thread_str, sizeof(thread_str) - 1, "thread=\"%lu\"", (unsigned long) (intptr_t) self); - if ((new_dbh = get_handle(db_str, db_callsite_str, thread_str))) { + if ((new_dbh = get_handle(sql_manager, db_str, db_callsite_str, thread_str))) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10, "Reuse Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type)); } else { @@ -552,9 +573,6 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h goto end; } - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10, - "Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line); - new_dbh = create_handle(type); if (db) { @@ -565,7 +583,11 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h new_dbh->native_handle.pgsql_dbh = pgsql_dbh; } - add_handle(new_dbh, db_str, db_callsite_str, thread_str); + add_handle(sql_manager, new_dbh, db_str, db_callsite_str, thread_str); + + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10, + "Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line); + } end: @@ -638,18 +660,20 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t return status; } -static void wake_thread(int force) +static void _wake_thread(switch_sql_manager_t *sql_manager, int force) { if (force) { - switch_thread_cond_signal(sql_manager.cond); + switch_thread_cond_signal(sql_manager->cond); return; } - if (switch_mutex_trylock(sql_manager.cond_mutex) == SWITCH_STATUS_SUCCESS) { - switch_thread_cond_signal(sql_manager.cond); - switch_mutex_unlock(sql_manager.cond_mutex); + if (switch_mutex_trylock(sql_manager->cond_mutex) == SWITCH_STATUS_SUCCESS) { + switch_thread_cond_signal(sql_manager->cond); + switch_mutex_unlock(sql_manager->cond_mutex); } } +#define wake_thread(f) _wake_thread(&switch_cache_db_sql_manager, f) + /** OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions? @@ -1173,13 +1197,16 @@ 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, reg_sec = 0;; + int sec = 0, reg_sec = 0; + switch_sql_manager_t *sql_manager; - sql_manager.db_thread_running = 1; + sql_manager = (switch_sql_manager_t*)obj; - while (sql_manager.db_thread_running == 1) { + sql_manager->db_thread_running = 1; + + while (sql_manager->db_thread_running == 1) { if (++sec == SQL_CACHE_TIMEOUT) { - sql_close(switch_epoch_time_now(NULL)); + sql_close(sql_manager, switch_epoch_time_now(NULL)); wake_thread(0); sec = 0; } @@ -1208,44 +1235,47 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, int lc = 0, wrote = 0, do_sleep = 1; uint32_t sanity = 120; int auto_pause = 0; + switch_sql_manager_t *sql_manager; + + sql_manager = (switch_sql_manager_t*)obj; switch_assert(sqlbuf); - while (!sql_manager.event_db) { - if (switch_core_db_handle(&sql_manager.event_db) == SWITCH_STATUS_SUCCESS && sql_manager.event_db) + while (!sql_manager->event_db) { + if (switch_core_db_handle(&sql_manager->event_db) == SWITCH_STATUS_SUCCESS && sql_manager->event_db) break; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error getting core db, Retrying\n"); switch_yield(500000); sanity--; } - if (!sql_manager.event_db) { + if (!sql_manager->event_db) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error getting core db Disabling core sql functionality\n"); return NULL; } - sql_manager.thread_running = 1; + sql_manager->thread_running = 1; - switch_mutex_lock(sql_manager.cond_mutex); + switch_mutex_lock(sql_manager->cond_mutex); - switch (sql_manager.event_db->type) { + switch (switch_cache_db_sql_manager.event_db->type) { case SCDB_TYPE_PGSQL: break; case SCDB_TYPE_ODBC: break; case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA synchronous=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA count_changes=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA temp_store=MEMORY;", NULL); - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA journal_mode=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA synchronous=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA count_changes=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA temp_store=MEMORY;", NULL); + switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA journal_mode=OFF;", NULL); } break; } - while (sql_manager.thread_running == 1) { - if (save_sql || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || - switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { + while (sql_manager->thread_running == 1) { + if (save_sql || switch_queue_trypop(sql_manager->sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || + switch_queue_trypop(sql_manager->sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { if (save_sql) { sql = save_sql; @@ -1268,8 +1298,8 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, sql_len = new_mlen; if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager.sql_queue[0]), - switch_queue_size(sql_manager.sql_queue[1])); + "REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager->sql_queue[0]), + switch_queue_size(sql_manager->sql_queue[1])); } if (!(tmp = realloc(sqlbuf, sql_len))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n"); @@ -1280,7 +1310,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } else { if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "SAVE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1])); + "SAVE %d %d\n", switch_queue_size(sql_manager->sql_queue[0]), switch_queue_size(sql_manager->sql_queue[1])); } save_sql = sql; sql = NULL; @@ -1289,7 +1319,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } } - iterations++; + iterations++; sprintf(sqlbuf + len, "%s;\n", sql); len += newlen; free(sql); @@ -1300,7 +1330,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } } - lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]); + lc = switch_queue_size(sql_manager->sql_queue[0]) + switch_queue_size(sql_manager->sql_queue[1]); if (lc > SWITCH_SQL_QUEUE_PAUSE_LEN) { @@ -1326,9 +1356,9 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, if (trans && iterations && (iterations > target || !lc)) { if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "RUN %d %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]), iterations); + "RUN %d %d %d\n", switch_queue_size(sql_manager->sql_queue[0]), switch_queue_size(sql_manager->sql_queue[1]), iterations); } - if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) { + if (switch_cache_db_persistant_execute_trans(sql_manager->event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); } if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { @@ -1349,10 +1379,10 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, wrote = 1; } - lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]); + lc = switch_queue_size(sql_manager->sql_queue[0]) + switch_queue_size(sql_manager->sql_queue[1]); if (!lc) { - switch_thread_cond_wait(sql_manager.cond, sql_manager.cond_mutex); + switch_thread_cond_wait(sql_manager->cond, sql_manager->cond_mutex); } else if (wrote) { if (lc > 2000) { do_sleep = 0; @@ -1364,21 +1394,21 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } - switch_mutex_unlock(sql_manager.cond_mutex); + switch_mutex_unlock(sql_manager->cond_mutex); - while (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) { + while (switch_queue_trypop(sql_manager->sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) { free(pop); } - while (switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { + while (switch_queue_trypop(sql_manager->sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { free(pop); } free(sqlbuf); - sql_manager.thread_running = 0; + sql_manager->thread_running = 0; - switch_cache_db_release_db_handle(&sql_manager.event_db); + switch_cache_db_release_db_handle(&sql_manager->event_db); return NULL; } @@ -1820,9 +1850,9 @@ static void core_event_handler(switch_event_t *event) for (i = 0; i < sql_idx; i++) { if (switch_stristr("update channels", sql[i]) || switch_stristr("delete from channels", sql[i])) { - switch_queue_push(sql_manager.sql_queue[1], sql[i]); + switch_queue_push(switch_cache_db_sql_manager.sql_queue[1], sql[i]); } else { - switch_queue_push(sql_manager.sql_queue[0], sql[i]); + switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql[i]); } sql[i] = NULL; wake_thread(0); @@ -2381,7 +2411,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c user, realm, switch_core_get_switchname()); } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); if ( !zstr(metadata) ) { sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname,metadata) " @@ -2413,7 +2443,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; } @@ -2433,7 +2463,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, c sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_switchname()); } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; } @@ -2456,35 +2486,33 @@ SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force) sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_switchname()); } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; } -switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage) +void switch_sqldb_init_sql_manager(switch_sql_manager_t *sql_manager, switch_memory_pool_t *pool, switch_bool_t manage) { - switch_threadattr_t *thd_attr; - uint32_t sanity = 400; - sql_manager.memory_pool = pool; - sql_manager.manage = manage; + sql_manager->memory_pool = pool; + sql_manager->manage = manage; - switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); - switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); - switch_mutex_init(&sql_manager.cond_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); - switch_mutex_init(&sql_manager.ctl_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); + switch_mutex_init(&sql_manager->dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); + switch_mutex_init(&sql_manager->io_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); + switch_mutex_init(&sql_manager->cond_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); + switch_mutex_init(&sql_manager->ctl_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); - switch_thread_cond_create(&sql_manager.cond, sql_manager.memory_pool); + switch_thread_cond_create(&sql_manager->cond, sql_manager->memory_pool); +} +switch_status_t switch_sqldb_connect(switch_sql_manager_t *sql_manager, switch_memory_pool_t *pool) +{ - - if (!sql_manager.manage) goto skip; - - top: + top: /* Activate SQL database */ - if (switch_core_db_handle(&sql_manager.dbh) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&sql_manager->dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { @@ -2508,8 +2536,25 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n"); + return SWITCH_STATUS_SUCCESS; +} - switch (sql_manager.dbh->type) { +switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage) +{ + switch_threadattr_t *thd_attr; + uint32_t sanity = 400; + switch_sql_manager_t *sql_manager = &switch_cache_db_sql_manager; + + switch_sqldb_init_sql_manager(sql_manager, pool, manage); + + if (manage == SWITCH_FALSE) goto skip; + + top: + if (switch_sqldb_connect(sql_manager, pool) == SWITCH_STATUS_FALSE) { + return SWITCH_STATUS_FALSE; + } + + switch (sql_manager->dbh->type) { case SCDB_TYPE_PGSQL: case SCDB_TYPE_ODBC: if (switch_test_flag((&runtime), SCF_CLEAR_SQL)) { @@ -2520,61 +2565,61 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ for (i = 0; tables[i]; i++) { switch_snprintfv(sql, sizeof(sql), "delete from %q where hostname='%q'", tables[i], hostname); - switch_cache_db_execute_sql(sql_manager.dbh, sql, NULL); + switch_cache_db_execute_sql(sql_manager->dbh, sql, NULL); } } break; case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql(sql_manager.dbh, "drop table channels", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "drop table calls", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "drop view detailed_calls", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "drop view basic_calls", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "drop table interfaces", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "drop table tasks", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA synchronous=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA count_changes=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA default_cache_size=8000", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA temp_store=MEMORY;", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA journal_mode=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "drop table channels", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "drop table calls", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "drop view detailed_calls", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "drop view basic_calls", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "drop table interfaces", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "drop table tasks", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA synchronous=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA count_changes=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA default_cache_size=8000", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA temp_store=MEMORY;", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA journal_mode=OFF;", NULL); } break; } - switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", "DROP TABLE registrations", create_registrations_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select metadata from registrations", NULL, "ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256)"); + switch_cache_db_test_reactive(sql_manager->dbh, "select metadata from registrations", NULL, "ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256)"); - switch (sql_manager.dbh->type) { + switch (sql_manager->dbh->type) { case SCDB_TYPE_PGSQL: case SCDB_TYPE_ODBC: { char *err; - switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + switch_cache_db_test_reactive(sql_manager->dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", "DROP TABLE registrations", create_registrations_sql); } else { char *tmp = switch_string_replace(create_registrations_sql, "url TEXT", "url VARCHAR(max)"); - switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + switch_cache_db_test_reactive(sql_manager->dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", "DROP TABLE registrations", tmp); free(tmp); } - switch_cache_db_test_reactive(sql_manager.dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); - switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); + switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_execute_sql(sql_manager.dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err); + switch_cache_db_execute_sql(sql_manager->dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err); } else { - switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err); + switch_cache_db_execute_sql(sql_manager->dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err); } if (err) { @@ -2582,7 +2627,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ runtime.odbc_user = NULL; runtime.odbc_pass = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling non-SQLite support; using SQLite\n"); - switch_cache_db_release_db_handle(&sql_manager.dbh); + switch_cache_db_release_db_handle(&sql_manager->dbh); free(err); goto top; } @@ -2590,49 +2635,49 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ break; case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql(sql_manager.dbh, create_channels_sql, NULL); - switch_cache_db_execute_sql(sql_manager.dbh, create_calls_sql, NULL); - switch_cache_db_execute_sql(sql_manager.dbh, create_interfaces_sql, NULL); - switch_cache_db_execute_sql(sql_manager.dbh, create_tasks_sql, NULL); - switch_cache_db_execute_sql(sql_manager.dbh, detailed_calls_sql, NULL); - switch_cache_db_execute_sql(sql_manager.dbh, basic_calls_sql, NULL); + switch_cache_db_execute_sql(sql_manager->dbh, create_channels_sql, NULL); + switch_cache_db_execute_sql(sql_manager->dbh, create_calls_sql, NULL); + switch_cache_db_execute_sql(sql_manager->dbh, create_interfaces_sql, NULL); + switch_cache_db_execute_sql(sql_manager->dbh, create_tasks_sql, NULL); + switch_cache_db_execute_sql(sql_manager->dbh, detailed_calls_sql, NULL); + switch_cache_db_execute_sql(sql_manager->dbh, basic_calls_sql, NULL); } break; } - switch_cache_db_execute_sql(sql_manager.dbh, "delete from complete where sticky=0", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "delete from aliases where sticky=0", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "delete from nat where sticky=0", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index alias1 on aliases (alias)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index tasks1 on tasks (hostname,task_id)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete1 on complete (a1,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete2 on complete (a2,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete3 on complete (a3,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete4 on complete (a4,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete5 on complete (a5,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete6 on complete (a6,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete7 on complete (a7,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete8 on complete (a8,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete9 on complete (a9,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete10 on complete (a10,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index channels1 on channels(hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index calls1 on calls(hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index chidx1 on channels (hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex on channels (uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex2 on channels (call_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index callsidx1 on calls (hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index eruuindex on calls (caller_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex on calls (callee_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex2 on calls (call_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "delete from complete where sticky=0", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "delete from aliases where sticky=0", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "delete from nat where sticky=0", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index alias1 on aliases (alias)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index tasks1 on tasks (hostname,task_id)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete1 on complete (a1,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete2 on complete (a2,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete3 on complete (a3,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete4 on complete (a4,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete5 on complete (a5,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete6 on complete (a6,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete7 on complete (a7,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete8 on complete (a8,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete9 on complete (a9,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete10 on complete (a10,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index channels1 on channels(hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index calls1 on calls(hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index chidx1 on channels (hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index uuindex on channels (uuid)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index uuindex2 on channels (call_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index callsidx1 on calls (hostname)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index eruuindex on calls (caller_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index eeuuindex on calls (callee_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index eeuuindex2 on calls (call_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager->dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL); skip: - if (sql_manager.manage) { + if (sql_manager->manage) { #ifdef SWITCH_SQL_BIND_EVERY_EVENT switch_event_bind("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); #else @@ -2661,16 +2706,16 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_event_bind("core_db", SWITCH_EVENT_NAT, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); #endif - switch_queue_create(&sql_manager.sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); - switch_queue_create(&sql_manager.sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); + switch_queue_create(&sql_manager->sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager->memory_pool); + switch_queue_create(&sql_manager->sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager->memory_pool); - switch_threadattr_create(&thd_attr, sql_manager.memory_pool); + switch_threadattr_create(&thd_attr, sql_manager->memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_core_sqldb_start_thread(); - switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); + switch_thread_create(&sql_manager->db_thread, thd_attr, switch_core_sql_db_thread, sql_manager, sql_manager->memory_pool); - while (sql_manager.manage && !sql_manager.thread_running && --sanity) { + while (sql_manager->manage && !sql_manager->thread_running && --sanity) { switch_yield(10000); } } @@ -2678,37 +2723,36 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ } -SWITCH_DECLARE(void) switch_core_sqldb_stop_thread(void) +SWITCH_DECLARE(void) switch_sqldb_stop_thread(switch_sql_manager_t *sql_manager) { - switch_mutex_lock(sql_manager.ctl_mutex); - if (sql_manager.thread && sql_manager.thread_running) { + switch_mutex_lock(sql_manager->ctl_mutex); + if (sql_manager->thread && sql_manager->thread_running) { switch_status_t st; - if (sql_manager.manage) { - switch_queue_push(sql_manager.sql_queue[0], NULL); - switch_queue_push(sql_manager.sql_queue[1], NULL); + if (sql_manager->manage) { + switch_queue_push(sql_manager->sql_queue[0], NULL); + switch_queue_push(sql_manager->sql_queue[1], NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n"); wake_thread(0); - sql_manager.thread_running = -1; - switch_thread_join(&st, sql_manager.thread); - sql_manager.thread = NULL; - switch_cache_db_release_db_handle(&sql_manager.dbh); - sql_manager.dbh = NULL; + sql_manager->thread_running = -1; + switch_thread_join(&st, sql_manager->thread); + sql_manager->thread = NULL; + switch_cache_db_release_db_handle(&sql_manager->dbh); + sql_manager->dbh = NULL; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL is not enabled\n"); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is not running\n"); } - switch_mutex_unlock(sql_manager.ctl_mutex); + switch_mutex_unlock(sql_manager->ctl_mutex); } -SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) + +void switch_core_recovery_create_indices(void) { switch_cache_db_handle_t *dbh; - switch_mutex_lock(sql_manager.ctl_mutex); - if (switch_core_recovery_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); @@ -2728,14 +2772,34 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) switch_cache_db_release_db_handle(&dbh); } +} - if (sql_manager.manage) { + +SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) +{ + char *post_connect_sql[2]; + post_connect_sql[0] = "delete from channels"; + post_connect_sql[1] = "delete from calls"; + + switch_core_recovery_create_indices(); + switch_sqldb_start_thread(&switch_cache_db_sql_manager, switch_core_sql_thread, post_connect_sql, 2); + +} + +SWITCH_DECLARE(void) switch_sqldb_start_thread(switch_sql_manager_t *sql_manager, void *(SWITCH_THREAD_FUNC * func) (switch_thread_t *, void *), + char *post_connect_sql[], int argc) +{ + int i = 0; + + switch_mutex_lock(sql_manager->ctl_mutex); + + if (sql_manager->manage) { top: - if (!sql_manager.dbh) { + if (!sql_manager->dbh) { /* Activate SQL database */ - if (switch_core_db_handle(&sql_manager.dbh) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&sql_manager->dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { @@ -2749,7 +2813,7 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) runtime.odbc_pass = NULL; runtime.odbc_dbtype = DBTYPE_DEFAULT; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n"); - sql_manager.dbh = NULL; + sql_manager->dbh = NULL; goto top; } @@ -2758,18 +2822,21 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) goto end; } - switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "delete from calls", NULL); + if (argc && post_connect_sql) { + for ( i = 0; i < argc; i++) { + switch_cache_db_execute_sql(sql_manager->dbh, post_connect_sql[i], NULL); + } + } } - if (!sql_manager.thread) { + if (!sql_manager->thread) { switch_threadattr_t *thd_attr; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting SQL thread.\n"); - switch_threadattr_create(&thd_attr, sql_manager.memory_pool); + switch_threadattr_create(&thd_attr, sql_manager->memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool); + switch_thread_create(&sql_manager->thread, thd_attr, func, sql_manager, sql_manager->memory_pool); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is already running\n"); } @@ -2779,28 +2846,38 @@ SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) end: - switch_mutex_unlock(sql_manager.ctl_mutex); + switch_mutex_unlock(sql_manager->ctl_mutex); } -void switch_core_sqldb_stop(void) +void switch_sqldb_stop(switch_sql_manager_t *sql_manager) { switch_status_t st; switch_event_unbind_callback(core_event_handler); - switch_core_sqldb_stop_thread(); + switch_sqldb_stop_thread(sql_manager); - if (sql_manager.db_thread && sql_manager.db_thread_running) { - sql_manager.db_thread_running = -1; - switch_thread_join(&st, sql_manager.db_thread); + if (sql_manager->db_thread && sql_manager->db_thread_running) { + sql_manager->db_thread_running = -1; + switch_thread_join(&st, sql_manager->db_thread); } - switch_cache_db_flush_handles(); - sql_close(0); + switch_cache_db_flush_handles(sql_manager); + sql_close(sql_manager, 0); +} + +void switch_core_sqldb_stop() +{ + switch_sqldb_stop(&switch_cache_db_sql_manager); } SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) +{ + _switch_cache_db_status(&switch_cache_db_sql_manager, stream); +} + +SWITCH_DECLARE(void) _switch_cache_db_status(switch_sql_manager_t *sql_manager, switch_stream_handle_t *stream) { /* return some status info suitable for the cli */ switch_cache_db_handle_t *dbh = NULL; @@ -2811,11 +2888,16 @@ SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) char *pos2 = NULL; int count = 0, used = 0; - switch_mutex_lock(sql_manager.dbh_mutex); + switch_mutex_lock(sql_manager->dbh_mutex); - for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) { - char *needle = "pass=\""; + for (dbh = sql_manager->handle_pool; dbh; dbh = dbh->next) { + char *needles[3]; time_t diff = 0; + int i = 0; + + needles[0] = "pass=\""; + needles[1] = "password="; + needles[2] = "password='"; diff = now - dbh->last_used; @@ -2828,11 +2910,26 @@ SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) /* sanitize password */ memset(cleankey_str, 0, sizeof(cleankey_str)); - pos1 = strstr(dbh->name, needle) + strlen(needle); - pos2 = strstr(pos1, "\""); - strncpy(cleankey_str, dbh->name, pos1 - dbh->name); - strcpy(&cleankey_str[pos1 - dbh->name], pos2); - + for (i = 0; i < 3; i++) { + if((pos1 = strstr(dbh->name, needles[i]))) { + pos1 += strlen(needles[i]); + + if (!(pos2 = strstr(pos1, "\""))) { + if (!(pos2 = strstr(pos1, "'"))) { + if (!(pos2 = strstr(pos1, " "))) { + pos2 = pos1 + strlen(pos1); + } + } + } + strncpy(cleankey_str, dbh->name, pos1 - dbh->name); + strcpy(&cleankey_str[pos1 - dbh->name], pos2); + break; + } + } + if (i == 3) { + strncpy(cleankey_str, dbh->name, strlen(dbh->name)); + } + count++; if (dbh->use_count) { @@ -2850,7 +2947,7 @@ SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) stream->write_function(stream, "%d total. %d in use.\n", count, used); - switch_mutex_unlock(sql_manager.dbh_mutex); + switch_mutex_unlock(sql_manager->dbh_mutex); } SWITCH_DECLARE(char*)switch_sql_concat(void) From 3dec8fb447973bff9bce020ac2a71a9c277a4569 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Mon, 8 Oct 2012 20:39:09 +0000 Subject: [PATCH 129/512] we don't need to use pg's cflags --- configure.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure.in b/configure.in index 4e036b0d81..e8ab623d7f 100644 --- a/configure.in +++ b/configure.in @@ -403,14 +403,12 @@ if test x"$enable_core_pgsql_support" = x"yes" ; then AC_PATH_PROG([PG_CONFIG], [pg_config], [no]) if test "$PG_CONFIG" != "no"; then AC_MSG_CHECKING([for PostgreSQL libraries]) - POSTGRESQL_CFLAGS="`$PG_CONFIG --cflags` -I`$PG_CONFIG --includedir`" POSTGRESQL_CXXFLAGS="`$PG_CONFIG --cppflags` -I`$PG_CONFIG --includedir`" POSTGRESQL_LDFLAGS="`$PG_CONFIG --ldflags` -L`$PG_CONFIG --libdir` -lpq" POSTGRESQL_VERSION=`$PG_CONFIG --version | sed -e 's#PostgreSQL ##'` AC_DEFINE([SWITCH_HAVE_PGSQL], [1], [Define to 1 if PostgreSQL libraries are available]) AC_CHECK_LIB([pq], [PQgetvalue],, AC_MSG_ERROR([no usable libpq; please install PostgreSQL devel package or equivalent])) AC_MSG_RESULT([yes]) - SWITCH_AM_CFLAGS="$POSTGRESQL_CFLAGS $SWITCH_AM_CFLAGS" SWITCH_AM_CXXFLAGS="$POSTGRESQL_CXXFLAGS $SWITCH_AM_CXXFLAGS" SWITCH_AM_LDFLAGS="$POSTGRESQL_LDFLAGS $SWITCH_AM_LDFLAGS" else From 7e28946ba436c3bdf9eede37365fe8f255826a16 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Mon, 8 Oct 2012 20:56:05 +0000 Subject: [PATCH 130/512] Make error message slightly more verbose. --- src/switch_core_sqldb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 23b08ace75..2888131698 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -607,6 +607,7 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t switch_status_t status = SWITCH_STATUS_FALSE; char *errmsg = NULL; char *tmp = NULL; + char *type = NULL; switch_mutex_t *io_mutex = dbh->io_mutex; if (io_mutex) switch_mutex_lock(io_mutex); @@ -618,17 +619,20 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t switch (dbh->type) { case SCDB_TYPE_PGSQL: { + type = "PGSQL"; status = switch_pgsql_handle_exec(dbh->native_handle.pgsql_dbh, sql, &errmsg); } break; case SCDB_TYPE_ODBC: { + type = "ODBC"; status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL, &errmsg); } break; case SCDB_TYPE_CORE_DB: { int ret = switch_core_db_exec(dbh->native_handle.core_db_dbh, sql, NULL, NULL, &errmsg); + type = "NATIVE"; if (ret == SWITCH_CORE_DB_OK) { status = SWITCH_STATUS_SUCCESS; @@ -645,7 +649,7 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t if (errmsg) { if (!switch_stristr("already exists", errmsg) && !switch_stristr("duplicate key name", errmsg)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n%s\n", errmsg, sql); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s SQL ERR [%s]\n%s\n", (type ? type : "Unknown"), errmsg, sql); } if (err) { *err = errmsg; From dc1477e5750f897047005008b624903f5cf0c37f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 8 Oct 2012 13:08:05 -0500 Subject: [PATCH 131/512] fix build without pgsql --- src/switch_pgsql.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index ead39a7e9f..1094aee20b 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -122,11 +122,9 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_disconnect(switch_pgsq #endif } - -#ifdef SWITCH_HAVE_PGSQL - SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handle_t *handle, const char* sql) { +#ifdef SWITCH_HAVE_PGSQL char *err_str; if (!PQsendQuery(handle->con, sql)) { @@ -139,14 +137,16 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handl return SWITCH_PGSQL_SUCCESS; error: +#endif return SWITCH_PGSQL_FAIL; } SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, const char *func, int line, switch_pgsql_handle_t *handle) { + switch_pgsql_status_t ret = SWITCH_PGSQL_SUCCESS; +#ifdef SWITCH_HAVE_PGSQL char err_buf[256]; PGcancel *cancel = NULL; - switch_pgsql_status_t ret = SWITCH_PGSQL_SUCCESS; memset(err_buf, 0, 256); cancel = PQgetCancel(handle->con); @@ -155,12 +155,14 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, ret = SWITCH_PGSQL_FAIL; } PQfreeCancel(cancel); +#endif return ret; } SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec) { +#ifdef SWITCH_HAVE_PGSQL switch_pgsql_result_t *res; switch_time_t start; switch_time_t ctime; @@ -273,11 +275,14 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq return SWITCH_PGSQL_SUCCESS; error: +#endif return SWITCH_PGSQL_FAIL; } SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result) { +#ifdef SWITCH_HAVE_PGSQL + if (!*result) { return; } @@ -287,10 +292,14 @@ SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result) } free(*result); *result = NULL; +#else + return; +#endif } SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char* func, int line, switch_pgsql_handle_t *handle) { +#ifdef SWITCH_HAVE_PGSQL switch_pgsql_result_t *res = NULL; switch_pgsql_status_t final_status = SWITCH_PGSQL_SUCCESS; int done = 0; @@ -304,8 +313,12 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const cha switch_pgsql_free_result(&res); } while (!done); return final_status; +#else + return SWITCH_PGSQL_FAIL; +#endif } +#ifdef SWITCH_HAVE_PG static int db_is_up(switch_pgsql_handle_t *handle) { int ret = 0; From 93f4c0f69844b5d3718b40c41aa6f3cb6f5e0492 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 8 Oct 2012 13:28:01 -0500 Subject: [PATCH 132/512] move sofia locking contention outside of cache_db handle management --- src/mod/endpoints/mod_sofia/sofia_glue.c | 60 +++++++++++------------- src/mod/endpoints/mod_sofia/sofia_reg.c | 54 ++++++++++----------- 2 files changed, 51 insertions(+), 63 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index a39a8e9e71..0e7ed4db0a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6394,19 +6394,17 @@ void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, { switch_cache_db_handle_t *dbh = NULL; + if (!(dbh = sofia_glue_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + return; + } + if (mutex) { switch_mutex_lock(mutex); } - if (!(dbh = sofia_glue_get_db_handle(profile))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); - goto end; - } - switch_cache_db_persistant_execute_trans(dbh, sql, 1); - end: - switch_cache_db_release_db_handle(&dbh); if (mutex) { @@ -6419,29 +6417,27 @@ void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch switch_cache_db_handle_t *dbh = NULL; char *err = NULL; + if (!(dbh = sofia_glue_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + return; + } + if (mutex) { switch_mutex_lock(mutex); } - if (!(dbh = sofia_glue_get_db_handle(profile))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); - goto end; - } - switch_cache_db_execute_sql(dbh, sql, &err); + if (mutex) { + switch_mutex_unlock(mutex); + } + if (err) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s]\n%s\n", err, sql); free(err); } - end: - switch_cache_db_release_db_handle(&dbh); - - if (mutex) { - switch_mutex_unlock(mutex); - } } switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile, @@ -6451,30 +6447,28 @@ switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile, char *errmsg = NULL; switch_cache_db_handle_t *dbh = NULL; + if (!(dbh = sofia_glue_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + return ret; + } + if (mutex) { switch_mutex_lock(mutex); } - if (!(dbh = sofia_glue_get_db_handle(profile))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); - goto end; - } - switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg); + if (mutex) { + switch_mutex_unlock(mutex); + } + if (errmsg) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg); free(errmsg); } - end: - switch_cache_db_release_db_handle(&dbh); - if (mutex) { - switch_mutex_unlock(mutex); - } - return ret; } @@ -6495,15 +6489,15 @@ char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex ret = switch_cache_db_execute_sql2str(dbh, sql, resbuf, len, &err); + if (mutex) { + switch_mutex_unlock(mutex); + } + if (err) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s]\n%s\n", err, sql); free(err); } - if (mutex) { - switch_mutex_unlock(mutex); - } - switch_cache_db_release_db_handle(&dbh); return ret; diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 1142534401..98299a784b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -690,9 +690,8 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int ",user_agent,server_user,server_host,profile_name,network_ip" ",%d from sip_registrations where call_id='%q' %s", reboot, call_id, sqlextra); - switch_mutex_lock(profile->ireg_mutex); - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile); - switch_mutex_unlock(profile->ireg_mutex); + + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_del_callback, profile); switch_safe_free(sql); sql = switch_mprintf("delete from sip_registrations where call_id='%q' %s", call_id, sqlextra); @@ -708,7 +707,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) { char sql[1024]; - switch_mutex_lock(profile->ireg_mutex); + if (now) { switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires" @@ -719,7 +718,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) ",user_agent,server_user,server_host,profile_name,network_ip" ",%d from sip_registrations where expires > 0", reboot); } - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_del_callback, profile); if (now) { switch_snprintfv(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%q'", (long) now, mod_sofia_globals.hostname); @@ -727,7 +726,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) switch_snprintfv(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); } - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); @@ -735,12 +734,12 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) switch_snprintfv(sql, sizeof(sql), "select call_id from sip_shared_appearance_dialogs where hostname='%q' " "and profile_name='%s' and expires <= %ld", mod_sofia_globals.hostname, profile->name, (long) now); - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sla_dialog_del_callback, profile); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sla_dialog_del_callback, profile); switch_snprintfv(sql, sizeof(sql), "delete from sip_shared_appearance_dialogs where expires > 0 and hostname='%q' and expires <= %ld", mod_sofia_globals.hostname, (long) now); - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); } @@ -751,7 +750,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) switch_snprintfv(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); } - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); if (now) { switch_snprintfv(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%q'", @@ -760,7 +759,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) switch_snprintfv(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); } - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); sofia_presence_check_subscriptions(profile, now); @@ -771,7 +770,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) switch_snprintfv(sql, sizeof(sql), "delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); } - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); if (now) { @@ -781,7 +780,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) " from sip_registrations where hostname='%s' and " "profile_name='%s'", mod_sofia_globals.hostname, profile->name); - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nat_callback, profile); } else if (sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) { switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid," "expires,user_agent,server_user,server_host,profile_name" @@ -789,12 +788,10 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) "or contact like '%%fs_nat=yes%%') and hostname='%s' " "and profile_name='%s'", mod_sofia_globals.hostname, profile->name); - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nat_callback, profile); } } - switch_mutex_unlock(profile->ireg_mutex); - } @@ -837,9 +834,9 @@ void sofia_reg_check_call_id(sofia_profile_t *profile, const char *call_id) ",user_agent,server_user,server_host,profile_name,network_ip" " from sip_registrations where call_id='%q' %s", call_id, sqlextra); - switch_mutex_lock(profile->ireg_mutex); - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_check_callback, profile); - switch_mutex_unlock(profile->ireg_mutex); + + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_check_callback, profile); + switch_safe_free(sql); switch_safe_free(sqlextra); @@ -851,31 +848,28 @@ void sofia_reg_check_sync(sofia_profile_t *profile) { char sql[1024]; - switch_mutex_lock(profile->ireg_mutex); switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires" ",user_agent,server_user,server_host,profile_name,network_ip" " from sip_registrations where expires > 0"); - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_del_callback, profile); switch_snprintfv(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); switch_snprintfv(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); switch_snprintfv(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); switch_snprintfv(sql, sizeof(sql), "delete from sip_subscriptions where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, NULL); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); switch_snprintfv(sql, sizeof(sql), "delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, NULL); - - switch_mutex_unlock(profile->ireg_mutex); + sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); } @@ -1558,13 +1552,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } else { sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", to_user, reg_host); } - switch_mutex_lock(profile->ireg_mutex); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } else { char buf[32] = ""; sql = switch_mprintf("select count(*) from sip_registrations where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, reg_host, contact_str); - switch_mutex_lock(profile->ireg_mutex); + sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); switch_safe_free(sql); @@ -1616,7 +1610,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } - switch_mutex_unlock(profile->ireg_mutex); + if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); From 1215ee4fe1533f4fe0f4c885297e3f8bc6652e39 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 8 Oct 2012 17:19:17 -0500 Subject: [PATCH 133/512] FS-4699 --resolve --- conf/vanilla/vars.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/vanilla/vars.xml b/conf/vanilla/vars.xml index 907c6f1015..f6b3431e9c 100644 --- a/conf/vanilla/vars.xml +++ b/conf/vanilla/vars.xml @@ -212,6 +212,7 @@ + From 4ddc2f96d4a59c469e90aa72f1f6c4fb15af7b2e Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 8 Oct 2012 18:59:14 -0400 Subject: [PATCH 134/512] add new files --- w32/Library/FreeSwitchCore.2008.vcproj | 8 ++++++++ w32/Library/FreeSwitchCore.2010.vcxproj | 4 +++- w32/Library/FreeSwitchCore.2010.vcxproj.filters | 8 +++++++- w32/Library/FreeSwitchCore.vcproj | 8 ++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/w32/Library/FreeSwitchCore.2008.vcproj b/w32/Library/FreeSwitchCore.2008.vcproj index e4303b904d..624e125542 100644 --- a/w32/Library/FreeSwitchCore.2008.vcproj +++ b/w32/Library/FreeSwitchCore.2008.vcproj @@ -854,6 +854,10 @@ RelativePath="..\..\src\switch_odbc.c" > + + @@ -1592,6 +1596,10 @@ RelativePath="..\..\src\include\switch_odbc.h" > + + diff --git a/w32/Library/FreeSwitchCore.2010.vcxproj b/w32/Library/FreeSwitchCore.2010.vcxproj index 5e466c3f10..89d3ed68f0 100644 --- a/w32/Library/FreeSwitchCore.2010.vcxproj +++ b/w32/Library/FreeSwitchCore.2010.vcxproj @@ -419,6 +419,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs 4389;4127;%(DisableSpecificWarnings) + @@ -738,6 +739,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs + @@ -834,4 +836,4 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs - \ No newline at end of file + diff --git a/w32/Library/FreeSwitchCore.2010.vcxproj.filters b/w32/Library/FreeSwitchCore.2010.vcxproj.filters index 9766295d13..7283c0b6ad 100644 --- a/w32/Library/FreeSwitchCore.2010.vcxproj.filters +++ b/w32/Library/FreeSwitchCore.2010.vcxproj.filters @@ -160,6 +160,9 @@ Source Files + + Source Files + Source Files @@ -285,6 +288,9 @@ Header Files + + Header Files + Header Files @@ -342,4 +348,4 @@ {a1474195-5783-4c77-977f-59657b38fd01} - \ No newline at end of file + diff --git a/w32/Library/FreeSwitchCore.vcproj b/w32/Library/FreeSwitchCore.vcproj index 52e5406457..137c455d49 100644 --- a/w32/Library/FreeSwitchCore.vcproj +++ b/w32/Library/FreeSwitchCore.vcproj @@ -534,6 +534,10 @@ RelativePath="..\..\src\switch_odbc.c" > + + @@ -1032,6 +1036,10 @@ RelativePath="..\..\src\include\switch_odbc.h" > + + From 21d240b28cea006cff95ecb1bee1d6d6e6142334 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 8 Oct 2012 19:05:12 -0400 Subject: [PATCH 135/512] windows build --- src/switch_pgsql.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index fc02ab73d5..27550afe67 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -31,9 +31,9 @@ */ #include -#include #ifdef SWITCH_HAVE_PGSQL +#include #include #include From 1ad45f70091b3e0762b14328dd590869bad3a153 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 8 Oct 2012 15:57:44 -0500 Subject: [PATCH 136/512] revert e08f9ada73cb7a39477c4fe255fe28af7c6bfa92 --- src/include/switch_core.h | 31 +-- src/include/switch_types.h | 5 - src/switch_core.c | 2 +- src/switch_core_sqldb.c | 543 +++++++++++++++---------------------- 4 files changed, 230 insertions(+), 351 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index d6da431dfc..73607926fa 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2193,11 +2193,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *dest_proto, sw SWITCH_DECLARE(switch_status_t) switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event); SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_session_t *session, const char *cmds); -SWITCH_DECLARE(void) switch_sqldb_stop_thread(switch_sql_manager_t *sql_manager); -#define switch_core_sqldb_stop_thread() switch_sqldb_stop_thread(&switch_cache_db_sql_manager) - -SWITCH_DECLARE(void) switch_sqldb_start_thread(switch_sql_manager_t *sql_manager, void *(SWITCH_THREAD_FUNC * func) (switch_thread_t *, void *), - char **post_connect_sql, int argc); +SWITCH_DECLARE(void) switch_core_sqldb_stop_thread(void); SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void); ///\} @@ -2244,6 +2240,8 @@ typedef union { switch_cache_db_pgsql_options_t pgsql_options; } switch_cache_db_connection_options_t; +struct switch_cache_db_handle; +typedef struct switch_cache_db_handle switch_cache_db_handle_t; static inline const char *switch_cache_db_type_name(switch_cache_db_handle_type_t type) { @@ -2283,9 +2281,7 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t other threads until the allocating thread actually terminates. \param [in] The handle */ -SWITCH_DECLARE(void) _switch_cache_db_release_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh); SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t ** dbh); - /*! \brief Gets a new cached handle from the pool, potentially creating a new connection. The connection is bound to the thread until it (the thread) terminates unless @@ -2294,19 +2290,12 @@ SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t \param [in] type - ODBC or SQLLITE \param [in] connection_options (userid, password, etc) */ -SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manager_t *sql_manager, - switch_cache_db_handle_t ** dbh, - switch_cache_db_handle_type_t type, - switch_cache_db_connection_options_t *connection_options, - const char *file, const char *func, int line); SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t ** dbh, switch_cache_db_handle_type_t type, switch_cache_db_connection_options_t *connection_options, const char *file, const char *func, int line); #define switch_cache_db_get_db_handle(_a, _b, _c) _switch_cache_db_get_db_handle(_a, _b, _c, __FILE__, __SWITCH_FUNC__, __LINE__) - - /*! \brief Executes the sql and returns the result as a string \param [in] dbh The handle @@ -2341,21 +2330,15 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach */ SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh); -extern switch_sql_manager_t switch_cache_db_sql_manager; /*! \brief Provides some feedback as to the status of the db connection pool \param [in] stream stream for status */ -SWITCH_DECLARE(void) _switch_cache_db_status(switch_sql_manager_t *sql_manager, switch_stream_handle_t *stream); SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream); -SWITCH_DECLARE(switch_status_t) __switch_core_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); #define switch_core_db_handle(_a) _switch_core_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) -SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); -#define switch_core_recovery_db_handle(_a) _switch_core_recovery_db_handle(&switch_cache_db_sql_manager, _a, __FILE__, __SWITCH_FUNC__, __LINE__) - -SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); -#define switch_core_persist_db_handle(_a) _switch_core_persist_db_handle(&switch_cache_db_sql_manager, _a, __FILE__, __SWITCH_FUNC__, __LINE__) +SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t ** dbh, const char *file, const char *func, int line); +#define switch_core_recovery_db_handle(_a) _switch_core_recovery_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__) SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_handle_t *db, const char *test_sql, const char *drop_sql, const char *reactive_sql); @@ -2364,9 +2347,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_ SWITCH_DECLARE(void) switch_core_set_signal_handlers(void); SWITCH_DECLARE(uint32_t) switch_core_debug_level(void); -SWITCH_DECLARE(void) switch_cache_db_flush_handles(switch_sql_manager_t *sql_manager); -#define switch_core_cache_db_flush_handles() switch_cache_db_flush_handles(&switch_cache_db_sql_manager) - +SWITCH_DECLARE(void) switch_cache_db_flush_handles(void); 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); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index ddd66a0a4e..6f77f32ef4 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1836,11 +1836,6 @@ typedef struct switch_odbc_handle switch_odbc_handle_t; typedef struct switch_pgsql_handle switch_pgsql_handle_t; typedef struct switch_pgsql_result switch_pgsql_result_t; -struct switch_cache_db_handle; -typedef struct switch_cache_db_handle switch_cache_db_handle_t; -struct switch_sql_manager; -typedef struct switch_sql_manager switch_sql_manager_t; - typedef struct switch_io_routines switch_io_routines_t; typedef struct switch_speech_handle switch_speech_handle_t; typedef struct switch_asr_handle switch_asr_handle_t; diff --git a/src/switch_core.c b/src/switch_core.c index 9c525a6c1e..8e1a6567d7 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2260,7 +2260,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void * switch_time_calibrate_clock(); break; case SCSC_FLUSH_DB_HANDLES: - switch_core_cache_db_flush_handles(); + switch_cache_db_flush_handles(); break; case SCSC_SEND_SIGHUP: handle_SIGHUP(1); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 2888131698..b679baab0c 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -26,7 +26,6 @@ * Anthony Minessale II * Michael Jerris * Paul D. Tinsley - * Eliot Gable * * * switch_core_sqldb.c -- Main Core Library (statistics tracker) @@ -56,7 +55,7 @@ struct switch_cache_db_handle { struct switch_cache_db_handle *next; }; -struct switch_sql_manager { +static struct { switch_cache_db_handle_t *event_db; switch_queue_t *sql_queue[2]; switch_memory_pool_t *memory_pool; @@ -74,9 +73,7 @@ struct switch_sql_manager { uint32_t total_handles; uint32_t total_used_handles; switch_cache_db_handle_t *dbh; -}; - -switch_sql_manager_t switch_cache_db_sql_manager; +} sql_manager; static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t type) @@ -93,11 +90,11 @@ static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t typ return new_dbh; } -static void add_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t *dbh, const char *db_str, const char *db_callsite_str, const char *thread_str) +static void add_handle(switch_cache_db_handle_t *dbh, const char *db_str, const char *db_callsite_str, const char *thread_str) { switch_ssize_t hlen = -1; - switch_mutex_lock(sql_manager->dbh_mutex); + switch_mutex_lock(sql_manager.dbh_mutex); switch_set_string(dbh->creator, db_callsite_str); @@ -106,37 +103,37 @@ static void add_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle dbh->thread_hash = switch_ci_hashfunc_default(thread_str, &hlen); dbh->use_count++; - sql_manager->total_used_handles++; - dbh->next = sql_manager->handle_pool; + sql_manager.total_used_handles++; + dbh->next = sql_manager.handle_pool; - sql_manager->handle_pool = dbh; - sql_manager->total_handles++; + sql_manager.handle_pool = dbh; + sql_manager.total_handles++; switch_mutex_lock(dbh->mutex); - switch_mutex_unlock(sql_manager->dbh_mutex); + switch_mutex_unlock(sql_manager.dbh_mutex); } -static void del_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t *dbh) +static void del_handle(switch_cache_db_handle_t *dbh) { switch_cache_db_handle_t *dbh_ptr, *last = NULL; - switch_mutex_lock(sql_manager->dbh_mutex); - for (dbh_ptr = sql_manager->handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { + switch_mutex_lock(sql_manager.dbh_mutex); + for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { if (dbh_ptr == dbh) { if (last) { last->next = dbh_ptr->next; } else { - sql_manager->handle_pool = dbh_ptr->next; + sql_manager.handle_pool = dbh_ptr->next; } - sql_manager->total_handles--; + sql_manager.total_handles--; break; } last = dbh_ptr; } - switch_mutex_unlock(sql_manager->dbh_mutex); + switch_mutex_unlock(sql_manager.dbh_mutex); } -static switch_cache_db_handle_t *get_handle(switch_sql_manager_t *sql_manager, const char *db_str, const char *user_str, const char *thread_str) +static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user_str, const char *thread_str) { switch_ssize_t hlen = -1; unsigned long hash = 0, thread_hash = 0; @@ -145,9 +142,9 @@ static switch_cache_db_handle_t *get_handle(switch_sql_manager_t *sql_manager, c hash = switch_ci_hashfunc_default(db_str, &hlen); thread_hash = switch_ci_hashfunc_default(thread_str, &hlen); - switch_mutex_lock(sql_manager->dbh_mutex); + switch_mutex_lock(sql_manager.dbh_mutex); - for (dbh_ptr = sql_manager->handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { + for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { if (dbh_ptr->thread_hash == thread_hash && dbh_ptr->hash == hash && !switch_test_flag(dbh_ptr, CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { r = dbh_ptr; @@ -155,7 +152,7 @@ static switch_cache_db_handle_t *get_handle(switch_sql_manager_t *sql_manager, c } if (!r) { - for (dbh_ptr = sql_manager->handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { + for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { if (dbh_ptr->hash == hash && !dbh_ptr->use_count && !switch_test_flag(dbh_ptr, CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { r = dbh_ptr; @@ -166,13 +163,13 @@ static switch_cache_db_handle_t *get_handle(switch_sql_manager_t *sql_manager, c if (r) { r->use_count++; - sql_manager->total_used_handles++; + sql_manager.total_used_handles++; r->hash = switch_ci_hashfunc_default(db_str, &hlen); r->thread_hash = thread_hash; switch_set_string(r->last_user, user_str); } - switch_mutex_unlock(sql_manager->dbh_mutex); + switch_mutex_unlock(sql_manager.dbh_mutex); return r; @@ -184,16 +181,11 @@ static switch_cache_db_handle_t *get_handle(switch_sql_manager_t *sql_manager, c \brief Open the default system database */ SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) -{ - return __switch_core_db_handle(&switch_cache_db_sql_manager, dbh, file, func, line); -} - -SWITCH_DECLARE(switch_status_t) __switch_core_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { switch_cache_db_connection_options_t options = { {0} }; switch_status_t r; - if (!sql_manager->manage) { + if (!sql_manager.manage) { return SWITCH_STATUS_FALSE; } @@ -207,26 +199,26 @@ SWITCH_DECLARE(switch_status_t) __switch_core_db_handle(switch_sql_manager_t *sq } else { options.core_db_options.db_path = SWITCH_CORE_DB; } - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { char *dsn; if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { options.pgsql_options.dsn = (char*)(dsn + 6); - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); } else { options.odbc_options.dsn = runtime.odbc_dsn; options.odbc_options.user = runtime.odbc_user; options.odbc_options.pass = runtime.odbc_pass; - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); } } /* I *think* we can do without this now, if not let me know if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager->io_mutex; + (*dbh)->io_mutex = sql_manager.io_mutex; } */ @@ -237,12 +229,12 @@ SWITCH_DECLARE(switch_status_t) __switch_core_db_handle(switch_sql_manager_t *sq /*! \brief Open the default system database */ -SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) +SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { switch_cache_db_connection_options_t options = { {0} }; switch_status_t r; - if (!sql_manager->manage) { + if (!sql_manager.manage) { return SWITCH_STATUS_FALSE; } @@ -256,26 +248,26 @@ SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_sql_manage } else { options.core_db_options.db_path = SWITCH_CORE_PERSIST_DB; } - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { char *dsn; if ((dsn = strstr(runtime.odbc_dsn, "pgsql;")) != NULL) { options.pgsql_options.dsn = (char*)(dsn + 6); - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); } else { options.odbc_options.dsn = runtime.odbc_dsn; options.odbc_options.user = runtime.odbc_user; options.odbc_options.pass = runtime.odbc_pass; - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); } } /* I *think* we can do without this now, if not let me know if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager->io_mutex; + (*dbh)->io_mutex = sql_manager.io_mutex; } */ @@ -284,12 +276,12 @@ SWITCH_DECLARE(switch_status_t) _switch_core_persist_db_handle(switch_sql_manage #define SWITCH_CORE_RECOVERY_DB "core_recovery" -SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) +SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line) { switch_cache_db_connection_options_t options = { {0} }; switch_status_t r; - if (!sql_manager->manage) { + if (!sql_manager.manage) { return SWITCH_STATUS_FALSE; } @@ -303,26 +295,26 @@ SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_sql_manag } else { options.core_db_options.db_path = SWITCH_CORE_RECOVERY_DB; } - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_CORE_DB, &options, file, func, line); } else { char *dsn; if ((dsn = strstr(runtime.recovery_odbc_dsn, "pgsql;")) != NULL) { options.pgsql_options.dsn = (char*)(dsn + 6); - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_PGSQL, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_PGSQL, &options, file, func, line); } else { options.odbc_options.dsn = runtime.recovery_odbc_dsn; options.odbc_options.user = runtime.recovery_odbc_user; options.odbc_options.pass = runtime.recovery_odbc_pass; - r = __switch_cache_db_get_db_handle(sql_manager, dbh, SCDB_TYPE_ODBC, &options, file, func, line); + r = _switch_cache_db_get_db_handle(dbh, SCDB_TYPE_ODBC, &options, file, func, line); } } /* I *think* we can do without this now, if not let me know if (r == SWITCH_STATUS_SUCCESS && !(*dbh)->io_mutex) { - (*dbh)->io_mutex = sql_manager->io_mutex; + (*dbh)->io_mutex = sql_manager.io_mutex; } */ @@ -334,16 +326,16 @@ SWITCH_DECLARE(switch_status_t) _switch_core_recovery_db_handle(switch_sql_manag #define SQL_REG_TIMEOUT 15 -static void sql_close(switch_sql_manager_t *sql_manager, time_t prune) +static void sql_close(time_t prune) { switch_cache_db_handle_t *dbh = NULL; int locked = 0; - switch_mutex_lock(sql_manager->dbh_mutex); + switch_mutex_lock(sql_manager.dbh_mutex); top: locked = 0; - for (dbh = sql_manager->handle_pool; dbh; dbh = dbh->next) { + for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) { time_t diff = 0; if (prune > 0 && prune > dbh->last_used) { @@ -376,7 +368,7 @@ static void sql_close(switch_sql_manager_t *sql_manager, time_t prune) break; } - del_handle(sql_manager, dbh); + del_handle(dbh); switch_mutex_unlock(dbh->mutex); switch_core_destroy_memory_pool(&dbh->pool); goto top; @@ -394,7 +386,7 @@ static void sql_close(switch_sql_manager_t *sql_manager, time_t prune) goto top; } - switch_mutex_unlock(sql_manager->dbh_mutex); + switch_mutex_unlock(sql_manager.dbh_mutex); } @@ -403,20 +395,16 @@ SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_cache_db_get_type(switch_ca return dbh->type; } -SWITCH_DECLARE(void) switch_cache_db_flush_handles(switch_sql_manager_t *sql_manager) +SWITCH_DECLARE(void) switch_cache_db_flush_handles(void) { - sql_close(sql_manager, switch_epoch_time_now(NULL) + SQL_CACHE_TIMEOUT + 1); + sql_close(switch_epoch_time_now(NULL) + SQL_CACHE_TIMEOUT + 1); } + SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh) -{ - _switch_cache_db_release_db_handle(&switch_cache_db_sql_manager, dbh); -} - -SWITCH_DECLARE(void) _switch_cache_db_release_db_handle(switch_sql_manager_t *sql_manager, switch_cache_db_handle_t **dbh) { if (dbh && *dbh) { - switch_mutex_lock(sql_manager->dbh_mutex); + switch_mutex_lock(sql_manager.dbh_mutex); (*dbh)->last_used = switch_epoch_time_now(NULL); (*dbh)->io_mutex = NULL; @@ -427,9 +415,9 @@ SWITCH_DECLARE(void) _switch_cache_db_release_db_handle(switch_sql_manager_t *sq } } switch_mutex_unlock((*dbh)->mutex); - sql_manager->total_used_handles--; + sql_manager.total_used_handles--; *dbh = NULL; - switch_mutex_unlock(sql_manager->dbh_mutex); + switch_mutex_unlock(sql_manager.dbh_mutex); } } @@ -440,16 +428,7 @@ SWITCH_DECLARE(void) switch_cache_db_dismiss_db_handle(switch_cache_db_handle_t } -SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t ** dbh, - switch_cache_db_handle_type_t type, - switch_cache_db_connection_options_t *connection_options, - const char *file, const char *func, int line) -{ - return __switch_cache_db_get_db_handle(&switch_cache_db_sql_manager, dbh, type, connection_options, file, func, line); -} - -SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manager_t *sql_manager, - switch_cache_db_handle_t **dbh, +SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh, switch_cache_db_handle_type_t type, switch_cache_db_connection_options_t *connection_options, const char *file, const char *func, int line) @@ -466,7 +445,7 @@ SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manag const char *odbc_user = NULL; const char *odbc_pass = NULL; - while(runtime.max_db_handles && sql_manager->total_handles >= runtime.max_db_handles && sql_manager->total_used_handles >= sql_manager->total_handles) { + while(runtime.max_db_handles && sql_manager.total_handles >= runtime.max_db_handles && sql_manager.total_used_handles >= sql_manager.total_handles) { if (!waiting++) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_WARNING, "Max handles %u exceeded, blocking....\n", runtime.max_db_handles); @@ -517,7 +496,7 @@ SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manag snprintf(db_callsite_str, sizeof(db_callsite_str) - 1, "%s:%d", file, line); snprintf(thread_str, sizeof(thread_str) - 1, "thread=\"%lu\"", (unsigned long) (intptr_t) self); - if ((new_dbh = get_handle(sql_manager, db_str, db_callsite_str, thread_str))) { + if ((new_dbh = get_handle(db_str, db_callsite_str, thread_str))) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10, "Reuse Unused Cached DB handle %s [%s]\n", new_dbh->name, switch_cache_db_type_name(new_dbh->type)); } else { @@ -573,6 +552,9 @@ SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manag goto end; } + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10, + "Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line); + new_dbh = create_handle(type); if (db) { @@ -583,11 +565,7 @@ SWITCH_DECLARE(switch_status_t) __switch_cache_db_get_db_handle(switch_sql_manag new_dbh->native_handle.pgsql_dbh = pgsql_dbh; } - add_handle(sql_manager, new_dbh, db_str, db_callsite_str, thread_str); - - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG10, - "Create Cached DB handle %s [%s] %s:%d\n", new_dbh->name, switch_cache_db_type_name(type), file, line); - + add_handle(new_dbh, db_str, db_callsite_str, thread_str); } end: @@ -664,20 +642,18 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t return status; } -static void _wake_thread(switch_sql_manager_t *sql_manager, int force) +static void wake_thread(int force) { if (force) { - switch_thread_cond_signal(sql_manager->cond); + switch_thread_cond_signal(sql_manager.cond); return; } - if (switch_mutex_trylock(sql_manager->cond_mutex) == SWITCH_STATUS_SUCCESS) { - switch_thread_cond_signal(sql_manager->cond); - switch_mutex_unlock(sql_manager->cond_mutex); + if (switch_mutex_trylock(sql_manager.cond_mutex) == SWITCH_STATUS_SUCCESS) { + switch_thread_cond_signal(sql_manager.cond); + switch_mutex_unlock(sql_manager.cond_mutex); } } -#define wake_thread(f) _wake_thread(&switch_cache_db_sql_manager, f) - /** OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions? @@ -1201,16 +1177,13 @@ 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, reg_sec = 0; - switch_sql_manager_t *sql_manager; + int sec = 0, reg_sec = 0;; - sql_manager = (switch_sql_manager_t*)obj; + sql_manager.db_thread_running = 1; - sql_manager->db_thread_running = 1; - - while (sql_manager->db_thread_running == 1) { + while (sql_manager.db_thread_running == 1) { if (++sec == SQL_CACHE_TIMEOUT) { - sql_close(sql_manager, switch_epoch_time_now(NULL)); + sql_close(switch_epoch_time_now(NULL)); wake_thread(0); sec = 0; } @@ -1239,47 +1212,44 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, int lc = 0, wrote = 0, do_sleep = 1; uint32_t sanity = 120; int auto_pause = 0; - switch_sql_manager_t *sql_manager; - - sql_manager = (switch_sql_manager_t*)obj; switch_assert(sqlbuf); - while (!sql_manager->event_db) { - if (switch_core_db_handle(&sql_manager->event_db) == SWITCH_STATUS_SUCCESS && sql_manager->event_db) + while (!sql_manager.event_db) { + if (switch_core_db_handle(&sql_manager.event_db) == SWITCH_STATUS_SUCCESS && sql_manager.event_db) break; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error getting core db, Retrying\n"); switch_yield(500000); sanity--; } - if (!sql_manager->event_db) { + if (!sql_manager.event_db) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error getting core db Disabling core sql functionality\n"); return NULL; } - sql_manager->thread_running = 1; + sql_manager.thread_running = 1; - switch_mutex_lock(sql_manager->cond_mutex); + switch_mutex_lock(sql_manager.cond_mutex); - switch (switch_cache_db_sql_manager.event_db->type) { + switch (sql_manager.event_db->type) { case SCDB_TYPE_PGSQL: break; case SCDB_TYPE_ODBC: break; case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA synchronous=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA count_changes=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA temp_store=MEMORY;", NULL); - switch_cache_db_execute_sql(sql_manager->event_db, "PRAGMA journal_mode=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA synchronous=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA count_changes=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA temp_store=MEMORY;", NULL); + switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA journal_mode=OFF;", NULL); } break; } - while (sql_manager->thread_running == 1) { - if (save_sql || switch_queue_trypop(sql_manager->sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || - switch_queue_trypop(sql_manager->sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { + while (sql_manager.thread_running == 1) { + if (save_sql || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || + switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { if (save_sql) { sql = save_sql; @@ -1302,8 +1272,8 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, sql_len = new_mlen; if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager->sql_queue[0]), - switch_queue_size(sql_manager->sql_queue[1])); + "REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager.sql_queue[0]), + switch_queue_size(sql_manager.sql_queue[1])); } if (!(tmp = realloc(sqlbuf, sql_len))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n"); @@ -1314,7 +1284,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } else { if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "SAVE %d %d\n", switch_queue_size(sql_manager->sql_queue[0]), switch_queue_size(sql_manager->sql_queue[1])); + "SAVE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1])); } save_sql = sql; sql = NULL; @@ -1323,7 +1293,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } } - iterations++; + iterations++; sprintf(sqlbuf + len, "%s;\n", sql); len += newlen; free(sql); @@ -1334,7 +1304,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } } - lc = switch_queue_size(sql_manager->sql_queue[0]) + switch_queue_size(sql_manager->sql_queue[1]); + lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]); if (lc > SWITCH_SQL_QUEUE_PAUSE_LEN) { @@ -1360,9 +1330,9 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, if (trans && iterations && (iterations > target || !lc)) { if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "RUN %d %d %d\n", switch_queue_size(sql_manager->sql_queue[0]), switch_queue_size(sql_manager->sql_queue[1]), iterations); + "RUN %d %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]), iterations); } - if (switch_cache_db_persistant_execute_trans(sql_manager->event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) { + if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); } if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { @@ -1383,10 +1353,10 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, wrote = 1; } - lc = switch_queue_size(sql_manager->sql_queue[0]) + switch_queue_size(sql_manager->sql_queue[1]); + lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]); if (!lc) { - switch_thread_cond_wait(sql_manager->cond, sql_manager->cond_mutex); + switch_thread_cond_wait(sql_manager.cond, sql_manager.cond_mutex); } else if (wrote) { if (lc > 2000) { do_sleep = 0; @@ -1398,21 +1368,21 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } - switch_mutex_unlock(sql_manager->cond_mutex); + switch_mutex_unlock(sql_manager.cond_mutex); - while (switch_queue_trypop(sql_manager->sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) { + while (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) { free(pop); } - while (switch_queue_trypop(sql_manager->sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { + while (switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { free(pop); } free(sqlbuf); - sql_manager->thread_running = 0; + sql_manager.thread_running = 0; - switch_cache_db_release_db_handle(&sql_manager->event_db); + switch_cache_db_release_db_handle(&sql_manager.event_db); return NULL; } @@ -1854,9 +1824,9 @@ static void core_event_handler(switch_event_t *event) for (i = 0; i < sql_idx; i++) { if (switch_stristr("update channels", sql[i]) || switch_stristr("delete from channels", sql[i])) { - switch_queue_push(switch_cache_db_sql_manager.sql_queue[1], sql[i]); + switch_queue_push(sql_manager.sql_queue[1], sql[i]); } else { - switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql[i]); + switch_queue_push(sql_manager.sql_queue[0], sql[i]); } sql[i] = NULL; wake_thread(0); @@ -2415,7 +2385,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c user, realm, switch_core_get_switchname()); } - switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); + switch_queue_push(sql_manager.sql_queue[0], sql); if ( !zstr(metadata) ) { sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname,metadata) " @@ -2447,7 +2417,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c } - switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); + switch_queue_push(sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; } @@ -2467,7 +2437,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, c sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_switchname()); } - switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); + switch_queue_push(sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; } @@ -2490,33 +2460,35 @@ SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force) sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_switchname()); } - switch_queue_push(switch_cache_db_sql_manager.sql_queue[0], sql); + switch_queue_push(sql_manager.sql_queue[0], sql); return SWITCH_STATUS_SUCCESS; } -void switch_sqldb_init_sql_manager(switch_sql_manager_t *sql_manager, switch_memory_pool_t *pool, switch_bool_t manage) +switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage) { + switch_threadattr_t *thd_attr; + uint32_t sanity = 400; - sql_manager->memory_pool = pool; - sql_manager->manage = manage; + sql_manager.memory_pool = pool; + sql_manager.manage = manage; - switch_mutex_init(&sql_manager->dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); - switch_mutex_init(&sql_manager->io_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); - switch_mutex_init(&sql_manager->cond_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); - switch_mutex_init(&sql_manager->ctl_mutex, SWITCH_MUTEX_NESTED, sql_manager->memory_pool); + switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); + switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); + switch_mutex_init(&sql_manager.cond_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); + switch_mutex_init(&sql_manager.ctl_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); - switch_thread_cond_create(&sql_manager->cond, sql_manager->memory_pool); -} + switch_thread_cond_create(&sql_manager.cond, sql_manager.memory_pool); -switch_status_t switch_sqldb_connect(switch_sql_manager_t *sql_manager, switch_memory_pool_t *pool) -{ - top: + + if (!sql_manager.manage) goto skip; + + top: /* Activate SQL database */ - if (switch_core_db_handle(&sql_manager->dbh) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&sql_manager.dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { @@ -2540,25 +2512,8 @@ switch_status_t switch_sqldb_connect(switch_sql_manager_t *sql_manager, switch_m switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening DB\n"); - 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; - uint32_t sanity = 400; - switch_sql_manager_t *sql_manager = &switch_cache_db_sql_manager; - - switch_sqldb_init_sql_manager(sql_manager, pool, manage); - - if (manage == SWITCH_FALSE) goto skip; - - top: - if (switch_sqldb_connect(sql_manager, pool) == SWITCH_STATUS_FALSE) { - return SWITCH_STATUS_FALSE; - } - - switch (sql_manager->dbh->type) { + switch (sql_manager.dbh->type) { case SCDB_TYPE_PGSQL: case SCDB_TYPE_ODBC: if (switch_test_flag((&runtime), SCF_CLEAR_SQL)) { @@ -2569,61 +2524,61 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ for (i = 0; tables[i]; i++) { switch_snprintfv(sql, sizeof(sql), "delete from %q where hostname='%q'", tables[i], hostname); - switch_cache_db_execute_sql(sql_manager->dbh, sql, NULL); + switch_cache_db_execute_sql(sql_manager.dbh, sql, NULL); } } break; case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql(sql_manager->dbh, "drop table channels", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "drop table calls", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "drop view detailed_calls", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "drop view basic_calls", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "drop table interfaces", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "drop table tasks", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA synchronous=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA count_changes=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA default_cache_size=8000", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA temp_store=MEMORY;", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "PRAGMA journal_mode=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "drop table channels", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "drop table calls", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "drop view detailed_calls", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "drop view basic_calls", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "drop table interfaces", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "drop table tasks", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA synchronous=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA count_changes=OFF;", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA default_cache_size=8000", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA temp_store=MEMORY;", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "PRAGMA journal_mode=OFF;", NULL); } break; } - switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from aliases", "DROP TABLE aliases", create_alias_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from complete", "DROP TABLE complete", create_complete_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from nat", "DROP TABLE nat", create_nat_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", "DROP TABLE registrations", create_registrations_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "select metadata from registrations", NULL, "ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256)"); + switch_cache_db_test_reactive(sql_manager.dbh, "select metadata from registrations", NULL, "ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256)"); - switch (sql_manager->dbh->type) { + switch (sql_manager.dbh->type) { case SCDB_TYPE_PGSQL: case SCDB_TYPE_ODBC: { char *err; - switch_cache_db_test_reactive(sql_manager->dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_test_reactive(sql_manager->dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", "DROP TABLE registrations", create_registrations_sql); } else { char *tmp = switch_string_replace(create_registrations_sql, "url TEXT", "url VARCHAR(max)"); - switch_cache_db_test_reactive(sql_manager->dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", + switch_cache_db_test_reactive(sql_manager.dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'", "DROP TABLE registrations", tmp); free(tmp); } - switch_cache_db_test_reactive(sql_manager->dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); - switch_cache_db_test_reactive(sql_manager->dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_execute_sql(sql_manager->dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err); + switch_cache_db_execute_sql(sql_manager.dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err); } else { - switch_cache_db_execute_sql(sql_manager->dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err); + switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err); } if (err) { @@ -2631,7 +2586,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ runtime.odbc_user = NULL; runtime.odbc_pass = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling non-SQLite support; using SQLite\n"); - switch_cache_db_release_db_handle(&sql_manager->dbh); + switch_cache_db_release_db_handle(&sql_manager.dbh); free(err); goto top; } @@ -2639,49 +2594,49 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ break; case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql(sql_manager->dbh, create_channels_sql, NULL); - switch_cache_db_execute_sql(sql_manager->dbh, create_calls_sql, NULL); - switch_cache_db_execute_sql(sql_manager->dbh, create_interfaces_sql, NULL); - switch_cache_db_execute_sql(sql_manager->dbh, create_tasks_sql, NULL); - switch_cache_db_execute_sql(sql_manager->dbh, detailed_calls_sql, NULL); - switch_cache_db_execute_sql(sql_manager->dbh, basic_calls_sql, NULL); + switch_cache_db_execute_sql(sql_manager.dbh, create_channels_sql, NULL); + switch_cache_db_execute_sql(sql_manager.dbh, create_calls_sql, NULL); + switch_cache_db_execute_sql(sql_manager.dbh, create_interfaces_sql, NULL); + switch_cache_db_execute_sql(sql_manager.dbh, create_tasks_sql, NULL); + switch_cache_db_execute_sql(sql_manager.dbh, detailed_calls_sql, NULL); + switch_cache_db_execute_sql(sql_manager.dbh, basic_calls_sql, NULL); } break; } - switch_cache_db_execute_sql(sql_manager->dbh, "delete from complete where sticky=0", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "delete from aliases where sticky=0", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "delete from nat where sticky=0", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index alias1 on aliases (alias)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index tasks1 on tasks (hostname,task_id)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete1 on complete (a1,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete2 on complete (a2,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete3 on complete (a3,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete4 on complete (a4,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete5 on complete (a5,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete6 on complete (a6,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete7 on complete (a7,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete8 on complete (a8,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete9 on complete (a9,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete10 on complete (a10,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index channels1 on channels(hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index calls1 on calls(hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index chidx1 on channels (hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index uuindex on channels (uuid)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index uuindex2 on channels (call_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index callsidx1 on calls (hostname)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index eruuindex on calls (caller_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index eeuuindex on calls (callee_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index eeuuindex2 on calls (call_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager->dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "delete from complete where sticky=0", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "delete from aliases where sticky=0", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "delete from nat where sticky=0", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index alias1 on aliases (alias)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index tasks1 on tasks (hostname,task_id)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete1 on complete (a1,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete2 on complete (a2,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete3 on complete (a3,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete4 on complete (a4,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete5 on complete (a5,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete6 on complete (a6,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete7 on complete (a7,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete8 on complete (a8,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete9 on complete (a9,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete10 on complete (a10,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index channels1 on channels(hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index calls1 on calls(hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index chidx1 on channels (hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex on channels (uuid)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex2 on channels (call_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index callsidx1 on calls (hostname)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index eruuindex on calls (caller_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex on calls (callee_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex2 on calls (call_uuid)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL); skip: - if (sql_manager->manage) { + if (sql_manager.manage) { #ifdef SWITCH_SQL_BIND_EVERY_EVENT switch_event_bind("core_db", SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); #else @@ -2710,16 +2665,16 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_event_bind("core_db", SWITCH_EVENT_NAT, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); #endif - switch_queue_create(&sql_manager->sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager->memory_pool); - switch_queue_create(&sql_manager->sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager->memory_pool); + switch_queue_create(&sql_manager.sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); + switch_queue_create(&sql_manager.sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); - switch_threadattr_create(&thd_attr, sql_manager->memory_pool); + switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_core_sqldb_start_thread(); - switch_thread_create(&sql_manager->db_thread, thd_attr, switch_core_sql_db_thread, sql_manager, sql_manager->memory_pool); + switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); - while (sql_manager->manage && !sql_manager->thread_running && --sanity) { + while (sql_manager.manage && !sql_manager.thread_running && --sanity) { switch_yield(10000); } } @@ -2727,36 +2682,37 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ } -SWITCH_DECLARE(void) switch_sqldb_stop_thread(switch_sql_manager_t *sql_manager) +SWITCH_DECLARE(void) switch_core_sqldb_stop_thread(void) { - switch_mutex_lock(sql_manager->ctl_mutex); - if (sql_manager->thread && sql_manager->thread_running) { + switch_mutex_lock(sql_manager.ctl_mutex); + if (sql_manager.thread && sql_manager.thread_running) { switch_status_t st; - if (sql_manager->manage) { - switch_queue_push(sql_manager->sql_queue[0], NULL); - switch_queue_push(sql_manager->sql_queue[1], NULL); + if (sql_manager.manage) { + switch_queue_push(sql_manager.sql_queue[0], NULL); + switch_queue_push(sql_manager.sql_queue[1], NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n"); wake_thread(0); - sql_manager->thread_running = -1; - switch_thread_join(&st, sql_manager->thread); - sql_manager->thread = NULL; - switch_cache_db_release_db_handle(&sql_manager->dbh); - sql_manager->dbh = NULL; + sql_manager.thread_running = -1; + switch_thread_join(&st, sql_manager.thread); + sql_manager.thread = NULL; + switch_cache_db_release_db_handle(&sql_manager.dbh); + sql_manager.dbh = NULL; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL is not enabled\n"); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is not running\n"); } - switch_mutex_unlock(sql_manager->ctl_mutex); + switch_mutex_unlock(sql_manager.ctl_mutex); } - -void switch_core_recovery_create_indices(void) +SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) { switch_cache_db_handle_t *dbh; + switch_mutex_lock(sql_manager.ctl_mutex); + if (switch_core_recovery_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); @@ -2776,34 +2732,14 @@ void switch_core_recovery_create_indices(void) switch_cache_db_release_db_handle(&dbh); } -} - -SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) -{ - char *post_connect_sql[2]; - post_connect_sql[0] = "delete from channels"; - post_connect_sql[1] = "delete from calls"; - - switch_core_recovery_create_indices(); - switch_sqldb_start_thread(&switch_cache_db_sql_manager, switch_core_sql_thread, post_connect_sql, 2); - -} - -SWITCH_DECLARE(void) switch_sqldb_start_thread(switch_sql_manager_t *sql_manager, void *(SWITCH_THREAD_FUNC * func) (switch_thread_t *, void *), - char *post_connect_sql[], int argc) -{ - int i = 0; - - switch_mutex_lock(sql_manager->ctl_mutex); - - if (sql_manager->manage) { + if (sql_manager.manage) { top: - if (!sql_manager->dbh) { + if (!sql_manager.dbh) { /* Activate SQL database */ - if (switch_core_db_handle(&sql_manager->dbh) != SWITCH_STATUS_SUCCESS) { + if (switch_core_db_handle(&sql_manager.dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { @@ -2817,7 +2753,7 @@ SWITCH_DECLARE(void) switch_sqldb_start_thread(switch_sql_manager_t *sql_manager runtime.odbc_pass = NULL; runtime.odbc_dbtype = DBTYPE_DEFAULT; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n"); - sql_manager->dbh = NULL; + sql_manager.dbh = NULL; goto top; } @@ -2826,21 +2762,18 @@ SWITCH_DECLARE(void) switch_sqldb_start_thread(switch_sql_manager_t *sql_manager goto end; } - if (argc && post_connect_sql) { - for ( i = 0; i < argc; i++) { - switch_cache_db_execute_sql(sql_manager->dbh, post_connect_sql[i], NULL); - } - } + switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "delete from calls", NULL); } - if (!sql_manager->thread) { + if (!sql_manager.thread) { switch_threadattr_t *thd_attr; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting SQL thread.\n"); - switch_threadattr_create(&thd_attr, sql_manager->memory_pool); + switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&sql_manager->thread, thd_attr, func, sql_manager, sql_manager->memory_pool); + switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is already running\n"); } @@ -2850,38 +2783,28 @@ SWITCH_DECLARE(void) switch_sqldb_start_thread(switch_sql_manager_t *sql_manager end: - switch_mutex_unlock(sql_manager->ctl_mutex); + switch_mutex_unlock(sql_manager.ctl_mutex); } -void switch_sqldb_stop(switch_sql_manager_t *sql_manager) +void switch_core_sqldb_stop(void) { switch_status_t st; switch_event_unbind_callback(core_event_handler); - switch_sqldb_stop_thread(sql_manager); + switch_core_sqldb_stop_thread(); - if (sql_manager->db_thread && sql_manager->db_thread_running) { - sql_manager->db_thread_running = -1; - switch_thread_join(&st, sql_manager->db_thread); + if (sql_manager.db_thread && sql_manager.db_thread_running) { + sql_manager.db_thread_running = -1; + switch_thread_join(&st, sql_manager.db_thread); } - switch_cache_db_flush_handles(sql_manager); - sql_close(sql_manager, 0); -} - -void switch_core_sqldb_stop() -{ - switch_sqldb_stop(&switch_cache_db_sql_manager); + switch_cache_db_flush_handles(); + sql_close(0); } SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) -{ - _switch_cache_db_status(&switch_cache_db_sql_manager, stream); -} - -SWITCH_DECLARE(void) _switch_cache_db_status(switch_sql_manager_t *sql_manager, switch_stream_handle_t *stream) { /* return some status info suitable for the cli */ switch_cache_db_handle_t *dbh = NULL; @@ -2892,16 +2815,11 @@ SWITCH_DECLARE(void) _switch_cache_db_status(switch_sql_manager_t *sql_manager, char *pos2 = NULL; int count = 0, used = 0; - switch_mutex_lock(sql_manager->dbh_mutex); + switch_mutex_lock(sql_manager.dbh_mutex); - for (dbh = sql_manager->handle_pool; dbh; dbh = dbh->next) { - char *needles[3]; + for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) { + char *needle = "pass=\""; time_t diff = 0; - int i = 0; - - needles[0] = "pass=\""; - needles[1] = "password="; - needles[2] = "password='"; diff = now - dbh->last_used; @@ -2914,26 +2832,11 @@ SWITCH_DECLARE(void) _switch_cache_db_status(switch_sql_manager_t *sql_manager, /* sanitize password */ memset(cleankey_str, 0, sizeof(cleankey_str)); - for (i = 0; i < 3; i++) { - if((pos1 = strstr(dbh->name, needles[i]))) { - pos1 += strlen(needles[i]); - - if (!(pos2 = strstr(pos1, "\""))) { - if (!(pos2 = strstr(pos1, "'"))) { - if (!(pos2 = strstr(pos1, " "))) { - pos2 = pos1 + strlen(pos1); - } - } - } - strncpy(cleankey_str, dbh->name, pos1 - dbh->name); - strcpy(&cleankey_str[pos1 - dbh->name], pos2); - break; - } - } - if (i == 3) { - strncpy(cleankey_str, dbh->name, strlen(dbh->name)); - } - + pos1 = strstr(dbh->name, needle) + strlen(needle); + pos2 = strstr(pos1, "\""); + strncpy(cleankey_str, dbh->name, pos1 - dbh->name); + strcpy(&cleankey_str[pos1 - dbh->name], pos2); + count++; if (dbh->use_count) { @@ -2951,7 +2854,7 @@ SWITCH_DECLARE(void) _switch_cache_db_status(switch_sql_manager_t *sql_manager, stream->write_function(stream, "%d total. %d in use.\n", count, used); - switch_mutex_unlock(sql_manager->dbh_mutex); + switch_mutex_unlock(sql_manager.dbh_mutex); } SWITCH_DECLARE(char*)switch_sql_concat(void) From bcfc2dbeb159aa1d2443e804e4fc496eac8ab9ba Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 8 Oct 2012 16:28:03 -0500 Subject: [PATCH 137/512] we do want this one bit from the last patch --- src/switch_core_sqldb.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b679baab0c..bb82202fbc 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2818,8 +2818,13 @@ SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) switch_mutex_lock(sql_manager.dbh_mutex); for (dbh = sql_manager.handle_pool; dbh; dbh = dbh->next) { - char *needle = "pass=\""; + char *needles[3]; time_t diff = 0; + int i = 0; + + needles[0] = "pass=\""; + needles[1] = "password="; + needles[2] = "password='"; diff = now - dbh->last_used; @@ -2832,11 +2837,26 @@ SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) /* sanitize password */ memset(cleankey_str, 0, sizeof(cleankey_str)); - pos1 = strstr(dbh->name, needle) + strlen(needle); - pos2 = strstr(pos1, "\""); - strncpy(cleankey_str, dbh->name, pos1 - dbh->name); - strcpy(&cleankey_str[pos1 - dbh->name], pos2); - + for (i = 0; i < 3; i++) { + if((pos1 = strstr(dbh->name, needles[i]))) { + pos1 += strlen(needles[i]); + + if (!(pos2 = strstr(pos1, "\""))) { + if (!(pos2 = strstr(pos1, "'"))) { + if (!(pos2 = strstr(pos1, " "))) { + pos2 = pos1 + strlen(pos1); + } + } + } + strncpy(cleankey_str, dbh->name, pos1 - dbh->name); + strcpy(&cleankey_str[pos1 - dbh->name], pos2); + break; + } + } + if (i == 3) { + strncpy(cleankey_str, dbh->name, strlen(dbh->name)); + } + count++; if (dbh->use_count) { From a20c556fb79f3de2d3c00db89e6c418829f24e36 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 8 Oct 2012 16:34:39 -0500 Subject: [PATCH 138/512] FS-4650 --resolve --- src/mod/applications/mod_commands/mod_commands.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 5923860507..7287d95acc 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -285,7 +285,7 @@ SWITCH_STANDARD_API(list_users_function) int32_t arg = 0; switch_xml_t xml_root, x_domains, x_domain_tag; switch_xml_t gts, gt, uts, ut; - char *_user = NULL, *_domain = NULL, *_group = NULL; + char *_user = NULL, *_domain = NULL, *_search_context = NULL, *_group = NULL; if ((pdata = strdup(cmd))) { @@ -300,10 +300,12 @@ SWITCH_STANDARD_API(list_users_function) if (!strcasecmp(argv[arg], "user")) { _user = argv[arg + 1]; } + if (!strcasecmp(argv[arg], "context")) { + _search_context = argv[arg + 1]; + } if (!strcasecmp(argv[arg], "domain")) { _domain = argv[arg + 1]; } - if (!strcasecmp(argv[arg], "group")) { _group = argv[arg + 1]; } @@ -370,6 +372,7 @@ SWITCH_STANDARD_API(list_users_function) us.x_user_tag = ut; us.x_domain_tag = x_domain_tag; us.stream = stream; + us.search_context = _search_context; dump_user(&us); } } @@ -383,6 +386,7 @@ SWITCH_STANDARD_API(list_users_function) us.x_user_tag = ut; us.x_domain_tag = x_domain_tag; us.stream = stream; + us.search_context = _search_context; dump_user(&us); } } From 7d7eaee942ecf8c3e2dd7dd6eef619d17dc1ba99 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Mon, 8 Oct 2012 22:22:34 +0000 Subject: [PATCH 139/512] Switch to Poll instead of Select. --- src/switch_pgsql.c | 52 ++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 1094aee20b..2b695c3f7d 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -35,6 +35,7 @@ #ifdef SWITCH_HAVE_PGSQL #include +#include struct switch_pgsql_handle { @@ -168,8 +169,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq switch_time_t ctime; unsigned int usec = msec * 1000; char *err_str; - fd_set pgset; - struct timeval timeout; + struct pollfd fds[2] = { {0} }; + int poll_res = 0; if(!handle) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n"); @@ -183,30 +184,37 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq /* Wait for a result to become available, up to msec milliseconds */ start = switch_time_now(); - while((ctime = switch_time_now()) - start <= usec) { - FD_ZERO(&pgset); - FD_SET(handle->sock, &pgset); + while((ctime = switch_micro_time_now()) - start <= usec) { + int wait_time = (usec - (ctime - start)) / 1000; + fds[0].fd = handle->sock; + fds[0].events |= POLLIN; + fds[0].events |= POLLERR; - timeout.tv_sec = 0; - timeout.tv_usec = 500; - /* Wait for the PostgreSQL socket to be ready for data reads. */ - if (select(FD_SETSIZE, &pgset, NULL, NULL, &timeout) > 0) { - /* Then try to consume any input waiting. */ - if (PQconsumeInput(handle->con)) { - /* And check to see if we have a full result ready for reading */ - if (!PQisBusy(handle->con)) { - /* If we can pull a full result without blocking, then break this loop */ - break; + if ((poll_res = poll(&fds[0], 1, wait_time)) > -1 ) { + if (fds[0].revents & POLLIN) { + /* Then try to consume any input waiting. */ + if (PQconsumeInput(handle->con)) { + /* And check to see if we have a full result ready for reading */ + if (!PQisBusy(handle->con)) { + /* If we can pull a full result without blocking, then break this loop */ + break; + } + } else { + /* If we had an error trying to consume input, report it and cancel the query. */ + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); + switch_safe_free(err_str); + switch_pgsql_cancel(handle); + goto error; } - } else { - /* If we had an error trying to consume input, report it and cancel the query. */ - err_str = switch_pgsql_handle_get_error(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); - switch_safe_free(err_str); - switch_pgsql_cancel(handle); + } else if (fds[0].revents & POLLERR) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql); goto error; } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql); + goto error; } } @@ -318,7 +326,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const cha #endif } -#ifdef SWITCH_HAVE_PG +#ifdef SWITCH_HAVE_PGSQL static int db_is_up(switch_pgsql_handle_t *handle) { int ret = 0; From f059d97ff8b6724c7aca655bf4ca1ef6a8c860a9 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Mon, 8 Oct 2012 22:48:26 +0000 Subject: [PATCH 140/512] Terminate buffers! --- src/switch_pgsql.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 2b695c3f7d..fc02ab73d5 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -629,10 +629,12 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_callback_exec_detailed if (tmp) { len = strlen(tmp); names[col] = malloc(len+1); + names[col][len] = '\0'; strncpy(names[col], tmp, len); len = PQgetlength(result->result, row, col); vals[col] = malloc(len+1); + vals[col][len] = '\0'; tmp = PQgetvalue(result->result, row, col); strncpy(vals[col], tmp, len); } else { From a0a584b0c95cbc187747e6f9e27c30cfcb4f3ca5 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Mon, 8 Oct 2012 20:56:54 -0400 Subject: [PATCH 141/512] you cant have -- inside an xml comment... we should really be testing changes like this to the config files before we push this as this wouldnt even make it past a clean install start up or reloadxml test --- conf/vanilla/autoload_configs/switch.conf.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/vanilla/autoload_configs/switch.conf.xml b/conf/vanilla/autoload_configs/switch.conf.xml index 34bdedcda9..fc0ac21b82 100644 --- a/conf/vanilla/autoload_configs/switch.conf.xml +++ b/conf/vanilla/autoload_configs/switch.conf.xml @@ -144,7 +144,6 @@ - + + + + diff --git a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c index 003e57da82..0e8f67a2c3 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c @@ -39,6 +39,8 @@ static struct { char *mongo_host; uint32_t mongo_port; char *mongo_namespace; + char *mongo_username; + char *mongo_password; mongo mongo_conn[1]; switch_mutex_t *mongo_mutex; switch_bool_t log_b; @@ -48,6 +50,8 @@ static switch_xml_config_item_t config_settings[] = { /* key, flags, ptr, default_value, syntax, helptext */ SWITCH_CONFIG_ITEM_STRING_STRDUP("host", CONFIG_REQUIRED, &globals.mongo_host, "127.0.0.1", NULL, "MongoDB server host address"), SWITCH_CONFIG_ITEM_STRING_STRDUP("namespace", CONFIG_REQUIRED, &globals.mongo_namespace, NULL, "database.collection", "MongoDB namespace"), + SWITCH_CONFIG_ITEM_STRING_STRDUP("username", CONFIG_RELOADABLE, &globals.mongo_username, NULL, NULL, "MongoDB username"), + SWITCH_CONFIG_ITEM_STRING_STRDUP("password", CONFIG_RELOADABLE, &globals.mongo_password, NULL, NULL, "MongoDB password"), /* key, type, flags, ptr, default_value, data, syntax, helptext */ SWITCH_CONFIG_ITEM("port", SWITCH_CONFIG_INT, CONFIG_REQUIRED, &globals.mongo_port, 27017, NULL, NULL, "MongoDB server TCP port"), @@ -79,6 +83,29 @@ static void set_bson_profile_data(bson *b, switch_caller_profile_t *caller_profi } +static switch_status_t cdr_mongo_authenticate() { + switch_status_t status = SWITCH_STATUS_SUCCESS; + mongo_error_t db_status; + char *ns_tmp, *ns_split[2]; + + /* Split namespace db.collection into separate vars */ + switch_strdup(ns_tmp, globals.mongo_namespace); + switch_separate_string(ns_tmp, '.', ns_split, 2); + + db_status = mongo_cmd_authenticate(globals.mongo_conn, ns_split[0], globals.mongo_username, globals.mongo_password); + + if (db_status != MONGO_OK) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_cmd_authenticate: authentication failed\n"); + status = SWITCH_STATUS_FALSE; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Successfully authenticated %s@%s\n", globals.mongo_username, ns_split[0]); + } + + switch_safe_free(ns_tmp); + return status; +} + + static switch_status_t my_on_reporting(switch_core_session_t *session) { switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -306,14 +333,22 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) status = SWITCH_STATUS_FALSE; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "MongoDB connection re-established.\n"); - if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr, NULL) != MONGO_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: error code %d\n", globals.mongo_conn->err); - status = SWITCH_STATUS_FALSE; + + /* Re-authentication is necessary after a reconnect */ + if (globals.mongo_username && globals.mongo_password) { + status = cdr_mongo_authenticate(); + } + + if (db_status == MONGO_OK) { + if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr, NULL) != MONGO_OK) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: %s (error code %d)\n", globals.mongo_conn->errstr, globals.mongo_conn->err); + status = SWITCH_STATUS_FALSE; + } } } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: error code %d\n", globals.mongo_conn->err); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: %s (error code %d)\n", globals.mongo_conn->errstr, globals.mongo_conn->err); status = SWITCH_STATUS_FALSE; } } @@ -385,6 +420,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_mongodb_load) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to MongoDB server %s:%d\n", globals.mongo_host, globals.mongo_port); } + if (globals.mongo_username && globals.mongo_password) { + status = cdr_mongo_authenticate(); + } + switch_mutex_init(&globals.mongo_mutex, SWITCH_MUTEX_NESTED, pool); switch_core_add_state_handler(&state_handlers); From 2b6e3425348809f3053687eca3c7078c7c584b7e Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Sun, 21 Oct 2012 16:21:01 +0200 Subject: [PATCH 221/512] mod_cdr_mongodb: tweak auth handling --- .../event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c index 0e8f67a2c3..5187cfb23c 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c @@ -339,11 +339,9 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) status = cdr_mongo_authenticate(); } - if (db_status == MONGO_OK) { - if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr, NULL) != MONGO_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: %s (error code %d)\n", globals.mongo_conn->errstr, globals.mongo_conn->err); - status = SWITCH_STATUS_FALSE; - } + if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr, NULL) != MONGO_OK) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: %s (error code %d)\n", globals.mongo_conn->errstr, globals.mongo_conn->err); + status = SWITCH_STATUS_FALSE; } } @@ -421,7 +419,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_mongodb_load) } if (globals.mongo_username && globals.mongo_password) { - status = cdr_mongo_authenticate(); + if (cdr_mongo_authenticate() != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } } switch_mutex_init(&globals.mongo_mutex, SWITCH_MUTEX_NESTED, pool); From b53e4ed80003ee266cccbc9f69c7dbdeb4aaa316 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Sun, 21 Oct 2012 17:52:45 +0200 Subject: [PATCH 222/512] mod_cdr_mongodb: add support for replica sets (refs FS-4668) --- .../autoload_configs/cdr_mongodb.conf.xml | 3 +- .../mod_cdr_mongodb/mod_cdr_mongodb.c | 51 +++++++++++++++++-- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml b/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml index 92751004ff..6750c46863 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml +++ b/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml @@ -1,6 +1,7 @@ - + diff --git a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c index 5187cfb23c..d4c4d7cf9a 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c @@ -33,12 +33,15 @@ #include #include +#define MONGO_REPLSET_MAX_MEMBERS 12 + static struct { switch_memory_pool_t *pool; int shutdown; char *mongo_host; - uint32_t mongo_port; + int mongo_port; char *mongo_namespace; + char *mongo_replset_name; char *mongo_username; char *mongo_password; mongo mongo_conn[1]; @@ -50,11 +53,12 @@ static switch_xml_config_item_t config_settings[] = { /* key, flags, ptr, default_value, syntax, helptext */ SWITCH_CONFIG_ITEM_STRING_STRDUP("host", CONFIG_REQUIRED, &globals.mongo_host, "127.0.0.1", NULL, "MongoDB server host address"), SWITCH_CONFIG_ITEM_STRING_STRDUP("namespace", CONFIG_REQUIRED, &globals.mongo_namespace, NULL, "database.collection", "MongoDB namespace"), + SWITCH_CONFIG_ITEM_STRING_STRDUP("replica_set_name", CONFIG_RELOADABLE, &globals.mongo_replset_name, "cdr_mongodb", NULL, "MongoDB replica set name"), SWITCH_CONFIG_ITEM_STRING_STRDUP("username", CONFIG_RELOADABLE, &globals.mongo_username, NULL, NULL, "MongoDB username"), SWITCH_CONFIG_ITEM_STRING_STRDUP("password", CONFIG_RELOADABLE, &globals.mongo_password, NULL, NULL, "MongoDB password"), /* key, type, flags, ptr, default_value, data, syntax, helptext */ - SWITCH_CONFIG_ITEM("port", SWITCH_CONFIG_INT, CONFIG_REQUIRED, &globals.mongo_port, 27017, NULL, NULL, "MongoDB server TCP port"), + SWITCH_CONFIG_ITEM("port", SWITCH_CONFIG_INT, CONFIG_REQUIRED, &globals.mongo_port, MONGO_DEFAULT_PORT, NULL, NULL, "MongoDB server TCP port"), SWITCH_CONFIG_ITEM("log-b-leg", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.log_b, SWITCH_TRUE, NULL, NULL, "Log B-leg in addition to A-leg"), SWITCH_CONFIG_ITEM_END() @@ -389,6 +393,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_mongodb_load) { switch_status_t status = SWITCH_STATUS_SUCCESS; mongo_error_t db_status; + char *repl_hosts[MONGO_REPLSET_MAX_MEMBERS]; + char *mongo_host[2]; + int num_hosts, mongo_port; memset(&globals, 0, sizeof(globals)); globals.pool = pool; @@ -397,7 +404,32 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_mongodb_load) return SWITCH_STATUS_FALSE; } - db_status = mongo_connect(globals.mongo_conn, globals.mongo_host, globals.mongo_port); + num_hosts = switch_separate_string(globals.mongo_host, ',', repl_hosts, MONGO_REPLSET_MAX_MEMBERS); + + if (num_hosts > 1) { + int i; + + mongo_replset_init(globals.mongo_conn, globals.mongo_replset_name); + + for (i = 0; i < num_hosts; i++) { + switch_separate_string(repl_hosts[i], ':', mongo_host, 2); + mongo_port = mongo_host[1] ? atoi(mongo_host[1]) : globals.mongo_port; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding MongoDB server %s:%d to replica set\n", mongo_host[0], mongo_port); + mongo_replset_add_seed(globals.mongo_conn, mongo_host[0], mongo_port); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connecting to MongoDB replica set %s\n", globals.mongo_replset_name); + db_status = mongo_replset_connect(globals.mongo_conn); + } else { + switch_separate_string(globals.mongo_host, ':', mongo_host, 2); + + if (mongo_host[1]) { + globals.mongo_port = atoi(mongo_host[1]); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connecting to MongoDB server %s:%d\n", globals.mongo_host, globals.mongo_port); + db_status = mongo_connect(globals.mongo_conn, globals.mongo_host, globals.mongo_port); + } if (db_status != MONGO_OK) { switch (globals.mongo_conn->err) { @@ -407,15 +439,24 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_mongodb_load) case MONGO_CONN_FAIL: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_connect: connection failed\n"); break; + case MONGO_CONN_ADDR_FAIL: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_connect: hostname lookup failed\n"); + break; case MONGO_CONN_NOT_MASTER: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_connect: not master\n"); break; + case MONGO_CONN_BAD_SET_NAME: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_replset_connect: configured replica set name does not match\n"); + break; + case MONGO_CONN_NO_PRIMARY: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_replset_connect: cannot find replica set primary member\n"); + break; default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_connect: unknown error %d\n", db_status); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_connect: unknown error: status code %d, error code %d\n", db_status, globals.mongo_conn->err); } return SWITCH_STATUS_FALSE; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to MongoDB server %s:%d\n", globals.mongo_host, globals.mongo_port); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connection established\n"); } if (globals.mongo_username && globals.mongo_password) { From a92fb019c54e6e70e9b4402d03062316a7ee90d5 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Sun, 21 Oct 2012 17:55:13 +0200 Subject: [PATCH 223/512] Add missing config param to sample config --- .../mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml b/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml index 6750c46863..86e43d2098 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml +++ b/src/mod/event_handlers/mod_cdr_mongodb/conf/autoload_configs/cdr_mongodb.conf.xml @@ -5,6 +5,9 @@ + + + From 58f1ee7ff0057675bbf14d10c0b9c69e706601c1 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Sun, 21 Oct 2012 22:59:51 +0200 Subject: [PATCH 224/512] mod_cdr_mongodb: add post-v0.6 patch to driver to support Unix domain sockets --- .../mod_cdr_mongodb/driver/src/env_posix.c | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c index f1020ca80d..ab0e166cf9 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -99,6 +100,36 @@ int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) { return MONGO_OK; } +int mongo_env_unix_socket_connect( mongo *conn, const char *sock_path ) { + struct sockaddr_un addr; + int status, len; + + conn->connected = 0; + + conn->sock = socket( AF_UNIX, SOCK_STREAM, 0 ); + + if ( conn->sock < 0 ) { + conn->sock = 0; + return MONGO_ERROR; + } + + addr.sun_family = AF_UNIX; + strncpy( addr.sun_path, sock_path, sizeof(addr.sun_path) - 1 ); + len = sizeof( addr ); + + status = connect( conn->sock, (struct sockaddr *) &addr, len ); + if( status < 0 ){ + mongo_env_close_socket( conn->sock ); + conn->sock = 0; + conn->err = MONGO_CONN_FAIL; + return MONGO_ERROR; + } + + conn->connected = 1; + + return MONGO_OK; +} + int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { char port_str[NI_MAXSERV]; int status; @@ -107,6 +138,10 @@ int mongo_env_socket_connect( mongo *conn, const char *host, int port ) { struct addrinfo *ai_list = NULL; struct addrinfo *ai_ptr = NULL; + if ( port < 0 ) { + return mongo_env_unix_socket_connect( conn, host ); + } + conn->sock = 0; conn->connected = 0; sprintf(port_str,"%d",port); From 970b2f176588a27676e4ada15c39d665dbc14fd5 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sun, 21 Oct 2012 22:43:21 -0500 Subject: [PATCH 225/512] FS-4722 german say date day month year --- src/mod/say/mod_say_de/mod_say_de.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/say/mod_say_de/mod_say_de.c b/src/mod/say/mod_say_de/mod_say_de.c index b4ae2d83b4..1c1871732c 100644 --- a/src/mod/say/mod_say_de/mod_say_de.c +++ b/src/mod/say/mod_say_de/mod_say_de.c @@ -310,8 +310,8 @@ static switch_status_t de_say_time(switch_core_session_t *session, char *tosay, if (say_date) { say_file("time/day-%d.wav", tm.tm_wday); + say_num(tm.tm_mday, SSM_COUNTED); say_file("time/mon-%d.wav", tm.tm_mon); - say_num(tm.tm_mday, SSM_COUNTED); say_num(tm.tm_year + 1900, SSM_PRONOUNCED); } From 09c03667a8f3ff917ad0bc283fd79131a3b038ac Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sun, 21 Oct 2012 22:53:02 -0500 Subject: [PATCH 226/512] FS-4721 --resolve --- src/mod/say/mod_say_de/mod_say_de.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/mod/say/mod_say_de/mod_say_de.c b/src/mod/say/mod_say_de/mod_say_de.c index 1c1871732c..b38f02a798 100644 --- a/src/mod/say/mod_say_de/mod_say_de.c +++ b/src/mod/say/mod_say_de/mod_say_de.c @@ -97,12 +97,14 @@ static switch_status_t play_group(switch_say_method_t method, switch_say_gender_ if (b) { if (b > 1) { /*german nominativ for "one" in numbers like 21, 171, 4591 is flexed, 2-9 are not*/ - if ( c == 1 ) { - say_file("digits/s-1.wav"); - } else { - say_file("digits/%d.wav", c); - } - say_file("currency/and.wav"); + if (c > 0) { + if ( c == 1 ) { + say_file("digits/s-1.wav"); + } else { + say_file("digits/%d.wav", c); + } + say_file("currency/and.wav"); + } if (method == SSM_COUNTED) { say_file("digits/h-%d0.wav", b); } else { From a8ee444ab984eedee653ae162a9f05c96aa570e2 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 22 Oct 2012 09:24:45 -0500 Subject: [PATCH 227/512] FS-4748 --resolve --- src/switch_channel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 6e4c607822..fd00c5f71e 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -268,7 +268,7 @@ SWITCH_DECLARE(const char *) switch_channel_callstate2str(switch_channel_callsta } -SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2callstate(const char *str) +SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_str2callstate(const char *str) { uint8_t x; switch_channel_callstate_t callstate = (switch_channel_callstate_t) SWITCH_CAUSE_NONE; @@ -283,7 +283,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2callstate(const char *str } } } - return (switch_call_cause_t) callstate; + return callstate; } From 17d1ffe45c8b42e19a7c3815b63ab9879cded5f2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 22 Oct 2012 11:56:22 -0400 Subject: [PATCH 228/512] FS-4748 the change to the header file did not make it into the commit --- src/include/switch_channel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index f4655a23e6..bddfb0f2d2 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -631,7 +631,7 @@ SWITCH_DECLARE(void) switch_channel_perform_set_callstate(switch_channel_t *chan #define switch_channel_set_callstate(channel, state) switch_channel_perform_set_callstate(channel, state, __FILE__, __SWITCH_FUNC__, __LINE__) SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_get_callstate(switch_channel_t *channel); SWITCH_DECLARE(const char *) switch_channel_callstate2str(switch_channel_callstate_t callstate); -SWITCH_DECLARE(switch_call_cause_t) switch_channel_str2callstate(const char *str); +SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_str2callstate(const char *str); SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_bool_t on); /** @} */ From 4b6db1329c9983589e6f4f1036526a2d49e57f63 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 22 Oct 2012 13:37:41 -0400 Subject: [PATCH 229/512] FS-4729 try this patch clean --- src/include/switch_types.h | 1 + src/switch_ivr.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index c4c2ed7190..b766d1db40 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1249,6 +1249,7 @@ typedef enum { CF_TRACKABLE, CF_NO_CDR, CF_EARLY_OK, + CF_MEDIA_TRANS, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */ CF_FLAG_MAX diff --git a/src/switch_ivr.c b/src/switch_ivr.c index b6c1127b31..b8fd0923e3 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1476,6 +1476,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ if ((session = switch_core_session_locate(uuid))) { channel = switch_core_session_get_channel(session); + + if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { + switch_core_session_rwunlock(session); + return SWITCH_STATUS_INUSE; + } + + switch_channel_set_flag(channel, CF_MEDIA_TRANS); if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { swap = 1; @@ -1527,6 +1534,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_ } } + switch_channel_clear_flag(channel, CF_MEDIA_TRANS); switch_core_session_rwunlock(session); if (other_channel) { @@ -1559,6 +1567,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_nomedia(const char *uuid, switch_medi status = SWITCH_STATUS_SUCCESS; channel = switch_core_session_get_channel(session); + if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { + switch_core_session_rwunlock(session); + return SWITCH_STATUS_INUSE; + } + + switch_channel_set_flag(channel, CF_MEDIA_TRANS); + if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { swap = 1; } @@ -1617,9 +1632,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_nomedia(const char *uuid, switch_medi switch_core_session_rwunlock(other_session); } } - switch_core_session_rwunlock(session); + + switch_channel_clear_flag(channel, CF_MEDIA_TRANS); } + + return status; } From 5ff654dab51014a37f7043206ea2fbe685e201f1 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Tue, 23 Oct 2012 10:44:31 +0800 Subject: [PATCH 230/512] fix NIL case --- src/mod/event_handlers/mod_erlang_event/ei_helpers.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c index 0206f37718..9d39b725d7 100644 --- a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c +++ b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c @@ -305,6 +305,11 @@ int ei_decode_string_or_binary(char *buf, int *index, int maxlen, char *dst) ei_get_type(buf, index, &type, &size); + if (type == ERL_NIL_EXT || size == 0) { + dst[0] = '\0'; + return 0; + } + if (type != ERL_STRING_EXT && type != ERL_BINARY_EXT) { return -1; } else if (size > maxlen) { From 8589e031d0ff9792275c70016d881caa9e625a9b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 22 Oct 2012 22:01:22 -0500 Subject: [PATCH 231/512] vs2010 reswig --- .../mod_managed/freeswitch_wrap.2010.cxx | 472 ++++++++++++++++- .../mod_managed/managed/swig.2010.cs | 484 +++++++++++++++++- 2 files changed, 944 insertions(+), 12 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 51e4d83cf7..40aab99e82 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -7867,6 +7867,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_get_loglevel(void * jarg1) } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_jb(void * jarg1, int jarg2) { + void * jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_media_type_t arg2 ; + stfu_instance_t *result = 0 ; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (switch_media_type_t)jarg2; + result = (stfu_instance_t *)switch_core_session_get_jb(arg1,arg2); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_soft_lock(void * jarg1, unsigned long jarg2) { switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -8105,6 +8119,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall_matching_var(char } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_findall_matching_var(char * jarg1, char * jarg2) { + void * jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_console_callback_match_t *result = 0 ; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + result = (switch_console_callback_match_t *)switch_core_session_findall_matching_var((char const *)arg1,(char const *)arg2); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall_endpoint(void * jarg1, int jarg2) { switch_endpoint_interface_t *arg1 = (switch_endpoint_interface_t *) 0 ; switch_call_cause_t arg2 ; @@ -11388,6 +11416,26 @@ SWIGEXPORT int SWIGSTDCALL CSharp__switch_cache_db_get_db_handle(void * jarg1, i } +SWIGEXPORT int SWIGSTDCALL CSharp__switch_cache_db_get_db_handle_dsn(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) { + int jresult ; + switch_cache_db_handle_t **arg1 = (switch_cache_db_handle_t **) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + int arg5 ; + switch_status_t result; + + arg1 = (switch_cache_db_handle_t **)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (int)jarg5; + result = (switch_status_t)_switch_cache_db_get_db_handle_dsn(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5); + jresult = result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_cache_db_execute_sql2str(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, void * jarg5) { char * jresult ; switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; @@ -11516,17 +11564,25 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute(void * jarg } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute_trans(void * jarg1, char * jarg2, unsigned long jarg3) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute_trans_full(void * jarg1, char * jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7) { int jresult ; switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; char *arg2 = (char *) 0 ; uint32_t arg3 ; + char *arg4 = (char *) 0 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + char *arg7 = (char *) 0 ; switch_status_t result; arg1 = (switch_cache_db_handle_t *)jarg1; arg2 = (char *)jarg2; arg3 = (uint32_t)jarg3; - result = (switch_status_t)switch_cache_db_persistant_execute_trans(arg1,arg2,arg3); + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + result = (switch_status_t)switch_cache_db_persistant_execute_trans_full(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7); jresult = result; return jresult; } @@ -11768,6 +11824,24 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_get_stacksizes(void * jarg1, void } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_dbtype() { + int jresult ; + switch_cache_db_handle_type_t result; + + result = (switch_cache_db_handle_type_t)switch_core_dbtype(); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sql_exec(char * jarg1) { + char *arg1 = (char *) 0 ; + + arg1 = (char *)jarg1; + switch_core_sql_exec((char const *)arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_recovery_recover(char * jarg1, char * jarg2) { int jresult ; char *arg1 = (char *) 0 ; @@ -11810,6 +11884,104 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_recovery_flush(char * jarg1, char } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_push(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + char *arg2 = (char *) 0 ; + uint32_t arg3 ; + switch_bool_t arg4 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (uint32_t)jarg3; + arg4 = (switch_bool_t)jarg4; + result = (switch_status_t)switch_switch_sql_queue_manager_push(arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_destroy(void * jarg1) { + int jresult ; + switch_sql_queue_manager_t **arg1 = (switch_sql_queue_manager_t **) 0 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t **)jarg1; + result = (switch_status_t)switch_switch_sql_queue_manager_destroy(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_init(void * jarg1, unsigned long jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7) { + int jresult ; + switch_sql_queue_manager_t **arg1 = (switch_sql_queue_manager_t **) 0 ; + uint32_t arg2 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + char *arg7 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t **)jarg1; + arg2 = (uint32_t)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + result = (switch_status_t)switch_switch_sql_queue_manager_init(arg1,arg2,(char const *)arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_start(void * jarg1) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + result = (switch_status_t)switch_switch_sql_queue_manager_start(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_stop(void * jarg1) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + result = (switch_status_t)switch_switch_sql_queue_manager_stop(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_execute_sql_event_callback(void * jarg1, char * jarg2, void * jarg3, void * jarg4, void * jarg5) { + int jresult ; + switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_db_event_callback_func_t arg3 = (switch_db_event_callback_func_t) 0 ; + void *arg4 = (void *) 0 ; + char **arg5 = (char **) 0 ; + switch_status_t result; + + arg1 = (switch_cache_db_handle_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_db_event_callback_func_t)jarg3; + arg4 = (void *)jarg4; + arg5 = (char **)jarg5; + result = (switch_status_t)switch_cache_db_execute_sql_event_callback(arg1,(char const *)arg2,arg3,arg4,arg5); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_switch_fork() { void * jresult ; pid_t result; @@ -15441,6 +15613,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_times_get(void * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_old_times_set(void * jarg1, void * jarg2) { + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_channel_timetable *arg2 = (switch_channel_timetable *) 0 ; + + arg1 = (switch_caller_profile *)jarg1; + arg2 = (switch_channel_timetable *)jarg2; + if (arg1) (arg1)->old_times = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_old_times_get(void * jarg1) { + void * jresult ; + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_channel_timetable *result = 0 ; + + arg1 = (switch_caller_profile *)jarg1; + result = (switch_channel_timetable *) ((arg1)->old_times); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_caller_extension_set(void * jarg1, void * jarg2) { switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; switch_caller_extension *arg2 = (switch_caller_extension *) 0 ; @@ -16483,6 +16677,28 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_frame_flags_get(void * jarg1) } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_frame_user_data_set(void * jarg1, void * jarg2) { + switch_frame *arg1 = (switch_frame *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_frame *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->user_data = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_frame_user_data_get(void * jarg1) { + void * jresult ; + switch_frame *arg1 = (switch_frame *) 0 ; + void *result = 0 ; + + arg1 = (switch_frame *)jarg1; + result = (void *) ((arg1)->user_data); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_frame() { void * jresult ; switch_frame *result = 0 ; @@ -17313,6 +17529,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_io_routines_state_run_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_io_routines_get_jb_set(void * jarg1, void * jarg2) { + switch_io_routines *arg1 = (switch_io_routines *) 0 ; + switch_io_get_jb_t arg2 = (switch_io_get_jb_t) 0 ; + + arg1 = (switch_io_routines *)jarg1; + arg2 = (switch_io_get_jb_t)jarg2; + if (arg1) (arg1)->get_jb = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_io_routines_get_jb_get(void * jarg1) { + void * jresult ; + switch_io_routines *arg1 = (switch_io_routines *) 0 ; + switch_io_get_jb_t result; + + arg1 = (switch_io_routines *)jarg1; + result = (switch_io_get_jb_t) ((arg1)->get_jb); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_io_routines_padding_set(void * jarg1, void * jarg2) { switch_io_routines *arg1 = (switch_io_routines *) 0 ; void **arg2 ; @@ -20387,6 +20625,144 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_memory_pool_get(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_buffer_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_buffer_t *arg2 = (switch_buffer_t *) 0 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (switch_buffer_t *)jarg2; + if (arg1) (arg1)->buffer = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_buffer_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_buffer_t *result = 0 ; + + arg1 = (switch_asr_handle *)jarg1; + result = (switch_buffer_t *) ((arg1)->buffer); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_dbuf_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_byte_t *arg2 = (switch_byte_t *) 0 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (switch_byte_t *)jarg2; + if (arg1) (arg1)->dbuf = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_dbuf_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_byte_t *result = 0 ; + + arg1 = (switch_asr_handle *)jarg1; + result = (switch_byte_t *) ((arg1)->dbuf); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_dbuflen_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_size_t arg2 ; + switch_size_t *argp2 ; + + arg1 = (switch_asr_handle *)jarg1; + argp2 = (switch_size_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->dbuflen = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_dbuflen_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_size_t result; + + arg1 = (switch_asr_handle *)jarg1; + result = ((arg1)->dbuflen); + jresult = new switch_size_t((const switch_size_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_resampler_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_audio_resampler_t *arg2 = (switch_audio_resampler_t *) 0 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (switch_audio_resampler_t *)jarg2; + if (arg1) (arg1)->resampler = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_resampler_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_audio_resampler_t *result = 0 ; + + arg1 = (switch_asr_handle *)jarg1; + result = (switch_audio_resampler_t *) ((arg1)->resampler); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_samplerate_set(void * jarg1, unsigned long jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->samplerate = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_asr_handle_samplerate_get(void * jarg1) { + unsigned long jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t result; + + arg1 = (switch_asr_handle *)jarg1; + result = (uint32_t) ((arg1)->samplerate); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_native_rate_set(void * jarg1, unsigned long jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->native_rate = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_asr_handle_native_rate_get(void * jarg1) { + unsigned long jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t result; + + arg1 = (switch_asr_handle *)jarg1; + result = (uint32_t) ((arg1)->native_rate); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_private_info_set(void * jarg1, void * jarg2) { switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; void *arg2 = (void *) 0 ; @@ -22792,6 +23168,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_next_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_session_set(void * jarg1, void * jarg2) { + switch_codec *arg1 = (switch_codec *) 0 ; + switch_core_session_t *arg2 = (switch_core_session_t *) 0 ; + + arg1 = (switch_codec *)jarg1; + arg2 = (switch_core_session_t *)jarg2; + if (arg1) (arg1)->session = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_session_get(void * jarg1) { + void * jresult ; + switch_codec *arg1 = (switch_codec *) 0 ; + switch_core_session_t *result = 0 ; + + arg1 = (switch_codec *)jarg1; + result = (switch_core_session_t *) ((arg1)->session); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec() { void * jresult ; switch_codec *result = 0 ; @@ -26349,10 +26747,10 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_callstate2str(int jarg1) { SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_str2callstate(char * jarg1) { int jresult ; char *arg1 = (char *) 0 ; - switch_call_cause_t result; + switch_channel_callstate_t result; arg1 = (char *)jarg1; - result = (switch_call_cause_t)switch_channel_str2callstate((char const *)arg1); + result = (switch_channel_callstate_t)switch_channel_str2callstate((char const *)arg1); jresult = result; return jresult; } @@ -27978,6 +28376,24 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_array_pair(void * jarg1, void * jarg2, void * jarg3, int jarg4) { + int jresult ; + switch_event_t **arg1 = (switch_event_t **) 0 ; + char **arg2 = (char **) 0 ; + char **arg3 = (char **) 0 ; + int arg4 ; + switch_status_t result; + + arg1 = (switch_event_t **)jarg1; + arg2 = (char **)jarg2; + arg3 = (char **)jarg3; + arg4 = (int)jarg4; + result = (switch_status_t)switch_event_create_array_pair(arg1,arg2,arg3,arg4); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_running() { int jresult ; switch_status_t result; @@ -31835,6 +32251,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_pause_jitter_buffer(void * jarg1, i } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_jitter_buffer(void * jarg1) { + void * jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + stfu_instance_t *result = 0 ; + + arg1 = (switch_rtp_t *)jarg1; + result = (stfu_instance_t *)switch_rtp_get_jitter_buffer(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_flag(void * jarg1, unsigned long jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_rtp_flag_t arg2 ; @@ -32521,6 +32949,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_log_node_t_channel_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_log_node_t_slevel_set(void * jarg1, int jarg2) { + switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; + switch_log_level_t arg2 ; + + arg1 = (switch_log_node_t *)jarg1; + arg2 = (switch_log_level_t)jarg2; + if (arg1) (arg1)->slevel = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_log_node_t_slevel_get(void * jarg1) { + int jresult ; + switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; + switch_log_level_t result; + + arg1 = (switch_log_node_t *)jarg1; + result = (switch_log_level_t) ((arg1)->slevel); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_log_node_t() { void * jresult ; switch_log_node_t *result = 0 ; @@ -33189,6 +33639,20 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_xml_toxml_nolock(void * jarg1, int j } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_xml_tohtml(void * jarg1, int jarg2) { + char * jresult ; + switch_xml_t arg1 = (switch_xml_t) 0 ; + switch_bool_t arg2 ; + char *result = 0 ; + + arg1 = (switch_xml_t)jarg1; + arg2 = (switch_bool_t)jarg2; + result = (char *)switch_xml_tohtml(arg1,arg2); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_xml_toxml_buf(void * jarg1, char * jarg2, void * jarg3, void * jarg4, int jarg5) { char * jresult ; switch_xml_t arg1 = (switch_xml_t) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index ae944a2be5..031eda1f37 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -1504,6 +1504,12 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_stfu_instance_t switch_core_session_get_jb(SWIGTYPE_p_switch_core_session session, switch_media_type_t type) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_jb(SWIGTYPE_p_switch_core_session.getCPtr(session), (int)type); + SWIGTYPE_p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_stfu_instance_t(cPtr, false); + return ret; + } + public static void switch_core_session_soft_lock(SWIGTYPE_p_switch_core_session session, uint sec) { freeswitchPINVOKE.switch_core_session_soft_lock(SWIGTYPE_p_switch_core_session.getCPtr(session), sec); } @@ -1599,6 +1605,12 @@ public class freeswitch { freeswitchPINVOKE.switch_core_session_hupall_matching_var(var_name, var_val, (int)cause); } + public static switch_console_callback_match switch_core_session_findall_matching_var(string var_name, string var_val) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_findall_matching_var(var_name, var_val); + switch_console_callback_match ret = (cPtr == IntPtr.Zero) ? null : new switch_console_callback_match(cPtr, false); + return ret; + } + public static void switch_core_session_hupall_endpoint(switch_endpoint_interface endpoint_interface, switch_call_cause_t cause) { freeswitchPINVOKE.switch_core_session_hupall_endpoint(switch_endpoint_interface.getCPtr(endpoint_interface), (int)cause); } @@ -2656,6 +2668,11 @@ public class freeswitch { return ret; } + public static switch_status_t _switch_cache_db_get_db_handle_dsn(SWIGTYPE_p_p_switch_cache_db_handle dbh, string dsn, string file, string func, int line) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE._switch_cache_db_get_db_handle_dsn(SWIGTYPE_p_p_switch_cache_db_handle.getCPtr(dbh), dsn, file, func, line); + return ret; + } + public static string switch_cache_db_execute_sql2str(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, string str, uint len, ref string err) { string ret = freeswitchPINVOKE.switch_cache_db_execute_sql2str(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, str, len, ref err); return ret; @@ -2695,8 +2712,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_cache_db_persistant_execute_trans(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, uint retries) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_cache_db_persistant_execute_trans(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, retries); + public static switch_status_t switch_cache_db_persistant_execute_trans_full(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, uint retries, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_cache_db_persistant_execute_trans_full(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, retries, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); return ret; } @@ -2794,6 +2811,15 @@ public class freeswitch { return ret; } + public static switch_cache_db_handle_type_t switch_core_dbtype() { + switch_cache_db_handle_type_t ret = (switch_cache_db_handle_type_t)freeswitchPINVOKE.switch_core_dbtype(); + return ret; + } + + public static void switch_core_sql_exec(string sql) { + freeswitchPINVOKE.switch_core_sql_exec(sql); + } + public static int switch_core_recovery_recover(string technology, string profile_name) { int ret = freeswitchPINVOKE.switch_core_recovery_recover(technology, profile_name); return ret; @@ -2811,6 +2837,36 @@ public class freeswitch { freeswitchPINVOKE.switch_core_recovery_flush(technology, profile_name); } + public static switch_status_t switch_switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); + return ret; + } + + public static switch_status_t switch_switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager qmp) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp)); + return ret; + } + + public static switch_status_t switch_switch_sql_queue_manager_init(SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_init(SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); + return ret; + } + + public static switch_status_t switch_switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager qm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); + return ret; + } + + public static switch_status_t switch_switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager qm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); + return ret; + } + + public static switch_status_t switch_cache_db_execute_sql_event_callback(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, SWIGTYPE_p_f_p_void_p_switch_event__int callback, SWIGTYPE_p_void pdata, ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_cache_db_execute_sql_event_callback(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, SWIGTYPE_p_f_p_void_p_switch_event__int.getCPtr(callback), SWIGTYPE_p_void.getCPtr(pdata), ref err); + return ret; + } + public static SWIGTYPE_p_pid_t switch_fork() { SWIGTYPE_p_pid_t ret = new SWIGTYPE_p_pid_t(freeswitchPINVOKE.switch_fork(), true); return ret; @@ -4189,8 +4245,8 @@ public class freeswitch { return ret; } - public static switch_call_cause_t switch_channel_str2callstate(string str) { - switch_call_cause_t ret = (switch_call_cause_t)freeswitchPINVOKE.switch_channel_str2callstate(str); + public static switch_channel_callstate_t switch_channel_str2callstate(string str) { + switch_channel_callstate_t ret = (switch_channel_callstate_t)freeswitchPINVOKE.switch_channel_str2callstate(str); return ret; } @@ -4491,6 +4547,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_event_create_array_pair(SWIGTYPE_p_p_switch_event arg0, ref string names, ref string vals, int len) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_array_pair(SWIGTYPE_p_p_switch_event.getCPtr(arg0), ref names, ref vals, len); + return ret; + } + public static switch_status_t switch_event_running() { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_running(); return ret; @@ -5438,6 +5499,12 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_stfu_instance_t switch_rtp_get_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) { + IntPtr cPtr = freeswitchPINVOKE.switch_rtp_get_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); + SWIGTYPE_p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_stfu_instance_t(cPtr, false); + return ret; + } + public static void switch_rtp_set_flag(SWIGTYPE_p_switch_rtp rtp_session, uint flags) { freeswitchPINVOKE.switch_rtp_set_flag(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), flags); } @@ -5724,6 +5791,11 @@ public class freeswitch { return ret; } + public static string switch_xml_tohtml(switch_xml xml, switch_bool_t prn_header) { + string ret = freeswitchPINVOKE.switch_xml_tohtml(switch_xml.getCPtr(xml), (int)prn_header); + return ret; + } + public static string switch_xml_toxml_buf(switch_xml xml, string buf, SWIGTYPE_p_switch_size_t buflen, SWIGTYPE_p_switch_size_t offset, switch_bool_t prn_header) { string ret = freeswitchPINVOKE.switch_xml_toxml_buf(switch_xml.getCPtr(xml), buf, SWIGTYPE_p_switch_size_t.getCPtr(buflen), SWIGTYPE_p_switch_size_t.getCPtr(offset), (int)prn_header); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -8497,6 +8569,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_loglevel")] public static extern int switch_core_session_get_loglevel(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_jb")] + public static extern IntPtr switch_core_session_get_jb(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_soft_lock")] public static extern void switch_core_session_soft_lock(HandleRef jarg1, uint jarg2); @@ -8557,6 +8632,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_matching_var")] public static extern void switch_core_session_hupall_matching_var(string jarg1, string jarg2, int jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_findall_matching_var")] + public static extern IntPtr switch_core_session_findall_matching_var(string jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_endpoint")] public static extern void switch_core_session_hupall_endpoint(HandleRef jarg1, int jarg2); @@ -9301,6 +9379,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp__switch_cache_db_get_db_handle")] public static extern int _switch_cache_db_get_db_handle(HandleRef jarg1, int jarg2, HandleRef jarg3, string jarg4, string jarg5, int jarg6); + [DllImport("mod_managed", EntryPoint="CSharp__switch_cache_db_get_db_handle_dsn")] + public static extern int _switch_cache_db_get_db_handle_dsn(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql2str")] public static extern string switch_cache_db_execute_sql2str(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, ref string jarg5); @@ -9325,8 +9406,8 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute")] public static extern int switch_cache_db_persistant_execute(HandleRef jarg1, string jarg2, uint jarg3); - [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute_trans")] - public static extern int switch_cache_db_persistant_execute_trans(HandleRef jarg1, string jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute_trans_full")] + public static extern int switch_cache_db_persistant_execute_trans_full(HandleRef jarg1, string jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, string jarg7); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_signal_handlers")] public static extern void switch_core_set_signal_handlers(); @@ -9388,6 +9469,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_stacksizes")] public static extern int switch_core_get_stacksizes(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_dbtype")] + public static extern int switch_core_dbtype(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sql_exec")] + public static extern void switch_core_sql_exec(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_recovery_recover")] public static extern int switch_core_recovery_recover(string jarg1, string jarg2); @@ -9400,6 +9487,24 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_recovery_flush")] public static extern void switch_core_recovery_flush(string jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_push")] + public static extern int switch_switch_sql_queue_manager_push(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_destroy")] + public static extern int switch_switch_sql_queue_manager_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_init")] + public static extern int switch_switch_sql_queue_manager_init(HandleRef jarg1, uint jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_start")] + public static extern int switch_switch_sql_queue_manager_start(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_stop")] + public static extern int switch_switch_sql_queue_manager_stop(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql_event_callback")] + public static extern int switch_cache_db_execute_sql_event_callback(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, ref string jarg5); + [DllImport("mod_managed", EntryPoint="CSharp_switch_fork")] public static extern IntPtr switch_fork(); @@ -10201,6 +10306,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_times_get")] public static extern IntPtr switch_caller_profile_times_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_old_times_set")] + public static extern void switch_caller_profile_old_times_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_old_times_get")] + public static extern IntPtr switch_caller_profile_old_times_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_caller_extension_set")] public static extern void switch_caller_profile_caller_extension_set(HandleRef jarg1, HandleRef jarg2); @@ -10456,6 +10567,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_flags_get")] public static extern uint switch_frame_flags_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_user_data_set")] + public static extern void switch_frame_user_data_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_user_data_get")] + public static extern IntPtr switch_frame_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_frame")] public static extern IntPtr new_switch_frame(); @@ -10678,6 +10795,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_state_run_get")] public static extern IntPtr switch_io_routines_state_run_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_get_jb_set")] + public static extern void switch_io_routines_get_jb_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_get_jb_get")] + public static extern IntPtr switch_io_routines_get_jb_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_padding_set")] public static extern void switch_io_routines_padding_set(HandleRef jarg1, HandleRef jarg2); @@ -11482,6 +11605,42 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_memory_pool_get")] public static extern IntPtr switch_asr_handle_memory_pool_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_buffer_set")] + public static extern void switch_asr_handle_buffer_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_buffer_get")] + public static extern IntPtr switch_asr_handle_buffer_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuf_set")] + public static extern void switch_asr_handle_dbuf_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuf_get")] + public static extern IntPtr switch_asr_handle_dbuf_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuflen_set")] + public static extern void switch_asr_handle_dbuflen_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuflen_get")] + public static extern IntPtr switch_asr_handle_dbuflen_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_resampler_set")] + public static extern void switch_asr_handle_resampler_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_resampler_get")] + public static extern IntPtr switch_asr_handle_resampler_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_samplerate_set")] + public static extern void switch_asr_handle_samplerate_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_samplerate_get")] + public static extern uint switch_asr_handle_samplerate_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_native_rate_set")] + public static extern void switch_asr_handle_native_rate_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_native_rate_get")] + public static extern uint switch_asr_handle_native_rate_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_private_info_set")] public static extern void switch_asr_handle_private_info_set(HandleRef jarg1, HandleRef jarg2); @@ -12124,6 +12283,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_next_get")] public static extern IntPtr switch_codec_next_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_session_set")] + public static extern void switch_codec_session_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_session_get")] + public static extern IntPtr switch_codec_session_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec")] public static extern IntPtr new_switch_codec(); @@ -13339,6 +13504,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_brackets")] public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6, int jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_array_pair")] + public static extern int switch_event_create_array_pair(HandleRef jarg1, ref string jarg2, ref string jarg3, int jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_running")] public static extern int switch_event_running(); @@ -14131,6 +14299,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_pause_jitter_buffer")] public static extern int switch_rtp_pause_jitter_buffer(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_jitter_buffer")] + public static extern IntPtr switch_rtp_get_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); @@ -14287,6 +14458,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_channel_get")] public static extern int switch_log_node_t_channel_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_slevel_set")] + public static extern void switch_log_node_t_slevel_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_slevel_get")] + public static extern int switch_log_node_t_slevel_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_log_node_t")] public static extern IntPtr new_switch_log_node_t(); @@ -14449,6 +14626,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_toxml_nolock")] public static extern string switch_xml_toxml_nolock(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_tohtml")] + public static extern string switch_xml_tohtml(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_toxml_buf")] public static extern string switch_xml_toxml_buf(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, int jarg5); @@ -16789,6 +16969,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_core_session_int__switch_status_t { private HandleRef swigCPtr; @@ -18439,6 +18649,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_void_p_switch_event__int { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_void_p_switch_event__int(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_void_p_switch_event__int() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_void_p_switch_event__int obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_void__void { private HandleRef swigCPtr; @@ -19669,6 +19909,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_sql_queue_manager { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_sql_queue_manager(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_sql_queue_manager() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_sql_queue_manager obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_xml { private HandleRef swigCPtr; @@ -19969,6 +20239,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_stfu_instance_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_stfu_instance_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_stfu_instance_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_stfu_instance_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_buffer { private HandleRef swigCPtr; @@ -20839,6 +21139,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_sql_queue_manager { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_sql_queue_manager(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_sql_queue_manager() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_sql_queue_manager obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_ssize_t { private HandleRef swigCPtr; @@ -21741,6 +22071,71 @@ public class switch_asr_handle : IDisposable { } } + public SWIGTYPE_p_switch_buffer buffer { + set { + freeswitchPINVOKE.switch_asr_handle_buffer_set(swigCPtr, SWIGTYPE_p_switch_buffer.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_handle_buffer_get(swigCPtr); + SWIGTYPE_p_switch_buffer ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_buffer(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_unsigned_char dbuf { + set { + freeswitchPINVOKE.switch_asr_handle_dbuf_set(swigCPtr, SWIGTYPE_p_unsigned_char.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_handle_dbuf_get(swigCPtr); + SWIGTYPE_p_unsigned_char ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_switch_size_t dbuflen { + set { + freeswitchPINVOKE.switch_asr_handle_dbuflen_set(swigCPtr, SWIGTYPE_p_switch_size_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_asr_handle_dbuflen_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public switch_audio_resampler_t resampler { + set { + freeswitchPINVOKE.switch_asr_handle_resampler_set(swigCPtr, switch_audio_resampler_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_handle_resampler_get(swigCPtr); + switch_audio_resampler_t ret = (cPtr == IntPtr.Zero) ? null : new switch_audio_resampler_t(cPtr, false); + return ret; + } + } + + public uint samplerate { + set { + freeswitchPINVOKE.switch_asr_handle_samplerate_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_asr_handle_samplerate_get(swigCPtr); + return ret; + } + } + + public uint native_rate { + set { + freeswitchPINVOKE.switch_asr_handle_native_rate_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_asr_handle_native_rate_get(swigCPtr); + return ret; + } + } + public SWIGTYPE_p_void private_info { set { freeswitchPINVOKE.switch_asr_handle_private_info_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); @@ -23385,6 +23780,17 @@ public class switch_caller_profile : IDisposable { } } + public switch_channel_timetable old_times { + set { + freeswitchPINVOKE.switch_caller_profile_old_times_set(swigCPtr, switch_channel_timetable.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_caller_profile_old_times_get(swigCPtr); + switch_channel_timetable ret = (cPtr == IntPtr.Zero) ? null : new switch_channel_timetable(cPtr, false); + return ret; + } + } + public switch_caller_extension caller_extension { set { freeswitchPINVOKE.switch_caller_profile_caller_extension_set(swigCPtr, switch_caller_extension.getCPtr(value)); @@ -23748,6 +24154,7 @@ public enum switch_channel_flag_t { CF_TRACKABLE, CF_NO_CDR, CF_EARLY_OK, + CF_MEDIA_TRANS, CF_FLAG_MAX } @@ -24424,6 +24831,17 @@ public class switch_codec : IDisposable { } } + public SWIGTYPE_p_switch_core_session session { + set { + freeswitchPINVOKE.switch_codec_session_set(swigCPtr, SWIGTYPE_p_switch_core_session.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_session_get(swigCPtr); + SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false); + return ret; + } + } + public switch_codec() : this(freeswitchPINVOKE.new_switch_codec(), true) { } @@ -28124,6 +28542,17 @@ public class switch_frame : IDisposable { } } + public SWIGTYPE_p_void user_data { + set { + freeswitchPINVOKE.switch_frame_user_data_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_frame_user_data_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + public switch_frame() : this(freeswitchPINVOKE.new_switch_frame(), true) { } @@ -29593,6 +30022,17 @@ public class switch_io_routines : IDisposable { } } + public SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t get_jb { + set { + freeswitchPINVOKE.switch_io_routines_get_jb_set(swigCPtr, SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_io_routines_get_jb_get(swigCPtr); + SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t(cPtr, false); + return ret; + } + } + public SWIGTYPE_p_p_void padding { set { freeswitchPINVOKE.switch_io_routines_padding_set(swigCPtr, SWIGTYPE_p_p_void.getCPtr(value)); @@ -29630,7 +30070,8 @@ public enum switch_io_routine_name_t { SWITCH_IO_RECEIVE_EVENT, SWITCH_IO_STATE_CHANGE, SWITCH_IO_READ_VIDEO_FRAME, - SWITCH_IO_WRITE_VIDEO_FRAME + SWITCH_IO_WRITE_VIDEO_FRAME, + SWITCH_IO_GET_JB } } @@ -30356,7 +30797,8 @@ public enum switch_log_level_t { SWITCH_LOG_CRIT = 2, SWITCH_LOG_ALERT = 1, SWITCH_LOG_CONSOLE = 0, - SWITCH_LOG_INVALID = 64 + SWITCH_LOG_INVALID = 64, + SWITCH_LOG_UNINIT = 1000 } } @@ -30495,6 +30937,16 @@ public class switch_log_node_t : IDisposable { } } + public switch_log_level_t slevel { + set { + freeswitchPINVOKE.switch_log_node_t_slevel_set(swigCPtr, (int)value); + } + get { + switch_log_level_t ret = (switch_log_level_t)freeswitchPINVOKE.switch_log_node_t_slevel_get(swigCPtr); + return ret; + } + } + public switch_log_node_t() : this(freeswitchPINVOKE.new_switch_log_node_t(), true) { } @@ -30703,6 +31155,22 @@ namespace FreeSWITCH.Native { namespace FreeSWITCH.Native { +public enum switch_media_type_t { + SWITCH_MEDIA_TYPE_AUDIO, + SWITCH_MEDIA_TYPE_VIDEO +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_module_flag_enum_t { SMODF_NONE = 0, SMODF_GLOBAL_SYMBOLS = (1 << 0) From ce4fa8acfbfee222921ab79f549ac0fceed1341f Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Tue, 23 Oct 2012 13:39:31 +0000 Subject: [PATCH 232/512] Added switch_atomic_t option for config parsing. --- src/include/switch_xml_config.h | 8 ++++++ src/switch_xml_config.c | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/include/switch_xml_config.h b/src/include/switch_xml_config.h index fc669e4fc1..6a81e4b16f 100644 --- a/src/include/switch_xml_config.h +++ b/src/include/switch_xml_config.h @@ -39,6 +39,7 @@ SWITCH_BEGIN_EXTERN_C /*! \brief Type of value to parse */ typedef enum { SWITCH_CONFIG_INT, /*< (ptr=int* default=int data=NULL) Integer */ + SWITCH_CONFIG_ATOMIC, /*< (ptr=switch_atomic_t* default=uint32_t data=NULL) Integer */ SWITCH_CONFIG_STRING, /*< (ptr=[char* or char ** (for alloc)] default=char* data=switch_xml_config_string_options_t*) Zero-terminated C-string */ SWITCH_CONFIG_BOOL, /*< (ptr=switch_bool_t* default=switch_bool_t data=NULL) Yes and no */ SWITCH_CONFIG_CUSTOM, /*< (ptr= default= data=switch_xml_config_callback_t) Custom, get value through function pointer */ @@ -70,6 +71,13 @@ typedef struct { int max; } switch_xml_config_int_options_t; +typedef struct { + switch_bool_t enforce_min; + uint32_t min; + switch_bool_t enforce_max; + uint32_t max; +} switch_xml_config_atomic_options_t; + struct switch_xml_config_item; typedef struct switch_xml_config_item switch_xml_config_item_t; diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c index c33dba4e8a..a6fdc55496 100644 --- a/src/switch_xml_config.c +++ b/src/switch_xml_config.c @@ -36,6 +36,7 @@ SWITCH_DECLARE_DATA switch_xml_config_string_options_t switch_config_string_strd static switch_xml_config_enum_item_t switch_config_types_enum[] = { {"int", SWITCH_CONFIG_INT}, + {"switch_atomic_t", SWITCH_CONFIG_INT}, {"string", SWITCH_CONFIG_STRING}, {"bool", SWITCH_CONFIG_BOOL}, {"custom", SWITCH_CONFIG_CUSTOM}, @@ -203,6 +204,48 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *ev } } break; + case SWITCH_CONFIG_ATOMIC: + { + switch_xml_config_atomic_options_t *atomic_options = (switch_xml_config_atomic_options_t *) item->data; + switch_atomic_t *dest = (switch_atomic_t *) ptr; + uint32_t uintval; + if (value) { + if (switch_is_number(value)) { + uintval = (uint32_t) strtoll(value, 10); + } else { + uintval = (uint32_t) (uintptr_t) item->defaultvalue; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%u]\n", + value, item->key, uintval); + } + + if (atomic_options) { + /* Enforce validation options */ + if ((atomic_options->enforce_min && !(uintval >= atomic_options->min)) || (atomic_options->enforce_max && !(uintval <= atomic_options->max))) { + /* Validation failed, set default */ + uintval = (uint32_t) (uintptr_t) item->defaultvalue; + /* Then complain */ + if (atomic_options->enforce_min && atomic_options->enforce_max) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Invalid value [%s] for parameter [%s], should be between [%u] and [%u], setting default [%u]\n", value, + item->key, atomic_options->min, atomic_options->max, uintval); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Invalid value [%s] for parameter [%s], should be %s [%u], setting default [%u]\n", value, item->key, + atomic_options->enforce_min ? "at least" : "at max", + atomic_options->enforce_min ? atomic_options->min : atomic_options->max, uintval); + } + } + } + } else { + uintval = (uint32_t) (uintptr_t) item->defaultvalue; + } + + if (switch_atomic_read(dest) != uintval) { + switch_atomic_set(dest, uintval); + changed = SWITCH_TRUE; + } + } + break; case SWITCH_CONFIG_STRING: { switch_xml_config_string_options_t string_options_default = { 0 }; From d923f0f75c093dcda201110c83ec525bbdfa7b7d Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Tue, 23 Oct 2012 14:00:52 +0000 Subject: [PATCH 233/512] oops --- src/switch_xml_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c index a6fdc55496..8b13f12fde 100644 --- a/src/switch_xml_config.c +++ b/src/switch_xml_config.c @@ -211,7 +211,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *ev uint32_t uintval; if (value) { if (switch_is_number(value)) { - uintval = (uint32_t) strtoll(value, 10); + uintval = (uint32_t) strtoll(value, NULL, 10); } else { uintval = (uint32_t) (uintptr_t) item->defaultvalue; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%u]\n", From 42fcaeacf59b76002798ccbab5bb0204c5e2a2e3 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Tue, 23 Oct 2012 15:02:36 +0000 Subject: [PATCH 234/512] Better error message handling. --- src/switch_pgsql.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 8c6d59cf80..22ab6ffd6d 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -536,32 +536,32 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgs SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err) { #ifdef SWITCH_HAVE_PGSQL - char *err_str = NULL; + char *err_str = NULL, *er = NULL; handle->affected_rows = 0; if (!db_is_up(handle)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not up!\n"); + er = strdup("Database is not up!"); goto error; } if (handle->auto_commit == SWITCH_FALSE && handle->in_txn == SWITCH_FALSE) { if (switch_pgsql_send_query(handle, "BEGIN") != SWITCH_PGSQL_SUCCESS) { + er = strdup("Error sending BEGIN!"); switch_pgsql_finish_results(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending BEGIN!\n"); goto error; } if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending BEGIN!\n"); + er = strdup("Error sending BEGIN!"); goto error; } handle->in_txn = SWITCH_TRUE; } if (switch_pgsql_send_query(handle, sql) != SWITCH_PGSQL_SUCCESS) { + er = strdup("Error sending query!"); switch_pgsql_finish_results(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending query!\n"); goto error; } @@ -571,7 +571,15 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql err_str = switch_pgsql_handle_get_error(handle); if (zstr(err_str)) { - err_str = strdup((char *)"SQL ERROR!"); + if (zstr(er)) { + err_str = strdup((char *)"SQL ERROR!"); + } else { + err_str = er; + } + } else { + if (!zstr(er)) { + free(er); + } } if (err_str) { From 2246b84554b237ba3fc63157ad8679be70d043a6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 23 Oct 2012 11:05:39 -0400 Subject: [PATCH 235/512] fix missing line --- src/switch_ivr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index b8fd0923e3..df5af62391 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1634,6 +1634,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_nomedia(const char *uuid, switch_medi } switch_channel_clear_flag(channel, CF_MEDIA_TRANS); + switch_core_session_rwunlock(session); } From 87c2bb552f45323f860216e1767e268d2be4d97e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 23 Oct 2012 12:23:19 -0400 Subject: [PATCH 236/512] FS-4751 I am leaving out the one for devel-bootstrap.sh because I am not sure it should be /usr/pkg/bin/bash --- libs/libg722_1/configure.ac | 2 +- libs/sofia-sip/scripts/lcov-report | 2 +- libs/sofia-sip/scripts/uncovered | 2 +- libs/spandsp/configure.ac | 4 ++-- libs/spandsp/unpack_gsm0610_data.sh | 4 ++-- libs/tiff-4.0.2/configure.ac | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/libg722_1/configure.ac b/libs/libg722_1/configure.ac index 62095ce374..829d7e0c45 100644 --- a/libs/libg722_1/configure.ac +++ b/libs/libg722_1/configure.ac @@ -200,7 +200,7 @@ AC_CHECK_HEADERS([audiofile.h]) AC_LANG([C]) -if test "${build}" == "${host}" +if test "${build}" = "${host}" then case "${host}" in x86_64-*) diff --git a/libs/sofia-sip/scripts/lcov-report b/libs/sofia-sip/scripts/lcov-report index 364f798128..77a0aaf40f 100755 --- a/libs/sofia-sip/scripts/lcov-report +++ b/libs/sofia-sip/scripts/lcov-report @@ -11,7 +11,7 @@ usage() { - test X$1 == X0 || exec >&2 + test X$1 = X0 || exec >&2 cat << EOF usage: coverage-report OPTIONS where OPTIONS are diff --git a/libs/sofia-sip/scripts/uncovered b/libs/sofia-sip/scripts/uncovered index 80f14ffad4..bdd156c789 100755 --- a/libs/sofia-sip/scripts/uncovered +++ b/libs/sofia-sip/scripts/uncovered @@ -11,7 +11,7 @@ usage() { - test X$1 == X0 || exec >&2 + test X$1 = X0 || exec >&2 cat < Date: Tue, 23 Oct 2012 13:00:16 -0400 Subject: [PATCH 237/512] OPENZAP-196 Fix casting issue - Apparently this fixes libpri BRI issues --- libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index 748b70a42f..c9f0576951 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -182,7 +182,7 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t * #define timeval_to_ms(x) \ - (((ftdm_time_t)(x)->tv_sec * 1000) + (ftdm_time_t)((x)->tv_usec / 1000)) + (ftdm_time_t)(((x)->tv_sec * 1000) + ((x)->tv_usec / 1000)) int lpwrap_start_timer(struct lpwrap_pri *spri, struct lpwrap_timer *timer, const uint32_t timeout_ms, timeout_handler callback) { From 542e7153fcf2105952c3a5a2ece04488a868d28a Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 23 Oct 2012 13:01:40 -0400 Subject: [PATCH 238/512] freetdm: Fix compilation with old libpri.h where AOC is not available --- libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 37f27f3355..3b819df718 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -2249,6 +2249,7 @@ static int handle_facility_aoc_e(const struct pri_subcmd_aoc_e *aoc_e) ftdm_log(FTDM_LOG_INFO, "AOC-E:\n%s", tmp); return 0; } +#endif /** * \brief Handler for libpri facility events @@ -2275,6 +2276,7 @@ static int on_facility(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev int res = -1; switch (sub->cmd) { +#ifdef HAVE_LIBPRI_AOC case PRI_SUBCMD_AOC_S: /* AOC-S: Start of call */ res = handle_facility_aoc_s(&sub->u.aoc_s); break; @@ -2293,6 +2295,7 @@ static int on_facility(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev sub->u.aoc_request_response.charging_request, sub->u.aoc_request_response.charging_response); break; +#endif default: ftdm_log(FTDM_LOG_DEBUG, "FACILITY subcommand %d is not implemented, ignoring\n", sub->cmd); } @@ -2303,7 +2306,6 @@ static int on_facility(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev ftdm_log(FTDM_LOG_DEBUG, "Caught Event on span %d %u (%s)\n", ftdm_span_get_id(spri->span), event_type, lpwrap_pri_event_str(event_type)); return 0; } -#endif /** * \brief Handler for libpri dchan up event From 8b14f81343cfad456c74ea6ead68b283a24c3c7e Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 23 Oct 2012 12:08:12 -0500 Subject: [PATCH 239/512] strtoll correction for windows --- src/switch_xml_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c index 8b13f12fde..888ed2c0f5 100644 --- a/src/switch_xml_config.c +++ b/src/switch_xml_config.c @@ -211,7 +211,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *ev uint32_t uintval; if (value) { if (switch_is_number(value)) { - uintval = (uint32_t) strtoll(value, NULL, 10); + uintval = (uint32_t) strtol(value, NULL, 10); } else { uintval = (uint32_t) (uintptr_t) item->defaultvalue; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%u]\n", From 5f469ad2bd97197845f9bee354eece4ecc3b27d7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 23 Oct 2012 13:14:51 -0400 Subject: [PATCH 240/512] FS-4753 --resolve this should properly detect it everywhere --- Makefile.am | 5 ++++- configure.in | 2 ++ libs/apr/.update | 2 +- libs/apr/Makefile.in | 12 ++++++++++++ libs/apr/configure.in | 3 +++ libs/apr/threadproc/unix/thread.c | 3 ++- libs/sofia-sip/.update | 2 +- libs/sofia-sip/Makefile.am | 3 +++ libs/sofia-sip/configure.ac | 3 +++ libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c | 7 ++----- src/mod/endpoints/mod_sofia/Makefile.am | 1 + 11 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Makefile.am b/Makefile.am index f11f891aac..036baafeba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -450,7 +450,10 @@ libs/curl/lib/libcurl.la: libs/curl libs/curl/Makefile @cd libs/curl && $(MAKE) @$(TOUCH_TARGET) -libs/apr/libapr-1.la: libs/apr libs/apr/.update +libs/apr/Makefile: libs/apr/Makefile.in libs/apr/config.status libs/apr libs/apr/.update + @cd libs/apr && ./config.status + +libs/apr/libapr-1.la: libs/apr/Makefile touch src/include/switch.h @cd libs/apr && $(MAKE) @$(TOUCH_TARGET) diff --git a/configure.in b/configure.in index 89cf47d79e..2c4835afc2 100644 --- a/configure.in +++ b/configure.in @@ -559,6 +559,8 @@ AX_HAVE_CPU_SET AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])]) AC_CHECK_LIB(rt, clock_getres, [AC_DEFINE(HAVE_CLOCK_GETRES, 1, [Define if you have clock_getres()])]) AC_CHECK_LIB(rt, clock_nanosleep, [AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1, [Define if you have clock_nanosleep()])]) +AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])]) + AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket)) AC_CHECK_FILE(/dev/ptmx, [AC_DEFINE(HAVE_DEV_PTMX, 1, [Define if you have /dev/ptmx])]) diff --git a/libs/apr/.update b/libs/apr/.update index 4452df8ef3..a55ae9a4f4 100644 --- a/libs/apr/.update +++ b/libs/apr/.update @@ -1 +1 @@ -Thu Sep 27 13:36:14 CDT 2012 +Tue Oct 23 13:13:30 EDT 2012 diff --git a/libs/apr/Makefile.in b/libs/apr/Makefile.in index fe6ad501c9..5aef325fe5 100644 --- a/libs/apr/Makefile.in +++ b/libs/apr/Makefile.in @@ -66,6 +66,18 @@ apr-config.out: $(APR_CONFIG) build/apr_rules.out: build/apr_rules.mk sed 's,^\(apr_build.*=\).*$$,\1$(installbuilddir),' < build/apr_rules.mk > $@ +.PRECIOUS: Makefile + +Makefile: $(srcdir)/Makefile.in $(top_blddir)/config.status + cd $(srcdir) && ./config.status + +$(top_blddir)/config.status: $(top_srcdir)/configure + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(top_srcdir)/configure.in + cd $(srcdir) && autoconf + cd $(srcdir) && autoheader + install: $(TARGET_LIB) apr-config.out build/apr_rules.out $(APR_MKDIR) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) $(DESTDIR)$(installbuilddir) \ $(DESTDIR)$(libdir)/pkgconfig $(DESTDIR)$(includedir) diff --git a/libs/apr/configure.in b/libs/apr/configure.in index 68c030e124..412ee7e937 100644 --- a/libs/apr/configure.in +++ b/libs/apr/configure.in @@ -550,6 +550,7 @@ AC_CHECK_LIB(truerand, main) AC_SEARCH_LIBS(modf, m) AC_CHECK_LIB(dl, dlopen) + dnl ----------------------------- Checking for Threads echo "${nl}Checking for Threads..." @@ -1619,6 +1620,8 @@ APR_CHECK_DEFINE_FILES(POLLIN, poll.h sys/poll.h) if test "$threads" = "1"; then APR_CHECK_DEFINE(PTHREAD_PROCESS_SHARED, pthread.h) AC_CHECK_FUNCS(pthread_mutexattr_setpshared) + AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])]) + # Some systems have setpshared and define PROCESS_SHARED, but don't # really support PROCESS_SHARED locks. So, we must validate that we # can go through the steps without receiving some sort of system error. diff --git a/libs/apr/threadproc/unix/thread.c b/libs/apr/threadproc/unix/thread.c index 786f83069e..391e5368c8 100644 --- a/libs/apr/threadproc/unix/thread.c +++ b/libs/apr/threadproc/unix/thread.c @@ -174,7 +174,8 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, } if ((stat = pthread_create((*new)->td, temp, dummy_worker, (*new))) == 0) { -#ifndef __APPLE__ + +#ifdef HAVE_PTHREAD_SETSCHEDPRIO if (attr && attr->priority) { pthread_t *thread = (*new)->td; pthread_setschedprio(*thread, attr->priority); diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index ecae8fc840..22f5eeb029 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Mon Oct 1 12:24:45 CDT 2012 +Tue Oct 23 13:13:35 EDT 2012 diff --git a/libs/sofia-sip/Makefile.am b/libs/sofia-sip/Makefile.am index 069007d300..7279695865 100644 --- a/libs/sofia-sip/Makefile.am +++ b/libs/sofia-sip/Makefile.am @@ -40,6 +40,9 @@ dist_man_MANS = # man/man1/localinfo.1 man/man1/addrinfo.1 \ # man/man1/stunc.1 man/man1/sip-dig.1 +noop: + @echo ok + $(dist_man_MANS): manpages manpages: diff --git a/libs/sofia-sip/configure.ac b/libs/sofia-sip/configure.ac index 196d815157..1bce33e178 100644 --- a/libs/sofia-sip/configure.ac +++ b/libs/sofia-sip/configure.ac @@ -254,6 +254,9 @@ if test x"$have_check" = "xyes"; then fi AC_CHECK_HEADERS([fnmatch.h]) +AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])]) + + dnl dl is currently used only in testing AC_CHECK_LIB([dl], [dlopen], [ dnl Note: -ldl is not added to LIBS diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c index db314b28dd..5eb391f38d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c @@ -269,13 +269,10 @@ int su_pthreaded_port_start(su_port_create_f *create, pthread_mutex_lock(arg.mutex); if (pthread_create(&tid, &attr, su_pthread_port_clone_main, &arg) == 0) { -#if defined (WIN32) - /* this needs to be revisited when pthread for Windows supports thread priority settings */ -#elif defined (__APPLE__) - /* no such function on Apple */ -#else +#ifdef HAVE_PTHREAD_SETSCHEDPRIO pthread_setschedprio(tid, 99); #endif + pthread_cond_wait(arg.cv, arg.mutex); thread_created = 1; } diff --git a/src/mod/endpoints/mod_sofia/Makefile.am b/src/mod/endpoints/mod_sofia/Makefile.am index efd6b2c385..7828c5eb49 100644 --- a/src/mod/endpoints/mod_sofia/Makefile.am +++ b/src/mod/endpoints/mod_sofia/Makefile.am @@ -41,6 +41,7 @@ BUILT_SOURCES = $(SOFIALA) $(mod_sofia_la_SOURCES) : $(BUILT_SOURCES) $(SOFIALA): $(SOFIA_DIR) $(SOFIA_DIR)/.update + cd $(SOFIA_BUILDDIR) && $(MAKE) noop cd $(SOFIA_BUILDDIR) && $(MAKE) SOFIA_CFLAGS="$(SWITCH_AM_CFLAGS)" $(TOUCH_TARGET) From f0895c9f51deea73155c12c0e8685def2fa7eca2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 23 Oct 2012 18:14:27 -0400 Subject: [PATCH 241/512] print extended debug messages at alert level --- src/switch_log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_log.c b/src/switch_log.c index c8bdad3917..35314b0c3a 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -362,7 +362,7 @@ SWITCH_DECLARE(void) switch_log_vprintf(switch_text_channel_t channel, const cha return; } - level = 7; + level = 1; } if (level > limit_level) { From 7f46c7e29033f8086386881f5e3685968f7b93a0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 23 Oct 2012 18:15:03 -0400 Subject: [PATCH 242/512] fix build dependancy regression to reduce rebuilds --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 036baafeba..4f6f4c2bdd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -452,8 +452,9 @@ libs/curl/lib/libcurl.la: libs/curl libs/curl/Makefile libs/apr/Makefile: libs/apr/Makefile.in libs/apr/config.status libs/apr libs/apr/.update @cd libs/apr && ./config.status + @$(TOUCH_TARGET) -libs/apr/libapr-1.la: libs/apr/Makefile +libs/apr/libapr-1.la: libs/apr/Makefile libs/apr/.update touch src/include/switch.h @cd libs/apr && $(MAKE) @$(TOUCH_TARGET) From 01dde19cbd967f0aa033dabb7a905ae356a34a2e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 23 Oct 2012 18:19:32 -0400 Subject: [PATCH 243/512] FS-4741 --resolve use paypal@freeswitch.org --- .../mod_dialplan_xml/mod_dialplan_xml.c | 28 +++++++---- src/switch_xml.c | 46 ++++++++++++++++--- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c index 2ff472afea..6b685d547d 100644 --- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c +++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c @@ -79,6 +79,17 @@ static switch_status_t exec_app(switch_core_session_t *session, const char *app, return status; } + +#define check_tz() tzoff = switch_channel_get_variable(channel, "tod_tz_offset"); \ + do { \ + if (!zstr(tzoff) && switch_is_number(tzoff)) { \ + offset = atoi(tzoff); \ + } else { \ + tzoff = NULL; \ + } \ + break; \ + } while(tzoff) + static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *caller_profile, switch_xml_t xexten, switch_caller_extension_t **extension) { switch_xml_t xcond, xaction, xexpression, xregex; @@ -88,13 +99,10 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * char *expression_expanded = NULL, *field_expanded = NULL; switch_regex_t *re = NULL, *save_re = NULL; int offset = 0; - const char *tzoff = switch_channel_get_variable(channel, "tod_tz_offset"); + const char *tzoff; + + check_tz(); - if (!zstr(tzoff) && switch_is_number(tzoff)) { - offset = atoi(tzoff); - } else { - tzoff = NULL; - } if (!exten_name) { exten_name = "_anon_"; @@ -109,8 +117,11 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * int ovector[30]; switch_bool_t anti_action = SWITCH_TRUE; break_t do_break_i = BREAK_ON_FALSE; + int time_match; + + check_tz(); + time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL); - int time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); @@ -161,8 +172,9 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * switch_channel_del_variable_prefix(channel, "DP_REGEX_MATCH"); for (xregex = switch_xml_child(xcond, "regex"); xregex; xregex = xregex->next) { + check_tz(); time_match = switch_xml_std_datetime_check(xregex, tzoff ? &offset : NULL); - + if (time_match == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, "Dialplan: %s Date/Time Match (PASS) [%s]\n", diff --git a/src/switch_xml.c b/src/switch_xml.c index ec7eddec0a..237873e15d 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2899,22 +2899,54 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond, int *offse const char *xminday = switch_xml_attr(xcond, "minute-of-day"); const char *xtod = switch_xml_attr(xcond, "time-of-day"); const char *tzoff = switch_xml_attr(xcond, "tz-offset"); - int loffset = 0; + const char *isdst = switch_xml_attr(xcond, "dst"); + int loffset = -1000; + int eoffset = -1000; + int dst = -1000; switch_time_t ts = switch_micro_time_now(); int time_match = -1; - switch_time_exp_t tm; + switch_time_exp_t tm, tm2; + + if (!zstr(isdst)) { + dst = switch_true(isdst); + } if (!zstr(tzoff) && switch_is_number(tzoff)) { loffset = atoi(tzoff); - offset = &loffset; + } + + switch_time_exp_lt(&tm2, ts); + + if (offset) { + eoffset = *offset; + switch_time_exp_tz(&tm, ts, *offset); + } else { + tm = tm2; + } + + if (eoffset == -1000) { + eoffset = tm.tm_gmtoff / 3600; + } + + if (loffset == -1000) { + loffset = eoffset; } - if (offset) { - switch_time_exp_tz(&tm, ts, *offset); - } else { - switch_time_exp_lt(&tm, ts); + if (time_match && tzoff) { + time_match = loffset == eoffset; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: TZOFFSET[%d] == %d (%s)\n", eoffset, loffset, time_match ? "PASS" : "FAIL"); + + } + + if (time_match && dst > -1) { + time_match = (tm2.tm_isdst > 0 && dst > 0); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: DST[%s] == %s (%s)\n", + tm2.tm_isdst > 0 ? "true" : "false", dst > 0 ? "true" : "false", time_match ? "PASS" : "FAIL"); + } if (time_match && xdt) { From 1a43405bed1b742e659dabfeb23cacb7c7a48c95 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 23 Oct 2012 20:38:03 -0400 Subject: [PATCH 244/512] up max db buffer size in core sql --- src/switch_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core.c b/src/switch_core.c index 82b08e3808..8f0895fb9b 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1471,7 +1471,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.runlevel++; runtime.sql_buffer_len = 1024 * 32; - runtime.max_sql_buffer_len = 1024 * 1024; + runtime.max_sql_buffer_len = 1024 * 1024 * 10; runtime.dummy_cng_frame.data = runtime.dummy_data; runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); From cecd0f4505e981041b416017bce1b1b2c19623dc Mon Sep 17 00:00:00 2001 From: Mahdi Moradi Date: Wed, 24 Oct 2012 18:59:36 +0330 Subject: [PATCH 245/512] With this changes, can say mobile numbers better. --- src/mod/say/mod_say_fa/mod_say_fa.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mod/say/mod_say_fa/mod_say_fa.c b/src/mod/say/mod_say_fa/mod_say_fa.c index e044fca7b6..838465b612 100644 --- a/src/mod/say/mod_say_fa/mod_say_fa.c +++ b/src/mod/say/mod_say_fa/mod_say_fa.c @@ -502,8 +502,16 @@ static switch_status_t fa_say_telephone(switch_core_session_t *session, char *to } else { - play_group(SSM_PRONOUNCED,0,tosay[0] - 48,tosay[1] - 48,NULL,session,args); - fa_say_telephone(session,tosay + 2,say_args,args); + if ( tosay_length == 10 && (tosay[0] != '2' || tosay[1] != '1') ) + { + play_group(SSM_PRONOUNCED,tosay[0] - 48,tosay[1] - 48,tosay[2] - 48,NULL,session,args); + fa_say_telephone(session,tosay + 3,say_args,args); + } + else + { + play_group(SSM_PRONOUNCED,0,tosay[0] - 48,tosay[1] - 48,NULL,session,args); + fa_say_telephone(session,tosay + 2,say_args,args); + } } return SWITCH_STATUS_SUCCESS; } From fa9a0ed7042469b47d3537c332afafc12ae76be3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 24 Oct 2012 12:34:03 -0500 Subject: [PATCH 246/512] FS-2746 found this assert in a BT on the conf box --- libs/xmlrpc-c/lib/abyss/src/response.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libs/xmlrpc-c/lib/abyss/src/response.c b/libs/xmlrpc-c/lib/abyss/src/response.c index 235d787ff3..febd5af032 100644 --- a/libs/xmlrpc-c/lib/abyss/src/response.c +++ b/libs/xmlrpc-c/lib/abyss/src/response.c @@ -327,7 +327,12 @@ ResponseWriteStart(TSession * const sessionP) { -----------------------------------------------------------------------------*/ struct _TServer * const srvP = ConnServer(sessionP->connP)->srvP; - assert(!sessionP->responseStarted); + //assert(!sessionP->responseStarted); + + if (sessionP->responseStarted) { + TraceMsg("Abyss client called ResponseWriteStart() more than once\n"); + return FALSE; + } if (sessionP->status == 0) { /* Handler hasn't set status. That's an error */ From adce3f9c7cc2dc441483d6a2d3d61a0935cb4ae9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 24 Oct 2012 13:53:54 -0400 Subject: [PATCH 247/512] FS-4729 try this version with the same debug patch applied --- src/switch_ivr_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 990b121f00..3d66adbd4d 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1677,7 +1677,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu status = SWITCH_STATUS_SUCCESS; - switch_ivr_bridge_display(originator_session, originatee_session); + //switch_ivr_bridge_display(originator_session, originatee_session); /* release the read locks we have on the channels */ switch_core_session_rwunlock(originator_session); From f1e16ccbfa9bc0df6951f2ca9998b7d00221e29e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 24 Oct 2012 12:33:13 -0500 Subject: [PATCH 248/512] only track calls once they have been answered --- src/switch_channel.c | 2 ++ src/switch_core_sqldb.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/switch_channel.c b/src/switch_channel.c index fd00c5f71e..5ccca55184 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -3395,6 +3395,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan switch_channel_audio_sync(channel); + switch_core_recovery_track(channel->session); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index e23d427a1b..80ab68c110 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2722,6 +2722,10 @@ SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session char *sql = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); + if (!switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_get_state(channel) < CS_SOFT_EXECUTE) { + return; + } + if (!switch_channel_test_flag(channel, CF_TRACKABLE)) { return; } @@ -2756,6 +2760,11 @@ SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session) const char *profile_name; const char *technology; + + if (!switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_get_state(channel) < CS_SOFT_EXECUTE) { + return; + } + if (switch_channel_test_flag(channel, CF_RECOVERING) || !switch_channel_test_flag(channel, CF_TRACKABLE)) { return; } From 3124f8226c1c4d2e286316a22ce58f934d3e4a6b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 24 Oct 2012 19:17:15 -0500 Subject: [PATCH 249/512] FS-4761 --resolve --- src/mod/applications/mod_lcr/mod_lcr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 8da2bd1dcc..55841170a4 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -1236,10 +1236,10 @@ static switch_status_t lcr_load_config() if (!strcasecmp(limit_type, "hash")) { profile->limit_type = "hash"; } else { - profile->limit_type = "sql"; + profile->limit_type = "db"; } } else { - profile->limit_type = "sql"; + profile->limit_type = "db"; } switch_core_hash_insert(globals.profile_hash, profile->name, profile); From b11649123a95a7e1cdbacd07987500452bb02ef5 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 25 Oct 2012 07:50:14 -0500 Subject: [PATCH 250/512] FS-4658 --resolve --- conf/vanilla/directory/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/vanilla/directory/default.xml b/conf/vanilla/directory/default.xml index 0dc67412de..95b75b40dd 100644 --- a/conf/vanilla/directory/default.xml +++ b/conf/vanilla/directory/default.xml @@ -21,7 +21,7 @@ - + From 6e919cd43ba559111678a2c3a795323f34416a5e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 10:07:27 -0500 Subject: [PATCH 251/512] FS-4764 --resolve --- src/switch_ivr_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 3d66adbd4d..24e18f6b58 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -262,7 +262,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if (switch_true(silence_var)) { silence_val = 1400; } else { - if ((silence_val = atoi(silence_var)) < 0) { + if ((silence_val = atoi(silence_var)) < -1) { silence_val = 0; } } From c670ed6df58c1442cbfaac939b89547b1ecc0c26 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 11:31:07 -0500 Subject: [PATCH 252/512] fix type in config --- src/switch_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core.c b/src/switch_core.c index 8f0895fb9b..431ed8d3a1 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1471,7 +1471,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.runlevel++; runtime.sql_buffer_len = 1024 * 32; - runtime.max_sql_buffer_len = 1024 * 1024 * 10; + runtime.max_sql_buffer_len = 1024 * 1024; runtime.dummy_cng_frame.data = runtime.dummy_data; runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); @@ -1780,7 +1780,7 @@ static void switch_load_core_config(const char *file) if (tmp < runtime.sql_buffer_len) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Value is not larger than sql-buffer-len\n"); } else if (tmp >= 32000 && tmp < 10500000) { - runtime.sql_buffer_len = tmp; + runtime.max_sql_buffer_len = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-sql-buffer-len: Value is not within rage 32k to 10m\n"); } From 68e0b7e859d9e81569b8aac1f42151bbdc57eb6a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 11:31:42 -0500 Subject: [PATCH 253/512] optimize sofia sql by using new core transaction processor we will no longer support databases that do not support transactions --- src/include/switch_core.h | 23 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 3 +- src/mod/endpoints/mod_sofia/mod_sofia.h | 5 +- src/mod/endpoints/mod_sofia/sofia.c | 225 +++++++------------ src/mod/endpoints/mod_sofia/sofia_glue.c | 63 +++--- src/mod/endpoints/mod_sofia/sofia_presence.c | 7 +- src/mod/endpoints/mod_sofia/sofia_reg.c | 97 ++++---- src/switch_core_session.c | 45 ++-- src/switch_core_sqldb.c | 139 +++++++++--- 9 files changed, 316 insertions(+), 291 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index a3898d9d64..f647066c38 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -70,6 +70,12 @@ typedef struct switch_hold_record_s { } switch_hold_record_t; +typedef struct switch_thread_data_s { + switch_thread_start_t func; + void *obj; + int alloc; +} switch_thread_data_t; + #define MESSAGE_STAMP_FFL(_m) _m->_file = __FILE__; _m->_func = __SWITCH_FUNC__; _m->_line = __LINE__ @@ -703,6 +709,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_by_name(_In_ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(_In_ switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_thread_pool_launch_thread(switch_thread_data_t **tdp); SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_core_session_t *session); /*! @@ -2418,14 +2425,18 @@ SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_recovery_flush(const char *technology, const char *profile_name); +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp); -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init(switch_sql_queue_manager_t **qmp, - uint32_t numq, const char *dsn, - const char *pre_trans_execute, - const char *post_trans_execute, - const char *inner_pre_trans_execute, - const char *inner_post_trans_execute); +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init_name(const char *name, + switch_sql_queue_manager_t **qmp, + uint32_t numq, const char *dsn, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute); + +#define switch_switch_sql_queue_manager_init(_q, _d, _p1, _p2, _ip1, _ip2) switch_switch_sql_queue_manager_init_name(__FILE__, _q, _d, _p1, _p2, _ip1, _ip2) SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm); SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 14d501489c..898b5e49ed 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4900,8 +4900,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session sql = switch_mprintf("insert into sip_dialogs (uuid,presence_id,presence_data,profile_name,hostname,rcd,call_info_state) " "values ('%q', '%q', '%q', '%q', '%q', %ld, '')", switch_core_session_get_uuid(nsession), switch_str_nil(presence_id), switch_str_nil(presence_data), profile->name, mod_sofia_globals.hostname, (long) now); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - switch_safe_free(sql); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } #endif diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index ecb2d1c149..f01a121608 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -241,7 +241,7 @@ typedef enum { PFLAG_DISABLE_HOLD, PFLAG_AUTO_NAT, PFLAG_SIPCOMPACT, - PFLAG_SQL_IN_TRANS, + PFLAG_USE_ME, PFLAG_PRESENCE_PRIVACY, PFLAG_PASS_CALLEE_ID, PFLAG_LOG_AUTH_FAIL, @@ -273,6 +273,7 @@ typedef enum { PFLAG_MWI_USE_REG_CALLID, PFLAG_FIRE_MESSAGE_EVENTS, PFLAG_SEND_DISPLAY_UPDATE, + PFLAG_RUNNING_TRANS, /* No new flags below this line */ PFLAG_MAX } PFLAGS; @@ -632,7 +633,7 @@ struct sofia_profile { char *post_trans_execute; char *inner_pre_trans_execute; char *inner_post_trans_execute; - switch_queue_t *sql_queue; + switch_sql_queue_manager_t *qm; char *acl[SOFIA_MAX_ACL]; char *acl_pass_context[SOFIA_MAX_ACL]; char *acl_fail_context[SOFIA_MAX_ACL]; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 979e185781..d463345f7c 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1520,6 +1520,28 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run_once(switch_thread_t *thread, void return NULL; } +void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) +{ + sofia_dispatch_event_t *de = *dep; + switch_memory_pool_t *pool; + sofia_profile_t *profile = (*dep)->profile; + switch_thread_data_t *td; + + switch_core_new_memory_pool(&pool); + + *dep = NULL; + de->pool = pool; + + td = switch_core_alloc(pool, sizeof(*td)); + td->func = sofia_msg_thread_run_once; + td->obj = de; + + switch_mutex_lock(profile->ireg_mutex); + switch_thread_pool_launch_thread(&td); + switch_mutex_unlock(profile->ireg_mutex); +} + +#if 0 void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) { sofia_dispatch_event_t *de = *dep; @@ -1551,6 +1573,7 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) sofia_process_dispatch_event(&de); } } +#endif void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) { @@ -2158,153 +2181,63 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread sofia_profile_t *profile = (sofia_profile_t *) obj; uint32_t ireg_loops = profile->ireg_seconds; /* Number of loop iterations done when we haven't checked for registrations */ uint32_t gateway_loops = GATEWAY_SECONDS; /* Number of loop iterations done when we haven't checked for gateways */ - void *pop = NULL; /* queue_pop placeholder */ - switch_size_t sql_len = 1024 * 32; /* length of sqlbuf */ - char *tmp, *sqlbuf = NULL; /* Buffer for SQL statements */ - char *sql = NULL; /* Current SQL statement */ - switch_time_t last_commit; /* Last time we committed stuff to the DB */ - switch_time_t last_check; /* Last time we did the second-resolution loop that checks various stuff */ - switch_size_t len = 0; /* Current length of sqlbuf */ - uint32_t statements = 0; /* Number of statements in the current sql buffer */ - - last_commit = last_check = switch_micro_time_now(); - - if (sofia_test_pflag(profile, PFLAG_SQL_IN_TRANS)) { - sqlbuf = (char *) malloc(sql_len); - } sofia_set_pflag_locked(profile, PFLAG_WORKER_RUNNING); - switch_queue_create(&profile->sql_queue, SOFIA_QUEUE_SIZE, profile->pool); - - /* While we're running, or there is a pending sql statment that we haven't appended to sqlbuf yet, because of a lack of buffer space */ - while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)) || sql) { - - if (sofia_test_pflag(profile, PFLAG_SQL_IN_TRANS)) { - /* Do we have enough statements or is the timeout expired */ - while (sql || (sofia_test_pflag(profile, PFLAG_RUNNING) && mod_sofia_globals.running == 1 && - switch_micro_time_now() - last_check < 1000000 && - (statements == 0 || (statements <= 1024 && (switch_micro_time_now() - last_commit)/1000 < profile->trans_timeout)))) { + while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING))) { + + if (profile->watchdog_enabled) { + uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0; + + if (profile->step_timeout) { + step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000); - switch_interval_time_t sleepy_time = !statements ? 1000000 : switch_micro_time_now() - last_commit - profile->trans_timeout*1000; - - if (sleepy_time < 1000 || sleepy_time > 1000000) { - sleepy_time = 1000; - } - - if (sql || (switch_queue_pop_timeout(profile->sql_queue, &pop, sleepy_time) == SWITCH_STATUS_SUCCESS && pop)) { - switch_size_t newlen; - - if (!sql) sql = (char *) pop; - - newlen = strlen(sql) + 2 /* strlen(";\n") */ ; - - if (len + newlen + 10 > sql_len) { - switch_size_t new_mlen = len + newlen + 10 + 10240; - - if (new_mlen < SQLLEN) { - sql_len = new_mlen; - - if (!(tmp = realloc(sqlbuf, sql_len))) { - abort(); - break; - } - sqlbuf = tmp; - } else { - break; - } - } - - sprintf(sqlbuf + len, "%s;\n", sql); - len += newlen; - free(sql); - sql = NULL; - - statements++; + if (step_diff > profile->step_timeout) { + step_fail = 1; } } - /* Execute here */ - last_commit = switch_micro_time_now(); - - if (len) { - //printf("TRANS:\n%s\n", sqlbuf); - switch_mutex_lock(profile->ireg_mutex); - sofia_glue_actually_execute_sql_trans(profile, sqlbuf, NULL); - //sofia_glue_actually_execute_sql(profile, "commit;\n", NULL); - switch_mutex_unlock(profile->ireg_mutex); - statements = 0; - len = 0; + if (profile->event_timeout) { + event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000); + + if (event_diff > profile->event_timeout) { + event_fail = 1; + } } - - } else { - if (switch_queue_pop_timeout(profile->sql_queue, &pop, 1000000) == SWITCH_STATUS_SUCCESS && pop) { - sofia_glue_actually_execute_sql(profile, (char *) pop, profile->ireg_mutex); - free(pop); + + if (step_fail && profile->event_timeout && !event_fail) { + step_fail = 0; + } + + if (event_fail || step_fail) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n" + "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name); + switch_yield(2000000); + watchdog_triggered_abort(); } } - if (switch_micro_time_now() - last_check >= 1000000) { - if (profile->watchdog_enabled) { - uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0; - - if (profile->step_timeout) { - step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000); - if (step_diff > profile->step_timeout) { - step_fail = 1; - } - } - - if (profile->event_timeout) { - event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000); - - if (event_diff > profile->event_timeout) { - event_fail = 1; - } - } - - if (step_fail && profile->event_timeout && !event_fail) { - step_fail = 0; - } - - if (event_fail || step_fail) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n" - "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name); - switch_yield(2000000); - watchdog_triggered_abort(); - } - } - - - if (!sofia_test_pflag(profile, PFLAG_STANDBY)) { - if (++ireg_loops >= IREG_SECONDS) { - time_t now = switch_epoch_time_now(NULL); - sofia_reg_check_expire(profile, now, 0); - ireg_loops = 0; - } - - if (++gateway_loops >= GATEWAY_SECONDS) { - sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL)); - gateway_loops = 0; - } - - sofia_sub_check_gateway(profile, time(NULL)); + if (!sofia_test_pflag(profile, PFLAG_STANDBY)) { + if (++ireg_loops >= IREG_SECONDS) { + time_t now = switch_epoch_time_now(NULL); + sofia_reg_check_expire(profile, now, 0); + ireg_loops = 0; } - last_check = switch_micro_time_now(); + if (++gateway_loops >= GATEWAY_SECONDS) { + sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL)); + gateway_loops = 0; + } + + sofia_sub_check_gateway(profile, time(NULL)); } - } - switch_mutex_lock(profile->ireg_mutex); - while (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { - sofia_glue_actually_execute_sql(profile, (char *) pop, NULL); - free(pop); + switch_yield(1000000); + } - switch_mutex_unlock(profile->ireg_mutex); sofia_clear_pflag_locked(profile, PFLAG_WORKER_RUNNING); - switch_safe_free(sqlbuf); return NULL; } @@ -2409,6 +2342,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void int sanity; switch_thread_t *worker_thread; switch_status_t st; + char qname [128] = ""; switch_mutex_lock(mod_sofia_globals.mutex); mod_sofia_globals.threads++; @@ -2596,6 +2530,17 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool); switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool); + switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name); + switch_switch_sql_queue_manager_init_name(qname, + &profile->qm, + 1, + profile->odbc_dsn ? profile->odbc_dsn : profile->dbname, + profile->pre_trans_execute, + profile->post_trans_execute, + profile->inner_pre_trans_execute, + profile->inner_post_trans_execute); + switch_switch_sql_queue_manager_start(profile->qm); + if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s", (sofia_test_pflag(profile, PFLAG_TLS)) ? ",_sips._tcp" : ""); @@ -2682,6 +2627,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_mutex_lock(profile->flag_mutex); switch_mutex_unlock(profile->flag_mutex); + switch_switch_sql_queue_manager_stop(profile->qm); + if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s", (sofia_test_pflag(profile, PFLAG_TLS)) ? ",_sips._tcp" : ""); @@ -4405,7 +4352,6 @@ switch_status_t config_sofia(int reload, char *profile_name) sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE); sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); - sofia_set_pflag(profile, PFLAG_SQL_IN_TRANS); profile->shutdown_type = "false"; profile->local_network = "localnet.auto"; @@ -5107,20 +5053,6 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID); } - } else if (!strcasecmp(var, "sql-in-transactions")) { - int tmp = atoi(val); - - if (switch_true(val)) { - tmp = 500; - } - - if (tmp > 0) { - profile->trans_timeout = tmp; - sofia_set_pflag(profile, PFLAG_SQL_IN_TRANS); - } else { - sofia_clear_pflag(profile, PFLAG_SQL_IN_TRANS); - } - } else if (!strcasecmp(var, "enable-soa")) { if (switch_true(val)) { sofia_set_flag(profile, TFLAG_ENABLE_SOA); @@ -6102,8 +6034,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_str_nil(presence_id), switch_str_nil(presence_data), switch_str_nil(p), (long) now); switch_assert(sql); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - switch_safe_free(sql); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } } else if (status == 200 && (profile->pres_type)) { @@ -9406,9 +9337,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia switch_assert(sql); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - switch_safe_free(sql); - + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } if (is_nat) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 10ce4deba1..0117612f6a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6269,7 +6269,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile) }; switch_cache_db_handle_t *dbh = sofia_glue_get_db_handle(profile); - + char *test2; + if (!dbh) { return 0; } @@ -6283,20 +6284,22 @@ int sofia_glue_init_sql(sofia_profile_t *profile) switch_cache_db_test_reactive(dbh, test_sql, "drop table sip_registrations", reg_sql); - - - if (sofia_test_pflag(profile, PFLAG_SQL_IN_TRANS)) { - char *test2 = switch_mprintf("%s;%s", test_sql, test_sql); + + test2 = switch_mprintf("%s;%s", test_sql, test_sql); - if (switch_cache_db_execute_sql(dbh, test2, NULL) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "GREAT SCOTT!!! Cannot execute batched statements!\n" - "If you are using mysql, make sure you are using MYODBC 3.51.18 or higher and enable FLAG_MULTI_STATEMENTS\n"); - sofia_clear_pflag(profile, PFLAG_SQL_IN_TRANS); - - } + if (switch_cache_db_execute_sql(dbh, test2, NULL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "GREAT SCOTT!!! Cannot execute batched statements!\n" + "If you are using mysql, make sure you are using MYODBC 3.51.18 or higher and enable FLAG_MULTI_STATEMENTS\n"); + + switch_cache_db_release_db_handle(&dbh); free(test2); + free(test_sql); + return 0; } + free(test2); + + free(test_sql); test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and full_to='XXX'", mod_sofia_globals.hostname); @@ -6346,45 +6349,31 @@ int sofia_glue_init_sql(sofia_profile_t *profile) void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic) { - switch_status_t status = SWITCH_STATUS_FALSE; - char *d_sql = NULL, *sql; + char *sql; switch_assert(sqlp && *sqlp); - sql = *sqlp; + sql = *sqlp; - if (profile->sql_queue) { - if (sql_already_dynamic) { - d_sql = sql; - } else { - d_sql = strdup(sql); - } - - switch_assert(d_sql); - if ((status = switch_queue_trypush(profile->sql_queue, d_sql)) == SWITCH_STATUS_SUCCESS) { - d_sql = NULL; - } - } else if (sql_already_dynamic) { - d_sql = sql; - } - - if (status != SWITCH_STATUS_SUCCESS) { - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - } - - switch_safe_free(d_sql); + switch_switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic); if (sql_already_dynamic) { *sqlp = NULL; } } + void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic) { - sofia_glue_actually_execute_sql(profile, *sqlp, profile->ireg_mutex); + char *sql; + + switch_assert(sqlp && *sqlp); + sql = *sqlp; + + switch_switch_sql_queue_manager_push_confirm(profile->qm, sql, 0, !sql_already_dynamic); + if (sql_already_dynamic) { - switch_safe_free(*sqlp); + *sqlp = NULL; } - *sqlp = NULL; } diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index f03584f1c3..42fefe3af8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3619,9 +3619,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, } switch_assert(sql != NULL); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - switch_safe_free(sql); - + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sstr = switch_mprintf("terminated;reason=noresource"); } else { @@ -4522,8 +4520,7 @@ void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now) "sub del sql: %s\n", sql); } - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - switch_safe_free(sql); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } } diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index ca2ff0f5c5..2d54f31bc4 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -695,7 +695,7 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int switch_safe_free(sql); sql = switch_mprintf("delete from sip_registrations where call_id='%q' %s", call_id, sqlextra); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_FALSE); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); switch_safe_free(sqlextra); switch_safe_free(sql); @@ -705,84 +705,80 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) { - char sql[1024]; - - + char *sql; if (now) { - switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires" + sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires" ",user_agent,server_user,server_host,profile_name,network_ip" ",%d from sip_registrations where expires > 0 and expires <= %ld", reboot, (long) now); } else { - switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires" + sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires" ",user_agent,server_user,server_host,profile_name,network_ip" ",%d from sip_registrations where expires > 0", reboot); } sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_del_callback, profile); if (now) { - switch_snprintfv(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%q'", + sql = switch_mprintf("delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%q'", (long) now, mod_sofia_globals.hostname); } else { - switch_snprintfv(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); + sql = switch_mprintf("delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); } - - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + if (now) { - switch_snprintfv(sql, sizeof(sql), "select call_id from sip_shared_appearance_dialogs where hostname='%q' " + sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' " "and profile_name='%s' and expires <= %ld", mod_sofia_globals.hostname, profile->name, (long) now); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sla_dialog_del_callback, profile); - switch_snprintfv(sql, sizeof(sql), "delete from sip_shared_appearance_dialogs where expires > 0 and hostname='%q' and expires <= %ld", + sql = switch_mprintf("delete from sip_shared_appearance_dialogs where expires > 0 and hostname='%q' and expires <= %ld", mod_sofia_globals.hostname, (long) now); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); } if (now) { - switch_snprintfv(sql, sizeof(sql), "delete from sip_presence where expires > 0 and expires <= %ld and hostname='%q'", + sql = switch_mprintf("delete from sip_presence where expires > 0 and expires <= %ld and hostname='%q'", (long) now, mod_sofia_globals.hostname); } else { - switch_snprintfv(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); + sql = switch_mprintf("delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); } - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); if (now) { - switch_snprintfv(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%q'", + sql = switch_mprintf("delete from sip_authentication where expires > 0 and expires <= %ld and hostname='%q'", (long) now, mod_sofia_globals.hostname); } else { - switch_snprintfv(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); + sql = switch_mprintf("delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); } - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - - sofia_presence_check_subscriptions(profile, now); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); if (now) { - switch_snprintfv(sql, sizeof(sql), "delete from sip_dialogs where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%q'", + sql = switch_mprintf("delete from sip_dialogs where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%q'", (long) now, mod_sofia_globals.hostname); } else { - switch_snprintfv(sql, sizeof(sql), "delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); + sql = switch_mprintf("delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); } - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); if (now) { if (sofia_test_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)) { - switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid," + sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid," "expires,user_agent,server_user,server_host,profile_name" " from sip_registrations where hostname='%s' and " "profile_name='%s'", mod_sofia_globals.hostname, profile->name); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nat_callback, profile); } else if (sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) { - switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid," + sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid," "expires,user_agent,server_user,server_host,profile_name" " from sip_registrations where (status like '%%NAT%%' " "or contact like '%%fs_nat=yes%%') and hostname='%s' " @@ -846,37 +842,36 @@ void sofia_reg_check_call_id(sofia_profile_t *profile, const char *call_id) void sofia_reg_check_sync(sofia_profile_t *profile) { - char sql[1024]; + char *sql; - - switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires" + sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires" ",user_agent,server_user,server_host,profile_name,network_ip" " from sip_registrations where expires > 0"); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_del_callback, profile); - switch_snprintfv(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sql = switch_mprintf("delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - switch_snprintfv(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sql = switch_mprintf("delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - switch_snprintfv(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sql = switch_mprintf("delete from sip_authentication where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - switch_snprintfv(sql, sizeof(sql), "delete from sip_subscriptions where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sql = switch_mprintf("delete from sip_subscriptions where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - switch_snprintfv(sql, sizeof(sql), "delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); + sql = switch_mprintf("delete from sip_dialogs where expires >= -1 and hostname='%q'", mod_sofia_globals.hostname); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const char *host, char *val, switch_size_t len) { struct callback_t cbt = { 0 }; - char sql[512] = ""; + char *sql; if (!user) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n"); @@ -887,10 +882,10 @@ char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const c cbt.len = len; if (host) { - switch_snprintfv(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", + sql = switch_mprintf("select contact from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", user, host, host); } else { - switch_snprintfv(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%q'", user); + sql = switch_mprintf("select contact from sip_registrations where sip_user='%q'", user); } @@ -908,7 +903,7 @@ char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const c switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host) { struct callback_t cbt = { 0 }; - char sql[512] = ""; + char *sql; if (!user) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n"); @@ -916,10 +911,10 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p } if (host) { - switch_snprintfv(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", + sql = switch_mprintf("select contact from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", user, host, host); } else { - switch_snprintfv(sql, sizeof(sql), "select contact from sip_registrations where sip_user='%q'", user); + sql = switch_mprintf("select contact from sip_registrations where sip_user='%q'", user); } @@ -932,7 +927,7 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host) { struct callback_t cbt = { 0 }; - char sql[512] = ""; + char *sql; if (!user) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Called with null user!\n"); @@ -940,10 +935,10 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_mu } if (host) { - switch_snprintfv(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", + sql = switch_mprintf("select contact,expires from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", user, host, host); } else { - switch_snprintfv(sql, sizeof(sql), "select contact,expires from sip_registrations where sip_user='%q'", user); + sql = switch_mprintf("select contact,expires from sip_registrations where sip_user='%q'", user); } sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_reg_with_positive_expires_callback, &cbt); @@ -973,8 +968,7 @@ void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_ (long) switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : DEFAULT_NONCE_TTL), profile->name, mod_sofia_globals.hostname); switch_assert(sql != NULL); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - switch_safe_free(sql); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : ""); @@ -2802,8 +2796,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, switch_epoch_time_now(NULL) + (profile->nonce_ttl ? profile->nonce_ttl : exptime + 10), ncl, nonce); switch_assert(sql != NULL); - sofia_glue_actually_execute_sql(profile, sql, profile->ireg_mutex); - switch_safe_free(sql); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); if (ret == AUTH_OK) ret = AUTH_RENEWED; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 4c16fadc51..4148267da6 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1530,25 +1530,25 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_th } if (check_status == SWITCH_STATUS_SUCCESS) { - switch_core_session_t *session = (switch_core_session_t *) pop; - switch_size_t id; + switch_thread_data_t *td = (switch_thread_data_t *) pop; - if (!session) break; + if (!td) break; - id = session->id; - switch_mutex_lock(session_manager.mutex); session_manager.busy++; switch_mutex_unlock(session_manager.mutex); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing session %"SWITCH_SIZE_T_FMT" %s\n", - (long) thread, id, switch_core_session_get_name(session)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing\n", (long) thread); - switch_core_session_thread(thread, (void *) session); + + td->func(thread, td->obj); + + if (td->alloc) { + free(td); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing\n", (long) thread); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Done Processing session %"SWITCH_SIZE_T_FMT"\n", - (long) thread, id); - switch_mutex_lock(session_manager.mutex); session_manager.busy--; switch_mutex_unlock(session_manager.mutex); @@ -1656,11 +1656,27 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_t return NULL; } +SWITCH_DECLARE(switch_status_t) switch_thread_pool_launch_thread(switch_thread_data_t **tdp) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_thread_data_t *td; + + switch_assert(tdp); + + td = *tdp; + *tdp = NULL; + + switch_queue_push(session_manager.thread_queue, td); + check_queue(); + + return status; +} SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_core_session_t *session) { switch_status_t status = SWITCH_STATUS_INUSE; - + switch_thread_data_t *td; + switch_mutex_lock(session->mutex); if (switch_test_flag(session, SSF_THREAD_RUNNING)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n"); @@ -1670,7 +1686,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_co status = SWITCH_STATUS_SUCCESS; switch_set_flag(session, SSF_THREAD_RUNNING); switch_set_flag(session, SSF_THREAD_STARTED); - switch_queue_push(session_manager.thread_queue, session); + td = switch_core_session_alloc(session, sizeof(*td)); + td->obj = session; + td->func = switch_core_session_thread; + switch_queue_push(session_manager.thread_queue, td); check_queue(); } switch_mutex_unlock(session->mutex); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 80ab68c110..2ebfd5b464 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1214,14 +1214,19 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *threa static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, void *obj); struct switch_sql_queue_manager { + const char *name; switch_cache_db_handle_t *event_db; switch_queue_t **sql_queue; + uint32_t *pre_written; + uint32_t *written; + int *sizes; uint32_t numq; char *dsn; switch_thread_t *thread; int thread_running; switch_thread_cond_t *cond; switch_mutex_t *cond_mutex; + switch_mutex_t *mutex; char *pre_trans_execute; char *post_trans_execute; char *inner_pre_trans_execute; @@ -1229,12 +1234,15 @@ struct switch_sql_queue_manager { switch_memory_pool_t *pool; }; -static void qm_wake(switch_sql_queue_manager_t *qm) +static int qm_wake(switch_sql_queue_manager_t *qm) { if (switch_mutex_trylock(qm->cond_mutex) == SWITCH_STATUS_SUCCESS) { switch_thread_cond_signal(qm->cond); switch_mutex_unlock(qm->cond_mutex); + return 1; } + + return 0; } static uint32_t qm_ttl(switch_sql_queue_manager_t *qm) @@ -1335,15 +1343,59 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push(switch_sql_ } +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) +{ + int want, size, x = 0, sanity = 0; + uint32_t written; + + if (!qm->thread_running) { + return SWITCH_STATUS_FALSE; + } + + if (sql_manager.thread_running != 1) { + return SWITCH_STATUS_FALSE; + } + + if (pos > qm->numq - 1) { + pos = 0; + } + + switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql); + + switch_mutex_lock(qm->mutex); + written = qm->written[pos]; + size = qm->sizes[pos]; + want = written + size; + switch_mutex_unlock(qm->mutex); + + qm_wake(qm); + + while((qm->written[pos] < want) || (qm->written[pos] >= written && want < written && qm->written[pos] > want)) { + switch_yield(5000); + + if (++x == 200) { + qm_wake(qm); + x = 0; + if (++sanity == 20) { + break; + } + } + } + + return SWITCH_STATUS_SUCCESS; +} -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init(switch_sql_queue_manager_t **qmp, - uint32_t numq, const char *dsn, - const char *pre_trans_execute, - const char *post_trans_execute, - const char *inner_pre_trans_execute, - const char *inner_post_trans_execute) + + +SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init_name(const char *name, + switch_sql_queue_manager_t **qmp, + uint32_t numq, const char *dsn, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute) { switch_memory_pool_t *pool; switch_sql_queue_manager_t *qm; @@ -1357,11 +1409,16 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init(switch_sql_ qm->pool = pool; qm->numq = numq; qm->dsn = switch_core_strdup(qm->pool, dsn); + qm->name = switch_core_strdup(qm->pool, name); switch_mutex_init(&qm->cond_mutex, SWITCH_MUTEX_NESTED, qm->pool); + switch_mutex_init(&qm->mutex, SWITCH_MUTEX_NESTED, qm->pool); switch_thread_cond_create(&qm->cond, qm->pool); qm->sql_queue = switch_core_alloc(qm->pool, sizeof(switch_queue_t *) * numq); + qm->sizes = switch_core_alloc(qm->pool, sizeof(int) * numq); + qm->written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); + qm->pre_written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); for (i = 0; i < qm->numq; i++) { switch_queue_create(&qm->sql_queue[i], SWITCH_SQL_QUEUE_LEN, qm->pool); @@ -1400,13 +1457,13 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, while (!qm->event_db) { if (switch_cache_db_get_db_handle_dsn(&qm->event_db, qm->dsn) == SWITCH_STATUS_SUCCESS && qm->event_db) break; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error getting core db, Retrying\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Error getting db handle, Retrying\n", qm->name); switch_yield(500000); sanity--; } if (!qm->event_db) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error getting core db\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s Error getting db handle\n", qm->name); return NULL; } @@ -1431,14 +1488,19 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, while (qm->thread_running == 1) { int proceed = !!save_sql; + int pindex = -1; if (!proceed) { for (i = 0; i < qm->numq; i++) { if (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { if (sql_manager.thread_running != 1) { - free(pop); - pop = NULL; + if (pop) { + switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL); + free(pop); + pop = NULL; + } } else { + pindex = i; proceed = 1; break; } @@ -1470,7 +1532,8 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { for (i = 0; i < qm->numq; i++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "REALLOC QUEUE %ld %d %d\n", + "%s REALLOC QUEUE %ld %d %d\n", + qm->name, (long int)sql_len, i, switch_queue_size(qm->sql_queue[i])); @@ -1478,7 +1541,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, } } if (!(tmp = realloc(sqlbuf, sql_len))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s SQL thread ending on mem err\n", qm->name); abort(); break; } @@ -1487,7 +1550,8 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { for (i = 0; i < qm->numq; i++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "SAVE QUEUE %d %d\n", + "%s SAVE QUEUE %d %d\n", + qm->name, i, switch_queue_size(qm->sql_queue[i])); @@ -1499,6 +1563,10 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, goto skip; } } + + switch_mutex_lock(qm->mutex); + qm->pre_written[pindex]++; + switch_mutex_unlock(qm->mutex); iterations++; sprintf(sqlbuf + len, "%s;\n", sql); @@ -1506,7 +1574,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, free(sql); sql = NULL; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "SQL thread ending\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s, SQL thread ending\n", qm->name); break; } } @@ -1519,14 +1587,14 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, auto_pause = 1; switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); auto_pause = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue overflowing [%d], Pausing calls.\n", lc); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s, SQL Queue overflowing [%d], Pausing calls.\n", qm->name, lc); } } else { if (auto_pause && lc < 1000) { auto_pause = 0; switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); auto_pause = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue back to normal size, resuming..\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s, SQL Queue back to normal size, resuming..\n", qm->name); } } @@ -1535,14 +1603,23 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, wrote = 0; if (trans && iterations && (iterations > target || !lc)) { + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + char line[128] = ""; + int l; + + switch_snprintf(line, sizeof(line), "%s RUN QUEUE ", qm->name); + for (i = 0; i < qm->numq; i++) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "RUN QUEUE %d %d %d\n", - i, - switch_queue_size(qm->sql_queue[i]), - iterations); + l = strlen(line); + switch_snprintf(line + l, sizeof(line) - l, "%d:%d ", i, switch_queue_size(qm->sql_queue[i])); } + + l = strlen(line); + switch_snprintf(line + l, sizeof(line) - l, "%d\n", iterations); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s", line); + } if (switch_cache_db_persistant_execute_trans_full(qm->event_db, sqlbuf, 1, qm->pre_trans_execute, @@ -1550,13 +1627,12 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, qm->inner_pre_trans_execute, qm->inner_post_trans_execute ) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s SQL thread unable to commit transaction, records lost!\n", qm->name); } if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DONE\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s DONE\n", qm->name); } - iterations = 0; trans = 0; len = 0; @@ -1572,6 +1648,14 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, lc = qm_ttl(qm); + switch_mutex_lock(qm->mutex); + for (i = 0; i < qm->numq; i++) { + qm->sizes[i] = switch_queue_size(qm->sql_queue[i]); + qm->written[i] += qm->pre_written[i]; + qm->pre_written[i] = 0; + } + switch_mutex_unlock(qm->mutex); + if (!lc) { switch_thread_cond_wait(qm->cond, qm->cond_mutex); } else if (wrote) { @@ -1587,7 +1671,10 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, for(i = 0; i < qm->numq; i++) { while (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { - switch_safe_free(pop); + if (pop) { + switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL); + free(pop); + } } } From b29412054ab1ce7c4a69a74ed310feefc928bd44 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 12:30:08 -0500 Subject: [PATCH 254/512] fold reconfig_sofia into config_sofia so we don't have 2 difft config funcs --- src/mod/endpoints/mod_sofia/mod_sofia.c | 11 +- src/mod/endpoints/mod_sofia/mod_sofia.h | 10 +- src/mod/endpoints/mod_sofia/sofia.c | 1022 +++-------------------- 3 files changed, 150 insertions(+), 893 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 898b5e49ed..31adce6f18 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3636,7 +3636,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t switch_xml_reload(&err); stream->write_function(stream, "Reload XML [%s]\n", err); - if (config_sofia(1, argv[0]) == SWITCH_STATUS_SUCCESS) { + if (config_sofia(SOFIA_CONFIG_RESCAN, argv[0]) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "%s started successfully\n", argv[0]); } else { stream->write_function(stream, "Failure starting %s\n", argv[0]); @@ -3713,7 +3713,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t switch_xml_reload(&err); stream->write_function(stream, "Reload XML [%s]\n", err); - if (reconfig_sofia(profile) == SWITCH_STATUS_SUCCESS) { + if (config_sofia(SOFIA_CONFIG_RESCAN, profile->name) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "+OK scan complete\n"); } else { stream->write_function(stream, "-ERR cannot find config for profile %s\n", profile->name); @@ -5707,8 +5707,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) /* start one message thread */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting initial message thread.\n"); sofia_msg_thread_start(0); + - if (config_sofia(0, NULL) != SWITCH_STATUS_SUCCESS) { + if (sofia_init() != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_GENERR; + } + + if (config_sofia(SOFIA_CONFIG_LOAD, NULL) != SWITCH_STATUS_SUCCESS) { mod_sofia_globals.running = 0; return SWITCH_STATUS_GENERR; } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index f01a121608..799574da84 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -138,6 +138,12 @@ typedef struct private_object private_object_t; #include #include +typedef enum { + SOFIA_CONFIG_LOAD = 0, + SOFIA_CONFIG_RESCAN, + SOFIA_CONFIG_RESPAWN +} sofia_config_t; + typedef enum { DTMF_2833, DTMF_INFO, @@ -966,7 +972,7 @@ void sofia_presence_event_handler(switch_event_t *event); void sofia_presence_cancel(void); -switch_status_t config_sofia(int reload, char *profile_name); +switch_status_t config_sofia(sofia_config_t reload, char *profile_name); void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_regtype_t regtype, const char *realm, int stale); auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, @@ -1118,7 +1124,6 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int force); char *sofia_glue_get_register_host(const char *uri); const char *sofia_glue_strip_proto(const char *uri); -switch_status_t reconfig_sofia(sofia_profile_t *profile); void sofia_glue_del_gateway(sofia_gateway_t *gp); void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up); void sofia_glue_del_every_gateway(sofia_profile_t *profile); @@ -1199,6 +1204,7 @@ void crtp_init(switch_loadable_module_interface_t *module_interface); int sofia_recover_callback(switch_core_session_t *session); void sofia_glue_set_name(private_object_t *tech_pvt, const char *channame); private_object_t *sofia_glue_new_pvt(switch_core_session_t *session); +switch_status_t sofia_init(void); /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index d463345f7c..b8a093bf25 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2672,7 +2672,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write unlock %s\n", profile->name); if (sofia_test_pflag(profile, PFLAG_RESPAWN)) { - config_sofia(1, profile->name); + config_sofia(SOFIA_CONFIG_RESPAWN, profile->name); } sofia_profile_destroy(profile); @@ -3389,799 +3389,34 @@ static void config_sofia_profile_urls(sofia_profile_t * profile) } } -switch_status_t reconfig_sofia(sofia_profile_t *profile) +switch_status_t sofia_init(void) { - switch_xml_t cfg, xml = NULL, xprofile, profiles, gateways_tag, domain_tag, domains_tag, aliases_tag, alias_tag, settings, param; - char *cf = "sofia.conf"; - switch_event_t *params = NULL; - switch_status_t status = SWITCH_STATUS_FALSE; - - switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(params); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->name); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true"); - - if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); - status = SWITCH_STATUS_FALSE; - goto done; + su_init(); + if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) { + su_deinit(); + return SWITCH_STATUS_GENERR; } - if ((settings = switch_xml_child(cfg, "global_settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if (!strcasecmp(var, "log-level")) { - su_log_set_level(NULL, atoi(val)); - } else if (!strcasecmp(var, "tracelevel")) { - mod_sofia_globals.tracelevel = switch_log_str2level(val); - } else if (!strcasecmp(var, "debug-presence")) { - mod_sofia_globals.debug_presence = atoi(val); - } else if (!strcasecmp(var, "debug-sla")) { - mod_sofia_globals.debug_sla = atoi(val); - } else if (!strcasecmp(var, "auto-restart")) { - mod_sofia_globals.auto_restart = switch_true(val); - } else if (!strcasecmp(var, "reg-deny-binding-fetch-and-no-lookup")) { /* backwards compatibility */ - mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */ - if (switch_true(val)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is " - "deprecated and will be removed - let FS devs know if you think it should stay\n"); - } - } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) { - if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) { - /* old behaviour */ - mod_sofia_globals.rewrite_multicasted_fs_path = 1; - } else if (!strcasecmp(val, "original_server_host")) { - mod_sofia_globals.rewrite_multicasted_fs_path = 2; - } else if (!strcasecmp(val, "original_hostname")) { - mod_sofia_globals.rewrite_multicasted_fs_path = 3; - } else { - mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE; - } - } - else if (!strcasecmp(var, "capture-server")) { - mod_sofia_globals.capture_server = switch_core_strdup(mod_sofia_globals.pool, val); - } - } - } - - if ((profiles = switch_xml_child(cfg, "profiles"))) { - for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) { - char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name"); - char *xprofiledomain = (char *) switch_xml_attr(xprofile, "domain"); - - if (strcasecmp(profile->name, xprofilename)) { - continue; - } - - /* you could change profile->foo here if it was a minor change like context or dialplan ... */ - profile->acl_count = 0; - profile->nat_acl_count = 0; - profile->reg_acl_count = 0; - profile->proxy_acl_count = 0; - sofia_set_pflag(profile, PFLAG_STUN_ENABLED); - sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); - profile->ib_calls = 0; - profile->ob_calls = 0; - profile->ib_failed_calls = 0; - profile->ob_failed_calls = 0; - profile->shutdown_type = "false"; - - if (xprofiledomain) { - profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain); - } - - if ((settings = switch_xml_child(xprofile, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - if (!strcasecmp(var, "debug")) { - profile->debug = atoi(val); - } else if (!strcasecmp(var, "shutdown-on-fail")) { - profile->shutdown_type = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "pass-callee-id")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); - } else { - sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID); - } - } else if (!strcasecmp(var, "rtp-digit-delay")) { - int delay = val ? atoi(val) : 0; - - if (delay < 0) delay = 0; - - profile->rtp_digit_delay = (uint32_t) delay; - } else if (!strcasecmp(var, "watchdog-enabled")) { - profile->watchdog_enabled = switch_true(val); - } else if (!strcasecmp(var, "watchdog-step-timeout")) { - profile->step_timeout = (unsigned long) atol(val); - } else if (!strcasecmp(var, "watchdog-event-timeout")) { - profile->event_timeout = (unsigned long) atol(val); - } else if (!strcasecmp(var, "in-dialog-chat")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT); - } else { - sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT); - } - } else if (!strcasecmp(var, "fire-message-events")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS); - } else { - sofia_clear_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS); - } - } else if (!strcasecmp(var, "disable-hold")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_DISABLE_HOLD); - } else { - sofia_clear_pflag(profile, PFLAG_DISABLE_HOLD); - } - } else if (!strcasecmp(var, "auto-jitterbuffer-msec")) { - int msec = atoi(val); - if (msec > 19) { - profile->jb_msec = switch_core_strdup(profile->pool, val); - } - } else if (!strcasecmp(var, "sip-trace")) { - if (switch_true(val)) { - sofia_set_flag(profile, TFLAG_TPORT_LOG); - } else { - sofia_clear_flag(profile, TFLAG_TPORT_LOG); - } - nua_set_params(profile->nua, TPTAG_LOG(sofia_test_flag(profile, TFLAG_TPORT_LOG)), TAG_END()); - } else if (!strcasecmp(var, "sip-capture")) { - if (switch_true(val)) { - sofia_set_flag(profile, TFLAG_CAPTURE); - } else { - sofia_clear_flag(profile, TFLAG_CAPTURE); - } - nua_set_params(profile->nua, TPTAG_CAPT(sofia_test_flag(profile, TFLAG_CAPTURE) ? mod_sofia_globals.capture_server : NULL), TAG_END()); - } else if (!strcasecmp(var, "send-message-query-on-register")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER); - } else if (!strcasecmp(val, "first-only")) { - sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER); - sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); - } else { - sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER); - sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); - } - } else if (!strcasecmp(var, "auto-rtp-bugs")) { - sofia_glue_parse_rtp_bugs(&profile->auto_rtp_bugs, val); - } else if (!strcasecmp(var, "manual-rtp-bugs")) { - sofia_glue_parse_rtp_bugs(&profile->manual_rtp_bugs, val); - } else if (!strcasecmp(var, "registration-thread-frequency")) { - profile->ireg_seconds = atoi(val); - if (profile->ireg_seconds < 0) { - profile->ireg_seconds = IREG_SECONDS; - } - } else if (!strcasecmp(var, "user-agent-string")) { - profile->user_agent = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "auto-restart")) { - profile->auto_restart = switch_true(val); - } else if (!strcasecmp(var, "log-auth-failures")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_LOG_AUTH_FAIL); - } else { - sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL); - } - } else if (!strcasecmp(var, "confirm-blind-transfer")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER); - } else { - sofia_clear_pflag(profile, PFLAG_CONFIRM_BLIND_TRANSFER); - } - } else if (!strcasecmp(var, "send-display-update")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE); - } else { - sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE); - } - } else if (!strcasecmp(var, "mwi-use-reg-callid")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_MWI_USE_REG_CALLID); - } else { - sofia_clear_pflag(profile, PFLAG_MWI_USE_REG_CALLID); - } - } else if (!strcasecmp(var, "presence-proto-lookup")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_PRESENCE_MAP); - } else { - sofia_clear_pflag(profile, PFLAG_PRESENCE_MAP); - } - } else if (!strcasecmp(var, "profile-standby")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_STANDBY); - } else { - sofia_clear_pflag(profile, PFLAG_STANDBY); - } - } else if (!strcasecmp(var, "liberal-dtmf")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_LIBERAL_DTMF); - } else { - sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF); - } - } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); - } else { - sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); - } - } else if (!strcasecmp(var, "t38-passthru")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_T38_PASSTHRU); - } else { - sofia_clear_pflag(profile, PFLAG_T38_PASSTHRU); - } - } else if (!strcasecmp(var, "presence-disable-early")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY); - } else { - sofia_clear_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY); - } - } else if (!strcasecmp(var, "ignore-183nosdp")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_IGNORE_183NOSDP); - } else { - sofia_clear_pflag(profile, PFLAG_IGNORE_183NOSDP); - } - } else if (!strcasecmp(var, "renegotiate-codec-on-hold")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_RENEG_ON_HOLD); - } else { - sofia_clear_pflag(profile, PFLAG_RENEG_ON_HOLD); - } - } else if (!strcasecmp(var, "renegotiate-codec-on-reinvite")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_RENEG_ON_REINVITE); - } else { - sofia_clear_pflag(profile, PFLAG_RENEG_ON_REINVITE); - } - } else if (!strcasecmp(var, "presence-probe-on-register")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER); - } else { - sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER); - } - - } else if (!strcasecmp(var, "send-presence-on-register")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); - } else if (!strcasecmp(val, "first-only")) { - sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); - sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); - } else { - sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); - sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); - } - } else if (!strcasecmp(var, "cid-in-1xx")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_CID_IN_1XX); - } else { - sofia_clear_pflag(profile, PFLAG_CID_IN_1XX); - } - } else if (!strcasecmp(var, "dtmf-type")) { - if (!strcasecmp(val, "rfc2833")) { - profile->dtmf_type = DTMF_2833; - } else if (!strcasecmp(val, "info")) { - profile->dtmf_type = DTMF_INFO; - } else { - profile->dtmf_type = DTMF_NONE; - } - } else if (!strcasecmp(var, "caller-id-type")) { - profile->cid_type = sofia_cid_name2type(val); - } else if (!strcasecmp(var, "record-template")) { - profile->record_template = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "record-path")) { - profile->record_path = switch_core_strdup(profile->pool, val); - } else if ((!strcasecmp(var, "inbound-no-media") || !strcasecmp(var, "inbound-bypass-media"))) { - if (switch_true(val)) { - sofia_set_flag(profile, TFLAG_INB_NOMEDIA); - } else { - sofia_clear_flag(profile, TFLAG_INB_NOMEDIA); - } - } else if (!strcasecmp(var, "force-subscription-expires")) { - int tmp = atoi(val); - if (tmp > 0) { - profile->force_subscription_expires = tmp; - } - } else if (!strcasecmp(var, "force-publish-expires")) { - int tmp = atoi(val); - if (tmp > 0) { - profile->force_publish_expires = tmp; - } - } else if (!strcasecmp(var, "inbound-late-negotiation")) { - if (switch_true(val)) { - sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION); - } else { - sofia_clear_flag(profile, TFLAG_LATE_NEGOTIATION); - } - } else if (!strcasecmp(var, "inbound-proxy-media")) { - if (switch_true(val)) { - sofia_set_flag(profile, TFLAG_PROXY_MEDIA); - } else { - sofia_clear_flag(profile, TFLAG_PROXY_MEDIA); - } - } else if (!strcasecmp(var, "inbound-zrtp-passthru")) { - if (switch_true(val)) { - sofia_set_flag(profile, TFLAG_ZRTP_PASSTHRU); - } else { - sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU); - } - } else if (!strcasecmp(var, "inbound-use-callid-as-uuid")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_CALLID_AS_UUID); - } else { - sofia_clear_pflag(profile, PFLAG_CALLID_AS_UUID); - } - } else if (!strcasecmp(var, "inbound-reg-in-new-thread")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_THREAD_PER_REG); - } else { - sofia_clear_pflag(profile, PFLAG_THREAD_PER_REG); - } - } else if (!strcasecmp(var, "rtp-autoflush-during-bridge")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); - } else { - sofia_clear_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); - } - } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); - } else { - sofia_clear_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); - } - } else if (!strcasecmp(var, "manual-redirect")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_MANUAL_REDIRECT); - } else { - sofia_clear_pflag(profile, PFLAG_MANUAL_REDIRECT); - } - } else if (!strcasecmp(var, "outbound-use-uuid-as-callid")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_UUID_AS_CALLID); - } else { - sofia_clear_pflag(profile, PFLAG_UUID_AS_CALLID); - } - } else if (!strcasecmp(var, "NDLB-received-in-nat-reg-contact")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT); - } else { - sofia_clear_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT); - } - } else if (!strcasecmp(var, "NDLB-allow-bad-iananame")) { - if (switch_true(val)) { - profile->ndlb |= PFLAG_NDLB_ALLOW_BAD_IANANAME; - } else { - profile->ndlb &= ~PFLAG_NDLB_ALLOW_BAD_IANANAME; - } - } else if (!strcasecmp(var, "NDLB-expires-in-register-response")) { - if (switch_true(val)) { - profile->ndlb |= PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE; - } else { - profile->ndlb &= ~PFLAG_NDLB_EXPIRES_IN_REGISTER_RESPONSE; - } - } else if (!strcasecmp(var, "NDLB-allow-crypto-in-avp")) { - if (switch_true(val)) { - profile->ndlb |= PFLAG_NDLB_ALLOW_CRYPTO_IN_AVP; - } else { - profile->ndlb &= ~PFLAG_NDLB_ALLOW_CRYPTO_IN_AVP; - } - } else if (!strcasecmp(var, "NDLB-allow-nondup-sdp")) { - if (switch_true(val)) { - profile->ndlb |= PFLAG_NDLB_ALLOW_NONDUP_SDP; - } else { - profile->ndlb &= ~PFLAG_NDLB_ALLOW_NONDUP_SDP; - } - } else if (!strcasecmp(var, "aggressive-nat-detection")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION); - } else { - sofia_clear_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION); - } - } else if (!strcasecmp(var, "disable-rtp-auto-adjust")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_DISABLE_RTP_AUTOADJ); - } else { - sofia_clear_pflag(profile, PFLAG_DISABLE_RTP_AUTOADJ); - } - } else if (!strcasecmp(var, "NDLB-support-asterisk-missing-srtp-auth")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_DISABLE_SRTP_AUTH); - } else { - sofia_clear_pflag(profile, PFLAG_DISABLE_SRTP_AUTH); - } - } else if (!strcasecmp(var, "NDLB-funny-stun")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_FUNNY_STUN); - } else { - sofia_clear_pflag(profile, PFLAG_FUNNY_STUN); - } - } else if (!strcasecmp(var, "stun-enabled")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_STUN_ENABLED); - } else { - sofia_clear_pflag(profile, PFLAG_STUN_ENABLED); - } - } else if (!strcasecmp(var, "stun-auto-disable")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_STUN_AUTO_DISABLE); - } else { - sofia_clear_pflag(profile, PFLAG_STUN_AUTO_DISABLE); - } - } else if (!strcasecmp(var, "apply-nat-acl")) { - if (profile->nat_acl_count < SOFIA_MAX_ACL) { - if (!profile->extsipip && switch_check_network_list_ip(profile->sipip, val)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val); - } else { - profile->nat_acl[profile->nat_acl_count++] = switch_core_strdup(profile->pool, val); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); - } - } else if (!strcasecmp(var, "apply-inbound-acl")) { - if (profile->acl_count < SOFIA_MAX_ACL) { - char *list, *pass = NULL, *fail = NULL; - - list = switch_core_strdup(profile->pool, val); - - if ((pass = strchr(list, ':'))) { - *pass++ = '\0'; - if ((fail = strchr(pass, ':'))) { - *fail++ = '\0'; - } - - if (zstr(pass)) pass = NULL; - if (zstr(fail)) fail = NULL; - - profile->acl_pass_context[profile->acl_count] = pass; - profile->acl_fail_context[profile->acl_count] = fail; - } - - profile->acl[profile->acl_count++] = list; - - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); - } - } else if (!strcasecmp(var, "apply-proxy-acl")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "apply proxy acl [%s]\n", val); - if (profile->proxy_acl_count < SOFIA_MAX_ACL) { - profile->proxy_acl[profile->proxy_acl_count++] = switch_core_strdup(profile->pool, val); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); - } - } else if (!strcasecmp(var, "apply-register-acl")) { - if (profile->reg_acl_count < SOFIA_MAX_ACL) { - profile->reg_acl[profile->reg_acl_count++] = switch_core_strdup(profile->pool, val); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL); - } - } else if (!strcasecmp(var, "user-agent-filter")) { - profile->user_agent_filter = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "max-registrations-per-extension")) { - profile->max_registrations_perext = atoi(val); - } else if (!strcasecmp(var,"presence-privacy")) { - profile->presence_privacy = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "rfc2833-pt")) { - profile->te = (switch_payload_t) atoi(val); - } else if (!strcasecmp(var, "cng-pt") && !(sofia_test_pflag(profile, PFLAG_SUPPRESS_CNG))) { - profile->cng_pt = (switch_payload_t) atoi(val); - } else if (!strcasecmp(var, "vad")) { - if (!strcasecmp(val, "in")) { - sofia_set_flag(profile, TFLAG_VAD_IN); - } else if (!strcasecmp(val, "out")) { - sofia_set_flag(profile, TFLAG_VAD_OUT); - } else if (!strcasecmp(val, "both")) { - sofia_set_flag(profile, TFLAG_VAD_IN); - sofia_set_flag(profile, TFLAG_VAD_OUT); - } else if (strcasecmp(val, "none")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid option %s for VAD\n", val); - } - } else if (!strcasecmp(var, "unregister-on-options-fail")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL); - } else { - sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL); - } - } else if (!strcasecmp(var, "require-secure-rtp")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_SECURE); - } else { - sofia_clear_pflag(profile, PFLAG_SECURE); - } - } else if (!strcasecmp(var, "multiple-registrations")) { - if (!strcasecmp(val, "call-id")) { - sofia_set_pflag(profile, PFLAG_MULTIREG); - } else if (!strcasecmp(val, "contact") || switch_true(val)) { - sofia_set_pflag(profile, PFLAG_MULTIREG); - sofia_set_pflag(profile, PFLAG_MULTIREG_CONTACT); - } else if (switch_true(val)) { - sofia_clear_pflag(profile, PFLAG_MULTIREG); - //sofia_clear_pflag(profile, PFLAG_MULTIREG_CONTACT); - } - } else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_SUPPRESS_CNG); - profile->cng_pt = 0; - } else { - sofia_clear_pflag(profile, PFLAG_SUPPRESS_CNG); - } - } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) { - if (switch_true(val)) { - profile->ndlb |= PFLAG_NDLB_BROKEN_AUTH_HASH; - } else { - profile->ndlb &= ~PFLAG_NDLB_BROKEN_AUTH_HASH; - } - } else if (!strcasecmp(var, "NDLB-sendrecv-in-session")) { - if (switch_true(val)) { - profile->ndlb |= PFLAG_NDLB_SENDRECV_IN_SESSION; - } else { - profile->ndlb &= ~PFLAG_NDLB_SENDRECV_IN_SESSION; - } - } else if (!strcasecmp(var, "pass-rfc2833")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_PASS_RFC2833); - } else { - sofia_clear_pflag(profile, PFLAG_PASS_RFC2833); - } - } else if (!strcasecmp(var, "rtp-autoflush")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_AUTOFLUSH); - } else { - sofia_clear_pflag(profile, PFLAG_AUTOFLUSH); - } - } else if (!strcasecmp(var, "rtp-autofix-timing")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_AUTOFIX_TIMING); - } else { - sofia_clear_pflag(profile, PFLAG_AUTOFIX_TIMING); - } - } else if (!strcasecmp(var, "nat-options-ping")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_NAT_OPTIONS_PING); - } else { - sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING); - } - } else if (!strcasecmp(var, "all-reg-options-ping")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING); - } else { - sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING); - } - } else if (!strcasecmp(var, "inbound-codec-negotiation")) { - if (!strcasecmp(val, "greedy")) { - sofia_set_pflag(profile, PFLAG_GREEDY); - } else if (!strcasecmp(val, "scrooge")) { - sofia_set_pflag(profile, PFLAG_GREEDY); - sofia_set_pflag(profile, PFLAG_SCROOGE); - } else { - sofia_clear_pflag(profile, PFLAG_SCROOGE); - sofia_clear_pflag(profile, PFLAG_GREEDY); - } - } else if (!strcasecmp(var, "disable-transcoding")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_DISABLE_TRANSCODING); - } else { - sofia_clear_pflag(profile, PFLAG_DISABLE_TRANSCODING); - } - } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_REWRITE_TIMESTAMPS); - } else { - sofia_clear_pflag(profile, PFLAG_REWRITE_TIMESTAMPS); - } - } else if (!strcasecmp(var, "auth-calls")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_AUTH_CALLS); - } else { - sofia_clear_pflag(profile, PFLAG_AUTH_CALLS); - } - } else if (!strcasecmp(var, "extended-info-parsing")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_EXTENDED_INFO_PARSING); - } else { - sofia_clear_pflag(profile, PFLAG_EXTENDED_INFO_PARSING); - } - } else if (!strcasecmp(var, "context")) { - profile->context = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "local-network-acl")) { - if (!strcasecmp(val, "none")) { - profile->local_network = NULL; - } else { - profile->local_network = switch_core_strdup(profile->pool, val); - } - } else if (!strcasecmp(var, "force-register-domain")) { - profile->reg_domain = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "force-subscription-domain")) { - profile->sub_domain = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "force-register-db-domain")) { - profile->reg_db_domain = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "hold-music")) { - profile->hold_music = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "outbound-proxy")) { - profile->outbound_proxy = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "rtcp-audio-interval-msec")) { - profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "rtcp-video-interval-msec")) { - profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "session-timeout")) { - int v_session_timeout = atoi(val); - if (v_session_timeout >= 0) { - profile->session_timeout = v_session_timeout; - } - } else if (!strcasecmp(var, "rtp-timeout-sec")) { - int v = atoi(val); - if (v >= 0) { - profile->rtp_timeout_sec = v; - } - } else if (!strcasecmp(var, "rtp-hold-timeout-sec")) { - int v = atoi(val); - if (v >= 0) { - profile->rtp_hold_timeout_sec = v; - } - } else if (!strcasecmp(var, "nonce-ttl")) { - profile->nonce_ttl = atoi(val); - } else if (!strcasecmp(var, "dialplan")) { - profile->dialplan = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "max-calls")) { - profile->max_calls = atoi(val); - } else if (!strcasecmp(var, "codec-prefs")) { - profile->inbound_codec_string = switch_core_strdup(profile->pool, val); - profile->outbound_codec_string = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "inbound-codec-prefs")) { - profile->inbound_codec_string = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "outbound-codec-prefs")) { - profile->outbound_codec_string = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "challenge-realm")) { - profile->challenge_realm = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "dtmf-duration")) { - uint32_t dur = atoi(val); - if (dur >= switch_core_min_dtmf_duration(0) && dur <= switch_core_max_dtmf_duration(0)) { - profile->dtmf_duration = dur; - } else { - profile->dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Duration out of bounds, using default of %d!\n", - SWITCH_DEFAULT_DTMF_DURATION); - } - } else if (!strcasecmp(var, "timer-T1")) { - int v = atoi(val); - if (v > 0) { - profile->timer_t1 = v; - } else { - profile->timer_t1 = 500; - } - nua_set_params(profile->nua, NTATAG_SIP_T1(profile->timer_t1), TAG_END()); - } else if (!strcasecmp(var, "timer-T1X64")) { - int v = atoi(val); - if (v > 0) { - profile->timer_t1x64 = v; - } else { - profile->timer_t1x64 = 32000; - } - nua_set_params(profile->nua, NTATAG_SIP_T1X64(profile->timer_t1x64), TAG_END()); - } else if (!strcasecmp(var, "timer-T2")) { - int v = atoi(val); - if (v > 0) { - profile->timer_t2 = v; - } else { - profile->timer_t2 = 4000; - } - nua_set_params(profile->nua, NTATAG_SIP_T2(profile->timer_t2), TAG_END()); - } else if (!strcasecmp(var, "timer-T4")) { - int v = atoi(val); - if (v > 0) { - profile->timer_t4 = v; - } else { - profile->timer_t4 = 4000; - } - nua_set_params(profile->nua, NTATAG_SIP_T4(profile->timer_t4), TAG_END()); - } else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY); - } else { - sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY); - } - } else if (!strcasecmp(var, "sip-force-expires")) { - int32_t sip_force_expires = atoi(val); - if (sip_force_expires >= 0) { - profile->sip_force_expires = sip_force_expires; - } else { - profile->sip_force_expires = 0; - } - } else if (!strcasecmp(var, "sip-expires-max-deviation")) { - int32_t sip_expires_max_deviation = atoi(val); - if (sip_expires_max_deviation >= 0) { - profile->sip_expires_max_deviation = sip_expires_max_deviation; - } else { - profile->sip_expires_max_deviation = 0; - } - } else if (!strcasecmp(var, "p-asserted-id-parse")) { - if (!strncasecmp(val, "default", 7)) { - profile->paid_type = PAID_DEFAULT; - } else if (!strncasecmp(val, "user-only", 9)) { - profile->paid_type = PAID_USER; - } else if (!strncasecmp(val, "user-domain", 11)) { - profile->paid_type = PAID_USER_DOMAIN; - } else if (!strncasecmp(val, "verbatim", 8)) { - profile->paid_type = PAID_VERBATIM; - } else { - profile->paid_type = PAID_DEFAULT; - } - } - } - } - - if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)) { - sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION); - } - - if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) { - parse_gateways(profile, gateways_tag); - } - - status = SWITCH_STATUS_SUCCESS; - - if ((domains_tag = switch_xml_child(xprofile, "domains"))) { - switch_event_t *xml_params; - switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS); - switch_assert(xml_params); - switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways"); - switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name); - - for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) { - switch_xml_t droot, x_domain_tag; - const char *dname = switch_xml_attr_soft(domain_tag, "name"); - const char *parse = switch_xml_attr_soft(domain_tag, "parse"); - const char *alias = switch_xml_attr_soft(domain_tag, "alias"); - - if (!zstr(dname)) { - if (!strcasecmp(dname, "all")) { - switch_xml_t xml_root, x_domains; - if (switch_xml_locate("directory", NULL, NULL, NULL, &xml_root, &x_domains, xml_params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) { - dname = switch_xml_attr_soft(x_domain_tag, "name"); - parse_domain_tag(profile, x_domain_tag, dname, parse, alias); - } - switch_xml_free(xml_root); - } - } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) { - parse_domain_tag(profile, x_domain_tag, dname, parse, alias); - switch_xml_free(droot); - } - } - } - - switch_event_destroy(&xml_params); - } - - if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) { - for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) { - char *aname = (char *) switch_xml_attr_soft(alias_tag, "name"); - if (!zstr(aname)) { - - if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Alias [%s] for profile [%s] (already exists)\n", - aname, profile->name); - } - } - } - } - } - } - - done: - - if (xml) { - switch_xml_free(xml); - } - - switch_event_destroy(¶ms); - - return status; + /* Redirect loggers in sofia */ + su_log_redirect(su_log_default, logger, NULL); + su_log_redirect(tport_log, logger, NULL); + su_log_redirect(iptsec_log, logger, NULL); + su_log_redirect(nea_log, logger, NULL); + su_log_redirect(nta_log, logger, NULL); + su_log_redirect(nth_client_log, logger, NULL); + su_log_redirect(nth_server_log, logger, NULL); + su_log_redirect(nua_log, logger, NULL); + su_log_redirect(soa_log, logger, NULL); + su_log_redirect(sresolv_log, logger, NULL); +#ifdef HAVE_SOFIA_STUN + su_log_redirect(stun_log, logger, NULL); +#endif + + return SWITCH_STATUS_SUCCESS; } -switch_status_t config_sofia(int reload, char *profile_name) + +switch_status_t config_sofia(sofia_config_t reload, char *profile_name) { char *cf = "sofia.conf"; switch_xml_t cfg, xml = NULL, xprofile, param, settings, profiles; @@ -4190,40 +3425,25 @@ switch_status_t config_sofia(int reload, char *profile_name) char url[512] = ""; int profile_found = 0; switch_event_t *params = NULL; + sofia_profile_t *profile_already_started = NULL; - if (!reload) { - su_init(); - if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) { - su_deinit(); - return SWITCH_STATUS_FALSE; - } - - /* Redirect loggers in sofia */ - su_log_redirect(su_log_default, logger, NULL); - su_log_redirect(tport_log, logger, NULL); - su_log_redirect(iptsec_log, logger, NULL); - su_log_redirect(nea_log, logger, NULL); - su_log_redirect(nta_log, logger, NULL); - su_log_redirect(nth_client_log, logger, NULL); - su_log_redirect(nth_server_log, logger, NULL); - su_log_redirect(nua_log, logger, NULL); - su_log_redirect(soa_log, logger, NULL); - su_log_redirect(sresolv_log, logger, NULL); -#ifdef HAVE_SOFIA_STUN - su_log_redirect(stun_log, logger, NULL); -#endif - } - if (!zstr(profile_name) && (profile = sofia_glue_find_profile(profile_name))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile [%s] Already exists.\n", switch_str_nil(profile_name)); - status = SWITCH_STATUS_FALSE; - sofia_glue_release_profile(profile); - return status; + if (reload == SOFIA_CONFIG_RESCAN) { + profile_already_started = profile; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile [%s] Already exists.\n", switch_str_nil(profile_name)); + status = SWITCH_STATUS_FALSE; + sofia_glue_release_profile(profile); + return status; + } } switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); switch_assert(params); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile_name); + if (reload == SOFIA_CONFIG_RESCAN) { + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "reconfig", "true"); + } if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); @@ -4294,80 +3514,102 @@ switch_status_t config_sofia(int reload, char *profile_name) profile_found = 1; } } + + if (!profile_already_started) { - /* Setup the pool */ - if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); - sofia_profile_start_failure(NULL, xprofilename); - goto done; + /* Setup the pool */ + if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); + sofia_profile_start_failure(NULL, xprofilename); + goto done; + } + + if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); + sofia_profile_start_failure(NULL, xprofilename); + goto done; + } + + profile->tls_verify_policy = TPTLS_VERIFY_NONE; + /* lib default */ + profile->tls_verify_depth = 2; + + + switch_mutex_init(&profile->gw_mutex, SWITCH_MUTEX_NESTED, pool); + + profile->trans_timeout = 100; + + profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833; + + profile->pool = pool; + profile->user_agent = SOFIA_USER_AGENT; + + profile->name = switch_core_strdup(profile->pool, xprofilename); + switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename); + + if (xprofiledomain) { + profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain); + } + + profile->dbname = switch_core_strdup(profile->pool, url); + switch_core_hash_init(&profile->chat_hash, profile->pool); + switch_core_hash_init(&profile->mwi_debounce_hash, profile->pool); + switch_thread_rwlock_create(&profile->rwlock, profile->pool); + switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED, profile->pool); + profile->dtmf_duration = 100; + profile->rtp_digit_delay = 40; + profile->sip_force_expires = 0; + profile->sip_expires_max_deviation = 0; + profile->tls_version = 0; + profile->tls_timeout = 300; + profile->mflags = MFLAG_REFER | MFLAG_REGISTER; + profile->server_rport_level = 1; + profile->client_rport_level = 1; + sofia_set_pflag(profile, PFLAG_STUN_ENABLED); + sofia_set_pflag(profile, PFLAG_DISABLE_100REL); + profile->auto_restart = 1; + sofia_set_pflag(profile, PFLAG_AUTOFIX_TIMING); + sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); + profile->contact_user = SOFIA_DEFAULT_CONTACT_USER; + sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); + sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE); + sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); + //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); + + profile->shutdown_type = "false"; + profile->local_network = "localnet.auto"; + sofia_set_flag(profile, TFLAG_ENABLE_SOA); + sofia_set_pflag(profile, PFLAG_CID_IN_1XX); + profile->ndlb |= PFLAG_NDLB_ALLOW_NONDUP_SDP; + profile->te = 101; + profile->ireg_seconds = IREG_SECONDS; + profile->paid_type = PAID_DEFAULT; + + + profile->tls_verify_policy = TPTLS_VERIFY_NONE; + /* lib default */ + profile->tls_verify_depth = 2; + profile->tls_verify_date = SWITCH_TRUE; + } else { + + /* you could change profile->foo here if it was a minor change like context or dialplan ... */ + profile->acl_count = 0; + profile->nat_acl_count = 0; + profile->reg_acl_count = 0; + profile->proxy_acl_count = 0; + sofia_set_pflag(profile, PFLAG_STUN_ENABLED); + sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); + profile->ib_calls = 0; + profile->ob_calls = 0; + profile->ib_failed_calls = 0; + profile->ob_failed_calls = 0; + profile->shutdown_type = "false"; + + if (xprofiledomain) { + profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain); + } } - if (!(profile = (sofia_profile_t *) switch_core_alloc(pool, sizeof(*profile)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); - sofia_profile_start_failure(NULL, xprofilename); - goto done; - } - profile->tls_verify_policy = TPTLS_VERIFY_NONE; - /* lib default */ - profile->tls_verify_depth = 2; - - - switch_mutex_init(&profile->gw_mutex, SWITCH_MUTEX_NESTED, pool); - - profile->trans_timeout = 100; - - profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833; - - profile->pool = pool; - profile->user_agent = SOFIA_USER_AGENT; - - profile->name = switch_core_strdup(profile->pool, xprofilename); - switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename); - - if (xprofiledomain) { - profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain); - } - - profile->dbname = switch_core_strdup(profile->pool, url); - switch_core_hash_init(&profile->chat_hash, profile->pool); - switch_core_hash_init(&profile->mwi_debounce_hash, profile->pool); - switch_thread_rwlock_create(&profile->rwlock, profile->pool); - switch_mutex_init(&profile->flag_mutex, SWITCH_MUTEX_NESTED, profile->pool); - profile->dtmf_duration = 100; - profile->rtp_digit_delay = 40; - profile->sip_force_expires = 0; - profile->sip_expires_max_deviation = 0; - profile->tls_version = 0; - profile->tls_timeout = 300; - profile->mflags = MFLAG_REFER | MFLAG_REGISTER; - profile->server_rport_level = 1; - profile->client_rport_level = 1; - sofia_set_pflag(profile, PFLAG_STUN_ENABLED); - sofia_set_pflag(profile, PFLAG_DISABLE_100REL); - profile->auto_restart = 1; - sofia_set_pflag(profile, PFLAG_AUTOFIX_TIMING); - sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); - profile->contact_user = SOFIA_DEFAULT_CONTACT_USER; - sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); - sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE); - sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); - //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); - - profile->shutdown_type = "false"; - profile->local_network = "localnet.auto"; - sofia_set_flag(profile, TFLAG_ENABLE_SOA); - sofia_set_pflag(profile, PFLAG_CID_IN_1XX); - profile->ndlb |= PFLAG_NDLB_ALLOW_NONDUP_SDP; - profile->te = 101; - profile->ireg_seconds = IREG_SECONDS; - profile->paid_type = PAID_DEFAULT; - - - profile->tls_verify_policy = TPTLS_VERIFY_NONE; - /* lib default */ - profile->tls_verify_depth = 2; - profile->tls_verify_date = SWITCH_TRUE; - for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); @@ -5343,7 +4585,7 @@ switch_status_t config_sofia(int reload, char *profile_name) } } - if (profile) { + if (profile && !profile_already_started) { switch_xml_t aliases_tag, alias_tag; if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) { @@ -5382,6 +4624,10 @@ switch_status_t config_sofia(int reload, char *profile_name) } done: + if (profile_already_started) { + sofia_glue_release_profile(profile_already_started); + } + switch_event_destroy(¶ms); if (xml) { From b8c0d3564c4ef1ec6595c1e2ce986d97f8792153 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 12:55:50 -0500 Subject: [PATCH 255/512] FS-4765 --resolve --- src/mod/applications/mod_commands/mod_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 5e96474fd3..eb9db51e25 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -5415,7 +5415,7 @@ SWITCH_STANDARD_API(strftime_tz_api_function) } if (zstr(format)) { - format = "%Y-%m-%d"; + format = "%Y-%m-%d %T"; } if (format && switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) { /* The lookup of the zone may fail. */ From 7e2110abf7317a6247c55526f012dab9870bec40 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 14:06:05 -0500 Subject: [PATCH 256/512] fix a few regressions from the last commit --- src/mod/endpoints/mod_sofia/sofia_presence.c | 23 +++++++++++++++----- src/mod/endpoints/mod_sofia/sofia_reg.c | 2 ++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 42fefe3af8..53a150e33b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -620,9 +620,15 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha if (argc >= 4) { + if (argc == 5 && !zstr(argv[4])) { + if (!switch_ivr_uuid_exists(argv[5])) { + return 0; + } + } + if (mod_sofia_globals.debug_presence > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s]\n", - argv[0], argv[1], argv[2], argv[3]); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s] uuid[%s]\n", + argv[0], argv[1], argv[2], argv[3], argv[4]); } if (!helper->hits) { @@ -668,7 +674,7 @@ static void do_normal_probe(switch_event_t *event) } if (probe_euser && probe_host && (profile = sofia_glue_find_profile(probe_host))) { - sql = switch_mprintf("select state,status,rpid,presence_id from sip_dialogs " + sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs " "where hostname='%q' and profile_name='%q' and call_info_state != 'seized' and " "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host); @@ -1061,7 +1067,12 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) status = NULL; } - if (status && switch_stristr("CS_HANGUP", status)) { + if (!zstr(uuid) && !switch_ivr_uuid_exists(uuid)) { + status = "CS_HANGUP"; + } + + + if ((status && switch_stristr("CS_HANGUP", status)) || (!zstr(uuid) && !switch_ivr_uuid_exists(uuid))) { status = "Available"; hup = 1; } @@ -1279,12 +1290,12 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) if (zstr(uuid)) { - sql = switch_mprintf("select state,status,rpid,presence_id from sip_dialogs " + sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs " "where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and " "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", mod_sofia_globals.hostname, profile->name, euser, host, euser, host); } else { - sql = switch_mprintf("select state,status,rpid,presence_id from sip_dialogs " + sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs " "where uuid != '%q' and call_info_state != 'seized' and hostname='%q' and profile_name='%q' and " "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", uuid, mod_sofia_globals.hostname, profile->name, euser, host, euser, host); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 2d54f31bc4..e7f6a2fbdc 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -759,6 +759,8 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + sofia_presence_check_subscriptions(profile, now); + if (now) { sql = switch_mprintf("delete from sip_dialogs where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%q'", (long) now, mod_sofia_globals.hostname); From 49166a3c583eaba14f752011478e6de7e514c94c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 14:17:26 -0500 Subject: [PATCH 257/512] typo --- 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 53a150e33b..181bd24a0a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -621,7 +621,7 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha if (argc >= 4) { if (argc == 5 && !zstr(argv[4])) { - if (!switch_ivr_uuid_exists(argv[5])) { + if (!switch_ivr_uuid_exists(argv[4])) { return 0; } } From 16d41e463c93a20c950fffc2571070521b29dcef Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 15:09:09 -0500 Subject: [PATCH 258/512] get rid of little caesars --- src/include/switch_core.h | 14 +++++++------- src/mod/endpoints/mod_sofia/sofia.c | 6 +++--- src/mod/endpoints/mod_sofia/sofia_glue.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index f647066c38..5531d697f6 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2425,10 +2425,10 @@ SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_recovery_flush(const char *technology, const char *profile_name); -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp); -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init_name(const char *name, +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp); +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *name, switch_sql_queue_manager_t **qmp, uint32_t numq, const char *dsn, const char *pre_trans_execute, @@ -2436,10 +2436,10 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init_name(const const char *inner_pre_trans_execute, const char *inner_post_trans_execute); -#define switch_switch_sql_queue_manager_init(_q, _d, _p1, _p2, _ip1, _ip2) switch_switch_sql_queue_manager_init_name(__FILE__, _q, _d, _p1, _p2, _ip1, _ip2) +#define switch_sql_queue_manager_init(_q, _d, _p1, _p2, _ip1, _ip2) switch_sql_queue_manager_init_name(__FILE__, _q, _d, _p1, _p2, _ip1, _ip2) -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm); -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm); +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm); +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm); SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback(switch_cache_db_handle_t *dbh, const char *sql, switch_db_event_callback_func_t callback, void *pdata, char **err); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index b8a093bf25..9f467059fb 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2531,7 +2531,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool); switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name); - switch_switch_sql_queue_manager_init_name(qname, + switch_sql_queue_manager_init_name(qname, &profile->qm, 1, profile->odbc_dsn ? profile->odbc_dsn : profile->dbname, @@ -2539,7 +2539,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void profile->post_trans_execute, profile->inner_pre_trans_execute, profile->inner_post_trans_execute); - switch_switch_sql_queue_manager_start(profile->qm); + switch_sql_queue_manager_start(profile->qm); if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s", @@ -2627,7 +2627,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_mutex_lock(profile->flag_mutex); switch_mutex_unlock(profile->flag_mutex); - switch_switch_sql_queue_manager_stop(profile->qm); + switch_sql_queue_manager_stop(profile->qm); if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s", diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 0117612f6a..f2cc910aac 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6354,7 +6354,7 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t switch_assert(sqlp && *sqlp); sql = *sqlp; - switch_switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic); + switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic); if (sql_already_dynamic) { *sqlp = NULL; @@ -6369,7 +6369,7 @@ void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bo switch_assert(sqlp && *sqlp); sql = *sqlp; - switch_switch_sql_queue_manager_push_confirm(profile->qm, sql, 0, !sql_already_dynamic); + switch_sql_queue_manager_push_confirm(profile->qm, sql, 0, !sql_already_dynamic); if (sql_already_dynamic) { *sqlp = NULL; From 7a180b752dee9eaecce781b7024786ca49212c0e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 15:10:15 -0500 Subject: [PATCH 259/512] swig --- .../languages/mod_managed/freeswitch_wrap.cxx | 1273 +++++++++++++++- src/mod/languages/mod_managed/managed/swig.cs | 1308 ++++++++++++++++- 2 files changed, 2540 insertions(+), 41 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index bab4805383..a1fed17362 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -926,6 +926,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_DEFAULT_CLID_NAME_get() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_DEFAULT_CLID_NUMBER_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "0000000000"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_DEFAULT_DTMF_DURATION_get() { int jresult ; int result; @@ -1421,6 +1432,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_PROCESS_CDR_VARIABLE_get() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_SKIP_CDR_CAUSES_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "skip_cdr_causes"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_FORCE_PROCESS_CDR_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -6191,6 +6213,230 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_app_log(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_hold_record_t_on_set(void * jarg1, void * jarg2) { + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_hold_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->on = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_hold_record_t_on_get(void * jarg1) { + void * jresult ; + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_hold_record_t *)jarg1; + result = ((arg1)->on); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_hold_record_t_off_set(void * jarg1, void * jarg2) { + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_hold_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->off = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_hold_record_t_off_get(void * jarg1) { + void * jresult ; + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_hold_record_t *)jarg1; + result = ((arg1)->off); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_hold_record_t_uuid_set(void * jarg1, char * jarg2) { + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_hold_record_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->uuid) delete [] arg1->uuid; + if (arg2) { + arg1->uuid = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->uuid, (const char *)arg2); + } else { + arg1->uuid = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_hold_record_t_uuid_get(void * jarg1) { + char * jresult ; + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_hold_record_t *)jarg1; + result = (char *) ((arg1)->uuid); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_hold_record_t_next_set(void * jarg1, void * jarg2) { + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + switch_hold_record_s *arg2 = (switch_hold_record_s *) 0 ; + + arg1 = (switch_hold_record_t *)jarg1; + arg2 = (switch_hold_record_s *)jarg2; + if (arg1) (arg1)->next = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_hold_record_t_next_get(void * jarg1) { + void * jresult ; + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + switch_hold_record_s *result = 0 ; + + arg1 = (switch_hold_record_t *)jarg1; + result = (switch_hold_record_s *) ((arg1)->next); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_hold_record_t() { + void * jresult ; + switch_hold_record_t *result = 0 ; + + result = (switch_hold_record_t *)new switch_hold_record_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_hold_record_t(void * jarg1) { + switch_hold_record_t *arg1 = (switch_hold_record_t *) 0 ; + + arg1 = (switch_hold_record_t *)jarg1; + delete arg1; + +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_thread_data_t_func_set(void * jarg1, void * jarg2) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + switch_thread_start_t arg2 ; + switch_thread_start_t *argp2 ; + + arg1 = (switch_thread_data_t *)jarg1; + argp2 = (switch_thread_start_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_thread_start_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->func = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_thread_data_t_func_get(void * jarg1) { + void * jresult ; + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + switch_thread_start_t result; + + arg1 = (switch_thread_data_t *)jarg1; + result = ((arg1)->func); + jresult = new switch_thread_start_t((switch_thread_start_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_thread_data_t_obj_set(void * jarg1, void * jarg2) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->obj = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_thread_data_t_obj_get(void * jarg1) { + void * jresult ; + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + void *result = 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + result = (void *) ((arg1)->obj); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_thread_data_t_alloc_set(void * jarg1, int jarg2) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + int arg2 ; + + arg1 = (switch_thread_data_t *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->alloc = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_thread_data_t_alloc_get(void * jarg1) { + int jresult ; + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + int result; + + arg1 = (switch_thread_data_t *)jarg1; + result = (int) ((arg1)->alloc); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_thread_data_t() { + void * jresult ; + switch_thread_data_t *result = 0 ; + + result = (switch_thread_data_t *)new switch_thread_data_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_thread_data_t(void * jarg1) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + delete arg1; + +} + + SWIGEXPORT int SWIGSTDCALL CSharp_MESSAGE_STRING_ARG_MAX_get() { int jresult ; int result; @@ -6837,6 +7083,16 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_core_thread_session(void * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_screen_size(void * jarg1, void * jarg2) { + int *arg1 = (int *) 0 ; + int *arg2 = (int *) 0 ; + + arg1 = (int *)jarg1; + arg2 = (int *)jarg2; + switch_core_screen_size(arg1,arg2); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_sched_heartbeat(void * jarg1, unsigned long jarg2) { switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -7945,6 +8201,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_thread_launch(void * jarg1 } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_thread_pool_launch_thread(void * jarg1) { + int jresult ; + switch_thread_data_t **arg1 = (switch_thread_data_t **) 0 ; + switch_status_t result; + + arg1 = (switch_thread_data_t **)jarg1; + result = (switch_status_t)switch_thread_pool_launch_thread(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_thread_pool_launch(void * jarg1) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -8027,6 +8295,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_get_loglevel(void * jarg1) } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_jb(void * jarg1, int jarg2) { + void * jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_media_type_t arg2 ; + stfu_instance_t *result = 0 ; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (switch_media_type_t)jarg2; + result = (stfu_instance_t *)switch_core_session_get_jb(arg1,arg2); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_soft_lock(void * jarg1, unsigned long jarg2) { switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -8265,6 +8547,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall_matching_var(char } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_findall_matching_var(char * jarg1, char * jarg2) { + void * jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_console_callback_match_t *result = 0 ; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + result = (switch_console_callback_match_t *)switch_core_session_findall_matching_var((char const *)arg1,(char const *)arg2); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall_endpoint(void * jarg1, int jarg2) { switch_endpoint_interface_t *arg1 = (switch_endpoint_interface_t *) 0 ; switch_call_cause_t arg2 ; @@ -9177,6 +9473,44 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_hash_find_rdlock(void * jarg1, } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_hash_first(void * jarg1) { + void * jresult ; + switch_hash_t *arg1 = (switch_hash_t *) 0 ; + switch_hash_index_t *result = 0 ; + + arg1 = (switch_hash_t *)jarg1; + result = (switch_hash_index_t *)switch_core_hash_first(arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_hash_next(void * jarg1) { + void * jresult ; + switch_hash_index_t *arg1 = (switch_hash_index_t *) 0 ; + switch_hash_index_t *result = 0 ; + + arg1 = (switch_hash_index_t *)jarg1; + result = (switch_hash_index_t *)switch_core_hash_next(arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_hash_this(void * jarg1, void * jarg2, void * jarg3, void * jarg4) { + switch_hash_index_t *arg1 = (switch_hash_index_t *) 0 ; + void **arg2 = (void **) 0 ; + switch_ssize_t *arg3 = (switch_ssize_t *) 0 ; + void **arg4 = (void **) 0 ; + + arg1 = (switch_hash_index_t *)jarg1; + arg2 = (void **)jarg2; + arg3 = (switch_ssize_t *)jarg3; + arg4 = (void **)jarg4; + switch_core_hash_this(arg1,(void const **)arg2,arg3,arg4); +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_switch_hash_first(char * jarg1, void * jarg2) { void * jresult ; char *arg1 = (char *) 0 ; @@ -11123,6 +11457,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_cache_db_native_handle_t_odbc_dbh_ge } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_native_handle_t_pgsql_dbh_set(void * jarg1, void * jarg2) { + switch_cache_db_native_handle_t *arg1 = (switch_cache_db_native_handle_t *) 0 ; + switch_pgsql_handle_t *arg2 = (switch_pgsql_handle_t *) 0 ; + + arg1 = (switch_cache_db_native_handle_t *)jarg1; + arg2 = (switch_pgsql_handle_t *)jarg2; + if (arg1) (arg1)->pgsql_dbh = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_cache_db_native_handle_t_pgsql_dbh_get(void * jarg1) { + void * jresult ; + switch_cache_db_native_handle_t *arg1 = (switch_cache_db_native_handle_t *) 0 ; + switch_pgsql_handle_t *result = 0 ; + + arg1 = (switch_cache_db_native_handle_t *)jarg1; + result = (switch_pgsql_handle_t *) ((arg1)->pgsql_dbh); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_cache_db_native_handle_t() { void * jresult ; switch_cache_db_native_handle_t *result = 0 ; @@ -11300,6 +11657,55 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_cache_db_odbc_options_t(void * } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_pgsql_options_t_dsn_set(void * jarg1, char * jarg2) { + switch_cache_db_pgsql_options_t *arg1 = (switch_cache_db_pgsql_options_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_cache_db_pgsql_options_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->dsn) delete [] arg1->dsn; + if (arg2) { + arg1->dsn = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->dsn, (const char *)arg2); + } else { + arg1->dsn = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_cache_db_pgsql_options_t_dsn_get(void * jarg1) { + char * jresult ; + switch_cache_db_pgsql_options_t *arg1 = (switch_cache_db_pgsql_options_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_cache_db_pgsql_options_t *)jarg1; + result = (char *) ((arg1)->dsn); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_cache_db_pgsql_options_t() { + void * jresult ; + switch_cache_db_pgsql_options_t *result = 0 ; + + result = (switch_cache_db_pgsql_options_t *)new switch_cache_db_pgsql_options_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_cache_db_pgsql_options_t(void * jarg1) { + switch_cache_db_pgsql_options_t *arg1 = (switch_cache_db_pgsql_options_t *) 0 ; + + arg1 = (switch_cache_db_pgsql_options_t *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_connection_options_t_core_db_options_set(void * jarg1, void * jarg2) { switch_cache_db_connection_options_t *arg1 = (switch_cache_db_connection_options_t *) 0 ; switch_cache_db_core_db_options_t *arg2 = (switch_cache_db_core_db_options_t *) 0 ; @@ -11346,6 +11752,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_cache_db_connection_options_t_odbc_o } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_connection_options_t_pgsql_options_set(void * jarg1, void * jarg2) { + switch_cache_db_connection_options_t *arg1 = (switch_cache_db_connection_options_t *) 0 ; + switch_cache_db_pgsql_options_t *arg2 = (switch_cache_db_pgsql_options_t *) 0 ; + + arg1 = (switch_cache_db_connection_options_t *)jarg1; + arg2 = (switch_cache_db_pgsql_options_t *)jarg2; + if (arg1) (arg1)->pgsql_options = *arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_cache_db_connection_options_t_pgsql_options_get(void * jarg1) { + void * jresult ; + switch_cache_db_connection_options_t *arg1 = (switch_cache_db_connection_options_t *) 0 ; + switch_cache_db_pgsql_options_t *result = 0 ; + + arg1 = (switch_cache_db_connection_options_t *)jarg1; + result = (switch_cache_db_pgsql_options_t *)& ((arg1)->pgsql_options); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_cache_db_connection_options_t() { void * jresult ; switch_cache_db_connection_options_t *result = 0 ; @@ -11427,6 +11856,26 @@ SWIGEXPORT int SWIGSTDCALL CSharp__switch_cache_db_get_db_handle(void * jarg1, i } +SWIGEXPORT int SWIGSTDCALL CSharp__switch_cache_db_get_db_handle_dsn(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) { + int jresult ; + switch_cache_db_handle_t **arg1 = (switch_cache_db_handle_t **) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + int arg5 ; + switch_status_t result; + + arg1 = (switch_cache_db_handle_t **)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (int)jarg5; + result = (switch_status_t)_switch_cache_db_get_db_handle_dsn(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5); + jresult = result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_cache_db_execute_sql2str(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, void * jarg5) { char * jresult ; switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; @@ -11521,24 +11970,6 @@ SWIGEXPORT int SWIGSTDCALL CSharp__switch_core_db_handle(void * jarg1, char * ja } -SWIGEXPORT int SWIGSTDCALL CSharp__switch_core_recovery_db_handle(void * jarg1, char * jarg2, char * jarg3, int jarg4) { - int jresult ; - switch_cache_db_handle_t **arg1 = (switch_cache_db_handle_t **) 0 ; - char *arg2 = (char *) 0 ; - char *arg3 = (char *) 0 ; - int arg4 ; - switch_status_t result; - - arg1 = (switch_cache_db_handle_t **)jarg1; - arg2 = (char *)jarg2; - arg3 = (char *)jarg3; - arg4 = (int)jarg4; - result = (switch_status_t)_switch_core_recovery_db_handle(arg1,(char const *)arg2,(char const *)arg3,arg4); - jresult = result; - return jresult; -} - - SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_test_reactive(void * jarg1, char * jarg2, char * jarg3, char * jarg4) { int jresult ; switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; @@ -11573,17 +12004,25 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute(void * jarg } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute_trans(void * jarg1, char * jarg2, unsigned long jarg3) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute_trans_full(void * jarg1, char * jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7) { int jresult ; switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; char *arg2 = (char *) 0 ; uint32_t arg3 ; + char *arg4 = (char *) 0 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + char *arg7 = (char *) 0 ; switch_status_t result; arg1 = (switch_cache_db_handle_t *)jarg1; arg2 = (char *)jarg2; arg3 = (uint32_t)jarg3; - result = (switch_status_t)switch_cache_db_persistant_execute_trans(arg1,arg2,arg3); + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + result = (switch_status_t)switch_cache_db_persistant_execute_trans_full(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7); jresult = result; return jresult; } @@ -11825,6 +12264,24 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_get_stacksizes(void * jarg1, void } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_dbtype() { + int jresult ; + switch_cache_db_handle_type_t result; + + result = (switch_cache_db_handle_type_t)switch_core_dbtype(); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sql_exec(char * jarg1) { + char *arg1 = (char *) 0 ; + + arg1 = (char *)jarg1; + switch_core_sql_exec((char const *)arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_recovery_recover(char * jarg1, char * jarg2) { int jresult ; char *arg1 = (char *) 0 ; @@ -11867,6 +12324,134 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_recovery_flush(char * jarg1, char } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_push_confirm(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + char *arg2 = (char *) 0 ; + uint32_t arg3 ; + switch_bool_t arg4 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (uint32_t)jarg3; + arg4 = (switch_bool_t)jarg4; + result = (switch_status_t)switch_sql_queue_manager_push_confirm(arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_push(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + char *arg2 = (char *) 0 ; + uint32_t arg3 ; + switch_bool_t arg4 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (uint32_t)jarg3; + arg4 = (switch_bool_t)jarg4; + result = (switch_status_t)switch_sql_queue_manager_push(arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_destroy(void * jarg1) { + int jresult ; + switch_sql_queue_manager_t **arg1 = (switch_sql_queue_manager_t **) 0 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t **)jarg1; + result = (switch_status_t)switch_sql_queue_manager_destroy(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_init_name(char * jarg1, void * jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_sql_queue_manager_t **arg2 = (switch_sql_queue_manager_t **) 0 ; + uint32_t arg3 ; + char *arg4 = (char *) 0 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + char *arg7 = (char *) 0 ; + char *arg8 = (char *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_sql_queue_manager_t **)jarg2; + arg3 = (uint32_t)jarg3; + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + arg8 = (char *)jarg8; + result = (switch_status_t)switch_sql_queue_manager_init_name((char const *)arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_start(void * jarg1) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + result = (switch_status_t)switch_sql_queue_manager_start(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_stop(void * jarg1) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + result = (switch_status_t)switch_sql_queue_manager_stop(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_execute_sql_event_callback(void * jarg1, char * jarg2, void * jarg3, void * jarg4, void * jarg5) { + int jresult ; + switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_db_event_callback_func_t arg3 = (switch_db_event_callback_func_t) 0 ; + void *arg4 = (void *) 0 ; + char **arg5 = (char **) 0 ; + switch_status_t result; + + arg1 = (switch_cache_db_handle_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_db_event_callback_func_t)jarg3; + arg4 = (void *)jarg4; + arg5 = (char **)jarg5; + result = (switch_status_t)switch_cache_db_execute_sql_event_callback(arg1,(char const *)arg2,arg3,arg4,arg5); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_fork() { + void * jresult ; + pid_t result; + + result = switch_fork(); + jresult = new pid_t((pid_t &)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_set(void * jarg1, char * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; char *arg2 = (char *) 0 ; @@ -13466,6 +14051,38 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_fd_read_line(int jarg1, char * jarg2 } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_fd_read_dline(int jarg1, void * jarg2, void * jarg3) { + void * jresult ; + int arg1 ; + char **arg2 = (char **) 0 ; + switch_size_t *arg3 = (switch_size_t *) 0 ; + switch_size_t result; + + arg1 = (int)jarg1; + arg2 = (char **)jarg2; + arg3 = (switch_size_t *)jarg3; + result = switch_fd_read_dline(arg1,arg2,arg3); + jresult = new switch_size_t((switch_size_t &)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_fp_read_dline(void * jarg1, void * jarg2, void * jarg3) { + void * jresult ; + FILE *arg1 = (FILE *) 0 ; + char **arg2 = (char **) 0 ; + switch_size_t *arg3 = (switch_size_t *) 0 ; + switch_size_t result; + + arg1 = (FILE *)jarg1; + arg2 = (char **)jarg2; + arg3 = (switch_size_t *)jarg3; + result = switch_fp_read_dline(arg1,arg2,arg3); + jresult = new switch_size_t((switch_size_t &)result); + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_frame_alloc(void * jarg1, void * jarg2) { int jresult ; switch_frame_t **arg1 = (switch_frame_t **) 0 ; @@ -15497,6 +16114,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_times_get(void * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_old_times_set(void * jarg1, void * jarg2) { + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_channel_timetable *arg2 = (switch_channel_timetable *) 0 ; + + arg1 = (switch_caller_profile *)jarg1; + arg2 = (switch_channel_timetable *)jarg2; + if (arg1) (arg1)->old_times = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_old_times_get(void * jarg1) { + void * jresult ; + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_channel_timetable *result = 0 ; + + arg1 = (switch_caller_profile *)jarg1; + result = (switch_channel_timetable *) ((arg1)->old_times); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_caller_extension_set(void * jarg1, void * jarg2) { switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; switch_caller_extension *arg2 = (switch_caller_extension *) 0 ; @@ -16569,6 +17209,29 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_frame_flags_get(void * jarg1) } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_frame_user_data_set(void * jarg1, void * jarg2) { + switch_frame *arg1 = (switch_frame *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_frame *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->user_data = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_frame_user_data_get(void * jarg1) { + void * jresult ; + switch_frame *arg1 = (switch_frame *) 0 ; + void *result = 0 ; + + arg1 = (switch_frame *)jarg1; + result = (void *) ((arg1)->user_data); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_frame() { void * jresult ; switch_frame *result = 0 ; @@ -17435,6 +18098,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_io_routines_state_run_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_io_routines_get_jb_set(void * jarg1, void * jarg2) { + switch_io_routines *arg1 = (switch_io_routines *) 0 ; + switch_io_get_jb_t arg2 = (switch_io_get_jb_t) 0 ; + + arg1 = (switch_io_routines *)jarg1; + arg2 = (switch_io_get_jb_t)jarg2; + if (arg1) (arg1)->get_jb = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_io_routines_get_jb_get(void * jarg1) { + void * jresult ; + switch_io_routines *arg1 = (switch_io_routines *) 0 ; + switch_io_get_jb_t result; + + arg1 = (switch_io_routines *)jarg1; + result = (switch_io_get_jb_t) ((arg1)->get_jb); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_io_routines_padding_set(void * jarg1, void * jarg2) { switch_io_routines *arg1 = (switch_io_routines *) 0 ; void **arg2 ; @@ -20627,6 +21313,150 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_memory_pool_get(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_buffer_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_buffer_t *arg2 = (switch_buffer_t *) 0 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (switch_buffer_t *)jarg2; + if (arg1) (arg1)->buffer = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_buffer_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_buffer_t *result = 0 ; + + arg1 = (switch_asr_handle *)jarg1; + result = (switch_buffer_t *) ((arg1)->buffer); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_dbuf_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_byte_t *arg2 = (switch_byte_t *) 0 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (switch_byte_t *)jarg2; + if (arg1) (arg1)->dbuf = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_dbuf_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_byte_t *result = 0 ; + + arg1 = (switch_asr_handle *)jarg1; + result = (switch_byte_t *) ((arg1)->dbuf); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_dbuflen_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_size_t arg2 ; + switch_size_t *argp2 ; + + arg1 = (switch_asr_handle *)jarg1; + argp2 = (switch_size_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->dbuflen = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_dbuflen_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_size_t result; + + arg1 = (switch_asr_handle *)jarg1; + result = ((arg1)->dbuflen); + jresult = new switch_size_t((switch_size_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_resampler_set(void * jarg1, void * jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_audio_resampler_t *arg2 = (switch_audio_resampler_t *) 0 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (switch_audio_resampler_t *)jarg2; + if (arg1) (arg1)->resampler = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_asr_handle_resampler_get(void * jarg1) { + void * jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + switch_audio_resampler_t *result = 0 ; + + arg1 = (switch_asr_handle *)jarg1; + result = (switch_audio_resampler_t *) ((arg1)->resampler); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_samplerate_set(void * jarg1, unsigned long jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->samplerate = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_asr_handle_samplerate_get(void * jarg1) { + unsigned long jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t result; + + arg1 = (switch_asr_handle *)jarg1; + result = (uint32_t) ((arg1)->samplerate); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_native_rate_set(void * jarg1, unsigned long jarg2) { + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_asr_handle *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->native_rate = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_asr_handle_native_rate_get(void * jarg1) { + unsigned long jresult ; + switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; + uint32_t result; + + arg1 = (switch_asr_handle *)jarg1; + result = (uint32_t) ((arg1)->native_rate); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_asr_handle_private_info_set(void * jarg1, void * jarg2) { switch_asr_handle *arg1 = (switch_asr_handle *) 0 ; void *arg2 = (void *) 0 ; @@ -23123,6 +23953,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_next_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_session_set(void * jarg1, void * jarg2) { + switch_codec *arg1 = (switch_codec *) 0 ; + switch_core_session_t *arg2 = (switch_core_session_t *) 0 ; + + arg1 = (switch_codec *)jarg1; + arg2 = (switch_core_session_t *)jarg2; + if (arg1) (arg1)->session = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_session_get(void * jarg1) { + void * jresult ; + switch_codec *arg1 = (switch_codec *) 0 ; + switch_core_session_t *result = 0 ; + + arg1 = (switch_codec *)jarg1; + result = (switch_core_session_t *) ((arg1)->session); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec() { void * jresult ; switch_codec *result = 0 ; @@ -26745,10 +27598,10 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_callstate2str(int jarg1) { SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_str2callstate(char * jarg1) { int jresult ; char *arg1 = (char *) 0 ; - switch_call_cause_t result; + switch_channel_callstate_t result; arg1 = (char *)jarg1; - result = (switch_call_cause_t)switch_channel_str2callstate((char const *)arg1); + result = (switch_channel_callstate_t)switch_channel_str2callstate((char const *)arg1); jresult = result; return jresult; } @@ -26826,6 +27679,18 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_partner_uuid(void * jarg } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_hold_record(void * jarg1) { + void * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_hold_record_t *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_hold_record_t *)switch_channel_get_hold_record(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) { int jresult ; switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; @@ -27637,6 +28502,263 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_event(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_t_event_id_set(void * jarg1, int jarg2) { + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + int arg2 ; + + arg1 = (switch_serial_event_t *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->event_id = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_serial_event_t_event_id_get(void * jarg1) { + int jresult ; + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + int result; + + arg1 = (switch_serial_event_t *)jarg1; + result = (int) ((arg1)->event_id); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_t_priority_set(void * jarg1, int jarg2) { + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + int arg2 ; + + arg1 = (switch_serial_event_t *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->priority = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_serial_event_t_priority_get(void * jarg1) { + int jresult ; + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + int result; + + arg1 = (switch_serial_event_t *)jarg1; + result = (int) ((arg1)->priority); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_t_flags_set(void * jarg1, int jarg2) { + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + int arg2 ; + + arg1 = (switch_serial_event_t *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->flags = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_serial_event_t_flags_get(void * jarg1) { + int jresult ; + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + int result; + + arg1 = (switch_serial_event_t *)jarg1; + result = (int) ((arg1)->flags); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_t_owner_set(void * jarg1, char * jarg2) { + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_serial_event_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->owner) delete [] arg1->owner; + if (arg2) { + arg1->owner = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->owner, (const char *)arg2); + } else { + arg1->owner = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_serial_event_t_owner_get(void * jarg1) { + char * jresult ; + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_serial_event_t *)jarg1; + result = (char *) ((arg1)->owner); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_t_subclass_name_set(void * jarg1, char * jarg2) { + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_serial_event_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->subclass_name) delete [] arg1->subclass_name; + if (arg2) { + arg1->subclass_name = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->subclass_name, (const char *)arg2); + } else { + arg1->subclass_name = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_serial_event_t_subclass_name_get(void * jarg1) { + char * jresult ; + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_serial_event_t *)jarg1; + result = (char *) ((arg1)->subclass_name); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_t_body_set(void * jarg1, char * jarg2) { + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_serial_event_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->body) delete [] arg1->body; + if (arg2) { + arg1->body = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->body, (const char *)arg2); + } else { + arg1->body = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_serial_event_t_body_get(void * jarg1) { + char * jresult ; + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_serial_event_t *)jarg1; + result = (char *) ((arg1)->body); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_serial_event_t() { + void * jresult ; + switch_serial_event_t *result = 0 ; + + result = (switch_serial_event_t *)new switch_serial_event_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_serial_event_t(void * jarg1) { + switch_serial_event_t *arg1 = (switch_serial_event_t *) 0 ; + + arg1 = (switch_serial_event_t *)jarg1; + delete arg1; + +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_header_t_name_set(void * jarg1, char * jarg2) { + switch_serial_event_header_t *arg1 = (switch_serial_event_header_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_serial_event_header_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->name) delete [] arg1->name; + if (arg2) { + arg1->name = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->name, (const char *)arg2); + } else { + arg1->name = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_serial_event_header_t_name_get(void * jarg1) { + char * jresult ; + switch_serial_event_header_t *arg1 = (switch_serial_event_header_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_serial_event_header_t *)jarg1; + result = (char *) ((arg1)->name); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_serial_event_header_t_value_set(void * jarg1, char * jarg2) { + switch_serial_event_header_t *arg1 = (switch_serial_event_header_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_serial_event_header_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->value) delete [] arg1->value; + if (arg2) { + arg1->value = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->value, (const char *)arg2); + } else { + arg1->value = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_serial_event_header_t_value_get(void * jarg1) { + char * jresult ; + switch_serial_event_header_t *arg1 = (switch_serial_event_header_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_serial_event_header_t *)jarg1; + result = (char *) ((arg1)->value); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_serial_event_header_t() { + void * jresult ; + switch_serial_event_header_t *result = 0 ; + + result = (switch_serial_event_header_t *)new switch_serial_event_header_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_serial_event_header_t(void * jarg1) { + switch_serial_event_header_t *arg1 = (switch_serial_event_header_t *) 0 ; + + arg1 = (switch_serial_event_header_t *)jarg1; + delete arg1; + +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_init(void * jarg1) { int jresult ; switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; @@ -28017,6 +29139,46 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_free_subclass_detailed(char * jar } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_binary_deserialize(void * jarg1, void * jarg2, void * jarg3, int jarg4) { + int jresult ; + switch_event_t **arg1 = (switch_event_t **) 0 ; + void **arg2 = (void **) 0 ; + switch_size_t arg3 ; + switch_bool_t arg4 ; + switch_status_t result; + switch_size_t *argp3 ; + + arg1 = (switch_event_t **)jarg1; + arg2 = (void **)jarg2; + argp3 = (switch_size_t *)jarg3; + if (!argp3) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0); + return 0; + } + arg3 = *argp3; + arg4 = (switch_bool_t)jarg4; + result = (switch_status_t)switch_event_binary_deserialize(arg1,arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_binary_serialize(void * jarg1, void * jarg2, void * jarg3) { + int jresult ; + switch_event_t *arg1 = (switch_event_t *) 0 ; + void **arg2 = (void **) 0 ; + switch_size_t *arg3 = (switch_size_t *) 0 ; + switch_status_t result; + + arg1 = (switch_event_t *)jarg1; + arg2 = (void **)jarg2; + arg3 = (switch_size_t *)jarg3; + result = (switch_status_t)switch_event_binary_serialize(arg1,arg2,arg3); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_serialize(void * jarg1, void * jarg2, int jarg3) { int jresult ; switch_event_t *arg1 = (switch_event_t *) 0 ; @@ -28085,6 +29247,24 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_array_pair(void * jarg1, void * jarg2, void * jarg3, int jarg4) { + int jresult ; + switch_event_t **arg1 = (switch_event_t **) 0 ; + char **arg2 = (char **) 0 ; + char **arg3 = (char **) 0 ; + int arg4 ; + switch_status_t result; + + arg1 = (switch_event_t **)jarg1; + arg2 = (char **)jarg2; + arg3 = (char **)jarg3; + arg4 = (int)jarg4; + result = (switch_status_t)switch_event_create_array_pair(arg1,arg2,arg3,arg4); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_running() { int jresult ; switch_status_t result; @@ -31977,6 +33157,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_pause_jitter_buffer(void * jarg1, i } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_jitter_buffer(void * jarg1) { + void * jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + stfu_instance_t *result = 0 ; + + arg1 = (switch_rtp_t *)jarg1; + result = (stfu_instance_t *)switch_rtp_get_jitter_buffer(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_flag(void * jarg1, unsigned long jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_rtp_flag_t arg2 ; @@ -32659,6 +33851,29 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_log_node_t_channel_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_log_node_t_slevel_set(void * jarg1, int jarg2) { + switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; + switch_log_level_t arg2 ; + + arg1 = (switch_log_node_t *)jarg1; + arg2 = (switch_log_level_t)jarg2; + if (arg1) (arg1)->slevel = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_log_node_t_slevel_get(void * jarg1) { + int jresult ; + switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; + switch_log_level_t result; + + arg1 = (switch_log_node_t *)jarg1; + result = (switch_log_level_t) ((arg1)->slevel); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_log_node_t() { void * jresult ; switch_log_node_t *result = 0 ; @@ -33340,6 +34555,20 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_xml_toxml_nolock(void * jarg1, int j } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_xml_tohtml(void * jarg1, int jarg2) { + char * jresult ; + switch_xml_t arg1 = (switch_xml_t) 0 ; + switch_bool_t arg2 ; + char *result = 0 ; + + arg1 = (switch_xml_t)jarg1; + arg2 = (switch_bool_t)jarg2; + result = (char *)switch_xml_tohtml(arg1,arg2); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_xml_toxml_buf(void * jarg1, char * jarg2, void * jarg3, void * jarg4, int jarg5) { char * jresult ; switch_xml_t arg1 = (switch_xml_t) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index ead2b8b2a4..e3eea0582d 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -1038,6 +1038,10 @@ public class freeswitch { freeswitchPINVOKE.switch_regex_set_event_header_callback(var, val, SWIGTYPE_p_void.getCPtr(user_data)); } + public static void switch_core_screen_size(SWIGTYPE_p_int x, SWIGTYPE_p_int y) { + freeswitchPINVOKE.switch_core_screen_size(SWIGTYPE_p_int.getCPtr(x), SWIGTYPE_p_int.getCPtr(y)); + } + public static void switch_core_session_sched_heartbeat(SWIGTYPE_p_switch_core_session session, uint seconds) { freeswitchPINVOKE.switch_core_session_sched_heartbeat(SWIGTYPE_p_switch_core_session.getCPtr(session), seconds); } @@ -1453,6 +1457,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_thread_pool_launch_thread(SWIGTYPE_p_p_switch_thread_data_s tdp) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_thread_pool_launch_thread(SWIGTYPE_p_p_switch_thread_data_s.getCPtr(tdp)); + return ret; + } + public static switch_status_t switch_core_session_thread_pool_launch(SWIGTYPE_p_switch_core_session session) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_thread_pool_launch(SWIGTYPE_p_switch_core_session.getCPtr(session)); return ret; @@ -1488,6 +1497,12 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_stfu_instance_t switch_core_session_get_jb(SWIGTYPE_p_switch_core_session session, switch_media_type_t type) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_jb(SWIGTYPE_p_switch_core_session.getCPtr(session), (int)type); + SWIGTYPE_p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_stfu_instance_t(cPtr, false); + return ret; + } + public static void switch_core_session_soft_lock(SWIGTYPE_p_switch_core_session session, uint sec) { freeswitchPINVOKE.switch_core_session_soft_lock(SWIGTYPE_p_switch_core_session.getCPtr(session), sec); } @@ -1583,6 +1598,12 @@ public class freeswitch { freeswitchPINVOKE.switch_core_session_hupall_matching_var(var_name, var_val, (int)cause); } + public static switch_console_callback_match switch_core_session_findall_matching_var(string var_name, string var_val) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_findall_matching_var(var_name, var_val); + switch_console_callback_match ret = (cPtr == IntPtr.Zero) ? null : new switch_console_callback_match(cPtr, false); + return ret; + } + public static void switch_core_session_hupall_endpoint(switch_endpoint_interface endpoint_interface, switch_call_cause_t cause) { freeswitchPINVOKE.switch_core_session_hupall_endpoint(switch_endpoint_interface.getCPtr(endpoint_interface), (int)cause); } @@ -1893,6 +1914,22 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_HashElem switch_core_hash_first(SWIGTYPE_p_switch_hash hash) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_hash_first(SWIGTYPE_p_switch_hash.getCPtr(hash)); + SWIGTYPE_p_HashElem ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_HashElem(cPtr, false); + return ret; + } + + public static SWIGTYPE_p_HashElem switch_core_hash_next(SWIGTYPE_p_HashElem hi) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_hash_next(SWIGTYPE_p_HashElem.getCPtr(hi)); + SWIGTYPE_p_HashElem ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_HashElem(cPtr, false); + return ret; + } + + public static void switch_core_hash_this(SWIGTYPE_p_HashElem hi, SWIGTYPE_p_p_void key, SWIGTYPE_p_switch_ssize_t klen, SWIGTYPE_p_p_void val) { + freeswitchPINVOKE.switch_core_hash_this(SWIGTYPE_p_HashElem.getCPtr(hi), SWIGTYPE_p_p_void.getCPtr(key), SWIGTYPE_p_switch_ssize_t.getCPtr(klen), SWIGTYPE_p_p_void.getCPtr(val)); + } + public static SWIGTYPE_p_HashElem switch_hash_first(string deprecate_me, SWIGTYPE_p_switch_hash hash) { IntPtr cPtr = freeswitchPINVOKE.switch_hash_first(deprecate_me, SWIGTYPE_p_switch_hash.getCPtr(hash)); SWIGTYPE_p_HashElem ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_HashElem(cPtr, false); @@ -2624,6 +2661,11 @@ public class freeswitch { return ret; } + public static switch_status_t _switch_cache_db_get_db_handle_dsn(SWIGTYPE_p_p_switch_cache_db_handle dbh, string dsn, string file, string func, int line) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE._switch_cache_db_get_db_handle_dsn(SWIGTYPE_p_p_switch_cache_db_handle.getCPtr(dbh), dsn, file, func, line); + return ret; + } + public static string switch_cache_db_execute_sql2str(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, string str, uint len, ref string err) { string ret = freeswitchPINVOKE.switch_cache_db_execute_sql2str(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, str, len, ref err); return ret; @@ -2653,11 +2695,6 @@ public class freeswitch { return ret; } - public static switch_status_t _switch_core_recovery_db_handle(SWIGTYPE_p_p_switch_cache_db_handle dbh, string file, string func, int line) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE._switch_core_recovery_db_handle(SWIGTYPE_p_p_switch_cache_db_handle.getCPtr(dbh), file, func, line); - return ret; - } - public static switch_bool_t switch_cache_db_test_reactive(SWIGTYPE_p_switch_cache_db_handle db, string test_sql, string drop_sql, string reactive_sql) { switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_cache_db_test_reactive(SWIGTYPE_p_switch_cache_db_handle.getCPtr(db), test_sql, drop_sql, reactive_sql); return ret; @@ -2668,8 +2705,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_cache_db_persistant_execute_trans(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, uint retries) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_cache_db_persistant_execute_trans(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, retries); + public static switch_status_t switch_cache_db_persistant_execute_trans_full(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, uint retries, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_cache_db_persistant_execute_trans_full(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, retries, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); return ret; } @@ -2767,6 +2804,15 @@ public class freeswitch { return ret; } + public static switch_cache_db_handle_type_t switch_core_dbtype() { + switch_cache_db_handle_type_t ret = (switch_cache_db_handle_type_t)freeswitchPINVOKE.switch_core_dbtype(); + return ret; + } + + public static void switch_core_sql_exec(string sql) { + freeswitchPINVOKE.switch_core_sql_exec(sql); + } + public static int switch_core_recovery_recover(string technology, string profile_name) { int ret = freeswitchPINVOKE.switch_core_recovery_recover(technology, profile_name); return ret; @@ -2784,6 +2830,46 @@ public class freeswitch { freeswitchPINVOKE.switch_core_recovery_flush(technology, profile_name); } + public static switch_status_t switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); + return ret; + } + + public static switch_status_t switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); + return ret; + } + + public static switch_status_t switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager qmp) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp)); + return ret; + } + + public static switch_status_t switch_sql_queue_manager_init_name(string name, SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_init_name(name, SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); + return ret; + } + + public static switch_status_t switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager qm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); + return ret; + } + + public static switch_status_t switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager qm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); + return ret; + } + + public static switch_status_t switch_cache_db_execute_sql_event_callback(SWIGTYPE_p_switch_cache_db_handle dbh, string sql, SWIGTYPE_p_f_p_void_p_switch_event__int callback, SWIGTYPE_p_void pdata, ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_cache_db_execute_sql_event_callback(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), sql, SWIGTYPE_p_f_p_void_p_switch_event__int.getCPtr(callback), SWIGTYPE_p_void.getCPtr(pdata), ref err); + return ret; + } + + public static SWIGTYPE_p_pid_t switch_fork() { + SWIGTYPE_p_pid_t ret = new SWIGTYPE_p_pid_t(freeswitchPINVOKE.switch_fork(), true); + return ret; + } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); return ret; @@ -3163,6 +3249,16 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_switch_size_t switch_fd_read_dline(int fd, ref string buf, SWIGTYPE_p_switch_size_t len) { + SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_fd_read_dline(fd, ref buf, SWIGTYPE_p_switch_size_t.getCPtr(len)), true); + return ret; + } + + public static SWIGTYPE_p_switch_size_t switch_fp_read_dline(SWIGTYPE_p_FILE fd, ref string buf, SWIGTYPE_p_switch_size_t len) { + SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_fp_read_dline(SWIGTYPE_p_FILE.getCPtr(fd), ref buf, SWIGTYPE_p_switch_size_t.getCPtr(len)), true); + return ret; + } + public static switch_status_t switch_frame_alloc(SWIGTYPE_p_p_switch_frame frame, SWIGTYPE_p_switch_size_t size) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_frame_alloc(SWIGTYPE_p_p_switch_frame.getCPtr(frame), SWIGTYPE_p_switch_size_t.getCPtr(size)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -4147,8 +4243,8 @@ public class freeswitch { return ret; } - public static switch_call_cause_t switch_channel_str2callstate(string str) { - switch_call_cause_t ret = (switch_call_cause_t)freeswitchPINVOKE.switch_channel_str2callstate(str); + public static switch_channel_callstate_t switch_channel_str2callstate(string str) { + switch_channel_callstate_t ret = (switch_channel_callstate_t)freeswitchPINVOKE.switch_channel_str2callstate(str); return ret; } @@ -4181,6 +4277,12 @@ public class freeswitch { return ret; } + public static switch_hold_record_t switch_channel_get_hold_record(SWIGTYPE_p_switch_channel channel) { + IntPtr cPtr = freeswitchPINVOKE.switch_channel_get_hold_record(SWIGTYPE_p_switch_channel.getCPtr(channel)); + switch_hold_record_t ret = (cPtr == IntPtr.Zero) ? null : new switch_hold_record_t(cPtr, false); + return ret; + } + public static switch_status_t switch_buffer_create(SWIGTYPE_p_apr_pool_t pool, SWIGTYPE_p_p_switch_buffer buffer, SWIGTYPE_p_switch_size_t max_len) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_buffer_create(SWIGTYPE_p_apr_pool_t.getCPtr(pool), SWIGTYPE_p_p_switch_buffer.getCPtr(buffer), SWIGTYPE_p_switch_size_t.getCPtr(max_len)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -4412,6 +4514,17 @@ public class freeswitch { return ret; } + public static switch_status_t switch_event_binary_deserialize(SWIGTYPE_p_p_switch_event eventp, SWIGTYPE_p_p_void data, SWIGTYPE_p_switch_size_t len, switch_bool_t destroy) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_binary_deserialize(SWIGTYPE_p_p_switch_event.getCPtr(eventp), SWIGTYPE_p_p_void.getCPtr(data), SWIGTYPE_p_switch_size_t.getCPtr(len), (int)destroy); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + + public static switch_status_t switch_event_binary_serialize(switch_event arg0, SWIGTYPE_p_p_void data, SWIGTYPE_p_switch_size_t len) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_binary_serialize(switch_event.getCPtr(arg0), SWIGTYPE_p_p_void.getCPtr(data), SWIGTYPE_p_switch_size_t.getCPtr(len)); + return ret; + } + public static switch_status_t switch_event_serialize(switch_event arg0, ref string str, switch_bool_t encode) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_serialize(switch_event.getCPtr(arg0), ref str, (int)encode); return ret; @@ -4432,6 +4545,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_event_create_array_pair(SWIGTYPE_p_p_switch_event arg0, ref string names, ref string vals, int len) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_array_pair(SWIGTYPE_p_p_switch_event.getCPtr(arg0), ref names, ref vals, len); + return ret; + } + public static switch_status_t switch_event_running() { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_running(); return ret; @@ -5379,6 +5497,12 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_stfu_instance_t switch_rtp_get_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) { + IntPtr cPtr = freeswitchPINVOKE.switch_rtp_get_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); + SWIGTYPE_p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_stfu_instance_t(cPtr, false); + return ret; + } + public static void switch_rtp_set_flag(SWIGTYPE_p_switch_rtp rtp_session, uint flags) { freeswitchPINVOKE.switch_rtp_set_flag(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), flags); } @@ -5665,6 +5789,11 @@ public class freeswitch { return ret; } + public static string switch_xml_tohtml(switch_xml xml, switch_bool_t prn_header) { + string ret = freeswitchPINVOKE.switch_xml_tohtml(switch_xml.getCPtr(xml), (int)prn_header); + return ret; + } + public static string switch_xml_toxml_buf(switch_xml xml, string buf, SWIGTYPE_p_switch_size_t buflen, SWIGTYPE_p_switch_size_t offset, switch_bool_t prn_header) { string ret = freeswitchPINVOKE.switch_xml_toxml_buf(switch_xml.getCPtr(xml), buf, SWIGTYPE_p_switch_size_t.getCPtr(buflen), SWIGTYPE_p_switch_size_t.getCPtr(offset), (int)prn_header); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -6129,6 +6258,7 @@ public class freeswitch { public static readonly string SWITCH_SEQ_CLEARLINEEND = freeswitchPINVOKE.SWITCH_SEQ_CLEARLINEEND_get(); public static readonly string SWITCH_SEQ_CLEARSCR = freeswitchPINVOKE.SWITCH_SEQ_CLEARSCR_get(); public static readonly string SWITCH_DEFAULT_CLID_NAME = freeswitchPINVOKE.SWITCH_DEFAULT_CLID_NAME_get(); + public static readonly string SWITCH_DEFAULT_CLID_NUMBER = freeswitchPINVOKE.SWITCH_DEFAULT_CLID_NUMBER_get(); public static readonly int SWITCH_DEFAULT_DTMF_DURATION = freeswitchPINVOKE.SWITCH_DEFAULT_DTMF_DURATION_get(); public static readonly int SWITCH_MIN_DTMF_DURATION = freeswitchPINVOKE.SWITCH_MIN_DTMF_DURATION_get(); public static readonly int SWITCH_MAX_DTMF_DURATION = freeswitchPINVOKE.SWITCH_MAX_DTMF_DURATION_get(); @@ -6174,6 +6304,7 @@ public class freeswitch { public static readonly string SWITCH_API_REPORTING_HOOK_VARIABLE = freeswitchPINVOKE.SWITCH_API_REPORTING_HOOK_VARIABLE_get(); public static readonly string SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE = freeswitchPINVOKE.SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE_get(); public static readonly string SWITCH_PROCESS_CDR_VARIABLE = freeswitchPINVOKE.SWITCH_PROCESS_CDR_VARIABLE_get(); + public static readonly string SWITCH_SKIP_CDR_CAUSES_VARIABLE = freeswitchPINVOKE.SWITCH_SKIP_CDR_CAUSES_VARIABLE_get(); public static readonly string SWITCH_FORCE_PROCESS_CDR_VARIABLE = freeswitchPINVOKE.SWITCH_FORCE_PROCESS_CDR_VARIABLE_get(); public static readonly string SWITCH_BRIDGE_CHANNEL_VARIABLE = freeswitchPINVOKE.SWITCH_BRIDGE_CHANNEL_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_NAME_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_NAME_VARIABLE_get(); @@ -6644,6 +6775,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_DEFAULT_CLID_NAME_get")] public static extern string SWITCH_DEFAULT_CLID_NAME_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_DEFAULT_CLID_NUMBER_get")] + public static extern string SWITCH_DEFAULT_CLID_NUMBER_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_DEFAULT_DTMF_DURATION_get")] public static extern int SWITCH_DEFAULT_DTMF_DURATION_get(); @@ -6779,6 +6913,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_PROCESS_CDR_VARIABLE_get")] public static extern string SWITCH_PROCESS_CDR_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_SKIP_CDR_CAUSES_VARIABLE_get")] + public static extern string SWITCH_SKIP_CDR_CAUSES_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_FORCE_PROCESS_CDR_VARIABLE_get")] public static extern string SWITCH_FORCE_PROCESS_CDR_VARIABLE_get(); @@ -7967,6 +8104,60 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_app_log")] public static extern void delete_switch_app_log(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_on_set")] + public static extern void switch_hold_record_t_on_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_on_get")] + public static extern IntPtr switch_hold_record_t_on_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_off_set")] + public static extern void switch_hold_record_t_off_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_off_get")] + public static extern IntPtr switch_hold_record_t_off_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_uuid_set")] + public static extern void switch_hold_record_t_uuid_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_uuid_get")] + public static extern string switch_hold_record_t_uuid_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_next_set")] + public static extern void switch_hold_record_t_next_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_hold_record_t_next_get")] + public static extern IntPtr switch_hold_record_t_next_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_hold_record_t")] + public static extern IntPtr new_switch_hold_record_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_hold_record_t")] + public static extern void delete_switch_hold_record_t(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_func_set")] + public static extern void switch_thread_data_t_func_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_func_get")] + public static extern IntPtr switch_thread_data_t_func_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_obj_set")] + public static extern void switch_thread_data_t_obj_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_obj_get")] + public static extern IntPtr switch_thread_data_t_obj_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_alloc_set")] + public static extern void switch_thread_data_t_alloc_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_alloc_get")] + public static extern int switch_thread_data_t_alloc_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_thread_data_t")] + public static extern IntPtr new_switch_thread_data_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_thread_data_t")] + public static extern void delete_switch_thread_data_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_MESSAGE_STRING_ARG_MAX_get")] public static extern int MESSAGE_STRING_ARG_MAX_get(); @@ -8120,6 +8311,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_core_thread_session")] public static extern void delete_switch_core_thread_session(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_screen_size")] + public static extern void switch_core_screen_size(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_sched_heartbeat")] public static extern void switch_core_session_sched_heartbeat(HandleRef jarg1, uint jarg2); @@ -8372,6 +8566,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_thread_launch")] public static extern int switch_core_session_thread_launch(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_pool_launch_thread")] + public static extern int switch_thread_pool_launch_thread(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_thread_pool_launch")] public static extern int switch_core_session_thread_pool_launch(HandleRef jarg1); @@ -8393,6 +8590,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_loglevel")] public static extern int switch_core_session_get_loglevel(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_jb")] + public static extern IntPtr switch_core_session_get_jb(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_soft_lock")] public static extern void switch_core_session_soft_lock(HandleRef jarg1, uint jarg2); @@ -8453,6 +8653,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_matching_var")] public static extern void switch_core_session_hupall_matching_var(string jarg1, string jarg2, int jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_findall_matching_var")] + public static extern IntPtr switch_core_session_findall_matching_var(string jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_endpoint")] public static extern void switch_core_session_hupall_endpoint(HandleRef jarg1, int jarg2); @@ -8639,6 +8842,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_hash_find_rdlock")] public static extern IntPtr switch_core_hash_find_rdlock(HandleRef jarg1, string jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_hash_first")] + public static extern IntPtr switch_core_hash_first(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_hash_next")] + public static extern IntPtr switch_core_hash_next(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_hash_this")] + public static extern void switch_core_hash_this(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_hash_first")] public static extern IntPtr switch_hash_first(string jarg1, HandleRef jarg2); @@ -9089,6 +9301,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_native_handle_t_odbc_dbh_get")] public static extern IntPtr switch_cache_db_native_handle_t_odbc_dbh_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_native_handle_t_pgsql_dbh_set")] + public static extern void switch_cache_db_native_handle_t_pgsql_dbh_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_native_handle_t_pgsql_dbh_get")] + public static extern IntPtr switch_cache_db_native_handle_t_pgsql_dbh_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_cache_db_native_handle_t")] public static extern IntPtr new_switch_cache_db_native_handle_t(); @@ -9131,6 +9349,18 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_cache_db_odbc_options_t")] public static extern void delete_switch_cache_db_odbc_options_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_pgsql_options_t_dsn_set")] + public static extern void switch_cache_db_pgsql_options_t_dsn_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_pgsql_options_t_dsn_get")] + public static extern string switch_cache_db_pgsql_options_t_dsn_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_cache_db_pgsql_options_t")] + public static extern IntPtr new_switch_cache_db_pgsql_options_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_cache_db_pgsql_options_t")] + public static extern void delete_switch_cache_db_pgsql_options_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_connection_options_t_core_db_options_set")] public static extern void switch_cache_db_connection_options_t_core_db_options_set(HandleRef jarg1, HandleRef jarg2); @@ -9143,6 +9373,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_connection_options_t_odbc_options_get")] public static extern IntPtr switch_cache_db_connection_options_t_odbc_options_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_connection_options_t_pgsql_options_set")] + public static extern void switch_cache_db_connection_options_t_pgsql_options_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_connection_options_t_pgsql_options_get")] + public static extern IntPtr switch_cache_db_connection_options_t_pgsql_options_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_cache_db_connection_options_t")] public static extern IntPtr new_switch_cache_db_connection_options_t(); @@ -9164,6 +9400,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp__switch_cache_db_get_db_handle")] public static extern int _switch_cache_db_get_db_handle(HandleRef jarg1, int jarg2, HandleRef jarg3, string jarg4, string jarg5, int jarg6); + [DllImport("mod_managed", EntryPoint="CSharp__switch_cache_db_get_db_handle_dsn")] + public static extern int _switch_cache_db_get_db_handle_dsn(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql2str")] public static extern string switch_cache_db_execute_sql2str(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, ref string jarg5); @@ -9182,17 +9421,14 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp__switch_core_db_handle")] public static extern int _switch_core_db_handle(HandleRef jarg1, string jarg2, string jarg3, int jarg4); - [DllImport("mod_managed", EntryPoint="CSharp__switch_core_recovery_db_handle")] - public static extern int _switch_core_recovery_db_handle(HandleRef jarg1, string jarg2, string jarg3, int jarg4); - [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_test_reactive")] public static extern int switch_cache_db_test_reactive(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute")] public static extern int switch_cache_db_persistant_execute(HandleRef jarg1, string jarg2, uint jarg3); - [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute_trans")] - public static extern int switch_cache_db_persistant_execute_trans(HandleRef jarg1, string jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute_trans_full")] + public static extern int switch_cache_db_persistant_execute_trans_full(HandleRef jarg1, string jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, string jarg7); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_signal_handlers")] public static extern void switch_core_set_signal_handlers(); @@ -9254,6 +9490,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_stacksizes")] public static extern int switch_core_get_stacksizes(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_dbtype")] + public static extern int switch_core_dbtype(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sql_exec")] + public static extern void switch_core_sql_exec(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_recovery_recover")] public static extern int switch_core_recovery_recover(string jarg1, string jarg2); @@ -9266,6 +9508,30 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_recovery_flush")] public static extern void switch_core_recovery_flush(string jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_push_confirm")] + public static extern int switch_sql_queue_manager_push_confirm(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_push")] + public static extern int switch_sql_queue_manager_push(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_destroy")] + public static extern int switch_sql_queue_manager_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_init_name")] + public static extern int switch_sql_queue_manager_init_name(string jarg1, HandleRef jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_start")] + public static extern int switch_sql_queue_manager_start(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_stop")] + public static extern int switch_sql_queue_manager_stop(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql_event_callback")] + public static extern int switch_cache_db_execute_sql_event_callback(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, ref string jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_fork")] + public static extern IntPtr switch_fork(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); @@ -9632,6 +9898,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_fd_read_line")] public static extern IntPtr switch_fd_read_line(int jarg1, string jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_fd_read_dline")] + public static extern IntPtr switch_fd_read_dline(int jarg1, ref string jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_fp_read_dline")] + public static extern IntPtr switch_fp_read_dline(HandleRef jarg1, ref string jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_alloc")] public static extern int switch_frame_alloc(HandleRef jarg1, HandleRef jarg2); @@ -10058,6 +10330,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_times_get")] public static extern IntPtr switch_caller_profile_times_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_old_times_set")] + public static extern void switch_caller_profile_old_times_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_old_times_get")] + public static extern IntPtr switch_caller_profile_old_times_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_caller_extension_set")] public static extern void switch_caller_profile_caller_extension_set(HandleRef jarg1, HandleRef jarg2); @@ -10313,6 +10591,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_flags_get")] public static extern uint switch_frame_flags_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_user_data_set")] + public static extern void switch_frame_user_data_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_user_data_get")] + public static extern IntPtr switch_frame_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_frame")] public static extern IntPtr new_switch_frame(); @@ -10535,6 +10819,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_state_run_get")] public static extern IntPtr switch_io_routines_state_run_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_get_jb_set")] + public static extern void switch_io_routines_get_jb_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_get_jb_get")] + public static extern IntPtr switch_io_routines_get_jb_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_routines_padding_set")] public static extern void switch_io_routines_padding_set(HandleRef jarg1, HandleRef jarg2); @@ -11339,6 +11629,42 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_memory_pool_get")] public static extern IntPtr switch_asr_handle_memory_pool_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_buffer_set")] + public static extern void switch_asr_handle_buffer_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_buffer_get")] + public static extern IntPtr switch_asr_handle_buffer_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuf_set")] + public static extern void switch_asr_handle_dbuf_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuf_get")] + public static extern IntPtr switch_asr_handle_dbuf_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuflen_set")] + public static extern void switch_asr_handle_dbuflen_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_dbuflen_get")] + public static extern IntPtr switch_asr_handle_dbuflen_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_resampler_set")] + public static extern void switch_asr_handle_resampler_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_resampler_get")] + public static extern IntPtr switch_asr_handle_resampler_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_samplerate_set")] + public static extern void switch_asr_handle_samplerate_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_samplerate_get")] + public static extern uint switch_asr_handle_samplerate_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_native_rate_set")] + public static extern void switch_asr_handle_native_rate_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_native_rate_get")] + public static extern uint switch_asr_handle_native_rate_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_asr_handle_private_info_set")] public static extern void switch_asr_handle_private_info_set(HandleRef jarg1, HandleRef jarg2); @@ -11981,6 +12307,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_next_get")] public static extern IntPtr switch_codec_next_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_session_set")] + public static extern void switch_codec_session_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_session_get")] + public static extern IntPtr switch_codec_session_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec")] public static extern IntPtr new_switch_codec(); @@ -12857,6 +13189,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_partner_uuid")] public static extern string switch_channel_get_partner_uuid(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_record")] + public static extern IntPtr switch_channel_get_hold_record(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")] public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -13037,6 +13372,66 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_event")] public static extern void delete_switch_event(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_event_id_set")] + public static extern void switch_serial_event_t_event_id_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_event_id_get")] + public static extern int switch_serial_event_t_event_id_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_priority_set")] + public static extern void switch_serial_event_t_priority_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_priority_get")] + public static extern int switch_serial_event_t_priority_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_flags_set")] + public static extern void switch_serial_event_t_flags_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_flags_get")] + public static extern int switch_serial_event_t_flags_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_owner_set")] + public static extern void switch_serial_event_t_owner_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_owner_get")] + public static extern string switch_serial_event_t_owner_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_subclass_name_set")] + public static extern void switch_serial_event_t_subclass_name_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_subclass_name_get")] + public static extern string switch_serial_event_t_subclass_name_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_body_set")] + public static extern void switch_serial_event_t_body_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_t_body_get")] + public static extern string switch_serial_event_t_body_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_serial_event_t")] + public static extern IntPtr new_switch_serial_event_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_serial_event_t")] + public static extern void delete_switch_serial_event_t(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_header_t_name_set")] + public static extern void switch_serial_event_header_t_name_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_header_t_name_get")] + public static extern string switch_serial_event_header_t_name_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_header_t_value_set")] + public static extern void switch_serial_event_header_t_value_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_serial_event_header_t_value_get")] + public static extern string switch_serial_event_header_t_value_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_serial_event_header_t")] + public static extern IntPtr new_switch_serial_event_header_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_serial_event_header_t")] + public static extern void delete_switch_serial_event_header_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_init")] public static extern int switch_event_init(HandleRef jarg1); @@ -13115,6 +13510,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_event_free_subclass_detailed")] public static extern int switch_event_free_subclass_detailed(string jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_binary_deserialize")] + public static extern int switch_event_binary_deserialize(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, int jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_binary_serialize")] + public static extern int switch_event_binary_serialize(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_serialize")] public static extern int switch_event_serialize(HandleRef jarg1, ref string jarg2, int jarg3); @@ -13127,6 +13528,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_brackets")] public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6, int jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_array_pair")] + public static extern int switch_event_create_array_pair(HandleRef jarg1, ref string jarg2, ref string jarg3, int jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_running")] public static extern int switch_event_running(); @@ -13919,6 +14323,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_pause_jitter_buffer")] public static extern int switch_rtp_pause_jitter_buffer(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_jitter_buffer")] + public static extern IntPtr switch_rtp_get_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); @@ -14075,6 +14482,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_channel_get")] public static extern int switch_log_node_t_channel_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_slevel_set")] + public static extern void switch_log_node_t_slevel_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_slevel_get")] + public static extern int switch_log_node_t_slevel_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_log_node_t")] public static extern IntPtr new_switch_log_node_t(); @@ -14237,6 +14650,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_toxml_nolock")] public static extern string switch_xml_toxml_nolock(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_tohtml")] + public static extern string switch_xml_tohtml(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_toxml_buf")] public static extern string switch_xml_toxml_buf(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, int jarg5); @@ -16565,6 +16981,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_core_session__int { private HandleRef swigCPtr; @@ -18185,6 +18631,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_void_p_switch_event__int { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_void_p_switch_event__int(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_void_p_switch_event__int() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_void_p_switch_event__int obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_void__void { private HandleRef swigCPtr; @@ -18485,6 +18961,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_pid_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_pid_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_pid_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_pid_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_p_char { private HandleRef swigCPtr; @@ -19385,6 +19891,66 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_sql_queue_manager { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_sql_queue_manager(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_sql_queue_manager() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_sql_queue_manager obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + +public class SWIGTYPE_p_p_switch_thread_data_s { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_thread_data_s(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_thread_data_s() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_thread_data_s obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_xml_binding { private HandleRef swigCPtr; @@ -19685,6 +20251,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_stfu_instance_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_stfu_instance_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_stfu_instance_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_stfu_instance_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_buffer { private HandleRef swigCPtr; @@ -20315,6 +20911,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_pgsql_handle { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_pgsql_handle(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_pgsql_handle() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_pgsql_handle obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_pollfd_t { private HandleRef swigCPtr; @@ -20555,6 +21181,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_sql_queue_manager { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_sql_queue_manager(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_sql_queue_manager() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_sql_queue_manager obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_ssize_t { private HandleRef swigCPtr; @@ -20615,6 +21271,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_thread_start_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_thread_start_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_thread_start_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_thread_start_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_time_exp_t { private HandleRef swigCPtr; @@ -21449,6 +22135,71 @@ public class switch_asr_handle : IDisposable { } } + public SWIGTYPE_p_switch_buffer buffer { + set { + freeswitchPINVOKE.switch_asr_handle_buffer_set(swigCPtr, SWIGTYPE_p_switch_buffer.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_handle_buffer_get(swigCPtr); + SWIGTYPE_p_switch_buffer ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_buffer(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_unsigned_char dbuf { + set { + freeswitchPINVOKE.switch_asr_handle_dbuf_set(swigCPtr, SWIGTYPE_p_unsigned_char.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_handle_dbuf_get(swigCPtr); + SWIGTYPE_p_unsigned_char ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_switch_size_t dbuflen { + set { + freeswitchPINVOKE.switch_asr_handle_dbuflen_set(swigCPtr, SWIGTYPE_p_switch_size_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_asr_handle_dbuflen_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public switch_audio_resampler_t resampler { + set { + freeswitchPINVOKE.switch_asr_handle_resampler_set(swigCPtr, switch_audio_resampler_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_asr_handle_resampler_get(swigCPtr); + switch_audio_resampler_t ret = (cPtr == IntPtr.Zero) ? null : new switch_audio_resampler_t(cPtr, false); + return ret; + } + } + + public uint samplerate { + set { + freeswitchPINVOKE.switch_asr_handle_samplerate_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_asr_handle_samplerate_get(swigCPtr); + return ret; + } + } + + public uint native_rate { + set { + freeswitchPINVOKE.switch_asr_handle_native_rate_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_asr_handle_native_rate_get(swigCPtr); + return ret; + } + } + public SWIGTYPE_p_void private_info { set { freeswitchPINVOKE.switch_asr_handle_private_info_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); @@ -22209,6 +22960,17 @@ public class switch_cache_db_connection_options_t : IDisposable { } } + public switch_cache_db_pgsql_options_t pgsql_options { + set { + freeswitchPINVOKE.switch_cache_db_connection_options_t_pgsql_options_set(swigCPtr, switch_cache_db_pgsql_options_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_cache_db_connection_options_t_pgsql_options_get(swigCPtr); + switch_cache_db_pgsql_options_t ret = (cPtr == IntPtr.Zero) ? null : new switch_cache_db_pgsql_options_t(cPtr, false); + return ret; + } + } + public switch_cache_db_connection_options_t() : this(freeswitchPINVOKE.new_switch_cache_db_connection_options_t(), true) { } @@ -22284,7 +23046,8 @@ namespace FreeSWITCH.Native { public enum switch_cache_db_handle_type_t { SCDB_TYPE_CORE_DB, - SCDB_TYPE_ODBC + SCDB_TYPE_ODBC, + SCDB_TYPE_PGSQL } } @@ -22351,6 +23114,17 @@ public class switch_cache_db_native_handle_t : IDisposable { } } + public SWIGTYPE_p_switch_pgsql_handle pgsql_dbh { + set { + freeswitchPINVOKE.switch_cache_db_native_handle_t_pgsql_dbh_set(swigCPtr, SWIGTYPE_p_switch_pgsql_handle.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_cache_db_native_handle_t_pgsql_dbh_get(swigCPtr); + SWIGTYPE_p_switch_pgsql_handle ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_pgsql_handle(cPtr, false); + return ret; + } + } + public switch_cache_db_native_handle_t() : this(freeswitchPINVOKE.new_switch_cache_db_native_handle_t(), true) { } @@ -22444,6 +23218,63 @@ public class switch_cache_db_odbc_options_t : IDisposable { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_cache_db_pgsql_options_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_cache_db_pgsql_options_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_cache_db_pgsql_options_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_cache_db_pgsql_options_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_cache_db_pgsql_options_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public string dsn { + set { + freeswitchPINVOKE.switch_cache_db_pgsql_options_t_dsn_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_cache_db_pgsql_options_t_dsn_get(swigCPtr); + return ret; + } + } + + public switch_cache_db_pgsql_options_t() : this(freeswitchPINVOKE.new_switch_cache_db_pgsql_options_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_call_cause_t { SWITCH_CAUSE_NONE = 0, SWITCH_CAUSE_UNALLOCATED_NUMBER = 1, @@ -22512,7 +23343,8 @@ public enum switch_call_cause_t { SWITCH_CAUSE_INVALID_GATEWAY = 608, SWITCH_CAUSE_GATEWAY_DOWN = 609, SWITCH_CAUSE_INVALID_URL = 610, - SWITCH_CAUSE_INVALID_PROFILE = 611 + SWITCH_CAUSE_INVALID_PROFILE = 611, + SWITCH_CAUSE_NO_PICKUP = 612 } } @@ -23089,6 +23921,17 @@ public class switch_caller_profile : IDisposable { } } + public switch_channel_timetable old_times { + set { + freeswitchPINVOKE.switch_caller_profile_old_times_set(swigCPtr, switch_channel_timetable.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_caller_profile_old_times_get(swigCPtr); + switch_channel_timetable ret = (cPtr == IntPtr.Zero) ? null : new switch_channel_timetable(cPtr, false); + return ret; + } + } + public switch_caller_extension caller_extension { set { freeswitchPINVOKE.switch_caller_profile_caller_extension_set(swigCPtr, switch_caller_extension.getCPtr(value)); @@ -23353,6 +24196,7 @@ public enum switch_channel_flag_t { CF_TRACKABLE, CF_NO_CDR, CF_EARLY_OK, + CF_MEDIA_TRANS, CF_FLAG_MAX } @@ -24021,6 +24865,17 @@ public class switch_codec : IDisposable { } } + public SWIGTYPE_p_switch_core_session session { + set { + freeswitchPINVOKE.switch_codec_session_set(swigCPtr, SWIGTYPE_p_switch_core_session.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_session_get(swigCPtr); + SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false); + return ret; + } + } + public switch_codec() : this(freeswitchPINVOKE.new_switch_codec(), true) { } @@ -24936,7 +25791,7 @@ namespace FreeSWITCH.Native { SCF_CLEAR_SQL = (1 << 17), SCF_THREADED_SYSTEM_EXEC = (1 << 18), SCF_SYNC_CLOCK_REQUESTED = (1 << 19), - SCF_CORE_ODBC_REQ = (1 << 20), + SCF_CORE_NON_SQLITE_DB_REQ = (1 << 20), SCF_DEBUG_SQL = (1 << 21), SCF_API_EXPANSION = (1 << 22), SCF_SESSION_THREAD_POOL = (1 << 23) @@ -25251,6 +26106,7 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_AUDIO_DATA, SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE, SWITCH_MESSAGE_INDICATE_STUN_ERROR, + SWITCH_MESSAGE_INDICATE_MEDIA_RENEG, SWITCH_MESSAGE_INVALID } @@ -27678,6 +28534,17 @@ public class switch_frame : IDisposable { } } + public SWIGTYPE_p_void user_data { + set { + freeswitchPINVOKE.switch_frame_user_data_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_frame_user_data_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + public switch_frame() : this(freeswitchPINVOKE.new_switch_frame(), true) { } @@ -27722,6 +28589,98 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class switch_hold_record_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_hold_record_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_hold_record_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_hold_record_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_hold_record_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_time_t on { + set { + freeswitchPINVOKE.switch_hold_record_t_on_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_hold_record_t_on_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t off { + set { + freeswitchPINVOKE.switch_hold_record_t_off_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_hold_record_t_off_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public string uuid { + set { + freeswitchPINVOKE.switch_hold_record_t_uuid_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_hold_record_t_uuid_get(swigCPtr); + return ret; + } + } + + public switch_hold_record_t next { + set { + freeswitchPINVOKE.switch_hold_record_t_next_set(swigCPtr, switch_hold_record_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_hold_record_t_next_get(swigCPtr); + switch_hold_record_t ret = (cPtr == IntPtr.Zero) ? null : new switch_hold_record_t(cPtr, false); + return ret; + } + } + + public switch_hold_record_t() : this(freeswitchPINVOKE.new_switch_hold_record_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class switch_input_args_t : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; @@ -28881,7 +29840,8 @@ public enum switch_io_routine_name_t { SWITCH_IO_RECEIVE_EVENT, SWITCH_IO_STATE_CHANGE, SWITCH_IO_READ_VIDEO_FRAME, - SWITCH_IO_WRITE_VIDEO_FRAME + SWITCH_IO_WRITE_VIDEO_FRAME, + SWITCH_IO_GET_JB } } @@ -29047,6 +30007,17 @@ public class switch_io_routines : IDisposable { } } + public SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t get_jb { + set { + freeswitchPINVOKE.switch_io_routines_get_jb_set(swigCPtr, SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_io_routines_get_jb_get(swigCPtr); + SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t(cPtr, false); + return ret; + } + } + public SWIGTYPE_p_p_void padding { set { freeswitchPINVOKE.switch_io_routines_padding_set(swigCPtr, SWIGTYPE_p_p_void.getCPtr(value)); @@ -29778,7 +30749,8 @@ public enum switch_log_level_t { SWITCH_LOG_CRIT = 2, SWITCH_LOG_ALERT = 1, SWITCH_LOG_CONSOLE = 0, - SWITCH_LOG_INVALID = 64 + SWITCH_LOG_INVALID = 64, + SWITCH_LOG_UNINIT = 1000 } } @@ -29915,6 +30887,16 @@ public class switch_log_node_t : IDisposable { } } + public switch_log_level_t slevel { + set { + freeswitchPINVOKE.switch_log_node_t_slevel_set(swigCPtr, (int)value); + } + get { + switch_log_level_t ret = (switch_log_level_t)freeswitchPINVOKE.switch_log_node_t_slevel_get(swigCPtr); + return ret; + } + } + public switch_log_node_t() : this(freeswitchPINVOKE.new_switch_log_node_t(), true) { } @@ -30121,6 +31103,22 @@ namespace FreeSWITCH.Native { namespace FreeSWITCH.Native { +public enum switch_media_type_t { + SWITCH_MEDIA_TYPE_AUDIO, + SWITCH_MEDIA_TYPE_VIDEO +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_module_flag_enum_t { SMODF_NONE = 0, SMODF_GLOBAL_SYMBOLS = (1 << 0) @@ -31455,6 +32453,180 @@ public class switch_scheduler_task : IDisposable { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_serial_event_header_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_serial_event_header_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_serial_event_header_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_serial_event_header_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_serial_event_header_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public string name { + set { + freeswitchPINVOKE.switch_serial_event_header_t_name_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_serial_event_header_t_name_get(swigCPtr); + return ret; + } + } + + public string value { + set { + freeswitchPINVOKE.switch_serial_event_header_t_value_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_serial_event_header_t_value_get(swigCPtr); + return ret; + } + } + + public switch_serial_event_header_t() : this(freeswitchPINVOKE.new_switch_serial_event_header_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + +public class switch_serial_event_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_serial_event_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_serial_event_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_serial_event_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_serial_event_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public int event_id { + set { + freeswitchPINVOKE.switch_serial_event_t_event_id_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_serial_event_t_event_id_get(swigCPtr); + return ret; + } + } + + public int priority { + set { + freeswitchPINVOKE.switch_serial_event_t_priority_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_serial_event_t_priority_get(swigCPtr); + return ret; + } + } + + public int flags { + set { + freeswitchPINVOKE.switch_serial_event_t_flags_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_serial_event_t_flags_get(swigCPtr); + return ret; + } + } + + public string owner { + set { + freeswitchPINVOKE.switch_serial_event_t_owner_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_serial_event_t_owner_get(swigCPtr); + return ret; + } + } + + public string subclass_name { + set { + freeswitchPINVOKE.switch_serial_event_t_subclass_name_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_serial_event_t_subclass_name_get(swigCPtr); + return ret; + } + } + + public string body { + set { + freeswitchPINVOKE.switch_serial_event_t_body_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_serial_event_t_body_get(swigCPtr); + return ret; + } + } + + public switch_serial_event_t() : this(freeswitchPINVOKE.new_switch_serial_event_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_session_ctl_t { SCSC_PAUSE_INBOUND, SCSC_PAUSE_OUTBOUND, @@ -32726,6 +33898,104 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class switch_thread_data_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_thread_data_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_thread_data_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_thread_data_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_thread_data_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_thread_start_t func { + set { + freeswitchPINVOKE.switch_thread_data_t_func_set(swigCPtr, SWIGTYPE_p_switch_thread_start_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_thread_start_t ret = new SWIGTYPE_p_switch_thread_start_t(freeswitchPINVOKE.switch_thread_data_t_func_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_void obj { + set { + freeswitchPINVOKE.switch_thread_data_t_obj_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_thread_data_t_obj_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public int alloc { + set { + freeswitchPINVOKE.switch_thread_data_t_alloc_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_thread_data_t_alloc_get(swigCPtr); + return ret; + } + } + + public switch_thread_data_t() : this(freeswitchPINVOKE.new_switch_thread_data_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +public enum switch_thread_priority_t { + SWITCH_PRI_LOW = 1, + SWITCH_PRI_NORMAL = 10, + SWITCH_PRI_IMPORTANT = 50, + SWITCH_PRI_REALTIME = 99 +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class switch_timer : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; From 1d4e16419e44eb00d0465e760bd972bf74fdf61b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 15:13:31 -0500 Subject: [PATCH 260/512] fix macro --- src/include/switch_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 5531d697f6..0616c532f6 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2436,7 +2436,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n const char *inner_pre_trans_execute, const char *inner_post_trans_execute); -#define switch_sql_queue_manager_init(_q, _d, _p1, _p2, _ip1, _ip2) switch_sql_queue_manager_init_name(__FILE__, _q, _d, _p1, _p2, _ip1, _ip2) +#define switch_sql_queue_manager_init(_q, _n, _d, _p1, _p2, _ip1, _ip2) switch_sql_queue_manager_init_name(__FILE__, _q, _n, _d, _p1, _p2, _ip1, _ip2) SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm); SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm); From 15837ff5c89b82eeb46a8684fc6680063a28ad8d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 25 Oct 2012 16:22:52 -0500 Subject: [PATCH 261/512] more little caesars --- src/switch_core_sqldb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 2ebfd5b464..ec64befd22 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1258,7 +1258,7 @@ static uint32_t qm_ttl(switch_sql_queue_manager_t *qm) } -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm) +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm) { switch_status_t status = SWITCH_STATUS_FALSE; @@ -1278,7 +1278,7 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_stop(switch_sql_ return status; } -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm) +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm) { switch_threadattr_t *thd_attr; @@ -1295,7 +1295,7 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_start(switch_sql } -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp) +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp) { switch_sql_queue_manager_t *qm; switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -1307,7 +1307,7 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_destroy(switch_s qm = *qmp; *qmp = NULL; - switch_switch_sql_queue_manager_stop(qm); + switch_sql_queue_manager_stop(qm); for(i = 0; i < qm->numq; i++) { while (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { @@ -1321,7 +1321,7 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_destroy(switch_s return status; } -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) { if (!qm->thread_running) { @@ -1343,7 +1343,7 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push(switch_sql_ } -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) { int want, size, x = 0, sanity = 0; uint32_t written; @@ -1389,7 +1389,7 @@ SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_push_confirm(swi -SWITCH_DECLARE(switch_status_t) switch_switch_sql_queue_manager_init_name(const char *name, +SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *name, switch_sql_queue_manager_t **qmp, uint32_t numq, const char *dsn, const char *pre_trans_execute, From 8a5212164f74e95b379c8778691c71027589de1e Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 25 Oct 2012 19:00:28 -0500 Subject: [PATCH 262/512] windows fixes for last commit + vs2010 reswig --- .../mod_managed/freeswitch_wrap.2010.cxx | 154 ++++++++++-- .../mod_managed/managed/swig.2010.cs | 222 ++++++++++++++++-- src/switch_core_sqldb.c | 4 +- 3 files changed, 342 insertions(+), 38 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 40aab99e82..e76d081416 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -6040,6 +6040,96 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_hold_record_t(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_thread_data_t_func_set(void * jarg1, void * jarg2) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + switch_thread_start_t arg2 ; + switch_thread_start_t *argp2 ; + + arg1 = (switch_thread_data_t *)jarg1; + argp2 = (switch_thread_start_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_thread_start_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->func = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_thread_data_t_func_get(void * jarg1) { + void * jresult ; + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + switch_thread_start_t result; + + arg1 = (switch_thread_data_t *)jarg1; + result = ((arg1)->func); + jresult = new switch_thread_start_t((const switch_thread_start_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_thread_data_t_obj_set(void * jarg1, void * jarg2) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->obj = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_thread_data_t_obj_get(void * jarg1) { + void * jresult ; + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + void *result = 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + result = (void *) ((arg1)->obj); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_thread_data_t_alloc_set(void * jarg1, int jarg2) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + int arg2 ; + + arg1 = (switch_thread_data_t *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->alloc = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_thread_data_t_alloc_get(void * jarg1) { + int jresult ; + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + int result; + + arg1 = (switch_thread_data_t *)jarg1; + result = (int) ((arg1)->alloc); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_thread_data_t() { + void * jresult ; + switch_thread_data_t *result = 0 ; + + result = (switch_thread_data_t *)new switch_thread_data_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_thread_data_t(void * jarg1) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + delete arg1; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_MESSAGE_STRING_ARG_MAX_get() { int jresult ; int result; @@ -7785,6 +7875,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_thread_launch(void * jarg1 } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_thread_pool_launch_thread(void * jarg1) { + int jresult ; + switch_thread_data_t **arg1 = (switch_thread_data_t **) 0 ; + switch_status_t result; + + arg1 = (switch_thread_data_t **)jarg1; + result = (switch_status_t)switch_thread_pool_launch_thread(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_thread_pool_launch(void * jarg1) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -11884,7 +11986,7 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_recovery_flush(char * jarg1, char } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_push(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_push_confirm(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { int jresult ; switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; char *arg2 = (char *) 0 ; @@ -11896,67 +11998,87 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_push(void * ja arg2 = (char *)jarg2; arg3 = (uint32_t)jarg3; arg4 = (switch_bool_t)jarg4; - result = (switch_status_t)switch_switch_sql_queue_manager_push(arg1,(char const *)arg2,arg3,arg4); + result = (switch_status_t)switch_sql_queue_manager_push_confirm(arg1,(char const *)arg2,arg3,arg4); jresult = result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_destroy(void * jarg1) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_push(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + char *arg2 = (char *) 0 ; + uint32_t arg3 ; + switch_bool_t arg4 ; + switch_status_t result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (uint32_t)jarg3; + arg4 = (switch_bool_t)jarg4; + result = (switch_status_t)switch_sql_queue_manager_push(arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_destroy(void * jarg1) { int jresult ; switch_sql_queue_manager_t **arg1 = (switch_sql_queue_manager_t **) 0 ; switch_status_t result; arg1 = (switch_sql_queue_manager_t **)jarg1; - result = (switch_status_t)switch_switch_sql_queue_manager_destroy(arg1); + result = (switch_status_t)switch_sql_queue_manager_destroy(arg1); jresult = result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_init(void * jarg1, unsigned long jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_init_name(char * jarg1, void * jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8) { int jresult ; - switch_sql_queue_manager_t **arg1 = (switch_sql_queue_manager_t **) 0 ; - uint32_t arg2 ; - char *arg3 = (char *) 0 ; + char *arg1 = (char *) 0 ; + switch_sql_queue_manager_t **arg2 = (switch_sql_queue_manager_t **) 0 ; + uint32_t arg3 ; char *arg4 = (char *) 0 ; char *arg5 = (char *) 0 ; char *arg6 = (char *) 0 ; char *arg7 = (char *) 0 ; + char *arg8 = (char *) 0 ; switch_status_t result; - arg1 = (switch_sql_queue_manager_t **)jarg1; - arg2 = (uint32_t)jarg2; - arg3 = (char *)jarg3; + arg1 = (char *)jarg1; + arg2 = (switch_sql_queue_manager_t **)jarg2; + arg3 = (uint32_t)jarg3; arg4 = (char *)jarg4; arg5 = (char *)jarg5; arg6 = (char *)jarg6; arg7 = (char *)jarg7; - result = (switch_status_t)switch_switch_sql_queue_manager_init(arg1,arg2,(char const *)arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7); + arg8 = (char *)jarg8; + result = (switch_status_t)switch_sql_queue_manager_init_name((char const *)arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8); jresult = result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_start(void * jarg1) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_start(void * jarg1) { int jresult ; switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; switch_status_t result; arg1 = (switch_sql_queue_manager_t *)jarg1; - result = (switch_status_t)switch_switch_sql_queue_manager_start(arg1); + result = (switch_status_t)switch_sql_queue_manager_start(arg1); jresult = result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_switch_sql_queue_manager_stop(void * jarg1) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_stop(void * jarg1) { int jresult ; switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; switch_status_t result; arg1 = (switch_sql_queue_manager_t *)jarg1; - result = (switch_status_t)switch_switch_sql_queue_manager_stop(arg1); + result = (switch_status_t)switch_sql_queue_manager_stop(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 031eda1f37..5fa0f55fbe 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -1469,6 +1469,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_thread_pool_launch_thread(SWIGTYPE_p_p_switch_thread_data_s tdp) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_thread_pool_launch_thread(SWIGTYPE_p_p_switch_thread_data_s.getCPtr(tdp)); + return ret; + } + public static switch_status_t switch_core_session_thread_pool_launch(SWIGTYPE_p_switch_core_session session) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_thread_pool_launch(SWIGTYPE_p_switch_core_session.getCPtr(session)); return ret; @@ -2837,28 +2842,33 @@ public class freeswitch { freeswitchPINVOKE.switch_core_recovery_flush(technology, profile_name); } - public static switch_status_t switch_switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); + public static switch_status_t switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); return ret; } - public static switch_status_t switch_switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager qmp) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp)); + public static switch_status_t switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_push(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); return ret; } - public static switch_status_t switch_switch_sql_queue_manager_init(SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_init(SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); + public static switch_status_t switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager qmp) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_destroy(SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp)); return ret; } - public static switch_status_t switch_switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager qm) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); + public static switch_status_t switch_sql_queue_manager_init_name(string name, SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_init_name(name, SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); return ret; } - public static switch_status_t switch_switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager qm) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); + public static switch_status_t switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager qm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_start(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); + return ret; + } + + public static switch_status_t switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager qm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_stop(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm)); return ret; } @@ -8140,6 +8150,30 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_hold_record_t")] public static extern void delete_switch_hold_record_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_func_set")] + public static extern void switch_thread_data_t_func_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_func_get")] + public static extern IntPtr switch_thread_data_t_func_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_obj_set")] + public static extern void switch_thread_data_t_obj_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_obj_get")] + public static extern IntPtr switch_thread_data_t_obj_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_alloc_set")] + public static extern void switch_thread_data_t_alloc_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_alloc_get")] + public static extern int switch_thread_data_t_alloc_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_thread_data_t")] + public static extern IntPtr new_switch_thread_data_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_thread_data_t")] + public static extern void delete_switch_thread_data_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_MESSAGE_STRING_ARG_MAX_get")] public static extern int MESSAGE_STRING_ARG_MAX_get(); @@ -8548,6 +8582,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_thread_launch")] public static extern int switch_core_session_thread_launch(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_pool_launch_thread")] + public static extern int switch_thread_pool_launch_thread(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_thread_pool_launch")] public static extern int switch_core_session_thread_pool_launch(HandleRef jarg1); @@ -9487,20 +9524,23 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_recovery_flush")] public static extern void switch_core_recovery_flush(string jarg1, string jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_push")] - public static extern int switch_switch_sql_queue_manager_push(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_push_confirm")] + public static extern int switch_sql_queue_manager_push_confirm(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); - [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_destroy")] - public static extern int switch_switch_sql_queue_manager_destroy(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_push")] + public static extern int switch_sql_queue_manager_push(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); - [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_init")] - public static extern int switch_switch_sql_queue_manager_init(HandleRef jarg1, uint jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_destroy")] + public static extern int switch_sql_queue_manager_destroy(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_start")] - public static extern int switch_switch_sql_queue_manager_start(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_init_name")] + public static extern int switch_sql_queue_manager_init_name(string jarg1, HandleRef jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8); - [DllImport("mod_managed", EntryPoint="CSharp_switch_switch_sql_queue_manager_stop")] - public static extern int switch_switch_sql_queue_manager_stop(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_start")] + public static extern int switch_sql_queue_manager_start(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_stop")] + public static extern int switch_sql_queue_manager_stop(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql_event_callback")] public static extern int switch_cache_db_execute_sql_event_callback(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, ref string jarg5); @@ -19939,6 +19979,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_thread_data_s { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_thread_data_s(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_thread_data_s() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_thread_data_s obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_xml { private HandleRef swigCPtr; @@ -21229,6 +21299,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_thread_start_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_thread_start_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_thread_start_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_thread_start_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_time_exp_t { private HandleRef swigCPtr; @@ -33981,6 +34081,88 @@ public enum switch_text_channel_t { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_thread_data_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_thread_data_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_thread_data_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_thread_data_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_thread_data_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_thread_start_t func { + set { + freeswitchPINVOKE.switch_thread_data_t_func_set(swigCPtr, SWIGTYPE_p_switch_thread_start_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_thread_start_t ret = new SWIGTYPE_p_switch_thread_start_t(freeswitchPINVOKE.switch_thread_data_t_func_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_void obj { + set { + freeswitchPINVOKE.switch_thread_data_t_obj_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_thread_data_t_obj_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public int alloc { + set { + freeswitchPINVOKE.switch_thread_data_t_alloc_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_thread_data_t_alloc_get(swigCPtr); + return ret; + } + } + + public switch_thread_data_t() : this(freeswitchPINVOKE.new_switch_thread_data_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_thread_priority_t { SWITCH_PRI_LOW = 1, SWITCH_PRI_NORMAL = 10, diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index ec64befd22..0e0bb65ae1 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1345,8 +1345,8 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push(switch_sql_queue_m SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) { - int want, size, x = 0, sanity = 0; - uint32_t written; + int size, x = 0, sanity = 0; + uint32_t written, want; if (!qm->thread_running) { return SWITCH_STATUS_FALSE; From 7088758ae35dacee2b293f00af16f74192bd7175 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 09:30:18 -0500 Subject: [PATCH 263/512] FS-4684 try this --- src/mod/endpoints/mod_sofia/sofia_glue.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index f2cc910aac..cada086bdc 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3214,7 +3214,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f const char *err = NULL; const char *val = NULL; switch_rtp_flag_t flags; - switch_status_t status; + switch_status_t status = SWITCH_STATUS_SUCCESS; char tmp[50]; uint32_t rtp_timeout_sec = tech_pvt->profile->rtp_timeout_sec; uint32_t rtp_hold_timeout_sec = tech_pvt->profile->rtp_hold_timeout_sec; @@ -3243,10 +3243,15 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f goto end; } - if (switch_rtp_ready(tech_pvt->rtp_session) && - (!sofia_test_flag(tech_pvt, TFLAG_VIDEO) || switch_rtp_ready(tech_pvt->video_rtp_session)) && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { - status = SWITCH_STATUS_SUCCESS; - goto end; + + if (!sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { + if (switch_rtp_ready(tech_pvt->rtp_session)) { + if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && !switch_rtp_ready(tech_pvt->video_rtp_session)) { + goto video; + } else { + goto end; + } + } } if ((status = sofia_glue_tech_set_codec(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) { From d905bc848873d2af2aec583c13caf844835b7438 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 10:13:04 -0500 Subject: [PATCH 264/512] FS-4763 --resolve --- src/mod/endpoints/mod_sofia/sofia_glue.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index cada086bdc..ac6ba9a9e9 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -5133,7 +5133,13 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc")) { - /* nevermind */ + /* if a bit rate is specified and doesn't match, this is not a codec match, except for ILBC */ + match = 0; + } + + if (match && map->rm_rate && codec_rate && map->rm_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") || !strcasecmp(map->rm_encoding, "pcmu"))) { + /* if the sampling rate is specified and doesn't match, this is not a codec match for G.711 */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sampling rates have to match for G.711\n"); match = 0; } @@ -5152,8 +5158,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } mimp = imp; break; - } else { - match = 0; } } From fbfe830abf7a5febd86e01045e815b2070cb130f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 11:57:38 -0500 Subject: [PATCH 265/512] do lookup in dingaling when an address is specified as host:foo.bar.com like sofia does --- src/mod/endpoints/mod_dingaling/mod_dingaling.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 78ee260d05..af67afcfc9 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1511,8 +1511,14 @@ static int do_tport_candidates(struct private_object *tech_pvt, ldl_transport_ty } address = advip; - if(address && !strncasecmp(address, "host:", 5)) { - address = address + 5; + if (address && !strncasecmp(address, "host:", 5)) { + char *lookup = switch_stun_host_lookup(address + 5, switch_core_session_get_pool(tech_pvt->session)); + + if (zstr(lookup)) { + address = address + 5; + } else { + address = lookup; + } } memset(cand, 0, sizeof(*cand)); From 28aa2ad2911d4585c8a9b36ce60065095a397329 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 12:10:36 -0500 Subject: [PATCH 266/512] optimize sql generator to skip insert/update stmts on channels that do not exist --- src/switch_core_sqldb.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 0e0bb65ae1..0cb6f9740d 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1951,16 +1951,43 @@ static char *parse_presence_data_cols(switch_event_t *event) #define MAX_SQL 5 -#define new_sql() switch_assert(sql_idx+1 < MAX_SQL); sql[sql_idx++] +#define new_sql() switch_assert(sql_idx+1 < MAX_SQL); if (exists) sql[sql_idx++] static void core_event_handler(switch_event_t *event) { char *sql[MAX_SQL] = { 0 }; int sql_idx = 0; char *extra_cols; + int exists = 1; + char *uuid = NULL; switch_assert(event); + switch (event->event_id) { + case SWITCH_EVENT_CHANNEL_UUID: + case SWITCH_EVENT_CHANNEL_CREATE: + case SWITCH_EVENT_CHANNEL_ANSWER: + case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA: + case SWITCH_EVENT_CHANNEL_HOLD: + case SWITCH_EVENT_CHANNEL_UNHOLD: + case SWITCH_EVENT_CHANNEL_EXECUTE: + case SWITCH_EVENT_CHANNEL_ORIGINATE: + case SWITCH_EVENT_CALL_UPDATE: + case SWITCH_EVENT_CHANNEL_CALLSTATE: + case SWITCH_EVENT_CHANNEL_STATE: + case SWITCH_EVENT_CHANNEL_BRIDGE: + case SWITCH_EVENT_CHANNEL_UNBRIDGE: + case SWITCH_EVENT_CALL_SECURE: + { + if ((uuid = switch_event_get_header(event, "unique-id"))) { + exists = switch_ivr_uuid_exists(uuid); + } + } + break; + default: + break; + } + switch (event->event_id) { case SWITCH_EVENT_ADD_SCHEDULE: { @@ -2035,7 +2062,8 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_core_get_switchname() ); break; - case SWITCH_EVENT_CODEC: + case SWITCH_EVENT_CHANNEL_ANSWER: + case SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA: new_sql() = switch_mprintf @@ -2140,6 +2168,8 @@ static void core_event_handler(switch_event_t *event) case CS_NEW: case CS_DESTROY: case CS_REPORTING: + case CS_HANGUP: + case CS_INIT: break; case CS_EXECUTE: if ((extra_cols = parse_presence_data_cols(event))) { @@ -3161,7 +3191,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_DESTROY, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_UUID, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_CREATE, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); - switch_event_bind("core_db", SWITCH_EVENT_CODEC, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); + switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_ANSWER, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); + switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_HOLD, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_UNHOLD, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); switch_event_bind("core_db", SWITCH_EVENT_CHANNEL_EXECUTE, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); From 63e2044a7ecf9ea6bd16332d0d5f272cd5be09d8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 14:15:14 -0500 Subject: [PATCH 267/512] modify sofia debug code to print file, line numbers and function name --- libs/sofia-sip/.update | 2 +- .../libsofia-sip-ua/iptsec/auth_module.c | 10 ++--- .../libsofia-sip-ua/nea/nea_server.c | 4 +- libs/sofia-sip/libsofia-sip-ua/nta/nta.c | 28 +++++++------- .../libsofia-sip-ua/nth/nth_client.c | 2 +- .../libsofia-sip-ua/nth/nth_server.c | 8 ++-- .../libsofia-sip-ua/nua/nua_register.c | 6 +-- .../libsofia-sip-ua/nua/nua_session.c | 4 +- .../sofia-sip/libsofia-sip-ua/nua/nua_stack.c | 2 +- libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c | 2 +- .../libsofia-sip-ua/sresolv/sresolv.c | 6 +-- .../libsofia-sip-ua/su/sofia-sip/su_debug.h | 37 +++++++++++++------ .../libsofia-sip-ua/su/sofia-sip/su_log.h | 18 +++++++-- .../libsofia-sip-ua/su/su_localinfo.c | 4 +- libs/sofia-sip/libsofia-sip-ua/su/su_log.c | 19 +++++++--- libs/sofia-sip/libsofia-sip-ua/tport/tport.c | 4 +- .../tport/tport_type_connect.c | 2 +- 17 files changed, 96 insertions(+), 62 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 22f5eeb029..e5cf1e495d 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Tue Oct 23 13:13:35 EDT 2012 +Fri Oct 26 14:14:41 CDT 2012 diff --git a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c index 087810ebc7..9c1ca218b5 100644 --- a/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c +++ b/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_module.c @@ -744,7 +744,7 @@ void auth_check_digest(auth_mod_t *am, auth_challenge_digest(am, as, ach); as->as_blacklist = am->am_blacklist; } - SU_DEBUG_5(("auth_method_digest: response did not match\n")); + SU_DEBUG_5(("auth_method_digest: response did not match\n" VA_NONE)); return; } @@ -761,7 +761,7 @@ void auth_check_digest(auth_mod_t *am, if (am->am_challenge) auth_challenge_digest(am, as, ach); - SU_DEBUG_7(("auth_method_digest: successful authentication\n")); + SU_DEBUG_7(("auth_method_digest: successful authentication\n" VA_NONE)); as->as_status = 0; /* Successful authentication! */ as->as_phrase = ""; @@ -1412,11 +1412,11 @@ int auth_validate_digest_nonce(auth_mod_t *am, /* Check nonce */ if (!ar->ar_nonce) { - SU_DEBUG_5(("auth_method_digest: no nonce\n")); + SU_DEBUG_5(("auth_method_digest: no nonce\n" VA_NONE)); return -1; } if (base64_d((void*)nonce, (sizeof nonce), ar->ar_nonce) != (sizeof nonce)) { - SU_DEBUG_5(("auth_method_digest: too short nonce\n")); + SU_DEBUG_5(("auth_method_digest: too short nonce\n" VA_NONE)); return -1; } @@ -1426,7 +1426,7 @@ int auth_validate_digest_nonce(auth_mod_t *am, auth_md5_hmac_digest(am, md5, hmac, sizeof hmac); if (memcmp(nonce->digest, hmac, sizeof nonce->digest)) { - SU_DEBUG_5(("auth_method_digest: bad nonce\n")); + SU_DEBUG_5(("auth_method_digest: bad nonce\n" VA_NONE)); return -1; } diff --git a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c index bd1e63b478..42539cf82d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c +++ b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c @@ -424,12 +424,12 @@ nea_server_t *nea_server_create(nta_agent_t *agent, throttle = min_throttle; if (!url) { - SU_DEBUG_5(("nea_server_create(): invalid url\n")); + SU_DEBUG_5(("nea_server_create(): invalid url\n" VA_NONE)); return NULL; } if (min_expires > expires || expires > max_expires) { - SU_DEBUG_5(("nea_server_create(): invalid expiration range\n")); + SU_DEBUG_5(("nea_server_create(): invalid expiration range\n" VA_NONE)); return NULL; } diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index e690b424e7..709e678d86 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -1276,7 +1276,7 @@ void agent_timer(su_root_magic_t *rm, su_timer_t *timer, nta_agent_t *agent) if (next == latest) { /* Do not set timer? */ - SU_DEBUG_9(("nta: timer not set\n")); + SU_DEBUG_9(("nta: timer not set\n" VA_NONE)); assert(!agent->sa_out.completed->q_head); assert(!agent->sa_out.trying->q_head); assert(!agent->sa_out.inv_calling->q_head); @@ -2162,7 +2162,7 @@ int nta_agent_add_tport(nta_agent_t *self, if (url_string_p(uri)) SU_DEBUG_1(("nta: %s: invalid bind URL\n", uri->us_str)); else - SU_DEBUG_1(("nta: invalid bind URL\n")); + SU_DEBUG_1(("nta: invalid bind URL\n" VA_NONE)); su_seterrno(EINVAL); return -1; } @@ -2249,19 +2249,19 @@ int nta_agent_add_tport(nta_agent_t *self, /* XXX - when to use maddr? */ if ((agent_init_via(self, tport_primaries(self->sa_tports), 0)) < 0) { error = su_errno(); - SU_DEBUG_1(("nta: cannot create Via headers\n")); + SU_DEBUG_1(("nta: cannot create Via headers\n" VA_NONE)); goto error; } else - SU_DEBUG_9(("nta: Via fields initialized\n")); + SU_DEBUG_9(("nta: Via fields initialized\n" VA_NONE)); if ((agent_init_contact(self)) < 0) { error = su_errno(); - SU_DEBUG_1(("nta: cannot create Contact header\n")); + SU_DEBUG_1(("nta: cannot create Contact header\n" VA_NONE)); goto error; } else - SU_DEBUG_9(("nta: Contact header created\n")); + SU_DEBUG_9(("nta: Contact header created\n" VA_NONE)); su_free(self->sa_home, url); ta_end(ta); @@ -2286,7 +2286,7 @@ int agent_create_master_transport(nta_agent_t *self, tagi_t *tags) if (!self->sa_tports) return -1; - SU_DEBUG_9(("nta: master transport created\n")); + SU_DEBUG_9(("nta: master transport created\n" VA_NONE)); return 0; } @@ -7713,7 +7713,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent, home = msg_home(msg); if (!sip->sip_request || sip_complete_message(msg) < 0) { - SU_DEBUG_3(("nta: outgoing_create: incomplete request\n")); + SU_DEBUG_3(("nta: outgoing_create: incomplete request\n" VA_NONE)); return NULL; } @@ -7900,7 +7900,7 @@ nta_outgoing_t *outgoing_create(nta_agent_t *agent, } } else { - SU_DEBUG_1(("outgoing_create: ACK without INVITE\n")); + SU_DEBUG_1(("outgoing_create: ACK without INVITE\n" VA_NONE)); assert(!"INVITE found for ACK"); } } @@ -7987,11 +7987,11 @@ outgoing_prepare_send(nta_outgoing_t *orq) outgoing_send_via(orq, tp); } else if (orq->orq_sips) { - SU_DEBUG_3(("nta outgoing create: no secure transport\n")); + SU_DEBUG_3(("nta outgoing create: no secure transport\n" VA_NONE)); outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1); } else { - SU_DEBUG_3(("nta outgoing create: no transport protocol\n")); + SU_DEBUG_3(("nta outgoing create: no transport protocol\n" VA_NONE)); outgoing_reply(orq, 503, "No transport", 1); } } @@ -8013,7 +8013,7 @@ outgoing_send_via(nta_outgoing_t *orq, tport_t *tp) if (old_tp) tport_unref(old_tp); if (outgoing_insert_via(orq, agent_tport_via(tp)) < 0) { - SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n")); + SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n" VA_NONE)); outgoing_reply(orq, 503, "Cannot insert Via", 1); return; } @@ -9211,7 +9211,7 @@ int outgoing_recv(nta_outgoing_t *_orq, if (orq->orq_destroyed && 200 <= status && status < 300) { if (orq->orq_uas && su_strcasecmp(sip->sip_to->a_tag, orq->orq_tag) != 0) { /* Orphan 200 Ok to INVITE. ACK and BYE it */ - SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE\n")); + SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE\n" VA_NONE)); return nta_msg_ackbye(sa, msg); } return -1; /* Proxy statelessly (RFC3261 section 16.11) */ @@ -9273,7 +9273,7 @@ int outgoing_recv(nta_outgoing_t *_orq, return outgoing_duplicate(orq, msg, sip); /* Orphan 200 Ok to INVITE. ACK and BYE it */ - SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE")); + SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE" VA_NONE)); return nta_msg_ackbye(sa, msg); } } diff --git a/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c b/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c index 96442454fb..6a2cd5f80b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c +++ b/libs/sofia-sip/libsofia-sip-ua/nth/nth_client.c @@ -911,7 +911,7 @@ int hc_resolve_and_send(nth_client_t * hc) if (msg_serialize(msg, http) < 0) { assert(hc->hc_tport); - SU_DEBUG_3(("nth client create: invalid message")); + SU_DEBUG_3(("nth client create: invalid message" VA_NONE)); return -1; } diff --git a/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c b/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c index 4daed06520..0c9b6182dc 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c +++ b/libs/sofia-sip/libsofia-sip-ua/nth/nth_server.c @@ -312,20 +312,20 @@ nth_site_t *nth_site_create(nth_site_t *parent, is_path = url->url_path != NULL; if (is_host && is_path) { - SU_DEBUG_3(("nth_site_create(): virtual host and path simultanously\n")); + SU_DEBUG_3(("nth_site_create(): virtual host and path simultanously\n" VA_NONE)); errno = EINVAL; goto error; } if (!parent && !is_host) { - SU_DEBUG_3(("nth_site_create(): host is required\n")); + SU_DEBUG_3(("nth_site_create(): host is required\n" VA_NONE)); errno = EINVAL; goto error; } if (parent) { if (!parent->site_isdir) { - SU_DEBUG_3(("nth_site_create(): invalid parent resource \n")); + SU_DEBUG_3(("nth_site_create(): invalid parent resource \n" VA_NONE)); errno = EINVAL; goto error; } @@ -995,7 +995,7 @@ static void server_reply(server_t *srv, tport_t *tport, if (tport_tqsend(tport, response, NULL, TPTAG_CLOSE_AFTER(close), TAG_END()) == -1) { - SU_DEBUG_3(("server_reply(): cannot queue response\n")); + SU_DEBUG_3(("server_reply(): cannot queue response\n" VA_NONE)); tport_shutdown(tport, 2); } diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c index a0dcbb1c4e..a4ec4246af 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c @@ -967,7 +967,7 @@ static int nua_register_client_response(nua_client_request_t *cr, if (tport && tport != nr->nr_tport) { if (nr->nr_error_report_id) { if (tport_release(nr->nr_tport, nr->nr_error_report_id, NULL, NULL, nr, 0) < 0) - SU_DEBUG_1(("nua_register: tport_release() failed\n")); + SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE)); nr->nr_error_report_id = 0; } tport_unref(nr->nr_tport); @@ -996,7 +996,7 @@ static int nua_register_client_response(nua_client_request_t *cr, if (nr->nr_tport) { if (nr->nr_error_report_id) { if (tport_release(nr->nr_tport, nr->nr_error_report_id, NULL, NULL, nr, 0) < 0) - SU_DEBUG_1(("nua_register: tport_release() failed\n")); + SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE)); nr->nr_error_report_id = 0; } @@ -1028,7 +1028,7 @@ void nua_register_connection_closed(tp_stack_t *sip_stack, pending = nr->nr_error_report_id; if (tport_release(tport, pending, NULL, NULL, nr, 0) < 0) - SU_DEBUG_1(("nua_register: tport_release() failed\n")); + SU_DEBUG_1(("nua_register: tport_release() failed\n" VA_NONE)); nr->nr_error_report_id = 0; tpn = tport_name(nr->nr_tport); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index c17b7b9bb0..3316d535c3 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -3039,11 +3039,11 @@ nh_referral_check(nua_handle_t *nh, tagi_t const *tags) ref->ref_event = sip_event_dup(nh->nh_home, event); if (!nh_validate(nh->nh_nua, ref_handle)) { - SU_DEBUG_3(("nua: invalid NOTIFY_REFER handle\n")); + SU_DEBUG_3(("nua: invalid NOTIFY_REFER handle\n" VA_NONE)); return -1; } else if (!ref->ref_event) { - SU_DEBUG_3(("nua: NOTIFY event missing\n")); + SU_DEBUG_3(("nua: NOTIFY event missing\n" VA_NONE)); return -1; } diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c index 5fe5d221d1..85f1647d3e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c @@ -192,7 +192,7 @@ int nua_stack_init(su_root_t *root, nua_t *nua) dnh->nh_ds->ds_leg == NULL || nta_agent_set_params(nua->nua_nta, NTATAG_UA(1), TAG_END()) < 0 || nua_stack_init_transport(nua, nua->nua_args) < 0) { - SU_DEBUG_1(("nua: initializing SIP stack failed\n")); + SU_DEBUG_1(("nua: initializing SIP stack failed\n" VA_NONE)); return -1; } diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c index 009ba80695..88a7fd389b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c @@ -3596,7 +3596,7 @@ sres_decode_msg(sres_resolver_t *res, m->m_offset = sizeof(m->m_packet.mp_header); if (m->m_size < m->m_offset) { - SU_DEBUG_5(("sres_decode_msg: truncated message\n")); + SU_DEBUG_5(("sres_decode_msg: truncated message\n" VA_NONE)); return -1; } diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c index fba22de731..0720265926 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sresolv.c @@ -132,13 +132,13 @@ sres_resolver_create(su_root_t *root, srs->srs_timer = t; if (!srs->srs_timer) - SU_DEBUG_3(("sres: cannot create timer\n")); + SU_DEBUG_3(("sres: cannot create timer\n" VA_NONE)); #if nomore else if (su_timer_set_for_ever(t, sres_sofia_timer, srs) < 0) - SU_DEBUG_3(("sres: cannot set timer\n")); + SU_DEBUG_3(("sres: cannot set timer\n" VA_NONE)); #else else if (sres_resolver_set_timer_cb(res, sres_sofia_set_timer, srs) < 0) - SU_DEBUG_3(("sres: cannot set timer cb\n")); + SU_DEBUG_3(("sres: cannot set timer cb\n" VA_NONE)); #endif else return res; /* Success! */ diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h index 3764fbd9c7..3881a67701 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h +++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_debug.h @@ -73,13 +73,17 @@ SOFIA_BEGIN_DECLS SOFIAPUBVAR su_log_t SU_LOG[]; #endif +#define VA_NONE "%s","" + #define SU_DEBUG_DEF(level) \ su_inline void su_debug_##level(char const *fmt, ...) \ __attribute__ ((__format__ (printf, 1, 2))); \ su_inline void su_debug_##level(char const *fmt, ...) \ - { va_list ap; va_start(ap, fmt); su_vllog(SU_LOG, level, fmt, ap); va_end(ap); } + { va_list ap; va_start(ap, fmt); su_vllog(SU_LOG, level, fmt, ap); va_end(ap); } + +//SU_DEBUG_DEF(0) +#define su_debug_0(_f, ...) su_llog(SU_LOG, 0, _f, __VA_ARGS__) -SU_DEBUG_DEF(0) /** Log messages at level 0. * * Fatal errors and panic messages should be logged at level 0. @@ -100,7 +104,10 @@ SU_DEBUG_DEF(0) #endif #if SU_DEBUG_MAX >= 1 -SU_DEBUG_DEF(1) +//SU_DEBUG_DEF(1) +#define su_debug_1(_f, ...) su_llog(SU_LOG, 1, _f, __VA_ARGS__) + + /**Log messages at level 1. * * Critical errors and minimal progress at subsystem level should be logged @@ -114,7 +121,8 @@ SU_DEBUG_DEF(1) #endif #if SU_DEBUG_MAX >= 2 -SU_DEBUG_DEF(2) +//SU_DEBUG_DEF(2) +#define su_debug_2(_f, ...) su_llog(SU_LOG, 2, _f, __VA_ARGS__) /**Log messages at level 2. * * Non-critical errors should be logged at level 2. @@ -127,7 +135,8 @@ SU_DEBUG_DEF(2) #endif #if SU_DEBUG_MAX >= 3 -SU_DEBUG_DEF(3) +//SU_DEBUG_DEF(3) +#define su_debug_3(_f, ...) su_llog(SU_LOG, 3, _f, __VA_ARGS__) /** Log messages at level 3. * * Warnings and progress messages should be logged at level 3. @@ -140,7 +149,8 @@ SU_DEBUG_DEF(3) #endif #if SU_DEBUG_MAX >= 4 -SU_DEBUG_DEF(4) +//SU_DEBUG_DEF(4) +#define su_debug_4(_f, ...) su_llog(SU_LOG, 4, _f, __VA_ARGS__) /** Log messages at level 4. */ #define SU_DEBUG_4(x) (SU_LOG_LEVEL >= 4 ? (su_debug_4 x) : (void)0) #else @@ -148,7 +158,8 @@ SU_DEBUG_DEF(4) #endif #if SU_DEBUG_MAX >= 5 -SU_DEBUG_DEF(5) +//SU_DEBUG_DEF(5) +#define su_debug_5(_f, ...) su_llog(SU_LOG, 5, _f, __VA_ARGS__) /** Log messages at level 5. * * Signaling protocol actions (incoming packets, etc.) should be logged @@ -162,7 +173,8 @@ SU_DEBUG_DEF(5) #endif #if SU_DEBUG_MAX >= 6 -SU_DEBUG_DEF(6) +//SU_DEBUG_DEF(6) +#define su_debug_6(_f, ...) su_llog(SU_LOG, 6, _f, __VA_ARGS__) /** Log messages at level 6. */ #define SU_DEBUG_6(x) (SU_LOG_LEVEL >= 6 ? (su_debug_6 x) : (void)0) #else @@ -170,7 +182,8 @@ SU_DEBUG_DEF(6) #endif #if SU_DEBUG_MAX >= 7 -SU_DEBUG_DEF(7) +//SU_DEBUG_DEF(7) +#define su_debug_7(_f, ...) su_llog(SU_LOG, 7, _f, __VA_ARGS__) /** Log messages at level 7. * * Media protocol actions (incoming packets, etc) should be logged at level 7. @@ -183,7 +196,8 @@ SU_DEBUG_DEF(7) #endif #if SU_DEBUG_MAX >= 8 -SU_DEBUG_DEF(8) +//SU_DEBUG_DEF(8) +#define su_debug_8(_f, ...) su_llog(SU_LOG, 8, _f, __VA_ARGS__) /** Log messages at level 8. */ #define SU_DEBUG_8(x) (SU_LOG_LEVEL >= 8 ? (su_debug_8 x) : (void)0) #else @@ -191,7 +205,8 @@ SU_DEBUG_DEF(8) #endif #if SU_DEBUG_MAX >= 9 -SU_DEBUG_DEF(9) +//SU_DEBUG_DEF(9) +#define su_debug_9(_f, ...) su_llog(SU_LOG, 9, _f, __VA_ARGS__) /** Log messages at level 9. * * Entering/exiting functions, very verbatim progress should be logged at diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h index 128bf7aa76..d2916b2564 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h +++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su_log.h @@ -52,6 +52,15 @@ typedef struct su_log_s su_log_t; SOFIA_BEGIN_DECLS +#ifdef _MSC_VER +#define __SOFIA_FUNC__ __FUNCTION__ +#else +#define __SOFIA_FUNC__ (const char *)__func__ +#endif + + + + /** Prototype for logging function */ typedef void (su_logger_f)(void *stream, char const *fmt, va_list ap); @@ -77,9 +86,9 @@ enum { SU_LOG_MAX = 9 }; SOFIAPUBFUN void su_log(char const *fmt, ...) __attribute__ ((__format__ (printf, 1, 2))); -SOFIAPUBFUN void su_llog(su_log_t *log, unsigned level, char const *fmt, ...) - __attribute__ ((__format__ (printf, 3, 4))); -SOFIAPUBFUN void su_vllog(su_log_t *log, unsigned level, +SOFIAPUBFUN void _su_llog(su_log_t *log, unsigned level, const char *file, const char *func, int line, char const *fmt, ...) + __attribute__ ((__format__ (printf, 6, 7))); +SOFIAPUBFUN void _su_vllog(su_log_t *log, unsigned level, const char *file, const char *func, int line, char const *fmt, va_list ap); SOFIAPUBFUN void su_log_redirect(su_log_t *log, su_logger_f *f, void *stream); SOFIAPUBFUN void su_log_set_level(su_log_t *log, unsigned level); @@ -92,6 +101,9 @@ SOFIAPUBVAR su_log_t su_log_global[]; /** Log the latest su error message */ SOFIAPUBFUN void su_perror(char const *s); +#define su_llog(_l, _ll, _f, ...) _su_llog(_l, _ll, __FILE__, __SOFIA_FUNC__, __LINE__, _f, __VA_ARGS__) +#define su_vllog(_l, _ll, _f, ...) _su_vllog(_l, _ll, __FILE__, __SOFIA_FUNC__, __LINE__, _f, __VA_ARGS__) + /** Log the su error message. */ SOFIAPUBFUN void su_perror2(char const *s, int errcode); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c index c1c4fd23df..2261ff6bac 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c @@ -1260,7 +1260,7 @@ int bsd_localinfo(su_localinfo_t const hints[1], flags |= LI_NUMERIC; if (!(li = calloc(1, sizeof(*li) + sulen + ifnamelen))) { - SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n")); + SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n" VA_NONE)); error = ELI_MEMORY; break; } @@ -1629,7 +1629,7 @@ int li_name(su_localinfo_t const *hints, if (error) { if ((flags & LI_NAMEREQD) == LI_NAMEREQD) return 1; - SU_DEBUG_7(("li_name: getnameinfo() failed\n")); + SU_DEBUG_7(("li_name: getnameinfo() failed\n" VA_NONE)); if (!su_inet_ntop(su->su_family, SU_ADDR(su), name, sizeof name)) return ELI_RESOLVER; } diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_log.c b/libs/sofia-sip/libsofia-sip-ua/su/su_log.c index ad977312bb..f56998f7c0 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_log.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_log.c @@ -100,17 +100,23 @@ void su_log(char const *fmt, ...) * * @note This function is used mainly by SU_DEBUG_n() macros. */ -void su_llog(su_log_t *log, unsigned level, char const *fmt, ...) +void _su_llog(su_log_t *log, unsigned level, const char *file, const char *func, int line, + char const *fmt, ...) { va_list ap; - + char buf[512]; va_start(ap, fmt); - su_vllog(log, level, fmt, ap); + + + snprintf(buf, sizeof(buf), "%s:%d %s() %s", file, line, func, fmt); + + _su_vllog(log, level, file, func, line, buf, ap); va_end(ap); } /** Log a message with level (stdarg version). */ -void su_vllog(su_log_t *log, unsigned level, char const *fmt, va_list ap) +void _su_vllog(su_log_t *log, unsigned level, const char *file, const char *func, int line, + char const *fmt, va_list ap) { su_logger_f *logger; void *stream; @@ -133,8 +139,9 @@ void su_vllog(su_log_t *log, unsigned level, char const *fmt, va_list ap) stream = su_log_default->log_stream; } - if (logger) - logger(stream, fmt, ap); + if (logger) { + logger(stream, fmt, ap); + } } static char const not_initialized[1]; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c index cc94cf4681..eb79deba50 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c @@ -3350,7 +3350,7 @@ tport_t *tport_tsend(tport_t *self, if (!self) { msg_set_errno(msg, su_errno()); - SU_DEBUG_9(("tport_socket failed in tsend\n")); + SU_DEBUG_9(("tport_socket failed in tsend\n" VA_NONE)); return NULL; } @@ -3406,7 +3406,7 @@ int tport_prepare_and_send(tport_t *self, msg_t *msg, /* ...or we are connecting */ (self->tp_events & (SU_WAIT_CONNECT | SU_WAIT_OUT))) { if (tport_queue(self, msg) < 0) { - SU_DEBUG_9(("tport_queue failed in tsend\n")); + SU_DEBUG_9(("tport_queue failed in tsend\n" VA_NONE)); return -1; } return 0; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c index 72b212f728..42679d1675 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_connect.c @@ -201,7 +201,7 @@ static tport_t *tport_http_connect(tport_primary_t *pri, su_addrinfo_t *ai, msg_set_next(response, thci->thci_stackmsg = tport_msg_alloc(tport, 512)); if (tport_send_msg(tport, msg, tpn, NULL) < 0) { - SU_DEBUG_9(("tport_send_msg failed in tpot_http_connect\n")); + SU_DEBUG_9(("tport_send_msg failed in tpot_http_connect\n" VA_NONE)); msg_destroy(msg); tport_zap_secondary(tport); return NULL; From 6b9c2ca8af9bb90d85b759d0d8f28405329fd396 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 14:17:52 -0500 Subject: [PATCH 268/512] fix for new db stuff --- src/include/switch_core.h | 1 + src/switch_core_sqldb.c | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 0616c532f6..69a9b07576 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2425,6 +2425,7 @@ SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_recovery_flush(const char *technology, const char *profile_name); +SWITCH_DECLARE(int) switch_sql_queue_manager_size(switch_sql_queue_manager_t *qm, uint32_t index); SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 0cb6f9740d..9807d9905d 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1219,7 +1219,6 @@ struct switch_sql_queue_manager { switch_queue_t **sql_queue; uint32_t *pre_written; uint32_t *written; - int *sizes; uint32_t numq; char *dsn; switch_thread_t *thread; @@ -1257,6 +1256,18 @@ static uint32_t qm_ttl(switch_sql_queue_manager_t *qm) return ttl; } +SWITCH_DECLARE(int) switch_sql_queue_manager_size(switch_sql_queue_manager_t *qm, uint32_t index) +{ + int size = 0; + + switch_mutex_lock(qm->mutex); + if (index < qm->numq) { + size = switch_queue_size(qm->sql_queue[index]); + } + switch_mutex_unlock(qm->mutex); + + return size; +} SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm) { @@ -1335,8 +1346,11 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push(switch_sql_queue_m if (pos > qm->numq - 1) { pos = 0; } - + + switch_mutex_lock(qm->mutex); switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql); + switch_mutex_unlock(qm->mutex); + qm_wake(qm); return SWITCH_STATUS_SUCCESS; @@ -1360,11 +1374,10 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql pos = 0; } - switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql); - switch_mutex_lock(qm->mutex); + switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql); written = qm->written[pos]; - size = qm->sizes[pos]; + size = switch_sql_queue_manager_size(qm, pos); want = written + size; switch_mutex_unlock(qm->mutex); @@ -1416,7 +1429,6 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n switch_thread_cond_create(&qm->cond, qm->pool); qm->sql_queue = switch_core_alloc(qm->pool, sizeof(switch_queue_t *) * numq); - qm->sizes = switch_core_alloc(qm->pool, sizeof(int) * numq); qm->written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); qm->pre_written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); @@ -1650,7 +1662,6 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, switch_mutex_lock(qm->mutex); for (i = 0; i < qm->numq; i++) { - qm->sizes[i] = switch_queue_size(qm->sql_queue[i]); qm->written[i] += qm->pre_written[i]; qm->pre_written[i] = 0; } From b94ef869e38eb5bb050eb63f4fa70a8a6bd4b6b6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 14:46:36 -0500 Subject: [PATCH 269/512] FS-4769 try this patch and put {drop_dtmf=true} in your dial string --- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 ++++ src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia_glue.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 31adce6f18..ddf0b5dccf 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1511,6 +1511,10 @@ static switch_status_t sofia_send_dtmf(switch_core_session_t *session, const swi tech_pvt = (private_object_t *) switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); + if (sofia_test_flag(tech_pvt, TFLAG_DROP_DTMF)) { + return SWITCH_STATUS_SUCCESS; + } + dtmf_type = tech_pvt->dtmf_type; /* We only can send INFO when we have no media */ diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 799574da84..864d3a1e6f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -352,6 +352,7 @@ typedef enum { TFLAG_SLA_BARGING, TFLAG_PASS_ACK, TFLAG_CRYPTO_RECOVER, + TFLAG_DROP_DTMF, /* No new flags below this line */ TFLAG_MAX } TFLAGS; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index ac6ba9a9e9..105236cdbd 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -969,6 +969,11 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * switch_core_session_set_private(session, tech_pvt); + if (switch_true(switch_channel_get_variable_dup(tech_pvt->channel, "drop_dtmf", SWITCH_FALSE, -1))) { + sofia_set_flag(tech_pvt, TFLAG_DROP_DTMF); + } + + if (channame) { sofia_glue_set_name(tech_pvt, channame); } From 6bc230547cea34352c368e917ef40216fb305473 Mon Sep 17 00:00:00 2001 From: William King Date: Fri, 26 Oct 2012 15:45:51 -0700 Subject: [PATCH 270/512] Adding an anti pattern check option --- src/mod/xml_int/mod_xml_radius/mod_xml_radius.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c index d80e9e7d54..0b99166f98 100644 --- a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c +++ b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c @@ -838,7 +838,9 @@ switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switc switch_xml_t condition, param; char *channel_var = NULL; char *regex = NULL; + char *anti = NULL; int all_matched = 1; + int result = 0; if ( (condition = switch_xml_child(conditions, "condition")) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to locate a condition under the conditions section\n"); @@ -856,14 +858,19 @@ switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switc for (; param && all_matched; param = param->next) { channel_var = (char *) switch_xml_attr(param, "var"); regex = (char *) switch_xml_attr(param, "regex"); + anti = (char *) switch_xml_attr(param, "anti"); if ( channel_var == NULL || regex == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improperly constructed mod_radius condition: %s %s\n", channel_var, regex); } - if ( switch_regex_match( switch_channel_get_variable(channel, channel_var), regex) != SWITCH_STATUS_SUCCESS) { + result = ( switch_regex_match( switch_channel_get_variable(channel, channel_var), regex) != SWITCH_STATUS_SUCCESS); + if (( anti == NULL && result ) || ( anti != NULL && !result ) ){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Didn't match: %s == %s \n", switch_channel_get_variable(channel, channel_var), regex); all_matched = 0; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Result of %s match: %s == %s \n", + anti, switch_channel_get_variable(channel, channel_var), regex); } } From 0e2f33e2b095239991f9fe48aa47894a96f0f0ce Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 16:12:44 -0500 Subject: [PATCH 271/512] add mutex for good measure --- src/switch_core_sqldb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 9807d9905d..45ea99ba29 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1504,7 +1504,13 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, if (!proceed) { for (i = 0; i < qm->numq; i++) { - if (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { + switch_status_t status; + + switch_mutex_lock(qm->mutex); + status = switch_queue_trypop(qm->sql_queue[i], &pop); + switch_mutex_unlock(qm->mutex); + + if (status == SWITCH_STATUS_SUCCESS) { if (sql_manager.thread_running != 1) { if (pop) { switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL); From 3ef548eeb57e19613f065247f1ccd67d8a2717a8 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 27 Oct 2012 08:24:01 +0800 Subject: [PATCH 272/512] fix compile, please review --- libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c b/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c index 3dc882dd1e..d9ef55f2e9 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_os_nw.c @@ -105,7 +105,7 @@ void nw_changed_cb(SCDynamicStoreRef store, su_network_changed_t *snc2; su_msg_r rmsg = SU_MSG_R_INIT; - SU_DEBUG_7(("nw_changed_cb: entering.\n")); + SU_DEBUG_7(("nw_changed_cb: entering.\n" VA_NONE)); if (su_msg_create(rmsg, su_root_task(snc->su_root), From 9d4b72b29afaa2d9f36a6a8954ebfaf1f27c6dab Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 20:51:51 -0500 Subject: [PATCH 273/512] fold the last round of sql manager changes back into the core and use it for the central db and simplify the algorithm --- src/include/private/switch_core_pvt.h | 2 - src/include/switch_core.h | 5 +- src/switch_core.c | 38 +- src/switch_core_sqldb.c | 816 +++++++++----------------- 4 files changed, 269 insertions(+), 592 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index b7d5f75868..40f51ba61a 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -256,8 +256,6 @@ struct switch_runtime { switch_profile_timer_t *profile_timer; double profile_time; double min_idle_time; - int sql_buffer_len; - int max_sql_buffer_len; switch_dbtype_t odbc_dbtype; char hostname[256]; char *switchname; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 69a9b07576..73a8fc8f17 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2205,8 +2205,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *dest_proto, sw SWITCH_DECLARE(switch_status_t) switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event); SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_session_t *session, const char *cmds); -SWITCH_DECLARE(void) switch_core_sqldb_stop_thread(void); -SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void); +SWITCH_DECLARE(void) switch_core_sqldb_pause(void); +SWITCH_DECLARE(void) switch_core_sqldb_resume(void); + ///\} diff --git a/src/switch_core.c b/src/switch_core.c index 431ed8d3a1..73d96b2869 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1470,11 +1470,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.db_handle_timeout = 5000000; runtime.runlevel++; - runtime.sql_buffer_len = 1024 * 32; - runtime.max_sql_buffer_len = 1024 * 1024; runtime.dummy_cng_frame.data = runtime.dummy_data; runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); + runtime.dbname = "core"; switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG); switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); switch_set_flag((&runtime), SCF_CLEAR_SQL); @@ -1754,37 +1753,6 @@ static void switch_load_core_config(const char *file) } else if (!strcasecmp(var, "multiple-registrations")) { runtime.multiple_registrations = switch_true(val); - } else if (!strcasecmp(var, "sql-buffer-len")) { - int tmp = atoi(val); - - if (end_of(val) == 'k') { - tmp *= 1024; - } else if (end_of(val) == 'm') { - tmp *= (1024 * 1024); - } - - if (tmp >= 32000 && tmp < 10500000) { - runtime.sql_buffer_len = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql-buffer-len: Value is not within rage 32k to 10m\n"); - } - } else if (!strcasecmp(var, "max-sql-buffer-len")) { - int tmp = atoi(val); - - if (end_of(val) == 'k') { - tmp *= 1024; - } else if (end_of(val) == 'm') { - tmp *= (1024 * 1024); - } - - if (tmp < runtime.sql_buffer_len) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Value is not larger than sql-buffer-len\n"); - } else if (tmp >= 32000 && tmp < 10500000) { - runtime.max_sql_buffer_len = tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-sql-buffer-len: Value is not within rage 32k to 10m\n"); - } - } else if (!strcasecmp(var, "auto-create-schemas")) { if (switch_true(val)) { switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); @@ -2256,9 +2224,9 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void * break; case SCSC_SQL: if (oldintval) { - switch_core_sqldb_start_thread(); + switch_core_sqldb_resume(); } else { - switch_core_sqldb_stop_thread(); + switch_core_sqldb_pause(); } break; case SCSC_PAUSE_ALL: diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 45ea99ba29..6e449b6f7b 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -56,26 +56,25 @@ struct switch_cache_db_handle { }; static struct { - switch_cache_db_handle_t *event_db; - switch_queue_t *sql_queue[4]; switch_memory_pool_t *memory_pool; - switch_thread_t *thread; switch_thread_t *db_thread; - int thread_running; int db_thread_running; switch_bool_t manage; switch_mutex_t *io_mutex; switch_mutex_t *dbh_mutex; switch_mutex_t *ctl_mutex; switch_cache_db_handle_t *handle_pool; - switch_thread_cond_t *cond; - switch_mutex_t *cond_mutex; uint32_t total_handles; uint32_t total_used_handles; switch_cache_db_handle_t *dbh; + switch_sql_queue_manager_t *qm; + int paused; } sql_manager; +static void switch_core_sqldb_start_thread(void); +static void switch_core_sqldb_stop_thread(void); + static switch_cache_db_handle_t *create_handle(switch_cache_db_handle_type_t type) { switch_cache_db_handle_t *new_dbh = NULL; @@ -575,19 +574,6 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t return status; } -static void wake_thread(int force) -{ - if (force) { - switch_thread_cond_signal(sql_manager.cond); - return; - } - - if (switch_mutex_trylock(sql_manager.cond_mutex) == SWITCH_STATUS_SUCCESS) { - switch_thread_cond_signal(sql_manager.cond); - switch_mutex_unlock(sql_manager.cond_mutex); - } -} - /** OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions? **/ @@ -1195,7 +1181,6 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *threa while (sql_manager.db_thread_running == 1) { if (++sec == SQL_CACHE_TIMEOUT) { sql_close(switch_epoch_time_now(NULL)); - wake_thread(0); sec = 0; } @@ -1217,7 +1202,6 @@ struct switch_sql_queue_manager { const char *name; switch_cache_db_handle_t *event_db; switch_queue_t **sql_queue; - uint32_t *pre_written; uint32_t *written; uint32_t numq; char *dsn; @@ -1281,6 +1265,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_stop(switch_sql_queue_m } if (qm->thread) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Stopping SQL thread.\n", qm->name); switch_thread_join(&status, qm->thread); qm->thread = NULL; status = SWITCH_STATUS_SUCCESS; @@ -1294,7 +1279,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_start(switch_sql_queue_ switch_threadattr_t *thd_attr; if (!qm->thread_running) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting SQL thread.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Starting SQL thread.\n", qm->name); switch_threadattr_create(&thd_attr, qm->pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_priority_set(thd_attr, SWITCH_PRI_NORMAL); @@ -1306,24 +1291,40 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_start(switch_sql_queue_ } +static void do_flush(switch_queue_t *q, switch_cache_db_handle_t *dbh) +{ + void *pop = NULL; + + while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) { + if (pop) { + if (dbh) { + switch_cache_db_execute_sql(dbh, (char *) pop, NULL); + } + free(pop); + } + } + +} + SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp) { switch_sql_queue_manager_t *qm; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_memory_pool_t *pool; - void *pop; uint32_t i; switch_assert(qmp); qm = *qmp; *qmp = NULL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Destroying SQL queue.\n", qm->name); + switch_sql_queue_manager_stop(qm); + + for(i = 0; i < qm->numq; i++) { - while (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { - switch_safe_free(pop); - } + do_flush(qm->sql_queue[i], NULL); } pool = qm->pool; @@ -1335,14 +1336,17 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_destroy(switch_sql_queu SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup) { + if (sql_manager.paused) { + if (!dup) free((char *)sql); + qm_wake(qm); + return SWITCH_STATUS_SUCCESS; + } + if (!qm->thread_running) { + if (!dup) free((char *)sql); return SWITCH_STATUS_FALSE; } - if (sql_manager.thread_running != 1) { - return SWITCH_STATUS_FALSE; - } - if (pos > qm->numq - 1) { pos = 0; } @@ -1362,14 +1366,17 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql int size, x = 0, sanity = 0; uint32_t written, want; + if (sql_manager.paused) { + if (!dup) free((char *)sql); + qm_wake(qm); + return SWITCH_STATUS_SUCCESS; + } + if (!qm->thread_running) { + if (!dup) free((char *)sql); return SWITCH_STATUS_FALSE; } - if (sql_manager.thread_running != 1) { - return SWITCH_STATUS_FALSE; - } - if (pos > qm->numq - 1) { pos = 0; } @@ -1430,7 +1437,6 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n qm->sql_queue = switch_core_alloc(qm->pool, sizeof(switch_queue_t *) * numq); qm->written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); - qm->pre_written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); for (i = 0; i < qm->numq; i++) { switch_queue_create(&qm->sql_queue[i], SWITCH_SQL_QUEUE_LEN, qm->pool); @@ -1448,24 +1454,111 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n return SWITCH_STATUS_SUCCESS; } + +static uint32_t do_trans(switch_cache_db_handle_t *dbh, + switch_queue_t *q, + switch_mutex_t *mutex, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute) +{ + char *errmsg = NULL; + void *pop; + switch_status_t status; + uint32_t ttl = 0; + + if (!switch_queue_size(q)) { + return 0; + } + + switch(dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg); + } + break; + case SCDB_TYPE_ODBC: + { + switch_odbc_status_t result; + + if ((result = switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); + errmsg = strdup(tmp); + } + } + break; + case SCDB_TYPE_PGSQL: + { + switch_pgsql_status_t result; + + if ((result = switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); + errmsg = strdup(tmp); + } + } + break; + } + + if (errmsg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "ERROR [%s]\n", errmsg); + free(errmsg); + goto end; + } + + + for(;;) { + if (mutex) switch_mutex_lock(mutex); + status = switch_queue_trypop(q, &pop); + if (mutex) switch_mutex_unlock(mutex); + + if (status != SWITCH_STATUS_SUCCESS || !pop) break; + + if ((status = switch_cache_db_execute_sql(dbh, (char *) pop, NULL)) == SWITCH_STATUS_SUCCESS) { + ttl++; + } + free(pop); + + if (status != SWITCH_STATUS_SUCCESS) break; + } + + end: + + switch(dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL); + } + break; + case SCDB_TYPE_ODBC: + { + switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); + switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); + } + break; + case SCDB_TYPE_PGSQL: + { + switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1); + switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 1); + switch_pgsql_finish_results(dbh->native_handle.pgsql_dbh); + } + break; + } + + + + return ttl; +} + static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, void *obj) { - void *pop = NULL; - uint32_t iterations = 0; - uint8_t trans = 0; - uint32_t target = 20000; - switch_size_t len = 0, sql_len = runtime.sql_buffer_len; - char *tmp, *sqlbuf = (char *) malloc(sql_len); - char *sql = NULL, *save_sql = NULL; - switch_size_t newlen; - int lc = 0, wrote = 0, do_sleep = 1; + uint32_t sanity = 120; - int auto_pause = 0; switch_sql_queue_manager_t *qm = (switch_sql_queue_manager_t *) obj; uint32_t i; - switch_assert(sqlbuf); - while (!qm->event_db) { if (switch_cache_db_get_db_handle_dsn(&qm->event_db, qm->dsn) == SWITCH_STATUS_SUCCESS && qm->event_db) break; @@ -1498,428 +1591,75 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, break; } + while (qm->thread_running == 1) { - int proceed = !!save_sql; - int pindex = -1; + int lc; + int i; + uint32_t iterations = 0; - if (!proceed) { + if (sql_manager.paused) { for (i = 0; i < qm->numq; i++) { - switch_status_t status; - - switch_mutex_lock(qm->mutex); - status = switch_queue_trypop(qm->sql_queue[i], &pop); - switch_mutex_unlock(qm->mutex); - - if (status == SWITCH_STATUS_SUCCESS) { - if (sql_manager.thread_running != 1) { - if (pop) { - switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL); - free(pop); - pop = NULL; - } - } else { - pindex = i; - proceed = 1; - break; - } - } + do_flush(qm->sql_queue[i], NULL); } + goto check; } + + for (i = 0; i < qm->numq; i++) { + uint32_t written = do_trans(qm->event_db, qm->sql_queue[i], NULL, + qm->pre_trans_execute, + qm->post_trans_execute, + qm->inner_pre_trans_execute, + qm->inner_post_trans_execute); - if (proceed) { - - if (save_sql) { - sql = save_sql; - save_sql = NULL; - } else if ((sql = (char *) pop)) { - pop = NULL; + iterations += written; + + switch_mutex_lock(qm->mutex); + qm->written[i] += written; + switch_mutex_unlock(qm->mutex); + } + + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + char line[128] = ""; + int l; + + switch_snprintf(line, sizeof(line), "%s RUN QUEUE [", qm->name); + + for (i = 0; i < qm->numq; i++) { + l = strlen(line); + switch_snprintf(line + l, sizeof(line) - l, "%d%s", switch_queue_size(qm->sql_queue[i]), i == qm->numq - 1 ? "" : "|"); } - if (sql) { - newlen = strlen(sql) + 2; - - if (iterations == 0) { - trans = 1; - } - - if (len + newlen + 1 > sql_len) { - int new_mlen = len + newlen + 10240; - - if (new_mlen < runtime.max_sql_buffer_len) { - sql_len = new_mlen; - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - for (i = 0; i < qm->numq; i++) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "%s REALLOC QUEUE %ld %d %d\n", - qm->name, - (long int)sql_len, - i, - switch_queue_size(qm->sql_queue[i])); - - } - } - if (!(tmp = realloc(sqlbuf, sql_len))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s SQL thread ending on mem err\n", qm->name); - abort(); - break; - } - sqlbuf = tmp; - } else { - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - for (i = 0; i < qm->numq; i++) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "%s SAVE QUEUE %d %d\n", - qm->name, - i, - switch_queue_size(qm->sql_queue[i])); - - } - } - save_sql = sql; - sql = NULL; - lc = 0; - goto skip; - } - } - - switch_mutex_lock(qm->mutex); - qm->pre_written[pindex]++; - switch_mutex_unlock(qm->mutex); - - iterations++; - sprintf(sqlbuf + len, "%s;\n", sql); - len += newlen; - free(sql); - sql = NULL; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s, SQL thread ending\n", qm->name); - break; - } + l = strlen(line); + switch_snprintf(line + l, sizeof(line) - l, "]--[%d]\n", iterations); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s", line); + } - lc = qm_ttl(qm); - + check: - if (lc > SWITCH_SQL_QUEUE_PAUSE_LEN) { - if (!auto_pause) { - auto_pause = 1; - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); - auto_pause = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s, SQL Queue overflowing [%d], Pausing calls.\n", qm->name, lc); - } - } else { - if (auto_pause && lc < 1000) { - auto_pause = 0; - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); - auto_pause = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s, SQL Queue back to normal size, resuming..\n", qm->name); - } - } - - skip: - - wrote = 0; + lc = qm_ttl(qm); - if (trans && iterations && (iterations > target || !lc)) { - - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - char line[128] = ""; - int l; - - switch_snprintf(line, sizeof(line), "%s RUN QUEUE ", qm->name); - - for (i = 0; i < qm->numq; i++) { - l = strlen(line); - switch_snprintf(line + l, sizeof(line) - l, "%d:%d ", i, switch_queue_size(qm->sql_queue[i])); - } - - l = strlen(line); - switch_snprintf(line + l, sizeof(line) - l, "%d\n", iterations); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s", line); - - } - if (switch_cache_db_persistant_execute_trans_full(qm->event_db, sqlbuf, 1, - qm->pre_trans_execute, - qm->post_trans_execute, - qm->inner_pre_trans_execute, - qm->inner_post_trans_execute - ) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s SQL thread unable to commit transaction, records lost!\n", qm->name); - } - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s DONE\n", qm->name); - } - - iterations = 0; - trans = 0; - len = 0; - *sqlbuf = '\0'; - lc = 0; - if (do_sleep) { - switch_yield(200000); - } else { - switch_yield(1000); - } - wrote = 1; - } - - lc = qm_ttl(qm); - - switch_mutex_lock(qm->mutex); - for (i = 0; i < qm->numq; i++) { - qm->written[i] += qm->pre_written[i]; - qm->pre_written[i] = 0; - } - switch_mutex_unlock(qm->mutex); - if (!lc) { switch_thread_cond_wait(qm->cond, qm->cond_mutex); - } else if (wrote) { - if (lc > 2000) { - do_sleep = 0; - } else { - do_sleep = 1; - } + } else if (lc < 2000) { + switch_yield(200000); } } switch_mutex_unlock(qm->cond_mutex); for(i = 0; i < qm->numq; i++) { - while (switch_queue_trypop(qm->sql_queue[i], &pop) == SWITCH_STATUS_SUCCESS) { - if (pop) { - switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL); - free(pop); - } - } + do_flush(qm->sql_queue[i], qm->event_db); } - free(sqlbuf); - qm->thread_running = 0; switch_cache_db_release_db_handle(&qm->event_db); - + return NULL; } -static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, void *obj) -{ - void *pop = NULL; - uint32_t iterations = 0; - uint8_t trans = 0; - uint32_t target = 20000; - switch_size_t len = 0, sql_len = runtime.sql_buffer_len; - char *tmp, *sqlbuf = (char *) malloc(sql_len); - char *sql = NULL, *save_sql = NULL; - switch_size_t newlen; - int lc = 0, wrote = 0, do_sleep = 1; - uint32_t sanity = 120; - int auto_pause = 0; - - switch_assert(sqlbuf); - - while (!sql_manager.event_db) { - if (switch_core_db_handle(&sql_manager.event_db) == SWITCH_STATUS_SUCCESS && sql_manager.event_db) - break; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error getting core db, Retrying\n"); - switch_yield(500000); - sanity--; - } - - if (!sql_manager.event_db) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error getting core db Disabling core sql functionality\n"); - return NULL; - } - - sql_manager.thread_running = 1; - - switch_mutex_lock(sql_manager.cond_mutex); - - switch (sql_manager.event_db->type) { - case SCDB_TYPE_PGSQL: - break; - case SCDB_TYPE_ODBC: - break; - case SCDB_TYPE_CORE_DB: - { - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA synchronous=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA count_changes=OFF;", NULL); - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA temp_store=MEMORY;", NULL); - switch_cache_db_execute_sql(sql_manager.event_db, "PRAGMA journal_mode=OFF;", NULL); - } - break; - } - - while (sql_manager.thread_running == 1) { - if (save_sql || - switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || - switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS || - switch_queue_trypop(sql_manager.sql_queue[2], &pop) == SWITCH_STATUS_SUCCESS || - switch_queue_trypop(sql_manager.sql_queue[3], &pop) == SWITCH_STATUS_SUCCESS - ) { - - if (save_sql) { - sql = save_sql; - save_sql = NULL; - } else if ((sql = (char *) pop)) { - pop = NULL; - } - - if (sql) { - newlen = strlen(sql) + 2; - - if (iterations == 0) { - trans = 1; - } - - if (len + newlen + 1 > sql_len) { - int new_mlen = len + newlen + 10240; - - if (new_mlen < runtime.max_sql_buffer_len) { - sql_len = new_mlen; - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager.sql_queue[0]), - switch_queue_size(sql_manager.sql_queue[1])); - } - if (!(tmp = realloc(sqlbuf, sql_len))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n"); - abort(); - break; - } - sqlbuf = tmp; - } else { - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "SAVE %d %d %d %d\n", - switch_queue_size(sql_manager.sql_queue[0]), - switch_queue_size(sql_manager.sql_queue[1]), - switch_queue_size(sql_manager.sql_queue[2]), - switch_queue_size(sql_manager.sql_queue[3]) - ); - } - save_sql = sql; - sql = NULL; - lc = 0; - goto skip; - } - } - - iterations++; - sprintf(sqlbuf + len, "%s;\n", sql); - len += newlen; - free(sql); - sql = NULL; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "SQL thread ending\n"); - break; - } - } - - lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]) + - switch_queue_size(sql_manager.sql_queue[2]) + switch_queue_size(sql_manager.sql_queue[3]); - - - if (lc > SWITCH_SQL_QUEUE_PAUSE_LEN) { - if (!auto_pause) { - auto_pause = 1; - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); - auto_pause = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue overflowing [%d], Pausing calls.\n", lc); - } - } else { - if (auto_pause && lc < 1000) { - auto_pause = 0; - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &auto_pause); - auto_pause = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL Queue back to normal size, resuming..\n"); - } - } - - skip: - - wrote = 0; - - if (trans && iterations && (iterations > target || !lc)) { - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "RUN %d %d %d %d %d\n", - switch_queue_size(sql_manager.sql_queue[0]), - switch_queue_size(sql_manager.sql_queue[1]), - switch_queue_size(sql_manager.sql_queue[2]), - switch_queue_size(sql_manager.sql_queue[3]), - iterations); - } - if (switch_cache_db_persistant_execute_trans_full(sql_manager.event_db, sqlbuf, 1, - runtime.core_db_pre_trans_execute, - runtime.core_db_post_trans_execute, - runtime.core_db_inner_pre_trans_execute, - runtime.core_db_inner_post_trans_execute - ) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); - } - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DONE\n"); - } - - - iterations = 0; - trans = 0; - len = 0; - *sqlbuf = '\0'; - lc = 0; - if (do_sleep) { - switch_yield(200000); - } else { - switch_yield(1000); - } - wrote = 1; - } - - lc = switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]) + - switch_queue_size(sql_manager.sql_queue[2]) + switch_queue_size(sql_manager.sql_queue[3]); - - if (!lc) { - switch_thread_cond_wait(sql_manager.cond, sql_manager.cond_mutex); - } else if (wrote) { - if (lc > 2000) { - do_sleep = 0; - } else { - do_sleep = 1; - } - } - - - } - - switch_mutex_unlock(sql_manager.cond_mutex); - - while (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) { - free(pop); - } - - while (switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { - free(pop); - } - - while (switch_queue_trypop(sql_manager.sql_queue[2], &pop) == SWITCH_STATUS_SUCCESS) { - free(pop); - } - - while (switch_queue_trypop(sql_manager.sql_queue[3], &pop) == SWITCH_STATUS_SUCCESS) { - free(pop); - } - - free(sqlbuf); - - sql_manager.thread_running = 0; - - switch_cache_db_release_db_handle(&sql_manager.event_db); - - return NULL; -} static char *parse_presence_data_cols(switch_event_t *event) { @@ -2388,12 +2128,11 @@ static void core_event_handler(switch_event_t *event) for (i = 0; i < sql_idx; i++) { if (switch_stristr("update channels", sql[i]) || switch_stristr("delete from channels", sql[i])) { - switch_queue_push(sql_manager.sql_queue[1], sql[i]); + switch_sql_queue_manager_push(sql_manager.qm, sql[i], 1, SWITCH_FALSE); } else { - switch_queue_push(sql_manager.sql_queue[0], sql[i]); + switch_sql_queue_manager_push(sql_manager.qm, sql[i], 0, SWITCH_FALSE); } sql[i] = NULL; - wake_thread(0); } } } @@ -2770,6 +2509,11 @@ SWITCH_DECLARE(int) switch_core_recovery_recover(const char *technology, const c switch_cache_db_handle_t *dbh; int r = 0; + if (!sql_manager.manage) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DATABASE NOT AVAIALBLE, REVCOVERY NOT POSSIBLE\n"); + return 0; + } + if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); return 0; @@ -2839,16 +2583,21 @@ SWITCH_DECLARE(int) switch_core_recovery_recover(const char *technology, const c SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_core_dbtype(void) { - return sql_manager.event_db->type; + return sql_manager.qm ? sql_manager.qm->event_db->type : SCDB_TYPE_CORE_DB; } SWITCH_DECLARE(void) switch_core_sql_exec(const char *sql) { + if (!sql_manager.manage) { + return; + } + if (!switch_test_flag((&runtime), SCF_USE_SQL)) { return; } - switch_queue_push(sql_manager.sql_queue[3], strdup(sql)); + + switch_sql_queue_manager_push(sql_manager.qm, sql, 3, SWITCH_TRUE); } SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session, switch_bool_t force) @@ -2856,6 +2605,10 @@ SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session char *sql = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); + if (!sql_manager.manage) { + return; + } + if (!switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_get_state(channel) < CS_SOFT_EXECUTE) { return; } @@ -2878,7 +2631,7 @@ SWITCH_DECLARE(void) switch_core_recovery_untrack(switch_core_session_t *session switch_core_get_uuid(), switch_core_session_get_uuid(session)); } - switch_queue_push(sql_manager.sql_queue[3], sql); + switch_sql_queue_manager_push(sql_manager.qm, sql, 3, SWITCH_FALSE); switch_channel_clear_flag(channel, CF_TRACKED); } @@ -2894,6 +2647,9 @@ SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session) const char *profile_name; const char *technology; + if (!sql_manager.manage) { + return; + } if (!switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_get_state(channel) < CS_SOFT_EXECUTE) { return; @@ -2921,7 +2677,7 @@ SWITCH_DECLARE(void) switch_core_recovery_track(switch_core_session_t *session) switch_str_nil(profile_name), switch_core_get_hostname(), switch_core_session_get_uuid(session), xml_cdr_text); } - switch_queue_push(sql_manager.sql_queue[2], sql); + switch_sql_queue_manager_push(sql_manager.qm, sql, 2, SWITCH_FALSE); free(xml_cdr_text); switch_channel_set_flag(channel, CF_TRACKED); @@ -2950,7 +2706,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c user, realm, switch_core_get_switchname()); } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); if ( !zstr(metadata) ) { sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname,metadata) " @@ -2982,7 +2738,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); return SWITCH_STATUS_SUCCESS; } @@ -3002,7 +2758,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_del_registration(const char *user, c sql = switch_mprintf("delete from registrations where reg_user='%q' and realm='%q' and hostname='%q'", user, realm, switch_core_get_switchname()); } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); + return SWITCH_STATUS_SUCCESS; } @@ -3025,7 +2782,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force) sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_switchname()); } - switch_queue_push(sql_manager.sql_queue[0], sql); + switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); return SWITCH_STATUS_SUCCESS; @@ -3034,20 +2791,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_expire_registration(int force) switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage) { switch_threadattr_t *thd_attr; - uint32_t sanity = 400; sql_manager.memory_pool = pool; sql_manager.manage = manage; switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); - switch_mutex_init(&sql_manager.cond_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); switch_mutex_init(&sql_manager.ctl_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); - switch_thread_cond_create(&sql_manager.cond, sql_manager.memory_pool); - - - if (!sql_manager.manage) goto skip; top: @@ -3117,6 +2868,15 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_cache_db_test_reactive(sql_manager.dbh, "select metadata from registrations", NULL, "ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256)"); + switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from recovery", "DROP TABLE recovery", recovery_sql); + switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery1 on recovery(technology)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery2 on recovery(profile_name)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery3 on recovery(uuid)", NULL); + switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery3 on recovery(runtime_uuid)", NULL); + + + + switch (sql_manager.dbh->type) { case SCDB_TYPE_PGSQL: case SCDB_TYPE_ODBC: @@ -3227,126 +2987,76 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_event_bind("core_db", SWITCH_EVENT_NAT, SWITCH_EVENT_SUBCLASS_ANY, core_event_handler, NULL); #endif - switch_queue_create(&sql_manager.sql_queue[0], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); - switch_queue_create(&sql_manager.sql_queue[1], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); - switch_queue_create(&sql_manager.sql_queue[2], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); - switch_queue_create(&sql_manager.sql_queue[3], SWITCH_SQL_QUEUE_LEN, sql_manager.memory_pool); - switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_core_sqldb_start_thread(); switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); - while (sql_manager.manage && !sql_manager.thread_running && --sanity) { - switch_yield(10000); - } } return SWITCH_STATUS_SUCCESS; } - -SWITCH_DECLARE(void) switch_core_sqldb_stop_thread(void) +SWITCH_DECLARE(void) switch_core_sqldb_pause(void) { - switch_mutex_lock(sql_manager.ctl_mutex); - if (sql_manager.thread && sql_manager.thread_running) { - switch_status_t st; - - if (sql_manager.manage) { - switch_queue_push(sql_manager.sql_queue[0], NULL); - switch_queue_push(sql_manager.sql_queue[1], NULL); - switch_queue_push(sql_manager.sql_queue[2], NULL); - switch_queue_push(sql_manager.sql_queue[3], NULL); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n"); - wake_thread(0); - sql_manager.thread_running = -1; - switch_thread_join(&st, sql_manager.thread); - sql_manager.thread = NULL; - switch_cache_db_release_db_handle(&sql_manager.dbh); - sql_manager.dbh = NULL; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL is not enabled\n"); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is not running\n"); + if (sql_manager.paused) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL is already paused.\n"); } - switch_mutex_unlock(sql_manager.ctl_mutex); + sql_manager.paused = 1; } -SWITCH_DECLARE(void) switch_core_sqldb_start_thread(void) +SWITCH_DECLARE(void) switch_core_sqldb_resume(void) { - switch_cache_db_handle_t *dbh; - - switch_mutex_lock(sql_manager.ctl_mutex); - - if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - - if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { - int arg = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC OR PGSQL IS REQUIRED!\n"); - switch_core_session_ctl(SCSC_SHUTDOWN_NOW, &arg); - } - - - } else { - switch_cache_db_test_reactive(dbh, "select hostname from recovery", "DROP TABLE recovery", recovery_sql); - switch_cache_db_execute_sql(dbh, "create index recovery1 on recovery(technology)", NULL); - switch_cache_db_execute_sql(dbh, "create index recovery2 on recovery(profile_name)", NULL); - switch_cache_db_execute_sql(dbh, "create index recovery3 on recovery(uuid)", NULL); - switch_cache_db_execute_sql(dbh, "create index recovery3 on recovery(runtime_uuid)", NULL); - switch_cache_db_release_db_handle(&dbh); + if (!sql_manager.paused) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SQL is already running.\n"); } + sql_manager.paused = 0; +} +static void switch_core_sqldb_stop_thread(void) +{ + switch_mutex_lock(sql_manager.ctl_mutex); if (sql_manager.manage) { - - top: - - if (!sql_manager.dbh) { - /* Activate SQL database */ - if (switch_core_db_handle(&sql_manager.dbh) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB!\n"); - - if (switch_test_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC OR PGSQL IS REQUIRED!\n"); - goto end; - } - - if (runtime.odbc_dsn) { - runtime.odbc_dsn = NULL; - runtime.odbc_dbtype = DBTYPE_DEFAULT; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Falling back to core_db.\n"); - sql_manager.dbh = NULL; - goto top; - } - - - switch_clear_flag((&runtime), SCF_USE_SQL); - goto end; - } - - switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "delete from calls", NULL); - } - - - if (!sql_manager.thread) { - switch_threadattr_t *thd_attr; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Starting SQL thread.\n"); - switch_threadattr_create(&thd_attr, sql_manager.memory_pool); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL thread is already running\n"); + if (sql_manager.qm) { + switch_sql_queue_manager_destroy(&sql_manager.qm); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL is not enabled\n"); } + + switch_mutex_unlock(sql_manager.ctl_mutex); +} - end: +static void switch_core_sqldb_start_thread(void) +{ + switch_mutex_lock(sql_manager.ctl_mutex); + if (sql_manager.manage) { + if (!sql_manager.qm) { + char *dbname = runtime.odbc_dsn; + + if (zstr(dbname)) { + dbname = runtime.dbname; + if (zstr(dbname)) { + dbname = "core"; + } + } + + switch_sql_queue_manager_init_name("CORE", + &sql_manager.qm, + 4, + dbname, + runtime.core_db_pre_trans_execute, + runtime.core_db_post_trans_execute, + runtime.core_db_inner_pre_trans_execute, + runtime.core_db_inner_post_trans_execute); + + } + switch_sql_queue_manager_start(sql_manager.qm); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL is not enabled\n"); + } switch_mutex_unlock(sql_manager.ctl_mutex); } From 0e139e1c0ed58d09cd5903799130d75ef46f6745 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 26 Oct 2012 21:00:25 -0500 Subject: [PATCH 274/512] missed a spot --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 6e449b6f7b..708577d823 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1605,7 +1605,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, } for (i = 0; i < qm->numq; i++) { - uint32_t written = do_trans(qm->event_db, qm->sql_queue[i], NULL, + uint32_t written = do_trans(qm->event_db, qm->sql_queue[i], qm->mutex, qm->pre_trans_execute, qm->post_trans_execute, qm->inner_pre_trans_execute, From 0fa6826a803fff200ecdd83008cc42bdfbc307b3 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sat, 27 Oct 2012 11:20:34 -0500 Subject: [PATCH 275/512] trivial compiler warning fix + vs2010 reswig --- .../mod_managed/freeswitch_wrap.2010.cxx | 22 +++++++++++++---- .../mod_managed/managed/swig.2010.cs | 24 ++++++++++++------- src/switch_core_sqldb.c | 2 +- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index e76d081416..3183c52bb2 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -11064,13 +11064,13 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_preprocess_session(void * jarg1, ch } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_stop_thread() { - switch_core_sqldb_stop_thread(); +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_pause() { + switch_core_sqldb_pause(); } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_start_thread() { - switch_core_sqldb_start_thread(); +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_resume() { + switch_core_sqldb_resume(); } @@ -11986,6 +11986,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_recovery_flush(char * jarg1, char } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_size(void * jarg1, unsigned long jarg2) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + uint32_t arg2 ; + int result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + arg2 = (uint32_t)jarg2; + result = (int)switch_sql_queue_manager_size(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_push_confirm(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { int jresult ; switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 5fa0f55fbe..a5ec72534d 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -2642,12 +2642,12 @@ public class freeswitch { return ret; } - public static void switch_core_sqldb_stop_thread() { - freeswitchPINVOKE.switch_core_sqldb_stop_thread(); + public static void switch_core_sqldb_pause() { + freeswitchPINVOKE.switch_core_sqldb_pause(); } - public static void switch_core_sqldb_start_thread() { - freeswitchPINVOKE.switch_core_sqldb_start_thread(); + public static void switch_core_sqldb_resume() { + freeswitchPINVOKE.switch_core_sqldb_resume(); } public static string switch_cache_db_type_name(switch_cache_db_handle_type_t type) { @@ -2842,6 +2842,11 @@ public class freeswitch { freeswitchPINVOKE.switch_core_recovery_flush(technology, profile_name); } + public static int switch_sql_queue_manager_size(SWIGTYPE_p_switch_sql_queue_manager qm, uint index) { + int ret = freeswitchPINVOKE.switch_sql_queue_manager_size(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), index); + return ret; + } + public static switch_status_t switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); return ret; @@ -9296,11 +9301,11 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_preprocess_session")] public static extern int switch_ivr_preprocess_session(HandleRef jarg1, string jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_stop_thread")] - public static extern void switch_core_sqldb_stop_thread(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_pause")] + public static extern void switch_core_sqldb_pause(); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_start_thread")] - public static extern void switch_core_sqldb_start_thread(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_resume")] + public static extern void switch_core_sqldb_resume(); [DllImport("mod_managed", EntryPoint="CSharp_CACHE_DB_LEN_get")] public static extern int CACHE_DB_LEN_get(); @@ -9524,6 +9529,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_recovery_flush")] public static extern void switch_core_recovery_flush(string jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_size")] + public static extern int switch_sql_queue_manager_size(HandleRef jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_push_confirm")] public static extern int switch_sql_queue_manager_push_confirm(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 708577d823..728f650bb7 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1594,7 +1594,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, while (qm->thread_running == 1) { int lc; - int i; + uint32_t i; uint32_t iterations = 0; if (sql_manager.paused) { From 60f7849cbe726a7c5a70bb9f2f8036dafd9b3469 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 27 Oct 2012 11:32:40 -0500 Subject: [PATCH 276/512] FS-4769 should work now --- src/mod/endpoints/mod_sofia/sofia_glue.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 105236cdbd..15b6eb0eeb 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -486,6 +486,10 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch tech_pvt->session_id = tech_pvt->owner_id; } + if (switch_true(switch_channel_get_variable_dup(tech_pvt->channel, "drop_dtmf", SWITCH_FALSE, -1))) { + sofia_set_flag(tech_pvt, TFLAG_DROP_DTMF); + } + tech_pvt->session_id++; if ((tech_pvt->profile->ndlb & PFLAG_NDLB_SENDRECV_IN_SESSION) || @@ -969,10 +973,6 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * switch_core_session_set_private(session, tech_pvt); - if (switch_true(switch_channel_get_variable_dup(tech_pvt->channel, "drop_dtmf", SWITCH_FALSE, -1))) { - sofia_set_flag(tech_pvt, TFLAG_DROP_DTMF); - } - if (channame) { sofia_glue_set_name(tech_pvt, channame); From 96550e893e1305265b185bedb6a1a25f7cbf1ae2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 27 Oct 2012 12:27:00 -0500 Subject: [PATCH 277/512] finish off sql optimization --- src/include/switch_core.h | 14 ++--- src/include/switch_types.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 24 ++++---- src/switch_core_sqldb.c | 93 ++++++++++++++++++++++------- 4 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 73a8fc8f17..bc8b403961 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2431,14 +2431,14 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push(switch_sql_queue_manager_t *qm, const char *sql, uint32_t pos, switch_bool_t dup); SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_destroy(switch_sql_queue_manager_t **qmp); SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *name, - switch_sql_queue_manager_t **qmp, - uint32_t numq, const char *dsn, - const char *pre_trans_execute, - const char *post_trans_execute, - const char *inner_pre_trans_execute, - const char *inner_post_trans_execute); + switch_sql_queue_manager_t **qmp, + uint32_t numq, const char *dsn, uint32_t max_trans, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute); -#define switch_sql_queue_manager_init(_q, _n, _d, _p1, _p2, _ip1, _ip2) switch_sql_queue_manager_init_name(__FILE__, _q, _n, _d, _p1, _p2, _ip1, _ip2) +#define switch_sql_queue_manager_init(_q, _n, _d, _m, _p1, _p2, _ip1, _ip2) switch_sql_queue_manager_init_name(__FILE__, _q, _n, _d, _m, _p1, _p2, _ip1, _ip2) SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_start(switch_sql_queue_manager_t *qm); SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_stop(switch_sql_queue_manager_t *qm); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index b766d1db40..25e2525e4a 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -213,6 +213,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_BITS_PER_BYTE 8 #define SWITCH_DEFAULT_FILE_BUFFER_LEN 65536 #define SWITCH_DTMF_LOG_LEN 1000 +#define SWITCH_MAX_TRANS 2000 typedef uint8_t switch_byte_t; /*! diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 9f467059fb..4550c5e716 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1638,7 +1638,7 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj if (pop) { sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop; sofia_process_dispatch_event(&de); - switch_os_yield(); + switch_cond_next(); } else { break; } @@ -1959,12 +1959,7 @@ void sofia_event_callback(nua_event_t event, end: - if (profile->pres_type) { - switch_cond_next(); - } else { - switch_os_yield(); - } - + switch_cond_next(); return; } @@ -2532,13 +2527,14 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name); switch_sql_queue_manager_init_name(qname, - &profile->qm, - 1, - profile->odbc_dsn ? profile->odbc_dsn : profile->dbname, - profile->pre_trans_execute, - profile->post_trans_execute, - profile->inner_pre_trans_execute, - profile->inner_post_trans_execute); + &profile->qm, + 1, + profile->odbc_dsn ? profile->odbc_dsn : profile->dbname, + SWITCH_MAX_TRANS, + profile->pre_trans_execute, + profile->post_trans_execute, + profile->inner_pre_trans_execute, + profile->inner_post_trans_execute); switch_sql_queue_manager_start(profile->qm); if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) { diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 728f650bb7..b677829edf 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1215,6 +1215,7 @@ struct switch_sql_queue_manager { char *inner_pre_trans_execute; char *inner_post_trans_execute; switch_memory_pool_t *pool; + uint32_t max_trans; }; static int qm_wake(switch_sql_queue_manager_t *qm) @@ -1410,12 +1411,12 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *name, - switch_sql_queue_manager_t **qmp, - uint32_t numq, const char *dsn, - const char *pre_trans_execute, - const char *post_trans_execute, - const char *inner_pre_trans_execute, - const char *inner_post_trans_execute) + switch_sql_queue_manager_t **qmp, + uint32_t numq, const char *dsn, uint32_t max_trans, + const char *pre_trans_execute, + const char *post_trans_execute, + const char *inner_pre_trans_execute, + const char *inner_post_trans_execute) { switch_memory_pool_t *pool; switch_sql_queue_manager_t *qm; @@ -1430,6 +1431,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n qm->numq = numq; qm->dsn = switch_core_strdup(qm->pool, dsn); qm->name = switch_core_strdup(qm->pool, name); + qm->max_trans = max_trans; switch_mutex_init(&qm->cond_mutex, SWITCH_MUTEX_NESTED, qm->pool); switch_mutex_init(&qm->mutex, SWITCH_MUTEX_NESTED, qm->pool); @@ -1458,6 +1460,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n static uint32_t do_trans(switch_cache_db_handle_t *dbh, switch_queue_t *q, switch_mutex_t *mutex, + uint32_t max, const char *pre_trans_execute, const char *post_trans_execute, const char *inner_pre_trans_execute, @@ -1467,11 +1470,22 @@ static uint32_t do_trans(switch_cache_db_handle_t *dbh, void *pop; switch_status_t status; uint32_t ttl = 0; + switch_mutex_t *io_mutex = dbh->io_mutex; if (!switch_queue_size(q)) { return 0; } + if (io_mutex) switch_mutex_lock(io_mutex); + + if (!zstr(pre_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, pre_trans_execute, &errmsg); + if (errmsg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", pre_trans_execute, errmsg); + free(errmsg); + } + } + switch(dbh->type) { case SCDB_TYPE_CORE_DB: { @@ -1509,7 +1523,15 @@ static uint32_t do_trans(switch_cache_db_handle_t *dbh, } - for(;;) { + if (!zstr(inner_pre_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, inner_pre_trans_execute, &errmsg); + if (errmsg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", inner_pre_trans_execute, errmsg); + free(errmsg); + } + } + + while(max == 0 || ttl <= max) { if (mutex) switch_mutex_lock(mutex); status = switch_queue_trypop(q, &pop); if (mutex) switch_mutex_unlock(mutex); @@ -1524,6 +1546,15 @@ static uint32_t do_trans(switch_cache_db_handle_t *dbh, if (status != SWITCH_STATUS_SUCCESS) break; } + if (!zstr(inner_post_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, inner_post_trans_execute, &errmsg); + if (errmsg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", inner_post_trans_execute, errmsg); + free(errmsg); + } + } + + end: switch(dbh->type) { @@ -1548,6 +1579,15 @@ static uint32_t do_trans(switch_cache_db_handle_t *dbh, } + if (!zstr(post_trans_execute)) { + switch_cache_db_execute_sql_real(dbh, post_trans_execute, &errmsg); + if (errmsg) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", post_trans_execute, errmsg); + free(errmsg); + } + } + + if (io_mutex) switch_mutex_unlock(io_mutex); return ttl; } @@ -1557,7 +1597,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, uint32_t sanity = 120; switch_sql_queue_manager_t *qm = (switch_sql_queue_manager_t *) obj; - uint32_t i; + uint32_t i, countdown = 0; while (!qm->event_db) { if (switch_cache_db_get_db_handle_dsn(&qm->event_db, qm->dsn) == SWITCH_STATUS_SUCCESS && qm->event_db) @@ -1605,17 +1645,23 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, } for (i = 0; i < qm->numq; i++) { - uint32_t written = do_trans(qm->event_db, qm->sql_queue[i], qm->mutex, - qm->pre_trans_execute, - qm->post_trans_execute, - qm->inner_pre_trans_execute, - qm->inner_post_trans_execute); + while(switch_queue_size(qm->sql_queue[i])) { + uint32_t written = do_trans(qm->event_db, qm->sql_queue[i], qm->mutex, qm->max_trans, + qm->pre_trans_execute, + qm->post_trans_execute, + qm->inner_pre_trans_execute, + qm->inner_post_trans_execute); - iterations += written; + iterations += written; - switch_mutex_lock(qm->mutex); - qm->written[i] += written; - switch_mutex_unlock(qm->mutex); + switch_mutex_lock(qm->mutex); + qm->written[i] += written; + switch_mutex_unlock(qm->mutex); + + if (written < qm->max_trans) { + break; + } + } } if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { @@ -1638,12 +1684,14 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, check: - lc = qm_ttl(qm); + countdown = 40; - if (!lc) { - switch_thread_cond_wait(qm->cond, qm->cond_mutex); - } else if (lc < 2000) { - switch_yield(200000); + while (--countdown && (lc = qm_ttl(qm)) < qm->max_trans / 4) { + if (lc == 0) { + switch_thread_cond_wait(qm->cond, qm->cond_mutex); + break; + } + switch_yield(5000); } } @@ -3047,6 +3095,7 @@ static void switch_core_sqldb_start_thread(void) &sql_manager.qm, 4, dbname, + SWITCH_MAX_TRANS, runtime.core_db_pre_trans_execute, runtime.core_db_post_trans_execute, runtime.core_db_inner_pre_trans_execute, From 652da36862cf005c88e1dda5af5c6c362b652de1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 27 Oct 2012 12:34:35 -0500 Subject: [PATCH 278/512] fix id-less bug from mailing list .. USE JIRA DANG IT --- src/mod/endpoints/mod_sofia/sofia_presence.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 181bd24a0a..17ab6b6efa 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -4132,7 +4132,6 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n char *pd_dup = NULL; int count = 1, sub_count = 1; char *contact_str; - int open = 1; sofia_nat_parse_t np = { { 0 } }; if (!sip) { @@ -4199,11 +4198,10 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n if (!strcasecmp(open_closed, "closed")) { rpid = note_txt = "Unregistered"; - } - - if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !open) { - count = sofia_reg_reg_count(profile, from_user, from_host); - sub_count = sofia_presence_contact_count(profile, contact_str); + if (sofia_test_pflag(profile, PFLAG_MULTIREG)) { + count = sofia_reg_reg_count(profile, from_user, from_host); + sub_count = sofia_presence_contact_count(profile, contact_str); + } } /* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */ From 3d090357cfef389e705d7e27cfdcf5a9a940170f Mon Sep 17 00:00:00 2001 From: Matteo Brancaleoni Date: Mon, 29 Oct 2012 11:58:22 +0100 Subject: [PATCH 279/512] ftmod_libpri: Always send PROGRESS messages with PROGRESS INDICATOR IE PROGRESS without PROGRESS INDICATOR IE is invalid according to Q.931, so always call pri_progress() with info flag set, even if we do not have media yet. Signed-off-by: Stefan Knoblich --- libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 3b819df718..2f1a5ff9ed 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -974,7 +974,13 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); } } else if (call) { - pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); + /* + * Even if we have no media, sending progress without PI is forbidden + * by Q.931 3.1.8, so a protocol error will be issued from libpri + * and from remote equipment. + * So just pretend we have PI. + */ + pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); } else { ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); } From 5533d713667d900c0df4da8ba97e98bdfe70dabc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 07:49:25 -0500 Subject: [PATCH 280/512] put back the hangup one for the time being --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b677829edf..d1b83426d8 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1973,7 +1973,7 @@ static void core_event_handler(switch_event_t *event) case CS_NEW: case CS_DESTROY: case CS_REPORTING: - case CS_HANGUP: + //case CS_HANGUP: /* marked for deprication */ case CS_INIT: break; case CS_EXECUTE: From f657a3787b81cb0f248852dc40381798023f9c3b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 08:23:21 -0500 Subject: [PATCH 281/512] fix regression from config refactor in rescan behaviour to pick up new gateways --- src/mod/endpoints/mod_sofia/sofia.c | 118 +++++++++++++++++++++------- 1 file changed, 91 insertions(+), 27 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 4550c5e716..10cc5ce51e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4581,40 +4581,104 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } } - if (profile && !profile_already_started) { - switch_xml_t aliases_tag, alias_tag; - if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) { - for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) { - char *aname = (char *) switch_xml_attr_soft(alias_tag, "name"); - if (!zstr(aname)) { + if (profile) { + if (profile_already_started) { + switch_xml_t gateways_tag, domain_tag, domains_tag, aliases_tag, alias_tag; - if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n", - aname, profile->name); + if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)) { + sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION); + } + + if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) { + parse_gateways(profile, gateways_tag); + } + + status = SWITCH_STATUS_SUCCESS; + + if ((domains_tag = switch_xml_child(xprofile, "domains"))) { + switch_event_t *xml_params; + switch_event_create(&xml_params, SWITCH_EVENT_REQUEST_PARAMS); + switch_assert(xml_params); + switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "purpose", "gateways"); + switch_event_add_header_string(xml_params, SWITCH_STACK_BOTTOM, "profile", profile->name); + + for (domain_tag = switch_xml_child(domains_tag, "domain"); domain_tag; domain_tag = domain_tag->next) { + switch_xml_t droot, x_domain_tag; + const char *dname = switch_xml_attr_soft(domain_tag, "name"); + const char *parse = switch_xml_attr_soft(domain_tag, "parse"); + const char *alias = switch_xml_attr_soft(domain_tag, "alias"); + + if (!zstr(dname)) { + if (!strcasecmp(dname, "all")) { + switch_xml_t xml_root, x_domains; + if (switch_xml_locate("directory", NULL, NULL, NULL, &xml_root, &x_domains, xml_params, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { + for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) { + dname = switch_xml_attr_soft(x_domain_tag, "name"); + parse_domain_tag(profile, x_domain_tag, dname, parse, alias); + } + switch_xml_free(xml_root); + } + } else if (switch_xml_locate_domain(dname, xml_params, &droot, &x_domain_tag) == SWITCH_STATUS_SUCCESS) { + parse_domain_tag(profile, x_domain_tag, dname, parse, alias); + switch_xml_free(droot); + } + } + } + + switch_event_destroy(&xml_params); + } + + if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) { + for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) { + char *aname = (char *) switch_xml_attr_soft(alias_tag, "name"); + if (!zstr(aname)) { + + if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Alias [%s] for profile [%s] (already exists)\n", + aname, profile->name); + } } } } - } - - if (profile->sipip) { - launch_sofia_profile_thread(profile); - if (profile->odbc_dsn) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Connecting ODBC Profile %s [%s]\n", profile->name, url); - switch_yield(1000000); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url); - } + } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name); - sofia_profile_start_failure(profile, profile->name); + switch_xml_t aliases_tag, alias_tag; + + if ((aliases_tag = switch_xml_child(xprofile, "aliases"))) { + for (alias_tag = switch_xml_child(aliases_tag, "alias"); alias_tag; alias_tag = alias_tag->next) { + char *aname = (char *) switch_xml_attr_soft(alias_tag, "name"); + if (!zstr(aname)) { + + if (sofia_glue_add_profile(switch_core_strdup(profile->pool, aname), profile) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Alias [%s] for profile [%s]\n", aname, profile->name); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding Alias [%s] for profile [%s] (name in use)\n", + aname, profile->name); + } + } + } + } + + if (profile->sipip) { + launch_sofia_profile_thread(profile); + if (profile->odbc_dsn) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Connecting ODBC Profile %s [%s]\n", profile->name, url); + switch_yield(1000000); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Unable to start Profile %s due to no configured sip-ip\n", profile->name); + sofia_profile_start_failure(profile, profile->name); + } + profile = NULL; + } + if (profile_found) { + break; } - profile = NULL; - } - if (profile_found) { - break; } } } From fe5dbf3b03240b23a0447e4d389da8a36f08443f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 09:27:08 -0500 Subject: [PATCH 282/512] FS-4770 --resolve --- src/include/switch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/switch.h b/src/include/switch.h index 3cfa271be4..2f7ac02f7f 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -106,7 +106,7 @@ #include #include -#include "../../../libs/stfu/stfu.h" +#include "stfu.h" #include "switch_platform.h" #include "switch_types.h" #include "switch_apr.h" From 759d26db09e97456aa39a91079f478b0d8a31627 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 09:27:59 -0500 Subject: [PATCH 283/512] FS-4771 --resolve --- src/include/switch_types.h | 1 + src/switch_core.c | 9 +++++++++ src/switch_loadable_module.c | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 25e2525e4a..ff8c55a521 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -464,6 +464,7 @@ typedef struct { struct switch_directories { char *base_dir; char *mod_dir; + char *lib_dir; char *conf_dir; char *log_dir; char *run_dir; diff --git a/src/switch_core.c b/src/switch_core.c index 73d96b2869..4682d3c002 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -575,6 +575,14 @@ SWITCH_DECLARE(void) switch_core_set_globals(void) #endif } + if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_LIB_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) { #ifdef SWITCH_CONF_DIR switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR); @@ -671,6 +679,7 @@ SWITCH_DECLARE(void) switch_core_set_globals(void) switch_assert(SWITCH_GLOBAL_dirs.base_dir); switch_assert(SWITCH_GLOBAL_dirs.mod_dir); + switch_assert(SWITCH_GLOBAL_dirs.lib_dir); switch_assert(SWITCH_GLOBAL_dirs.conf_dir); switch_assert(SWITCH_GLOBAL_dirs.log_dir); switch_assert(SWITCH_GLOBAL_dirs.run_dir); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 3a79c3e024..d87d37f7fc 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1219,7 +1219,11 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena #ifdef WIN32 dso = switch_dso_open("FreeSwitch.dll", load_global, &derr); #elif defined (MACOSX) || defined(DARWIN) - dso = switch_dso_open(SWITCH_PREFIX_DIR "/lib/libfreeswitch.dylib", load_global, &derr); + { + char *lib_path = switch_mprintf("%s/libfreeswitch.dylib", SWITCH_GLOBAL_dirs.lib_dir); + dso = switch_dso_open(lib_path, load_global, &derr); + switch_safe_free(lib_path); + } #else dso = switch_dso_open(NULL, load_global, &derr); #endif From bf0056f3b8d69ad1ee7ee45d4cbf959b2efcce45 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 09:47:01 -0500 Subject: [PATCH 284/512] FS-4729 try this --- src/include/switch_types.h | 1 + src/switch_ivr_bridge.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index ff8c55a521..8ce9c34a50 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1171,6 +1171,7 @@ typedef enum { CF_OUTBOUND, CF_EARLY_MEDIA, CF_BRIDGE_ORIGINATOR, + CF_UUID_BRIDGE_ORIGINATOR, CF_TRANSFER, CF_ACCEPT_CNG, CF_REDIRECT, diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 24e18f6b58..3a930a62bc 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -745,7 +745,7 @@ static switch_status_t uuid_bridge_on_reset(switch_core_session_t *session) cleanup_proxy_mode_b(session); - if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { + if (switch_channel_test_flag(channel, CF_UUID_BRIDGE_ORIGINATOR)) { switch_channel_set_state(channel, CS_SOFT_EXECUTE); } @@ -767,7 +767,7 @@ static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *sessio switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CUSTOM SOFT_EXECUTE\n", switch_channel_get_name(channel)); switch_channel_clear_state_handler(channel, &uuid_bridge_state_handlers); - if (!switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { + if (!switch_channel_test_flag(channel, CF_UUID_BRIDGE_ORIGINATOR)) { return SWITCH_STATUS_SUCCESS; } @@ -801,7 +801,7 @@ static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *sessio if (running_state == CS_SOFT_EXECUTE) { - if (switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) { + if (switch_channel_test_flag(other_channel, CF_UUID_BRIDGE_ORIGINATOR)) { goto done; } else { break; @@ -878,7 +878,7 @@ static switch_status_t uuid_bridge_on_soft_execute(switch_core_session_t *sessio other_session = NULL; } - switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR); + switch_channel_clear_flag(channel, CF_UUID_BRIDGE_ORIGINATOR); return SWITCH_STATUS_FALSE; } @@ -1663,10 +1663,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu //switch_channel_set_variable(originatee_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL); switch_channel_clear_state_handler(originator_channel, NULL); switch_channel_clear_state_handler(originatee_channel, NULL); - switch_channel_clear_flag_recursive(originator_channel, CF_BRIDGE_ORIGINATOR); - switch_channel_clear_flag_recursive(originatee_channel, CF_BRIDGE_ORIGINATOR); - switch_channel_set_state_flag(originator_channel, CF_BRIDGE_ORIGINATOR); + + switch_channel_clear_state_flag(originator_channel, CF_BRIDGE_ORIGINATOR); switch_channel_clear_state_flag(originatee_channel, CF_BRIDGE_ORIGINATOR); + switch_channel_set_state_flag(originator_channel, CF_UUID_BRIDGE_ORIGINATOR); + switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers); switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers); From bc4e396d197cc551f6e97b7c9ad77be3c1c2b4b9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 09:52:01 -0500 Subject: [PATCH 285/512] FS-4770 --- Makefile.am | 1 + configure.in | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 4f6f4c2bdd..f1e98e05e1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -202,6 +202,7 @@ library_include_HEADERS = \ src/include/switch_xml_config.h \ src/include/switch_cpp.h \ src/include/switch_json.h \ + libs/stfu/stfu.h \ libs/libteletone/src/libteletone_detect.h \ libs/libteletone/src/libteletone_generate.h \ libs/libteletone/src/libteletone.h \ diff --git a/configure.in b/configure.in index 2c4835afc2..95b0553de2 100644 --- a/configure.in +++ b/configure.in @@ -155,8 +155,8 @@ fi AX_PATH_LIBGNUTLS() # set defaults for use on all platforms -SWITCH_AM_CFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src" -SWITCH_AM_CXXFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src" +SWITCH_AM_CFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src -I${switch_srcdir}/libs/stfu" +SWITCH_AM_CXXFLAGS="-I${switch_srcdir}/src/include -I${switch_builddir}/src/include -I${switch_srcdir}/libs/libteletone/src -I${switch_srcdir}/libs/stfu" SWITCH_AM_LDFLAGS="-lm" #set SOLINK variable based on compiler and host From 0952a99a76bbbd563fd612cd8e12c552e5218356 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 29 Oct 2012 13:20:10 -0400 Subject: [PATCH 286/512] FS-4718: --resolve merge osx 10.8 build fixes --- configure.in | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 95b0553de2..8031700ac6 100644 --- a/configure.in +++ b/configure.in @@ -164,7 +164,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then SOLINK="-Bdynamic -dy -G" elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then case "$host" in - *darwin10.*) + *darwin12.*|*darwin10.*) SOLINK="-dynamic -force-flat-namespace" ;; *darwin*) @@ -248,7 +248,7 @@ elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then APR_ADDTO(SWITCH_AM_CFLAGS, -Werror) if test "${enable_64}" = "yes"; then case "$host" in - *darwin10.*|*darwin9.*|*darwin8.*) + *darwin12.*|*darwin10.*|*darwin9.*|*darwin8.*) APR_ADDTO(CFLAGS, -arch x86_64) APR_ADDTO(LDFLAGS, -arch x86_64) APR_ADDTO(CXXFLAGS, -arch x86_64) @@ -447,6 +447,17 @@ PLATFORM_CORE_LDFLAGS= PLATFORM_CORE_LIBS= # tweak platform specific flags case "$host" in + *darwin12.*) + APR_ADDTO(SWITCH_AM_CFLAGS, -DMACOSX) + APR_ADDTO(CFLAGS, -pipe -no-cpp-precomp -Wno-deprecated-declarations) + APR_ADDTO(LDFLAGS, -pipe -bind_at_load) + APR_ADDTO(CXXFLAGS, -pipe) + APR_REMOVEFROM(SWITCH_AM_CFLAGS, -fPIC) + if test "x$enable_core_odbc_support" != "xno"; then + APR_ADDTO([PLATFORM_CORE_LDFLAGS], [--framework CoreFoundation]) + fi + APR_ADDTO([PLATFORM_CORE_LIBS], [-ldl]) + ;; *darwin10.*) APR_ADDTO(SWITCH_AM_CFLAGS, -DMACOSX) APR_ADDTO(CFLAGS, -pipe -no-cpp-precomp) From fae4dd51adc73f18ae2a7111683e694e36e6ac44 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 29 Oct 2012 13:26:26 -0400 Subject: [PATCH 287/512] FS-3992: --resolve fix OSX platform detection for spidermonkey on 10.7 and later --- libs/js/nsprpub/configure.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/js/nsprpub/configure.in b/libs/js/nsprpub/configure.in index 93d3bd9f85..7ac45ed9fc 100644 --- a/libs/js/nsprpub/configure.in +++ b/libs/js/nsprpub/configure.in @@ -425,7 +425,7 @@ if test "$target" != "$host"; then LDFLAGS=$_SAVE_LDFLAGS case "$build:$target" in - powerpc-apple-darwin8*:i?86-apple-darwin*) + powerpc-apple-darwin8*:*86-apple-darwin*) dnl The Darwin cross compiler doesn't necessarily point itself at a dnl root that has libraries for the proper architecture, it defaults dnl to the system root. The libraries in the system root on current @@ -446,7 +446,7 @@ if test "$target" != "$host"; then AC_PROG_CXX case "$build:$target" in - powerpc-apple-darwin8*:i?86-apple-darwin*) + powerpc-apple-darwin8*:*86-apple-darwin*) dnl Revert the changes made above. From this point on, the target dnl compiler will never be used without applying the SDK to CFLAGS dnl (see --with-macos-sdk below). @@ -496,7 +496,7 @@ fi rm -f a.out case "$build:$target" in - i?86-apple-darwin*:powerpc-apple-darwin*) + *86-apple-darwin*:powerpc-apple-darwin*) dnl cross_compiling will have erroneously been set to "no" in this dnl case, because the x86 build host is able to run ppc code in a dnl translated environment, making a cross compiler appear native. @@ -975,7 +975,7 @@ case "$target" in AC_DEFINE(HAVE_BSD_FLOCK) CFLAGS="$CFLAGS -Wmost -fno-common" case "${target_cpu}" in - i*86*) + *86*) AC_DEFINE(i386) CPU_ARCH=i386 PR_MD_ASFILES=os_Darwin_x86.s @@ -1014,7 +1014,7 @@ case "$target" in dnl Architecture minimum 10.1 export MACOSX_DEPLOYMENT_TARGET=10.1 ;; - i*86*) + *86*) dnl Architecture minimum 10.4 export MACOSX_DEPLOYMENT_TARGET=10.4 ;; From 4b5cdd87f1cab36e7cde2c6c93b45fd56ed414b9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 11:46:17 -0500 Subject: [PATCH 288/512] refactor --- src/mod/endpoints/mod_sofia/sofia.c | 3 - src/switch_core_sqldb.c | 118 ++++++++++++---------------- src/switch_core_state_machine.c | 7 ++ src/switch_ivr_originate.c | 7 +- 4 files changed, 60 insertions(+), 75 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 10cc5ce51e..a6e22653f5 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1638,7 +1638,6 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj if (pop) { sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop; sofia_process_dispatch_event(&de); - switch_cond_next(); } else { break; } @@ -1959,8 +1958,6 @@ void sofia_event_callback(nua_event_t event, end: - switch_cond_next(); - return; } diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index d1b83426d8..4ccdb97a80 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1457,46 +1457,36 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n } -static uint32_t do_trans(switch_cache_db_handle_t *dbh, - switch_queue_t *q, - switch_mutex_t *mutex, - uint32_t max, - const char *pre_trans_execute, - const char *post_trans_execute, - const char *inner_pre_trans_execute, - const char *inner_post_trans_execute) +static uint32_t do_trans(switch_sql_queue_manager_t *qm) { char *errmsg = NULL; void *pop; switch_status_t status; uint32_t ttl = 0; - switch_mutex_t *io_mutex = dbh->io_mutex; - - if (!switch_queue_size(q)) { - return 0; - } + switch_mutex_t *io_mutex = qm->event_db->io_mutex; + int i; if (io_mutex) switch_mutex_lock(io_mutex); - if (!zstr(pre_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, pre_trans_execute, &errmsg); + if (!zstr(qm->pre_trans_execute)) { + switch_cache_db_execute_sql_real(qm->event_db, qm->pre_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", pre_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", qm->pre_trans_execute, errmsg); free(errmsg); } } - switch(dbh->type) { + switch(qm->event_db->type) { case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg); + switch_cache_db_execute_sql_real(qm->event_db, "BEGIN", &errmsg); } break; case SCDB_TYPE_ODBC: { switch_odbc_status_t result; - if ((result = switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { + if ((result = switch_odbc_SQLSetAutoCommitAttr(qm->event_db->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { char tmp[100]; switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); errmsg = strdup(tmp); @@ -1507,7 +1497,7 @@ static uint32_t do_trans(switch_cache_db_handle_t *dbh, { switch_pgsql_status_t result; - if ((result = switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { + if ((result = switch_pgsql_SQLSetAutoCommitAttr(qm->event_db->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { char tmp[100]; switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); errmsg = strdup(tmp); @@ -1523,33 +1513,44 @@ static uint32_t do_trans(switch_cache_db_handle_t *dbh, } - if (!zstr(inner_pre_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, inner_pre_trans_execute, &errmsg); + if (!zstr(qm->inner_pre_trans_execute)) { + switch_cache_db_execute_sql_real(qm->event_db, qm->inner_pre_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", inner_pre_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL PRE TRANS EXEC %s [%s]\n", qm->inner_pre_trans_execute, errmsg); free(errmsg); } } - while(max == 0 || ttl <= max) { - if (mutex) switch_mutex_lock(mutex); - status = switch_queue_trypop(q, &pop); - if (mutex) switch_mutex_unlock(mutex); - - if (status != SWITCH_STATUS_SUCCESS || !pop) break; - if ((status = switch_cache_db_execute_sql(dbh, (char *) pop, NULL)) == SWITCH_STATUS_SUCCESS) { - ttl++; + while(qm->max_trans == 0 || ttl <= qm->max_trans) { + pop = NULL; + + for (i = 0; (qm->max_trans == 0 || ttl <= qm->max_trans) && (i < qm->numq); i++) { + switch_mutex_lock(qm->mutex); + switch_queue_trypop(qm->sql_queue[i], &pop); + switch_mutex_unlock(qm->mutex); + if (pop) break; } - free(pop); - if (status != SWITCH_STATUS_SUCCESS) break; + if (pop) { + if ((status = switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL)) == SWITCH_STATUS_SUCCESS) { + switch_mutex_lock(qm->mutex); + qm->written[i]++; + switch_mutex_unlock(qm->mutex); + ttl++; + } + free(pop); + pop = NULL; + if (status != SWITCH_STATUS_SUCCESS) break; + } else { + break; + } } - if (!zstr(inner_post_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, inner_post_trans_execute, &errmsg); + if (!zstr(qm->inner_post_trans_execute)) { + switch_cache_db_execute_sql_real(qm->event_db, qm->inner_post_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", inner_post_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", qm->inner_post_trans_execute, errmsg); free(errmsg); } } @@ -1557,32 +1558,32 @@ static uint32_t do_trans(switch_cache_db_handle_t *dbh, end: - switch(dbh->type) { + switch(qm->event_db->type) { case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql_real(dbh, "COMMIT", NULL); + switch_cache_db_execute_sql_real(qm->event_db, "COMMIT", NULL); } break; case SCDB_TYPE_ODBC: { - switch_odbc_SQLEndTran(dbh->native_handle.odbc_dbh, 1); - switch_odbc_SQLSetAutoCommitAttr(dbh->native_handle.odbc_dbh, 1); + switch_odbc_SQLEndTran(qm->event_db->native_handle.odbc_dbh, 1); + switch_odbc_SQLSetAutoCommitAttr(qm->event_db->native_handle.odbc_dbh, 1); } break; case SCDB_TYPE_PGSQL: { - switch_pgsql_SQLEndTran(dbh->native_handle.pgsql_dbh, 1); - switch_pgsql_SQLSetAutoCommitAttr(dbh->native_handle.pgsql_dbh, 1); - switch_pgsql_finish_results(dbh->native_handle.pgsql_dbh); + switch_pgsql_SQLEndTran(qm->event_db->native_handle.pgsql_dbh, 1); + switch_pgsql_SQLSetAutoCommitAttr(qm->event_db->native_handle.pgsql_dbh, 1); + switch_pgsql_finish_results(qm->event_db->native_handle.pgsql_dbh); } break; } - if (!zstr(post_trans_execute)) { - switch_cache_db_execute_sql_real(dbh, post_trans_execute, &errmsg); + if (!zstr(qm->post_trans_execute)) { + switch_cache_db_execute_sql_real(qm->event_db, qm->post_trans_execute, &errmsg); if (errmsg) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", post_trans_execute, errmsg); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL POST TRANS EXEC %s [%s]\n", qm->post_trans_execute, errmsg); free(errmsg); } } @@ -1635,7 +1636,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, while (qm->thread_running == 1) { int lc; uint32_t i; - uint32_t iterations = 0; + uint32_t written, iterations = 0; if (sql_manager.paused) { for (i = 0; i < qm->numq; i++) { @@ -1643,26 +1644,11 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, } goto check; } - - for (i = 0; i < qm->numq; i++) { - while(switch_queue_size(qm->sql_queue[i])) { - uint32_t written = do_trans(qm->event_db, qm->sql_queue[i], qm->mutex, qm->max_trans, - qm->pre_trans_execute, - qm->post_trans_execute, - qm->inner_pre_trans_execute, - qm->inner_post_trans_execute); - iterations += written; - - switch_mutex_lock(qm->mutex); - qm->written[i] += written; - switch_mutex_unlock(qm->mutex); - - if (written < qm->max_trans) { - break; - } - } - } + do { + written = do_trans(qm); + iterations += written; + } while(written == qm->max_trans); if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { char line[128] = ""; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index ad9af6ca5e..87b8a32a20 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -457,6 +457,13 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_channel_event_set_data(session->channel, event); switch_event_fire(&event); } + + if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(session->channel, event); + switch_event_fire(&event); + } + } } break; case CS_ROUTING: /* Look for a dialplan and find something to do */ diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 17f1ad19e2..ed8534cfc7 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2420,7 +2420,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess for (i = 0; i < and_argc; i++) { const char *current_variable; - switch_event_t *local_var_event = NULL, *originate_var_event = NULL, *event = NULL; + switch_event_t *local_var_event = NULL, *originate_var_event = NULL; end = NULL; @@ -2686,11 +2686,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } - switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE); - switch_assert(event); - switch_channel_event_set_data(originate_status[i].peer_channel, event); - switch_event_fire(&event); - if (originate_status[i].peer_channel) { const char *vvar; From d2a73cc0e4681e7d1dcf165d372efa936372bf93 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 11 Oct 2012 00:49:33 -0500 Subject: [PATCH 289/512] Updated ftmod_pritap.c to send SIGEVENT_UP when the tapped line is answered --- libs/freetdm/src/ftdm_io.c | 2 +- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 932ce30aa7..8e6db56af4 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -6093,7 +6093,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t case FTDM_SIGEVENT_START: { - ftdm_assert(!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED), "Started call twice!"); + ftdm_assert(!ftdm_test_flag(fchan, FTDM_CHANNEL_CALL_STARTED), "Started call twice!\n"); if (ftdm_test_flag(fchan, FTDM_CHANNEL_OUTBOUND)) { ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "Inbound call taking over outbound channel\n"); diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index f136d59d9c..343f317944 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -38,6 +38,8 @@ #define PRI_SPAN(p) (((p) >> 8) & 0xff) #define PRI_CHANNEL(p) ((p) & 0xff) +#define PRITAP_NETWORK_ANSWER 0x1 + typedef enum { PRITAP_RUNNING = (1 << 0), } pritap_flags_t; @@ -279,25 +281,36 @@ static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) sig.span_id = ftdmchan->span_id; sig.channel = ftdmchan; - ftdm_channel_complete_state(ftdmchan); + ftdm_channel_complete_state(ftdmchan); switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_DOWN: { ftdmchan->call_data = NULL; + ftdmchan->pflags = 0; ftdm_channel_close(&ftdmchan); peerchan->call_data = NULL; + peerchan->pflags = 0; ftdm_channel_close(&peerchan); } break; case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - case FTDM_CHANNEL_STATE_UP: case FTDM_CHANNEL_STATE_HANGUP: break; + case FTDM_CHANNEL_STATE_UP: + { + if (ftdm_test_pflag(ftdmchan, PRITAP_NETWORK_ANSWER)) { + ftdm_clear_pflag(ftdmchan, PRITAP_NETWORK_ANSWER); + sig.event_id = FTDM_SIGEVENT_UP; + ftdm_span_send_signal(ftdmchan->span, &sig); + } + } + break; + case FTDM_CHANNEL_STATE_RING: { sig.event_id = FTDM_SIGEVENT_START; @@ -625,6 +638,8 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) break; } ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Tapped call was answered in state %s\n", ftdm_channel_state2str(pcall->fchan->state)); + ftdm_set_pflag_locked(pcall->fchan, PRITAP_NETWORK_ANSWER); + ftdm_set_state_locked(pcall->fchan, FTDM_CHANNEL_STATE_UP); break; case PRI_EVENT_HANGUP_REQ: From 0a92094995b2bebd05ccc80d4b39a765b8ba9f46 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 12 Oct 2012 02:18:12 -0500 Subject: [PATCH 290/512] freetdm: ftmod_pritap - Add interface type parameter (cpe/net) --- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 343f317944..37a19c8082 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -55,6 +55,12 @@ typedef struct { int inuse:1; } passive_call_t; +typedef enum pritap_iface { + PRITAP_IFACE_UNKNOWN = 0, + PRITAP_IFACE_CPE = 1, + PRITAP_IFACE_NET = 2, +} pritap_iface_t; + typedef struct pritap { int32_t flags; struct pri *pri; @@ -65,6 +71,7 @@ typedef struct pritap { ftdm_span_t *peerspan; ftdm_mutex_t *pcalls_lock; passive_call_t pcalls[FTDM_MAX_CHANNELS_PHYSICAL_SPAN]; + pritap_iface_t iface; } pritap_t; static FIO_IO_UNLOAD_FUNCTION(ftdm_pritap_unload) @@ -268,11 +275,15 @@ static ftdm_state_map_t pritap_state_map = { } }; +#define PRITAP_GET_INTERFACE(iface) iface == PRITAP_IFACE_CPE ? "CPE" : \ + iface == PRITAP_IFACE_NET ? "NET" : "UNKNOWN" static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) { ftdm_status_t status; ftdm_sigmsg_t sig; ftdm_channel_t *peerchan = ftdmchan->call_data; + pritap_t *pritap = ftdmchan->span->signal_data; + pritap_t *peer_pritap = pritap->peerspan->signal_data; ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "processing state %s\n", ftdm_channel_state2str(ftdmchan->state)); @@ -314,6 +325,9 @@ static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_RING: { sig.event_id = FTDM_SIGEVENT_START; + /* The ring interface (where the setup was received) is the peer, since we RING the channel + * where PROCEED/PROGRESS is received */ + ftdm_sigmsg_add_var(&sig, "pritap_ring_interface", PRITAP_GET_INTERFACE(peer_pritap->iface)); if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } @@ -855,6 +869,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span) ftdm_channel_t *dchan = NULL; pritap_t *pritap = NULL; ftdm_span_t *peerspan = NULL; + pritap_iface_t iface = PRITAP_IFACE_UNKNOWN; unsigned paramindex = 0; if (span->trunk_type >= FTDM_TRUNK_NONE) { @@ -882,6 +897,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span) debug = val; } else if (!strcasecmp(var, "mixaudio")) { mixaudio = ftdm_true(val); + } else if (!strcasecmp(var, "interface")) { + if (!strcasecmp(val, "cpe")) { + iface = PRITAP_IFACE_CPE; + } else if (!strcasecmp(val, "net")) { + iface = PRITAP_IFACE_NET; + } else { + ftdm_log(FTDM_LOG_WARNING, "Ignoring invalid tapping interface type %s\n", val); + } } else if (!strcasecmp(var, "peerspan")) { if (ftdm_span_find_by_name(val, &peerspan) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Invalid tapping peer span %s\n", val); @@ -906,6 +929,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span) pritap->dchan = dchan; pritap->peerspan = peerspan; pritap->mixaudio = mixaudio; + pritap->iface = iface; span->start = ftdm_pritap_start; span->stop = ftdm_pritap_stop; From 3cb1fd267fcc42233f2f33819c69e541514fb425 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 17 Oct 2012 18:21:16 -0500 Subject: [PATCH 291/512] Try to fix pritap segfault --- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 37a19c8082..f5a9b61d80 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -297,13 +297,19 @@ static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_DOWN: { + ftdm_channel_t *fchan = ftdmchan; + ftdmchan->call_data = NULL; ftdmchan->pflags = 0; - ftdm_channel_close(&ftdmchan); + ftdm_channel_close(&fchan); - peerchan->call_data = NULL; - peerchan->pflags = 0; - ftdm_channel_close(&peerchan); + if (peerchan) { + peerchan->call_data = NULL; + peerchan->pflags = 0; + ftdm_channel_close(&peerchan); + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Odd, no peer chan\n"); + } } break; @@ -597,6 +603,8 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) ftdm_log(FTDM_LOG_DEBUG, "Ignoring duplicated proceeding with callref %d\n", crv); break; } + pcall->proceeding = 1; + peerpcall = tap_pri_get_pcall(pritap, NULL); if (!peerpcall) { ftdm_log(FTDM_LOG_ERROR, "Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!\n", @@ -625,7 +633,6 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); break; } - pcall->fchan = fchan; peerfchan = tap_pri_get_fchan(peertap, pcall, e->proceeding.channel); if (!peerfchan) { @@ -633,11 +640,13 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) peertap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); break; } + pcall->fchan = fchan; peerpcall->fchan = fchan; fchan->call_data = peerfchan; peerfchan->call_data = fchan; + ftdm_log_chan_msg(pcall->fchan, FTDM_LOG_NOTICE, "Starting new tapped call\n"); ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_RING); break; @@ -651,6 +660,12 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); break; } + if (!pcall->fchan) { + ftdm_log(FTDM_LOG_ERROR, + "Received answer in channel %s:%d:%d for callref %d but we never got a channel", + pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); + break; + } ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Tapped call was answered in state %s\n", ftdm_channel_state2str(pcall->fchan->state)); ftdm_set_pflag_locked(pcall->fchan, PRITAP_NETWORK_ANSWER); ftdm_set_state_locked(pcall->fchan, FTDM_CHANNEL_STATE_UP); @@ -668,6 +683,13 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) break; } + if (!pcall->fchan) { + ftdm_log(FTDM_LOG_DEBUG, + "ignoring hangup in channel %s:%d:%d for callref %d since we never got a channel", + pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); + break; + } + fchan = pcall->fchan; ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_TERMINATING); break; From 7d5a4a71721cac7dc0f725fac86f3c615ed87029 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 23 Oct 2012 00:40:19 -0500 Subject: [PATCH 292/512] freetdm: ftmod_pritap - Destroy call references as soon as possible --- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index f5a9b61d80..5b94ede432 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -308,7 +308,7 @@ static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) peerchan->pflags = 0; ftdm_channel_close(&peerchan); } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Odd, no peer chan\n"); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Odd, no peer chan\n"); } } break; @@ -497,13 +497,11 @@ static void tap_pri_put_pcall(pritap_t *pritap, void *callref) } tstcrv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref); if (tstcrv == crv) { - ftdm_log(FTDM_LOG_DEBUG, "releasing slot %d in span %s used by callref %d/%p\n", i, - pritap->span->name, crv, pritap->pcalls[i].callref); - if (!pritap->pcalls[i].inuse) { - ftdm_log(FTDM_LOG_ERROR, "slot %d in span %s used by callref %d/%p was released already?\n", - i, pritap->span->name, crv, pritap->pcalls[i].callref); + if (pritap->pcalls[i].inuse) { + ftdm_log(FTDM_LOG_DEBUG, "releasing slot %d in span %s used by callref %d/%p\n", i, + pritap->span->name, crv, pritap->pcalls[i].callref); + pritap->pcalls[i].inuse = 0; } - pritap->pcalls[i].inuse = 0; } } @@ -595,7 +593,7 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) /* check that we already know about this call in the peer PRI (which was the one receiving the PRI_EVENT_RING event) */ if (!(pcall = tap_pri_get_pcall_bycrv(peertap, crv))) { ftdm_log(FTDM_LOG_DEBUG, - "ignoring proceeding in channel %s:%d:%d for callref %d since we don't know about it", + "ignoring proceeding in channel %s:%d:%d for callref %d since we don't know about it\n", pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); break; } @@ -646,7 +644,7 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) fchan->call_data = peerfchan; peerfchan->call_data = fchan; - ftdm_log_chan_msg(pcall->fchan, FTDM_LOG_NOTICE, "Starting new tapped call\n"); + ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Starting new tapped call with callref %d\n", crv); ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_RING); break; @@ -666,9 +664,11 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); break; } + ftdm_channel_lock(pcall->fchan); ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Tapped call was answered in state %s\n", ftdm_channel_state2str(pcall->fchan->state)); - ftdm_set_pflag_locked(pcall->fchan, PRITAP_NETWORK_ANSWER); - ftdm_set_state_locked(pcall->fchan, FTDM_CHANNEL_STATE_UP); + ftdm_set_pflag(pcall->fchan, PRITAP_NETWORK_ANSWER); + ftdm_set_state(pcall->fchan, FTDM_CHANNEL_STATE_UP); + ftdm_channel_unlock(pcall->fchan); break; case PRI_EVENT_HANGUP_REQ: @@ -683,15 +683,18 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) break; } - if (!pcall->fchan) { - ftdm_log(FTDM_LOG_DEBUG, - "ignoring hangup in channel %s:%d:%d for callref %d since we never got a channel", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); - break; + if (pcall->fchan) { + fchan = pcall->fchan; + ftdm_channel_lock(fchan); + if (fchan->state < FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_set_state(fchan, FTDM_CHANNEL_STATE_TERMINATING); + } + pcall->fchan = NULL; /* after this event we're not supposed to need to do anything with the channel anymore */ + ftdm_channel_unlock(fchan); } - fchan = pcall->fchan; - ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_TERMINATING); + tap_pri_put_pcall(pritap, e->hangup.call); + tap_pri_put_pcall(peertap, e->hangup.call); break; case PRI_EVENT_HANGUP_ACK: From d88e79e63227dfd475df0a714dc19b9c41fbf844 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 23 Oct 2012 00:52:29 -0500 Subject: [PATCH 293/512] freetdm: ftmod_pritap - Use uint8 for flags (I smell a bug somewhere with bitfields) --- libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 5b94ede432..551c7632b1 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -51,8 +51,8 @@ typedef struct { ftdm_number_t callednum; ftdm_channel_t *fchan; char callingname[80]; - int proceeding:1; - int inuse:1; + uint8_t proceeding; + uint8_t inuse; } passive_call_t; typedef enum pritap_iface { From e4e6fa65d0126b716cc0aaba0bd32d8452e206a4 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Tue, 23 Oct 2012 22:29:55 -0500 Subject: [PATCH 294/512] freetdm: ftmod_pritap - Lock the channel during call setup Destroy the peer before the master channel --- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 61 ++++++++++++++----- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 551c7632b1..902f3666b6 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -281,7 +281,6 @@ static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) { ftdm_status_t status; ftdm_sigmsg_t sig; - ftdm_channel_t *peerchan = ftdmchan->call_data; pritap_t *pritap = ftdmchan->span->signal_data; pritap_t *peer_pritap = pritap->peerspan->signal_data; @@ -299,17 +298,25 @@ static ftdm_status_t state_advance(ftdm_channel_t *ftdmchan) { ftdm_channel_t *fchan = ftdmchan; + /* Destroy the peer data first */ + if (fchan->call_data) { + ftdm_channel_t *peerchan = fchan->call_data; + ftdm_channel_t *pchan = peerchan; + + ftdm_channel_lock(peerchan); + + pchan->call_data = NULL; + pchan->pflags = 0; + ftdm_channel_close(&pchan); + + ftdm_channel_unlock(peerchan); + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "No call data?\n"); + } + ftdmchan->call_data = NULL; ftdmchan->pflags = 0; ftdm_channel_close(&fchan); - - if (peerchan) { - peerchan->call_data = NULL; - peerchan->pflags = 0; - ftdm_channel_close(&peerchan); - } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Odd, no peer chan\n"); - } } break; @@ -511,6 +518,7 @@ static void tap_pri_put_pcall(pritap_t *pritap, void *callref) static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_call_t *pcall, int channel) { ftdm_channel_t *fchan = NULL; + int err = 0; int chanpos = PRI_CHANNEL(channel); if (!chanpos || chanpos > pritap->span->chan_count) { ftdm_log(FTDM_LOG_CRIT, "Invalid pri tap channel %d requested in span %s\n", channel, pritap->span->name); @@ -518,14 +526,19 @@ static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_ca } fchan = pritap->span->channels[PRI_CHANNEL(channel)]; + + ftdm_channel_lock(fchan); + if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) { ftdm_log(FTDM_LOG_ERROR, "Channel %d requested in span %s is already in use!\n", channel, pritap->span->name); - return NULL; + err = 1; + goto done; } if (ftdm_channel_open_chan(fchan) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Could not open tap channel %d requested in span %s\n", channel, pritap->span->name); - return NULL; + err = 1; + goto done; } memset(&fchan->caller_data, 0, sizeof(fchan->caller_data)); @@ -539,6 +552,15 @@ static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_ca ftdm_set_string(fchan->caller_data.ani.digits, pcall->callingani.digits); ftdm_set_string(fchan->caller_data.dnis.digits, pcall->callednum.digits); +done: + if (fchan) { + ftdm_channel_unlock(fchan); + } + + if (err) { + return NULL; + } + return fchan; } @@ -641,11 +663,17 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) pcall->fchan = fchan; peerpcall->fchan = fchan; - fchan->call_data = peerfchan; - peerfchan->call_data = fchan; + ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "Starting new tapped call with callref %d\n", crv); + + ftdm_channel_lock(fchan); + fchan->call_data = peerfchan; + ftdm_set_state(fchan, FTDM_CHANNEL_STATE_RING); + ftdm_channel_unlock(fchan); + + ftdm_channel_lock(peerfchan); + peerfchan->call_data = fchan; + ftdm_channel_unlock(peerfchan); - ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Starting new tapped call with callref %d\n", crv); - ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_RING); break; case PRI_EVENT_ANSWER: @@ -673,7 +701,8 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) case PRI_EVENT_HANGUP_REQ: crv = tap_pri_get_crv(pritap->pri, e->hangup.call); - ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n", + + ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n", pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv); if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) { From aeb07172b09fc6e38e115a9bd358b1508a516c87 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 25 Oct 2012 02:01:05 -0400 Subject: [PATCH 295/512] freetdm: ftmod_pritap - Do not print an error when the crv is no longer in use since this is a valid code path --- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 902f3666b6..7e4bf314a7 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -437,18 +437,18 @@ static passive_call_t *tap_pri_get_pcall_bycrv(pritap_t *pritap, int crv) for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) { tstcrv = pritap->pcalls[i].callref ? tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref) : 0; if (pritap->pcalls[i].callref && tstcrv == crv) { - if (!pritap->pcalls[i].inuse) { - ftdm_log(FTDM_LOG_ERROR, "Found crv %d in slot %d of span %s with call %p but is no longer in use!\n", - crv, i, pritap->span->name, pritap->pcalls[i].callref); - continue; + if (pritap->pcalls[i].inuse) { + ftdm_mutex_unlock(pritap->pcalls_lock); + return &pritap->pcalls[i]; } - - ftdm_mutex_unlock(pritap->pcalls_lock); - - return &pritap->pcalls[i]; + /* This just means the crv is being re-used in another call before this one was destroyed */ + ftdm_log(FTDM_LOG_DEBUG, "Found crv %d in slot %d of span %s with call %p but is no longer in use\n", + crv, i, pritap->span->name, pritap->pcalls[i].callref); } } + ftdm_log(FTDM_LOG_DEBUG, "crv %d was not found active in span %s\n", crv, pritap->span->name); + ftdm_mutex_unlock(pritap->pcalls_lock); return NULL; @@ -471,7 +471,10 @@ static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref) memset(&pritap->pcalls[i], 0, sizeof(pritap->pcalls[0])); } if (callref == pritap->pcalls[i].callref) { - pritap->pcalls[i].inuse = 1; + if (callref == NULL) { + pritap->pcalls[i].inuse = 1; + ftdm_log(FTDM_LOG_DEBUG, "Enabling callref slot %d in span %s\n", i, pritap->span->name); + } ftdm_mutex_unlock(pritap->pcalls_lock); From 87a1d78e42aee1e952cbd137a9ddd719fb9c346e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 25 Oct 2012 20:58:46 -0400 Subject: [PATCH 296/512] freetdm: ftmod_pritap - Use a single thread per every pair of spans tapping a single line --- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 104 ++++++++++++------ 1 file changed, 72 insertions(+), 32 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 7e4bf314a7..1328f8f385 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -42,6 +42,7 @@ typedef enum { PRITAP_RUNNING = (1 << 0), + PRITAP_MASTER = (1 << 1), } pritap_flags_t; typedef struct { @@ -373,9 +374,9 @@ static __inline__ void pritap_check_state(ftdm_span_t *span) uint32_t j; ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE); for(j = 1; j <= span->chan_count; j++) { - ftdm_mutex_lock(span->channels[j]->mutex); + ftdm_channel_lock(span->channels[j]); ftdm_channel_advance_states(span->channels[j]); - ftdm_mutex_unlock(span->channels[j]->mutex); + ftdm_channel_unlock(span->channels[j]); } } } @@ -685,14 +686,14 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv); if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) { ftdm_log(FTDM_LOG_DEBUG, - "ignoring answer in channel %s:%d:%d for callref %d since we don't know about it", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); + "ignoring answer in channel %s:%d:%d for callref %d since we don't know about it\n", + pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->proceeding.channel), crv); break; } if (!pcall->fchan) { ftdm_log(FTDM_LOG_ERROR, - "Received answer in channel %s:%d:%d for callref %d but we never got a channel", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); + "Received answer in channel %s:%d:%d for callref %d but we never got a channel\n", + pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv); break; } ftdm_channel_lock(pcall->fchan); @@ -747,12 +748,14 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj) { ftdm_span_t *span = (ftdm_span_t *) obj; + ftdm_span_t *peer = NULL; pritap_t *pritap = span->signal_data; + pritap_t *p_pritap = NULL; pri_event *event = NULL; - struct pollfd dpoll = { 0, 0, 0 }; + struct pollfd dpoll[2]; int rc = 0; - ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %d\n", span->span_id); + ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %s\n", span->name); pritap->span = span; @@ -770,48 +773,80 @@ static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj) goto done; } - dpoll.fd = pritap->dchan->sockfd; + /* The last span starting runs the show ... + * This simplifies locking and avoid races by having multiple threads for a single tapped link + * Since both threads really handle a single tapped link there is no benefit on multi-threading, just complications ... */ + peer = pritap->peerspan; + p_pritap = peer->signal_data; + if (!ftdm_test_flag(pritap, PRITAP_MASTER)) { + ftdm_log(FTDM_LOG_DEBUG, "Running dummy thread on span %s\n", span->name); + while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { + poll(NULL, 0, 100); + } + } else { + memset(&dpoll, 0, sizeof(dpoll)); + dpoll[0].fd = pritap->dchan->sockfd; + dpoll[1].fd = p_pritap->dchan->sockfd; - while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { + ftdm_log(FTDM_LOG_DEBUG, "Master tapping thread on span %s (fd1=%d, fd2=%d)\n", span->name, + pritap->dchan->sockfd, p_pritap->dchan->sockfd); + while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) { - pritap_check_state(span); + pritap_check_state(span); + pritap_check_state(peer); - dpoll.revents = 0; - dpoll.events = POLLIN; + dpoll[0].revents = 0; + dpoll[0].events = POLLIN; - rc = poll(&dpoll, 1, 10); + dpoll[1].revents = 0; + dpoll[1].events = POLLIN; - if (rc < 0) { - if (errno == EINTR) { - ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n"); + rc = poll(&dpoll[0], 2, 10); + + if (rc < 0) { + if (errno == EINTR) { + ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n"); + continue; + } + ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno)); continue; } - ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno)); - continue; - } - pri_schedule_run(pritap->pri); + pri_schedule_run(pritap->pri); + pri_schedule_run(p_pritap->pri); - if (rc) { - if (dpoll.revents & POLLIN) { - event = pri_read_event(pritap->pri); - if (event) { - handle_pri_passive_event(pritap, event); + pritap_check_state(span); + pritap_check_state(peer); + + if (rc) { + if (dpoll[0].revents & POLLIN) { + event = pri_read_event(pritap->pri); + if (event) { + handle_pri_passive_event(pritap, event); + pritap_check_state(span); + } } - } else { - ftdm_log(FTDM_LOG_WARNING, "nothing to read?\n"); - } - } - pritap_check_state(span); + if (dpoll[1].revents & POLLIN) { + event = pri_read_event(p_pritap->pri); + if (event) { + handle_pri_passive_event(p_pritap, event); + pritap_check_state(peer); + } + } + } + + } } + done: - ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %d\n", span->span_id); + ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %s\n", span->name); ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); ftdm_clear_flag(pritap, PRITAP_RUNNING); + ftdm_clear_flag(pritap, PRITAP_MASTER); return NULL; } @@ -897,6 +932,7 @@ static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span) { ftdm_status_t ret; pritap_t *pritap = span->signal_data; + pritap_t *p_pritap = pritap->peerspan->signal_data; if (ftdm_test_flag(pritap, PRITAP_RUNNING)) { return FTDM_FAIL; @@ -908,6 +944,10 @@ static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span) ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); ftdm_set_flag(pritap, PRITAP_RUNNING); + if (p_pritap && ftdm_test_flag(p_pritap, PRITAP_RUNNING)) { + /* our peer already started, we're the master */ + ftdm_set_flag(pritap, PRITAP_MASTER); + } ret = ftdm_thread_create_detached(ftdm_pritap_run, span); if (ret != FTDM_SUCCESS) { From d39269b21749e98308687c91a8c8786fa79a113f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 26 Oct 2012 11:40:12 -0400 Subject: [PATCH 297/512] freetdm: ftmod_pritap - Fix memory corruption due to freeing a call pointer that was still in use --- .../src/ftmod/ftmod_pritap/ftmod_pritap.c | 78 ++++++++++++++++--- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c index 1328f8f385..75d8b2a81c 100644 --- a/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c +++ b/libs/freetdm/src/ftmod/ftmod_pritap/ftmod_pritap.c @@ -455,6 +455,30 @@ static passive_call_t *tap_pri_get_pcall_bycrv(pritap_t *pritap, int crv) return NULL; } +/* + * This is a tricky function with some side effects, some explanation needed ... + * + * The libpri stack process HDLC frames, then finds Q921 frames and Q931 events, each time + * it finds a new Q931 event, checks if the crv of that event matches a known call in the internal + * list found in the PRI control block (for us, one control block per span), if it does not find + * the call, allocates a new one and then sends the event up to the user (us, ftmod_pritap in this case) + * + * The user is then expected to destroy the call when done with it (on hangup), but things get tricky here + * because in ftmod_pritap we do not destroy the call right away to be sure we only destroy it when no one + * else needs that pointer, therefore we decide to delay the destruction of the call pointer until later + * when a new call comes which triggers the garbage collecting code in this function + * + * Now, what happens if a new call arrives right away with the same crv than the last call? the pri stack + * does *not* allocate a new call pointer because is still a known call and we must therefore re-use the + * same call pointer + * + * This function accepts a pointer to a callref, even a NULL one. When callref is NULL we search for an + * available slot so the caller of this function can use it to store a new callref pointer. In the process + * we also scan for slots that still have a callref pointer but are no longer in use (inuse=0) and we + * destroy that callref and clear the slot (memset). The trick is, we only do this if the callref to + * be garbage collected is NOT the one provided by the parameter callref, of course! otherwise we may + * be freeing a pointer to a callref for a new call that used an old (recycled) callref! + */ static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref) { int i; @@ -463,7 +487,11 @@ static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref) ftdm_mutex_lock(pritap->pcalls_lock); for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) { - if (pritap->pcalls[i].callref && !pritap->pcalls[i].inuse) { + /* If this slot has a call reference + * and it is different than the *callref provided to us + * and is no longer in use, + * then it is time to garbage collect it ... */ + if (pritap->pcalls[i].callref && callref != pritap->pcalls[i].callref && !pritap->pcalls[i].inuse) { crv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref); /* garbage collection */ ftdm_log(FTDM_LOG_DEBUG, "Garbage collecting callref %d/%p from span %s in slot %d\n", @@ -475,6 +503,13 @@ static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref) if (callref == NULL) { pritap->pcalls[i].inuse = 1; ftdm_log(FTDM_LOG_DEBUG, "Enabling callref slot %d in span %s\n", i, pritap->span->name); + } else if (!pritap->pcalls[i].inuse) { + crv = tap_pri_get_crv(pritap->pri, callref); + ftdm_log(FTDM_LOG_DEBUG, "Recyclying callref slot %d in span %s for callref %d/%p\n", + i, pritap->span->name, crv, callref); + memset(&pritap->pcalls[i], 0, sizeof(pritap->pcalls[0])); + pritap->pcalls[i].callref = callref; + pritap->pcalls[i].inuse = 1; } ftdm_mutex_unlock(pritap->pcalls_lock); @@ -591,10 +626,17 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) ftdm_log(FTDM_LOG_WARNING, "There is a call with callref %d already, ignoring duplicated ring event\n", crv); break; } - pcall = tap_pri_get_pcall(pritap, NULL); + + /* Try to get a recycled call (ie, e->ring.call is a call that the PRI stack allocated previously and then + * re-used for the next RING event because we did not destroy it fast enough) */ + pcall = tap_pri_get_pcall(pritap, e->ring.call); if (!pcall) { - ftdm_log(FTDM_LOG_ERROR, "Failed to get a free passive PRI call slot for callref %d, this is a bug!\n", crv); - break; + /* ok so the call is really not known to us, let's get a new one */ + pcall = tap_pri_get_pcall(pritap, NULL); + if (!pcall) { + ftdm_log(FTDM_LOG_ERROR, "Failed to get a free passive PRI call slot for callref %d, this is a bug!\n", crv); + break; + } } pcall->callref = e->ring.call; ftdm_set_string(pcall->callingnum.digits, e->ring.callingnum); @@ -629,13 +671,25 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) } pcall->proceeding = 1; - peerpcall = tap_pri_get_pcall(pritap, NULL); - if (!peerpcall) { - ftdm_log(FTDM_LOG_ERROR, "Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!\n", - crv, pritap->span->name); + /* This call should not be known to this PRI yet ... */ + if ((peerpcall = tap_pri_get_pcall_bycrv(pritap, crv))) { + ftdm_log(FTDM_LOG_ERROR, + "ignoring proceeding in channel %s:%d:%d for callref %d, dup???\n", + pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); break; } - peerpcall->callref = e->proceeding.call; + + /* Check if the call pointer is being recycled */ + peerpcall = tap_pri_get_pcall(pritap, e->proceeding.call); + if (!peerpcall) { + peerpcall = tap_pri_get_pcall(pritap, NULL); + if (!peerpcall) { + ftdm_log(FTDM_LOG_ERROR, "Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!\n", + crv, pritap->span->name); + break; + } + peerpcall->callref = e->proceeding.call; + } /* check that the layer 1 and trans capability are supported */ layer1 = pri_get_layer1(peertap->pri, pcall->callref); @@ -707,12 +761,12 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) crv = tap_pri_get_crv(pritap->pri, e->hangup.call); ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv); + pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv); if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) { ftdm_log(FTDM_LOG_DEBUG, "ignoring hangup in channel %s:%d:%d for callref %d since we don't know about it", - pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv); + pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv); break; } @@ -733,7 +787,7 @@ static void handle_pri_passive_event(pritap_t *pritap, pri_event *e) case PRI_EVENT_HANGUP_ACK: crv = tap_pri_get_crv(pritap->pri, e->hangup.call); ftdm_log(FTDM_LOG_DEBUG, "Hangup ack on channel %s:%d:%d with callref %d\n", - pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv); + pritap->span->name, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), crv); tap_pri_put_pcall(pritap, e->hangup.call); tap_pri_put_pcall(peertap, e->hangup.call); break; From 3812ebb958dcc7b9acc93e9b30aede5700f481d1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 15:07:50 -0500 Subject: [PATCH 298/512] let codecs see current frame via the codec obj --- src/include/switch_module_interfaces.h | 1 + src/switch_core_io.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index deb96e4d47..d9fa1b2abf 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -618,6 +618,7 @@ struct switch_codec { switch_mutex_t *mutex; struct switch_codec *next; switch_core_session_t *session; + switch_frame_t *cur_frame; }; /*! \brief A table of settings and callbacks that define a paticular implementation of a codec */ diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 7dbfdb2ac8..f175cf2e07 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -376,6 +376,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_codec_t *codec = use_codec->implementation?use_codec:read_frame->codec; switch_thread_rwlock_rdlock(session->bug_rwlock); codec->session = session; + codec->cur_frame = read_frame; status = switch_core_codec_decode(codec, session->read_codec, read_frame->data, @@ -384,6 +385,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &read_frame->flags); codec->session = NULL; + codec->cur_frame = NULL; switch_thread_rwlock_unlock(session->bug_rwlock); } @@ -627,12 +629,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_assert(enc_frame != NULL); switch_assert(enc_frame->data != NULL); session->read_codec->session = session; + session->read_codec->cur_frame = enc_frame; status = switch_core_codec_encode(session->read_codec, enc_frame->codec, enc_frame->data, enc_frame->datalen, session->read_impl.actual_samples_per_second, session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag); + session->read_codec->cur_frame = NULL; session->read_codec->session = NULL; switch (status) { case SWITCH_STATUS_RESAMPLE: @@ -908,6 +912,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess if (frame->codec) { session->raw_write_frame.datalen = session->raw_write_frame.buflen; frame->codec->session = session; + frame->codec->cur_frame = frame; status = switch_core_codec_decode(frame->codec, session->write_codec, frame->data, @@ -915,6 +920,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess session->write_impl.actual_samples_per_second, session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags); frame->codec->session = NULL; + frame->codec->cur_frame = NULL; if (do_resample && status == SWITCH_STATUS_SUCCESS) { status = SWITCH_STATUS_RESAMPLE; @@ -1095,6 +1101,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess enc_frame = write_frame; session->enc_write_frame.datalen = session->enc_write_frame.buflen; session->write_codec->session = session; + session->write_codec->cur_frame = frame; status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, @@ -1102,9 +1109,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess session->write_impl.actual_samples_per_second, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); session->write_codec->session = NULL; - - - + session->write_codec->cur_frame = NULL; switch (status) { case SWITCH_STATUS_RESAMPLE: resample++; @@ -1199,6 +1204,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess rate = session->write_impl.actual_samples_per_second; } session->write_codec->session = session; + session->write_codec->cur_frame = frame; status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, @@ -1206,6 +1212,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess rate, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); session->write_codec->session = NULL; + session->write_codec->cur_frame = NULL; switch (status) { case SWITCH_STATUS_RESAMPLE: From d86f2c724a9d93a4e3c85372c5d9e5b04a2225ff Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 13:46:17 -0500 Subject: [PATCH 299/512] fix logic err --- src/switch_core_sqldb.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 4ccdb97a80..b250b737dd 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2617,7 +2617,15 @@ SWITCH_DECLARE(int) switch_core_recovery_recover(const char *technology, const c SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_core_dbtype(void) { - return sql_manager.qm ? sql_manager.qm->event_db->type : SCDB_TYPE_CORE_DB; + switch_cache_db_handle_type_t type = SCDB_TYPE_CORE_DB; + + switch_mutex_lock(sql_manager.ctl_mutex); + if (sql_manager.qm && sql_manager.qm->event_db) { + type = sql_manager.qm->event_db->type; + } + switch_mutex_unlock(sql_manager.ctl_mutex); + + return type; } SWITCH_DECLARE(void) switch_core_sql_exec(const char *sql) From bc0912cd11efb3f4525b8150733035ef37fc2ee3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 14:24:01 -0500 Subject: [PATCH 300/512] FS-4773 --resolve --- src/mod/applications/mod_dptools/mod_dptools.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 158413b9e0..5e6a732841 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1176,6 +1176,15 @@ SWITCH_STANDARD_APP(answer_function) switch_channel_answer(channel); } +SWITCH_STANDARD_APP(wait_for_answer_function) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Waiting for answer\n"); + while (!switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_ready(channel)) { + switch_ivr_sleep(session, 100, SWITCH_TRUE, NULL); + } +} + SWITCH_STANDARD_APP(presence_function) { char *argv[6] = { 0 }; @@ -5083,6 +5092,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) zombie_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); SWITCH_ADD_APP(app_interface, "pre_answer", "Pre-Answer the call", "Pre-Answer the call for a channel.", pre_answer_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "answer", "Answer the call", "Answer the call for a channel.", answer_function, "", SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "wait_for_answer", "Wait for call to be answered", "Wait for call to be answered.", wait_for_answer_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "hangup", "Hangup the call", "Hangup the call for a channel.", hangup_function, "[]", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "set_name", "Name the channel", "Name the channel", set_name_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "presence", "Send Presence", "Send Presence.", presence_function, " []", From de5f0c5144f240f39a965e04942c56a6cbc3a150 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 14:38:37 -0500 Subject: [PATCH 301/512] fix some sql mem leaks. regression from recent refactor --- src/mod/endpoints/mod_sofia/sofia_reg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index e7f6a2fbdc..3e0e3965fe 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -717,6 +717,8 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) } sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_del_callback, profile); + free(sql); + if (now) { sql = switch_mprintf("delete from sip_registrations where expires > 0 and expires <= %ld and hostname='%q'", (long) now, mod_sofia_globals.hostname); @@ -733,6 +735,8 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) "and profile_name='%s' and expires <= %ld", mod_sofia_globals.hostname, profile->name, (long) now); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sla_dialog_del_callback, profile); + free(sql); + sql = switch_mprintf("delete from sip_shared_appearance_dialogs where expires > 0 and hostname='%q' and expires <= %ld", mod_sofia_globals.hostname, (long) now); @@ -944,6 +948,7 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_mu } sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_reg_with_positive_expires_callback, &cbt); + free(sql); return cbt.list; } From 8626978201ccdcfd418eaf2540adb5349fb908ef Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 15:16:55 -0500 Subject: [PATCH 302/512] fix race cond --- src/switch_core_sqldb.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b250b737dd..ba98b02af4 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1202,6 +1202,7 @@ struct switch_sql_queue_manager { const char *name; switch_cache_db_handle_t *event_db; switch_queue_t **sql_queue; + uint32_t *pre_written; uint32_t *written; uint32_t numq; char *dsn; @@ -1439,6 +1440,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n qm->sql_queue = switch_core_alloc(qm->pool, sizeof(switch_queue_t *) * numq); qm->written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); + qm->pre_written = switch_core_alloc(qm->pool, sizeof(uint32_t) * numq); for (i = 0; i < qm->numq; i++) { switch_queue_create(&qm->sql_queue[i], SWITCH_SQL_QUEUE_LEN, qm->pool); @@ -1468,6 +1470,12 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) if (io_mutex) switch_mutex_lock(io_mutex); + switch_mutex_lock(qm->mutex); + for (i = 0; i < qm->numq; i++) { + qm->pre_written[i] = 0; + } + switch_mutex_unlock(qm->mutex); + if (!zstr(qm->pre_trans_execute)) { switch_cache_db_execute_sql_real(qm->event_db, qm->pre_trans_execute, &errmsg); if (errmsg) { @@ -1534,9 +1542,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) if (pop) { if ((status = switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL)) == SWITCH_STATUS_SUCCESS) { - switch_mutex_lock(qm->mutex); - qm->written[i]++; - switch_mutex_unlock(qm->mutex); + qm->pre_written[i]++; ttl++; } free(pop); @@ -1588,6 +1594,14 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) } } + + switch_mutex_lock(qm->mutex); + for (i = 0; i < qm->numq; i++) { + qm->written[i] += qm->pre_written[i]; + } + switch_mutex_unlock(qm->mutex); + + if (io_mutex) switch_mutex_unlock(io_mutex); return ttl; From 00def46a640d2620678b8d18080ca782febd6ffe Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 29 Oct 2012 15:51:16 -0500 Subject: [PATCH 303/512] typo --- docs/phrase/phrase_en.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml index c9fa47ec59..cb25bcb141 100644 --- a/docs/phrase/phrase_en.xml +++ b/docs/phrase/phrase_en.xml @@ -511,7 +511,7 @@ - + From fe4d736ff9c6889040e47408df07dfb66ea770e3 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 29 Oct 2012 22:34:51 -0500 Subject: [PATCH 304/512] windows trivial compiler fixes and vs2010 reswig --- src/include/switch.h | 4 ++ .../mod_managed/freeswitch_wrap.2010.cxx | 72 +++++++++++++++++-- .../mod_managed/managed/swig.2010.cs | 44 +++++++++++- src/switch_core_sqldb.c | 5 +- 4 files changed, 115 insertions(+), 10 deletions(-) diff --git a/src/include/switch.h b/src/include/switch.h index 2f7ac02f7f..c7ea7b0218 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -106,7 +106,11 @@ #include #include +#ifndef WIN32 #include "stfu.h" +#else +#include "../../../libs/stfu/stfu.h" +#endif #include "switch_platform.h" #include "switch_types.h" #include "switch_apr.h" diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 3183c52bb2..5e23486d4c 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -1840,6 +1840,16 @@ SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_DTMF_LOG_LEN_get() { } +SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_MAX_TRANS_get() { + int jresult ; + int result; + + result = (int)(2000); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_dtmf_t_digit_set(void * jarg1, char jarg2) { switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; char arg2 ; @@ -2310,6 +2320,36 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_directories_mod_dir_get(void * jarg1 } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_directories_lib_dir_set(void * jarg1, char * jarg2) { + switch_directories *arg1 = (switch_directories *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_directories *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->lib_dir) delete [] arg1->lib_dir; + if (arg2) { + arg1->lib_dir = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->lib_dir, (const char *)arg2); + } else { + arg1->lib_dir = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_directories_lib_dir_get(void * jarg1) { + char * jresult ; + switch_directories *arg1 = (switch_directories *) 0 ; + char *result = 0 ; + + arg1 = (switch_directories *)jarg1; + result = (char *) ((arg1)->lib_dir); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_directories_conf_dir_set(void * jarg1, char * jarg2) { switch_directories *arg1 = (switch_directories *) 0 ; char *arg2 = (char *) 0 ; @@ -12048,27 +12088,29 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_destroy(void * jarg1) } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_init_name(char * jarg1, void * jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_init_name(char * jarg1, void * jarg2, unsigned long jarg3, char * jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9) { int jresult ; char *arg1 = (char *) 0 ; switch_sql_queue_manager_t **arg2 = (switch_sql_queue_manager_t **) 0 ; uint32_t arg3 ; char *arg4 = (char *) 0 ; - char *arg5 = (char *) 0 ; + uint32_t arg5 ; char *arg6 = (char *) 0 ; char *arg7 = (char *) 0 ; char *arg8 = (char *) 0 ; + char *arg9 = (char *) 0 ; switch_status_t result; arg1 = (char *)jarg1; arg2 = (switch_sql_queue_manager_t **)jarg2; arg3 = (uint32_t)jarg3; arg4 = (char *)jarg4; - arg5 = (char *)jarg5; + arg5 = (uint32_t)jarg5; arg6 = (char *)jarg6; arg7 = (char *)jarg7; arg8 = (char *)jarg8; - result = (switch_status_t)switch_sql_queue_manager_init_name((char const *)arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8); + arg9 = (char *)jarg9; + result = (switch_status_t)switch_sql_queue_manager_init_name((char const *)arg1,arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9); jresult = result; return jresult; } @@ -23326,6 +23368,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_session_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_cur_frame_set(void * jarg1, void * jarg2) { + switch_codec *arg1 = (switch_codec *) 0 ; + switch_frame_t *arg2 = (switch_frame_t *) 0 ; + + arg1 = (switch_codec *)jarg1; + arg2 = (switch_frame_t *)jarg2; + if (arg1) (arg1)->cur_frame = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_cur_frame_get(void * jarg1) { + void * jresult ; + switch_codec *arg1 = (switch_codec *) 0 ; + switch_frame_t *result = 0 ; + + arg1 = (switch_codec *)jarg1; + result = (switch_frame_t *) ((arg1)->cur_frame); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec() { void * jresult ; switch_codec *result = 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index a5ec72534d..5ce0dc006c 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -2862,8 +2862,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_sql_queue_manager_init_name(string name, SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_init_name(name, SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); + public static switch_status_t switch_sql_queue_manager_init_name(string name, SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, uint max_trans, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_init_name(name, SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, max_trans, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); return ret; } @@ -6371,6 +6371,7 @@ public class freeswitch { public static readonly int SWITCH_BITS_PER_BYTE = freeswitchPINVOKE.SWITCH_BITS_PER_BYTE_get(); public static readonly int SWITCH_DEFAULT_FILE_BUFFER_LEN = freeswitchPINVOKE.SWITCH_DEFAULT_FILE_BUFFER_LEN_get(); public static readonly int SWITCH_DTMF_LOG_LEN = freeswitchPINVOKE.SWITCH_DTMF_LOG_LEN_get(); + public static readonly int SWITCH_MAX_TRANS = freeswitchPINVOKE.SWITCH_MAX_TRANS_get(); public static readonly int SWITCH_MAX_STACKS = freeswitchPINVOKE.SWITCH_MAX_STACKS_get(); public static readonly int SWITCH_THREAD_STACKSIZE = freeswitchPINVOKE.SWITCH_THREAD_STACKSIZE_get(); public static readonly int SWITCH_SYSTEM_THREAD_STACKSIZE = freeswitchPINVOKE.SWITCH_SYSTEM_THREAD_STACKSIZE_get(); @@ -7084,6 +7085,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_DTMF_LOG_LEN_get")] public static extern int SWITCH_DTMF_LOG_LEN_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_MAX_TRANS_get")] + public static extern int SWITCH_MAX_TRANS_get(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_digit_set")] public static extern void switch_dtmf_t_digit_set(HandleRef jarg1, char jarg2); @@ -7210,6 +7214,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_directories_mod_dir_get")] public static extern string switch_directories_mod_dir_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_directories_lib_dir_set")] + public static extern void switch_directories_lib_dir_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_directories_lib_dir_get")] + public static extern string switch_directories_lib_dir_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_directories_conf_dir_set")] public static extern void switch_directories_conf_dir_set(HandleRef jarg1, string jarg2); @@ -9542,7 +9552,7 @@ class freeswitchPINVOKE { public static extern int switch_sql_queue_manager_destroy(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_init_name")] - public static extern int switch_sql_queue_manager_init_name(string jarg1, HandleRef jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8); + public static extern int switch_sql_queue_manager_init_name(string jarg1, HandleRef jarg2, uint jarg3, string jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9); [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_start")] public static extern int switch_sql_queue_manager_start(HandleRef jarg1); @@ -12337,6 +12347,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_session_get")] public static extern IntPtr switch_codec_session_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_cur_frame_set")] + public static extern void switch_codec_cur_frame_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_cur_frame_get")] + public static extern IntPtr switch_codec_cur_frame_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec")] public static extern IntPtr new_switch_codec(); @@ -24182,6 +24198,7 @@ public enum switch_channel_flag_t { CF_OUTBOUND, CF_EARLY_MEDIA, CF_BRIDGE_ORIGINATOR, + CF_UUID_BRIDGE_ORIGINATOR, CF_TRANSFER, CF_ACCEPT_CNG, CF_REDIRECT, @@ -24950,6 +24967,17 @@ public class switch_codec : IDisposable { } } + public switch_frame cur_frame { + set { + freeswitchPINVOKE.switch_codec_cur_frame_set(swigCPtr, switch_frame.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_cur_frame_get(swigCPtr); + switch_frame ret = (cPtr == IntPtr.Zero) ? null : new switch_frame(cPtr, false); + return ret; + } + } + public switch_codec() : this(freeswitchPINVOKE.new_switch_codec(), true) { } @@ -26627,6 +26655,16 @@ public class switch_directories : IDisposable { } } + public string lib_dir { + set { + freeswitchPINVOKE.switch_directories_lib_dir_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_directories_lib_dir_get(swigCPtr); + return ret; + } + } + public string conf_dir { set { freeswitchPINVOKE.switch_directories_conf_dir_set(swigCPtr, value); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index ba98b02af4..3d8b43564e 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1466,7 +1466,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) switch_status_t status; uint32_t ttl = 0; switch_mutex_t *io_mutex = qm->event_db->io_mutex; - int i; + uint32_t i; if (io_mutex) switch_mutex_lock(io_mutex); @@ -1648,8 +1648,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, while (qm->thread_running == 1) { - int lc; - uint32_t i; + uint32_t i, lc; uint32_t written, iterations = 0; if (sql_manager.paused) { From acd73bfaee8650889393cb09ef02fb60a7affaaf Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 29 Oct 2012 23:16:46 -0500 Subject: [PATCH 305/512] FS-4758 try this --- src/mod/event_handlers/mod_event_socket/mod_event_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 371ce62b3a..f970a1c63e 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 @@ -366,7 +366,7 @@ static void event_handler(switch_event_t *event) if (send && switch_test_flag(l, LFLAG_MYEVENTS)) { char *uuid = switch_event_get_header(event, "unique-id"); - if (!uuid || strcmp(uuid, switch_core_session_get_uuid(l->session))) { + if (!uuid || (l->session && strcmp(uuid, switch_core_session_get_uuid(l->session)))) { send = 0; } } From d5d107d28194b7f54e2776cd27276daeca2abfea Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 30 Oct 2012 10:43:38 -0400 Subject: [PATCH 306/512] FS-3473: --resolve do not use asm optimizations on newer broken apple compiler until we can figure out the correct fix for this --- libs/spandsp/src/gsm0610_rpe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/spandsp/src/gsm0610_rpe.c b/libs/spandsp/src/gsm0610_rpe.c index 28b1a72e79..c62d892ce7 100644 --- a/libs/spandsp/src/gsm0610_rpe.c +++ b/libs/spandsp/src/gsm0610_rpe.c @@ -59,7 +59,7 @@ static void weighting_filter(int16_t x[40], const int16_t *e) // signal [-5..0.39.44] IN) { -#if defined(__GNUC__) && defined(SPANDSP_USE_MMX) && defined(__x86_64__) +#if defined(__GNUC__) && defined(SPANDSP_USE_MMX) && defined(__x86_64__) && !(defined(__APPLE_CC__) && __APPLE_CC__ >= 5448) /* Table 4.4 Coefficients of the weighting filter */ /* This must be padded to a multiple of 4 for MMX to work */ static const union From 29628007f46663e54cb5bf68623ad3755c0da5e0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 Oct 2012 08:03:03 -0500 Subject: [PATCH 307/512] good measure --- src/switch_ivr_bridge.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 3a930a62bc..b286ab5918 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1664,8 +1664,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu switch_channel_clear_state_handler(originator_channel, NULL); switch_channel_clear_state_handler(originatee_channel, NULL); + + switch_channel_clear_state_flag(originator_channel, CF_BRIDGE_ORIGINATOR); switch_channel_clear_state_flag(originatee_channel, CF_BRIDGE_ORIGINATOR); + + switch_channel_clear_flag(originator_channel, CF_UUID_BRIDGE_ORIGINATOR); + switch_channel_clear_flag(originatee_channel, CF_UUID_BRIDGE_ORIGINATOR); switch_channel_set_state_flag(originator_channel, CF_UUID_BRIDGE_ORIGINATOR); switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers); From c9d6b801ab0b34684eba1b704da8f0c3ef4616fc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 Oct 2012 09:05:41 -0500 Subject: [PATCH 308/512] add calls to execute_on_post_originate for a leg too --- src/switch_ivr_originate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index ed8534cfc7..ffdb890de3 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -3727,6 +3727,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_safe_free(fail_on_single_reject_var); if (caller_channel) { + + switch_channel_execute_on(caller_channel, SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE); + switch_channel_api_on(caller_channel, SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE); + switch_channel_clear_flag(caller_channel, CF_ORIGINATOR); switch_channel_clear_flag(caller_channel, CF_XFER_ZOMBIE); } From c711eabd75f4743fbfeefdac57893b56cfff4802 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Tue, 30 Oct 2012 18:19:13 +0000 Subject: [PATCH 309/512] More descriptive ODBC error messages. --- src/switch_odbc.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/switch_odbc.c b/src/switch_odbc.c index bba4b4cbe6..babf05b3a1 100644 --- a/src/switch_odbc.c +++ b/src/switch_odbc.c @@ -444,7 +444,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_ #ifdef SWITCH_HAVE_ODBC SQLHSTMT stmt = NULL; int result; - char *err_str = NULL; + char *err_str = NULL, *err2 = NULL; SQLLEN m = 0; handle->affected_rows = 0; @@ -454,16 +454,32 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_ } if (SQLAllocHandle(SQL_HANDLE_STMT, handle->con, &stmt) != SQL_SUCCESS) { + err2 = "SQLAllocHandle failed."; goto error; } if (SQLPrepare(stmt, (unsigned char *) sql, SQL_NTS) != SQL_SUCCESS) { + err2 = "SQLPrepare failed."; goto error; } result = SQLExecute(stmt); - if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO && result != SQL_NO_DATA) { + switch (result) { + case SQL_SUCCESS: + case SQL_SUCCESS_WITH_INFO: + case SQL_NO_DATA: + break; + case SQL_ERROR: + err2 = "SQLExecute returned SQL_ERROR."; + goto error; + break; + case SQL_NEED_DATA: + err2 = "SQLExecute returned SQL_NEED_DATA."; + goto error; + break; + default: + err2 = "SQLExecute returned unknown result code."; goto error; } @@ -486,7 +502,11 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_ } if (zstr(err_str)) { - err_str = strdup((char *)"SQL ERROR!"); + if (err2) { + err_str = strdup(err2); + } else { + err_str = strdup((char *)"SQL ERROR!"); + } } if (err_str) { From 4baec0654015b447327111a1bbea18d052a3241f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 Oct 2012 11:06:33 -0500 Subject: [PATCH 310/512] add api_on_pre_originate --- src/include/switch_types.h | 2 ++ src/switch_ivr_originate.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 8ce9c34a50..7138b13293 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -146,6 +146,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE "execute_on_tone_detect" #define SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE "execute_on_originate" #define SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE "execute_on_post_originate" +#define SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE "execute_on_pre_originate" #define SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE "api_on_answer" #define SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE "api_on_pre_answer" @@ -154,6 +155,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE "api_on_tone_detect" #define SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE "api_on_originate" #define SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE "api_on_post_originate" +#define SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE "api_on_pre_originate" #define SWITCH_CALL_TIMEOUT_VARIABLE "call_timeout" #define SWITCH_HOLDING_UUID_VARIABLE "holding_uuid" diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index ffdb890de3..d8a555c512 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1888,6 +1888,9 @@ 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_channel_execute_on(caller_channel, SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE); + switch_channel_api_on(caller_channel, SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE); + switch_core_session_get_read_impl(session, &read_impl); if ((to_var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) { From 3595c528aeae748cb98dbfc24d41ee71cd7ed6c3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 Oct 2012 14:22:31 -0500 Subject: [PATCH 311/512] reset rtpip index on reload --- src/mod/endpoints/mod_sofia/sofia.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index a6e22653f5..9118c874e2 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3597,6 +3597,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->ib_failed_calls = 0; profile->ob_failed_calls = 0; profile->shutdown_type = "false"; + profile->rtpip_index = 0; if (xprofiledomain) { profile->domain_name = switch_core_strdup(profile->pool, xprofiledomain); From 74dbbb014f6efe8edc4ac698786cd80bd251d5ef Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 Oct 2012 15:33:35 -0500 Subject: [PATCH 312/512] FS-4775 --resolve use vars voicemail_callback_dialplan and voicemail_callback_context --- src/mod/applications/mod_voicemail/mod_voicemail.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 8e58bfbac5..e6ce3aecf0 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1604,7 +1604,18 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t *cc.buf = '\0'; goto play_file; } else if (!strcmp(input, profile->callback_key)) { - switch_core_session_execute_exten(session, cbt->cid_number, profile->callback_dialplan, profile->callback_context); + const char *callback_dialplan; + const char *callback_context; + + if (!(callback_dialplan = switch_channel_get_variable(channel, "voicemail_callback_dialplan"))) { + callback_dialplan = profile->callback_dialplan; + } + + if (!(callback_context = switch_channel_get_variable(channel, "voicemail_callback_context"))) { + callback_context = profile->callback_context; + } + + switch_core_session_execute_exten(session, cbt->cid_number, callback_dialplan, callback_context); } else if (!strcmp(input, profile->forward_key)) { char *cmd = NULL; char *new_file_path = NULL; From 1de65cbcd0dbe6d20d0067e02c862b9c86196aca Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 30 Oct 2012 19:02:10 -0400 Subject: [PATCH 313/512] handle state update for hangup --- src/include/switch_ivr.h | 1 + src/switch_core_sqldb.c | 11 ++++++++--- src/switch_ivr.c | 13 +++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 9299c584d9..06679f53d3 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -927,6 +927,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi SWITCH_DECLARE(switch_status_t) switch_ivr_sound_test(switch_core_session_t *session); SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname, const char *prefix); SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid); +SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_force_exists(const char *uuid); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 3d8b43564e..e0c60ee584 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1755,7 +1755,8 @@ static char *parse_presence_data_cols(switch_event_t *event) #define MAX_SQL 5 -#define new_sql() switch_assert(sql_idx+1 < MAX_SQL); if (exists) sql[sql_idx++] +#define new_sql() switch_assert(sql_idx+1 < MAX_SQL); if (exists) sql[sql_idx++] +#define new_sql_f() switch_assert(sql_idx+1 < MAX_SQL); if (force_exists) sql[sql_idx++] static void core_event_handler(switch_event_t *event) { @@ -1763,6 +1764,7 @@ static void core_event_handler(switch_event_t *event) int sql_idx = 0; char *extra_cols; int exists = 1; + int force_exists = 1; char *uuid = NULL; switch_assert(event); @@ -1784,7 +1786,10 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CALL_SECURE: { if ((uuid = switch_event_get_header(event, "unique-id"))) { - exists = switch_ivr_uuid_exists(uuid); + force_exists = exists = switch_ivr_uuid_exists(uuid); + if (!exists) { + force_exists = switch_ivr_uuid_force_exists(uuid); + } } } break; @@ -2033,7 +2038,7 @@ static void core_event_handler(switch_event_t *event) } break; default: - new_sql() = switch_mprintf("update channels set state='%s' where uuid='%s'", + new_sql_f() = switch_mprintf("update channels set state='%s' where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "unique-id")); break; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index df5af62391..eb8d4ab9e6 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -3209,6 +3209,19 @@ SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid) return exists; } +SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_force_exists(const char *uuid) +{ + switch_bool_t exists = SWITCH_FALSE; + switch_core_session_t *psession = NULL; + + if ((psession = switch_core_session_force_locate(uuid))) { + switch_core_session_rwunlock(psession); + exists = 1; + } + + return exists; +} + SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp) { if (zstr(cmd)) { From f1bcc387a340d6cde56bb136ffd57077131bc001 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 Oct 2012 16:05:40 -0500 Subject: [PATCH 314/512] put back seq number when pulling from jb --- src/switch_rtp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 1b5925c23b..8f9fc955a7 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3054,6 +3054,7 @@ 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(jb_frame->seq); status = SWITCH_STATUS_SUCCESS; } } From ab99143d5ff1fb4d5024cbba613a3fd4fb753143 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 30 Oct 2012 16:56:03 -0500 Subject: [PATCH 315/512] only put session pointers in when its done from a codec that comes from a session and set it to the right one --- .../endpoints/mod_dingaling/mod_dingaling.c | 3 +++ src/mod/endpoints/mod_sofia/sofia_glue.c | 5 ++++ src/switch_core_io.c | 25 ++++++++++--------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index af67afcfc9..679a4d6588 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1167,6 +1167,8 @@ static int activate_audio_rtp(struct private_object *tech_pvt) r = 0; goto end; } + tech_pvt->transports[LDL_TPORT_RTP].read_codec.session = tech_pvt->session; + tech_pvt->transports[LDL_TPORT_RTP].read_frame.rate = tech_pvt->transports[LDL_TPORT_RTP].read_codec.implementation->samples_per_second; tech_pvt->transports[LDL_TPORT_RTP].read_frame.codec = &tech_pvt->transports[LDL_TPORT_RTP].read_codec; @@ -1186,6 +1188,7 @@ static int activate_audio_rtp(struct private_object *tech_pvt) r = 0; goto end; } + tech_pvt->transports[LDL_TPORT_RTP].write_codec.session = tech_pvt->session; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set Write Codec to %s@%d\n", tech_pvt->transports[LDL_TPORT_RTP].codec_name, (int) tech_pvt->transports[LDL_TPORT_RTP].write_codec.implementation->samples_per_second); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 15b6eb0eeb..bbaa9ae347 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3037,6 +3037,9 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); switch_goto_status(SWITCH_STATUS_FALSE, end); } + + tech_pvt->read_codec.session = tech_pvt->session; + if (switch_core_codec_init_with_bitrate(&tech_pvt->write_codec, tech_pvt->iananame, @@ -3052,6 +3055,8 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) switch_goto_status(SWITCH_STATUS_FALSE, end); } + tech_pvt->write_codec.session = tech_pvt->session; + switch_channel_set_variable(tech_pvt->channel, "sip_use_codec_name", tech_pvt->iananame); switch_channel_set_variable(tech_pvt->channel, "sip_use_codec_fmtp", tech_pvt->rm_fmtp); switch_channel_set_variable_printf(tech_pvt->channel, "sip_use_codec_rate", "%d", tech_pvt->rm_rate); diff --git a/src/switch_core_io.c b/src/switch_core_io.c index f175cf2e07..ba4874d81f 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -375,8 +375,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi } else { switch_codec_t *codec = use_codec->implementation?use_codec:read_frame->codec; switch_thread_rwlock_rdlock(session->bug_rwlock); - codec->session = session; codec->cur_frame = read_frame; + session->read_codec->cur_frame = read_frame; status = switch_core_codec_decode(codec, session->read_codec, read_frame->data, @@ -384,8 +384,8 @@ 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); - codec->session = NULL; codec->cur_frame = NULL; + session->read_codec->cur_frame = NULL; switch_thread_rwlock_unlock(session->bug_rwlock); } @@ -628,8 +628,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_assert(session->read_codec != NULL); switch_assert(enc_frame != NULL); switch_assert(enc_frame->data != NULL); - session->read_codec->session = session; session->read_codec->cur_frame = enc_frame; + enc_frame->codec->cur_frame = enc_frame; status = switch_core_codec_encode(session->read_codec, enc_frame->codec, enc_frame->data, @@ -637,7 +637,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->read_impl.actual_samples_per_second, session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag); session->read_codec->cur_frame = NULL; - session->read_codec->session = NULL; + enc_frame->codec->cur_frame = NULL; switch (status) { case SWITCH_STATUS_RESAMPLE: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 1\n"); @@ -911,17 +911,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess if (frame->codec) { session->raw_write_frame.datalen = session->raw_write_frame.buflen; - frame->codec->session = session; frame->codec->cur_frame = frame; + session->write_codec->cur_frame = frame; status = switch_core_codec_decode(frame->codec, session->write_codec, frame->data, frame->datalen, session->write_impl.actual_samples_per_second, session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags); - frame->codec->session = NULL; frame->codec->cur_frame = NULL; - + session->write_codec->cur_frame = NULL; if (do_resample && status == SWITCH_STATUS_SUCCESS) { status = SWITCH_STATUS_RESAMPLE; } @@ -1100,16 +1099,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess enc_frame = write_frame; session->enc_write_frame.datalen = session->enc_write_frame.buflen; - session->write_codec->session = session; session->write_codec->cur_frame = frame; + frame->codec->cur_frame = frame; status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, enc_frame->datalen, session->write_impl.actual_samples_per_second, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); - session->write_codec->session = NULL; + session->write_codec->cur_frame = NULL; + frame->codec->cur_frame = NULL; switch (status) { case SWITCH_STATUS_RESAMPLE: resample++; @@ -1203,17 +1203,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess } else { rate = session->write_impl.actual_samples_per_second; } - session->write_codec->session = session; + session->write_codec->cur_frame = frame; + frame->codec->cur_frame = frame; status = switch_core_codec_encode(session->write_codec, frame->codec, enc_frame->data, enc_frame->datalen, rate, session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); - session->write_codec->session = NULL; - session->write_codec->cur_frame = NULL; + session->write_codec->cur_frame = NULL; + frame->codec->cur_frame = NULL; switch (status) { case SWITCH_STATUS_RESAMPLE: resample++; From 4fcf7c34432edd6dc3ea03e419a261749b312995 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 31 Oct 2012 10:44:38 -0400 Subject: [PATCH 316/512] always update state to CS_HANGUP for now, even if the channel is gone to handle race where we miss this update --- src/switch_core_sqldb.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index e0c60ee584..64fc933d33 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1756,7 +1756,7 @@ static char *parse_presence_data_cols(switch_event_t *event) #define MAX_SQL 5 #define new_sql() switch_assert(sql_idx+1 < MAX_SQL); if (exists) sql[sql_idx++] -#define new_sql_f() switch_assert(sql_idx+1 < MAX_SQL); if (force_exists) sql[sql_idx++] +#define new_sql_a() switch_assert(sql_idx+1 < MAX_SQL); sql[sql_idx++] static void core_event_handler(switch_event_t *event) { @@ -1764,7 +1764,6 @@ static void core_event_handler(switch_event_t *event) int sql_idx = 0; char *extra_cols; int exists = 1; - int force_exists = 1; char *uuid = NULL; switch_assert(event); @@ -1786,10 +1785,7 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CALL_SECURE: { if ((uuid = switch_event_get_header(event, "unique-id"))) { - force_exists = exists = switch_ivr_uuid_exists(uuid); - if (!exists) { - force_exists = switch_ivr_uuid_force_exists(uuid); - } + exists = switch_ivr_uuid_exists(uuid); } } break; @@ -1980,6 +1976,11 @@ static void core_event_handler(switch_event_t *event) //case CS_HANGUP: /* marked for deprication */ case CS_INIT: break; + case CS_HANGUP: /* marked for deprication */ + new_sql_a() = switch_mprintf("update channels set state='%s' where uuid='%s'", + switch_event_get_header_nil(event, "channel-state"), + switch_event_get_header_nil(event, "unique-id")); + break; case CS_EXECUTE: if ((extra_cols = parse_presence_data_cols(event))) { new_sql() = switch_mprintf("update channels set state='%s',%s where uuid='%q'", @@ -2038,7 +2039,7 @@ static void core_event_handler(switch_event_t *event) } break; default: - new_sql_f() = switch_mprintf("update channels set state='%s' where uuid='%s'", + new_sql() = switch_mprintf("update channels set state='%s' where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "unique-id")); break; From a5acfa218c2e2bc6194ae55a0d155ceb4db6b888 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 31 Oct 2012 15:17:09 +0000 Subject: [PATCH 317/512] Help mod_h323 build on wheezy libopenh323-dev is in squeeze and sid, but it doesn't look like it's going to make it into wheezy at this point. H323Plus claims to be a drop-in replacement, but this should probably be tested thoroughly. Note that mod_h323 is still in the avoid_mods list pending testing to verify that it builds cleanly on each target. Thanks-to: Steven Ayre FS-4567 --resolve --- debian/bootstrap.sh | 2 +- debian/control-modules | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 9b3e9687fd..5307b25573 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -176,7 +176,7 @@ Build-Depends: wget, pkg-config, # configure options libssl-dev, unixodbc-dev, - libncurses5-dev, libjpeg62-dev, + libncurses5-dev, libjpeg62-dev | libjpeg8-dev, python-dev, erlang-dev, # documentation doxygen, diff --git a/debian/control-modules b/debian/control-modules index b9f0a5772a..1787a81389 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -384,7 +384,7 @@ Build-Depends: libx11-dev Module: endpoints/mod_h323 Description: mod_h323 Adds mod_h323. -Build-Depends: libopenh323-dev, libpt-dev +Build-Depends: libopenh323-dev | libh323plus-dev, libpt-dev Module: endpoints/mod_html5 Description: HTML5 endpoint module From 603f3eff973cb0688f89ccae09e33ac8d344fe4d Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 31 Oct 2012 11:22:01 -0400 Subject: [PATCH 318/512] add configure flag to turn on legacy coredb behavior --- configure.in | 7 +++++++ src/switch_core_sqldb.c | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 8031700ac6..a343ad3e9e 100644 --- a/configure.in +++ b/configure.in @@ -425,6 +425,13 @@ fi fi +AC_ARG_ENABLE(deprecated-core-db-events, + [AS_HELP_STRING([--enable-deprecated-core-db-events], [Keep deprecated core db events])],,[enable_deprecated_core_db_events="no"]) + +if test x"$enable_deprecated_core_db_events" = x"yes" ; then + AC_DEFINE([SWITCH_DEPRECATED_CORE_DB], [1], [Define to 1 to enable deprecated core db events]) +fi + AC_ARG_ENABLE(timerfd-wrapper, [AC_HELP_STRING([--enable-timerfd-wrapper],[timerfd is in the kernel but not in your libc])],[enable_timer_fd_wrapper="$enableval"],[enable_timer_fd_wrapper="no"]) AM_CONDITIONAL([ENABLE_TIMERFD_WRAPPER],[test "x$enable_timer_fd_wrapper" != "xno"]) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 64fc933d33..ba3f116d3c 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1973,14 +1973,18 @@ static void core_event_handler(switch_event_t *event) case CS_NEW: case CS_DESTROY: case CS_REPORTING: - //case CS_HANGUP: /* marked for deprication */ +#ifndef SWITCH_DEPRECATED_CORE_DB + case CS_HANGUP: /* marked for deprication */ +#endif case CS_INIT: break; +#ifdef SWITCH_DEPRECATED_CORE_DB case CS_HANGUP: /* marked for deprication */ new_sql_a() = switch_mprintf("update channels set state='%s' where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "unique-id")); break; +#endif case CS_EXECUTE: if ((extra_cols = parse_presence_data_cols(event))) { new_sql() = switch_mprintf("update channels set state='%s',%s where uuid='%q'", From 6d7e2799c3dbe5ce0f9ab8d1ca45ff712b9c71af Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 11:41:42 -0400 Subject: [PATCH 319/512] FS-4741 I think I see the issue, try this --- src/switch_xml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_xml.c b/src/switch_xml.c index 237873e15d..e949113a59 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2920,7 +2920,7 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond, int *offse if (offset) { eoffset = *offset; - switch_time_exp_tz(&tm, ts, *offset); + switch_time_exp_tz(&tm, ts, *offset * 3600); } else { tm = tm2; } From 0343b3ae8f56ee8825039ce582709e490c027017 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 11:45:09 -0400 Subject: [PATCH 320/512] FS-4777 --resolve --- libs/libdingaling/src/libdingaling.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index e2b32a0637..5b45f50e2f 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -820,6 +820,9 @@ static ldl_status parse_jingle_code(ldl_handle_t *handle, iks *xml, char *to, ch break; } } + } else { + globals.logger(DL_LOG_WARNING, "No preference specified"); + continue; } if (index < 0) { From 7ade45164a39af2f8232a30f91d0321ecee8a045 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 11:46:17 -0400 Subject: [PATCH 321/512] FS-4776 --resolve --- libs/libdingaling/src/libdingaling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 5b45f50e2f..9457663681 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -623,7 +623,7 @@ static ldl_status parse_jingle_code(ldl_handle_t *handle, iks *xml, char *to, ch } - if (!(id && action)) { + if (!(id && action && from)) { globals.logger(DL_LOG_CRIT, "missing required params\n"); return LDL_STATUS_FALSE; } From 23bb963d17848d1f21b2934073b3e8c4f12a0880 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 08:51:55 -0500 Subject: [PATCH 322/512] FS-4779 I don't have this labbed up to try so can you try this patch and repost logs if it doesn't work --- src/mod/endpoints/mod_sofia/mod_sofia.c | 32 ++++++++++++++++++------- src/mod/endpoints/mod_sofia/sofia.c | 15 ++++++++++-- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index ddf0b5dccf..c11d37c42f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2019,16 +2019,30 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_get_name(channel), msg->string_arg); sofia_glue_tech_set_local_sdp(tech_pvt, msg->string_arg, SWITCH_TRUE); - if(zstr(tech_pvt->local_sdp_str)) { - sofia_set_flag(tech_pvt, TFLAG_3PCC_INVITE); + if (msg->numeric_arg) { // ACK + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY nomedia - sending ack\n"); + nua_ack(tech_pvt->nh, + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + SOATAG_USER_SDP_STR(msg->string_arg), + SOATAG_REUSE_REJECTED(1), + SOATAG_RTP_SELECT(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), + TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), + TAG_END()); + sofia_clear_flag(tech_pvt, TFLAG_3PCC_INVITE); + + } else { + if(zstr(tech_pvt->local_sdp_str)) { + sofia_set_flag(tech_pvt, TFLAG_3PCC_INVITE); + } + + sofia_set_flag_locked(tech_pvt, TFLAG_SENT_UPDATE); + + if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { + switch_channel_set_flag(channel, CF_REQ_MEDIA); + } + sofia_glue_do_invite(session); } - - sofia_set_flag_locked(tech_pvt, TFLAG_SENT_UPDATE); - - if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { - switch_channel_set_flag(channel, CF_REQ_MEDIA); - } - sofia_glue_do_invite(session); } break; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 9118c874e2..679fcd52c9 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1155,6 +1155,7 @@ static void our_sofia_event_callback(nua_event_t event, switch_core_recovery_track(session); sofia_set_flag(tech_pvt, TFLAG_GOT_ACK); + if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) { switch_core_session_t *other_session; @@ -5750,13 +5751,23 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE) && !sofia_test_flag(tech_pvt, TFLAG_SDP)) { sofia_set_flag(tech_pvt, TFLAG_SDP); if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + switch_core_session_message_t *msg; + other_channel = switch_core_session_get_channel(other_session); - //other_tech_pvt = switch_core_session_get_private(other_session); if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) { switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp); } - switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER); + + msg = switch_core_session_alloc(other_session, sizeof(*msg)); + msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT; + msg->from = __FILE__; + msg->string_arg = switch_core_session_strdup(other_session, r_sdp); + msg->numeric_arg = 1; // send ack + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing SDP ACK to other leg.\n%s\n", r_sdp); + + switch_core_session_queue_message(other_session, msg); + switch_core_session_rwunlock(other_session); } goto done; From 5ca8cf7d8ece44bc90e95f72fc705c1a9c959d4c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 08:59:31 -0500 Subject: [PATCH 323/512] call destroy not stop in sofia profile --- src/mod/endpoints/mod_sofia/sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 679fcd52c9..adb06caaba 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2621,7 +2621,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_mutex_lock(profile->flag_mutex); switch_mutex_unlock(profile->flag_mutex); - switch_sql_queue_manager_stop(profile->qm); + switch_sql_queue_manager_destroy(&profile->qm); if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp,_sip._tcp,_sip._sctp%s", From c50336b1f82c5c38529a4e2ddfba1d8d55fc896d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 10:31:23 -0500 Subject: [PATCH 324/512] deal with handles being released incorrectly --- src/switch_core_sqldb.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index ba3f116d3c..ac32d7d146 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -209,6 +209,7 @@ static void sql_close(time_t prune) { switch_cache_db_handle_t *dbh = NULL; int locked = 0; + int sanity = 10000; switch_mutex_lock(sql_manager.dbh_mutex); top: @@ -254,7 +255,12 @@ static void sql_close(time_t prune) } else { if (!prune) { - locked++; + if (!sanity) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SANITY CHECK FAILED! Handle %s (%s;%s) was not properly released.\n", + dbh->name, dbh->creator, dbh->last_user); + } else { + locked++; + } } continue; } @@ -262,6 +268,10 @@ static void sql_close(time_t prune) } if (locked) { + if (!prune) { + switch_cond_next(); + if (sanity) sanity--; + } goto top; } From a4a44fb140d432b8c4327e713fb215fcf7c42901 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 10:43:59 -0500 Subject: [PATCH 325/512] FS-4741 parse timezone variable and adjust time for time based routing --- src/include/switch_xml.h | 2 +- src/mod/applications/mod_sms/mod_sms.c | 18 +++++++++++++++++- .../mod_dialplan_xml/mod_dialplan_xml.c | 7 ++++--- src/switch_xml.c | 4 +++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h index a29250ad49..173981e5b2 100644 --- a/src/include/switch_xml.h +++ b/src/include/switch_xml.h @@ -423,7 +423,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_unbind_search_function_ptr(_In_ switc ///\return the section mask SWITCH_DECLARE(switch_xml_section_t) switch_xml_parse_section_string(_In_opt_z_ const char *str); -SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond, int *offset); +SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond, int *offset, const char *tzname); SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language); diff --git a/src/mod/applications/mod_sms/mod_sms.c b/src/mod/applications/mod_sms/mod_sms.c index 8b747cb015..34b2971333 100644 --- a/src/mod/applications/mod_sms/mod_sms.c +++ b/src/mod/applications/mod_sms/mod_sms.c @@ -64,6 +64,16 @@ typedef enum { } break_t; +#define check_tz() tzoff = switch_event_get_header(event, "tod_tz_offset"); \ + tzname = switch_event_get_header(event, "timezone"); \ + do { \ + if (!zstr(tzoff) && switch_is_number(tzoff)) { \ + offset = atoi(tzoff); \ + } else { \ + tzoff = NULL; \ + } \ + break; \ + } while(tzoff) static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_t **extension) { @@ -73,6 +83,10 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_ char *expression_expanded = NULL, *field_expanded = NULL; switch_regex_t *re = NULL; const char *to = switch_event_get_header(event, "to"); + const char *tzoff = NULL, *tzname = NULL; + int offset = 0; + + check_tz(); if (!to) { to = "nobody"; @@ -90,8 +104,10 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_ int ovector[30]; switch_bool_t anti_action = SWITCH_TRUE; break_t do_break_i = BREAK_ON_FALSE; + int time_match; - int time_match = switch_xml_std_datetime_check(xcond, NULL); + check_tz(); + time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL, tzname); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c index 6b685d547d..ac1500c4f5 100644 --- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c +++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c @@ -81,6 +81,7 @@ static switch_status_t exec_app(switch_core_session_t *session, const char *app, #define check_tz() tzoff = switch_channel_get_variable(channel, "tod_tz_offset"); \ + tzname = switch_channel_get_variable(channel, "timezone"); \ do { \ if (!zstr(tzoff) && switch_is_number(tzoff)) { \ offset = atoi(tzoff); \ @@ -99,7 +100,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * char *expression_expanded = NULL, *field_expanded = NULL; switch_regex_t *re = NULL, *save_re = NULL; int offset = 0; - const char *tzoff; + const char *tzoff = NULL, *tzname = NULL; check_tz(); @@ -120,7 +121,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * int time_match; check_tz(); - time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL); + time_match = switch_xml_std_datetime_check(xcond, tzoff ? &offset : NULL, tzname); switch_safe_free(field_expanded); @@ -173,7 +174,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * for (xregex = switch_xml_child(xcond, "regex"); xregex; xregex = xregex->next) { check_tz(); - time_match = switch_xml_std_datetime_check(xregex, tzoff ? &offset : NULL); + time_match = switch_xml_std_datetime_check(xregex, tzoff ? &offset : NULL, tzname); if (time_match == 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, diff --git a/src/switch_xml.c b/src/switch_xml.c index e949113a59..e0f3e3d37d 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2883,7 +2883,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_cut(switch_xml_t xml) return xml; } -SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond, int *offset) +SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond, int *offset, const char *tzname) { const char *xdt = switch_xml_attr(xcond, "date-time"); @@ -2921,6 +2921,8 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond, int *offse if (offset) { eoffset = *offset; switch_time_exp_tz(&tm, ts, *offset * 3600); + } else if (!zstr(tzname)) { + switch_time_exp_tz_name(tzname, &tm, ts); } else { tm = tm2; } From d1ad4d477c62bc8984b38b52a2b92f54e1943bcd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 12:56:09 -0500 Subject: [PATCH 326/512] add no_loopback flag to apps so they can tell mod_loopback to bow out --- src/include/switch_types.h | 3 +- .../applications/mod_spandsp/mod_spandsp.c | 4 +- src/mod/endpoints/mod_loopback/mod_loopback.c | 40 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 7138b13293..d7d96b5aaf 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1304,7 +1304,8 @@ typedef enum { SAF_SUPPORT_NOMEDIA = (1 << 0), SAF_ROUTING_EXEC = (1 << 1), SAF_MEDIA_TAP = (1 << 2), - SAF_ZOMBIE_EXEC = (1 << 3) + SAF_ZOMBIE_EXEC = (1 << 3), + SAF_NO_LOOPBACK = (1 << 4) } switch_application_flag_enum_t; typedef uint32_t switch_application_flag_t; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index 6ee395770f..fa7a0da79a 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -714,9 +714,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spandsp_init) t38_gateway_function, "", SAF_MEDIA_TAP); SWITCH_ADD_APP(app_interface, "rxfax", "FAX Receive Application", "FAX Receive Application", spanfax_rx_function, SPANFAX_RX_USAGE, - SAF_SUPPORT_NOMEDIA); + SAF_SUPPORT_NOMEDIA | SAF_NO_LOOPBACK); SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE, - SAF_SUPPORT_NOMEDIA); + SAF_SUPPORT_NOMEDIA | SAF_NO_LOOPBACK); SWITCH_ADD_APP(app_interface, "spandsp_stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "spandsp_start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP); diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 8835cc05a1..adf911cbba 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -42,6 +42,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_loopback_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_loopback_shutdown); SWITCH_MODULE_DEFINITION(mod_loopback, mod_loopback_load, mod_loopback_shutdown, NULL); +static switch_status_t find_non_loopback_bridge(switch_core_session_t *session, switch_core_session_t **br_session, const char **br_uuid); + static switch_endpoint_interface_t *loopback_endpoint_interface = NULL; typedef enum { @@ -409,6 +411,8 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; + switch_caller_extension_t *exten; + int bow = 0; channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -418,6 +422,37 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel)); + + if ((exten = switch_channel_get_caller_extension(channel))) { + switch_caller_application_t *app_p; + + for (app_p = exten->applications; app_p; app_p = app_p->next) { + int32_t flags; + + switch_core_session_get_app_flags(app_p->application_name, &flags); + + if ((flags & SAF_NO_LOOPBACK)) { + bow = 1; + break; + } + } + } + + if (bow) { + switch_core_session_t *other_session; + const char *other_uuid; + + if ((find_non_loopback_bridge(tech_pvt->other_session, &other_session, &other_uuid) == SWITCH_STATUS_SUCCESS)) { + switch_caller_extension_t *extension; + switch_channel_t *other_channel = switch_core_session_get_channel(other_session); + switch_caller_extension_clone(&extension, exten, switch_core_session_get_pool(other_session)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "BOWOUT Transfering current extension to non-loopback leg.\n"); + switch_channel_transfer_to_extension(other_channel, extension); + switch_core_session_rwunlock(other_session); + } + + } + return SWITCH_STATUS_SUCCESS; } @@ -1126,11 +1161,16 @@ static switch_io_routines_t channel_io_routines = { /*.receive_message */ channel_receive_message }; +SWITCH_STANDARD_APP(unloop_function) { /* NOOP */} + SWITCH_MODULE_LOAD_FUNCTION(mod_loopback_load) { + switch_application_interface_t *app_interface; memset(&globals, 0, sizeof(globals)); + SWITCH_ADD_APP(app_interface, "unloop", "Tell loopback to unfold", "Tell loopback to unfold", unloop_function, "", SAF_NO_LOOPBACK); + /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); loopback_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); From 9fae77ae76d41206420970edae435b25e2d9f2c7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 13:02:03 -0500 Subject: [PATCH 327/512] doh --- src/mod/endpoints/mod_loopback/mod_loopback.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index adf911cbba..e711622d34 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -1169,8 +1169,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_loopback_load) memset(&globals, 0, sizeof(globals)); - SWITCH_ADD_APP(app_interface, "unloop", "Tell loopback to unfold", "Tell loopback to unfold", unloop_function, "", SAF_NO_LOOPBACK); - /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); loopback_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); @@ -1178,6 +1176,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_loopback_load) loopback_endpoint_interface->io_routines = &channel_io_routines; loopback_endpoint_interface->state_handler = &channel_event_handlers; + SWITCH_ADD_APP(app_interface, "unloop", "Tell loopback to unfold", "Tell loopback to unfold", unloop_function, "", SAF_NO_LOOPBACK); + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } From aee3767420e5efcaf935260af3a1fcab83748705 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 31 Oct 2012 14:27:57 -0500 Subject: [PATCH 328/512] FS-4780 try this --- src/switch_core_media_bug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index f5c57721ad..b8b83da6bd 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -251,7 +251,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_read(switch_media_bug_t *b } } else { if (read_impl.decoded_bytes_per_packet > other_read_impl.decoded_bytes_per_packet) { - frame_size = other_read_impl.decoded_bytes_per_packet; + frame_size = read_impl.decoded_bytes_per_packet; } } } From 254514448fcee0224adfd6f4627021c2b28cd1f2 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 31 Oct 2012 20:48:28 -0500 Subject: [PATCH 329/512] vs2010 reswig --- .../mod_managed/freeswitch_wrap.2010.cxx | 38 ++++++++++++++++++- .../mod_managed/managed/swig.2010.cs | 25 ++++++++++-- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 5e23486d4c..8d09ec6b03 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -1190,6 +1190,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VA } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("execute_on_pre_originate"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -1260,6 +1270,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIAB } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("api_on_pre_originate"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -31460,6 +31480,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_uuid_exists(char * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_uuid_force_exists(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_bool_t result; + + arg1 = (char *)jarg1; + result = (switch_bool_t)switch_ivr_uuid_force_exists((char const *)arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_last_ping(void * jarg1) { int jresult ; switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; @@ -34401,15 +34433,17 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_xml_parse_section_string(char } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_std_datetime_check(void * jarg1, void * jarg2) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_std_datetime_check(void * jarg1, void * jarg2, char * jarg3) { int jresult ; switch_xml_t arg1 = (switch_xml_t) 0 ; int *arg2 = (int *) 0 ; + char *arg3 = (char *) 0 ; int result; arg1 = (switch_xml_t)jarg1; arg2 = (int *)jarg2; - result = (int)switch_xml_std_datetime_check(arg1,arg2); + arg3 = (char *)jarg3; + result = (int)switch_xml_std_datetime_check(arg1,arg2,(char const *)arg3); 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 5ce0dc006c..25a99cdf69 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -5245,6 +5245,11 @@ public class freeswitch { return ret; } + public static switch_bool_t switch_ivr_uuid_force_exists(string uuid) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_ivr_uuid_force_exists(uuid); + return ret; + } + public static switch_status_t switch_ivr_dmachine_last_ping(SWIGTYPE_p_switch_ivr_dmachine dmachine) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_last_ping(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); return ret; @@ -6001,8 +6006,8 @@ public class freeswitch { return ret; } - public static int switch_xml_std_datetime_check(switch_xml xcond, SWIGTYPE_p_int offset) { - int ret = freeswitchPINVOKE.switch_xml_std_datetime_check(switch_xml.getCPtr(xcond), SWIGTYPE_p_int.getCPtr(offset)); + public static int switch_xml_std_datetime_check(switch_xml xcond, SWIGTYPE_p_int offset, string tzname) { + int ret = freeswitchPINVOKE.switch_xml_std_datetime_check(switch_xml.getCPtr(xcond), SWIGTYPE_p_int.getCPtr(offset), tzname); return ret; } @@ -6306,6 +6311,7 @@ public class freeswitch { public static readonly string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE_get(); + public static readonly string SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE_get(); @@ -6313,6 +6319,7 @@ public class freeswitch { public static readonly string SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE_get(); + public static readonly string SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CALL_TIMEOUT_VARIABLE = freeswitchPINVOKE.SWITCH_CALL_TIMEOUT_VARIABLE_get(); public static readonly string SWITCH_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_HOLDING_UUID_VARIABLE_get(); public static readonly string SWITCH_SOFT_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_SOFT_HOLDING_UUID_VARIABLE_get(); @@ -6890,6 +6897,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE_get")] public static extern string SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get")] + public static extern string SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get")] public static extern string SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get(); @@ -6911,6 +6921,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE_get")] public static extern string SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get")] + public static extern string SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get")] public static extern string SWITCH_CALL_TIMEOUT_VARIABLE_get(); @@ -14141,6 +14154,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_uuid_exists")] public static extern int switch_ivr_uuid_exists(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_uuid_force_exists")] + public static extern int switch_ivr_uuid_force_exists(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_last_ping")] public static extern int switch_ivr_dmachine_last_ping(HandleRef jarg1); @@ -14802,7 +14818,7 @@ class freeswitchPINVOKE { public static extern uint switch_xml_parse_section_string(string jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_std_datetime_check")] - public static extern int switch_xml_std_datetime_check(HandleRef jarg1, HandleRef jarg2); + public static extern int switch_xml_std_datetime_check(HandleRef jarg1, HandleRef jarg2, string jarg3); [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_locate_language")] public static extern int switch_xml_locate_language(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, HandleRef jarg5, HandleRef jarg6, string jarg7); @@ -21790,7 +21806,8 @@ namespace FreeSWITCH.Native { SAF_SUPPORT_NOMEDIA = (1 << 0), SAF_ROUTING_EXEC = (1 << 1), SAF_MEDIA_TAP = (1 << 2), - SAF_ZOMBIE_EXEC = (1 << 3) + SAF_ZOMBIE_EXEC = (1 << 3), + SAF_NO_LOOPBACK = (1 << 4) } } From 2494448846eafac0ef7c6a2ba174004a4e361590 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 09:00:38 -0500 Subject: [PATCH 330/512] FS-4781 --resolve I added some more code to the jb for seq but I still think the timestamp is more reliable than the seq since we can't know if the rtp is passing over a media proxy who may preserve the timestamps but still rewrite the seq, its more likely the ts shows the more accurate order of the rtp stream --- libs/stfu/stfu.c | 40 ++++++++++++++++++++++++++++- libs/stfu/stfu.h | 1 + src/mod/codecs/mod_silk/Makefile | 1 + src/mod/codecs/mod_silk/mod_silk.c | 41 +++++++++++++++++++++++------- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 7ca036fc64..f02219cd9e 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -69,6 +69,7 @@ struct stfu_instance { struct stfu_queue *old_queue; struct stfu_frame *last_frame; uint32_t cur_ts; + uint16_t cur_seq; uint32_t last_wr_ts; uint32_t last_rd_ts; uint32_t samples_per_packet; @@ -361,6 +362,7 @@ void stfu_n_reset(stfu_instance_t *i) stfu_n_sync(i, 1); i->cur_ts = 0; + i->cur_seq = 0; i->last_wr_ts = 0; i->last_rd_ts = 0; i->miss_count = 0; @@ -650,6 +652,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) 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; + i->cur_ts = i->out_queue->array[x].seq; break; } if (i->cur_ts == 0) { @@ -661,6 +664,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) } } else { i->cur_ts = i->cur_ts + i->samples_per_packet; + i->cur_seq++; } found = stfu_n_find_frame(i, i->out_queue, i->last_wr_ts, i->cur_ts, &rframe); @@ -679,12 +683,14 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) if (found) { i->cur_ts = rframe->ts; + i->cur_seq = rframe->seq; } if (i->sync_out) { if (!found) { if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) { i->cur_ts = rframe->ts; + i->cur_seq = rframe->seq; } if (stfu_log != null_logger && i->debug) { @@ -783,6 +789,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) rframe->dlen = i->plc_len; rframe->pt = i->plc_pt; rframe->ts = i->cur_ts; + rframe->seq = i->cur_seq; i->miss_count++; if (stfu_log != null_logger && i->debug) { @@ -799,6 +806,38 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) return rframe; } +int32_t stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame) +{ + uint32_t i = 0, j = 0; + stfu_queue_t *queues[] = { jb->out_queue, jb->in_queue, jb->old_queue}; + stfu_queue_t *queue = NULL; + stfu_frame_t *frame = NULL; + + uint32_t target_ts = 0; + + if (!next_frame) return 0; + + target_ts = timestamp + (distance - 1) * jb->samples_per_packet; + + for (i = 0; i < sizeof(queues)/sizeof(queues[0]); i++) { + queue = queues[i]; + + if (!queue) continue; + + for(j = 0; j < queue->array_size; j++) { + frame = &queue->array[j]; + /* FIXME: ts rollover happened? bad luck */ + if (frame->ts > target_ts) { + memcpy(next_frame, frame, sizeof(stfu_frame_t)); + return 1; + } + } + } + + return 0; +} + + #ifdef WIN32 #ifndef vsnprintf #define vsnprintf _vsnprintf @@ -927,7 +966,6 @@ static void default_logger(const char *file, const char *func, int line, int lev } - /* For Emacs: * Local Variables: * mode:c diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index e3d05bcbc1..bc3dd519ba 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -191,6 +191,7 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_ 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, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last); stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i); +int32_t stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame); 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); diff --git a/src/mod/codecs/mod_silk/Makefile b/src/mod/codecs/mod_silk/Makefile index 68ea756954..23d7811ee7 100644 --- a/src/mod/codecs/mod_silk/Makefile +++ b/src/mod/codecs/mod_silk/Makefile @@ -4,6 +4,7 @@ SILK_BUILDDIR=$(switch_builddir)/libs/silk LOCAL_CFLAGS=-I$(SILK_DIR)/src -I$(SILK_DIR)/interface SILK_LA=$(SILK_BUILDDIR)/.libs/libSKP_SILK_SDK.la LOCAL_LIBADD=$(SILK_LA) +LOCAL_OBJS=$(BASE)/libs/stfu/stfu.o include $(BASE)/build/modmake.rules $(SILK_LA): $(SILK_DIR)/.update diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index af32332de2..922c86d06b 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -31,6 +31,7 @@ */ #include "switch.h" +#include "stfu.h" #include "SKP_Silk_SDK_API.h" SWITCH_MODULE_LOAD_FUNCTION(mod_silk_load); @@ -321,23 +322,43 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, SKP_int16 ret, len; int16_t *target = decoded_data; switch_core_session_t *session = codec->session; - stfu_instance_t *jb; + stfu_instance_t *jb = NULL; + + SKP_int lost_flag = (*flag & SFF_PLC); + stfu_frame_t next_frame; + + SKP_uint8 recbuff[STFU_DATALEN]; + SKP_int16 reclen; + int32_t found_frame; + switch_bool_t did_lbrr = SWITCH_FALSE; *decoded_data_len = 0; - if (session) { - jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO); - } - - if (jb) { - /* to allow compile */ - jb = NULL; + if (lost_flag) { + if (session) { + jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO); + } + if (jb && codec && codec->cur_frame) { + for (int i = 1; i <= MAX_LBRR_DELAY; i++) { + found_frame = stfu_n_copy_next_frame(jb, codec->cur_frame->timestamp, codec->cur_frame->seq, i, &next_frame); + if (found_frame) { + SKP_Silk_SDK_search_for_LBRR(next_frame.data, next_frame.dlen, i, (SKP_uint8*) &recbuff, &reclen); + if (reclen) { + encoded_data = &recbuff; + encoded_data_len = reclen; + lost_flag = SKP_FALSE; + did_lbrr = SWITCH_TRUE; + break; + } + } + } + } } do { ret = SKP_Silk_SDK_Decode(context->dec_state, &context->decoder_object, - ((*flag & SFF_PLC)), + lost_flag, encoded_data, encoded_data_len, target, @@ -345,6 +366,8 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, if (ret){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SKP_Silk_Decode returned %d!\n", ret); printSilkError(ret); + /* if FEC was activated, we can ignore bit errors*/ + if (! (ret == SKP_SILK_DEC_PAYLOAD_ERROR && did_lbrr)) return SWITCH_STATUS_FALSE; } From 3e94242c4b5ff35742789385b72f547e537bfcfd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 09:14:34 -0500 Subject: [PATCH 331/512] FS-4779 try this instead --- src/mod/endpoints/mod_sofia/sofia.c | 56 +++++++++++++++-------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index adb06caaba..4a074088fc 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1133,6 +1133,8 @@ static void our_sofia_event_callback(nua_event_t event, case nua_i_ack: { if (channel && sip) { + char *r_sdp = NULL; + if (sip->sip_to && sip->sip_to->a_tag) { switch_channel_set_variable(channel, "sip_to_tag", sip->sip_to->a_tag); } @@ -1155,6 +1157,34 @@ static void our_sofia_event_callback(nua_event_t event, switch_core_recovery_track(session); sofia_set_flag(tech_pvt, TFLAG_GOT_ACK); + if (sip->sip_payload && sip->sip_payload->pl_data && sip->sip_content_type && + sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) { + r_sdp = sip->sip_payload->pl_data; + } + + if (!zstr(r_sdp) && (sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) { + switch_core_session_t *other_session; + sofia_set_flag(tech_pvt, TFLAG_SDP); + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + switch_core_session_message_t *msg; + switch_channel_t *other_channel = switch_core_session_get_channel(other_session); + + if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) { + switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp); + } + + msg = switch_core_session_alloc(other_session, sizeof(*msg)); + msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT; + msg->from = __FILE__; + msg->string_arg = switch_core_session_strdup(other_session, r_sdp); + msg->numeric_arg = 1; // send ack + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing SDP ACK to other leg.\n%s\n", r_sdp); + + switch_core_session_queue_message(other_session, msg); + + switch_core_session_rwunlock(other_session); + } + } if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) { switch_core_session_t *other_session; @@ -5748,32 +5778,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } - if (r_sdp && sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE) && !sofia_test_flag(tech_pvt, TFLAG_SDP)) { - sofia_set_flag(tech_pvt, TFLAG_SDP); - if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - switch_core_session_message_t *msg; - - other_channel = switch_core_session_get_channel(other_session); - - if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) { - switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp); - } - - msg = switch_core_session_alloc(other_session, sizeof(*msg)); - msg->message_id = SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT; - msg->from = __FILE__; - msg->string_arg = switch_core_session_strdup(other_session, r_sdp); - msg->numeric_arg = 1; // send ack - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing SDP ACK to other leg.\n%s\n", r_sdp); - - switch_core_session_queue_message(other_session, msg); - - switch_core_session_rwunlock(other_session); - } - goto done; - - } - if (send_ack) { tech_send_ack(nh, tech_pvt); } else { From f7366b6c91b256bcf6a2547aa6aa6d4fae71a0b6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 12:25:29 -0500 Subject: [PATCH 332/512] loop on eintr on pop and trypop --- src/switch_apr.c | 69 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/switch_apr.c b/src/switch_apr.c index aeb10185a9..db6f075bed 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -614,34 +614,9 @@ SWITCH_DECLARE(const char *) switch_dir_next_file(switch_dir_t *thedir, char *bu /* thread stubs */ -#ifndef WIN32 -struct apr_threadattr_t { - apr_pool_t *pool; - pthread_attr_t attr; - int priority; -}; -#else -/* this needs to be revisited when apr for windows supports thread priority settings */ -/* search for WIN32 in this file */ -struct apr_threadattr_t { - apr_pool_t *pool; - apr_int32_t detach; - apr_size_t stacksize; -}; -#endif - - SWITCH_DECLARE(switch_status_t) switch_threadattr_create(switch_threadattr_t ** new_attr, switch_memory_pool_t *pool) { - switch_status_t status; - - if ((status = apr_threadattr_create(new_attr, pool)) == SWITCH_STATUS_SUCCESS) { -#ifndef WIN32 - (*new_attr)->priority = SWITCH_PRI_LOW; -#endif - } - - return status; + return apr_threadattr_create(new_attr, pool); } SWITCH_DECLARE(switch_status_t) switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on) @@ -654,12 +629,29 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_stacksize_set(switch_threadatt return apr_threadattr_stacksize_set(attr, stacksize); } -SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_set(switch_threadattr_t *attr, switch_thread_priority_t priority) -{ #ifndef WIN32 - attr->priority = priority; +struct apr_threadattr_t { + apr_pool_t *pool; + pthread_attr_t attr; +}; #endif - return SWITCH_STATUS_SUCCESS; + +SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_increase(switch_threadattr_t *attr) +{ + int stat = 0; +#ifndef WIN32 + struct sched_param param; + struct apr_threadattr_t *myattr = attr; + + pthread_attr_getschedparam(&myattr->attr, ¶m); + param.sched_priority = 1; + stat = pthread_attr_setschedparam(&myattr->attr, ¶m); + + if (stat == 0) { + return SWITCH_STATUS_SUCCESS; + } +#endif + return stat; } static char TT_KEY[] = "1"; @@ -1050,7 +1042,13 @@ SWITCH_DECLARE(unsigned int) switch_queue_size(switch_queue_t *queue) SWITCH_DECLARE(switch_status_t) switch_queue_pop(switch_queue_t *queue, void **data) { - return apr_queue_pop(queue, data); + apr_status_t s; + + do { + s = apr_queue_pop(queue, data); + } while (s == APR_EINTR); + + return s; } SWITCH_DECLARE(switch_status_t) switch_queue_pop_timeout(switch_queue_t *queue, void **data, switch_interval_time_t timeout) @@ -1072,7 +1070,14 @@ SWITCH_DECLARE(switch_status_t) switch_queue_push(switch_queue_t *queue, void *d SWITCH_DECLARE(switch_status_t) switch_queue_trypop(switch_queue_t *queue, void **data) { - return apr_queue_trypop(queue, data); + apr_status_t s; + + do { + s = apr_queue_trypop(queue, data); + } while (s == APR_EINTR); + + return s; + } SWITCH_DECLARE(switch_status_t) switch_queue_interrupt_all(switch_queue_t *queue) From ce142f06f733188aca5b0d25017052df51593c12 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 12:26:31 -0500 Subject: [PATCH 333/512] revert --- src/switch_apr.c | 67 ++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/switch_apr.c b/src/switch_apr.c index db6f075bed..aeb10185a9 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -614,9 +614,34 @@ SWITCH_DECLARE(const char *) switch_dir_next_file(switch_dir_t *thedir, char *bu /* thread stubs */ +#ifndef WIN32 +struct apr_threadattr_t { + apr_pool_t *pool; + pthread_attr_t attr; + int priority; +}; +#else +/* this needs to be revisited when apr for windows supports thread priority settings */ +/* search for WIN32 in this file */ +struct apr_threadattr_t { + apr_pool_t *pool; + apr_int32_t detach; + apr_size_t stacksize; +}; +#endif + + SWITCH_DECLARE(switch_status_t) switch_threadattr_create(switch_threadattr_t ** new_attr, switch_memory_pool_t *pool) { - return apr_threadattr_create(new_attr, pool); + switch_status_t status; + + if ((status = apr_threadattr_create(new_attr, pool)) == SWITCH_STATUS_SUCCESS) { +#ifndef WIN32 + (*new_attr)->priority = SWITCH_PRI_LOW; +#endif + } + + return status; } SWITCH_DECLARE(switch_status_t) switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on) @@ -629,29 +654,12 @@ SWITCH_DECLARE(switch_status_t) switch_threadattr_stacksize_set(switch_threadatt return apr_threadattr_stacksize_set(attr, stacksize); } -#ifndef WIN32 -struct apr_threadattr_t { - apr_pool_t *pool; - pthread_attr_t attr; -}; -#endif - -SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_increase(switch_threadattr_t *attr) +SWITCH_DECLARE(switch_status_t) switch_threadattr_priority_set(switch_threadattr_t *attr, switch_thread_priority_t priority) { - int stat = 0; #ifndef WIN32 - struct sched_param param; - struct apr_threadattr_t *myattr = attr; - - pthread_attr_getschedparam(&myattr->attr, ¶m); - param.sched_priority = 1; - stat = pthread_attr_setschedparam(&myattr->attr, ¶m); - - if (stat == 0) { - return SWITCH_STATUS_SUCCESS; - } + attr->priority = priority; #endif - return stat; + return SWITCH_STATUS_SUCCESS; } static char TT_KEY[] = "1"; @@ -1042,13 +1050,7 @@ SWITCH_DECLARE(unsigned int) switch_queue_size(switch_queue_t *queue) SWITCH_DECLARE(switch_status_t) switch_queue_pop(switch_queue_t *queue, void **data) { - apr_status_t s; - - do { - s = apr_queue_pop(queue, data); - } while (s == APR_EINTR); - - return s; + return apr_queue_pop(queue, data); } SWITCH_DECLARE(switch_status_t) switch_queue_pop_timeout(switch_queue_t *queue, void **data, switch_interval_time_t timeout) @@ -1070,14 +1072,7 @@ SWITCH_DECLARE(switch_status_t) switch_queue_push(switch_queue_t *queue, void *d SWITCH_DECLARE(switch_status_t) switch_queue_trypop(switch_queue_t *queue, void **data) { - apr_status_t s; - - do { - s = apr_queue_trypop(queue, data); - } while (s == APR_EINTR); - - return s; - + return apr_queue_trypop(queue, data); } SWITCH_DECLARE(switch_status_t) switch_queue_interrupt_all(switch_queue_t *queue) From b113330049766cf27219ebdf5f243e52e8fa0054 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 12:27:11 -0500 Subject: [PATCH 334/512] revert --- src/switch_apr.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/switch_apr.c b/src/switch_apr.c index aeb10185a9..d4db415280 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -1050,7 +1050,13 @@ SWITCH_DECLARE(unsigned int) switch_queue_size(switch_queue_t *queue) SWITCH_DECLARE(switch_status_t) switch_queue_pop(switch_queue_t *queue, void **data) { - return apr_queue_pop(queue, data); + apr_status_t s; + + do { + s = apr_queue_pop(queue, data); + } while (s == APR_EINTR); + + return s; } SWITCH_DECLARE(switch_status_t) switch_queue_pop_timeout(switch_queue_t *queue, void **data, switch_interval_time_t timeout) @@ -1072,7 +1078,14 @@ SWITCH_DECLARE(switch_status_t) switch_queue_push(switch_queue_t *queue, void *d SWITCH_DECLARE(switch_status_t) switch_queue_trypop(switch_queue_t *queue, void **data) { - return apr_queue_trypop(queue, data); + apr_status_t s; + + do { + s = apr_queue_trypop(queue, data); + } while (s == APR_EINTR); + + return s; + } SWITCH_DECLARE(switch_status_t) switch_queue_interrupt_all(switch_queue_t *queue) From e081f8ffc266f4c6bb5d37f23ae7575e24ee4449 Mon Sep 17 00:00:00 2001 From: William King Date: Thu, 1 Nov 2012 11:47:38 -0700 Subject: [PATCH 335/512] Improve handling of file error and closing conditions. Thanks to telapi.com for the patch. --- src/mod/formats/mod_vlc/mod_vlc.c | 45 ++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index d5b5ec336d..fb9c88b091 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -45,6 +45,7 @@ #include #include #include +#include #define VLC_BUFFER_SIZE 65536 @@ -83,6 +84,29 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vlc_shutdown); SWITCH_MODULE_LOAD_FUNCTION(mod_vlc_load); SWITCH_MODULE_DEFINITION(mod_vlc, mod_vlc_load, mod_vlc_shutdown, NULL); +static void vlc_mediaplayer_error_callback(const libvlc_event_t * event, void * data) +{ + vlc_file_context_t *context = (vlc_file_context_t *) data; + int status = libvlc_media_get_state(context->m); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a libvlc_MediaPlayerEncounteredError callback. mediaPlayer Status: %d\n", status); + if (status == libvlc_Error) { + context->err = 1; + switch_thread_cond_signal(context->started); + } +} +static void vlc_media_state_callback(const libvlc_event_t * event, void * data) +{ + vlc_file_context_t *context = (vlc_file_context_t *) data; + int new_state = event->u.media_state_changed.new_state; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a libvlc_MediaStateChanged callback. New state: %d\n", new_state); + if (new_state == libvlc_Ended || new_state == libvlc_Error) { + switch_thread_cond_signal(context->started); + } +} + + + void vlc_auto_play_callback(void *data, const void *samples, unsigned count, int64_t pts) { vlc_file_context_t *context = (vlc_file_context_t *) data; @@ -145,6 +169,7 @@ void vlc_imem_release_callback(void *data, const char *cookie, size_t size, void static switch_status_t vlc_file_open(switch_file_handle_t *handle, const char *path) { vlc_file_context_t *context; + libvlc_event_manager_t *mp_event_manager, *m_event_manager; context = switch_core_alloc(handle->memory_pool, sizeof(*context)); context->pool = handle->memory_pool; @@ -192,6 +217,12 @@ static switch_status_t vlc_file_open(switch_file_handle_t *handle, const char *p libvlc_audio_set_format(context->mp, "S16N", context->samplerate, 1); + m_event_manager = libvlc_media_event_manager(context->m); + libvlc_event_attach(m_event_manager, libvlc_MediaStateChanged, vlc_media_state_callback, (void *) context); + + mp_event_manager = libvlc_media_player_event_manager(context->mp); + libvlc_event_attach(mp_event_manager, libvlc_MediaPlayerEncounteredError, vlc_mediaplayer_error_callback, (void *) context); + libvlc_audio_set_callbacks(context->mp, vlc_auto_play_callback, NULL,NULL,NULL,NULL, (void *) context); libvlc_media_player_play(context->mp); @@ -258,21 +289,29 @@ static switch_status_t vlc_file_read(switch_file_handle_t *handle, void *data, s status = libvlc_media_get_state(context->m); - if (status == 7) { + if (status == libvlc_Error) { return SWITCH_STATUS_GENERR; } switch_mutex_lock(context->audio_mutex); - while (context->playing == 0) { + while (context->playing == 0 && status != libvlc_Ended && status != libvlc_Error) { switch_thread_cond_wait(context->started, context->audio_mutex); + status = libvlc_media_get_state(context->m); } + + if (context->err == 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "VLC error\n"); + return SWITCH_STATUS_FALSE; + } + switch_mutex_unlock(context->audio_mutex); switch_mutex_lock(context->audio_mutex); read = switch_buffer_read(context->audio_buffer, data, bytes); switch_mutex_unlock(context->audio_mutex); - if (!read && (status == 5 || status == 6)) { + status = libvlc_media_get_state(context->m); + if (!read && (status == libvlc_Stopped || status == libvlc_Ended || status == libvlc_Error)) { return SWITCH_STATUS_FALSE; } else if (!read) { read = 2; From b4502078cf2c75dac1720d45cbc147c261c81314 Mon Sep 17 00:00:00 2001 From: William King Date: Thu, 1 Nov 2012 11:50:15 -0700 Subject: [PATCH 336/512] Remove potential infinate loop when caller hung up before audio completed. Thanks to telapi.com for the patch --- src/mod/formats/mod_vlc/mod_vlc.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index fb9c88b091..4984601618 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -340,19 +340,29 @@ static switch_status_t vlc_file_write(switch_file_handle_t *handle, void *data, static switch_status_t vlc_file_close(switch_file_handle_t *handle) { vlc_file_context_t *context = handle->private_info; + int sanity = 0; context->playing = 0; /* The clients need to empty the last of the audio buffer */ while ( switch_buffer_inuse(context->audio_buffer) > 0 ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VLC waiting to close the files: %d \n", (int) switch_buffer_inuse(context->audio_buffer)); - sleep(1); + switch_yield(500000); + if (++sanity > 10) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Giving up waiting for client to empty the audio buffer\n"); + break; + } } /* Let the clients get the last of the audio stream */ + sanity = 0; while ( 3 == libvlc_media_get_state(context->m) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VLC waiting for clients: %d \n", libvlc_media_get_state(context->m)); - sleep(1); + switch_yield(500000); + if (++sanity > 10) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Giving up waiting for client to get the last of the audio stream\n"); + break; + } } if( context->mp ) From efcd5656fb28e5d5f6deefb48e26b0d270e56659 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 1 Nov 2012 15:00:28 -0500 Subject: [PATCH 337/512] FS-4743 --resolve --- src/mod/languages/mod_java/modjava.c | 50 +++++++++++++++++++--------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/mod/languages/mod_java/modjava.c b/src/mod/languages/mod_java/modjava.c index 98bf5f9ac8..428a9095be 100644 --- a/src/mod/languages/mod_java/modjava.c +++ b/src/mod/languages/mod_java/modjava.c @@ -38,7 +38,7 @@ static switch_memory_pool_t *memoryPool = NULL; static switch_dso_handle_t *javaVMHandle = NULL; JavaVM *javaVM = NULL; - +jclass launcherClass = NULL; SWITCH_MODULE_LOAD_FUNCTION(mod_java_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_java_shutdown); @@ -62,19 +62,16 @@ static vm_control_t vmControl; static void launch_java(switch_core_session_t *session, const char *data, JNIEnv *env) { - jclass Launcher = NULL; jmethodID launch = NULL; jstring uuid = NULL; jstring args = NULL; - Launcher = (*env)->FindClass(env, "org/freeswitch/Launcher"); - if (Launcher == NULL) + if (launcherClass == NULL) { - (*env)->ExceptionDescribe(env); goto done; } - launch = (*env)->GetStaticMethodID(env, Launcher, "launch", "(Ljava/lang/String;Ljava/lang/String;)V"); + launch = (*env)->GetStaticMethodID(env, launcherClass, "launch", "(Ljava/lang/String;Ljava/lang/String;)V"); if (launch == NULL) { (*env)->ExceptionDescribe(env); @@ -95,7 +92,7 @@ static void launch_java(switch_core_session_t *session, const char *data, JNIEnv goto done; } - (*env)->CallStaticVoidMethod(env, Launcher, launch, uuid, args); + (*env)->CallStaticVoidMethod(env, launcherClass, launch, uuid, args); if ((*env)->ExceptionOccurred(env)) (*env)->ExceptionDescribe(env); @@ -104,8 +101,6 @@ done: (*env)->DeleteLocalRef(env, args); if (uuid != NULL) (*env)->DeleteLocalRef(env, uuid); - if (Launcher != NULL) - (*env)->DeleteLocalRef(env, Launcher); } static switch_status_t exec_user_method(user_method_t * userMethod) { @@ -145,12 +140,14 @@ static switch_status_t exec_user_method(user_method_t * userMethod) { goto done; } - arg = (*env)->NewStringUTF(env, userMethod->arg); + if (userMethod->arg != NULL) { + arg = (*env)->NewStringUTF(env, userMethod->arg); - if (arg == NULL) { - (*env)->ExceptionDescribe(env); - status = SWITCH_STATUS_FALSE; - goto done; + if (arg == NULL) { + (*env)->ExceptionDescribe(env); + status = SWITCH_STATUS_FALSE; + goto done; + } } (*env)->CallStaticVoidMethod(env, class, method, arg); @@ -311,8 +308,31 @@ static switch_status_t create_java_vm(JavaVMOption *options, int optionCount, vm res = pJNI_CreateJavaVM(&javaVM, (void*) &env, &initArgs); if (res == JNI_OK) { + // call FindClass here already so that the Java VM executes the static + // initializer (@see org.freeswitch.Launcher) which loads the jni library + // so we can use jni functions right away (for example in the startup method) + launcherClass = (*env)->FindClass(env, "org/freeswitch/Launcher"); + if ( launcherClass == NULL ) + { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to find 'org.freeswitch.Launcher' class!\n"); + (*env)->ExceptionDescribe(env); + status = SWITCH_STATUS_FALSE; + } + + // store a global reference for use in the launch_java() function + launcherClass = (*env)->NewGlobalRef(env, launcherClass); + if ( launcherClass == NULL ) + { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory!\n"); + (*env)->ExceptionDescribe(env); + status = SWITCH_STATUS_FALSE; + } + else + { + status = SWITCH_STATUS_SUCCESS; + } + (*javaVM)->DetachCurrentThread(javaVM); - status = SWITCH_STATUS_SUCCESS; } else { From 43dfc703278f6dfbe99825f67151978396a6b6b1 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 1 Nov 2012 15:04:31 -0500 Subject: [PATCH 338/512] FS-4745 --resolve --- conf/vanilla/autoload_configs/java.conf.xml | 13 +- .../languages/mod_java/freeswitch_java.cpp | 179 ++++++++++++++++++ src/mod/languages/mod_java/freeswitch_java.h | 11 ++ src/mod/languages/mod_java/mod_java.i | 7 +- .../org/freeswitch/ApplicationLauncher.java | 15 ++ .../org/freeswitch/OriginateStateHandler.java | 22 +++ .../src/org/freeswitch/StateHandler.java | 54 ++++++ 7 files changed, 291 insertions(+), 10 deletions(-) create mode 100644 src/mod/languages/mod_java/src/org/freeswitch/ApplicationLauncher.java create mode 100644 src/mod/languages/mod_java/src/org/freeswitch/OriginateStateHandler.java create mode 100644 src/mod/languages/mod_java/src/org/freeswitch/StateHandler.java diff --git a/conf/vanilla/autoload_configs/java.conf.xml b/conf/vanilla/autoload_configs/java.conf.xml index 3d1a3b5e5b..5f71553e30 100644 --- a/conf/vanilla/autoload_configs/java.conf.xml +++ b/conf/vanilla/autoload_configs/java.conf.xml @@ -1,13 +1,8 @@ - - - + - - - - + diff --git a/src/mod/languages/mod_java/freeswitch_java.cpp b/src/mod/languages/mod_java/freeswitch_java.cpp index d8390b2ade..d8508e145c 100644 --- a/src/mod/languages/mod_java/freeswitch_java.cpp +++ b/src/mod/languages/mod_java/freeswitch_java.cpp @@ -1,5 +1,35 @@ #include "freeswitch_java.h" +jobject originate_state_handler; + +SWITCH_DECLARE(void) setOriginateStateHandler(jobject stateHandler) +{ + JNIEnv *env = NULL; + jint envStatus = javaVM->GetEnv((void**)&env, JNI_VERSION_1_4); + if ( envStatus != JNI_OK ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting JNIEnv!\n"); + return; + } + + if ( stateHandler != NULL && originate_state_handler != NULL ) { + const char* errorMessage = "Originate state handler is already registered"; + jclass exceptionClass = env->FindClass("java/util/TooManyListenersException"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, errorMessage); + env->ThrowNew(exceptionClass, errorMessage); + } else if ( stateHandler == NULL && originate_state_handler != NULL ) { + env->DeleteGlobalRef(originate_state_handler); + originate_state_handler = NULL; + } else { + originate_state_handler = env->NewGlobalRef(stateHandler); + if ( originate_state_handler == NULL ) { + const char* errorMessage = "Unable to create global reference for state handler"; + jclass exceptionClass = env->FindClass("java/lang/OutOfMemoryError"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, errorMessage); + env->ThrowNew(exceptionClass, errorMessage); + } + } +} + JavaSession::JavaSession() : CoreSession() { } @@ -328,3 +358,152 @@ done: return status; } +switch_status_t originate_handler_method(switch_core_session_t *session, const char* method) { + if ( originate_state_handler != NULL ) { + JNIEnv *env = NULL; + bool needDetach = false; + + jint envStatus = javaVM->GetEnv((void**)&env, JNI_VERSION_1_4); + if ( envStatus == JNI_EDETACHED ) { + envStatus = javaVM->AttachCurrentThread((void**)&env, NULL); + if ( envStatus == JNI_OK ) needDetach = true; + } + + if ( envStatus != JNI_OK ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting JNIEnv!\n"); + return SWITCH_STATUS_FALSE; + } + + jclass handlerClass = env->GetObjectClass(originate_state_handler); + if ( handlerClass == NULL ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting handler class!\n"); + if ( needDetach ) javaVM->DetachCurrentThread(); + return SWITCH_STATUS_FALSE; + } + + jint result = SWITCH_STATUS_FALSE; + jmethodID handlerMethod = env->GetMethodID(handlerClass, method, "(Ljava/lang/String;)I"); + if ( handlerMethod != NULL ) { + char *uuid = switch_core_session_get_uuid(session); + jstring javaUuid = env->NewStringUTF(uuid); + result = env->CallIntMethod(originate_state_handler, handlerMethod, javaUuid); + env->DeleteLocalRef(javaUuid); + } + + env->DeleteLocalRef(handlerClass); + if ( needDetach ) javaVM->DetachCurrentThread(); + return (switch_status_t)result; + } + + return SWITCH_STATUS_FALSE; +} + +switch_status_t originate_on_init(switch_core_session_t *session) { + return originate_handler_method(session, "onInit"); +} + +switch_status_t originate_on_routing(switch_core_session_t *session) { + return originate_handler_method(session, "onRouting"); +} + +switch_status_t originate_on_execute(switch_core_session_t *session) { + return originate_handler_method(session, "onExecute"); +} + +switch_status_t originate_on_hangup(switch_core_session_t *session) { + if ( originate_state_handler != NULL ) { + JNIEnv *env = NULL; + bool needDetach = false; + + jint envStatus = javaVM->GetEnv((void**)&env, JNI_VERSION_1_4); + if ( envStatus == JNI_EDETACHED ) { + envStatus = javaVM->AttachCurrentThread((void**)&env, NULL); + if ( envStatus == JNI_OK ) needDetach = true; + } + + if ( envStatus != JNI_OK ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting JNIEnv!\n"); + return SWITCH_STATUS_FALSE; + } + + jclass handlerClass = env->GetObjectClass(originate_state_handler); + if ( handlerClass == NULL ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error getting handler class!\n"); + if ( needDetach ) javaVM->DetachCurrentThread(); + return SWITCH_STATUS_FALSE; + } + + jint result = SWITCH_STATUS_FALSE; + jmethodID handlerMethod = env->GetMethodID(handlerClass, "onHangup", "(Ljava/lang/String;Ljava/lang/String;)I"); + if ( handlerMethod != NULL ) { + switch_channel_t *channel = switch_core_session_get_channel(session); + const char *uuid = switch_core_session_get_uuid(session); + const char *cause = switch_channel_cause2str(switch_channel_get_cause(channel)); + jstring javaUuid = env->NewStringUTF(uuid); + jstring javaCause = env->NewStringUTF(cause); + result = env->CallIntMethod(originate_state_handler, handlerMethod, javaUuid, javaCause); + env->DeleteLocalRef(javaUuid); + env->DeleteLocalRef(javaCause); + } + + env->DeleteLocalRef(handlerClass); + if ( needDetach ) javaVM->DetachCurrentThread(); + return (switch_status_t)result; + } + + return SWITCH_STATUS_FALSE; +} + +switch_status_t originate_on_exchange_media(switch_core_session_t *session) { + return originate_handler_method(session, "onExchangeMedia"); +} + +switch_status_t originate_on_soft_execute(switch_core_session_t *session) { + return originate_handler_method(session, "onSoftExecute"); +} + +switch_status_t originate_on_consume_media(switch_core_session_t *session) { + return originate_handler_method(session, "onConsumeMedia"); +} + +switch_status_t originate_on_hibernate(switch_core_session_t *session) { + return originate_handler_method(session, "onHibernate"); +} + +switch_status_t originate_on_reset(switch_core_session_t *session) { + return originate_handler_method(session, "onReset"); +} + +switch_status_t originate_on_park(switch_core_session_t *session) { + return originate_handler_method(session, "onPark"); +} + +switch_status_t originate_on_reporting(switch_core_session_t *session) { + return originate_handler_method(session, "onReporting"); +} + +switch_status_t originate_on_destroy(switch_core_session_t *session) { + return originate_handler_method(session, "onDestroy"); +} + +switch_state_handler_table_t originate_state_handlers = { + /*.on_init */ &originate_on_init, + /*.on_routing */ &originate_on_routing, + /*.on_execute */ &originate_on_execute, + /*.on_hangup */ &originate_on_hangup, + /*.on_exchange_media */ &originate_on_exchange_media, + /*.on_soft_execute */ &originate_on_soft_execute, + /*.on_consume_media */ &originate_on_consume_media, + /*.on_hibernate */ &originate_on_hibernate, + /*.on_reset */ &originate_on_reset, + /*.on_park */ &originate_on_park, + /*.on_reporting */ &originate_on_reporting, + /*.on_destroy */ &originate_on_destroy +}; + +int JavaSession::originate(JavaSession* aleg, char* destination, int timeout) { + switch_state_handler_table_t *stateHandlers = NULL; + if ( originate_state_handler != NULL ) stateHandlers = &originate_state_handlers; + return CoreSession::originate(aleg, destination, timeout, stateHandlers); +} + diff --git a/src/mod/languages/mod_java/freeswitch_java.h b/src/mod/languages/mod_java/freeswitch_java.h index e87b5928f0..5d6d138168 100644 --- a/src/mod/languages/mod_java/freeswitch_java.h +++ b/src/mod/languages/mod_java/freeswitch_java.h @@ -6,6 +6,16 @@ extern JavaVM *javaVM; +#ifdef __cplusplus +extern "C" { +#endif + +SWITCH_DECLARE(void) setOriginateStateHandler(jobject stateHandler); + +#ifdef __cplusplus +} +#endif + class JavaSession:public CoreSession { public: JavaSession(); @@ -19,6 +29,7 @@ class JavaSession:public CoreSession { void setHangupHook(jobject hangupHook); virtual void check_hangup_hook(); virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype); + int originate(JavaSession* aleg, char* destination, int timeout); }; #endif diff --git a/src/mod/languages/mod_java/mod_java.i b/src/mod/languages/mod_java/mod_java.i index 42527fd541..858dac8d08 100644 --- a/src/mod/languages/mod_java/mod_java.i +++ b/src/mod/languages/mod_java/mod_java.i @@ -2,6 +2,7 @@ %include ../../../../swig_common.i /** insert the following includes into generated code so it compiles */ %{ +#include "switch.h" #include "switch_cpp.h" #include "freeswitch_java.h" %} @@ -53,7 +54,11 @@ %typemap(javain) char *terminator "$javainput" %typemap(freearg) char *terminator "" - +#define SWITCH_DECLARE(type) type +%javamethodmodifiers CoreSession::originate(CoreSession *, char *, int, switch_state_handler_table_t *) "protected"; +%javaexception ("java.util.TooManyListenersException") setOriginateStateHandler(jobject); +%typemap(jtype) jobject stateHandler "org.freeswitch.StateHandler" +%typemap(jstype) jobject stateHandler "org.freeswitch.StateHandler" %include "enums.swg" %include switch_swigable_cpp.h diff --git a/src/mod/languages/mod_java/src/org/freeswitch/ApplicationLauncher.java b/src/mod/languages/mod_java/src/org/freeswitch/ApplicationLauncher.java new file mode 100644 index 0000000000..0e7ad0abe0 --- /dev/null +++ b/src/mod/languages/mod_java/src/org/freeswitch/ApplicationLauncher.java @@ -0,0 +1,15 @@ +package org.freeswitch.example; + +import org.freeswitch.swig.freeswitch; + +public class ApplicationLauncher { + + public static final void startup(String arg) { + try { + freeswitch.setOriginateStateHandler(OriginateStateHandler.getInstance()); + } catch (Exception e) { + freeswitch.console_log("err", "Error registering originate state handler"); + } + } + +} diff --git a/src/mod/languages/mod_java/src/org/freeswitch/OriginateStateHandler.java b/src/mod/languages/mod_java/src/org/freeswitch/OriginateStateHandler.java new file mode 100644 index 0000000000..dd59515828 --- /dev/null +++ b/src/mod/languages/mod_java/src/org/freeswitch/OriginateStateHandler.java @@ -0,0 +1,22 @@ +package org.freeswitch.example; + +import org.freeswitch.StateHandler.OnHangupHandler; + +public class OriginateStateHandler implements OnHangupHandler { + + private static OriginateStateHandler instance = null; + + public static final OriginateStateHandler getInstance() { + if ( instance == null ) instance = new OriginateStateHandler(); + return instance; + } + + private OriginateStateHandler() { + // hide constructor + } + + public int onHangup(String uuid, String cause) { + return 1; // SWITCH_STATUS_FALSE + } + +} \ No newline at end of file diff --git a/src/mod/languages/mod_java/src/org/freeswitch/StateHandler.java b/src/mod/languages/mod_java/src/org/freeswitch/StateHandler.java new file mode 100644 index 0000000000..b5f9ba2648 --- /dev/null +++ b/src/mod/languages/mod_java/src/org/freeswitch/StateHandler.java @@ -0,0 +1,54 @@ +package org.freeswitch; + +public interface StateHandler { + + public interface OnInitHandler extends StateHandler { + public int onInit(String uuid); + } + + public static interface OnRoutingHandler extends StateHandler { + public int onRouting(String uuid); + } + + public static interface OnExecuteHandler extends StateHandler { + public int onExecute(String uuid); + } + + public static interface OnHangupHandler extends StateHandler { + public int onHangup(String uuid, String cause); + } + + public static interface OnExchangeMediaHandler extends StateHandler { + public int onExchangeMedia(String uuid); + } + + public static interface OnSoftExecuteHandler extends StateHandler { + public int onSoftExecute(String uuid); + } + + public static interface OnConsumeMediaHandler extends StateHandler { + public int onConsumeMedia(String uuid); + } + + public static interface OnHibernateHandler extends StateHandler { + public int onHibernate(String uuid); + } + + public static interface OnResetHandler extends StateHandler { + public int onReset(String uuid); + } + + public static interface OnParkHandler extends StateHandler { + public int onPark(String uuid); + } + + public static interface OnReportingHandler extends StateHandler { + public int onReporting(String uuid); + } + + public static interface OnDestroyHandler extends StateHandler { + public int onDestroy(String uuid); + } + +} + From 94763ea52bd87f937c9437671b3b51ad565ef421 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 13:07:42 -0500 Subject: [PATCH 339/512] FS-4681 --resolve --- src/include/switch_core.h | 10 +++++++++- .../mod_conference/mod_conference.c | 19 ++++++++++++++----- src/switch_core_session.c | 19 +++++++++++++------ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index bc8b403961..ead85fdf4a 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -825,14 +825,22 @@ SWITCH_DECLARE(void) switch_core_dump_variables(_In_ switch_stream_handle_t *str */ SWITCH_DECLARE(void) switch_core_session_hupall(_In_ switch_call_cause_t cause); +typedef enum { + SHT_NONE = 0, + SHT_UNANSWERED = (1 << 0), + SHT_ANSWERED = (1 << 1) +} switch_hup_type_t; + /*! \brief Hangup all sessions which match a specific channel variable \param var_name The variable name to look for \param var_val The value to look for \param cause the hangup cause to apply to the hungup channels */ -SWITCH_DECLARE(void) switch_core_session_hupall_matching_var(_In_ const char *var_name, _In_ const char *var_val, _In_ switch_call_cause_t cause); +SWITCH_DECLARE(uint32_t) switch_core_session_hupall_matching_var_ans(_In_ const char *var_name, _In_ const char *var_val, _In_ + switch_call_cause_t cause, switch_hup_type_t type); SWITCH_DECLARE(switch_console_callback_match_t *) switch_core_session_findall_matching_var(const char *var_name, const char *var_val); +#define switch_core_session_hupall_matching_var(_vn, _vv, _c) switch_core_session_hupall_matching_var_ans(_vn, _vv, _c, SHT_UNANSWERED | SHT_ANSWERED) /*! \brief Hangup all sessions that belong to an endpoint diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 57e0636647..d5ea7e702a 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -8539,11 +8539,13 @@ static void conference_send_presence(conference_obj_t *conference) } } - -static void kickall_matching_var(conference_obj_t *conference, const char *var, const char *val) +#if 0 +static uint32_t kickall_matching_var(conference_obj_t *conference, const char *var, const char *val) { conference_member_t *member = NULL; const char *vval = NULL; + uint32_t r = 0; + switch_mutex_lock(conference->mutex); switch_mutex_lock(conference->member_mutex); @@ -8560,14 +8562,18 @@ static void kickall_matching_var(conference_obj_t *conference, const char *var, if (vval && !strcmp(vval, val)) { switch_set_flag_locked(member, MFLAG_KICKED); switch_clear_flag_locked(member, MFLAG_RUNNING); - switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK); + switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK); + r++; } } switch_mutex_unlock(conference->member_mutex); switch_mutex_unlock(conference->mutex); + + return r; } +#endif static void call_setup_event_handler(switch_event_t *event) { @@ -8631,8 +8637,11 @@ static void call_setup_event_handler(switch_event_t *event) } } else if (!strcasecmp(action, "end")) { - //switch_core_session_hupall_matching_var("conference_call_key", key, SWITCH_CAUSE_NORMAL_CLEARING); - kickall_matching_var(conference, "conference_call_key", key); + if (switch_core_session_hupall_matching_var("conference_call_key", key, SWITCH_CAUSE_NORMAL_CLEARING)) { + send_conference_notify(conference, "SIP/2.0 200 OK\r\n", call_id, SWITCH_TRUE); + } else { + send_conference_notify(conference, "SIP/2.0 481 Failure\r\n", call_id, SWITCH_TRUE); + } status = SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 4148267da6..cf7daaac16 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -204,18 +204,20 @@ struct str_node { struct str_node *next; }; -SWITCH_DECLARE(void) switch_core_session_hupall_matching_var(const char *var_name, const char *var_val, switch_call_cause_t cause) +SWITCH_DECLARE(uint32_t) switch_core_session_hupall_matching_var_ans(const char *var_name, const char *var_val, switch_call_cause_t cause, + switch_hup_type_t type) { switch_hash_index_t *hi; void *val; switch_core_session_t *session; switch_memory_pool_t *pool; struct str_node *head = NULL, *np; + uint32_t r = 0; switch_core_new_memory_pool(&pool); if (!var_val) - return; + return r; switch_mutex_lock(runtime.session_hash_mutex); for (hi = switch_hash_first(NULL, session_manager.session_table); hi; hi = switch_hash_next(hi)) { @@ -223,10 +225,13 @@ SWITCH_DECLARE(void) switch_core_session_hupall_matching_var(const char *var_nam if (val) { session = (switch_core_session_t *) val; if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) { - np = switch_core_alloc(pool, sizeof(*np)); - np->str = switch_core_strdup(pool, session->uuid_str); - np->next = head; - head = np; + int ans = switch_channel_test_flag(switch_core_session_get_channel(session), CF_ANSWERED); + if ((ans && (type & SHT_ANSWERED)) || (!ans && (type & SHT_UNANSWERED))) { + np = switch_core_alloc(pool, sizeof(*np)); + np->str = switch_core_strdup(pool, session->uuid_str); + np->next = head; + head = np; + } switch_core_session_rwunlock(session); } } @@ -239,6 +244,7 @@ SWITCH_DECLARE(void) switch_core_session_hupall_matching_var(const char *var_nam if (switch_channel_up_nosig(session->channel) && (this_val = switch_channel_get_variable(session->channel, var_name)) && (!strcmp(this_val, var_val))) { switch_channel_hangup(session->channel, cause); + r++; } switch_core_session_rwunlock(session); } @@ -246,6 +252,7 @@ SWITCH_DECLARE(void) switch_core_session_hupall_matching_var(const char *var_nam switch_core_destroy_memory_pool(&pool); + return r; } From 87b796c85720be6c13c39ea9a5a44eb20968d7cc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 16:29:53 -0400 Subject: [PATCH 340/512] FS-4776 forgot to push this --- src/mod/endpoints/mod_dingaling/mod_dingaling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 679a4d6588..f8f233aa87 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -4186,7 +4186,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi tech_pvt->them = switch_core_session_strdup(session, ldl_session_get_callee(dlsession)); tech_pvt->us = switch_core_session_strdup(session, ldl_session_get_caller(dlsession)); - if ((tmp = strdup(tech_pvt->us))) { + if (tech_pvt->us && (tmp = strdup(tech_pvt->us))) { char *p, *q; if ((p = strchr(tmp, '@'))) { From 5bc9fa8a666ac1474a410031ad452b595b29e25e Mon Sep 17 00:00:00 2001 From: William King Date: Thu, 1 Nov 2012 13:30:22 -0700 Subject: [PATCH 341/512] More accurate and detailed sample configuration file. --- .../mod_xml_radius/xml_radius.conf.xml | 70 +++++++++++-------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml b/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml index 6349d05210..16e5df5fb6 100644 --- a/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml +++ b/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml @@ -74,9 +74,12 @@ - + + + - + + @@ -103,21 +106,27 @@ - - - - - - - - + + + + + + + + + + + + + - + + + + + + @@ -129,25 +138,30 @@ - - - + + + + + + + + + + + - - - - - + + - + + + + + From 3c249b012e27359914afc8ae62c1daba26346e7d Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Thu, 1 Nov 2012 22:39:06 +0000 Subject: [PATCH 342/512] FS-4003 --resolve add IPv6 support to ESL client library, thanks to Steven Ayre --- libs/esl/src/esl.c | 35 +++++++++++++++++++++++------------ libs/esl/src/include/esl.h | 2 +- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index b092991988..3972e7a7b4 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -916,6 +916,8 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char * int rval = 0; const char *hval; struct addrinfo hints = { 0 }, *result; + struct sockaddr_in *sockaddr_in; + struct sockaddr_in6 *sockaddr_in6; #ifndef WIN32 int fd_flags = 0; #else @@ -936,27 +938,36 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char * if (!handle->packet_buf) { esl_buffer_create(&handle->packet_buf, BUF_CHUNK, BUF_START, 0); } - - handle->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - - if (handle->sock == ESL_SOCK_INVALID) { - snprintf(handle->err, sizeof(handle->err), "Socket Error"); - return ESL_FAIL; - } - - hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; - + if (getaddrinfo(host, NULL, &hints, &result)) { strncpy(handle->err, "Cannot resolve host", sizeof(handle->err)); goto fail; } memcpy(&handle->sockaddr, result->ai_addr, sizeof(handle->sockaddr)); - handle->sockaddr.sin_family = AF_INET; - handle->sockaddr.sin_port = htons(port); + switch(handle->sockaddr.ss_family) { + case AF_INET: + sockaddr_in = (struct sockaddr_in*)&(handle->sockaddr); + sockaddr_in->sin_port = htons(port); + break; + case AF_INET6: + sockaddr_in6 = (struct sockaddr_in6*)&(handle->sockaddr); + sockaddr_in6->sin6_port = htons(port); + break; + default: + strncpy(handle->err, "Host resolves to unsupported address family", sizeof(handle->err)); + goto fail; + } freeaddrinfo(result); + + handle->sock = socket(handle->sockaddr.ss_family, SOCK_STREAM, IPPROTO_TCP); + + if (handle->sock == ESL_SOCK_INVALID) { + snprintf(handle->err, sizeof(handle->err), "Socket Error"); + return ESL_FAIL; + } if (timeout) { #ifdef WIN32 diff --git a/libs/esl/src/include/esl.h b/libs/esl/src/include/esl.h index 5e66fe437a..09e129ab78 100644 --- a/libs/esl/src/include/esl.h +++ b/libs/esl/src/include/esl.h @@ -288,7 +288,7 @@ typedef enum { /*! \brief A handle that will hold the socket information and different events received. */ typedef struct { - struct sockaddr_in sockaddr; + struct sockaddr_storage sockaddr; struct hostent hostent; char hostbuf[256]; esl_socket_t sock; From 0a0f5951ab616d5b136e79b7d4ad253510f9d0cc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 1 Nov 2012 15:50:41 -0500 Subject: [PATCH 343/512] check in page app --- .../applications/mod_dptools/mod_dptools.c | 449 ++++++++++++++++++ 1 file changed, 449 insertions(+) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 5e6a732841..6f8084648a 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4967,6 +4967,453 @@ SWITCH_STANDARD_APP(mutex_function) /* /// mutex /// */ +typedef struct page_data_s { + uint32_t *counter; + const char *dial_str; + const char *dp; + const char *context; + const char *exten; + const char *path; + switch_event_t *var_event; + switch_memory_pool_t *pool; + switch_mutex_t *mutex; +} page_data_t; + +static switch_status_t page_hanguphook(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_channel_state_t state = switch_channel_get_state(channel); + + if (state == CS_HANGUP) { + page_data_t *pd; + + if ((pd = (page_data_t *) switch_channel_get_private(channel, "__PAGE_DATA"))) { + uint32_t *counter = pd->counter; + + switch_mutex_lock(pd->mutex); + (*counter)--; + switch_mutex_unlock(pd->mutex); + + + } + + switch_core_event_hook_remove_state_change(session, page_hanguphook); + } + + return SWITCH_STATUS_SUCCESS; +} + +void *SWITCH_THREAD_FUNC page_thread(switch_thread_t *thread, void *obj) +{ + page_data_t *mypd, *pd = (page_data_t *) obj; + switch_core_session_t *session; + switch_call_cause_t cause = SWITCH_CAUSE_NONE; + uint32_t *counter = pd->counter; + switch_memory_pool_t *pool = pd->pool; + + + if (switch_ivr_originate(NULL, &session, &cause, pd->dial_str, 60, NULL, NULL, NULL, NULL, pd->var_event, SOF_NONE, NULL) == SWITCH_STATUS_SUCCESS) { + switch_channel_t *channel = switch_core_session_get_channel(session); + + switch_channel_set_variable(channel, "page_file", pd->path); + + mypd = switch_core_session_alloc(session, sizeof(*mypd)); + mypd->counter = pd->counter; + mypd->mutex = pd->mutex; + switch_core_event_hook_add_state_change(session, page_hanguphook); + switch_channel_set_private(channel, "__PAGE_DATA", mypd); + switch_ivr_session_transfer(session, pd->exten, pd->dp, pd->context); + switch_core_session_rwunlock(session); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "originate failed: %s [%s]\n", switch_channel_cause2str(cause), pd->dial_str); + switch_mutex_lock(pd->mutex); + (*counter)--; + switch_mutex_unlock(pd->mutex); + } + + switch_event_safe_destroy(&pd->var_event); + + if (pool) { + switch_core_destroy_memory_pool(&pool); + } + + return NULL; +} + +static void launch_call(const char *dial_str, + const char *path, const char *exten, const char *context, const char *dp, + switch_mutex_t *mutex, uint32_t *counter, switch_event_t **var_event) +{ + switch_thread_data_t *td; + switch_memory_pool_t *pool; + page_data_t *pd; + + switch_core_new_memory_pool(&pool); + + pd = switch_core_alloc(pool, sizeof(*pd)); + pd->pool = pool; + pd->exten = switch_core_strdup(pool, exten); + pd->context = switch_core_strdup(pool, context); + pd->dp = switch_core_strdup(pool, dp); + pd->dial_str = switch_core_strdup(pool, dial_str); + pd->path = switch_core_strdup(pool, path); + pd->mutex = mutex; + + if (var_event && *var_event) { + switch_event_dup(&pd->var_event, *var_event); + switch_event_destroy(var_event); + } + + switch_mutex_lock(pd->mutex); + (*counter)++; + switch_mutex_unlock(pd->mutex); + + pd->counter = counter; + + td = switch_core_alloc(pool, sizeof(*td)); + td->func = page_thread; + td->obj = pd; + + switch_thread_pool_launch_thread(&td); + +} + +typedef struct call_monitor_s { + switch_memory_pool_t *pool; + const char *path; + char *data; + const char *context; + const char *exten; + const char *dp; + uint32_t chunk_size; + int nuke; +} call_monitor_t; + + + +void *SWITCH_THREAD_FUNC call_monitor_thread(switch_thread_t *thread, void *obj) +{ + call_monitor_t *cm = (call_monitor_t *) obj; + uint32_t sent = 0; + switch_mutex_t *mutex; + uint32_t counter = 0; + switch_memory_pool_t *pool = cm->pool; + int size; + char *argv[512] = { 0 }; + int busy = 0; + switch_event_t *var_event = NULL; + char *data; + + switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, cm->pool); + + if (switch_file_exists(cm->path, cm->pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File %s does not exist!\n", cm->path); + goto end; + } + + data = cm->data; + + while (data && *data && *data == ' ') { + data++; + } + + while (*data == '<') { + char *parsed = NULL; + + if (switch_event_create_brackets(data, '<', '>', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + goto end; + } + + data = parsed; + } + + while (data && *data && *data == ' ') { + data++; + } + + if (!(size = switch_separate_string_string(data, SWITCH_ENT_ORIGINATE_DELIM, argv, (sizeof(argv) / sizeof(argv[0]))))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channels specified.\n"); + goto end; + } + + + if (cm->chunk_size > size) { + cm->chunk_size = size; + } + + while (sent < size) { + do { + switch_mutex_lock(mutex); + busy = (counter >= cm->chunk_size); + switch_mutex_unlock(mutex); + + if (busy) { + switch_yield(100000); + } + + } while (busy); + + printf("%ld ASS LAUNCH %s %d %d\n", (long)pthread_self(), argv[sent], sent, size); + + launch_call(argv[sent++], cm->path, cm->exten, cm->context, cm->dp, mutex, &counter, &var_event); + } + + + end: + + while(counter) { + switch_mutex_lock(mutex); + switch_mutex_unlock(mutex); + switch_yield(100000); + } + + if (cm->nuke && !zstr(cm->path)) { + unlink(cm->path); + } + + if (pool) { + switch_core_destroy_memory_pool(&pool); + } + + return NULL; +} + +static void launch_call_monitor(const char *path, int del, const char *data, uint32_t chunk_size, const char *exten, const char *context, const char *dp) +{ + switch_thread_data_t *td; + switch_memory_pool_t *pool; + call_monitor_t *cm; + + switch_core_new_memory_pool(&pool); + + cm = switch_core_alloc(pool, sizeof(*cm)); + + if (del) { + cm->nuke = 1; + } + + cm->pool = pool; + cm->path = switch_core_strdup(pool, path); + cm->data = switch_core_strdup(pool, data); + cm->exten = switch_core_strdup(pool, exten); + cm->context = switch_core_strdup(pool, context); + cm->dp = switch_core_strdup(pool, dp); + cm->chunk_size = chunk_size; + + td = switch_core_alloc(pool, sizeof(*td)); + td->func = call_monitor_thread; + td->obj = cm; + + switch_thread_pool_launch_thread(&td); + +} + + +#define PAGE_SYNTAX "[:_:]" +SWITCH_STANDARD_APP(page_function) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + uint32_t limit = 0; + const char *path = NULL; + switch_input_args_t args = { 0 }; + switch_file_handle_t fh = { 0 }; + uint32_t chunk_size = 10; + const char *l = NULL; + const char *tmp; + int del = 0, rate; + const char *exten; + const char *context = NULL; + const char *dp = "inline"; + const char *pdata = data; + + if (zstr(pdata)) { + pdata = switch_channel_get_variable(channel, "page_data"); + } + + if (zstr(pdata)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No channels specified.\n"); + return; + } + + + exten = switch_channel_get_variable(channel, "page_exten"); + context = switch_channel_get_variable(channel, "page_context"); + + if ((l = switch_channel_get_variable(channel, "page_dp"))) { + dp = l; + } + + + l = switch_channel_get_variable(channel, "page_record_limit"); + + if (l) { + if (*l == '+') { + l++; + } + if (l) { + limit = switch_atoui(l); + } + } + + if ((l = switch_channel_get_variable(channel, "page_record_thresh"))) { + fh.thresh = switch_atoui(l); + } + + if ((l = switch_channel_get_variable(channel, "page_chunk_size"))) { + uint32_t tmp = switch_atoui(l); + + if (tmp > 0) { + chunk_size = tmp; + } + } + + if ((l = switch_channel_get_variable(channel, "page_record_silence_hits"))) { + fh.silence_hits = switch_atoui(l); + } + + if ((tmp = switch_channel_get_variable(channel, "record_rate"))) { + rate = atoi(tmp); + if (rate > 0) { + fh.samplerate = rate; + } + } + + args.input_callback = on_dtmf; + + switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, ""); + + + if (!(path = switch_channel_get_variable(channel, "page_path"))) { + const char *beep; + + path = switch_core_session_sprintf(session, "%s%s%s.wav", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session)); + del = 1; + + if (!(beep = switch_channel_get_variable(channel, "page_beep"))) { + beep = "tone_stream://%(500,0, 620)"; + } + + switch_ivr_play_file(session, NULL, beep, NULL); + + + switch_ivr_record_file(session, &fh, path, &args, limit); + } + + if (zstr(exten)) { + exten = switch_core_session_sprintf(session, "playback:%s", path); + } + + if (switch_file_exists(path, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { + launch_call_monitor(path, del, pdata, chunk_size, exten, context, dp); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "File %s does not exist\n", path); + } + +} + + +SWITCH_STANDARD_API(page_api_function) +{ + char *odata = NULL, *data = NULL; + switch_event_t *var_event = NULL; + const char *exten; + char *oexten = NULL; + const char *context = NULL; + const char *dp = "inline"; + const char *pdata = data; + const char *l; + uint32_t chunk_size = 10; + const char *path; + + + if (zstr(cmd)) { + stream->write_function(stream, "-ERR no data"); + goto end; + } + + odata = strdup(cmd); + data = odata; + + while (data && *data && *data == ' ') { + data++; + } + + while (*data == '(') { + char *parsed = NULL; + + if (switch_event_create_brackets(data, '(', ')', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + goto end; + } + + data = parsed; + } + + while (data && *data && *data == ' ') { + data++; + } + + if (!var_event) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + goto end; + } + + pdata = data; + + if (zstr(pdata)) { + pdata = switch_event_get_header(var_event, "page_data"); + } + + if (zstr(pdata)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channels specified.\n"); + goto end; + } + + + exten = switch_event_get_header(var_event, "page_exten"); + context = switch_event_get_header(var_event, "page_context"); + + if ((l = switch_event_get_header(var_event, "page_dp"))) { + dp = l; + } + + + if ((l = switch_event_get_header(var_event, "page_chunk_size"))) { + uint32_t tmp = switch_atoui(l); + + if (tmp > 0) { + chunk_size = tmp; + } + } + + if (!(path = switch_event_get_header(var_event, "page_path"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No file specified.\n"); + goto end; + } + + if (zstr(exten)) { + oexten = switch_mprintf("playback:%s", path); + exten = oexten; + } + + if (switch_file_exists(path, NULL) == SWITCH_STATUS_SUCCESS) { + launch_call_monitor(path, 0, pdata, chunk_size, exten, context, dp); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File %s does not exist\n", path); + } + + + end: + + + switch_safe_free(odata); + switch_safe_free(oexten); + + return SWITCH_STATUS_SUCCESS; +} + + #define SPEAK_DESC "Speak text to a channel via the tts interface" #define DISPLACE_DESC "Displace audio from a file to the channels input" @@ -5044,6 +5491,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_CHAT(chat_interface, "api", api_chat_send); SWITCH_ADD_API(api_interface, "strepoch", "Convert a date string into epoch time", strepoch_api_function, ""); + SWITCH_ADD_API(api_interface, "page", "Send a file as a page", page_api_function, "(var1=val1,var2=val2)[:_:]"); SWITCH_ADD_API(api_interface, "strmicroepoch", "Convert a date string into micoepoch time", strmicroepoch_api_function, ""); SWITCH_ADD_API(api_interface, "chat", "chat", chat_api_function, "||||[]"); SWITCH_ADD_API(api_interface, "strftime", "strftime", strftime_api_function, ""); @@ -5073,6 +5521,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "hold", "Send a hold message", "Send a hold message", hold_function, HOLD_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "unhold", "Send a un-hold message", "Send a un-hold message", unhold_function, UNHOLD_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "mutex", "block on a call flow only allowing one at a time", "", mutex_function, MUTEX_SYNTAX, SAF_NONE); + SWITCH_ADD_APP(app_interface, "page", "", "", page_function, PAGE_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, " [ ]", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function, From ccb3f7fd2b47ff52a8b080e9d6a535440db31293 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 1 Nov 2012 18:09:25 -0500 Subject: [PATCH 344/512] FS-4785 --resolve --- src/mod/codecs/mod_opus/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/codecs/mod_opus/Makefile b/src/mod/codecs/mod_opus/Makefile index c57e047461..aefffbd061 100644 --- a/src/mod/codecs/mod_opus/Makefile +++ b/src/mod/codecs/mod_opus/Makefile @@ -5,10 +5,11 @@ OPUS=opus-1.0.1 OPUS_DIR=$(switch_srcdir)/libs/$(OPUS) OPUS_BUILDDIR=$(switch_builddir)/libs/$(OPUS) LOCAL_CFLAGS=-I$(OPUS_DIR)/include -g -O2 +LOCAL_LDFLAGS=-lm -lz OPUS_LA=$(OPUS_BUILDDIR)/.libs/libopus.la -LOCAL_LIBADD=$(OPUS_LA) -lm -lz +LOCAL_LIBADD=$(OPUS_LA) include $(BASE)/build/modmake.rules From 98bbb9affe0a1d9fe163c964a3c1c4fa392ca937 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 1 Nov 2012 21:59:18 -0500 Subject: [PATCH 345/512] mostly trivial windows fixes for last several commits - anthm pthread_self in mod_dptools is not in scope for windows? commented out. --- libs/stfu/stfu.c | 9 ++++++- libs/stfu/stfu.h | 2 +- .../applications/mod_dptools/mod_dptools.c | 2 +- src/mod/codecs/mod_silk/mod_silk.c | 7 ++++- .../mod_managed/freeswitch_wrap.2010.cxx | 10 +++++-- .../mod_managed/managed/swig.2010.cs | 26 ++++++++++++++++--- w32/Library/FreeSwitchCore.2008.vcproj | 12 ++++----- w32/Library/FreeSwitchCore.2010.vcxproj | 10 +++---- 8 files changed, 57 insertions(+), 21 deletions(-) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index f02219cd9e..a2f9760da9 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -806,15 +806,22 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) return rframe; } -int32_t stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame) +STFU_DECLARE(int32_t) stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame) { uint32_t i = 0, j = 0; +#ifdef WIN32 +#pragma warning (disable:4204) +#endif stfu_queue_t *queues[] = { jb->out_queue, jb->in_queue, jb->old_queue}; +#ifdef WIN32 +#pragma warning (default:4204) +#endif stfu_queue_t *queue = NULL; stfu_frame_t *frame = NULL; uint32_t target_ts = 0; + seq = seq; if (!next_frame) return 0; target_ts = timestamp + (distance - 1) * jb->samples_per_packet; diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index bc3dd519ba..e1a0d439a3 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -191,7 +191,7 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_ 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, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last); stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i); -int32_t stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame); +STFU_DECLARE(int32_t) stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame); 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); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 6f8084648a..d274198ecd 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -5154,7 +5154,7 @@ void *SWITCH_THREAD_FUNC call_monitor_thread(switch_thread_t *thread, void *obj) } while (busy); - printf("%ld ASS LAUNCH %s %d %d\n", (long)pthread_self(), argv[sent], sent, size); + /* printf("%ld ASS LAUNCH %s %d %d\n", (long)pthread_self(), argv[sent], sent, size); */ launch_call(argv[sent++], cm->path, cm->exten, cm->context, cm->dp, mutex, &counter, &var_event); } diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index 922c86d06b..bb0eeaa7fd 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -31,7 +31,11 @@ */ #include "switch.h" +#ifndef WIN32 #include "stfu.h" +#else +#include "../../../libs/stfu/stfu.h" +#endif #include "SKP_Silk_SDK_API.h" SWITCH_MODULE_LOAD_FUNCTION(mod_silk_load); @@ -331,6 +335,7 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, SKP_int16 reclen; int32_t found_frame; switch_bool_t did_lbrr = SWITCH_FALSE; + int i; *decoded_data_len = 0; @@ -339,7 +344,7 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO); } if (jb && codec && codec->cur_frame) { - for (int i = 1; i <= MAX_LBRR_DELAY; i++) { + for (i = 1; i <= MAX_LBRR_DELAY; i++) { found_frame = stfu_n_copy_next_frame(jb, codec->cur_frame->timestamp, codec->cur_frame->seq, i, &next_frame); if (found_frame) { SKP_Silk_SDK_search_for_LBRR(next_frame.data, next_frame.dlen, i, (SKP_uint8*) &recbuff, &reclen); diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 8d09ec6b03..d37e098099 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -8269,15 +8269,21 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall(int jarg1) { } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall_matching_var(char * jarg1, char * jarg2, int jarg3) { +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_session_hupall_matching_var_ans(char * jarg1, char * jarg2, int jarg3, int jarg4) { + unsigned long jresult ; char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; switch_call_cause_t arg3 ; + switch_hup_type_t arg4 ; + uint32_t result; arg1 = (char *)jarg1; arg2 = (char *)jarg2; arg3 = (switch_call_cause_t)jarg3; - switch_core_session_hupall_matching_var((char const *)arg1,(char const *)arg2,arg3); + arg4 = (switch_hup_type_t)jarg4; + result = (uint32_t)switch_core_session_hupall_matching_var_ans((char const *)arg1,(char const *)arg2,arg3,arg4); + jresult = (unsigned long)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 25a99cdf69..24aac8ed9e 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -1606,8 +1606,9 @@ public class freeswitch { freeswitchPINVOKE.switch_core_session_hupall((int)cause); } - public static void switch_core_session_hupall_matching_var(string var_name, string var_val, switch_call_cause_t cause) { - freeswitchPINVOKE.switch_core_session_hupall_matching_var(var_name, var_val, (int)cause); + public static uint switch_core_session_hupall_matching_var_ans(string var_name, string var_val, switch_call_cause_t cause, switch_hup_type_t type) { + uint ret = freeswitchPINVOKE.switch_core_session_hupall_matching_var_ans(var_name, var_val, (int)cause, (int)type); + return ret; } public static switch_console_callback_match switch_core_session_findall_matching_var(string var_name, string var_val) { @@ -8694,8 +8695,8 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall")] public static extern void switch_core_session_hupall(int jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_matching_var")] - public static extern void switch_core_session_hupall_matching_var(string jarg1, string jarg2, int jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_matching_var_ans")] + public static extern uint switch_core_session_hupall_matching_var_ans(string jarg1, string jarg2, int jarg3, int jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_findall_matching_var")] public static extern IntPtr switch_core_session_findall_matching_var(string jarg1, string jarg2); @@ -28851,6 +28852,23 @@ public class switch_hold_record_t : IDisposable { namespace FreeSWITCH.Native { +public enum switch_hup_type_t { + SHT_NONE = 0, + SHT_UNANSWERED = (1 << 0), + SHT_ANSWERED = (1 << 1) +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + using System; using System.Runtime.InteropServices; diff --git a/w32/Library/FreeSwitchCore.2008.vcproj b/w32/Library/FreeSwitchCore.2008.vcproj index 624e125542..16635f2b93 100644 --- a/w32/Library/FreeSwitchCore.2008.vcproj +++ b/w32/Library/FreeSwitchCore.2008.vcproj @@ -48,7 +48,7 @@ Name="VCCLCompilerTool" Optimization="0" 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-4.0.2\libtiff;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;TPL_NOLIB;" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;TPL_NOLIB;STFU_EXPORTS" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -142,7 +142,7 @@ Name="VCCLCompilerTool" Optimization="0" 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-4.0.2\libtiff;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;TPL_NOLIB;" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;TPL_NOLIB;STFU_EXPORTS" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -235,7 +235,7 @@ Name="VCCLCompilerTool" Optimization="0" 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-4.0.2\libtiff;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;TPL_NOLIB;" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;TPL_NOLIB;STFU_EXPORTS" RuntimeLibrary="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="switch.h" @@ -325,7 +325,7 @@ Name="VCCLCompilerTool" Optimization="0" 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-4.0.2\libtiff;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;TPL_NOLIB;" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;TPL_NOLIB;STFU_EXPORTS" RuntimeLibrary="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="switch.h" @@ -855,11 +855,11 @@ > 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;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -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;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -199,7 +199,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs MaxSpeed ..\..\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-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;%(PreprocessorDefinitions) MultiThreadedDLL Use switch.h @@ -248,7 +248,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs MaxSpeed ..\..\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-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;%(PreprocessorDefinitions) MultiThreadedDLL Use switch.h @@ -836,4 +836,4 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs - + \ No newline at end of file From fa2c9ec07e684b074ef901fef7c91f06e5a22e6b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 2 Nov 2012 08:47:38 -0500 Subject: [PATCH 346/512] FS-4011 --resolve --- .../mod_voicemail/mod_voicemail.c | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index e6ce3aecf0..195ac3170f 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -2582,6 +2582,7 @@ static switch_status_t deliver_vm(vm_profile_t *profile, char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; const char *filename; switch_xml_t x_param, x_params; + const char *vm_cc = NULL, *vm_cc_tmp = NULL; char *vm_email = NULL; char *vm_email_from = NULL; char *vm_notify_email = NULL; @@ -2641,7 +2642,9 @@ static switch_status_t deliver_vm(vm_profile_t *profile, const char *var = switch_xml_attr_soft(x_param, "name"); const char *val = switch_xml_attr_soft(x_param, "value"); - if (!strcasecmp(var, "vm-mailto")) { + if (!strcasecmp(var, "vm-cc")) { + vm_cc = switch_core_strdup(pool, val); + } else if (!strcasecmp(var, "vm-mailto")) { vm_email = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "vm-notify-mailto")) { vm_notify_email = switch_core_strdup(pool, val); @@ -2922,18 +2925,34 @@ static switch_status_t deliver_vm(vm_profile_t *profile, if (session) { switch_channel_t *channel = switch_core_session_get_channel(session); - const char *vm_cc; + if (channel && (vm_cc_tmp = switch_channel_get_variable(channel, "vm_cc"))) { + vm_cc = vm_cc_tmp; + } + } - if ((vm_cc = switch_channel_get_variable(channel, "vm_cc"))) { + if (vm_cc) { + char *vm_cc_dup; + int vm_cc_num = 0; + char *vm_cc_list[256] = { 0 }; + int vm_cc_i; + + vm_cc_dup = strdup(vm_cc); + vm_cc_num = switch_separate_string(vm_cc_dup, ',', vm_cc_list, (sizeof(vm_cc_list) / sizeof(vm_cc_list[0]))); + + for (vm_cc_i=0; vm_cc_i Date: Fri, 2 Nov 2012 19:07:26 +0000 Subject: [PATCH 347/512] update these examples to use the correct syntax for pgsql --- conf/vanilla/autoload_configs/switch.conf.xml | 2 +- conf/vanilla/sip_profiles/internal.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/vanilla/autoload_configs/switch.conf.xml b/conf/vanilla/autoload_configs/switch.conf.xml index fc0ac21b82..ddf41f8996 100644 --- a/conf/vanilla/autoload_configs/switch.conf.xml +++ b/conf/vanilla/autoload_configs/switch.conf.xml @@ -144,7 +144,7 @@ - + - + From b002394f2102fddd78dc87373fd227a997440768 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 2 Nov 2012 12:49:39 -0500 Subject: [PATCH 348/512] 7 ate 9 --- src/switch_core_sqldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index ac32d7d146..7fa478815e 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -330,13 +330,13 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_ if (!strncasecmp(dsn, "pgsql://", 8)) { type = SCDB_TYPE_PGSQL; connection_options.pgsql_options.dsn = (char *)(dsn + 8); - } else if ((!(i = strncasecmp(dsn, "odbc://", 8))) || strchr(dsn, ':')) { + } else if ((!(i = strncasecmp(dsn, "odbc://", 7))) || strchr(dsn, ':')) { type = SCDB_TYPE_ODBC; if (i) { switch_set_string(tmp, dsn); } else { - switch_set_string(tmp, dsn+8); + switch_set_string(tmp, dsn+7); } connection_options.odbc_options.dsn = tmp; From e884de5b0782f2b3c2a6a32dd546b86d6924acc8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 2 Nov 2012 13:54:54 -0500 Subject: [PATCH 349/512] add NUTAG_RETRY_AFTER_ENABLE() tag to lib sofia and use it in mod_sofia to disable processing retry-after headers on a per-call basis --- libs/sofia-sip/.update | 2 +- .../libsofia-sip-ua/nua/nua_client.c | 1 + .../libsofia-sip-ua/nua/nua_params.c | 9 +++++++ .../libsofia-sip-ua/nua/nua_params.h | 5 ++++ libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c | 24 +++++++++++++++++++ .../libsofia-sip-ua/nua/sofia-sip/nua_tag.h | 5 ++++ src/mod/endpoints/mod_sofia/sofia.c | 1 + 7 files changed, 46 insertions(+), 1 deletion(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index e5cf1e495d..09f61c0ed4 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Fri Oct 26 14:14:41 CDT 2012 +Fri Nov 2 13:36:06 CDT 2012 diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c index e7ec9fb890..a9fed48ffe 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c @@ -1217,6 +1217,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr, status == 500 || status == 503 || status == 600 || status == 603) && sip->sip_retry_after && + NH_PGET(nh, retry_after_enable) && sip->sip_retry_after->af_delta < 3200) { su_timer_t *timer; char phrase[18]; /* Retry After XXXX\0 */ diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c index 0f6a491dff..c63455fc91 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c @@ -157,6 +157,7 @@ int nua_stack_set_defaults(nua_handle_t *nh, NHP_SET(nhp, callee_caps, 0); NHP_SET(nhp, service_route_enable, 1); NHP_SET(nhp, path_enable, 1); + NHP_SET(nhp, retry_after_enable, 1); NHP_SET(nhp, refer_expires, 300); NHP_SET(nhp, refer_with_id, 1); @@ -295,6 +296,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags) * NUTAG_ONLY183_100REL() \n * NUTAG_OUTBOUND() \n * NUTAG_PATH_ENABLE() \n + * NUTAG_RETRY_AFTER_ENABLE() \n * NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n * NUTAG_REFER_EXPIRES() \n * NUTAG_REFER_WITH_ID() \n @@ -417,6 +419,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags) * NUTAG_ONLY183_100REL() \n * NUTAG_OUTBOUND() \n * NUTAG_PATH_ENABLE() \n + * NUTAG_RETRY_AFTER_ENABLE() \n * NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n * NUTAG_REFER_EXPIRES() \n * NUTAG_REFER_WITH_ID() \n @@ -801,6 +804,10 @@ static int nhp_set_tags(su_home_t *home, else if (tag == nutag_path_enable) { NHP_SET(nhp, path_enable, value != 0); } + /* NUTAG_RETRY_AFTER_ENABLE(retry_after_enable) */ + else if (tag == nutag_retry_after_enable) { + NHP_SET(nhp, retry_after_enable, value != 0); + } /* NUTAG_AUTH_CACHE(auth_cache) */ else if (tag == nutag_auth_cache) { if (value >= 0 && value < (tag_value_t)_nua_auth_cache_invalid) @@ -1494,6 +1501,7 @@ int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags) * NUTAG_ONLY183_100REL() \n * NUTAG_OUTBOUND() \n * NUTAG_PATH_ENABLE() \n + * NUTAG_RETRY_AFTER_ENABLE() \n * NUTAG_REFER_EXPIRES() \n * NUTAG_REFER_WITH_ID() \n * NUTAG_REFRESH_WITHOUT_SDP() \n @@ -1669,6 +1677,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, TIF(NUTAG_MEDIA_FEATURES, media_features), TIF(NUTAG_SERVICE_ROUTE_ENABLE, service_route_enable), TIF(NUTAG_PATH_ENABLE, path_enable), + TIF(NUTAG_RETRY_AFTER_ENABLE, retry_after_enable), TIF(NUTAG_AUTH_CACHE, auth_cache), TIF(NUTAG_REFER_EXPIRES, refer_expires), TIF(NUTAG_REFER_WITH_ID, refer_with_id), diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h index 9fe4a98652..5c26e4ef13 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h @@ -111,6 +111,10 @@ struct nua_handle_preferences unsigned nhp_refer_with_id:1; unsigned nhp_timer_autorequire:1; + + /** Enable Retry-After */ + unsigned nhp_retry_after_enable:1; + unsigned:0; /* Default lifetime for implicit subscriptions created by REFER */ @@ -210,6 +214,7 @@ struct nua_handle_preferences unsigned nhb_initial_route:1; unsigned nhb_proxy:1; unsigned nhb_timer_autorequire:1; + unsigned nhb_retry_after_enable:1; unsigned :0; } set_bits; unsigned set_unsigned[2]; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c index 491d485731..9e0c8d85ca 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c @@ -126,6 +126,7 @@ * - NUTAG_M_USERNAME() * - NUTAG_OUTBOUND() * - NUTAG_PATH_ENABLE() + * - NUTAG_RETRY_AFTER_ENABLE() * - NUTAG_SERVICE_ROUTE_ENABLE() * Specifications: * - @RFC3261 section 10, @RFC3327, @RFC3608, @RFC3680, @RFC3840, @@ -2663,6 +2664,29 @@ tag_typedef_t nutag_path_enable = BOOLTAG_TYPEDEF(path_enable); * Reference tag for NUTAG_PATH_ENABLE(). */ +/**@def NUTAG_RETRY_AFTER_ENABLE(x) + * + * If true, support RFC 3261 Retry-After + * + * @par Used with + * - nua_create(), nua_set_params(), nua_get_params() + * - nua_handle(), nua_set_hparams(), nua_get_hparams() + * - nua_register() + * + * @par Parameter type + * int (boolean: nonzero is true, zero is false) + * + * @par Values + * - 0 (false) - Do not honor Retry-After + * - 1 (true) - honor Retry-After + * + */ +tag_typedef_t nutag_retry_after_enable = BOOLTAG_TYPEDEF(retry_after_enable); + +/**@def NUTAG_RETRY_AFTER_ENABLE_REF(x) + * Reference tag for NUTAG_RETRY_AFTER_ENABLE(). + */ + /**@def NUTAG_SERVICE_ROUTE_ENABLE(x) diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h index 813e0d757a..be909d6911 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h @@ -550,6 +550,11 @@ SOFIAPUBVAR tag_typedef_t nutag_path_enable; #define NUTAG_PATH_ENABLE_REF(x) nutag_path_enable_ref, tag_bool_vr(&(x)) SOFIAPUBVAR tag_typedef_t nutag_path_enable_ref; +#define NUTAG_RETRY_AFTER_ENABLE(x) nutag_retry_after_enable, tag_bool_v(x) +SOFIAPUBVAR tag_typedef_t nutag_retry_after_enable; +#define NUTAG_RETRY_AFTER_ENABLE_REF(x) nutag_retry_after_enable_ref, tag_bool_vr(&(x)) +SOFIAPUBVAR tag_typedef_t nutag_retry_after_enable_ref; + #define NUTAG_SERVICE_ROUTE_ENABLE(x) nutag_service_route_enable, tag_bool_v(x) SOFIAPUBVAR tag_typedef_t nutag_service_route_enable; #define NUTAG_SERVICE_ROUTE_ENABLE_REF(x) \ diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 4a074088fc..ebc8f2aa6b 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2408,6 +2408,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void profile, /* Additional data to pass to callback */ TAG_IF( ! sofia_test_pflag(profile, PFLAG_TLS) || ! profile->tls_only, NUTAG_URL(profile->bindurl)), NTATAG_USER_VIA(1), + NUTAG_RETRY_AFTER_ENABLE(0), TAG_IF(!strchr(profile->sipip, ':'), SOATAG_AF(SOA_AF_IP4_ONLY)), TAG_IF(strchr(profile->sipip, ':'), From 49551f605c3018c3dc758cc1acac81265330c401 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 2 Nov 2012 13:58:56 -0500 Subject: [PATCH 350/512] remove debug line --- src/mod/applications/mod_dptools/mod_dptools.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index d274198ecd..b3ed2a7c1b 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -5154,8 +5154,6 @@ void *SWITCH_THREAD_FUNC call_monitor_thread(switch_thread_t *thread, void *obj) } while (busy); - /* printf("%ld ASS LAUNCH %s %d %d\n", (long)pthread_self(), argv[sent], sent, size); */ - launch_call(argv[sent++], cm->path, cm->exten, cm->context, cm->dp, mutex, &counter, &var_event); } From ba0e7ae9ca27babbdc56e2e3da9d9b18881b3df0 Mon Sep 17 00:00:00 2001 From: William King Date: Fri, 2 Nov 2012 17:06:27 -0700 Subject: [PATCH 351/512] Adding ability to toggle mod_xml_radius debug flag from a console api command rather than having to rebuild and reload the module. --- .../xml_int/mod_xml_radius/mod_xml_radius.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c index 0b99166f98..d858f46535 100644 --- a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c +++ b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c @@ -45,7 +45,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_xml_radius_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_radius_shutdown); SWITCH_MODULE_DEFINITION(mod_xml_radius, mod_xml_radius_load, mod_xml_radius_shutdown, NULL); -static int GLOBAL_DEBUG = 0; +int GLOBAL_DEBUG = 0; switch_status_t mod_xml_radius_new_handle(rc_handle **new_handle, switch_xml_t xml) { switch_xml_t server, param; @@ -531,6 +531,21 @@ switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch } +/* static switch_status_t name (_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) */ +SWITCH_STANDARD_API(mod_xml_radius_debug_api) +{ + if ( !strncmp(cmd, "on", 2) ) { + GLOBAL_DEBUG = 1; + } else if ( !strncmp(cmd, "off", 3)){ + GLOBAL_DEBUG = 0; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Valid options are [yes|no]\n" ); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "debug is %s\n", (GLOBAL_DEBUG ? "on" : "off") ); + return SWITCH_STATUS_SUCCESS; +} + /* static switch_status_t name (_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) */ SWITCH_STANDARD_API(mod_xml_radius_connect_test) { @@ -1132,6 +1147,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_xml_radius_load) } SWITCH_ADD_API(mod_xml_radius_api_interface, "xml_radius_connect_test", "mod_xml_radius connection test", mod_xml_radius_connect_test, NULL); + SWITCH_ADD_API(mod_xml_radius_api_interface, "xml_radius_debug", "mod_xml_radius toggle debug", mod_xml_radius_debug_api, NULL); switch_core_add_state_handler(&state_handlers); From 3c2c6832fa5eab8bc84bf7f0be93a0f1c3876b68 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Nov 2012 06:37:01 -0600 Subject: [PATCH 352/512] FS-4792 --resolve sure --- src/switch_limit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_limit.c b/src/switch_limit.c index 6e792ca53d..c1c2789f8b 100644 --- a/src/switch_limit.c +++ b/src/switch_limit.c @@ -83,7 +83,7 @@ static switch_status_t limit_state_handler(switch_core_session_t *session) const char *backendlist = switch_channel_get_variable(channel, LIMIT_BACKEND_VARIABLE); if (zstr(backendlist)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unset limit backendlist!\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Unset limit backendlist!\n"); return SWITCH_STATUS_SUCCESS; } From b86944bcac2de9b35793bb27f43d1fddc57852e7 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 5 Nov 2012 11:09:06 -0600 Subject: [PATCH 353/512] Enable FEC up packet loss percent --- src/mod/codecs/mod_silk/mod_silk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index bb0eeaa7fd..c585548ea6 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -56,10 +56,10 @@ struct silk_codec_settings { typedef struct silk_codec_settings silk_codec_settings_t; static silk_codec_settings_t default_codec_settings = { - /*.useinbandfec */ 0, + /*.useinbandfec */ 1, /*.usedtx */ 0, /*.maxaveragebitrate */ 0, - /*.plpct */ 10, // 10% for now + /*.plpct */ 20, // 20% for now }; struct silk_context { From 72daaa73e963604693229ff7fa7b708f48e22a16 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Nov 2012 10:33:28 -0600 Subject: [PATCH 354/512] 6b7d5e5a9a04164c0f7ecc4cd9dc9ffdc729c5f5 was actually wrong, I was sick that day, I should have gotten more rest.. =/ --- src/mod/codecs/mod_opus/mod_opus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 4519eebaa4..80d6ceacf1 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -182,7 +182,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) { switch_codec_interface_t *codec_interface; int samples = 480; - int bytes = 80; + int bytes = 960; int mss = 10000; int x = 0; int rate = 48000; From 851db97afa8ba63424f9fd30bb0d6fa77121ae85 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 5 Nov 2012 13:53:59 -0500 Subject: [PATCH 355/512] fix darwin 10.7 build --- configure.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index a343ad3e9e..b051991804 100644 --- a/configure.in +++ b/configure.in @@ -164,7 +164,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then SOLINK="-Bdynamic -dy -G" elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then case "$host" in - *darwin12.*|*darwin10.*) + *darwin12.*|*darwin11.*|*darwin10.*) SOLINK="-dynamic -force-flat-namespace" ;; *darwin*) @@ -248,7 +248,7 @@ elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then APR_ADDTO(SWITCH_AM_CFLAGS, -Werror) if test "${enable_64}" = "yes"; then case "$host" in - *darwin12.*|*darwin10.*|*darwin9.*|*darwin8.*) + *darwin12.*|*darwin11.*|*darwin10.*|*darwin9.*|*darwin8.*) APR_ADDTO(CFLAGS, -arch x86_64) APR_ADDTO(LDFLAGS, -arch x86_64) APR_ADDTO(CXXFLAGS, -arch x86_64) @@ -454,7 +454,7 @@ PLATFORM_CORE_LDFLAGS= PLATFORM_CORE_LIBS= # tweak platform specific flags case "$host" in - *darwin12.*) + *darwin12.*|*darwin11.*) APR_ADDTO(SWITCH_AM_CFLAGS, -DMACOSX) APR_ADDTO(CFLAGS, -pipe -no-cpp-precomp -Wno-deprecated-declarations) APR_ADDTO(LDFLAGS, -pipe -bind_at_load) From 306c2fa205559adfd2e1825c60fb12de74f7aff1 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 5 Nov 2012 15:12:38 -0500 Subject: [PATCH 356/512] don't skip sending cid number if there is a + in it --- libs/freetdm/mod_freetdm/mod_freetdm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 06dc587a4b..7ed8be290a 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1318,6 +1318,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi if (!zstr(outbound_profile->caller_id_number)) { callerid_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->caller_id_number)); + if ( callerid_num && *callerid_num == '+' ) { + callerid_num++; + } } if (!zstr(callerid_num) && !strcmp(callerid_num, SWITCH_DEFAULT_CLID_NUMBER)) { @@ -1394,6 +1397,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerNumber"); if (sipvar) { + if ( *sipvar == '+' ) { + sipvar++; + } ftdm_set_string(caller_data.cid_num.digits, sipvar); } @@ -1653,7 +1659,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_data.rdnis.plan = outbound_profile->rdnis_numplan; ftdm_set_string(caller_data.cid_name, outbound_profile->caller_id_name); - ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(outbound_profile->caller_id_number)); + ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(callerid_num)); memset(&hunting, 0, sizeof(hunting)); From b19ce17cb2503e9dad8afd25dc3894bd1e63a7a2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Nov 2012 13:36:16 -0600 Subject: [PATCH 357/512] regression from 2494448846eafac0ef7c6a2ba174004a4e361590 --- 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 a2f9760da9..9a2ecbcb72 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -652,7 +652,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) 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; - i->cur_ts = i->out_queue->array[x].seq; + i->cur_seq = i->out_queue->array[x].seq; break; } if (i->cur_ts == 0) { From baf4a472a534ab5000494f6df2dfb4e972925db0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Nov 2012 13:54:09 -0600 Subject: [PATCH 358/512] update rev --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index b051991804..a0752f1ab7 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_INIT([freeswitch], [1.3.0], BUG-REPORT-ADDRESS) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [0]) +AC_SUBST(SWITCH_VERSION_MICRO, [2]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From f61ffd77f2e8d6fd4f5536880e7fc95a4c0e0695 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Nov 2012 14:04:02 -0600 Subject: [PATCH 359/512] doh --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a0752f1ab7..1283b2a185 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.0], BUG-REPORT-ADDRESS) +AC_INIT([freeswitch], [1.3.2], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) AC_SUBST(SWITCH_VERSION_MICRO, [2]) From d97542481667fe612246a96f7e686c1a86be6339 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 09:55:14 +0100 Subject: [PATCH 360/512] skypopen: removing my own chatmessage from the array --- src/mod/endpoints/mod_skypopen/skypopen_protocol.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c index 2126955452..3e6ea06193 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c @@ -522,7 +522,15 @@ int skypopen_signaling_read(private_t *tech_pvt) sprintf(msg_to_skype, "SET CHATMESSAGE %s SEEN", id); skypopen_signaling_write(tech_pvt, msg_to_skype); + } else { + DEBUGA_SKYPE + ("CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s, chatname=%s, from_handle=%s, from_dispname=%s, body=%s NOT DELETEEEEEEEEEEEEEEEEED\n", + SKYPOPEN_P_LOG, id, i, tech_pvt->chatmessages[i].type, tech_pvt->chatmessages[i].id, tech_pvt->chatmessages[i].chatname, + tech_pvt->chatmessages[i].from_handle, tech_pvt->chatmessages[i].from_dispname, tech_pvt->chatmessages[i].body); + memset(&tech_pvt->chatmessages[i], '\0', sizeof(&tech_pvt->chatmessages[i])); + DEBUGA_SKYPE("chatmessage %s HAS BEEN DELETEEEEEEEEEEEEEEEEED\n", SKYPOPEN_P_LOG, id); } + } } From a6068d25fef891f00fec936abf36f405142dc02b Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 09:57:19 +0100 Subject: [PATCH 361/512] skypopen: removing my own chatmessage from the array - nicer logmesg --- src/mod/endpoints/mod_skypopen/skypopen_protocol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c index 3e6ea06193..b07784fa7f 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c @@ -524,11 +524,11 @@ int skypopen_signaling_read(private_t *tech_pvt) skypopen_signaling_write(tech_pvt, msg_to_skype); } else { DEBUGA_SKYPE - ("CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s, chatname=%s, from_handle=%s, from_dispname=%s, body=%s NOT DELETEEEEEEEEEEEEEEEEED\n", + ("CHATMESSAGE %s is in position %d in the chatmessages array, type=%s, id=%s, chatname=%s, from_handle=%s, from_dispname=%s, body=%s NOT DELETED\n", SKYPOPEN_P_LOG, id, i, tech_pvt->chatmessages[i].type, tech_pvt->chatmessages[i].id, tech_pvt->chatmessages[i].chatname, tech_pvt->chatmessages[i].from_handle, tech_pvt->chatmessages[i].from_dispname, tech_pvt->chatmessages[i].body); memset(&tech_pvt->chatmessages[i], '\0', sizeof(&tech_pvt->chatmessages[i])); - DEBUGA_SKYPE("chatmessage %s HAS BEEN DELETEEEEEEEEEEEEEEEEED\n", SKYPOPEN_P_LOG, id); + DEBUGA_SKYPE("chatmessage %s HAS BEEN DELETED\n", SKYPOPEN_P_LOG, id); } } From 648ce206c6d8a7d4a5dcdd3e6a768017fcb21814 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 10:39:12 +0100 Subject: [PATCH 362/512] FS-4338 gsmopen: added patch to compile in FreeBSD --- .../endpoints/mod_gsmopen/FREEBSD_README.txt | 9 + .../endpoints/mod_gsmopen/FREEBSD_patch.diff | 171 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt create mode 100644 src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff diff --git a/src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt b/src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt new file mode 100644 index 0000000000..4cbedeae63 --- /dev/null +++ b/src/mod/endpoints/mod_gsmopen/FREEBSD_README.txt @@ -0,0 +1,9 @@ +This patch (updated to be applied today) was sent via Jira by royj@yandex.ru, with Jira issue FS-4338. + +Apply in this way: +# patch -p6 < FREEBSD_patch.diff + +I have not tested it, but it works for him. +Please open another Jira issue if anything wrong. + +-giovanni diff --git a/src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff b/src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff new file mode 100644 index 0000000000..cd5613a2d7 --- /dev/null +++ b/src/mod/endpoints/mod_gsmopen/FREEBSD_patch.diff @@ -0,0 +1,171 @@ +diff --git a/src/mod/endpoints/mod_gsmopen/Makefile b/src/mod/endpoints/mod_gsmopen/Makefile +index 18943c8..5324c52 100644 +--- a/src/mod/endpoints/mod_gsmopen/Makefile ++++ b/src/mod/endpoints/mod_gsmopen/Makefile +@@ -1,5 +1,5 @@ + MODNAME=mod_gsmopen +-LOCAL_CFLAGS += -I../../../../libs/spandsp/src -I../../../..//libs/tiff-4.0.2/libtiff -DGSMOPEN_C_VER=\"`git log -1 --format="%h" gsmopen_protocol.cpp`\" -DMODGSMOPEN_C_VER=\"`git log -1 --format="%h" mod_gsmopen.cpp`\" ++LOCAL_CFLAGS += -I/usr/local/include -I../../../../libs/spandsp/src -I../../../..//libs/tiff-4.0.2/libtiff -DGSMOPEN_C_VER=\"`git log -1 --format="%h" gsmopen_protocol.cpp`\" -DMODGSMOPEN_C_VER=\"`git log -1 --format="%h" mod_gsmopen.cpp`\" + LOCAL_LDFLAGS=-L../../../../libs/spandsp/src -lspandsp -lctb-0.16 -lgsmme + LOCAL_OBJS=gsmopen_protocol.o + include ../../../../build/modmake.rules +diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +index 5bdda08..73ef93d 100644 +--- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp ++++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +@@ -2356,7 +2356,7 @@ int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outb + iconv_t iconv_format; + int iconv_res; + char *outbuf; +- char *inbuf; ++ //char *inbuf; + size_t inbytesleft; + int c; + char stringa[5]; +@@ -2376,9 +2376,10 @@ int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outb + } + + outbuf = utf8_out; +- inbuf = converted; ++ const char *inbuf = converted; + +- iconv_format = iconv_open("UTF8", "UCS-2BE"); ++ //iconv_format = iconv_open("UTF8", "UCS-2BE"); ++ iconv_format = iconv_open("UTF-8", "UCS-2BE"); + //iconv_format = iconv_open("UTF8", "UCS2"); + if (iconv_format == (iconv_t) -1) { + ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); +@@ -2417,12 +2418,12 @@ int utf8_to_iso_8859_1(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, c + iconv_t iconv_format; + int iconv_res; + char *outbuf; +- char *inbuf; ++ //char *inbuf; + + outbuf = iso_8859_1_out; +- inbuf = utf8_in; ++ const char *inbuf = utf8_in; + +- iconv_format = iconv_open("ISO_8859-1", "UTF8"); ++ iconv_format = iconv_open("ISO_8859-1", "UTF-8"); + if (iconv_format == (iconv_t) -1) { + ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); + return -1; +@@ -2467,7 +2468,7 @@ int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out, + iconv_t iconv_format; + int iconv_res; + char *outbuf; +- char *inbuf; ++ //char *inbuf; + size_t inbytesleft; + //int c; + //char stringa[5]; +@@ -2477,9 +2478,9 @@ int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out, + DEBUGA_GSMOPEN("iso_8859_1_in=%s\n", GSMOPEN_P_LOG, iso_8859_1_in); + + outbuf = utf8_out; +- inbuf = iso_8859_1_in; ++ const char *inbuf = iso_8859_1_in; + +- iconv_format = iconv_open("UTF8", "ISO_8859-1"); ++ iconv_format = iconv_open("UTF-8", "ISO_8859-1"); + if (iconv_format == (iconv_t) -1) { + ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); + return -1; +@@ -2514,7 +2515,7 @@ int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *u + iconv_t iconv_format; + int iconv_res; + char *outbuf; +- char *inbuf; ++ //char *inbuf; + char converted[16000]; + int i; + char stringa[16]; +@@ -2523,9 +2524,9 @@ int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *u + memset(converted, '\0', sizeof(converted)); + + outbuf = converted; +- inbuf = utf8_in; ++ const char *inbuf = utf8_in; + +- iconv_format = iconv_open("UCS-2BE", "UTF8"); ++ iconv_format = iconv_open("UCS-2BE", "UTF-8"); + if (iconv_format == (iconv_t) -1) { + ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno)); + return -1; +diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h +index d88528b..f8851cc 100644 +--- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h ++++ b/src/mod/endpoints/mod_gsmopen/libctb-0.16/include/ctb-0.16/linux/serport.h +@@ -10,7 +10,7 @@ + ///////////////////////////////////////////////////////////////////////////// + + #include "ctb-0.16/serportx.h" +-#include ++//#include + #include + + namespace ctb { +@@ -40,7 +40,7 @@ namespace ctb { + need the errors during a active connection, we must save the actual + error numbers in this separate structurs. + */ +- struct serial_icounter_struct save_info, last_info; ++ //struct serial_icounter_struct save_info, last_info; + + /*! + \brief adaptor member function, to convert the plattform independent +diff --git a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp +index a369abc..d190567 100644 +--- a/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp ++++ b/src/mod/endpoints/mod_gsmopen/libctb-0.16/src/linux/serport.cpp +@@ -136,7 +136,7 @@ namespace ctb { + // + int SerialPort::Ioctl(int cmd, void* args) + { +- int count = 0; ++ /* int count = 0; + int err = 0; + struct serial_icounter_struct info; + SerialPort_EINFO einfo; +@@ -184,7 +184,8 @@ namespace ctb { + return -1; + } + last_info = info; +- return 0; ++ return 0;*/ ++ return -1; + }; + + int SerialPort::IsOpen() +@@ -292,9 +293,9 @@ namespace ctb { + // request the actual numbers of breaks, framing, overrun + // and parity errors (because Linux summing all of them during + // system lifetime, not only while serial port is open. +- ioctl(fd,TIOCGICOUNT,&save_info); ++ //ioctl(fd,TIOCGICOUNT,&save_info); + // it's also careless, but we assume, that there was no error +- last_info = save_info; ++ //last_info = save_info; + + // in case of a non-standard rate, the termios struct have to set + // with the B38400 rate, see above! +@@ -359,7 +360,7 @@ namespace ctb { + + int SerialPort::SetBaudrateAny( int baudrate ) + { +- struct serial_struct ser_info; ++ /* struct serial_struct ser_info; + + int result = ioctl( fd, TIOCGSERIAL, &ser_info ); + +@@ -369,7 +370,8 @@ namespace ctb { + + result = ioctl( fd, TIOCSSERIAL, &ser_info ); + +- return result; ++ return result;*/ ++ return -1; + } + + int SerialPort::SetBaudrateStandard( int baudrate ) From 65bc765846c6ec171f0ad9c201d39c072771179a Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 11:34:34 +0100 Subject: [PATCH 363/512] FS-4659 gsmopen: give error and abort call when dialing was not through correctly (eg: get back OK). Also, grow the default timeout when expecting a string back from the modem to half a second - 500000 usec - so to avoid false negatives --- src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp | 8 +++++--- src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp index 5bdda08f81..81d1192307 100644 --- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp @@ -2189,7 +2189,7 @@ int gsmopen_serial_write_AT_expect1(private_t *tech_pvt, const char *data, const return -1; } - at_result = gsmopen_serial_read_AT(tech_pvt, 1, 100000, seconds, expected_string, expect_crlf); // minimum 1/10th sec timeout + at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, seconds, expected_string, expect_crlf); // minimum half a sec timeout UNLOCKA(tech_pvt->controldev_lock); POPPA_UNLOCKA(tech_pvt->controldev_lock); @@ -2700,6 +2700,8 @@ int gsmopen_hangup(private_t *tech_pvt) int gsmopen_call(private_t *tech_pvt, char *rdest, int timeout) { + int result; + //gsmopen_sleep(5000); DEBUGA_GSMOPEN("Calling GSM, rdest is: %s\n", GSMOPEN_P_LOG, rdest); //gsmopen_signaling_write(tech_pvt, "SET AGC OFF"); @@ -2707,11 +2709,11 @@ int gsmopen_call(private_t *tech_pvt, char *rdest, int timeout) //gsmopen_signaling_write(tech_pvt, "SET AEC OFF"); //gsmopen_sleep(10000); - gsmopen_serial_call(tech_pvt, rdest); + result=gsmopen_serial_call(tech_pvt, rdest); //ERRORA("failed to communicate with GSM client, now exit\n", GSMOPEN_P_LOG); //return -1; //} - return 0; + return result; } int gsmopen_senddigit(private_t *tech_pvt, char digit) diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp index 62f5cdd20f..18451d8cf2 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp @@ -1054,6 +1054,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi switch_call_cause_t *cancel_cause) { private_t *tech_pvt = NULL; + int result; + if ((*new_session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { switch_channel_t *channel = NULL; switch_caller_profile_t *caller_profile; @@ -1171,8 +1173,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi switch_set_flag(tech_pvt, TFLAG_OUTBOUND); switch_mutex_unlock(tech_pvt->flag_mutex); switch_channel_set_state(channel, CS_INIT); - gsmopen_call(tech_pvt, rdest, 30); + result=gsmopen_call(tech_pvt, rdest, 30); switch_mutex_unlock(globals.mutex); + if(result != 0){ + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } return SWITCH_CAUSE_SUCCESS; } From 85542799f053dc0399fc2ad757434c6b212014f1 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 12:05:26 +0100 Subject: [PATCH 364/512] FS-4782 gsmopen: abide the origination_uuid variable. Dude abide --- src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp index 18451d8cf2..026db9eb8d 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp @@ -1056,7 +1056,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi private_t *tech_pvt = NULL; int result; - if ((*new_session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { + if ((*new_session = switch_core_session_request_uuid(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid"))) != 0) { + switch_channel_t *channel = NULL; switch_caller_profile_t *caller_profile; char *rdest; From 92d44e5023038b1d5a3431b3fc5d553cedd0fb65 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 12:24:17 +0100 Subject: [PATCH 365/512] FS-4691 gsmopen: patch from Ivan Mironov allowing for longer device names, useful for symlinks created by udev --- src/mod/endpoints/mod_gsmopen/gsmopen.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen.h b/src/mod/endpoints/mod_gsmopen/gsmopen.h index b5404ae6a9..af17a9f416 100644 --- a/src/mod/endpoints/mod_gsmopen/gsmopen.h +++ b/src/mod/endpoints/mod_gsmopen/gsmopen.h @@ -331,7 +331,7 @@ struct private_object { unsigned long ib_failed_calls; unsigned long ob_failed_calls; - char controldevice_name[50]; /*!< \brief name of the serial device controlling the interface, possibly none */ + char controldevice_name[512]; /*!< \brief name of the serial device controlling the interface, possibly none */ int controldevprotocol; /*!< \brief which protocol is used for serial control of this interface */ char controldevprotocolname[50]; /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */ int controldevfd; /*!< \brief serial controlling file descriptor for this interface */ @@ -469,7 +469,7 @@ struct private_object { int network_creg_not_supported; char creg[128]; - char controldevice_audio_name[50]; + char controldevice_audio_name[512]; int controldev_audio_fd; int controldevice_audio_speed; int controldev_audio_dead; From dedbb3a8cb455caf46b158dd4058e756e9f63931 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 12:31:32 +0100 Subject: [PATCH 366/512] FS-4692 gsmopen: patch from Ivan Mironov allowing for values 'context', 'dialplan', 'destination' and 'hold_music' from configuration file global_settings used by default for individual interfaces --- src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp index 026db9eb8d..1474f77908 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp @@ -1223,6 +1223,14 @@ static switch_status_t load_config(int reload_type) } switch_mutex_lock(globals.mutex); + + set_global_dialplan("XML"); + DEBUGA_GSMOPEN("Default globals.dialplan=%s\n", GSMOPEN_P_LOG, globals.dialplan); + set_global_destination("5000"); + DEBUGA_GSMOPEN("Default globals.destination=%s\n", GSMOPEN_P_LOG, globals.destination); + set_global_context("default"); + DEBUGA_GSMOPEN("Default globals.context=%s\n", GSMOPEN_P_LOG, globals.context); + if ((global_settings = switch_xml_child(cfg, "global_settings"))) { for (param = switch_xml_child(global_settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); @@ -1256,16 +1264,16 @@ static switch_status_t load_config(int reload_type) for (myinterface = switch_xml_child(interfaces, "interface"); myinterface; myinterface = myinterface->next) { char *id = (char *) switch_xml_attr(myinterface, "id"); char *name = (char *) switch_xml_attr(myinterface, "name"); - const char *context = "default"; - const char *dialplan = "XML"; - const char *destination = "5000"; + const char *context = globals.context; + const char *dialplan = globals.dialplan; + const char *destination = globals.destination; const char *controldevice_name = "/dev/ttyUSB3"; const char *controldevice_audio_name = "/dev/ttyUSB2"; char *digit_timeout = NULL; char *max_digits = NULL; char *hotline = NULL; char *dial_regex = NULL; - char *hold_music = NULL; + char *hold_music = globals.hold_music; char *fail_dial_regex = NULL; const char *enable_callerid = "true"; From d0c9ad1617c153714457e096101b0916729e74a2 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 12:47:40 +0100 Subject: [PATCH 367/512] FS-4740 skypopen: do not act on 'channel reset'. Ignore it as in the majority of endpoints --- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index c3b5d81681..0901bb895c 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -191,7 +191,7 @@ static switch_status_t interface_exists(char *the_interface); static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); -static switch_status_t channel_on_reset(switch_core_session_t *session); +//static switch_status_t channel_on_reset(switch_core_session_t *session); static switch_status_t channel_on_destroy(switch_core_session_t *session); static switch_status_t channel_on_routing(switch_core_session_t *session); static switch_status_t channel_on_exchange_media(switch_core_session_t *session); @@ -766,6 +766,7 @@ static switch_status_t channel_on_soft_execute(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } +#if 0 static switch_status_t channel_on_reset(switch_core_session_t *session) { private_t *tech_pvt = NULL; @@ -788,6 +789,7 @@ static switch_status_t channel_on_reset(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } +#endif //0 static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) @@ -1238,7 +1240,7 @@ switch_state_handler_table_t skypopen_state_handlers = { /*.on_soft_execute */ channel_on_soft_execute, /*.on_consume_media */ channel_on_consume_media, /*.on_hibernate */ NULL, - /*.on_reset */ channel_on_reset, + /*.on_reset */ NULL, /*.on_park */ NULL, /*.on_reporting */ NULL, /*.on_destroy */ channel_on_destroy From fe6c8b7037a1561433941e43788a95aa81d05752 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 6 Nov 2012 09:15:41 -0500 Subject: [PATCH 368/512] don't seg on invaild config --- 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 b3ed2a7c1b..91dd4944b1 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -3921,7 +3921,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, if ((x_params = switch_xml_child(x_user, "params"))) { for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { - const char *pvar = switch_xml_attr(x_param, "name"); + const char *pvar = switch_xml_attr_soft(x_param, "name"); const char *val = switch_xml_attr(x_param, "value"); if (!strcasecmp(pvar, "dial-string")) { From 33378fad7dac570df85ce25e699ca4956d32bf53 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 16:58:44 +0100 Subject: [PATCH 369/512] FS-4750 skypopen: generate inbound A-leg CDR (eg: do not jump from hangup to CS_DESTROY) --- src/mod/endpoints/mod_skypopen/mod_skypopen.c | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 0901bb895c..455e18b1cd 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -645,7 +645,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session) } //DEBUGA_SKYPE("debugging_hangup 12\n", SKYPOPEN_P_LOG); - switch_channel_set_state(channel, CS_DESTROY); + //switch_channel_set_state(channel, CS_DESTROY); return SWITCH_STATUS_SUCCESS; } @@ -2731,6 +2731,8 @@ int skypopen_partner_handle_ring(private_t *tech_pvt) if (tech_pvt && tech_pvt->ringing_state == SKYPOPEN_RINGING_INIT) { /* we are not inside an active call */ + switch_channel_t *channel = NULL; + tech_pvt->interface_state = SKYPOPEN_STATE_PRERING; gettimeofday(&tech_pvt->ring_time, NULL); switch_copy_string(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1); @@ -2743,6 +2745,22 @@ int skypopen_partner_handle_ring(private_t *tech_pvt) new_inbound_channel(tech_pvt); + switch_sleep(10000); + + session = switch_core_session_locate(tech_pvt->session_uuid_str); + if (session) { + channel = switch_core_session_get_channel(session); + switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING); + if (channel) { + switch_channel_mark_ring_ready(channel); + DEBUGA_SKYPE("switch_channel_mark_ring_ready(channel);\n", SKYPOPEN_P_LOG); + } else { + ERRORA("no channel\n", SKYPOPEN_P_LOG); + } + switch_core_session_rwunlock(session); + } else { + ERRORA("no session\n", SKYPOPEN_P_LOG); + } } else if (!tech_pvt || !tech_pvt->skype_call_id) { ERRORA("No Call ID?\n", SKYPOPEN_P_LOG); } else { From 14c4f66612148cb51e1efe4220974d6178eb5b3a Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Tue, 6 Nov 2012 18:06:39 +0100 Subject: [PATCH 370/512] FS-4742 skypopen: tentative blind fix to the Skype's Voicemail VM_PLAYING_GREETING problem --- .../mod_skypopen/skypopen_protocol.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c index b07784fa7f..84d4cb81ef 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c @@ -639,6 +639,53 @@ int skypopen_signaling_read(private_t *tech_pvt) //skypopen_sleep(10000); } + + if (!strcasecmp(prop, "VM_DURATION") && (!strcasecmp(value, "0"))) { + char msg_to_skype[1024]; + + NOTICA("We called a Skype contact and he started Skype voicemail on our skype_call: %s.\n", SKYPOPEN_P_LOG, id); + + if (!strlen(tech_pvt->session_uuid_str)) { + DEBUGA_SKYPE("no tech_pvt->session_uuid_str\n", SKYPOPEN_P_LOG); + } + if (tech_pvt->skype_callflow != CALLFLOW_STATUS_REMOTEHOLD) { + if (!strlen(tech_pvt->session_uuid_str) || !strlen(tech_pvt->skype_call_id) + || !strcasecmp(tech_pvt->skype_call_id, id)) { + skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); + DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPOPEN_P_LOG, id); + + if (tech_pvt->skype_callflow != CALLFLOW_STATUS_EARLYMEDIA) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; + tech_pvt->interface_state = SKYPOPEN_STATE_UP; + + if (tech_pvt->tcp_cli_thread == NULL) { + DEBUGA_SKYPE("START start_audio_threads\n", SKYPOPEN_P_LOG); + if (start_audio_threads(tech_pvt)) { + WARNINGA("start_audio_threads FAILED\n", SKYPOPEN_P_LOG); + return CALLFLOW_INCOMING_HANGUP; + } + } + //skypopen_sleep(1000); + sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, tech_pvt->tcp_cli_port); + skypopen_signaling_write(tech_pvt, msg_to_skype); + //skypopen_sleep(1000); + sprintf(msg_to_skype, "#output ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id, tech_pvt->tcp_srv_port); + skypopen_signaling_write(tech_pvt, msg_to_skype); + } + tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; + if (skypopen_answered(tech_pvt) != SWITCH_STATUS_SUCCESS) { + sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id); + skypopen_signaling_write(tech_pvt, msg_to_skype); + } + } else { + DEBUGA_SKYPE("I'm on %s, skype_call %s is NOT MY call, ignoring\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id); + } + } else { + tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; + DEBUGA_SKYPE("Back from REMOTEHOLD!\n", SKYPOPEN_P_LOG); + } + } + if (!strcasecmp(prop, "STATUS")) { if (!strcasecmp(value, "RINGING")) { @@ -841,6 +888,8 @@ int skypopen_signaling_read(private_t *tech_pvt) tech_pvt->skype_call_id[0] = '\0'; //skypopen_sleep(1000); return CALLFLOW_INCOMING_HANGUP; + } else if (!strncmp(value, "VM_", 2)) { + DEBUGA_SKYPE ("Our skype_call %s is in Skype voicemail: %s\n", SKYPOPEN_P_LOG, id, value); } else { WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPOPEN_P_LOG, id, value); } From 8e3f6d21f9ac041aeaf6484c3f0a08a7726ee2f5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 6 Nov 2012 08:51:33 -0600 Subject: [PATCH 371/512] FS-4796 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ebc8f2aa6b..1c14c473d7 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1502,6 +1502,10 @@ static void our_sofia_event_callback(nua_event_t event, nua_handle_bind(nh, NULL); } + if (tech_pvt && (tech_pvt->nh == nh)) { + tech_pvt->nh = NULL; + } + nua_handle_destroy(nh); nh = NULL; } From 6c1e81a813e58ae0652580c0763bde83bc037eb2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 6 Nov 2012 08:53:00 -0600 Subject: [PATCH 372/512] FS-4797 --resolve --- src/switch_rtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 8f9fc955a7..73c1db88b0 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3145,8 +3145,8 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->rtcp_fresh_frame = 1; - rtp_session->stats.rtcp.packet_count += sr->pc; - rtp_session->stats.rtcp.octet_count += sr->oc; + rtp_session->stats.rtcp.packet_count += ntohl(sr->pc); + rtp_session->stats.rtcp.octet_count += ntohl(sr->oc); rtp_session->stats.rtcp.peer_ssrc = ntohl(sr->ssrc); /* sender report */ From 658beb7fbd9618a416c8625b4f8edbe19b8f59f7 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Tue, 6 Nov 2012 22:50:29 +0000 Subject: [PATCH 373/512] This "else" condition is not an error condition. It is reached when you execute a multi-statement query and it reaches the end of all statements. --- src/switch_pgsql.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 22ab6ffd6d..9a84b2e3b0 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -289,7 +289,6 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq free(res); res = NULL; *result_out = NULL; - goto error; } return SWITCH_PGSQL_SUCCESS; From 89e163a10040c222eccbf1976b972d4efac579e2 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 7 Nov 2012 06:43:15 +0000 Subject: [PATCH 374/512] release FreeSWITCH 1.2.4 --- build/next-release.txt | 2 +- configure.in | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/next-release.txt b/build/next-release.txt index 996f71d3b9..c813fe116c 100644 --- a/build/next-release.txt +++ b/build/next-release.txt @@ -1 +1 @@ -1.2-rc3 +1.2.5 diff --git a/configure.in b/configure.in index da3a5af258..737de28d50 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.2.3], BUG-REPORT-ADDRESS) +AC_INIT([freeswitch], [1.2.4], BUG-REPORT-ADDRESS) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [2]) -AC_SUBST(SWITCH_VERSION_MICRO, [3]) +AC_SUBST(SWITCH_VERSION_MICRO, [4]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From feb38cece2a9103ee16cd263ce51b9fc7151256d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Nov 2012 08:14:32 -0600 Subject: [PATCH 375/512] FS-4779 give this a shot --- src/mod/endpoints/mod_sofia/mod_sofia.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index c11d37c42f..6bd9cdd3e0 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2024,10 +2024,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi nua_ack(tech_pvt->nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), - SOATAG_USER_SDP_STR(msg->string_arg), - SOATAG_REUSE_REJECTED(1), - SOATAG_RTP_SELECT(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), - TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), + SIPTAG_PAYLOAD_STR(msg->string_arg), + SIPTAG_CONTENT_TYPE_STR("application/sdp"), TAG_END()); sofia_clear_flag(tech_pvt, TFLAG_3PCC_INVITE); From f60962ae877762db4e9f494148a2b104482ddca2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Nov 2012 12:10:50 -0600 Subject: [PATCH 376/512] fix some contention issues under really high load...That doesn't mean you need to push it this hard and bug me about it =p --- src/mod/endpoints/mod_sofia/mod_sofia.h | 4 + src/mod/endpoints/mod_sofia/sofia.c | 46 ++--------- src/mod/endpoints/mod_sofia/sofia_glue.c | 20 +++++ src/mod/endpoints/mod_sofia/sofia_presence.c | 77 +++++++++++++------ src/mod/endpoints/mod_sofia/sofia_reg.c | 5 +- .../mod_event_socket/mod_event_socket.c | 10 --- src/switch_event.c | 5 +- 7 files changed, 89 insertions(+), 78 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 864d3a1e6f..909516d63e 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -389,6 +389,7 @@ struct mod_sofia_globals { int tracelevel; char *capture_server; int rewrite_multicasted_fs_path; + int presence_flush; }; extern struct mod_sofia_globals mod_sofia_globals; @@ -694,6 +695,7 @@ struct sofia_profile { int ireg_seconds; sofia_paid_type_t paid_type; uint32_t rtp_digit_delay; + switch_queue_t *event_queue; }; struct private_object { @@ -1206,6 +1208,8 @@ int sofia_recover_callback(switch_core_session_t *session); void sofia_glue_set_name(private_object_t *tech_pvt, const char *channame); private_object_t *sofia_glue_new_pvt(switch_core_session_t *session); switch_status_t sofia_init(void); +void sofia_glue_fire_events(sofia_profile_t *profile); +void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event); /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 1c14c473d7..6fcccabf53 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1559,7 +1559,7 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) { sofia_dispatch_event_t *de = *dep; switch_memory_pool_t *pool; - sofia_profile_t *profile = (*dep)->profile; + //sofia_profile_t *profile = (*dep)->profile; switch_thread_data_t *td; switch_core_new_memory_pool(&pool); @@ -1571,45 +1571,10 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) td->func = sofia_msg_thread_run_once; td->obj = de; - switch_mutex_lock(profile->ireg_mutex); switch_thread_pool_launch_thread(&td); - switch_mutex_unlock(profile->ireg_mutex); + } -#if 0 -void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) -{ - sofia_dispatch_event_t *de = *dep; - switch_threadattr_t *thd_attr = NULL; - switch_memory_pool_t *pool; - switch_thread_t *thread; - sofia_profile_t *profile = (*dep)->profile; - switch_status_t status; - - switch_core_new_memory_pool(&pool); - - - *dep = NULL; - de->pool = pool; - - switch_mutex_lock(profile->ireg_mutex); - switch_threadattr_create(&thd_attr, de->pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - status = switch_thread_create(&thread, - thd_attr, - sofia_msg_thread_run_once, - de, - de->pool); - switch_mutex_unlock(profile->ireg_mutex); - - if (status != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot create threads!\n"); - sofia_process_dispatch_event(&de); - } -} -#endif - void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) { sofia_dispatch_event_t *de = *dep; @@ -1992,6 +1957,7 @@ void sofia_event_callback(nua_event_t event, sofia_queue_message(de); end: + //switch_cond_next(); return; } @@ -2133,7 +2099,7 @@ void event_handler(switch_event_t *event) contact_str = fixed_contact_str; } - switch_mutex_lock(profile->ireg_mutex); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET); @@ -2150,7 +2116,7 @@ void event_handler(switch_event_t *event) sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str); } - switch_mutex_unlock(profile->ireg_mutex); + if (profile) { sofia_glue_release_profile(profile); @@ -2557,6 +2523,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool); switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool); + switch_queue_create(&profile->event_queue, SOFIA_QUEUE_SIZE, profile->pool); + switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name); switch_sql_queue_manager_init_name(qname, diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index bbaa9ae347..7e55407962 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6498,6 +6498,9 @@ switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile, switch_cache_db_release_db_handle(&dbh); + + sofia_glue_fire_events(profile); + return ret; } @@ -7139,6 +7142,23 @@ char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool) return s; } +void sofia_glue_fire_events(sofia_profile_t *profile) +{ + void *pop = NULL; + + while (profile->event_queue && switch_queue_trypop(profile->event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { + switch_event_t *event = (switch_event_t *) pop; + switch_event_fire(&event); + } + +} + +void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event) +{ + switch_queue_push(profile->event_queue, *event); + *event = NULL; +} + /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 17ab6b6efa..ed156c5f05 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1027,7 +1027,7 @@ static void conference_data_event_handler(switch_event_t *event) switch_safe_free(dup_domain); } -static void actual_sofia_presence_event_handler(switch_event_t *event) +static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event) { sofia_profile_t *profile = NULL; char *from = switch_event_get_header(event, "from"); @@ -1047,10 +1047,10 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) switch_console_callback_match_t *matches; struct presence_helper helper = { 0 }; int hup = 0; - + switch_event_t *s_event = NULL; if (!mod_sofia_globals.running) { - return; + goto done; } if (zstr(proto) || !strcasecmp(proto, "any")) { @@ -1091,7 +1091,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) if (!mod_sofia_globals.profile_hash) { - return; + goto done; } if (from) { @@ -1171,7 +1171,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) } switch_safe_free(sql); - return; + goto done; } if (zstr(event_type)) { @@ -1195,7 +1195,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) } } else { switch_safe_free(user); - return; + goto done; } if ((euser = strchr(user, '+'))) { euser++; @@ -1203,7 +1203,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) euser = user; } } else { - return; + goto done; } switch (event->event_id) { @@ -1462,8 +1462,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) if (hup && dh.hits < 1) { /* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */ - switch_event_t *s_event; - + if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name); @@ -1471,10 +1470,9 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", euser, host); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence"); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); - switch_event_fire(&s_event); } } - + if (!zstr((char *) helper.stream.data)) { char *this_sql = (char *) helper.stream.data; @@ -1509,11 +1507,24 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) switch_safe_free(sql); switch_safe_free(user); + + return s_event; } static int EVENT_THREAD_RUNNING = 0; static int EVENT_THREAD_STARTED = 0; +static void do_flush(void) +{ + void *pop = NULL; + + while (mod_sofia_globals.presence_queue && switch_queue_trypop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { + switch_event_t *event = (switch_event_t *) pop; + switch_event_destroy(&event); + } + +} + void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread, void *obj) { void *pop; @@ -1544,6 +1555,15 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread break; } + if (mod_sofia_globals.presence_flush) { + switch_mutex_lock(mod_sofia_globals.mutex); + if (mod_sofia_globals.presence_flush) { + do_flush(); + mod_sofia_globals.presence_flush = 0; + } + switch_mutex_unlock(mod_sofia_globals.mutex); + } + switch(event->event_id) { case SWITCH_EVENT_MESSAGE_WAITING: actual_sofia_presence_mwi_event_handler(event); @@ -1552,7 +1572,11 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread conference_data_event_handler(event); break; default: - actual_sofia_presence_event_handler(event); + do { + switch_event_t *ievent = event; + event = actual_sofia_presence_event_handler(ievent); + switch_event_destroy(&ievent); + } while (event); break; } @@ -1561,10 +1585,7 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread } } - while (switch_queue_trypop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { - switch_event_t *event = (switch_event_t *) pop; - switch_event_destroy(&event); - } + do_flush(); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Ended\n"); @@ -1606,13 +1627,23 @@ void sofia_presence_event_handler(switch_event_t *event) { switch_event_t *cloned_event; - switch_event_dup(&cloned_event, event); - switch_assert(cloned_event); - switch_queue_push(mod_sofia_globals.presence_queue, cloned_event); - if (!EVENT_THREAD_STARTED) { sofia_presence_event_thread_start(); + switch_yield(500000); } + + switch_event_dup(&cloned_event, event); + switch_assert(cloned_event); + + if (switch_queue_trypush(mod_sofia_globals.presence_queue, cloned_event) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Presence queue overloaded.... Flushing queue\n"); + switch_mutex_lock(mod_sofia_globals.mutex); + mod_sofia_globals.presence_flush = 1; + switch_mutex_unlock(mod_sofia_globals.mutex); + switch_event_destroy(&cloned_event); + } + + } @@ -1640,7 +1671,7 @@ static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, ch } - switch_event_fire(&event); + sofia_event_fire(profile, &event); } return 0; } @@ -1653,7 +1684,7 @@ static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, ch switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "expires", expires); - switch_event_fire(&event); + sofia_event_fire(profile, &event); } return 0; @@ -1777,7 +1808,7 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char } } - switch_event_fire(&event); + sofia_event_fire(profile, &event); } switch_safe_free(free_me); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 3e0e3965fe..4efa9fabe6 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -635,7 +635,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", argv[3]); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "expires", argv[6]); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", argv[7]); - switch_event_fire(&s_event); + sofia_event_fire(profile, &s_event); } if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { @@ -653,7 +653,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Unregistered"); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence"); - switch_event_fire(&s_event); + sofia_event_fire(profile, &s_event); } } @@ -859,7 +859,6 @@ void sofia_reg_check_sync(sofia_profile_t *profile) sql = switch_mprintf("delete from sip_registrations where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - sql = switch_mprintf("delete from sip_presence where expires > 0 and hostname='%q'", mod_sofia_globals.hostname); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); 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 f970a1c63e..f1dc5874e8 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 @@ -175,13 +175,8 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l if (switch_queue_trypush(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) { if (l->lost_logs) { int ll = l->lost_logs; - switch_event_t *event; l->lost_logs = 0; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Lost %d log lines!\n", ll); - if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "info", "lost %d log lines", ll); - switch_event_fire(&event); - } } } else { switch_log_node_free(&dnode); @@ -378,11 +373,6 @@ static void event_handler(switch_event_t *event) int le = l->lost_events; l->lost_events = 0; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(l->session), SWITCH_LOG_CRIT, "Lost %d events!\n", le); - clone = NULL; - if (switch_event_create(&clone, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(clone, SWITCH_STACK_BOTTOM, "info", "lost %d events", le); - switch_event_fire(&clone); - } } } else { if (++l->lost_events > MAX_MISSED) { diff --git a/src/switch_event.c b/src/switch_event.c index 566ccc82f8..e589e02f43 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -472,7 +472,6 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping dispatch queues\n"); - for(x = 0; x < (uint32_t)DISPATCH_THREAD_COUNT; x++) { switch_queue_trypush(EVENT_DISPATCH_QUEUE, NULL); } @@ -487,8 +486,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) } x = 0; - while (x < 10000 && THREAD_COUNT) { - switch_cond_next(); + while (x < 100 && THREAD_COUNT) { + switch_yield(100000); if (THREAD_COUNT == last) { x++; } From 0160072adcc516b53816d8db379ba4bf6862b182 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Wed, 7 Nov 2012 21:35:20 +0000 Subject: [PATCH 377/512] Fix query cancelling so it leaves the handle in a good state; fix detection of broken connections in db_is_up by consuming the EOF on a failed connection before checking if the connection failed; add more detailed logging about who called the SQL function when something goes wrong. --- src/include/switch_pgsql.h | 15 ++++++++++++--- src/switch_pgsql.c | 22 +++++++++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/include/switch_pgsql.h b/src/include/switch_pgsql.h index 282172e646..00da8efffa 100644 --- a/src/include/switch_pgsql.h +++ b/src/include/switch_pgsql.h @@ -106,11 +106,20 @@ SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result); SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char *func, int line, switch_pgsql_handle_t *handle); #define switch_pgsql_finish_results(handle) switch_pgsql_finish_results_real(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle) -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err); +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base_detailed(const char *file, const char *func, int line, + switch_pgsql_handle_t *handle, const char *sql, char **err); +#define switch_pgsql_handle_exec_base(handle, sql, err) switch_pgsql_handle_exec_base_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle, sql, err) SWITCH_DECLARE(switch_pgsql_state_t) switch_pgsql_handle_get_state(switch_pgsql_handle_t *handle); -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec(switch_pgsql_handle_t *handle, const char *sql, char **err); -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err); + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_detailed(const char *file, const char *func, int line, + switch_pgsql_handle_t *handle, const char *sql, char **err); +#define switch_pgsql_handle_exec(handle, sql, err) switch_pgsql_handle_exec_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle, sql, err) + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string_detailed(const char *file, const char *func, int line, + switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err); +#define switch_pgsql_handle_exec_string(handle, sql, resbuf, len, err) switch_pgsql_handle_exec_string_detailed(__FILE__, (char * )__SWITCH_FUNC__, __LINE__, handle, sql, resbuf, len, err) + SWITCH_DECLARE(switch_bool_t) switch_pgsql_available(void); SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLSetAutoCommitAttr(switch_pgsql_handle_t *handle, switch_bool_t on); SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLEndTran(switch_pgsql_handle_t *handle, switch_bool_t commit); diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 9a84b2e3b0..328a5811eb 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -160,6 +160,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, } PQfreeCancel(cancel); #endif + /* Make sure the query is fully cancelled */ + while (PQgetResult(handle->con) != NULL); return ret; } @@ -236,7 +238,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq err_str = switch_pgsql_handle_get_error(handle); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); switch_safe_free(err_str); - switch_pgsql_cancel(handle); + /* switch_pgsql_cancel(handle); */ goto error; } @@ -362,6 +364,9 @@ static int db_is_up(switch_pgsql_handle_t *handle) goto done; } + /* Try a non-blocking read on the connection to gobble up any EOF from a closed connection and mark the connection BAD if it is closed. */ + PQconsumeInput(handle->con); + if (PQstatus(handle->con) == CONNECTION_BAD) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n"); handle->state = SWITCH_PGSQL_STATE_ERROR; @@ -478,7 +483,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_connect(switch_pgsql_h #endif } -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err) +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string_detailed(const char *file, const char *func, int line, + switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err) { #ifdef SWITCH_HAVE_PGSQL switch_pgsql_status_t sstatus = SWITCH_PGSQL_SUCCESS; @@ -487,7 +493,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgs handle->affected_rows = 0; - if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) { + if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) { goto error; } @@ -532,7 +538,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgs #endif } -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err) +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base_detailed(const char *file, const char *func, int line, + switch_pgsql_handle_t *handle, const char *sql, char **err) { #ifdef SWITCH_HAVE_PGSQL char *err_str = NULL, *er = NULL; @@ -583,7 +590,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql if (err_str) { if (!switch_stristr("already exists", err_str) && !switch_stristr("duplicate key name", err_str)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); } if (err) { *err = err_str; @@ -595,10 +602,11 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql return SWITCH_PGSQL_FAIL; } -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec(switch_pgsql_handle_t *handle, const char *sql, char **err) +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_detailed(const char *file, const char *func, int line, + switch_pgsql_handle_t *handle, const char *sql, char **err) { #ifdef SWITCH_HAVE_PGSQL - if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) { + if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) { goto error; } From 6627dc86963b11ab0fca1f04ae6ac7a137581ad1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Nov 2012 14:53:10 -0600 Subject: [PATCH 378/512] fix some contention issues under really high load...That doesn't mean you need to push it this hard and bug me about it =p --- configure.in | 2 +- libs/apr/.update | 2 +- libs/apr/configure.in | 2 +- libs/apr/threadproc/unix/thread.c | 15 ++++++++++---- libs/sofia-sip/.update | 2 +- libs/sofia-sip/configure.ac | 2 +- .../libsofia-sip-ua/su/su_pthread_port.c | 8 ++++++-- src/mod/endpoints/mod_sofia/sofia_glue.c | 20 +++++++++++++++++++ 8 files changed, 42 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index 1283b2a185..821c939399 100644 --- a/configure.in +++ b/configure.in @@ -577,7 +577,7 @@ AX_HAVE_CPU_SET AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])]) AC_CHECK_LIB(rt, clock_getres, [AC_DEFINE(HAVE_CLOCK_GETRES, 1, [Define if you have clock_getres()])]) AC_CHECK_LIB(rt, clock_nanosleep, [AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1, [Define if you have clock_nanosleep()])]) -AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])]) +AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])]) AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket)) diff --git a/libs/apr/.update b/libs/apr/.update index a55ae9a4f4..c106d5b06f 100644 --- a/libs/apr/.update +++ b/libs/apr/.update @@ -1 +1 @@ -Tue Oct 23 13:13:30 EDT 2012 +Wed Nov 7 10:37:54 CST 2012 diff --git a/libs/apr/configure.in b/libs/apr/configure.in index 412ee7e937..354fa772ba 100644 --- a/libs/apr/configure.in +++ b/libs/apr/configure.in @@ -1620,7 +1620,7 @@ APR_CHECK_DEFINE_FILES(POLLIN, poll.h sys/poll.h) if test "$threads" = "1"; then APR_CHECK_DEFINE(PTHREAD_PROCESS_SHARED, pthread.h) AC_CHECK_FUNCS(pthread_mutexattr_setpshared) - AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])]) + AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])]) # Some systems have setpshared and define PROCESS_SHARED, but don't # really support PROCESS_SHARED locks. So, we must validate that we diff --git a/libs/apr/threadproc/unix/thread.c b/libs/apr/threadproc/unix/thread.c index 391e5368c8..8859e79ac7 100644 --- a/libs/apr/threadproc/unix/thread.c +++ b/libs/apr/threadproc/unix/thread.c @@ -146,6 +146,7 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, { apr_status_t stat; pthread_attr_t *temp; + pthread_t tt; (*new) = (apr_thread_t *)apr_pcalloc(pool, sizeof(apr_thread_t)); @@ -173,15 +174,21 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, return stat; } - if ((stat = pthread_create((*new)->td, temp, dummy_worker, (*new))) == 0) { + if ((stat = pthread_create(&tt, temp, dummy_worker, (*new))) == 0) { -#ifdef HAVE_PTHREAD_SETSCHEDPRIO +#ifdef HAVE_PTHREAD_SETSCHEDPARAM if (attr && attr->priority) { - pthread_t *thread = (*new)->td; - pthread_setschedprio(*thread, attr->priority); + int policy; + struct sched_param param = { 0 }; + + pthread_getschedparam(tt, &policy, ¶m); + param.sched_priority = attr->priority; + pthread_setschedparam(tt, policy, ¶m); } #endif + *(*new)->td = tt; + return APR_SUCCESS; } else { diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 09f61c0ed4..5f41229805 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Fri Nov 2 13:36:06 CDT 2012 +Wed Nov 7 10:37:42 CST 2012 diff --git a/libs/sofia-sip/configure.ac b/libs/sofia-sip/configure.ac index 1bce33e178..f882bc76b4 100644 --- a/libs/sofia-sip/configure.ac +++ b/libs/sofia-sip/configure.ac @@ -254,7 +254,7 @@ if test x"$have_check" = "xyes"; then fi AC_CHECK_HEADERS([fnmatch.h]) -AC_CHECK_LIB(pthread, pthread_setschedprio, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPRIO, 1, [Define if you have pthread_setschedprio()])]) +AC_CHECK_LIB(pthread, pthread_setschedparam, [AC_DEFINE(HAVE_PTHREAD_SETSCHEDPARAM, 1, [Define if you have pthread_setschedparam()])]) dnl dl is currently used only in testing diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c index 5eb391f38d..d20eb709bd 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_pthread_port.c @@ -268,9 +268,13 @@ int su_pthreaded_port_start(su_port_create_f *create, pthread_mutex_lock(arg.mutex); if (pthread_create(&tid, &attr, su_pthread_port_clone_main, &arg) == 0) { +#ifdef HAVE_PTHREAD_SETSCHEDPARAM + int policy; + struct sched_param param; -#ifdef HAVE_PTHREAD_SETSCHEDPRIO - pthread_setschedprio(tid, 99); + pthread_getschedparam(tid, &policy, ¶m); + param.sched_priority = 99; + pthread_setschedparam(tid, policy, ¶m); #endif pthread_cond_wait(arg.cv, arg.mutex); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 7e55407962..cf89cba93c 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6532,6 +6532,9 @@ char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex switch_cache_db_release_db_handle(&dbh); + + sofia_glue_fire_events(profile); + return ret; } @@ -7159,6 +7162,23 @@ void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event) *event = NULL; } +void sofia_glue_fire_events(sofia_profile_t *profile) +{ + void *pop = NULL; + + while (profile->event_queue && switch_queue_trypop(profile->event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { + switch_event_t *event = (switch_event_t *) pop; + switch_event_fire(&event); + } + +} + +void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event) +{ + switch_queue_push(profile->event_queue, *event); + *event = NULL; +} + /* For Emacs: * Local Variables: From ba625501ba306700d37bf9f3ab69257183d81264 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Nov 2012 14:53:47 -0600 Subject: [PATCH 379/512] fix a lock logic error in lcr endpoint --- src/mod/applications/mod_lcr/mod_lcr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 55841170a4..5e232d7ad6 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -1318,7 +1318,7 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session, switch_event_t *event = NULL; const char *intrastate = NULL; const char *intralata = NULL; - switch_core_session_t *mysession = NULL; + switch_core_session_t *mysession = NULL, *locked_session = NULL; switch_channel_t *channel = NULL; dest = strdup(outbound_profile->destination_number); @@ -1362,7 +1362,7 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session, } else if (var_event) { char *session_uuid = switch_event_get_header(var_event, "ent_originate_aleg_uuid"); if (session_uuid) { - mysession = switch_core_session_locate(session_uuid); + mysession = locked_session = switch_core_session_locate(session_uuid); } cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name"); cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number"); @@ -1464,8 +1464,8 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session, if (event) { switch_event_destroy(&event); } - if (mysession) { - switch_core_session_rwunlock(mysession); + if (locked_session) { + switch_core_session_rwunlock(locked_session); } lcr_destroy(routes.head); switch_core_destroy_memory_pool(&pool); From 6814014f7d077a961ca633a5bc0a70377e22b8be Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Nov 2012 14:57:08 -0600 Subject: [PATCH 380/512] bad merge --- src/mod/endpoints/mod_sofia/sofia_glue.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index cf89cba93c..74096a3173 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -7162,23 +7162,6 @@ void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event) *event = NULL; } -void sofia_glue_fire_events(sofia_profile_t *profile) -{ - void *pop = NULL; - - while (profile->event_queue && switch_queue_trypop(profile->event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { - switch_event_t *event = (switch_event_t *) pop; - switch_event_fire(&event); - } - -} - -void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event) -{ - switch_queue_push(profile->event_queue, *event); - *event = NULL; -} - /* For Emacs: * Local Variables: From bfe3fdf347a79ae99a7e5a7bfcec1292b1b13eba Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Nov 2012 16:46:30 -0600 Subject: [PATCH 381/512] regression from 0160072adcc516b53816d8db379ba4bf6862b182 code was outside of code block --- src/switch_pgsql.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 328a5811eb..5a0ca21809 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -159,9 +159,12 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, ret = SWITCH_PGSQL_FAIL; } PQfreeCancel(cancel); -#endif + /* Make sure the query is fully cancelled */ while (PQgetResult(handle->con) != NULL); + +#endif + return ret; } From 2cea7f0ff6b8fccfee70d7cf0efdadbe000ddbaf Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 7 Nov 2012 17:47:39 -0800 Subject: [PATCH 382/512] Enable mod_lua to use native pgsql dbh support --- src/mod/languages/mod_lua/freeswitch_lua.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 679c9fbee4..32c01225bd 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -342,6 +342,12 @@ Dbh::Dbh(char *dsn, char *user, char *pass) if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) == SWITCH_STATUS_SUCCESS) { m_connected = true; } + } else if (!strncasecmp(dsn, "pgsql://", 8)) { + type = SCDB_TYPE_PGSQL; + options.pgsql_options.dsn = (char *)(dsn + 8); + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_PGSQL, &options) == SWITCH_STATUS_SUCCESS) { + m_connected = true; + } } else { options.odbc_options.dsn = dsn; options.odbc_options.user = user; From 48a0924b5470c0689896b4f315f7584755b188ab Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 7 Nov 2012 18:04:13 -0800 Subject: [PATCH 383/512] merge failure on my part. this should have been included. --- src/mod/languages/mod_lua/freeswitch_lua.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 32c01225bd..811a8a7bd6 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -335,6 +335,7 @@ Dbh::Dbh(char *dsn, char *user, char *pass) { switch_cache_db_connection_options_t options = { {0} }; const char *prefix = "core:"; + switch_cache_db_handle_type_t type; m_connected = false; if (strstr(dsn, prefix) == dsn) { From e8f3e42f8b7dbdad51c37a087602bb34469d8efe Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 8 Nov 2012 09:52:20 -0600 Subject: [PATCH 384/512] FS-4779 try this patch --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 5f41229805..dbb9bc2ccd 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Nov 7 10:37:42 CST 2012 +Thu Nov 8 09:48:11 CST 2012 diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index 3316d535c3..9b862415a3 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -1245,6 +1245,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags) int status = 200; char const *phrase = "OK", *reason = NULL; char const *invite_branch; + char const *pl_s = NULL; assert(cr->cr_orq); assert(cr->cr_method == sip_method_invite); @@ -1256,6 +1257,11 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags) goto error; } + tl_gets(tags, + SIPTAG_PAYLOAD_STR_REF(pl_s), + TAG_END()); + + assert(ds->ds_leg); msg = nta_outgoing_getrequest(cr->cr_orq); @@ -1305,7 +1311,7 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags) while (sip->sip_supported) sip_header_remove(msg, sip, (sip_header_t*)sip->sip_supported); - if (ss == NULL || ss->ss_state > nua_callstate_ready) + if (ss == NULL || ss->ss_state > nua_callstate_ready || pl_s) ; else if (cr->cr_offer_recv && !cr->cr_answer_sent) { if (nh->nh_soa == NULL) { From 1e929e723f04dc52c11bbfc45203c7e301b77841 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Thu, 8 Nov 2012 18:40:30 +0000 Subject: [PATCH 385/512] More fixes for reconnecting to PGSQL on connection failure. --- src/switch_pgsql.c | 526 ++++++++++++++++++++++++--------------------- 1 file changed, 277 insertions(+), 249 deletions(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 5a0ca21809..4264f86e91 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -43,7 +43,7 @@ struct switch_pgsql_handle { char *dsn; - const char *sql; + char *sql; PGconn* con; int sock; switch_pgsql_state_t state; @@ -96,250 +96,6 @@ SWITCH_DECLARE(switch_pgsql_handle_t *) switch_pgsql_handle_new(const char *dsn) return NULL; } -SWITCH_DECLARE(void) switch_pgsql_set_num_retries(switch_pgsql_handle_t *handle, int num_retries) -{ -#ifdef SWITCH_HAVE_PGSQL - if (handle) { - handle->num_retries = num_retries; - } -#endif -} - -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_disconnect(switch_pgsql_handle_t *handle) -{ -#ifdef SWITCH_HAVE_PGSQL - - if (!handle) { - return SWITCH_PGSQL_FAIL; - } - - if (handle->state == SWITCH_PGSQL_STATE_CONNECTED) { - PQfinish(handle->con); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Disconnected from [%s]\n", handle->dsn); - } - - handle->state = SWITCH_PGSQL_STATE_DOWN; - - return SWITCH_PGSQL_SUCCESS; -#else - return SWITCH_PGSQL_FAIL; -#endif -} - -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handle_t *handle, const char* sql) -{ -#ifdef SWITCH_HAVE_PGSQL - char *err_str; - - if (!PQsendQuery(handle->con, sql)) { - err_str = switch_pgsql_handle_get_error(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str); - switch_pgsql_finish_results(handle); - goto error; - } - handle->sql = sql; - - return SWITCH_PGSQL_SUCCESS; - error: -#endif - return SWITCH_PGSQL_FAIL; -} - -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, const char *func, int line, switch_pgsql_handle_t *handle) -{ - switch_pgsql_status_t ret = SWITCH_PGSQL_SUCCESS; -#ifdef SWITCH_HAVE_PGSQL - char err_buf[256]; - PGcancel *cancel = NULL; - - memset(err_buf, 0, 256); - cancel = PQgetCancel(handle->con); - if(!PQcancel(cancel, err_buf, 256)) { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CRIT, "Failed to cancel long-running query (%s): %s\n", handle->sql, err_buf); - ret = SWITCH_PGSQL_FAIL; - } - PQfreeCancel(cancel); - - /* Make sure the query is fully cancelled */ - while (PQgetResult(handle->con) != NULL); - -#endif - - return ret; -} - - -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec) -{ -#ifdef SWITCH_HAVE_PGSQL - switch_pgsql_result_t *res; - switch_time_t start; - switch_time_t ctime; - unsigned int usec = msec * 1000; - char *err_str; - struct pollfd fds[2] = { {0} }; - int poll_res = 0; - - if(!handle) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n"); - return SWITCH_PGSQL_FAIL; - } - - /* Try to consume input that might be waiting right away */ - if (PQconsumeInput(handle->con)) { - /* And check to see if we have a full result ready for reading */ - if (PQisBusy(handle->con)) { - - /* Wait for a result to become available, up to msec milliseconds */ - start = switch_time_now(); - while((ctime = switch_micro_time_now()) - start <= usec) { - int wait_time = (usec - (ctime - start)) / 1000; - fds[0].fd = handle->sock; - fds[0].events |= POLLIN; - fds[0].events |= POLLERR; - - /* Wait for the PostgreSQL socket to be ready for data reads. */ - if ((poll_res = poll(&fds[0], 1, wait_time)) > -1 ) { - if (fds[0].revents & POLLIN) { - /* Then try to consume any input waiting. */ - if (PQconsumeInput(handle->con)) { - /* And check to see if we have a full result ready for reading */ - if (!PQisBusy(handle->con)) { - /* If we can pull a full result without blocking, then break this loop */ - break; - } - } else { - /* If we had an error trying to consume input, report it and cancel the query. */ - err_str = switch_pgsql_handle_get_error(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); - switch_safe_free(err_str); - switch_pgsql_cancel(handle); - goto error; - } - } else if (fds[0].revents & POLLERR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql); - goto error; - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql); - goto error; - } - } - - /* If we broke the loop above because of a timeout, report that and cancel the query. */ - if (ctime - start > usec) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql); - switch_pgsql_cancel(handle); - goto error; - } - - - - } - } else { - /* If we had an error trying to consume input, report it and cancel the query. */ - err_str = switch_pgsql_handle_get_error(handle); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); - switch_safe_free(err_str); - /* switch_pgsql_cancel(handle); */ - goto error; - } - - - /* At this point, we know we can read a full result without blocking. */ - if(!(res = malloc(sizeof(switch_pgsql_result_t)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Malloc failed!\n"); - goto error; - } - memset(res, 0, sizeof(switch_pgsql_result_t)); - - - res->result = PQgetResult(handle->con); - if (res->result) { - *result_out = res; - res->status = PQresultStatus(res->result); - switch(res->status) { -#if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 2 - case PGRES_SINGLE_TUPLE: - /* Added in PostgreSQL 9.2 */ -#endif - case PGRES_TUPLES_OK: - { - res->rows = PQntuples(res->result); - handle->affected_rows = res->rows; - res->cols = PQnfields(res->result); - } - break; -#if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 1 - case PGRES_COPY_BOTH: - /* Added in PostgreSQL 9.1 */ -#endif - case PGRES_COPY_OUT: - case PGRES_COPY_IN: - case PGRES_COMMAND_OK: - break; - case PGRES_EMPTY_QUERY: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_EMPTY_QUERY\n", handle->sql); - case PGRES_BAD_RESPONSE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_BAD_RESPONSE\n", handle->sql); - case PGRES_NONFATAL_ERROR: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_NONFATAL_ERROR\n", handle->sql); - case PGRES_FATAL_ERROR: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_FATAL_ERROR\n", handle->sql); - res->err = PQresultErrorMessage(res->result); - goto error; - break; - } - } else { - free(res); - res = NULL; - *result_out = NULL; - } - - return SWITCH_PGSQL_SUCCESS; - error: -#endif - return SWITCH_PGSQL_FAIL; -} - -SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result) -{ -#ifdef SWITCH_HAVE_PGSQL - - if (!*result) { - return; - } - - if ((*result)->result) { - PQclear((*result)->result); - } - free(*result); - *result = NULL; -#else - return; -#endif -} - -SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char* func, int line, switch_pgsql_handle_t *handle) -{ -#ifdef SWITCH_HAVE_PGSQL - switch_pgsql_result_t *res = NULL; - switch_pgsql_status_t final_status = SWITCH_PGSQL_SUCCESS; - int done = 0; - do { - switch_pgsql_next_result(handle, &res); - if (res && res->err) { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error executing query:\n%s\n", res->err); - final_status = SWITCH_PGSQL_FAIL; - } - if (!res) done = 1; - switch_pgsql_free_result(&res); - } while (!done); - return final_status; -#else - return SWITCH_PGSQL_FAIL; -#endif -} #ifdef SWITCH_HAVE_PGSQL static int db_is_up(switch_pgsql_handle_t *handle) @@ -367,8 +123,8 @@ static int db_is_up(switch_pgsql_handle_t *handle) goto done; } - /* Try a non-blocking read on the connection to gobble up any EOF from a closed connection and mark the connection BAD if it is closed. */ - PQconsumeInput(handle->con); + /* Try a non-blocking read on the connection to gobble up any EOF from a closed connection and mark the connection BAD if it is closed. */ + PQconsumeInput(handle->con); if (PQstatus(handle->con) == CONNECTION_BAD) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n"); @@ -454,6 +210,273 @@ static int db_is_up(switch_pgsql_handle_t *handle) #endif +SWITCH_DECLARE(void) switch_pgsql_set_num_retries(switch_pgsql_handle_t *handle, int num_retries) +{ +#ifdef SWITCH_HAVE_PGSQL + if (handle) { + handle->num_retries = num_retries; + } +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_disconnect(switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + + if (!handle) { + return SWITCH_PGSQL_FAIL; + } + + if (handle->state == SWITCH_PGSQL_STATE_CONNECTED) { + PQfinish(handle->con); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Disconnected from [%s]\n", handle->dsn); + } + switch_safe_free(handle->sql); + handle->state = SWITCH_PGSQL_STATE_DOWN; + + return SWITCH_PGSQL_SUCCESS; +#else + return SWITCH_PGSQL_FAIL; +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handle_t *handle, const char* sql) +{ +#ifdef SWITCH_HAVE_PGSQL + char *err_str; + + switch_safe_free(handle->sql); + handle->sql = strdup(sql); + if (!PQsendQuery(handle->con, sql)) { + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str); + switch_pgsql_finish_results(handle); + goto error; + } + + return SWITCH_PGSQL_SUCCESS; + error: +#endif + return SWITCH_PGSQL_FAIL; +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, const char *func, int line, switch_pgsql_handle_t *handle) +{ + switch_pgsql_status_t ret = SWITCH_PGSQL_SUCCESS; +#ifdef SWITCH_HAVE_PGSQL + char err_buf[256]; + PGcancel *cancel = NULL; + + memset(err_buf, 0, 256); + cancel = PQgetCancel(handle->con); + if(!PQcancel(cancel, err_buf, 256)) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CRIT, "Failed to cancel long-running query (%s): %s\n", handle->sql, err_buf); + ret = SWITCH_PGSQL_FAIL; + } + PQfreeCancel(cancel); + { + PGresult *tmp = NULL; + /* Make sure the query is fully cancelled */ + while ((tmp = PQgetResult(handle->con)) != NULL) PQclear(tmp); + } +#endif + return ret; +} + + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec) +{ +#ifdef SWITCH_HAVE_PGSQL + switch_pgsql_result_t *res; + switch_time_t start; + switch_time_t ctime; + unsigned int usec = msec * 1000; + char *err_str; + struct pollfd fds[2] = { {0} }; + int poll_res = 0; + + if(!handle) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n"); + return SWITCH_PGSQL_FAIL; + } + + /* Try to consume input that might be waiting right away */ + if (PQconsumeInput(handle->con)) { + /* And check to see if we have a full result ready for reading */ + if (PQisBusy(handle->con)) { + + /* Wait for a result to become available, up to msec milliseconds */ + start = switch_time_now(); + while((ctime = switch_micro_time_now()) - start <= usec) { + int wait_time = (usec - (ctime - start)) / 1000; + fds[0].fd = handle->sock; + fds[0].events |= POLLIN; + fds[0].events |= POLLERR; + fds[0].events |= POLLNVAL; + fds[0].events |= POLLHUP; + fds[0].events |= POLLPRI; + fds[0].events |= POLLRDNORM; + fds[0].events |= POLLRDBAND; + + /* Wait for the PostgreSQL socket to be ready for data reads. */ + if ((poll_res = poll(&fds[0], 1, wait_time)) > 0 ) { + if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql); + goto error; + } else if (fds[0].revents & POLLERR) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql); + goto error; + } else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) { + /* Then try to consume any input waiting. */ + if (PQconsumeInput(handle->con)) { + if (PQstatus(handle->con) == CONNECTION_BAD) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n"); + handle->state = SWITCH_PGSQL_STATE_ERROR; + goto error; + } + + /* And check to see if we have a full result ready for reading */ + if (!PQisBusy(handle->con)) { + /* If we can pull a full result without blocking, then break this loop */ + break; + } + } else { + /* If we had an error trying to consume input, report it and cancel the query. */ + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); + switch_safe_free(err_str); + switch_pgsql_cancel(handle); + goto error; + } + } + } else if (poll_res == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql); + goto error; + } + } + + /* If we broke the loop above because of a timeout, report that and cancel the query. */ + if (ctime - start > usec) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql); + switch_pgsql_cancel(handle); + goto error; + } + + } + } else { + /* If we had an error trying to consume input, report it and cancel the query. */ + err_str = switch_pgsql_handle_get_error(handle); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str); + switch_safe_free(err_str); + /* switch_pgsql_cancel(handle); */ + goto error; + } + + + /* At this point, we know we can read a full result without blocking. */ + if(!(res = malloc(sizeof(switch_pgsql_result_t)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Malloc failed!\n"); + goto error; + } + memset(res, 0, sizeof(switch_pgsql_result_t)); + + + res->result = PQgetResult(handle->con); + if (res->result) { + *result_out = res; + res->status = PQresultStatus(res->result); + switch(res->status) { +#if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 2 + case PGRES_SINGLE_TUPLE: + /* Added in PostgreSQL 9.2 */ +#endif + case PGRES_TUPLES_OK: + { + res->rows = PQntuples(res->result); + handle->affected_rows = res->rows; + res->cols = PQnfields(res->result); + } + break; +#if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 1 + case PGRES_COPY_BOTH: + /* Added in PostgreSQL 9.1 */ +#endif + case PGRES_COPY_OUT: + case PGRES_COPY_IN: + case PGRES_COMMAND_OK: + break; + case PGRES_EMPTY_QUERY: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_EMPTY_QUERY\n", handle->sql); + case PGRES_BAD_RESPONSE: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_BAD_RESPONSE\n", handle->sql); + case PGRES_NONFATAL_ERROR: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_NONFATAL_ERROR\n", handle->sql); + case PGRES_FATAL_ERROR: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_FATAL_ERROR\n", handle->sql); + res->err = PQresultErrorMessage(res->result); + goto error; + break; + } + } else { + free(res); + res = NULL; + *result_out = NULL; + } + + return SWITCH_PGSQL_SUCCESS; + error: + { + PGresult *tmp = NULL; + /* Make sure the failed connection does not have any transactions marked as in progress */ + while ((tmp = PQgetResult(handle->con)) != NULL) PQclear(tmp); + + /* Try to reconnect to the DB if we were dropped */ + db_is_up(handle); + } +#endif + return SWITCH_PGSQL_FAIL; +} + +SWITCH_DECLARE(void) switch_pgsql_free_result(switch_pgsql_result_t **result) +{ +#ifdef SWITCH_HAVE_PGSQL + + if (!*result) { + return; + } + + if ((*result)->result) { + PQclear((*result)->result); + } + free(*result); + *result = NULL; +#else + return; +#endif +} + +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char* func, int line, switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + switch_pgsql_result_t *res = NULL; + switch_pgsql_status_t final_status = SWITCH_PGSQL_SUCCESS; + int done = 0; + do { + switch_pgsql_next_result(handle, &res); + if (res && res->err) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error executing query:\n%s\n", res->err); + final_status = SWITCH_PGSQL_FAIL; + } + if (!res) done = 1; + switch_pgsql_free_result(&res); + } while (!done); + return final_status; +#else + return SWITCH_PGSQL_FAIL; +#endif +} + + SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_connect(switch_pgsql_handle_t *handle) { #ifdef SWITCH_HAVE_PGSQL @@ -557,11 +580,14 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base_detailed(con if (handle->auto_commit == SWITCH_FALSE && handle->in_txn == SWITCH_FALSE) { if (switch_pgsql_send_query(handle, "BEGIN") != SWITCH_PGSQL_SUCCESS) { er = strdup("Error sending BEGIN!"); - switch_pgsql_finish_results(handle); + if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { + db_is_up(handle); /* If finish_results failed, maybe the db went dead */ + } goto error; } if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { + db_is_up(handle); er = strdup("Error sending BEGIN!"); goto error; } @@ -570,7 +596,9 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base_detailed(con if (switch_pgsql_send_query(handle, sql) != SWITCH_PGSQL_SUCCESS) { er = strdup("Error sending query!"); - switch_pgsql_finish_results(handle); + if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { + db_is_up(handle); + } goto error; } From fec1046db2e464e1b543458b3d4c3a9da365966a Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 8 Nov 2012 12:54:57 -0600 Subject: [PATCH 386/512] FS-4807 clear up an example for people that don't want to bother with learning how things work --- conf/vanilla/dialplan/default.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/conf/vanilla/dialplan/default.xml b/conf/vanilla/dialplan/default.xml index 82189d6633..7f5002152f 100644 --- a/conf/vanilla/dialplan/default.xml +++ b/conf/vanilla/dialplan/default.xml @@ -141,6 +141,18 @@ + + + + + + + + + From 302c323a8f2602033cc466bd48c8e317cff5a6d1 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Thu, 8 Nov 2012 19:49:08 +0000 Subject: [PATCH 387/512] Update PGSQL socket descriptor on reconnect in case a new descriptor was assigned. --- src/switch_pgsql.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 4264f86e91..f326305657 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -135,6 +135,7 @@ static int db_is_up(switch_pgsql_handle_t *handle) goto error; } handle->state = SWITCH_PGSQL_STATE_CONNECTED; + handle->sock = PQsocket(handle->con); } /* if (!PQsendQuery(handle->con, "SELECT 1")) { @@ -167,6 +168,7 @@ static int db_is_up(switch_pgsql_handle_t *handle) if (PQstatus(handle->con) == CONNECTION_OK) { handle->state = SWITCH_PGSQL_STATE_CONNECTED; recon = SWITCH_PGSQL_SUCCESS; + handle->sock = PQsocket(handle->con); } } From 6591eb14974ae748cb519c4c2febe0cd696b0422 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 8 Nov 2012 12:35:45 -0600 Subject: [PATCH 388/512] fix mod_db regex --- src/mod/applications/mod_db/mod_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index fd077b14ff..9c1f9310d1 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -271,7 +271,7 @@ SWITCH_LIMIT_STATUS(limit_status_db) /* INIT / Config */ -static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "^pgsql;|[^:]+:[^:]+:.+" }; +static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "^pgsql|^odbc|^sqlite|[^:]+:[^:]+:.+" }; static switch_xml_config_item_t config_settings[] = { SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn, From b39a2cbb8b5ea785b7737067f1f27bb4ae033e1f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 8 Nov 2012 14:13:05 -0600 Subject: [PATCH 389/512] put running_state in the channel event rather than the state so presence events reflect the current state of the channel and not the one that was possibly changed during the last state --- src/switch_channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 5ccca55184..9e40829f82 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2254,7 +2254,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann originatee_caller_profile = caller_profile->originatee_caller_profile; } - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(channel->state)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(channel->running_state)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", switch_channel_callstate2str(channel->callstate)); switch_snprintf(state_num, sizeof(state_num), "%d", channel->state); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", state_num); From 2fa045cf370c7ada95cc5e0f23b1024dd30580e6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 8 Nov 2012 16:47:01 -0600 Subject: [PATCH 390/512] FS-4784 --resolve this should have the same effect --- .../applications/mod_cidlookup/mod_cidlookup.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/mod/applications/mod_cidlookup/mod_cidlookup.c b/src/mod/applications/mod_cidlookup/mod_cidlookup.c index 3844acb342..411ea376a1 100755 --- a/src/mod/applications/mod_cidlookup/mod_cidlookup.c +++ b/src/mod/applications/mod_cidlookup/mod_cidlookup.c @@ -695,6 +695,8 @@ SWITCH_STANDARD_APP(cidlookup_app_function) } if (cid && channel) { + switch_event_t *event; + switch_channel_set_variable(channel, "original_caller_id_name", switch_core_strdup(pool, profile->caller_id_name)); if (!zstr(cid->src)) { switch_channel_set_variable(channel, "cidlookup_source", cid->src); @@ -703,6 +705,19 @@ SWITCH_STANDARD_APP(cidlookup_app_function) switch_channel_set_variable(channel, "cidlookup_area", cid->area); } profile->caller_id_name = switch_core_strdup(profile->pool, cid->name);; + + + if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) { + const char *uuid = switch_channel_get_partner_uuid(channel); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "RECV"); + + if (uuid) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid); + } + switch_channel_event_set_data(channel, event); + switch_event_fire(&event); + } + } From af9d10921287e99de7eb06476825232ab67b9429 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 9 Nov 2012 09:26:48 -0500 Subject: [PATCH 391/512] FS-4818: --resolve use portable sed construct even though this script is not intended to be called on any platform where this matters --- scripts/ci/common.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/ci/common.sh b/scripts/ci/common.sh index 059def200e..a1e97c6064 100755 --- a/scripts/ci/common.sh +++ b/scripts/ci/common.sh @@ -103,14 +103,16 @@ set_fs_ver () { -e "s|\(AC_SUBST(SWITCH_VERSION_MINOR, \[\).*\(\])\)|\1$minor\2|" \ -e "s|\(AC_SUBST(SWITCH_VERSION_MICRO, \[\).*\(\])\)|\1$micro\2|" \ -e "s|\(AC_INIT(\[freeswitch\], \[\).*\(\], BUG-REPORT-ADDRESS)\)|\1$ver\2|" \ - -i configure.in + configure.in > configure.in.$$ + mv configure.in.$$ configure.in if [ -n "$rev" ]; then [ -n "$hrev" ] || hrev="$rev" sed -e "s|\(AC_SUBST(SWITCH_VERSION_REVISION, \[\).*\(\])\)|\1$rev\2|" \ -e "s|\(AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, \[\).*\(\])\)|\1$hrev\2|" \ -e "s|#\(AC_SUBST(SWITCH_VERSION_REVISION\)|\1|" \ -e "s|#\(AC_SUBST(SWITCH_VERSION_REVISION_HUMAN\)|\1|" \ - -i configure.in + configure.in > configure.in.$$ + mv configure.in.$$ configure.in fi } From db20df23004ce949cb3e85460832561b4b0aa854 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 9 Nov 2012 09:27:47 -0500 Subject: [PATCH 392/512] FS-4817: --resolve netbsd portability fixes --- libs/libedit/src/unvis.c | 2 +- libs/libedit/src/vi.c | 4 ++-- libs/libedit/src/vis.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/libedit/src/unvis.c b/libs/libedit/src/unvis.c index 5b22184c9c..3d71f6f227 100644 --- a/libs/libedit/src/unvis.c +++ b/libs/libedit/src/unvis.c @@ -45,7 +45,7 @@ __RCSID("$NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $"); #include #include -#if defined(__weak_reference) && !defined(__FreeBSD__) +#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__) __weak_alias(strunvis,_strunvis) #endif diff --git a/libs/libedit/src/vi.c b/libs/libedit/src/vi.c index bb408d329c..f09ba6c1ce 100644 --- a/libs/libedit/src/vi.c +++ b/libs/libedit/src/vi.c @@ -915,14 +915,14 @@ vi_comment_out(EditLine *el, int c) * NB: posix implies that we should enter insert mode, however * this is against historical precedent... */ -#if defined(__weak_reference) && !defined(__FreeBSD__) +#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__) extern char *get_alias_text(const char *) __weak_reference(get_alias_text); #endif protected el_action_t /*ARGSUSED*/ vi_alias(EditLine *el, int c) { -#if defined(__weak_reference) && !defined(__FreeBSD__) +#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__) char alias_name[3]; char *alias_text; diff --git a/libs/libedit/src/vis.c b/libs/libedit/src/vis.c index b37f7141e3..673caa9a15 100644 --- a/libs/libedit/src/vis.c +++ b/libs/libedit/src/vis.c @@ -88,7 +88,7 @@ __RCSID("$NetBSD: vis.c,v 1.35 2006/08/28 20:42:12 christos Exp $"); #include #include -#if defined(__weak_reference) && !defined(__FreeBSD__) +#if defined(__weak_reference) && !defined(__FreeBSD__) && !defined(__NetBSD__) __weak_alias(strsvis,_strsvis) __weak_alias(strsvisx,_strsvisx) __weak_alias(strvis,_strvis) From d25bde067d14594f9bea4efaf6e154d7f5bbef8e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 9 Nov 2012 08:47:30 -0600 Subject: [PATCH 393/512] FS-4816 --resolve --- src/switch_core_sqldb.c | 73 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 7fa478815e..17a3f3b0f8 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2957,6 +2957,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ case SCDB_TYPE_ODBC: { char *err; + int result = 0; + switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); @@ -2973,12 +2975,72 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_cache_db_test_reactive(sql_manager.dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); - if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { - switch_cache_db_execute_sql(sql_manager.dbh, "begin;delete from channels where hostname='';delete from channels where hostname='';commit;", &err); - } else { - switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname='';delete from channels where hostname='';", &err); + + switch(sql_manager.dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql_real(sql_manager.dbh, "BEGIN", &err); + } + break; + case SCDB_TYPE_ODBC: + { + switch_odbc_status_t result; + + if ((result = switch_odbc_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.odbc_dbh, 0)) != SWITCH_ODBC_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); + err = strdup(tmp); + } + } + break; + case SCDB_TYPE_PGSQL: + { + switch_pgsql_status_t result; + + if ((result = switch_pgsql_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.pgsql_dbh, 0)) != SWITCH_PGSQL_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to Set AutoCommit Off", result); + err = strdup(tmp); + } + } + break; + } + + switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname=''", &err); + if (!err) { + switch_cache_db_execute_sql(sql_manager.dbh, "delete from channels where hostname=''", &err); + + switch(sql_manager.dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_cache_db_execute_sql_real(sql_manager.dbh, "COMMIT", &err); + } + break; + case SCDB_TYPE_ODBC: + { + if (switch_odbc_SQLEndTran(sql_manager.dbh->native_handle.odbc_dbh, 1) != SWITCH_ODBC_SUCCESS || + switch_odbc_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.odbc_dbh, 1) != SWITCH_ODBC_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction.", result); + err = strdup(tmp); + } + } + break; + case SCDB_TYPE_PGSQL: + { + if (switch_pgsql_SQLEndTran(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS || + switch_pgsql_SQLSetAutoCommitAttr(sql_manager.dbh->native_handle.pgsql_dbh, 1) != SWITCH_PGSQL_SUCCESS || + switch_pgsql_finish_results(sql_manager.dbh->native_handle.pgsql_dbh) != SWITCH_PGSQL_SUCCESS) { + char tmp[100]; + switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to commit transaction.", result); + err = strdup(tmp); + } + } + break; + } } + if (err) { runtime.odbc_dsn = NULL; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Transactions not supported on your DB, disabling non-SQLite support; using SQLite\n"); @@ -3069,6 +3131,9 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); } + + switch_cache_db_release_db_handle(&sql_manager.dbh); + return SWITCH_STATUS_SUCCESS; } From 36a2fb092d27ee70c2c403b46b4191d0a7af9a3b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 9 Nov 2012 11:14:41 -0600 Subject: [PATCH 394/512] release FreeSWITCH 1.3.3 --- build/next-release.txt | 2 +- configure.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/next-release.txt b/build/next-release.txt index 996f71d3b9..d0149fef74 100644 --- a/build/next-release.txt +++ b/build/next-release.txt @@ -1 +1 @@ -1.2-rc3 +1.3.4 diff --git a/configure.in b/configure.in index 821c939399..992e712e22 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_INIT([freeswitch], [1.3.2], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [2]) +AC_SUBST(SWITCH_VERSION_MICRO, [3]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 52cbe33ffbaf1247158b499d7ae2d9181799c107 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 9 Nov 2012 11:28:22 -0600 Subject: [PATCH 397/512] update --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 992e712e22..d10fbd6fc3 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.2], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.3], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) AC_SUBST(SWITCH_VERSION_MICRO, [3]) From 1c71b9fc21ff98596d2870a8c290ca492e6bcd64 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 9 Nov 2012 11:50:11 -0600 Subject: [PATCH 398/512] increment version --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index d10fbd6fc3..63d7c575a8 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.3], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.4b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [3]) +AC_SUBST(SWITCH_VERSION_MICRO, [4b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 9bc3dfc8745e8cd99b02ff35afbc55cf1317023b Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 9 Nov 2012 16:53:39 -0500 Subject: [PATCH 399/512] fretdm: little white lie --- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 363dcee7c5..ac3fcf2417 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -858,6 +858,12 @@ static FIO_COMMAND_FUNCTION(zt_command) err = ioctl(ftdmchan->sockfd, codes.FLUSH, &flushmode); } break; + case FTDM_COMMAND_SET_RX_QUEUE_SIZE: + case FTDM_COMMAND_SET_TX_QUEUE_SIZE: + /* little white lie ... eventually we can implement this, in the meantime, not worth the effort + and this is only used by some sig modules such as ftmod_r2 to behave bettter under load */ + err = 0; + break; default: err = FTDM_NOTIMPL; break; From 26b10fcc01d367e652714cf98401e174ba827014 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sun, 11 Nov 2012 14:23:27 +0800 Subject: [PATCH 400/512] FS-3960 update and apply patch --- src/mod/formats/mod_shout/mod_shout.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 740d8a86cb..6d00f7ab38 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -1161,6 +1161,8 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames) char title_b4[128] = ""; char title_aft[128 * 3 + 1] = ""; char *mp3, *m3u; + int uri_offset = 1; + const char *uuid = argv[0]; const char *created = argv[1]; const char *cid_name = argv[2]; @@ -1178,8 +1180,10 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames) snprintf(title_b4, sizeof(title_b4), "%s <%s>", cid_name, cid_num); switch_url_encode(title_b4, title_aft, sizeof(title_aft)); - mp3 = switch_mprintf("http://%s:%s%s/mp3/%s/%s.mp3", holder->host, holder->port, holder->uri, uuid, cid_num); - m3u = switch_mprintf("http://%s:%s%s/m3u/mp3/%s/%s.mp3.m3u", holder->host, holder->port, holder->uri, uuid, cid_num); + if (!strncmp(holder->uri, "/webapi", 7)) uri_offset = 4; + + mp3 = switch_mprintf("http://%s:%s/%s/mp3/%s/%s.mp3", holder->host, holder->port, holder->uri + uri_offset, uuid, cid_num); + m3u = switch_mprintf("http://%s:%s/%s/m3u/mp3/%s/%s.mp3.m3u", holder->host, holder->port, holder->uri + uri_offset, uuid, cid_num); holder->stream->write_function(holder->stream, "[mp3] ", mp3); holder->stream->write_function(holder->stream, "[m3u]\n", m3u); From 082085fc5a9ccc6b91eaa4822aca0668869a6b7c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 11 Nov 2012 09:09:22 -0600 Subject: [PATCH 401/512] FS-4824 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 6fcccabf53..ff2b8dc496 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4813,7 +4813,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_refuse"); } - if (status >= 500 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850") + if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850") || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH") || !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) { tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause); From 8cd8b15266c3fbc5b92c0fcb3683b14f4f54122b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 12 Nov 2012 05:50:00 -0600 Subject: [PATCH 402/512] FS-4825 --resolve --- src/mod/applications/mod_sms/mod_sms.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mod/applications/mod_sms/mod_sms.c b/src/mod/applications/mod_sms/mod_sms.c index 34b2971333..372e7903b5 100644 --- a/src/mod/applications/mod_sms/mod_sms.c +++ b/src/mod/applications/mod_sms/mod_sms.c @@ -438,6 +438,16 @@ static switch_status_t chat_send(switch_event_t *message_event) } +SWITCH_STANDARD_CHAT_APP(system_function) +{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Executing command: %s\n", data); + if (switch_system(data, SWITCH_TRUE) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Failed to execute command: %s\n", data); + return SWITCH_STATUS_FALSE; + } + return SWITCH_STATUS_SUCCESS; +} + SWITCH_STANDARD_CHAT_APP(stop_function) { switch_set_flag(message, EF_NO_CHAT_EXEC); @@ -531,6 +541,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sms_load) SWITCH_ADD_CHAT_APP(chat_app_interface, "set", "set a variable", "set a variable", set_function, "", SCAF_NONE); SWITCH_ADD_CHAT_APP(chat_app_interface, "send", "send the message as-is", "send the message as-is", send_function, "", SCAF_NONE); SWITCH_ADD_CHAT_APP(chat_app_interface, "fire", "fire the message", "fire the message", fire_function, "", SCAF_NONE); + SWITCH_ADD_CHAT_APP(chat_app_interface, "system", "execute a system command", "execute a sytem command", system_function, "", SCAF_NONE); /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; From fa1876447444c886c8047c26c755b0d9830fca25 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 12 Nov 2012 19:04:59 +0000 Subject: [PATCH 403/512] Build debian packages with -fPIC By building globally with -fPIC we can get mod_flite to build. --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index cd7934e439..959a9e5254 100755 --- a/debian/rules +++ b/debian/rules @@ -6,7 +6,7 @@ FS_CC?=gcc FS_CXX?=g++ -FS_CFLAGS?=-ggdb3 -O2 +FS_CFLAGS?=-ggdb3 -O2 -fPIC FS_CPPFLAGS?= FS_CXXFLAGS?=$(FS_CFLAGS) export PATH?=/usr/lib/ccache:/usr/sbin:/usr/bin:/sbin:/bin From 443a8db1a5bc3126ea84e62dd44ec45a193eee44 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 12 Nov 2012 19:58:30 +0000 Subject: [PATCH 404/512] Build mod_flite Debian package FS-4263 --resolve --- debian/bootstrap.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 5307b25573..ad32b90895 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -15,7 +15,6 @@ avoid_mods=( applications/mod_rad_auth applications/mod_skel asr_tts/mod_cepstral - asr_tts/mod_flite codecs/mod_com_g729 codecs/mod_ilbc codecs/mod_sangoma_codec From 8c58a109994bd7e80af045653a19a8c54bbbe922 Mon Sep 17 00:00:00 2001 From: Matteo Brancaleoni Date: Thu, 8 Nov 2012 12:59:22 +0100 Subject: [PATCH 405/512] ftmod_libpri: Rework handling of peer-initiated hangup events Use peerhangup flag variable to track whether a hangup has been initiated by the peer or libpri itself (e.g. Layer 2 timeouts). These changes fix a couple of problems with hangup events not being handled properly in some situations: - Call abort caused by incoming RESTART on a channel in use - T309 timeout after L2 loss - Improved hangup handling in libpri-side on_hangup() event handler and state_advance() (FreeTDM side) Signed-off-by: Stefan Knoblich --- .../src/ftmod/ftmod_libpri/ftmod_libpri.c | 51 +++++++++++++++---- .../src/ftmod/ftmod_libpri/ftmod_libpri.h | 1 + .../src/ftmod/ftmod_libpri/lpwrap_pri.c | 4 ++ 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 2f1a5ff9ed..0e22b0f350 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -942,7 +942,7 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) ftdm_channel_t *chtmp = chan; if (call) { - pri_destroycall(isdn_data->spri.pri, call); + /* pri call destroy is done by libpri itself (on release_ack) */ chan_priv->call = NULL; } @@ -953,6 +953,9 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) lpwrap_stop_timer(&isdn_data->spri, &chan_priv->t316); chan_priv->t316_timeout_cnt = 0; + /* Unset remote hangup */ + chan_priv->peerhangup = 0; + 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), @@ -1206,12 +1209,21 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) { if (call) { ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); - pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause); -// pri_destroycall(isdn_data->spri.pri, call); -// chan_priv->call = NULL; + + if (chan_priv->peerhangup) { + /* Call is inbound and hangup has been initiated by peer */ + if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + } else if (caller_data->hangup_cause == PRI_CAUSE_NO_USER_RESPONSE) { + /* Can happen when we have a DL link expire or some timer expired */ + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + } else if (caller_data->hangup_cause == PRI_CAUSE_DESTINATION_OUT_OF_ORDER) { + /* Can happen when we have a DL link expire or some timer expired */ + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + } + } } - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); } break; @@ -1368,6 +1380,7 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even { ftdm_span_t *span = spri->span; ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel); + ftdm_libpri_b_chan_t *chan_priv = chan->call_data; if (!chan) { ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel); @@ -1386,8 +1399,6 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even ftdm_log(FTDM_LOG_DEBUG, "-- Hangup REQ on channel %d:%d\n", ftdm_span_get_id(spri->span), pevent->hangup.channel); - pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause); - chan->caller_data.hangup_cause = pevent->hangup.cause; switch (ftdm_channel_get_state(chan)) { @@ -1400,19 +1411,27 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even } break; - case LPWRAP_PRI_EVENT_HANGUP_ACK: /* */ + case LPWRAP_PRI_EVENT_HANGUP_ACK: /* RELEASE_COMPLETE */ ftdm_log(FTDM_LOG_DEBUG, "-- Hangup ACK on channel %d:%d\n", ftdm_span_get_id(spri->span), pevent->hangup.channel); - pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause); - - ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + switch (ftdm_channel_get_state(chan)) { + case FTDM_CHANNEL_STATE_RESTART: + /* ACK caused by DL FAILURE in DISC REQ */ + ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN); + break; + default: + ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + break; + } break; case LPWRAP_PRI_EVENT_HANGUP: /* "RELEASE/RELEASE_COMPLETE/other" */ ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", ftdm_span_get_id(spri->span), pevent->hangup.channel); + chan_priv->peerhangup = 1; + switch (ftdm_channel_get_state(chan)) { case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_RINGING: @@ -1424,9 +1443,19 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING); break; case FTDM_CHANNEL_STATE_HANGUP: + /* this will send "RELEASE_COMPLETE", eventually */ + pri_hangup(spri->pri, pevent->hangup.call, chan->caller_data.hangup_cause); chan->caller_data.hangup_cause = pevent->hangup.cause; ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); break; + case FTDM_CHANNEL_STATE_RESTART: + /* + * We got an hungup doing a restart, normally beacause link has been lost during + * a call and the T309 timer has expired. So destroy it :) (DL_RELEASE_IND) + */ + pri_destroycall(spri->pri, pevent->hangup.call); + ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN); + break; // case FTDM_CHANNEL_STATE_TERMINATING: // ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP); // break; diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h index 26db8d3155..852f5caaca 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h @@ -131,6 +131,7 @@ struct ftdm_libpri_b_chan { q931_call *call; /*!< libpri opaque call handle */ uint32_t flags; /*!< channel flags */ uint32_t t316_timeout_cnt; /*!< T316 timeout counter */ + int peerhangup; /*!< hangup requested from libpri (RELEASE/RELEASE_ACK/DL_RELEASE/TIMERS EXPIRY) */ }; typedef struct ftdm_libpri_b_chan ftdm_libpri_b_chan_t; diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index c9f0576951..44518a4496 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -169,6 +169,10 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t * if (spri->pri) { pri_set_debug(spri->pri, debug); +#ifdef HAVE_LIBPRI_BRI + /* "follow Q.931 Section 5.3.2 call hangup better" */ + pri_hangup_fix_enable(spri->pri, 1); +#endif #ifdef HAVE_LIBPRI_AOC pri_aoc_events_enable(spri->pri, 1); #endif From eb0c514e4f69205b5494735e0528967bee53058a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 12 Nov 2012 18:45:53 -0600 Subject: [PATCH 406/512] don't count pickup endpoints in sps limits --- src/mod/applications/mod_dptools/mod_dptools.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 91dd4944b1..834fe69e9a 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -3584,6 +3584,7 @@ static switch_call_cause_t pickup_outgoing_channel(switch_core_session_t *sessio pickup = outbound_profile->destination_number; + flags |= SOF_NO_LIMITS; if (!(nsession = switch_core_session_request(pickup_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); From 74dd18fe97ffc2c9e6fb84ee84611fb19205d8f1 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 13 Nov 2012 08:51:48 -0600 Subject: [PATCH 407/512] add missing reference - windows gsmopen --- src/mod/endpoints/mod_gsmopen/mod_gsmopen.2010.vcxproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2010.vcxproj b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2010.vcxproj index b2895a73d5..2429ca905f 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2010.vcxproj +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2010.vcxproj @@ -160,6 +160,9 @@ rpcrt4.lib "..\..\..\..\debug\libtiff.lib" "..\..\..\..\libs\spandsp\src\debug\ + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + {26c82fce-e0cf-4d10-a00c-d8e582ffeb53} From b04e4be512cae1d0248232af0187db9022960fcd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 13 Nov 2012 11:36:50 -0600 Subject: [PATCH 408/512] fix race condition in double loopback bowout --- src/mod/endpoints/mod_loopback/mod_loopback.c | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index e711622d34..7c72d7e136 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -709,10 +709,26 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch return status; } +static void switch_channel_wait_for_state_or_greater(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state) +{ + + switch_assert(channel); + + for (;;) { + if ((switch_channel_get_state(channel) < CS_HANGUP && + switch_channel_get_state(channel) == switch_channel_get_running_state(channel) && switch_channel_get_running_state(channel) == want_state) || + (other_channel && switch_channel_down_nosig(other_channel)) || switch_channel_down(channel)) { + break; + } + switch_cond_next(); + } +} + + static switch_status_t find_non_loopback_bridge(switch_core_session_t *session, switch_core_session_t **br_session, const char **br_uuid) { switch_channel_t *channel = switch_core_session_get_channel(session); - const char *a_uuid; + const char *a_uuid = NULL; switch_core_session_t *sp; *br_session = NULL; @@ -722,9 +738,17 @@ static switch_status_t find_non_loopback_bridge(switch_core_session_t *session, while (a_uuid && (sp = switch_core_session_locate(a_uuid))) { if (switch_core_session_check_interface(sp, loopback_endpoint_interface)) { - private_t *tech_pvt = switch_core_session_get_private(sp); + private_t *tech_pvt; + switch_channel_t *spchan = switch_core_session_get_channel(sp); + + switch_channel_wait_for_state_or_greater(spchan, channel, CS_ROUTING); + + tech_pvt = switch_core_session_get_private(sp); + + if (tech_pvt->other_channel) { + a_uuid = switch_channel_get_partner_uuid(tech_pvt->other_channel); + } - a_uuid = switch_channel_get_partner_uuid(tech_pvt->other_channel); switch_core_session_rwunlock(sp); sp = NULL; } else { From f4e55fb1871db9e4d39b96afcbd1c918e347dba1 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 13 Nov 2012 12:48:59 -0600 Subject: [PATCH 409/512] fix regression from 6b6c83a7180afa31a6bf0b2ea6a04a0b316652f4 --- src/switch_xml.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_xml.c b/src/switch_xml.c index e0f3e3d37d..fe67c95169 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2458,7 +2458,7 @@ static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len, *len += sprintf(*s + *len, "%s", XML_INDENT); /* indent */ } } - *len += sprintf(*s + (*len), "", xml->name); /* close tag */ + *len += sprintf(*s + (*len), "\n", xml->name); /* close tag */ } while (txt[off] && off < xml->off) From 580e63ecfaec645d16cbcb37c924a17516336b24 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 13 Nov 2012 12:30:21 -0600 Subject: [PATCH 410/512] check for signalling in sleep app on channels without media --- src/switch_ivr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index eb8d4ab9e6..18329714aa 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -153,7 +153,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, if (!switch_channel_media_ready(channel)) { - for (elapsed=0; elapsed<(ms/20); elapsed++) { + for (elapsed=0; switch_channel_up(channel) && elapsed<(ms/20); elapsed++) { if (switch_channel_test_flag(channel, CF_BREAK)) { switch_channel_clear_flag(channel, CF_BREAK); return SWITCH_STATUS_BREAK; From 5fffdc29365840fc0c0e4914d70902c0dbfd058b Mon Sep 17 00:00:00 2001 From: William King Date: Tue, 13 Nov 2012 16:56:58 -0800 Subject: [PATCH 411/512] This fixes multiple issues dealing with sms from registered endpoints to other destinations. --- src/switch_loadable_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index d87d37f7fc..26e93a8071 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1766,8 +1766,8 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autolo switch_loadable_module_runtime(); - chat_globals.running = 1; memset(&chat_globals, 0, sizeof(chat_globals)); + chat_globals.running = 1; chat_globals.pool = loadable_modules.pool; switch_mutex_init(&chat_globals.mutex, SWITCH_MUTEX_NESTED, chat_globals.pool); From 18f20e24bf2a2cd309bf41b6ed373342d4688e97 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 13 Nov 2012 17:56:09 -0600 Subject: [PATCH 412/512] fix bad return vals on sending messages when under stress --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/nta/nta.c | 2 +- libs/sofia-sip/libsofia-sip-ua/su/su.c | 13 +++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index dbb9bc2ccd..b50d284902 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Thu Nov 8 09:48:11 CST 2012 +Tue Nov 13 15:22:19 CST 2012 diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index 709e678d86..c9bbea2d6b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -9211,7 +9211,7 @@ int outgoing_recv(nta_outgoing_t *_orq, if (orq->orq_destroyed && 200 <= status && status < 300) { if (orq->orq_uas && su_strcasecmp(sip->sip_to->a_tag, orq->orq_tag) != 0) { /* Orphan 200 Ok to INVITE. ACK and BYE it */ - SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE\n" VA_NONE)); + SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE %p\n", (void *)orq)); return nta_msg_ackbye(sa, msg); } return -1; /* Proxy statelessly (RFC3261 section 16.11) */ diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su.c b/libs/sofia-sip/libsofia-sip-ua/su/su.c index 8067fdec60..c99d32f24d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su.c @@ -510,13 +510,20 @@ issize_t su_vsend(su_socket_t s, su_sockaddr_t const *su, socklen_t sulen) { struct msghdr hdr[1] = {{0}}; + int rv; hdr->msg_name = (void *)su; hdr->msg_namelen = sulen; hdr->msg_iov = (struct iovec *)iov; hdr->msg_iovlen = iovlen; - return sendmsg(s, hdr, flags); + do { + if ((rv = sendmsg(s, hdr, flags)) == -1) { + if (errno == EAGAIN) usleep(1000); + } + } while (rv == -1 && (errno == EAGAIN || errno == EINTR)); + + return rv; } issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags, @@ -531,7 +538,9 @@ issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags, hdr->msg_iov = (struct iovec *)iov; hdr->msg_iovlen = iovlen; - retval = recvmsg(s, hdr, flags); + do { + retval = recvmsg(s, hdr, flags); + } while (retval == -1 && errno == EINTR); if (su && sulen) *sulen = hdr->msg_namelen; From 7cb8d4dbb0b28cba86183a6e80ff10594ed237e4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 13 Nov 2012 17:56:27 -0600 Subject: [PATCH 413/512] fix mutex to work better --- .../applications/mod_dptools/mod_dptools.c | 30 +++++++++---------- src/switch_event.c | 14 +++++---- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 834fe69e9a..eefd4aad4b 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4814,10 +4814,6 @@ static switch_bool_t do_mutex(switch_core_session_t *session, const char *key, s struct read_frame_data rf = { 0 }; long to_val = 0; - if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { - return SWITCH_FALSE; - } - switch_mutex_lock(globals.mutex_mutex); used = switch_channel_test_app_flag_key(key, channel, MUTEX_FLAG_WAIT) || switch_channel_test_app_flag_key(key, channel, MUTEX_FLAG_SET); @@ -4877,19 +4873,12 @@ static switch_bool_t do_mutex(switch_core_session_t *session, const char *key, s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s mutex %s is busy, waiting...\n", switch_channel_get_name(channel), key); - if (!(feedback = switch_channel_get_variable(channel, "mutex_feedback"))) { - if ((var = switch_channel_get_variable(channel, "ringback"))) { - feedback = switch_core_session_sprintf(session, "tone_stream://%s;loops=-1", var); - } else { - feedback = switch_channel_get_hold_music(channel); + if ((feedback = switch_channel_get_variable(channel, "mutex_feedback"))) { + if (!strcasecmp(feedback, "silence")) { + feedback = "silence_stream://-1"; } } - if (zstr(feedback) || !strcasecmp(feedback, "silence")) { - feedback = "silence_stream://-1"; - } - - if ((rf.exten = switch_channel_get_variable(channel, "mutex_orbit_exten"))) { to_val = 60; } @@ -4917,7 +4906,16 @@ static switch_bool_t do_mutex(switch_core_session_t *session, const char *key, s args.user_data = &rf; while(switch_channel_ready(channel) && switch_channel_test_app_flag_key(key, channel, MUTEX_FLAG_WAIT)) { - switch_status_t st = switch_ivr_play_file(session, NULL, feedback, &args); + switch_status_t st; + + if (feedback) { + switch_channel_pre_answer(channel); + st = switch_ivr_play_file(session, NULL, feedback, &args); + } else { + if ((st = switch_ivr_sleep(session, 20, SWITCH_FALSE, NULL)) == SWITCH_STATUS_SUCCESS) { + st = read_frame_callback(session, NULL, &rf); + } + } if (st != SWITCH_STATUS_SUCCESS) { break; @@ -5519,7 +5517,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "flush_dtmf", "flush any queued dtmf", "flush any queued dtmf", flush_dtmf_function, "", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "hold", "Send a hold message", "Send a hold message", hold_function, HOLD_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "unhold", "Send a un-hold message", "Send a un-hold message", unhold_function, UNHOLD_SYNTAX, SAF_SUPPORT_NOMEDIA); - SWITCH_ADD_APP(app_interface, "mutex", "block on a call flow only allowing one at a time", "", mutex_function, MUTEX_SYNTAX, SAF_NONE); + SWITCH_ADD_APP(app_interface, "mutex", "block on a call flow only allowing one at a time", "", mutex_function, MUTEX_SYNTAX, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "page", "", "", page_function, PAGE_SYNTAX, SAF_NONE); SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, " [ ]", SAF_SUPPORT_NOMEDIA); diff --git a/src/switch_event.c b/src/switch_event.c index e589e02f43..7a965d4dcd 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1138,17 +1138,21 @@ SWITCH_DECLARE(void) switch_event_destroy(switch_event_t **event) for (hp = ep->headers; hp;) { this = hp; hp = hp->next; - FREE(this->name); if (this->idx) { - int i = 0; + if (!this->array) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "INDEX WITH NO ARRAY WTF?? [%s][%s]\n", this->name, this->value); + } else { + int i = 0; - for (i = 0; i < this->idx; i++) { - FREE(this->array[i]); + for (i = 0; i < this->idx; i++) { + FREE(this->array[i]); + } + FREE(this->array); } - FREE(this->array); } + FREE(this->name); FREE(this->value); From 8f0b7e69de639c662aa292075838d6e65dbd1357 Mon Sep 17 00:00:00 2001 From: William King Date: Tue, 13 Nov 2012 18:18:33 -0800 Subject: [PATCH 414/512] Handle routing loop detection properly so that the delivery confirmation handling is more accurate. --- src/mod/endpoints/mod_sofia/sofia.c | 1 + src/mod/endpoints/mod_sofia/sofia_presence.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ff2b8dc496..89024c5203 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2459,6 +2459,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void #ifdef MANUAL_BYE NUTAG_APPL_METHOD("BYE"), #endif + NUTAG_APPL_METHOD("MESSAGE"), NUTAG_SESSION_TIMER(profile->session_timeout), NTATAG_MAX_PROCEEDING(profile->max_proceeding), diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index ed156c5f05..a053813a84 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -4351,7 +4351,8 @@ void sofia_presence_handle_sip_i_message(int status, if ((us = sofia_glue_get_unknown_header(sip, "X-FS-Sending-Message")) && !strcmp(us, switch_core_get_uuid())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Not sending message to ourselves!\n"); - goto end; + nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); + return; } if (sip->sip_content_type && sip->sip_content_type->c_subtype) { From dfce47f26d416ec885cd3b589b079d5a0d457692 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Wed, 14 Nov 2012 21:53:17 +0800 Subject: [PATCH 415/512] Relaxed the constraints for declaring a clean end of call on FAX receive. If we get an EOP, we no longer worry whether the final stages tidy up. This helps tolerate the increasing number of VoIP calls which hang up before the audio has flushed down the line. A few little cleanups. --- libs/spandsp/src/spandsp/private/t30.h | 3 + libs/spandsp/src/spandsp/telephony.h | 10 ++ libs/spandsp/src/t30.c | 167 +++++++++++++++------- libs/spandsp/src/t4_tx.c | 37 +++-- libs/spandsp/tests/fax_decode.c | 16 ++- libs/spandsp/tests/line_model_monitor.cpp | 6 +- 6 files changed, 157 insertions(+), 82 deletions(-) diff --git a/libs/spandsp/src/spandsp/private/t30.h b/libs/spandsp/src/spandsp/private/t30.h index 1fede6ed79..9b70a7a73b 100644 --- a/libs/spandsp/src/spandsp/private/t30.h +++ b/libs/spandsp/src/spandsp/private/t30.h @@ -212,6 +212,9 @@ struct t30_state_s /*! \brief TRUE once the far end FAX entity has been detected. */ int far_end_detected; + + /*! \brief TRUE once the end of procedure condition has been detected. */ + int end_of_procedure_detected; /*! \brief TRUE if a local T.30 interrupt is pending. */ int local_interrupt_pending; diff --git a/libs/spandsp/src/spandsp/telephony.h b/libs/spandsp/src/spandsp/telephony.h index 7a09bbe044..132cce9bf8 100644 --- a/libs/spandsp/src/spandsp/telephony.h +++ b/libs/spandsp/src/spandsp/telephony.h @@ -88,6 +88,16 @@ typedef int (*span_tx_handler_t)(void *s, int16_t amp[], int max_len); #define FP_Q_2_14(x) ((int16_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5))) #define FP_Q_1_15(x) ((int16_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_9_7_32(x) ((int32_t) (128.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_8_8_32(x) ((int32_t) (256.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_7_9_32(x) ((int32_t) (512.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_6_10_32(x) ((int32_t) (1024.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_5_11_32(x) ((int32_t) (2048.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_4_12_32(x) ((int32_t) (4096.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_3_13_32(x) ((int32_t) (8192.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_2_14_32(x) ((int32_t) (16384.0*x + ((x >= 0.0) ? 0.5 : -0.5))) +#define FP_Q_1_15_32(x) ((int32_t) (32768.0*x + ((x >= 0.0) ? 0.5 : -0.5))) + #define FP_Q_9_23(x) ((int32_t) (65536.0*128.0*x + ((x >= 0.0) ? 0.5 : -0.5))) #define FP_Q_8_24(x) ((int32_t) (65536.0*256.0*x + ((x >= 0.0) ? 0.5 : -0.5))) #define FP_Q_7_25(x) ((int32_t) (65536.0*512.0*x + ((x >= 0.0) ? 0.5 : -0.5))) diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index a12d357f76..7772459aba 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -132,19 +132,19 @@ enum static const char *phase_names[] = { - "T30_PHASE_IDLE", - "T30_PHASE_A_CED", - "T30_PHASE_A_CNG", - "T30_PHASE_B_RX", - "T30_PHASE_B_TX", - "T30_PHASE_C_NON_ECM_RX", - "T30_PHASE_C_NON_ECM_TX", - "T30_PHASE_C_ECM_RX", - "T30_PHASE_C_ECM_TX", - "T30_PHASE_D_RX", - "T30_PHASE_D_TX", - "T30_PHASE_E", - "T30_PHASE_CALL_FINISHED" + "IDLE", + "A_CED", + "A_CNG", + "B_RX", + "B_TX", + "C_NON_ECM_RX", + "C_NON_ECM_TX", + "C_ECM_RX", + "C_ECM_TX", + "D_RX", + "D_TX", + "E", + "CALL_FINISHED" }; /* These state names are modelled after places in the T.30 flow charts. */ @@ -184,6 +184,43 @@ enum T30_STATE_CALL_FINISHED }; +static const char *state_names[] = +{ + "NONE", + "ANSWERING", + "B", + "C", + "D", + "D_TCF", + "D_POST_TCF", + "F_TCF", + "F_CFR", + "F_FTT", + "F_DOC_NON_ECM", + "F_POST_DOC_NON_ECM", + "F_DOC_ECM", + "F_POST_DOC_ECM", + "F_POST_RCP_MCF", + "F_POST_RCP_PPR", + "F_POST_RCP_RNR", + "R", + "T", + "I", + "II", + "II_Q", + "III_Q_MCF", + "III_Q_RTP", + "III_Q_RTN", + "IV", + "IV_PPS_NULL", + "IV_PPS_Q", + "IV_PPS_RNR", + "IV_CTC", + "IV_EOR", + "IV_EOR_RNR", + "CALL_FINISHED" +}; + enum { T30_MIN_SCAN_20MS = 0, @@ -1309,7 +1346,7 @@ static int build_dcs(t30_state_t *s) int i; int bad; int row_squashing_ratio; - + /* Make a DCS frame based on local issues and the latest received DIS/DTC frame. Negotiate the result based on what both parties can do. */ s->dcs_frame[0] = ADDRESS_FIELD; @@ -2017,7 +2054,7 @@ static int start_receiving_document(t30_state_t *s) static void unexpected_non_final_frame(t30_state_t *s, const uint8_t *msg, int len) { - span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %s\n", t30_frametype(msg[2]), state_names[s->state]); if (s->current_status == T30_ERR_OK) t30_set_status(s, T30_ERR_UNEXPECTED); } @@ -2025,7 +2062,7 @@ static void unexpected_non_final_frame(t30_state_t *s, const uint8_t *msg, int l static void unexpected_final_frame(t30_state_t *s, const uint8_t *msg, int len) { - span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %s\n", t30_frametype(msg[2]), state_names[s->state]); if (s->current_status == T30_ERR_OK) t30_set_status(s, T30_ERR_UNEXPECTED); send_dcn(s); @@ -2473,17 +2510,15 @@ static int send_response_to_pps(t30_state_t *s) { set_state(s, T30_STATE_F_POST_RCP_MCF); send_simple_frame(s, T30_MCF); + return TRUE; } - else - { - /* We need to send the PPR frame we have created, to try to fill in the missing/bad data. */ - set_state(s, T30_STATE_F_POST_RCP_PPR); - s->ecm_frame_map[0] = ADDRESS_FIELD; - s->ecm_frame_map[1] = CONTROL_FIELD_FINAL_FRAME; - s->ecm_frame_map[2] = (uint8_t) (T30_PPR | s->dis_received); - send_frame(s, s->ecm_frame_map, 3 + 32); - } - return 0; + /* We need to send the PPR frame we have created, to try to fill in the missing/bad data. */ + set_state(s, T30_STATE_F_POST_RCP_PPR); + s->ecm_frame_map[0] = ADDRESS_FIELD; + s->ecm_frame_map[1] = CONTROL_FIELD_FINAL_FRAME; + s->ecm_frame_map[2] = (uint8_t) (T30_PPR | s->dis_received); + send_frame(s, s->ecm_frame_map, 3 + 32); + return FALSE; } /*- End of function --------------------------------------------------------*/ @@ -2685,7 +2720,17 @@ static int process_rx_pps(t30_state_t *s, const uint8_t *msg, int len) } else { - send_response_to_pps(s); + if (send_response_to_pps(s)) + { + switch (s->last_pps_fcf2) + { + case T30_PRI_EOP: + case T30_EOP: + span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n"); + s->end_of_procedure_detected = TRUE; + break; + } + } } break; default: @@ -3364,6 +3409,8 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg, } /* Fall through */ case T30_EOP: + span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n"); + s->end_of_procedure_detected = TRUE; s->next_rx_step = fcf; queue_phase(s, T30_PHASE_D_TX); switch (copy_quality(s)) @@ -3397,7 +3444,6 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg, send_simple_frame(s, T30_RTN); break; } - break; case T30_DCN: t30_set_status(s, T30_ERR_RX_DCNFAX); @@ -3565,7 +3611,17 @@ static void process_state_f_post_rcp_rnr(t30_state_t *s, const uint8_t *msg, int else { /* Now we send the deferred response */ - send_response_to_pps(s); + if (send_response_to_pps(s)) + { + switch (s->last_pps_fcf2) + { + case T30_PRI_EOP: + case T30_EOP: + span_log(&s->logging, SPAN_LOG_FLOW, "End of procedure detected\n"); + s->end_of_procedure_detected = TRUE; + break; + } + } } break; case T30_CRP: @@ -4656,7 +4712,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len) /* The following handles context sensitive message types, which should occur at the end of message sequences. They should, therefore have the final frame flag set. */ - span_log(&s->logging, SPAN_LOG_FLOW, "Rx final frame in state %d\n", s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "Rx final frame in state %s\n", state_names[s->state]); switch (s->state) { @@ -4891,7 +4947,7 @@ static void set_state(t30_state_t *s, int state) { if (s->state != state) { - span_log(&s->logging, SPAN_LOG_FLOW, "Changing from state %d to %d\n", s->state, state); + span_log(&s->logging, SPAN_LOG_FLOW, "Changing from state %s to %s\n", state_names[s->state], state_names[state]); s->state = state; } s->step = 0; @@ -4982,9 +5038,9 @@ static void repeat_last_command(t30_state_t *s) default: span_log(&s->logging, SPAN_LOG_FLOW, - "Repeat command called with nothing to repeat - phase %s, state %d\n", + "Repeat command called with nothing to repeat - phase %s, state %s\n", phase_names[s->phase], - s->state); + state_names[s->state]); break; } } @@ -5098,7 +5154,7 @@ static void timer_t2_t4_stop(t30_state_t *s) static void timer_t0_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T0 expired in state %d\n", s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T0 expired in state %s\n", state_names[s->state]); t30_set_status(s, T30_ERR_T0_EXPIRED); /* Just end the call */ disconnect(s); @@ -5107,7 +5163,7 @@ static void timer_t0_expired(t30_state_t *s) static void timer_t1_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T1 expired in state %d\n", s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T1 expired in state %s\n", state_names[s->state]); /* The initial connection establishment has timeout out. In other words, we have been unable to communicate successfully with a remote machine. It is time to abandon the call. */ @@ -5132,7 +5188,7 @@ static void timer_t1_expired(t30_state_t *s) static void timer_t2_expired(t30_state_t *s) { if (s->timer_t2_t4_is != TIMER_IS_T2B) - span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %d\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]); switch (s->state) { case T30_STATE_III_Q_MCF: @@ -5202,7 +5258,7 @@ static void timer_t2_expired(t30_state_t *s) static void timer_t1a_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T1A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]); t30_set_status(s, T30_ERR_HDLC_CARRIER); disconnect(s); } @@ -5210,7 +5266,7 @@ static void timer_t1a_expired(t30_state_t *s) static void timer_t2a_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T2A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]); t30_set_status(s, T30_ERR_HDLC_CARRIER); disconnect(s); } @@ -5218,14 +5274,14 @@ static void timer_t2a_expired(t30_state_t *s) static void timer_t2b_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T2B expired in phase %s, state %d. The line is now quiet.\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T2B expired in phase %s, state %s. The line is now quiet.\n", phase_names[s->phase], state_names[s->state]); timer_t2_expired(s); } /*- End of function --------------------------------------------------------*/ static void timer_t3_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T3 expired in phase %s, state %d\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T3 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]); t30_set_status(s, T30_ERR_T3_EXPIRED); disconnect(s); } @@ -5235,7 +5291,7 @@ static void timer_t4_expired(t30_state_t *s) { /* There was no response (or only a corrupt response) to a command, within the T4 timeout period. */ - span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %d\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T4 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]); /* Of course, things might just be a little late, especially if there are T.38 links in the path. There is no point in simply timing out, and resending, if we are currently receiving something from the far end - its a half-duplex @@ -5249,7 +5305,7 @@ static void timer_t4_expired(t30_state_t *s) static void timer_t4a_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T4A expired in phase %s, state %d. An HDLC frame lasted too long.\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T4A expired in phase %s, state %s. An HDLC frame lasted too long.\n", phase_names[s->phase], state_names[s->state]); t30_set_status(s, T30_ERR_HDLC_CARRIER); disconnect(s); } @@ -5257,7 +5313,7 @@ static void timer_t4a_expired(t30_state_t *s) static void timer_t4b_expired(t30_state_t *s) { - span_log(&s->logging, SPAN_LOG_FLOW, "T4B expired in phase %s, state %d. The line is now quiet.\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T4B expired in phase %s, state %s. The line is now quiet.\n", phase_names[s->phase], state_names[s->state]); timer_t4_expired(s); } /*- End of function --------------------------------------------------------*/ @@ -5265,7 +5321,7 @@ static void timer_t4b_expired(t30_state_t *s) static void timer_t5_expired(t30_state_t *s) { /* Give up waiting for the receiver to become ready in error correction mode */ - span_log(&s->logging, SPAN_LOG_FLOW, "T5 expired in phase %s, state %d\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "T5 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]); t30_set_status(s, T30_ERR_TX_T5EXP); } /*- End of function --------------------------------------------------------*/ @@ -5351,7 +5407,7 @@ static void t30_non_ecm_rx_status(void *user_data, int status) int was_trained; s = (t30_state_t *) user_data; - span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM signal status is %s (%d) in state %d\n", signal_status_to_str(status), status, s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "Non-ECM signal status is %s (%d) in state %s\n", signal_status_to_str(status), status, state_names[s->state]); switch (status) { case SIG_STATUS_TRAINING_IN_PROGRESS: @@ -5555,7 +5611,7 @@ SPAN_DECLARE_NONSTD(int) t30_non_ecm_get_bit(void *user_data) bit = 0; break; default: - span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %d\n", s->state); + span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get_bit in bad state %s\n", state_names[s->state]); bit = SIG_STATUS_END_OF_DATA; break; } @@ -5590,7 +5646,7 @@ SPAN_DECLARE(int) t30_non_ecm_get(void *user_data, uint8_t buf[], int max_len) len = 0; break; default: - span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get in bad state %d\n", s->state); + span_log(&s->logging, SPAN_LOG_WARNING, "t30_non_ecm_get in bad state %s\n", state_names[s->state]); len = -1; break; } @@ -5604,7 +5660,7 @@ static void t30_hdlc_rx_status(void *user_data, int status) int was_trained; s = (t30_state_t *) user_data; - span_log(&s->logging, SPAN_LOG_FLOW, "HDLC signal status is %s (%d) in state %d\n", signal_status_to_str(status), status, s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "HDLC signal status is %s (%d) in state %s\n", signal_status_to_str(status), status, state_names[s->state]); switch (status) { case SIG_STATUS_TRAINING_IN_PROGRESS: @@ -5798,7 +5854,7 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status) switch (status) { case T30_FRONT_END_SEND_STEP_COMPLETE: - span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %d\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "Send complete in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]); /* We have finished sending our messages, so move on to the next operation. */ switch (s->state) { @@ -6025,12 +6081,12 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status) disconnect from the far end overlaps something. */ break; default: - span_log(&s->logging, SPAN_LOG_FLOW, "Bad state for send complete in t30_front_end_status - %d\n", s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "Bad state for send complete in t30_front_end_status - %s\n", state_names[s->state]); break; } break; case T30_FRONT_END_RECEIVE_COMPLETE: - span_log(&s->logging, SPAN_LOG_FLOW, "Receive complete in phase %s, state %d\n", phase_names[s->phase], s->state); + span_log(&s->logging, SPAN_LOG_FLOW, "Receive complete in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]); /* Usually receive complete is notified by a carrier down signal. However, in cases like a T.38 packet stream dying in the middle of reception there needs to be a means to stop things. */ @@ -6175,8 +6231,12 @@ SPAN_DECLARE(void) t30_terminate(t30_state_t *s) hussle things along. */ break; default: - /* The call terminated prematurely. */ - t30_set_status(s, T30_ERR_CALLDROPPED); + /* If we have seen a genuine EOP or PRI_EOP, that's good enough. */ + if (!s->end_of_procedure_detected) + { + /* The call terminated prematurely. */ + t30_set_status(s, T30_ERR_CALLDROPPED); + } break; } if (s->phase_e_handler) @@ -6268,6 +6328,7 @@ SPAN_DECLARE(int) t30_restart(t30_state_t *s) s->rtp_events = 0; s->local_interrupt_pending = FALSE; s->far_end_detected = FALSE; + s->end_of_procedure_detected = FALSE; s->timer_t0_t1 = ms_to_samples(DEFAULT_TIMER_T0); if (s->calling_party) { diff --git a/libs/spandsp/src/t4_tx.c b/libs/spandsp/src/t4_tx.c index 2e2f25c706..4fb764fa6f 100644 --- a/libs/spandsp/src/t4_tx.c +++ b/libs/spandsp/src/t4_tx.c @@ -661,7 +661,7 @@ static int make_header(t4_tx_state_t *s) if ((s->header_text = malloc(132 + 1)) == NULL) return -1; } - /* This is very English oriented, but then most FAX machines are. Some + /* This is very English oriented, but then most FAX machines are, too. Some measure of i18n in the time and date, and even the header_info string, is entirely possible, although the font area would need some serious work to properly deal with East Asian script. There is no spec for what the header @@ -733,26 +733,21 @@ static int header_row_read_handler(void *user_data, uint8_t buf[], size_t len) return len; } } - switch (s->tiff.image_type) + row = s->header_row/repeats; + pos = 0; + for (t = s->header_text; *t && pos <= len - 2; t++) { - case T4_IMAGE_TYPE_BILEVEL: - row = s->header_row/repeats; - pos = 0; - for (t = s->header_text; *t && pos <= len - 2; t++) - { - pattern = header_font[(uint8_t) *t][row]; - buf[pos++] = (uint8_t) (pattern >> 8); - buf[pos++] = (uint8_t) (pattern & 0xFF); - } - while (pos < len) - buf[pos++] = 0; - s->header_row++; - if (s->header_row >= 16*repeats) - { - /* End of header. Change to normal image row data. */ - set_row_read_handler(s, s->row_handler, s->row_handler_user_data); - } - break; + pattern = header_font[(uint8_t) *t][row]; + buf[pos++] = (uint8_t) (pattern >> 8); + buf[pos++] = (uint8_t) (pattern & 0xFF); + } + while (pos < len) + buf[pos++] = 0; + s->header_row++; + if (s->header_row >= 16*repeats) + { + /* End of header. Change to normal image row data. */ + set_row_read_handler(s, s->row_handler, s->row_handler_user_data); } return len; } @@ -1113,7 +1108,7 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s) break; } /* If there is a page header, create that first */ - if (s->header_info && s->header_info[0] && make_header(s) == 0) + if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL && s->header_info && s->header_info[0] && make_header(s) == 0) { s->header_row = 0; set_row_read_handler(s, header_row_read_handler, (void *) s); diff --git a/libs/spandsp/tests/fax_decode.c b/libs/spandsp/tests/fax_decode.c index 722f40681f..ea6da19125 100644 --- a/libs/spandsp/tests/fax_decode.c +++ b/libs/spandsp/tests/fax_decode.c @@ -106,6 +106,7 @@ int image_width = 1728; int octets_per_ecm_frame = 256; int error_correcting_mode = FALSE; int current_fallback = 0; +int end_of_page_detected = FALSE; static void decode_20digit_msg(const uint8_t *pkt, int len) { @@ -232,8 +233,6 @@ static int check_rx_dcs(const uint8_t *msg, int len) if ((current_fallback = find_fallback_entry(dcs_frame[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3))) < 0) printf("Remote asked for a modem standard we do not support\n"); error_correcting_mode = ((dcs_frame[6] & DISBIT3) != 0); - - //v17_rx_restart(&v17, fallback_sequence[fallback_entry].bit_rate, FALSE); return 0; } /*- End of function --------------------------------------------------------*/ @@ -298,6 +297,7 @@ static void t4_begin(void) t4_rx_start_page(&t4_rx_state); t4_up = TRUE; + end_of_page_detected = FALSE; for (i = 0; i < 256; i++) ecm_len[i] = -1; @@ -381,7 +381,9 @@ static void v17_put_bit(void *user_data, int bit) if (t4_rx_put_bit(&t4_rx_state, bit)) { t4_end(); - fprintf(stderr, "End of page detected\n"); + if (!end_of_page_detected) + fprintf(stderr, "End of page detected\n"); + end_of_page_detected = TRUE; } } //printf("V.17 Rx bit %d - %d\n", rx_bits++, bit); @@ -417,7 +419,9 @@ static void v29_put_bit(void *user_data, int bit) if (t4_rx_put_bit(&t4_rx_state, bit)) { t4_end(); - fprintf(stderr, "End of page detected\n"); + if (!end_of_page_detected) + fprintf(stderr, "End of page detected\n"); + end_of_page_detected = TRUE; } } //printf("V.29 Rx bit %d - %d\n", rx_bits++, bit); @@ -453,7 +457,9 @@ static void v27ter_put_bit(void *user_data, int bit) if (t4_rx_put_bit(&t4_rx_state, bit)) { t4_end(); - fprintf(stderr, "End of page detected\n"); + if (!end_of_page_detected) + fprintf(stderr, "End of page detected\n"); + end_of_page_detected = TRUE; } } //printf("V.27ter Rx bit %d - %d\n", rx_bits++, bit); diff --git a/libs/spandsp/tests/line_model_monitor.cpp b/libs/spandsp/tests/line_model_monitor.cpp index d2c4f89bc9..8e57fe8a94 100644 --- a/libs/spandsp/tests/line_model_monitor.cpp +++ b/libs/spandsp/tests/line_model_monitor.cpp @@ -216,7 +216,7 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len) #endif } s->in_ptr = 0; -#if defined(HAVE_FFTW3_H) +#if defined(HAVE_FFTW3_H) fftw_execute(s->p); #else fftw_one(s->p, s->in, s->out); @@ -227,7 +227,7 @@ int line_model_monitor_line_spectrum_update(const int16_t amp[], int len) for (i = 0; i < 512; i++) { s->spec_re_plot[2*i] = i*4000.0/512.0; -#if defined(HAVE_FFTW3_H) +#if defined(HAVE_FFTW3_H) s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i][0]*s->out[i][0] + s->out[i][1]*s->out[i][1])/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14; #else s->spec_re_plot[2*i + 1] = 10.0*log10((s->out[i].re*s->out[i].re + s->out[i].im*s->out[i].im)/(256.0*32768*256.0*32768) + 1.0e-10) + 3.14; @@ -395,7 +395,7 @@ int start_line_model_monitor(int len) s->w->end(); s->w->show(); -#if defined(HAVE_FFTW3_H) +#if defined(HAVE_FFTW3_H) s->p = fftw_plan_dft_1d(1024, s->in, s->out, FFTW_BACKWARD, FFTW_ESTIMATE); for (i = 0; i < 1024; i++) { From 2f2a351067c850d478f0c05fd4ace6dac7f56fd0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Nov 2012 09:20:52 -0600 Subject: [PATCH 416/512] add initial_callee_id_name/number --- src/mod/endpoints/mod_sofia/mod_sofia.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 6bd9cdd3e0..55b99ac31c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -262,12 +262,14 @@ char *generate_pai_str(private_object_t *tech_pvt) return NULL; } - if (zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_name"))) && + if (zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "initial_callee_id_name"))) && + zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_name"))) && zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_name")))) { callee_name = switch_channel_get_variable(tech_pvt->channel, "callee_id_name"); } - if (zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_number"))) && + if (zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "initial_callee_id_number"))) && + zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_number"))) && zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_number"))) && zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "callee_id_number")))) { From ca0ffe6b763820e9cc05ab8d78b417219152da7b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Nov 2012 13:22:48 -0600 Subject: [PATCH 417/512] add version to status output --- src/mod/applications/mod_commands/mod_commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index eb9db51e25..78655106a1 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2037,7 +2037,9 @@ SWITCH_STANDARD_API(status_function) duration.sec, duration.sec == 1 ? "" : "s", duration.ms , duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s", nl); - stream->write_function(stream, "FreeSWITCH is %s%s", switch_core_ready() ? "ready" : "not ready", nl); + stream->write_function(stream, "FreeSWITCH (Version %s) is %s%s", SWITCH_VERSION_FULL_HUMAN, + switch_core_ready() ? "ready" : "not ready", nl); + stream->write_function(stream, "%" SWITCH_SIZE_T_FMT " session(s) since startup%s", switch_core_session_id() - 1, nl); switch_core_session_ctl(SCSC_LAST_SPS, &last_sps); switch_core_session_ctl(SCSC_SPS, &sps); From 8b74de2d6238f18bdb51a811a26798397ef08587 Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 14 Nov 2012 16:43:37 -0800 Subject: [PATCH 418/512] Adding delivery status code if the sms was sent in blocking mode. --- src/mod/endpoints/mod_sofia/sofia_presence.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index a053813a84..ab6576d52c 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -364,7 +364,9 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event) if (!(mstatus > 199 && mstatus < 300)) { status = SWITCH_STATUS_FALSE; } - + + switch_event_add_header(message_event, SWITCH_STACK_BOTTOM, "Delivery-Result-Code", "%d", mstatus); + switch_mutex_lock(profile->flag_mutex); switch_core_hash_delete(profile->chat_hash, uuid_str); switch_mutex_unlock(profile->flag_mutex); From b8f0d11a8a32446637ff6ef3d783a0cd68bc5abf Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 14 Nov 2012 16:45:32 -0800 Subject: [PATCH 419/512] Fire an event on successful sms delivery, as well as clearify if the delivery method was blocking or not. --- src/mod/applications/mod_sms/mod_sms.c | 3 +++ src/switch_loadable_module.c | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_sms/mod_sms.c b/src/mod/applications/mod_sms/mod_sms.c index 372e7903b5..d90896f74d 100644 --- a/src/mod/applications/mod_sms/mod_sms.c +++ b/src/mod/applications/mod_sms/mod_sms.c @@ -50,6 +50,9 @@ static void event_handler(switch_event_t *event) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Delivery Failure\n"); DUMP_EVENT(event); + return; + } else if ( check_failure && switch_false(check_failure) ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS Delivery Success\n"); return; } diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 26e93a8071..a94c274b6d 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -512,6 +512,7 @@ static switch_status_t do_chat_send(switch_event_t *message_event) switch_chat_interface_t *ci; switch_status_t status = SWITCH_STATUS_FALSE; switch_hash_index_t *hi; + switch_event_t *dup = NULL; const void *var; void *val; const char *proto; @@ -588,14 +589,20 @@ static switch_status_t do_chat_send(switch_event_t *message_event) } } - if (status != SWITCH_STATUS_SUCCESS) { - switch_event_t *dup; - switch_event_dup(&dup, message_event); - switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true"); - switch_event_fire(&dup); + + switch_event_dup(&dup, message_event); + + if ( switch_true(switch_event_get_header(message_event, "blocking")) ) { + if (status == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "false"); + } else { + switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Delivery-Failure", "true"); + } + } else { + switch_event_add_header_string(dup, SWITCH_STACK_BOTTOM, "Nonblocking-Delivery", "true"); } - + switch_event_fire(&dup); return status; } From a47321f0fdef0079ff911336c3527a8a710711f3 Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 14 Nov 2012 16:48:21 -0800 Subject: [PATCH 420/512] Differentiate when the sms message successfully matched an extension in the chatplan, and when it fell through. --- src/mod/applications/mod_sms/mod_sms.c | 7 ++++--- src/switch_loadable_module.c | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/mod/applications/mod_sms/mod_sms.c b/src/mod/applications/mod_sms/mod_sms.c index d90896f74d..15d0de6233 100644 --- a/src/mod/applications/mod_sms/mod_sms.c +++ b/src/mod/applications/mod_sms/mod_sms.c @@ -395,7 +395,7 @@ static switch_event_t *chatplan_hunt(switch_event_t *event) static switch_status_t chat_send(switch_event_t *message_event) { - switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_status_t status = SWITCH_STATUS_BREAK; switch_event_t *exten; int forwards = 0; const char *var; @@ -428,14 +428,15 @@ static switch_status_t chat_send(switch_event_t *message_event) for (hp = exten->headers; hp; hp = hp->next) { status = switch_core_execute_chat_app(message_event, hp->name, hp->value); if (!SWITCH_READ_ACCEPTABLE(status)) { + status = SWITCH_STATUS_SUCCESS; break; } } switch_event_destroy(&exten); - status = SWITCH_STATUS_BREAK; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS chatplan no actions found\n"); } - return status; diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index a94c274b6d..d63ff074f1 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -564,12 +564,21 @@ static switch_status_t do_chat_send(switch_event_t *message_event) if ((ci = (switch_chat_interface_t *) val)) { if (ci->chat_send && !strncasecmp(ci->interface_name, "GLOBAL_", 7)) { status = ci->chat_send(message_event); - if (status == SWITCH_STATUS_BREAK) { + if (status == SWITCH_STATUS_SUCCESS) { + /* The event was handled by an extension in the chatplan, + * so the event will be duplicated, modified and queued again, + * but it won't be processed by the chatplan again. + * So this copy of the event can be destroyed by the caller. + */ + switch_mutex_unlock(loadable_modules.mutex); + return SWITCH_STATUS_SUCCESS; + } else if (status == SWITCH_STATUS_BREAK) { + /* The event went through the chatplan, but no extension matched + * to handle the sms messsage. It'll be attempted to be delivered + * directly, and unless that works the sms delivery will have failed. + */ do_skip = 1; - status = SWITCH_STATUS_SUCCESS; - } - - if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { + } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Chat Interface Error [%s]!\n", dest_proto); break; } From f8aa3777e9aa4354f7d10827db2b5647baea2162 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Nov 2012 18:43:22 -0600 Subject: [PATCH 421/512] thread pool was not releasing surplus threads after timeout --- src/include/private/switch_core_pvt.h | 1 + src/switch_core_session.c | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 40f51ba61a..137c129f27 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -285,6 +285,7 @@ struct switch_session_manager { int ready; int running; int busy; + int nuking; }; extern struct switch_session_manager session_manager; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index cf7daaac16..449cd1c3c4 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1530,13 +1530,15 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_th while(session_manager.ready) { switch_status_t check_status; + pop = NULL; + if (check) { check_status = switch_queue_trypop(session_manager.thread_queue, &pop); } else { check_status = switch_queue_pop(session_manager.thread_queue, &pop); } - if (check_status == SWITCH_STATUS_SUCCESS) { + if (check_status == SWITCH_STATUS_SUCCESS && pop) { switch_thread_data_t *td = (switch_thread_data_t *) pop; if (!td) break; @@ -1609,12 +1611,11 @@ static switch_status_t check_queue(void) int x = 0; switch_mutex_lock(session_manager.mutex); - ttl = switch_queue_size(session_manager.thread_queue); + ttl = switch_queue_size(session_manager.thread_queue) - session_manager.nuking; x = (session_manager.running - session_manager.busy); switch_mutex_unlock(session_manager.mutex); - while (x < ttl) { switch_thread_t *thread; switch_threadattr_t *thd_attr; @@ -1653,13 +1654,26 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_t switch_yield(100000); if (++x == 300) { - switch_queue_interrupt_all(session_manager.thread_queue); - x = 0; + switch_mutex_lock(session_manager.mutex); + session_manager.nuking = (session_manager.running - session_manager.busy); + switch_mutex_unlock(session_manager.mutex); + + if (session_manager.nuking) { + int i = 0; + + for (i = 0; i < session_manager.nuking; i++) { + switch_queue_push(session_manager.thread_queue, NULL); + } + + x--; + } else { + x = 0; + } } check_queue(); } - + return NULL; } From 4b96a8b2e5d015207412dd13d11729e11f3e580e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 14 Nov 2012 19:19:03 -0600 Subject: [PATCH 422/512] wait_for_state_or_greater actually needs >= --- src/mod/endpoints/mod_loopback/mod_loopback.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 7c72d7e136..bc2c1a61e9 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -716,7 +716,7 @@ static void switch_channel_wait_for_state_or_greater(switch_channel_t *channel, for (;;) { if ((switch_channel_get_state(channel) < CS_HANGUP && - switch_channel_get_state(channel) == switch_channel_get_running_state(channel) && switch_channel_get_running_state(channel) == want_state) || + switch_channel_get_state(channel) == switch_channel_get_running_state(channel) && switch_channel_get_running_state(channel) >= want_state) || (other_channel && switch_channel_down_nosig(other_channel)) || switch_channel_down(channel)) { break; } @@ -807,9 +807,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc switch_channel_t *ch_a = NULL, *ch_b = NULL; int good_to_go = 0; + switch_mutex_unlock(tech_pvt->mutex); find_non_loopback_bridge(session, &br_a, &a_uuid); find_non_loopback_bridge(tech_pvt->other_session, &br_b, &b_uuid); - + switch_mutex_lock(tech_pvt->mutex); if (br_a) { From a9017b4d4d227a1f3dabf3105757d7cff8c738d3 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 15 Nov 2012 08:39:10 -0500 Subject: [PATCH 423/512] FS-4649: --resolve fix ifdefs for opengl headers --- libs/tiff-4.0.2/tools/tiffgt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/tiff-4.0.2/tools/tiffgt.c b/libs/tiff-4.0.2/tools/tiffgt.c index de420396c6..4c8e50923f 100644 --- a/libs/tiff-4.0.2/tools/tiffgt.c +++ b/libs/tiff-4.0.2/tools/tiffgt.c @@ -31,11 +31,16 @@ #include #include -#if HAVE_APPLE_OPENGL_FRAMEWORK +#if HAVE_OPENGL_GL_H # include +#endif +#if HAVE_GLUT_GLUT_H # include -#else +#endif +#if HAVE_GL_GL_H # include +#endif +#if HAVE_GL_GLUT_H # include #endif From 893cd7beb7e1d019121e33686b405f19539fefe6 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Thu, 15 Nov 2012 20:37:52 +0000 Subject: [PATCH 424/512] Add att_xfer_destination_number variable to indicate the original destination number of the attended transfer leg on REFER for semi-attended transfer scenarios. --- src/mod/endpoints/mod_sofia/sofia.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 89024c5203..c7b221da0b 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6731,10 +6731,12 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t if ((a_session = switch_core_session_locate(br_a))) { const char *moh = profile->hold_music; switch_channel_t *a_channel = switch_core_session_get_channel(a_session); + switch_caller_profile_t *prof = switch_channel_get_caller_profile(channel_b); const char *tmp; switch_core_event_hook_add_state_change(a_session, xfer_hanguphook); switch_channel_set_variable(a_channel, "att_xfer_kill_uuid", switch_core_session_get_uuid(b_session)); + switch_channel_set_variable(a_channel, "att_xfer_destination_number", prof->destination_number); if (profile->media_options & MEDIA_OPT_BYPASS_AFTER_ATT_XFER) { switch_channel_set_flag(a_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE); From 57f44f9f58b823f1b09e8345ddc9e1b2f1ea508e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Nov 2012 12:54:01 -0600 Subject: [PATCH 425/512] fix regression with presence packet storm --- src/mod/endpoints/mod_sofia/sofia_presence.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index ab6576d52c..ed514e5960 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1461,10 +1461,9 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); } - +#if 0 if (hup && dh.hits < 1) { /* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */ - if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name); @@ -1472,9 +1471,10 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", euser, host); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence"); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); + sofia_event_fire(profile, &s_event); } } - +#endif if (!zstr((char *) helper.stream.data)) { char *this_sql = (char *) helper.stream.data; From 73f022873b89d73d5a0da209e4c5dfe2341bae06 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Nov 2012 12:54:35 -0600 Subject: [PATCH 426/512] FS-4836 try this --- src/include/switch_channel.h | 2 ++ src/include/switch_core.h | 1 + src/switch_channel.c | 42 +++++++++++++++++++++++++++++++-- src/switch_core_session.c | 5 ++++ src/switch_core_state_machine.c | 2 ++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index bddfb0f2d2..cd8cbb47f0 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -643,6 +643,8 @@ SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension( SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension); SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *channel); SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_channel_t *channel); +SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel); +SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel); SWITCH_END_EXTERN_C #endif diff --git a/src/include/switch_core.h b/src/include/switch_core.h index ead85fdf4a..210b676b1e 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -722,6 +722,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_co /*! \brief Signal a session's state machine thread that a state change has occured */ +SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_session_t *session); diff --git a/src/switch_channel.c b/src/switch_channel.c index 9e40829f82..a057f9deb8 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -129,6 +129,7 @@ struct switch_channel { switch_mutex_t *dtmf_mutex; switch_mutex_t *flag_mutex; switch_mutex_t *state_mutex; + switch_mutex_t *thread_mutex; switch_mutex_t *profile_mutex; switch_core_session_t *session; switch_channel_state_t state; @@ -352,6 +353,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->state_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&(*channel)->thread_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool); (*channel)->hangup_cause = SWITCH_CAUSE_NONE; (*channel)->name = ""; @@ -1925,6 +1927,32 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *nam return CS_DESTROY; } +static inline void careful_set(switch_channel_t *channel, switch_channel_state_t *state, switch_channel_state_t val) { + + if (switch_mutex_trylock(channel->thread_mutex)) { + *state = val; + switch_mutex_unlock(channel->thread_mutex); + } else { + switch_mutex_t *mutex = switch_core_session_get_mutex(channel->session); + int x = 0; + + for (x = 0; x < 100; x++) { + if (switch_mutex_trylock(mutex) == SWITCH_STATUS_SUCCESS) { + *state = val; + switch_mutex_unlock(mutex); + break; + } else { + switch_cond_next(); + } + } + + if (x == 100) { + *state = val; + } + + } +} + SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel, switch_channel_state_t state, const char *file, const char *func, int line) { @@ -1950,7 +1978,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state( switch_mutex_lock(channel->state_mutex); - channel->running_state = state; + careful_set(channel, &channel->running_state, state); if (state <= CS_DESTROY) { switch_event_t *event; @@ -2218,7 +2246,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]); - channel->state = state; + careful_set(channel, &channel->state, state); if (state == CS_HANGUP && !channel->hangup_cause) { channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING; @@ -2240,6 +2268,16 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c return channel->state; } +SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel) +{ + switch_mutex_lock(channel->thread_mutex); +} + +SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel) +{ + switch_mutex_unlock(channel->thread_mutex); +} + SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *channel, switch_event_t *event) { switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 449cd1c3c4..eb250b8dea 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1245,6 +1245,11 @@ SWITCH_DECLARE(switch_channel_t *) switch_core_session_get_channel(switch_core_s return session->channel; } +SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session) +{ + return session->mutex; +} + SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(switch_core_session_t *session) { switch_status_t status; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 87b8a32a20..daa5bf37d4 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -521,11 +521,13 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_ivr_parse_all_events(session); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { + switch_channel_state_thread_lock(session->channel); switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { switch_thread_cond_wait(session->cond, session->mutex); } switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING); + switch_channel_state_thread_unlock(session->channel); } switch_ivr_parse_all_events(session); From 057861867e00646cc1677aa3b77ff87a0d2b05ae Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Nov 2012 13:14:08 -0600 Subject: [PATCH 427/512] FS-4836 not quite --- src/include/switch_channel.h | 2 -- src/include/switch_core.h | 1 - src/switch_channel.c | 42 ++------------------------------- src/switch_core_session.c | 5 ---- src/switch_core_state_machine.c | 2 -- 5 files changed, 2 insertions(+), 50 deletions(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index cd8cbb47f0..bddfb0f2d2 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -643,8 +643,6 @@ SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension( SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension); SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *channel); SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_channel_t *channel); -SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel); -SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel); SWITCH_END_EXTERN_C #endif diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 210b676b1e..ead85fdf4a 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -722,7 +722,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_co /*! \brief Signal a session's state machine thread that a state change has occured */ -SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_session_t *session); diff --git a/src/switch_channel.c b/src/switch_channel.c index a057f9deb8..9e40829f82 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -129,7 +129,6 @@ struct switch_channel { switch_mutex_t *dtmf_mutex; switch_mutex_t *flag_mutex; switch_mutex_t *state_mutex; - switch_mutex_t *thread_mutex; switch_mutex_t *profile_mutex; switch_core_session_t *session; switch_channel_state_t state; @@ -353,7 +352,6 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->state_mutex, SWITCH_MUTEX_NESTED, pool); - switch_mutex_init(&(*channel)->thread_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool); (*channel)->hangup_cause = SWITCH_CAUSE_NONE; (*channel)->name = ""; @@ -1927,32 +1925,6 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *nam return CS_DESTROY; } -static inline void careful_set(switch_channel_t *channel, switch_channel_state_t *state, switch_channel_state_t val) { - - if (switch_mutex_trylock(channel->thread_mutex)) { - *state = val; - switch_mutex_unlock(channel->thread_mutex); - } else { - switch_mutex_t *mutex = switch_core_session_get_mutex(channel->session); - int x = 0; - - for (x = 0; x < 100; x++) { - if (switch_mutex_trylock(mutex) == SWITCH_STATUS_SUCCESS) { - *state = val; - switch_mutex_unlock(mutex); - break; - } else { - switch_cond_next(); - } - } - - if (x == 100) { - *state = val; - } - - } -} - SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel, switch_channel_state_t state, const char *file, const char *func, int line) { @@ -1978,7 +1950,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state( switch_mutex_lock(channel->state_mutex); - careful_set(channel, &channel->running_state, state); + channel->running_state = state; if (state <= CS_DESTROY) { switch_event_t *event; @@ -2246,7 +2218,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]); - careful_set(channel, &channel->state, state); + channel->state = state; if (state == CS_HANGUP && !channel->hangup_cause) { channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING; @@ -2268,16 +2240,6 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c return channel->state; } -SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel) -{ - switch_mutex_lock(channel->thread_mutex); -} - -SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel) -{ - switch_mutex_unlock(channel->thread_mutex); -} - SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *channel, switch_event_t *event) { switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index eb250b8dea..449cd1c3c4 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1245,11 +1245,6 @@ SWITCH_DECLARE(switch_channel_t *) switch_core_session_get_channel(switch_core_s return session->channel; } -SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session) -{ - return session->mutex; -} - SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(switch_core_session_t *session) { switch_status_t status; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index daa5bf37d4..87b8a32a20 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -521,13 +521,11 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_ivr_parse_all_events(session); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { - switch_channel_state_thread_lock(session->channel); switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { switch_thread_cond_wait(session->cond, session->mutex); } switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING); - switch_channel_state_thread_unlock(session->channel); } switch_ivr_parse_all_events(session); From 6f2976298f61a17bafcb31b0c4b53c642f278d1e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Nov 2012 13:16:50 -0600 Subject: [PATCH 428/512] FS-4836 ok try this --- src/include/switch_channel.h | 2 ++ src/include/switch_core.h | 1 + src/switch_channel.c | 42 +++++++++++++++++++++++++++++++-- src/switch_core_session.c | 5 ++++ src/switch_core_state_machine.c | 2 ++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index bddfb0f2d2..cd8cbb47f0 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -643,6 +643,8 @@ SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension( SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension); SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *channel); SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_channel_t *channel); +SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel); +SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel); SWITCH_END_EXTERN_C #endif diff --git a/src/include/switch_core.h b/src/include/switch_core.h index ead85fdf4a..210b676b1e 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -722,6 +722,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_co /*! \brief Signal a session's state machine thread that a state change has occured */ +SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(_In_ switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_signal_state_change(_In_ switch_core_session_t *session); diff --git a/src/switch_channel.c b/src/switch_channel.c index 9e40829f82..5fa30564d2 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -129,6 +129,7 @@ struct switch_channel { switch_mutex_t *dtmf_mutex; switch_mutex_t *flag_mutex; switch_mutex_t *state_mutex; + switch_mutex_t *thread_mutex; switch_mutex_t *profile_mutex; switch_core_session_t *session; switch_channel_state_t state; @@ -352,6 +353,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->state_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&(*channel)->thread_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool); (*channel)->hangup_cause = SWITCH_CAUSE_NONE; (*channel)->name = ""; @@ -1925,6 +1927,32 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_name_state(const char *nam return CS_DESTROY; } +static inline void careful_set(switch_channel_t *channel, switch_channel_state_t *state, switch_channel_state_t val) { + + if (switch_mutex_trylock(channel->thread_mutex) == SWITCH_STATUS_SUCCESS) { + *state = val; + switch_mutex_unlock(channel->thread_mutex); + } else { + switch_mutex_t *mutex = switch_core_session_get_mutex(channel->session); + int x = 0; + + for (x = 0; x < 100; x++) { + if (switch_mutex_trylock(mutex) == SWITCH_STATUS_SUCCESS) { + *state = val; + switch_mutex_unlock(mutex); + break; + } else { + switch_cond_next(); + } + } + + if (x == 100) { + *state = val; + } + + } +} + SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel, switch_channel_state_t state, const char *file, const char *func, int line) { @@ -1950,7 +1978,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state( switch_mutex_lock(channel->state_mutex); - channel->running_state = state; + careful_set(channel, &channel->running_state, state); if (state <= CS_DESTROY) { switch_event_t *event; @@ -2218,7 +2246,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) State Change %s -> %s\n", channel->name, state_names[last_state], state_names[state]); - channel->state = state; + careful_set(channel, &channel->state, state); if (state == CS_HANGUP && !channel->hangup_cause) { channel->hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING; @@ -2240,6 +2268,16 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_state(switch_c return channel->state; } +SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel) +{ + switch_mutex_lock(channel->thread_mutex); +} + +SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel) +{ + switch_mutex_unlock(channel->thread_mutex); +} + SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *channel, switch_event_t *event) { switch_caller_profile_t *caller_profile, *originator_caller_profile = NULL, *originatee_caller_profile = NULL; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 449cd1c3c4..eb250b8dea 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1245,6 +1245,11 @@ SWITCH_DECLARE(switch_channel_t *) switch_core_session_get_channel(switch_core_s return session->channel; } +SWITCH_DECLARE(switch_mutex_t *) switch_core_session_get_mutex(switch_core_session_t *session) +{ + return session->mutex; +} + SWITCH_DECLARE(switch_status_t) switch_core_session_wake_session_thread(switch_core_session_t *session) { switch_status_t status; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 87b8a32a20..daa5bf37d4 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -521,11 +521,13 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_ivr_parse_all_events(session); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { + switch_channel_state_thread_lock(session->channel); switch_channel_set_flag(session->channel, CF_THREAD_SLEEPING); if (switch_channel_get_state(session->channel) == switch_channel_get_running_state(session->channel)) { switch_thread_cond_wait(session->cond, session->mutex); } switch_channel_clear_flag(session->channel, CF_THREAD_SLEEPING); + switch_channel_state_thread_unlock(session->channel); } switch_ivr_parse_all_events(session); From 55eb2c5ccf6c54ee6a2bdf709c625497a01f09d8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Nov 2012 17:58:40 -0600 Subject: [PATCH 429/512] fix issue where max event threads would always launch as soon as you only needed one more --- src/switch_event.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index 7a965d4dcd..259a5fa25c 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -37,7 +37,7 @@ #include "tpl.h" //#define SWITCH_EVENT_RECYCLE -#define DISPATCH_QUEUE_LEN 100 +#define DISPATCH_QUEUE_LEN 10000 //#define DEBUG_DISPATCH_QUEUES /*! \brief A node to store binded events */ @@ -291,6 +291,8 @@ static void *SWITCH_THREAD_FUNC switch_event_dispatch_thread(switch_thread_t *th } +static int PENDING = 0; + static switch_status_t switch_event_queue_dispatch_event(switch_event_t **eventp) { @@ -302,11 +304,14 @@ static switch_status_t switch_event_queue_dispatch_event(switch_event_t **eventp while (event) { int launch = 0; - + switch_mutex_lock(EVENT_QUEUE_MUTEX); - if (switch_queue_size(EVENT_DISPATCH_QUEUE) > (unsigned int)(DISPATCH_QUEUE_LEN * DISPATCH_THREAD_COUNT)) { - launch++; + if (!PENDING && switch_queue_size(EVENT_DISPATCH_QUEUE) > (unsigned int)(DISPATCH_QUEUE_LEN * DISPATCH_THREAD_COUNT)) { + if (SOFT_MAX_DISPATCH + 1 > MAX_DISPATCH) { + launch++; + PENDING++; + } } switch_mutex_unlock(EVENT_QUEUE_MUTEX); @@ -315,6 +320,10 @@ static switch_status_t switch_event_queue_dispatch_event(switch_event_t **eventp if (SOFT_MAX_DISPATCH + 1 < MAX_DISPATCH) { switch_event_launch_dispatch_threads(SOFT_MAX_DISPATCH + 1); } + + switch_mutex_lock(EVENT_QUEUE_MUTEX); + PENDING--; + switch_mutex_unlock(EVENT_QUEUE_MUTEX); } *eventp = NULL; From 6644cefb20f780d4785f6583dfe63283bb37b7f1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Nov 2012 17:59:11 -0600 Subject: [PATCH 430/512] finish fixing thread pool logic from yesterday --- src/include/private/switch_core_pvt.h | 2 +- src/switch_core_session.c | 32 +++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 137c129f27..7bdf1e3dd0 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -285,7 +285,7 @@ struct switch_session_manager { int ready; int running; int busy; - int nuking; + int popping; }; extern struct switch_session_manager session_manager; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index eb250b8dea..e1093c50f3 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1540,7 +1540,15 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_th if (check) { check_status = switch_queue_trypop(session_manager.thread_queue, &pop); } else { + switch_mutex_lock(session_manager.mutex); + session_manager.popping++; + switch_mutex_unlock(session_manager.mutex); + check_status = switch_queue_pop(session_manager.thread_queue, &pop); + + switch_mutex_lock(session_manager.mutex); + session_manager.popping--; + switch_mutex_unlock(session_manager.mutex); } if (check_status == SWITCH_STATUS_SUCCESS && pop) { @@ -1616,7 +1624,7 @@ static switch_status_t check_queue(void) int x = 0; switch_mutex_lock(session_manager.mutex); - ttl = switch_queue_size(session_manager.thread_queue) - session_manager.nuking; + ttl = switch_queue_size(session_manager.thread_queue); x = (session_manager.running - session_manager.busy); switch_mutex_unlock(session_manager.mutex); @@ -1659,18 +1667,24 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_t switch_yield(100000); if (++x == 300) { - switch_mutex_lock(session_manager.mutex); - session_manager.nuking = (session_manager.running - session_manager.busy); - switch_mutex_unlock(session_manager.mutex); + if (session_manager.popping) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, + "Thread pool: running:%d busy:%d popping:%d\n", session_manager.running, session_manager.busy, session_manager.popping); - if (session_manager.nuking) { - int i = 0; + if (session_manager.popping) { + int i = 0; + + switch_mutex_lock(session_manager.mutex); + for (i = 0; i < session_manager.popping; i++) { + switch_queue_trypush(session_manager.thread_queue, NULL); + } + switch_mutex_unlock(session_manager.mutex); - for (i = 0; i < session_manager.nuking; i++) { - switch_queue_push(session_manager.thread_queue, NULL); } - + x--; + + continue; } else { x = 0; } From d48e3de7c8057d11856e200aae1abb629d597f5b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 15 Nov 2012 21:07:58 -0600 Subject: [PATCH 431/512] make it so when you put someone on hold and then they attended transfer you, the resulting bridge will still be playing hold music --- src/include/switch_types.h | 1 + src/mod/endpoints/mod_sofia/mod_sofia.c | 42 ++++++++++++++----------- src/switch_ivr_bridge.c | 21 ++++++++++++- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index d7d96b5aaf..15993c7993 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1255,6 +1255,7 @@ typedef enum { CF_NO_CDR, CF_EARLY_OK, CF_MEDIA_TRANS, + CF_HOLD_ON_BRIDGE, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */ CF_FLAG_MAX diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 55b99ac31c..deedea0802 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2456,25 +2456,31 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_HOLD: { - sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD); - switch_channel_set_flag(channel, CF_LEG_HOLDING); - sofia_glue_do_invite(session); - if (!zstr(msg->string_arg)) { - char message[256] = ""; - const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent"); - if (ua && switch_stristr("snom", ua)) { - snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", msg->string_arg, tech_pvt->caller_profile->destination_number); - nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"), - TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END()); - } else if (ua && switch_stristr("polycom", ua)) { - snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number); - nua_update(tech_pvt->nh, - NUTAG_SESSION_TIMER(tech_pvt->session_timeout), - NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher), - TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)), - TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)), - TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); + if (msg->numeric_arg) { + sofia_glue_toggle_hold(tech_pvt, 1); + } else { + + sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD); + switch_channel_set_flag(channel, CF_LEG_HOLDING); + sofia_glue_do_invite(session); + if (!zstr(msg->string_arg)) { + char message[256] = ""; + const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent"); + + if (ua && switch_stristr("snom", ua)) { + snprintf(message, sizeof(message), "From:\r\nTo: \"%s\" %s\r\n", msg->string_arg, tech_pvt->caller_profile->destination_number); + nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END()); + } else if (ua && switch_stristr("polycom", ua)) { + snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number); + nua_update(tech_pvt->nh, + NUTAG_SESSION_TIMER(tech_pvt->session_timeout), + NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher), + TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)), + TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); + } } } } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index b286ab5918..7eb96b287a 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -316,7 +316,16 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if ((b_state = switch_channel_down_nosig(chan_b))) { goto end_of_bridge_loop; } - + + if (switch_channel_test_flag(chan_a, CF_HOLD_ON_BRIDGE)) { + switch_core_session_message_t hmsg = { 0 }; + switch_channel_clear_flag(chan_a, CF_HOLD_ON_BRIDGE); + hmsg.message_id = SWITCH_MESSAGE_INDICATE_HOLD; + hmsg.from = __FILE__; + hmsg.numeric_arg = 1; + switch_core_session_receive_message(session_a, &hmsg); + } + if (read_frame_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a) && switch_core_session_private_event_count(session_a)) { switch_channel_set_flag(chan_b, CF_SUSPEND); msg.numeric_arg = 42; @@ -1556,6 +1565,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu originatee_channel = switch_core_session_get_channel(originatee_session); + if (switch_channel_test_flag(originator_channel, CF_LEG_HOLDING)) { + switch_channel_set_flag(originator_channel, CF_HOLD_ON_BRIDGE); + } + + if (switch_channel_test_flag(originatee_channel, CF_LEG_HOLDING)) { + switch_channel_set_flag(originatee_channel, CF_HOLD_ON_BRIDGE); + } + + + if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) { switch_channel_flip_cid(originatee_channel); switch_channel_set_flag(originatee_channel, CF_DIALPLAN); From 60630274f1915c84cc2148fc6df43f5760fb4b8c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Nov 2012 07:43:19 -0600 Subject: [PATCH 432/512] FS-4840 --resolve --- .../endpoints/mod_dingaling/mod_dingaling.c | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index f8f233aa87..e7c42e727d 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -2650,6 +2650,45 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } +static switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + mdl_profile_t *profile = NULL; + switch_hash_index_t *hi; + void *val; + const void *vvar; + switch_console_callback_match_t *my_matches = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; + + for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + profile = (mdl_profile_t *) val; + if (!strncmp("dl_logout", line, 9)) { + if (profile->handle) { + switch_console_push_match(&my_matches, profile->name); + } + } else if (!strncmp("dl_login", line, 8)) { + if (!switch_test_flag(profile, TFLAG_IO)) { + char *profile_name = switch_mprintf("%s%s", "profile=", profile->name); + switch_console_push_match(&my_matches, profile_name); + free(profile_name); + } + } else if (!strncmp("dl_pres", line, 7)) { + if (profile->user_flags & LDL_FLAG_COMPONENT) { + switch_console_push_match(&my_matches, profile->name); + } + } else { + switch_console_push_match(&my_matches, profile->name); + } + } + + if (my_matches) { + *matches = my_matches; + status = SWITCH_STATUS_SUCCESS; + } + + return status; +} + SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load) { switch_chat_interface_t *chat_interface; @@ -2726,6 +2765,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load) SWITCH_ADD_API(api_interface, "dingaling", "DingaLing Menu", dingaling, DINGALING_SYNTAX); SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send); + switch_console_set_complete("add dl_debug ::[true:false"); + switch_console_set_complete("add dl_pres ::dingaling::list_profiles"); + switch_console_set_complete("add dl_logout ::dingaling::list_profiles"); + switch_console_set_complete("add dl_login ::dingaling::list_profiles"); + switch_console_set_complete("add dl_login login="); + switch_console_set_complete("add dingaling status"); + switch_console_set_complete("add dingaling reload"); + switch_console_add_complete_func("::dingaling::list_profiles", list_profiles); + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } From 59c8982083da5e0ef2759a3aaafbba185b1fed78 Mon Sep 17 00:00:00 2001 From: Christopher Rienzo Date: Fri, 16 Nov 2012 17:46:35 +0000 Subject: [PATCH 433/512] Fix minor oops on FS-4840 --- src/mod/endpoints/mod_dingaling/mod_dingaling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index e7c42e727d..70f699363a 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -2668,7 +2668,7 @@ static switch_status_t list_profiles(const char *line, const char *cursor, switc } } else if (!strncmp("dl_login", line, 8)) { if (!switch_test_flag(profile, TFLAG_IO)) { - char *profile_name = switch_mprintf("%s%s", "profile=", profile->name); + char *profile_name = switch_mprintf("profile=%s", profile->name); switch_console_push_match(&my_matches, profile_name); free(profile_name); } From 7448b075b745469e9d2170453d9652de360f1ff4 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Fri, 16 Nov 2012 14:30:00 -0500 Subject: [PATCH 434/512] FS-4760 --resolve --- src/mod/applications/mod_callcenter/mod_callcenter.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 82893aef0d..2e20f3c969 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1389,9 +1389,6 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_time_t t_agent_answered = 0; switch_time_t t_member_called = atoi(h->member_joined_epoch); switch_event_t *event = NULL; - char agent_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; - - switch_uuid_str(agent_uuid_str, sizeof(agent_uuid_str)); switch_mutex_lock(globals.mutex); globals.threads++; @@ -1421,7 +1418,6 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Type", h->agent_type); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid_str); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name); @@ -1451,7 +1447,6 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "loopback_bowout", "false"); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "loopback_bowout_on_execute", "false"); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true"); - switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "origination_uuid", "%s", agent_uuid_str); switch_channel_process_export(member_channel, NULL, ovars, "cc_export_vars"); From 961a6fbcad70796786860f673629fd0827b6285e Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Fri, 16 Nov 2012 14:02:17 -0800 Subject: [PATCH 435/512] Update ChangeLog for 1.2.4 (not much here since it was mostly bug fixes and stability stuff) --- docs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/ChangeLog b/docs/ChangeLog index d73e3630af..7eb7c5da55 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -1,3 +1,7 @@ +freeswitch (1.2.4) + core: Add Postgres core db support (r:0c1180d5) + mod_cdr_mongodb: update MongoDB driver to v0.6 (r:10093b44) + mod_dingaling: do lookup in dingaling when an address is specified as host:foo.bar.com like sofia does (r:fbfe830a) freeswitch (1.2.3) core: add hold_events variable with start and stop times for each hold (r:9a193a9c) core: update json lib in core and ESL and re-apply old patches (r:5a956890) From 6c2baed108de7cbeea94b6f526cfaa99d96de8c6 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick Date: Fri, 16 Nov 2012 23:36:29 +0100 Subject: [PATCH 436/512] Fix segfault in mod_cdr_mongo when "number" is null. Thanks Dave May for bug report and patch. Fixes FS-4843. --- src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c index d4c4d7cf9a..8a2b30d5e9 100644 --- a/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c +++ b/src/mod/event_handlers/mod_cdr_mongodb/mod_cdr_mongodb.c @@ -204,8 +204,8 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) bson_append_start_object(&cdr, "extension"); - bson_append_string(&cdr, "name", caller_profile->caller_extension->extension_name); - bson_append_string(&cdr, "number", caller_profile->caller_extension->extension_number); + bson_append_string(&cdr, "name", switch_str_nil(caller_profile->caller_extension->extension_name)); + bson_append_string(&cdr, "number", switch_str_nil(caller_profile->caller_extension->extension_number)); if (caller_profile->caller_extension->current_application) { bson_append_string(&cdr, "current_app", caller_profile->caller_extension->current_application->application_name); From 43b094f139f55b3dd3130aad4b3a6d1ef32a445d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Nov 2012 20:09:38 -0600 Subject: [PATCH 437/512] fix some sql order issues --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 2 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 16 +++++++++++++++- src/mod/endpoints/mod_sofia/sofia_presence.c | 13 +++++++------ src/mod/endpoints/mod_sofia/sofia_reg.c | 11 ++++++++++- src/switch_core_sqldb.c | 6 +++--- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 909516d63e..5240553caa 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -1015,6 +1015,7 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex); void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex); void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic); +void sofia_glue_execute_sql_soon(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic); void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot); void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now); void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index c7b221da0b..b4d3e894a3 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2530,7 +2530,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_snprintf(qname, sizeof(qname), "sofia:%s", profile->name); switch_sql_queue_manager_init_name(qname, &profile->qm, - 1, + 2, profile->odbc_dsn ? profile->odbc_dsn : profile->dbname, SWITCH_MAX_TRANS, profile->pre_trans_execute, diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 74096a3173..37caeba651 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6373,7 +6373,7 @@ void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t switch_assert(sqlp && *sqlp); sql = *sqlp; - switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic); + switch_sql_queue_manager_push(profile->qm, sql, 1, !sql_already_dynamic); if (sql_already_dynamic) { *sqlp = NULL; @@ -6395,6 +6395,20 @@ void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bo } } +void sofia_glue_execute_sql_soon(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic) +{ + char *sql; + + switch_assert(sqlp && *sqlp); + sql = *sqlp; + + switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic); + + if (sql_already_dynamic) { + *sqlp = NULL; + } +} + switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line) { diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index ed514e5960..e11d96ff76 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1350,7 +1350,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event } if (zstr(call_id)) { - + sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and " "sip_subscriptions.event != 'line-seize' " "and sip_subscriptions.proto='%q' and (event='%q' or event='%q') and sub_to_user='%q' and " @@ -1366,8 +1366,8 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql); } - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - + sofia_glue_execute_sql_soon(profile, &sql, SWITCH_TRUE); + sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," @@ -1376,7 +1376,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," "sip_subscriptions.accept,sip_subscriptions.profile_name" ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q'," - "sip_subscriptions.version, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to," + "sip_subscriptions.version+1, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to," "sip_subscriptions.network_ip, sip_subscriptions.network_port " "from sip_subscriptions " "left join sip_presence on " @@ -1395,6 +1395,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event event_type, alt_event_type, euser, host, profile->sipip, profile->extsipip ? profile->extsipip : "N/A", host); } else { + sql = switch_mprintf("update sip_subscriptions set version=version+1 where sip_subscriptions.event != 'line-seize' and " "hostname='%q' and profile_name = '%q' and sip_subscriptions.call_id='%q'", mod_sofia_globals.hostname, profile->name, call_id); @@ -1404,7 +1405,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql); } - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + sofia_glue_execute_sql_soon(profile, &sql, SWITCH_TRUE); sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," @@ -1413,7 +1414,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," "sip_subscriptions.accept,sip_subscriptions.profile_name" ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q'," - "sip_subscriptions.version, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to," + "sip_subscriptions.version+1, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to," "sip_subscriptions.network_ip, sip_subscriptions.network_port " "from sip_subscriptions " "left join sip_presence on " diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 4efa9fabe6..79b49c1b6b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -2353,6 +2353,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (zstr(np)) { nonce_cb_t cb = { 0 }; long nc_long = 0; + int sanity = 0; + first = 1; if (nc) { @@ -2366,7 +2368,14 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, cb.nplen = nplen; switch_assert(sql != NULL); - sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nonce_callback, &cb); + + do { + if (sanity) { + switch_yield(100000 * sanity); + } + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nonce_callback, &cb); + } while(nc_long < 2 && ++sanity < 10 && zstr(np)); + free(sql); //if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) { diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 17a3f3b0f8..7d1e6c8716 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -835,7 +835,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans_full(sw switch(dbh->type) { case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql_real(dbh, "BEGIN", &errmsg); + switch_cache_db_execute_sql_real(dbh, "BEGIN EXCLUSIVE", &errmsg); } break; case SCDB_TYPE_ODBC: @@ -1497,7 +1497,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) switch(qm->event_db->type) { case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql_real(qm->event_db, "BEGIN", &errmsg); + switch_cache_db_execute_sql_real(qm->event_db, "BEGIN EXCLUSIVE", &errmsg); } break; case SCDB_TYPE_ODBC: @@ -2979,7 +2979,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch(sql_manager.dbh->type) { case SCDB_TYPE_CORE_DB: { - switch_cache_db_execute_sql_real(sql_manager.dbh, "BEGIN", &err); + switch_cache_db_execute_sql_real(sql_manager.dbh, "BEGIN EXCLUSIVE", &err); } break; case SCDB_TYPE_ODBC: From 62c95eed254b8795708b8f3dea930c8252cf7bbd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Nov 2012 20:17:15 -0600 Subject: [PATCH 438/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 63d7c575a8..db62c5e6a1 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.4b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.4], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [4b]) +AC_SUBST(SWITCH_VERSION_MICRO, [4]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 6ac2e9cd71779c4c9cb00c28279b4f8b4ef75b66 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Nov 2012 20:22:42 -0600 Subject: [PATCH 439/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index db62c5e6a1..c1a43ea170 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.4], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.5b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [4]) +AC_SUBST(SWITCH_VERSION_MICRO, [5b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From ca18dcbe02479a6798b20afb56dee3cc40e21ba3 Mon Sep 17 00:00:00 2001 From: Christopher Rienzo Date: Sat, 17 Nov 2012 16:52:36 -0500 Subject: [PATCH 440/512] mod_dingaling- fix input check for dl_login so that dynamic profiles can be used --- src/mod/endpoints/mod_dingaling/mod_dingaling.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 70f699363a..b0ed56b4c9 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -3090,7 +3090,7 @@ SWITCH_STANDARD_API(dingaling) SWITCH_STANDARD_API(dl_login) { - char *argv[10] = { 0 }; + char *argv[20] = { 0 }; int argc = 0; char *var, *val, *myarg = NULL; mdl_profile_t *profile = NULL; @@ -3112,7 +3112,7 @@ SWITCH_STANDARD_API(dl_login) argc = switch_separate_string(myarg, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - if (zstr(cmd) || argc != 1) { + if (zstr(cmd)) { stream->write_function(stream, "USAGE: %s\n", LOGIN_SYNTAX); status = SWITCH_STATUS_SUCCESS; goto done; From de7dc5685dd20a0539360d5b330d69663ae470a4 Mon Sep 17 00:00:00 2001 From: Christopher Rienzo Date: Sat, 17 Nov 2012 17:32:12 -0500 Subject: [PATCH 441/512] Remove redundant syntax check in dl_login --- src/mod/endpoints/mod_dingaling/mod_dingaling.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index b0ed56b4c9..24a0e497a9 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -3112,12 +3112,6 @@ SWITCH_STANDARD_API(dl_login) argc = switch_separate_string(myarg, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - if (zstr(cmd)) { - stream->write_function(stream, "USAGE: %s\n", LOGIN_SYNTAX); - status = SWITCH_STATUS_SUCCESS; - goto done; - } - if (argv[0] && !strncasecmp(argv[0], "profile=", 8)) { char *profile_name = argv[0] + 8; profile = switch_core_hash_find(globals.profile_hash, profile_name); From c7e8dce2473046cc867c9606f050e55944ac31d0 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sat, 17 Nov 2012 21:38:07 -0600 Subject: [PATCH 442/512] FS-4828 --resolve --- libs/esl/src/esl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 3972e7a7b4..59da3d0ab9 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -918,6 +918,7 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char * struct addrinfo hints = { 0 }, *result; struct sockaddr_in *sockaddr_in; struct sockaddr_in6 *sockaddr_in6; + socklen_t socklen; #ifndef WIN32 int fd_flags = 0; #else @@ -951,10 +952,12 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char * case AF_INET: sockaddr_in = (struct sockaddr_in*)&(handle->sockaddr); sockaddr_in->sin_port = htons(port); + socklen = sizeof(struct sockaddr_in); break; case AF_INET6: sockaddr_in6 = (struct sockaddr_in6*)&(handle->sockaddr); sockaddr_in6->sin6_port = htons(port); + socklen = sizeof(struct sockaddr_in6); break; default: strncpy(handle->err, "Host resolves to unsupported address family", sizeof(handle->err)); @@ -985,7 +988,7 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char * #endif } - rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, sizeof(handle->sockaddr)); + rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, socklen); if (timeout) { int r; From db673a043f2438ff127b16a4465333926b9efd70 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sun, 18 Nov 2012 23:55:54 -0500 Subject: [PATCH 443/512] freetdm: ftmod_zt - Integrated HW DTMF support --- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 71 ++++++++++++++++++---- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h | 20 +++++- 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index ac3fcf2417..8d4ee8ab6f 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -102,6 +102,7 @@ struct ioctl_codes { ioctlcmd SETTXBITS; ioctlcmd GETRXBITS; ioctlcmd SETPOLARITY; + ioctlcmd TONEDETECT; }; /** @@ -139,7 +140,8 @@ static struct ioctl_codes zt_ioctl_codes = { .GETCONFMUTE = ZT_GETCONFMUTE, .ECHOTRAIN = ZT_ECHOTRAIN, .SETTXBITS = ZT_SETTXBITS, - .GETRXBITS = ZT_GETRXBITS + .GETRXBITS = ZT_GETRXBITS, + .TONEDETECT = ZT_TONEDETECT, }; /** @@ -178,7 +180,8 @@ static struct ioctl_codes dahdi_ioctl_codes = { .ECHOTRAIN = DAHDI_ECHOTRAIN, .SETTXBITS = DAHDI_SETTXBITS, .GETRXBITS = DAHDI_GETRXBITS, - .SETPOLARITY = DAHDI_SETPOLARITY + .SETPOLARITY = DAHDI_SETPOLARITY, + .TONEDETECT = DAHDI_TONEDETECT, }; #define ZT_INVALID_SOCKET -1 @@ -361,7 +364,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f cc.sigtype = ZT_SIG_CAS; cc.idlebits = cas_bits; if (ioctl(CONTROL_FD, codes.CHANCONFIG, &cc)) { - ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno)); + ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s as FreeTDM device %d:%d fd:%d err:%s\n", chanpath, ftdmchan->span_id, ftdmchan->chan_id, sockfd, strerror(errno)); close(sockfd); continue; } @@ -436,12 +439,23 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f continue; } + zt_tone_mode_t mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; + if (ioctl(sockfd, codes.TONEDETECT, &mode)) { + ftdm_log(FTDM_LOG_DEBUG, "HW DTMF not available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd); + } else { + ftdm_log(FTDM_LOG_DEBUG, "HW DTMF available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd); + ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT); + mode = 0; + ioctl(sockfd, codes.TONEDETECT, &mode); + } + if (!ftdm_strlen_zero(name)) { ftdm_copy_string(ftdmchan->chan_name, name, sizeof(ftdmchan->chan_name)); } if (!ftdm_strlen_zero(number)) { ftdm_copy_string(ftdmchan->chan_number, number, sizeof(ftdmchan->chan_number)); } + configured++; } else { ftdm_log(FTDM_LOG_ERROR, "failure configuring device %s\n", chanpath); @@ -666,7 +680,6 @@ static FIO_OPEN_FUNCTION(zt_open) } } } - } return FTDM_SUCCESS; } @@ -864,6 +877,18 @@ static FIO_COMMAND_FUNCTION(zt_command) and this is only used by some sig modules such as ftmod_r2 to behave bettter under load */ err = 0; break; + case FTDM_COMMAND_ENABLE_DTMF_DETECT: + { + zt_tone_mode_t mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; + err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode); + } + break; + case FTDM_COMMAND_DISABLE_DTMF_DETECT: + { + zt_tone_mode_t mode = 0; + err = ioctl(ftdmchan->sockfd, codes.TONEDETECT, &mode); + } + break; default: err = FTDM_NOTIMPL; break; @@ -955,7 +980,7 @@ pollagain: pfds[0].fd = ftdmchan->sockfd; pfds[0].events = inflags; result = poll(pfds, 1, to); - *flags = 0; + *flags = FTDM_NO_FLAGS; if (result < 0 && errno == EINTR) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "DAHDI wait got interrupted, trying again\n"); @@ -971,8 +996,6 @@ pollagain: inflags = pfds[0].revents; } - *flags = FTDM_NO_FLAGS; - if (result < 0){ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Poll failed"); ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to poll DAHDI device: %s\n", strerror(errno)); @@ -1048,6 +1071,23 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) return k ? FTDM_SUCCESS : FTDM_FAIL; } +static __inline__ int handle_dtmf_event(ftdm_channel_t *fchan, zt_event_t zt_event_id) +{ + if ((zt_event_id & ZT_EVENT_DTMFUP)) { + int digit = (zt_event_id & (~ZT_EVENT_DTMFUP)); + char tmp_dtmf[2] = { digit, 0 }; + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF UP [%d]\n", digit); + ftdm_channel_queue_dtmf(fchan, tmp_dtmf); + return 0; + } else if ((zt_event_id & ZT_EVENT_DTMFDOWN)) { + int digit = (zt_event_id & (~ZT_EVENT_DTMFDOWN)); + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "DTMF DOWN [%d]\n", digit); + return 0; + } else { + return -1; + } +} + /** * \brief Process an event from a ftdmchan and set the proper OOB event_id. The channel must be locked. * \param fchan Channel to retrieve event from @@ -1157,8 +1197,12 @@ static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan, break; default: { - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id); - *event_id = FTDM_OOB_INVALID; + if (handle_dtmf_event(fchan, zt_event_id)) { + ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id); + *event_id = FTDM_OOB_INVALID; + } else { + *event_id = FTDM_OOB_NOOP; + } } break; } @@ -1314,8 +1358,12 @@ tryagain: 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); + + if (handle_dtmf_event(ftdmchan, zt_event_id)) { + /* 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; } @@ -1331,7 +1379,6 @@ static FIO_CHANNEL_DESTROY_FUNCTION(zt_channel_destroy) { close(ftdmchan->sockfd); ftdmchan->sockfd = ZT_INVALID_SOCKET; - return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h index c9bb171b55..9d680668d2 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.h @@ -195,7 +195,9 @@ typedef enum { ZT_EVENT_TIMER_EXPIRED = 15, ZT_EVENT_TIMER_PING = 16, ZT_EVENT_POLARITY = 17, - ZT_EVENT_RINGBEGIN = 18 + ZT_EVENT_RINGBEGIN = 18, + ZT_EVENT_DTMFDOWN = (1 << 17), + ZT_EVENT_DTMFUP = (1 << 18), } zt_event_t; typedef enum { @@ -258,6 +260,12 @@ ZT_BBIT = 4, ZT_ABIT = 8 } zt_cas_bit_t; +typedef enum { +/* Tone Detection */ +ZT_TONEDETECT_ON = (1 << 0), /* Detect tones */ +ZT_TONEDETECT_MUTE = (1 << 1) /* Mute audio in received channel */ +} zt_tone_mode_t; + /* Defines */ #define ZT_MAX_BLOCKSIZE 8192 @@ -312,6 +320,11 @@ ZT_ABIT = 8 #define ZT_SETTXBITS _IOW (ZT_CODE, 43, int) #define ZT_GETRXBITS _IOR (ZT_CODE, 45, int) +/* + * Enable tone detection -- implemented by low level driver + */ +#define ZT_TONEDETECT _IOW(ZT_CODE, 91, int) + #define DAHDI_GET_BLOCKSIZE _IOR (DAHDI_CODE, 1, int) /* Get Transfer Block Size. */ #define DAHDI_SET_BLOCKSIZE _IOW (DAHDI_CODE, 1, int) /* Set Transfer Block Size. */ #define DAHDI_FLUSH _IOW (DAHDI_CODE, 3, int) /* Flush Buffer(s) and stop I/O */ @@ -361,6 +374,11 @@ ZT_ABIT = 8 #define DAHDI_SETPOLARITY _IOW (DAHDI_CODE, 92, int) /* Polarity setting for FXO lines */ +/* + * Enable tone detection -- implemented by low level driver + */ +#define DAHDI_TONEDETECT _IOW(DAHDI_CODE, 91, int) + #endif /* For Emacs: From b64cc02390637fc977cd1527e93e8ab294a6a36e Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 19 Nov 2012 10:23:46 -0500 Subject: [PATCH 444/512] freetdm: ftmod_zt - Declare tone mode at the top to avoid compilation errors --- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 8d4ee8ab6f..c088c1453f 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -274,6 +274,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f { unsigned configured = 0, x; zt_params_t ztp; + zt_tone_mode_t mode = 0; memset(&ztp, 0, sizeof(ztp)); @@ -439,7 +440,7 @@ static unsigned zt_open_range(ftdm_span_t *span, unsigned start, unsigned end, f continue; } - zt_tone_mode_t mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; + mode = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE; if (ioctl(sockfd, codes.TONEDETECT, &mode)) { ftdm_log(FTDM_LOG_DEBUG, "HW DTMF not available on FreeTDM device %d:%d fd:%d\n", ftdmchan->span_id, ftdmchan->chan_id, sockfd); } else { From 41e00c78c5c53fa4185224b6ae0f563760f21ad0 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Mon, 19 Nov 2012 09:49:10 -0800 Subject: [PATCH 445/512] Bump Callie sounds ver to 1.0.22 --- build/sounds_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/sounds_version.txt b/build/sounds_version.txt index 0214d1555f..fca8d25c59 100644 --- a/build/sounds_version.txt +++ b/build/sounds_version.txt @@ -1,3 +1,3 @@ -en-us-callie 1.0.18 +en-us-callie 1.0.22 ru-RU-elena 1.0.13 From 21b9ec886851408f92dd10ec2bbd88711bbd9a2b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 19 Nov 2012 16:23:55 -0600 Subject: [PATCH 446/512] FS-4847 --resolve --- src/switch_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index 090812a45b..a64e567c0e 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -881,7 +881,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, from = "freeswitch"; } #ifdef WIN32 - switch_snprintf(buf, B64BUFFLEN, "type %s | %s -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); + switch_snprintf(buf, B64BUFFLEN, "type %s | \"%s\" -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); #else switch_snprintf(buf, B64BUFFLEN, "/bin/cat %s | %s -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); #endif From 9015b20f328ffe1526af3bbaf4447a2b04c88490 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 19 Nov 2012 16:28:39 -0600 Subject: [PATCH 447/512] FS-4847 try this too --- src/switch_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index a64e567c0e..fad8530245 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -881,7 +881,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, from = "freeswitch"; } #ifdef WIN32 - switch_snprintf(buf, B64BUFFLEN, "type %s | \"%s\" -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); + switch_snprintf(buf, B64BUFFLEN, "type \"%s\" | \"%s\" -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); #else switch_snprintf(buf, B64BUFFLEN, "/bin/cat %s | %s -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); #endif From 1d7623c9344a9177de5ae5e0521d31449e3e5e86 Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Mon, 19 Nov 2012 16:17:32 -0800 Subject: [PATCH 448/512] Update ChangeLog for 1.2.5 --- docs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/ChangeLog b/docs/ChangeLog index 7eb7c5da55..f5e330d00e 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -1,3 +1,7 @@ +freeswitch (1.2.5) + mod_lua: Enable mod_lua to use native pgsql dbh support (r:2cea7f0f) + mod_sofia: Add att_xfer_destination_number variable to indicate the original destination number of the attended transfer leg on REFER for semi-attended transfer scenarios. (r:893cd7be) + sounds: Bump Callie sounds ver to 1.0.22 (r:41e00c78) freeswitch (1.2.4) core: Add Postgres core db support (r:0c1180d5) mod_cdr_mongodb: update MongoDB driver to v0.6 (r:10093b44) From f6baeb21098b35a39ac0e1242db806e90973fa99 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 19 Nov 2012 18:21:19 -0600 Subject: [PATCH 449/512] bump --- configure.in | 4 ++-- src/include/switch_pgsql.h | 2 ++ src/switch_core_sqldb.c | 13 ++++++++++- src/switch_pgsql.c | 46 ++++++++++++++++++++++++++++---------- 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/configure.in b/configure.in index c1a43ea170..52d884f090 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.5b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.5], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [5b]) +AC_SUBST(SWITCH_VERSION_MICRO, [5]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) diff --git a/src/include/switch_pgsql.h b/src/include/switch_pgsql.h index 00da8efffa..ff4e83f11a 100644 --- a/src/include/switch_pgsql.h +++ b/src/include/switch_pgsql.h @@ -156,6 +156,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_callback_exec_detailed SWITCH_DECLARE(char *) switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle); SWITCH_DECLARE(int) switch_pgsql_handle_affected_rows(switch_pgsql_handle_t *handle); +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_flush(switch_pgsql_handle_t *handle); + SWITCH_END_EXTERN_C #endif diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 7d1e6c8716..b776a14a87 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -293,6 +293,17 @@ SWITCH_DECLARE(void) switch_cache_db_flush_handles(void) SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh) { if (dbh && *dbh) { + + switch((*dbh)->type) { + case SCDB_TYPE_PGSQL: + { + switch_pgsql_flush((*dbh)->native_handle.pgsql_dbh); + } + break; + default: + break; + } + switch_mutex_lock(sql_manager.dbh_mutex); (*dbh)->last_used = switch_epoch_time_now(NULL); @@ -406,7 +417,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h switch (type) { case SCDB_TYPE_PGSQL: { - db_name = connection_options->odbc_options.dsn; + db_name = connection_options->pgsql_options.dsn; odbc_user = NULL; odbc_pass = NULL; } diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index f326305657..6d6bd656e9 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -276,11 +276,8 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_cancel_real(const char *file, ret = SWITCH_PGSQL_FAIL; } PQfreeCancel(cancel); - { - PGresult *tmp = NULL; - /* Make sure the query is fully cancelled */ - while ((tmp = PQgetResult(handle->con)) != NULL) PQclear(tmp); - } + switch_pgsql_flush(handle); + #endif return ret; } @@ -427,14 +424,13 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq return SWITCH_PGSQL_SUCCESS; error: - { - PGresult *tmp = NULL; - /* Make sure the failed connection does not have any transactions marked as in progress */ - while ((tmp = PQgetResult(handle->con)) != NULL) PQclear(tmp); - /* Try to reconnect to the DB if we were dropped */ - db_is_up(handle); - } + /* Make sure the failed connection does not have any transactions marked as in progress */ + switch_pgsql_flush(handle); + + /* Try to reconnect to the DB if we were dropped */ + db_is_up(handle); + #endif return SWITCH_PGSQL_FAIL; } @@ -572,6 +568,9 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base_detailed(con #ifdef SWITCH_HAVE_PGSQL char *err_str = NULL, *er = NULL; + + + switch_pgsql_flush(handle); handle->affected_rows = 0; if (!db_is_up(handle)) { @@ -829,6 +828,29 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLSetAutoCommitAttr(switch_p #endif } +SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_flush(switch_pgsql_handle_t *handle) +{ +#ifdef SWITCH_HAVE_PGSQL + + PGresult *tmp = NULL; + int x = 0; + + /* Make sure the query is fully cleared */ + while ((tmp = PQgetResult(handle->con)) != NULL) { + PQclear(tmp); + x++; + } + + if (x) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Flushing %d results\n", x); + } + + return SWITCH_PGSQL_SUCCESS; +#else + return (switch_pgsql_status_t) SWITCH_FALSE; +#endif +} + SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_SQLEndTran(switch_pgsql_handle_t *handle, switch_bool_t commit) { #ifdef SWITCH_HAVE_PGSQL From 7ead440fa01228f3546d6c7d85a13b141f5b4d2d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 19 Nov 2012 18:23:05 -0600 Subject: [PATCH 450/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 52d884f090..15c91a976a 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.5], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.6b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [5]) +AC_SUBST(SWITCH_VERSION_MICRO, [6b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 93b5f7fdfd786e468bb87bb1175fa7b3378bc86f Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 19 Nov 2012 23:32:41 -0600 Subject: [PATCH 451/512] FS-4099 FS-4847 --- src/switch_core.c | 5665 +++++++++++++++++++++++---------------------- 1 file changed, 2834 insertions(+), 2831 deletions(-) diff --git a/src/switch_core.c b/src/switch_core.c index 4682d3c002..9bbb11956d 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1,2831 +1,2834 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * 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 Jerris - * Paul D. Tinsley - * Marcel Barbulescu - * Joseph Sullivan - * - * - * switch_core.c -- Main Core Library - * - */ - - - -#include -#include -#include -#include -#include -#include "private/switch_core_pvt.h" -#include -#ifndef WIN32 -#include -#ifdef HAVE_SETRLIMIT -#include -#endif -#endif -#include - - -SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 }; - -/* The main runtime obj we keep this hidden for ourselves */ -struct switch_runtime runtime = { 0 }; -static void switch_load_core_config(const char *file); - -static void send_heartbeat(void) -{ - switch_event_t *event; - switch_core_time_duration_t duration; - - switch_core_measure_time(switch_core_uptime(), &duration); - - if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time", - "%u year%s, " - "%u day%s, " - "%u hour%s, " - "%u minute%s, " - "%u second%s, " - "%u millisecond%s, " - "%u microsecond%s", - duration.yr, duration.yr == 1 ? "" : "s", - duration.day, duration.day == 1 ? "" : "s", - duration.hr, duration.hr == 1 ? "" : "s", - duration.min, duration.min == 1 ? "" : "s", - duration.sec, duration.sec == 1 ? "" : "s", - duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s"); - - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", SWITCH_VERSION_FULL); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT, switch_core_uptime() / 1000); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count()); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu()); - switch_event_fire(&event); - } -} - -static char main_ip4[256] = ""; -static char main_ip6[256] = ""; - -static void check_ip(void) -{ - char guess_ip4[256] = ""; - char guess_ip6[256] = ""; - char old_ip4[256] = ""; - char old_ip6[256] = ""; - int ok4 = 1, ok6 = 1; - int mask = 0; - - gethostname(runtime.hostname, sizeof(runtime.hostname)); - switch_core_set_variable("hostname", runtime.hostname); - - switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET); - switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6); - - if (!*main_ip4) { - switch_set_string(main_ip4, guess_ip4); - } else { - if (!(ok4 = !strcmp(main_ip4, guess_ip4))) { - struct in_addr in; - - in.s_addr = mask; - switch_set_string(old_ip4, main_ip4); - switch_set_string(main_ip4, guess_ip4); - switch_core_set_variable("local_ip_v4", guess_ip4); - switch_core_set_variable("local_mask_v4", inet_ntoa(in)); - } - } - - if (!*main_ip6) { - switch_set_string(main_ip6, guess_ip6); - } else { - if (!(ok6 = !strcmp(main_ip6, guess_ip6))) { - switch_set_string(old_ip6, main_ip6); - switch_set_string(main_ip6, guess_ip6); - switch_core_set_variable("local_ip_v6", guess_ip6); - } - } - - if (!ok4 || !ok6) { - switch_event_t *event; - - if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change"); - if (!ok4) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4); - } - if (!ok6) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6); - } - switch_event_fire(&event); - } - } -} - -SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback) -{ - send_heartbeat(); - - /* reschedule this task */ - task->runtime = switch_epoch_time_now(NULL) + 20; -} - - -SWITCH_STANDARD_SCHED_FUNC(check_ip_callback) -{ - check_ip(); - - /* reschedule this task */ - task->runtime = switch_epoch_time_now(NULL) + 60; -} - - -SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console) -{ - if ((runtime.console = fopen(console, "a")) == 0) { - fprintf(stderr, "Cannot open output file %s.\n", console); - return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(FILE *) switch_core_get_console(void) -{ - return runtime.console; -} - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) -{ - -#ifdef WIN32 - CONSOLE_SCREEN_BUFFER_INFO csbi; - int ret; - - if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) { - if (x) *x = csbi.dwSize.X; - if (y) *y = csbi.dwSize.Y; - } - -#elif defined(TIOCGWINSZ) - struct winsize w; - ioctl(0, TIOCGWINSZ, &w); - - if (x) *x = w.ws_col; - if (y) *y = w.ws_row; -#else - if (x) *x = 80; - if (y) *y = 24; -#endif - -} - -SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel) -{ - FILE *handle = stdout; - - switch (channel) { - case SWITCH_CHANNEL_ID_LOG: - case SWITCH_CHANNEL_ID_LOG_CLEAN: - handle = runtime.console; - break; - default: - handle = runtime.console; - break; - } - - return handle; -} - - -SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler) -{ - int index, tmp_index = 0; - const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 }; - - switch_mutex_lock(runtime.global_mutex); - - for (index = 0; index < runtime.state_handler_index; index++) { - const switch_state_handler_table_t *cur = runtime.state_handlers[index]; - runtime.state_handlers[index] = NULL; - if (cur == state_handler) { - continue; - } - tmp[tmp_index++] = cur; - } - - runtime.state_handler_index = 0; - - for (index = 0; index < tmp_index; index++) { - runtime.state_handlers[runtime.state_handler_index++] = tmp[index]; - } - switch_mutex_unlock(runtime.global_mutex); -} - - -SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler) -{ - int index; - - switch_mutex_lock(runtime.global_mutex); - index = runtime.state_handler_index++; - - if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS) { - index = -1; - } else { - runtime.state_handlers[index] = state_handler; - } - - switch_mutex_unlock(runtime.global_mutex); - return index; -} - -SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index) -{ - - if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) { - return NULL; - } - - return runtime.state_handlers[index]; -} - -SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream) -{ - switch_event_header_t *hi; - - switch_mutex_lock(runtime.global_mutex); - for (hi = runtime.global_vars->headers; hi; hi = hi->next) { - stream->write_function(stream, "%s=%s\n", hi->name, hi->value); - } - switch_mutex_unlock(runtime.global_mutex); -} - -SWITCH_DECLARE(const char *) switch_core_get_hostname(void) -{ - return runtime.hostname; -} - -SWITCH_DECLARE(const char *) switch_core_get_switchname(void) -{ - if (!zstr(runtime.switchname)) return runtime.switchname; - return runtime.hostname; -} - - -SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) -{ - char *val; - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - val = (char *) switch_event_get_header(runtime.global_vars, varname); - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - return val; -} - -SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname) -{ - char *val = NULL, *v; - - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { - val = strdup(v); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - - return val; -} - -SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool) -{ - char *val = NULL, *v; - - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { - val = switch_core_strdup(pool, v); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - - return val; -} - -static void switch_core_unset_variables(void) -{ - switch_thread_rwlock_wrlock(runtime.global_var_rwlock); - switch_event_destroy(&runtime.global_vars); - switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); - switch_thread_rwlock_unlock(runtime.global_var_rwlock); -} - -SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value) -{ - char *val; - - if (varname) { - switch_thread_rwlock_wrlock(runtime.global_var_rwlock); - val = (char *) switch_event_get_header(runtime.global_vars, varname); - if (val) { - switch_event_del_header(runtime.global_vars, varname); - } - if (value) { - char *v = strdup(value); - switch_string_var_check(v, SWITCH_TRUE); - switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); - } else { - switch_event_del_header(runtime.global_vars, varname); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - } -} - -SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2) -{ - char *val; - - if (varname) { - switch_thread_rwlock_wrlock(runtime.global_var_rwlock); - val = (char *) switch_event_get_header(runtime.global_vars, varname); - - if (val) { - if (!val2 || strcmp(val, val2) != 0) { - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - return SWITCH_FALSE; - } - switch_event_del_header(runtime.global_vars, varname); - } else if (!zstr(val2)) { - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - return SWITCH_FALSE; - } - - if (value) { - char *v = strdup(value); - switch_string_var_check(v, SWITCH_TRUE); - switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); - } else { - switch_event_del_header(runtime.global_vars, varname); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - } - return SWITCH_TRUE; -} - -SWITCH_DECLARE(char *) switch_core_get_uuid(void) -{ - return runtime.uuid_str; -} - - -static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj) -{ - switch_core_session_t *session = obj; - switch_channel_t *channel; - switch_frame_t *read_frame; - -// switch_assert(thread != NULL); -// switch_assert(session != NULL); - - if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { - return NULL; - } - - switch_mutex_lock(session->frame_read_mutex); - - channel = switch_core_session_get_channel(session); - - switch_channel_set_flag(channel, CF_SERVICE); - while (switch_channel_test_flag(channel, CF_SERVICE)) { - - if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) { - switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { - case SWITCH_STATUS_SUCCESS: - case SWITCH_STATUS_TIMEOUT: - case SWITCH_STATUS_BREAK: - break; - default: - switch_channel_clear_flag(channel, CF_SERVICE); - break; - } - } - - if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) { - switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { - case SWITCH_STATUS_SUCCESS: - case SWITCH_STATUS_TIMEOUT: - case SWITCH_STATUS_BREAK: - break; - default: - switch_channel_clear_flag(channel, CF_SERVICE); - break; - } - } - } - - switch_mutex_unlock(session->frame_read_mutex); - - switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); - switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); - - switch_core_session_rwunlock(session); - - return NULL; -} - -/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */ -SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session) -{ - switch_channel_t *channel; - switch_assert(session); - - channel = switch_core_session_get_channel(session); - switch_assert(channel); - - switch_channel_clear_flag(channel, CF_SERVICE); - switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); - switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); - - switch_core_session_kill_channel(session, SWITCH_SIG_BREAK); - -} - -SWITCH_DECLARE(void) switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video) -{ - switch_channel_t *channel; - switch_assert(session); - - channel = switch_core_session_get_channel(session); - switch_assert(channel); - - if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO); - if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO); - - switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session); -} - -/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and - a void object and trust that that the function will be run in a thread with arg This lets - you request and activate a thread without giving up any knowledge about what is in the thread - neither the core nor the calling module know anything about each other. - - This thread is expected to never exit until the application exits so the func is responsible - to make sure that is the case. - - The typical use for this is so switch_loadable_module.c can start up a thread for each module - passing the table of module methods as a session obj into the core without actually allowing - the core to have any clue and keeping switch_loadable_module.c from needing any thread code. - -*/ - -SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool) -{ - switch_thread_t *thread = NULL; - switch_threadattr_t *thd_attr = NULL; - switch_core_thread_session_t *ts; - int mypool; - - mypool = pool ? 0 : 1; - - if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n"); - return NULL; - } - - switch_threadattr_create(&thd_attr, pool); - - if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n"); - } else { - if (mypool) { - ts->pool = pool; - } - ts->objs[0] = obj; - ts->objs[1] = thread; - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&thread, thd_attr, func, ts, pool); - } - - return thread; -} - -SWITCH_DECLARE(void) switch_core_set_globals(void) -{ -#define BUFSIZE 1024 -#ifdef WIN32 - char lpPathBuffer[BUFSIZE]; - DWORD dwBufSize = BUFSIZE; - char base_dir[1024]; - char *lastbacklash; - char *tmp; - - GetModuleFileName(NULL, base_dir, BUFSIZE); - lastbacklash = strrchr(base_dir, '\\'); - base_dir[(lastbacklash - base_dir)] = '\0'; - /* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */ - SetCurrentDirectory(base_dir); - tmp = switch_string_replace(base_dir, "\\", "/"); - strcpy(base_dir, tmp); - free(tmp); - -#else - char base_dir[1024] = SWITCH_PREFIX_DIR; -#endif - - if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) { - switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir); - } - - if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_MOD_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_LIB_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_CONF_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_LOG_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_RUN_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_RECORDINGS_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_SOUNDS_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_STORAGE_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_DB_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_SCRIPT_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_HTDOCS_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_GRAMMAR_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_TEMP_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR); -#else -#ifdef WIN32 - GetTempPath(dwBufSize, lpPathBuffer); - lpPathBuffer[strlen(lpPathBuffer)-1] = 0; - switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp"); -#endif -#endif - } - - switch_assert(SWITCH_GLOBAL_dirs.base_dir); - switch_assert(SWITCH_GLOBAL_dirs.mod_dir); - switch_assert(SWITCH_GLOBAL_dirs.lib_dir); - switch_assert(SWITCH_GLOBAL_dirs.conf_dir); - switch_assert(SWITCH_GLOBAL_dirs.log_dir); - switch_assert(SWITCH_GLOBAL_dirs.run_dir); - switch_assert(SWITCH_GLOBAL_dirs.db_dir); - switch_assert(SWITCH_GLOBAL_dirs.script_dir); - switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir); - switch_assert(SWITCH_GLOBAL_dirs.grammar_dir); - switch_assert(SWITCH_GLOBAL_dirs.recordings_dir); - switch_assert(SWITCH_GLOBAL_dirs.sounds_dir); - switch_assert(SWITCH_GLOBAL_dirs.temp_dir); -} - - -SWITCH_DECLARE(int32_t) set_low_priority(void) -{ - - -#ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); -#else -#ifdef USE_SCHED_SETSCHEDULER - /* - * Try to use a normal scheduler - */ - struct sched_param sched = { 0 }; - sched.sched_priority = 0; - if (sched_setscheduler(0, SCHED_OTHER, &sched)) { - return -1; - } -#endif - -#ifdef HAVE_SETPRIORITY - /* - * setpriority() works on FreeBSD (6.2), nice() doesn't - */ - if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#else - if (nice(19) != 19) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#endif -#endif - - return 0; -} - -SWITCH_DECLARE(int32_t) set_realtime_priority(void) -{ -#ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); -#else -#ifdef USE_SCHED_SETSCHEDULER - /* - * Try to use a round-robin scheduler - * with a fallback if that does not work - */ - struct sched_param sched = { 0 }; - sched.sched_priority = SWITCH_PRI_LOW; - if (sched_setscheduler(0, SCHED_FIFO, &sched)) { - sched.sched_priority = 0; - if (sched_setscheduler(0, SCHED_OTHER, &sched)) { - return -1; - } - } -#endif - - - -#ifdef HAVE_SETPRIORITY - /* - * setpriority() works on FreeBSD (6.2), nice() doesn't - */ - if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#else - if (nice(-10) != -10) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#endif -#endif - return 0; -} - -SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void) -{ - return runtime.cpu_count; -} - -SWITCH_DECLARE(int32_t) set_normal_priority(void) -{ - return 0; -} - -SWITCH_DECLARE(int32_t) set_auto_priority(void) -{ -#ifndef WIN32 - runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); -#else - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - runtime.cpu_count = sysinfo.dwNumberOfProcessors; -#endif - - if (!runtime.cpu_count) runtime.cpu_count = 1; - - /* If we have more than 1 cpu, we should use realtime priority so we can have priority threads */ - if (runtime.cpu_count > 1) { - return set_realtime_priority(); - } - - return 0; -} - -SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group) -{ -#ifndef WIN32 - uid_t runas_uid = 0; - gid_t runas_gid = 0; - struct passwd *runas_pw = NULL; - - if (user) { - /* - * Lookup user information in the system's db - */ - runas_pw = getpwnam(user); - if (!runas_pw) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user); - return -1; - } - runas_uid = runas_pw->pw_uid; - } - - if (group) { - struct group *gr = NULL; - - /* - * Lookup group information in the system's db - */ - gr = getgrnam(group); - if (!gr) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group); - return -1; - } - runas_gid = gr->gr_gid; - } - - if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) { - /* already running as the right user and group, nothing to do! */ - return 0; - } - - if (runas_uid) { -#ifdef HAVE_SETGROUPS - /* - * Drop all group memberships prior to changing anything - * or else we're going to inherit the parent's list of groups - * (which is not what we want...) - */ - if (setgroups(0, NULL) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to drop group access list\n"); - return -1; - } -#endif - if (runas_gid) { - /* - * A group has been passed, switch to it - * (without loading the user's other groups) - */ - if (setgid(runas_gid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); - return -1; - } - } else { - /* - * No group has been passed, use the user's primary group in this case - */ - if (setgid(runas_pw->pw_gid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); - return -1; - } -#ifdef HAVE_INITGROUPS - /* - * Set all the other groups the user is a member of - * (This can be really useful for fine-grained access control) - */ - if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to set group access list for user\n"); - return -1; - } -#endif - } - - /* - * Finally drop all privileges by switching to the new userid - */ - if (setuid(runas_uid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n"); - return -1; - } - } -#endif - return 0; -} - -SWITCH_DECLARE(void) switch_core_runtime_loop(int bg) -{ -#ifdef WIN32 - HANDLE shutdown_event; - char path[256] = ""; -#endif - if (bg) { - bg = 0; -#ifdef WIN32 - switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); - shutdown_event = CreateEvent(NULL, FALSE, FALSE, path); - if (shutdown_event) { - WaitForSingleObject(shutdown_event, INFINITE); - } -#else - runtime.running = 1; - while (runtime.running) { - switch_yield(1000000); - } -#endif - } else { - /* wait for console input */ - switch_console_loop(); - } -} - -SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext) -{ - if (!ext) { - return NULL; - } - return (const char *) switch_core_hash_find(runtime.mime_types, ext); -} - - -SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void) -{ - return switch_hash_first(NULL, runtime.mime_types); -} - -SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext) -{ - const char *check; - switch_status_t status = SWITCH_STATUS_FALSE; - - switch_assert(type); - switch_assert(ext); - - check = (const char *) switch_core_hash_find(runtime.mime_types, ext); - - if (!check) { - char *ptype = switch_core_permanent_strdup(type); - char *ext_list = strdup(ext); - int argc = 0; - char *argv[20] = { 0 }; - int x; - - switch_assert(ext_list); - - if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - - for (x = 0; x < argc; x++) { - if (argv[x] && ptype) { - switch_core_hash_insert(runtime.mime_types, argv[x], ptype); - } - } - - status = SWITCH_STATUS_SUCCESS; - } - - free(ext_list); - } - - return status; -} - -static void load_mime_types(void) -{ - char *cf = "mime.types"; - FILE *fd = NULL; - char *line_buf = NULL; - switch_size_t llen = 0; - char *mime_path = NULL; - - mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf); - switch_assert(mime_path); - - fd = fopen(mime_path, "rb"); - - if (fd == NULL) { - goto end; - } - - while ((switch_fp_read_dline(fd, &line_buf, &llen))) { - char *p; - char *type = line_buf; - - if (*line_buf == '#') { - continue; - } - - if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) { - *p = '\0'; - } - - if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) { - *p++ = '\0'; - - while (*p == ' ' || *p == '\t') { - p++; - } - - switch_core_mime_add_type(type, p); - } - - } - - switch_safe_free(line_buf); - - if (fd) { - fclose(fd); - fd = NULL; - } - - end: - - switch_safe_free(mime_path); - -} - -SWITCH_DECLARE(void) switch_core_setrlimits(void) -{ -#ifdef HAVE_SETRLIMIT - struct rlimit rlp; - - /* - Setting the stack size on FreeBSD results in an instant crash. - - If anyone knows how to fix this, - feel free to submit a patch to http://jira.freeswitch.org - */ - -#ifndef __FreeBSD__ - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; - rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; - setrlimit(RLIMIT_STACK, &rlp); -#endif - - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = 999999; - rlp.rlim_max = 999999; - setrlimit(RLIMIT_NOFILE, &rlp); - - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = RLIM_INFINITY; - rlp.rlim_max = RLIM_INFINITY; - - setrlimit(RLIMIT_CPU, &rlp); - setrlimit(RLIMIT_DATA, &rlp); - setrlimit(RLIMIT_FSIZE, &rlp); -#ifdef RLIMIT_NPROC - setrlimit(RLIMIT_NPROC, &rlp); -#endif -#ifdef RLIMIT_RTPRIO - setrlimit(RLIMIT_RTPRIO, &rlp); -#endif - -#if !defined(__OpenBSD__) && !defined(__NetBSD__) - setrlimit(RLIMIT_AS, &rlp); -#endif -#endif - return; -} - -typedef struct { - switch_memory_pool_t *pool; - switch_hash_t *hash; -} switch_ip_list_t; - -static switch_ip_list_t IP_LIST = { 0 }; - -SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token) -{ - switch_network_list_t *list; - ip_t ip, mask, net; - uint32_t bits; - char *ipv6 = strchr(ip_str,':'); - switch_bool_t ok = SWITCH_FALSE; - - switch_mutex_lock(runtime.global_mutex); - if (ipv6) { - switch_inet_pton(AF_INET6, ip_str, &ip); - } else { - switch_inet_pton(AF_INET, ip_str, &ip); - ip.v4 = htonl(ip.v4); - } - - if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) { - if (ipv6) { - ok = switch_network_list_validate_ip6_token(list, ip, token); - } else { - ok = switch_network_list_validate_ip_token(list, ip.v4, token); - } - } else if (strchr(list_name, '/')) { - if (strchr(list_name, ',')) { - char *list_name_dup = strdup(list_name); - char *argv[32]; - int argc; - - switch_assert(list_name_dup); - - if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { - int i; - for (i = 0; i < argc; i++) { - switch_parse_cidr(argv[i], &net, &mask, &bits); - if (ipv6) { - if ((ok = switch_testv6_subnet(ip, net, mask))){ - break; - } - } else { - if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) { - break; - } - } - } - } - free(list_name_dup); - } else { - switch_parse_cidr(list_name, &net, &mask, &bits); - ok = switch_test_subnet(ip.v4, net.v4, mask.v4); - } - } - switch_mutex_unlock(runtime.global_mutex); - - return ok; -} - - -SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload) -{ - switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL; - switch_network_list_t *rfc_list, *list; - char guess_ip[16] = ""; - int mask = 0; - char guess_mask[16] = ""; - char *tmp_name; - struct in_addr in; - - switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); - in.s_addr = mask; - switch_set_string(guess_mask, inet_ntoa(in)); - - switch_mutex_lock(runtime.global_mutex); - - if (IP_LIST.hash) { - switch_core_hash_destroy(&IP_LIST.hash); - } - - if (IP_LIST.pool) { - switch_core_destroy_memory_pool(&IP_LIST.pool); - } - - memset(&IP_LIST, 0, sizeof(IP_LIST)); - switch_core_new_memory_pool(&IP_LIST.pool); - switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool); - - - tmp_name = "rfc1918.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "wan.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name); - switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE); - switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE); - switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "nat.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name); - } - switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "loopback.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "localnet.auto"; - switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - - if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name); - } - switch_core_hash_insert(IP_LIST.hash, tmp_name, list); - - - if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) { - if ((x_lists = switch_xml_child(cfg, "network-lists"))) { - for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) { - const char *name = switch_xml_attr(x_list, "name"); - const char *dft = switch_xml_attr(x_list, "default"); - switch_bool_t default_type = SWITCH_TRUE; - - if (zstr(name)) { - continue; - } - - if (dft) { - default_type = switch_true(dft); - } - - if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) { - abort(); - } - - if (reload) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); - } - - - for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) { - const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL; - switch_bool_t ok = default_type; - const char *type = switch_xml_attr(x_node, "type"); - - if (type) { - ok = switch_true(type); - } - - cidr = switch_xml_attr(x_node, "cidr"); - host = switch_xml_attr(x_node, "host"); - mask = switch_xml_attr(x_node, "mask"); - domain = switch_xml_attr(x_node, "domain"); - - if (domain) { - switch_event_t *my_params = NULL; - switch_xml_t x_domain, xml_root; - switch_xml_t gt, gts, ut, uts; - - switch_event_create(&my_params, SWITCH_EVENT_GENERAL); - switch_assert(my_params); - switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain); - switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list"); - - if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain); - switch_event_destroy(&my_params); - continue; - } - - switch_event_destroy(&my_params); - - for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) { - const char *user_cidr = switch_xml_attr(ut, "cidr"); - const char *id = switch_xml_attr(ut, "id"); - - if (id && user_cidr) { - char *token = switch_mprintf("%s@%s", id, domain); - switch_assert(token); - switch_network_list_add_cidr_token(list, user_cidr, ok, token); - free(token); - } - } - - for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) { - for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) { - for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) { - for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) { - const char *user_cidr = switch_xml_attr(ut, "cidr"); - const char *id = switch_xml_attr(ut, "id"); - - if (id && user_cidr) { - char *token = switch_mprintf("%s@%s", id, domain); - switch_assert(token); - switch_network_list_add_cidr_token(list, user_cidr, ok, token); - free(token); - } - } - } - } - } - - switch_xml_free(xml_root); - } else if (cidr) { - if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); - } - } else if (host && mask) { - if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name); - } - } - - switch_core_hash_insert(IP_LIST.hash, name, list); - } - } - } - - switch_xml_free(xml); - } - - switch_mutex_unlock(runtime.global_mutex); -} - -SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration) -{ - if (duration) { - if (duration > SWITCH_MAX_DTMF_DURATION) { - duration = SWITCH_MAX_DTMF_DURATION; - } - if (duration < SWITCH_MIN_DTMF_DURATION) { - duration = SWITCH_MIN_DTMF_DURATION; - } - runtime.max_dtmf_duration = duration; - if (duration < runtime.min_dtmf_duration) { - runtime.min_dtmf_duration = duration; - } - } - return runtime.max_dtmf_duration; -} - -SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration) -{ - if (duration) { - if (duration < SWITCH_MIN_DTMF_DURATION) { - duration = SWITCH_MIN_DTMF_DURATION; - } - if (duration > SWITCH_MAX_DTMF_DURATION) { - duration = SWITCH_MAX_DTMF_DURATION; - } - runtime.default_dtmf_duration = duration; - - if (duration < runtime.min_dtmf_duration) { - runtime.min_dtmf_duration = duration; - } - - if (duration > runtime.max_dtmf_duration) { - runtime.max_dtmf_duration = duration; - } - - } - return runtime.default_dtmf_duration; -} - -SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration) -{ - if (duration) { - if (duration < SWITCH_MIN_DTMF_DURATION) { - duration = SWITCH_MIN_DTMF_DURATION; - } - if (duration > SWITCH_MAX_DTMF_DURATION) { - duration = SWITCH_MAX_DTMF_DURATION; - } - - runtime.min_dtmf_duration = duration; - - if (duration > runtime.max_dtmf_duration) { - runtime.max_dtmf_duration = duration; - } - } - return runtime.min_dtmf_duration; -} - -SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu) -{ - switch_status_t status = SWITCH_STATUS_FALSE; - - if (cpu > -1) { - -#ifdef HAVE_CPU_SET_MACROS - cpu_set_t set; - - CPU_ZERO(&set); - CPU_SET(cpu, &set); - - if (!sched_setaffinity(0, sizeof(set), &set)) { - status = SWITCH_STATUS_SUCCESS; - } - -#else -#if WIN32 - if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) { - status = SWITCH_STATUS_SUCCESS; - } -#endif -#endif - } - - return status; -} - - -static void switch_core_set_serial(void) -{ - char buf[13] = ""; - char path[256]; - - int fd = -1, write_fd = -1; - switch_ssize_t bytes = 0; - - switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR); - - - if ((fd = open(path, O_RDONLY, 0)) < 0) { - char *ip = switch_core_get_variable_dup("local_ip_v4"); - uint32_t ipi = 0; - switch_byte_t *byte; - int i = 0; - - if (ip) { - switch_inet_pton(AF_INET, ip, &ipi); - free(ip); - ip = NULL; - } - - - byte = (switch_byte_t *) & ipi; - - for (i = 0; i < 8; i += 2) { - switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte); - byte++; - } - - switch_stun_random_string(buf + 8, 4, "0123456789abcdef"); - - if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) { - bytes = write(write_fd, buf, sizeof(buf)); - bytes++; - close(write_fd); - write_fd = -1; - } - } else { - bytes = read(fd, buf, sizeof(buf)); - close(fd); - fd = -1; - } - - switch_core_set_variable("switch_serial", buf); -} - - -SWITCH_DECLARE(int) switch_core_test_flag(int flag) -{ - return switch_test_flag((&runtime), flag); -} - - -SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err) -{ - switch_uuid_t uuid; - char guess_ip[256]; - int mask = 0; - struct in_addr in; - - - if (runtime.runlevel > 0) { - /* one per customer */ - return SWITCH_STATUS_SUCCESS; - } - - memset(&runtime, 0, sizeof(runtime)); - gethostname(runtime.hostname, sizeof(runtime.hostname)); - - runtime.max_db_handles = 50; - runtime.db_handle_timeout = 5000000; - - runtime.runlevel++; - runtime.dummy_cng_frame.data = runtime.dummy_data; - runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); - runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); - runtime.dbname = "core"; - switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG); - switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); - switch_set_flag((&runtime), SCF_CLEAR_SQL); - switch_set_flag((&runtime), SCF_API_EXPANSION); - switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); -#ifdef WIN32 - switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); -#endif - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - runtime.hard_log_level = SWITCH_LOG_DEBUG; - runtime.mailer_app = "sendmail"; - runtime.mailer_app_args = "-t"; - runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION; - runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION; - runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION; - runtime.odbc_dbtype = DBTYPE_DEFAULT; - runtime.dbname = NULL; -#ifndef WIN32 - runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); -#else - { - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - runtime.cpu_count = sysinfo.dwNumberOfProcessors; - } -#endif - - if (!runtime.cpu_count) runtime.cpu_count = 1; - - - /* INIT APR and Create the pool context */ - if (apr_initialize() != SWITCH_STATUS_SUCCESS) { - *err = "FATAL ERROR! Could not initialize APR\n"; - return SWITCH_STATUS_MEMERR; - } - - if (!(runtime.memory_pool = switch_core_memory_init())) { - *err = "FATAL ERROR! Could not allocate memory pool\n"; - return SWITCH_STATUS_MEMERR; - } - switch_assert(runtime.memory_pool != NULL); - - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - - - switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - - switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - - switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - - switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool); - switch_core_set_globals(); - switch_core_session_init(runtime.memory_pool); - switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); - switch_core_hash_init(&runtime.mime_types, runtime.memory_pool); - switch_core_hash_init_case(&runtime.ptimes, runtime.memory_pool, SWITCH_FALSE); - load_mime_types(); - runtime.flags |= flags; - runtime.sps_total = 30; - - *err = NULL; - - if (console) { - runtime.console = stdout; - } - - switch_ssl_init_ssl_locks(); - switch_curl_init(); - - switch_core_set_variable("hostname", runtime.hostname); - switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); - switch_core_set_variable("local_ip_v4", guess_ip); - in.s_addr = mask; - switch_core_set_variable("local_mask_v4", inet_ntoa(in)); - - - switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6); - switch_core_set_variable("local_ip_v6", guess_ip); - switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir); - switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir); - switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir); - switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir); - switch_core_set_serial(); - - switch_console_init(runtime.memory_pool); - switch_event_init(runtime.memory_pool); - - if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) { - apr_terminate(); - return SWITCH_STATUS_MEMERR; - } - - if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { - switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING)); - } - - switch_log_init(runtime.memory_pool, runtime.colorize_console); - - if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; - - runtime.tipping_point = 0; - runtime.timer_affinity = -1; - runtime.microseconds_per_tick = 20000; - - switch_load_core_config("switch.conf"); - - switch_core_state_machine_init(runtime.memory_pool); - - if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - *err = "Error activating database"; - return SWITCH_STATUS_FALSE; - } - - switch_scheduler_task_thread_start(); - - switch_nat_late_init(); - - switch_rtp_init(runtime.memory_pool); - - runtime.running = 1; - runtime.initiated = switch_time_now(); - runtime.mono_initiated = switch_mono_micro_time_now(); - - switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL); - - switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD); - - switch_uuid_get(&uuid); - switch_uuid_format(runtime.uuid_str, &uuid); - switch_core_set_variable("core_uuid", runtime.uuid_str); - - - return SWITCH_STATUS_SUCCESS; -} - - -#ifndef WIN32 -static void handle_SIGCHLD(int sig) -{ - int status = 0; - - wait(&status); - return; -} -#endif - -#ifdef TRAP_BUS -static void handle_SIGBUS(int sig) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Sig BUS!\n"); - return; -} -#endif - -static void handle_SIGHUP(int sig) -{ - if (sig) { - switch_event_t *event; - - if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP"); - switch_event_fire(&event); - } - } - return; -} - - -SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number) -{ - uint32_t *p; - - if ((p = switch_core_hash_find(runtime.ptimes, name))) { - return *p; - } - - return 20; -} - -static uint32_t d_30 = 30; - -static void switch_load_core_config(const char *file) -{ - switch_xml_t xml = NULL, cfg = NULL; - - switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); - switch_core_hash_insert(runtime.ptimes, "G723", &d_30); - - if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) { - switch_xml_t settings, param; - - if ((settings = switch_xml_child(cfg, "default-ptimes"))) { - for (param = switch_xml_child(settings, "codec"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "ptime"); - - if (!zstr(var) && !zstr(val)) { - uint32_t *p; - uint32_t v = switch_atoul(val); - - if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var); - continue; - } - - if (v == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var); - continue; - } - - p = switch_core_alloc(runtime.memory_pool, sizeof(*p)); - *p = v; - switch_core_hash_insert(runtime.ptimes, var, p); - } - - } - } - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "loglevel")) { - int level; - if (*val > 47 && *val < 58) { - level = atoi(val); - } else { - level = switch_log_str2level(val); - } - - if (level != SWITCH_LOG_INVALID) { - switch_core_session_ctl(SCSC_LOGLEVEL, &level); - } -#ifdef HAVE_SETRLIMIT - } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) { - struct rlimit rlp; - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = RLIM_INFINITY; - rlp.rlim_max = RLIM_INFINITY; - setrlimit(RLIMIT_CORE, &rlp); -#endif - } else if (!strcasecmp(var, "debug-level")) { - int tmp = atoi(val); - if (tmp > -1 && tmp < 11) { - switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp); - } - } else if (!strcasecmp(var, "max-db-handles")) { - long tmp = atol(val); - - if (tmp > 4 && tmp < 5001) { - runtime.max_db_handles = (uint32_t) tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n"); - } - } else if (!strcasecmp(var, "db-handle-timeout")) { - long tmp = atol(val); - - if (tmp > 0 && tmp < 5001) { - runtime.db_handle_timeout = (uint32_t) tmp * 1000000; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n"); - } - - } else if (!strcasecmp(var, "multiple-registrations")) { - runtime.multiple_registrations = switch_true(val); - } else if (!strcasecmp(var, "auto-create-schemas")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); - } else { - switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS); - } - } else if (!strcasecmp(var, "session-thread-pool")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); - } else { - switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL); - } - } else if (!strcasecmp(var, "auto-clear-sql")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_CLEAR_SQL); - } else { - switch_clear_flag((&runtime), SCF_CLEAR_SQL); - } - } else if (!strcasecmp(var, "api-expansion")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_API_EXPANSION); - } else { - switch_clear_flag((&runtime), SCF_API_EXPANSION); - } - } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) { - switch_set_flag((&runtime), SCF_EARLY_HANGUP); - } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) { - runtime.colorize_console = SWITCH_TRUE; - } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) { - runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) { - runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) { - runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) { - runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) { - runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "mailer-app-args") && val) { - runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) { - switch_core_sessions_per_second(atoi(val)); - } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) { - int tmp = atoi(val); - if (tmp > 0) { - switch_core_max_dtmf_duration((uint32_t) tmp); - } - } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) { - int tmp = atoi(val); - if (tmp > 0) { - switch_core_min_dtmf_duration((uint32_t) tmp); - } - } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) { - int tmp = atoi(val); - if (tmp > 0) { - switch_core_default_dtmf_duration((uint32_t) tmp); - } - } else if (!strcasecmp(var, "enable-use-system-time")) { - switch_time_set_use_system_time(switch_true(val)); - } else if (!strcasecmp(var, "enable-monotonic-timing")) { - switch_time_set_monotonic(switch_true(val)); - } else if (!strcasecmp(var, "enable-softtimer-timerfd")) { - switch_time_set_timerfd(switch_true(val)); - } else if (!strcasecmp(var, "enable-clock-nanosleep")) { - switch_time_set_nanosleep(switch_true(val)); - } else if (!strcasecmp(var, "enable-cond-yield")) { - switch_time_set_cond_yield(switch_true(val)); - } else if (!strcasecmp(var, "enable-timer-matrix")) { - switch_time_set_matrix(switch_true(val)); - } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) { - switch_core_session_limit(atoi(val)); - } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) { - int v = switch_true(val); - if (v) { - switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); - } else { - switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); - } - } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) { -#ifdef WIN32 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n"); -#else - int v = switch_true(val); - if (v) { - switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } else { - switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } -#endif - } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) { - switch_core_min_idle_cpu(atof(val)); - } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) { - runtime.tipping_point = atoi(val); - } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) { - int tmp = atoi(val); - - - if (tmp > runtime.cpu_count / 2) { - tmp = runtime.cpu_count / 2; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n", - runtime.cpu_count / 2); - } - - if (tmp < 1) { - tmp = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n"); - } - - switch_event_launch_dispatch_threads(tmp); - - } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) { - runtime.microseconds_per_tick = 1000; - } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) { - if (!strcasecmp(val, "disabled")) { - runtime.timer_affinity = -1; - } else { - runtime.timer_affinity = atoi(val); - } - } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) { - 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() || switch_pgsql_available()) { - runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n"); - } - } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) { - switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ); - } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) { - if (!strcasecmp(val, "MSSQL")) { - runtime.odbc_dbtype = DBTYPE_MSSQL; - } else { - runtime.odbc_dbtype = DBTYPE_DEFAULT; - } -#ifdef ENABLE_ZRTP - } else if (!strcasecmp(var, "rtp-enable-zrtp")) { - switch_core_set_variable("zrtp_enabled", val); -#endif - } else if (!strcasecmp(var, "switchname") && !zstr(val)) { - runtime.switchname = switch_core_strdup(runtime.memory_pool, val); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname); - } - } - } - - if ((settings = switch_xml_child(cfg, "variables"))) { - for (param = switch_xml_child(settings, "variable"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - if (var && val) { - switch_core_set_variable(var, val); - } - } - } - - switch_xml_free(xml); - } - - -} - -SWITCH_DECLARE(const char *) switch_core_banner(void) -{ - - return ("\n" - ".=============================================================.\n" - "| _____ ______ _____ _____ ____ _ _ |\n" - "| | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | |\n" - "| | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | |\n" - "| | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | |\n" - "| |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| |\n" - "| |\n" - ".=============================================================." - "\n" - - "| Anthony Minessale II, Michael Jerris, Brian West, Others |\n" - "| FreeSWITCH (http://www.freeswitch.org) |\n" - "| Paypal Donations Appreciated: paypal@freeswitch.org |\n" - "| Brought to you by ClueCon http://www.cluecon.com/ |\n" - ".=============================================================.\n" - "\n"); -} - - -SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err) -{ - switch_event_t *event; - char *cmd; - int x = 0; - const char *use = NULL; -#include "cc.h" - - - if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_GENERR; - } - - if (runtime.runlevel > 1) { - /* one per customer */ - return SWITCH_STATUS_SUCCESS; - } - - runtime.runlevel++; - - switch_core_set_signal_handlers(); - switch_load_network_lists(SWITCH_FALSE); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n"); - if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { - *err = "Cannot load modules"; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err); - return SWITCH_STATUS_GENERR; - } - - switch_load_network_lists(SWITCH_FALSE); - - switch_load_core_config("post_load_switch.conf"); - - switch_core_set_signal_handlers(); - - if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); - switch_event_fire(&event); - } - - switch_core_screen_size(&x, NULL); - - use = (x > 100) ? cc : cc_s; - -#ifdef WIN32 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use); -#else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", - SWITCH_SEQ_DEFAULT_COLOR, - SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE, - switch_core_banner(), - use, SWITCH_SEQ_DEFAULT_COLOR); - -#endif - - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, - "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n", - SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN, - switch_core_session_limit(0), - switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); - - - if (x < 160) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n"); - } - - switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); - - if ((cmd = switch_core_get_variable_dup("api_on_startup"))) { - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - switch_console_execute(cmd, 0, &stream); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data); - free(stream.data); - free(cmd); - } - - return SWITCH_STATUS_SUCCESS; - -} - -SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration) -{ - switch_time_t temp = total_ms / 1000; - memset(duration, 0, sizeof(*duration)); - duration->mms = (uint32_t) (total_ms % 1000); - duration->ms = (uint32_t) (temp % 1000); - temp = temp / 1000; - duration->sec = (uint32_t) (temp % 60); - temp = temp / 60; - duration->min = (uint32_t) (temp % 60); - temp = temp / 60; - duration->hr = (uint32_t) (temp % 24); - temp = temp / 24; - duration->day = (uint32_t) (temp % 365); - duration->yr = (uint32_t) (temp / 365); -} - -SWITCH_DECLARE(switch_time_t) switch_core_uptime(void) -{ - return switch_mono_micro_time_now() - runtime.mono_initiated; -} - - -#ifdef _MSC_VER -static void win_shutdown(void) -{ - - HANDLE shutdown_event; - char path[512]; - /* for windows we need the event to signal for shutting down a background FreeSWITCH */ - snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); - - /* open the event so we can signal it */ - shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path); - - if (shutdown_event) { - /* signal the event to shutdown */ - SetEvent(shutdown_event); - /* cleanup */ - CloseHandle(shutdown_event); - } -} -#endif - -SWITCH_DECLARE(void) switch_core_set_signal_handlers(void) -{ - /* set signal handlers */ - signal(SIGINT, SIG_IGN); -#ifndef WIN32 - if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)) { - signal(SIGCHLD, SIG_DFL); - } else { - signal(SIGCHLD, handle_SIGCHLD); - } -#endif -#ifdef SIGPIPE - signal(SIGPIPE, SIG_IGN); -#endif -#ifdef SIGQUIT - signal(SIGQUIT, SIG_IGN); -#endif -#ifdef SIGPOLL - signal(SIGPOLL, SIG_IGN); -#endif -#ifdef SIGIO - signal(SIGIO, SIG_IGN); -#endif -#ifdef TRAP_BUS - signal(SIGBUS, handle_SIGBUS); -#endif -#ifdef SIGUSR1 - signal(SIGUSR1, handle_SIGHUP); -#endif - signal(SIGHUP, handle_SIGHUP); -} - -SWITCH_DECLARE(uint32_t) switch_core_debug_level(void) -{ - return runtime.debug_level; -} - - -SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val) -{ - int *intval = (int *) val; - int oldintval = 0, newintval = 0; - - if (intval) { - oldintval = *intval; - } - - if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) { - return -1; - } - - switch (cmd) { - case SCSC_RECOVER: - { - char *arg = (char *) val; - char *tech = NULL, *prof = NULL; - int r, flush = 0; - - if (!zstr(arg)) { - tech = strdup(arg); - - if ((prof = strchr(tech, ':'))) { - *prof++ = '\0'; - } - - if (!strcasecmp(tech, "flush")) { - flush++; - - if (prof) { - tech = prof; - if ((prof = strchr(tech, ':'))) { - *prof++ = '\0'; - } - } - } - - } - - if (flush) { - switch_core_recovery_flush(tech, prof); - r = -1; - } else { - r = switch_core_recovery_recover(tech, prof); - } - - switch_safe_free(tech); - return r; - - } - break; - case SCSC_DEBUG_SQL: - { - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_clear_flag((&runtime), SCF_DEBUG_SQL); - newintval = 0; - } else { - switch_set_flag((&runtime), SCF_DEBUG_SQL); - newintval = 1; - } - } - break; - case SCSC_VERBOSE_EVENTS: - if (intval) { - if (oldintval > -1) { - if (oldintval) { - switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); - } else { - switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); - } - } - newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS); - } - break; - case SCSC_API_EXPANSION: - if (intval) { - if (oldintval > -1) { - if (oldintval) { - switch_set_flag((&runtime), SCF_API_EXPANSION); - } else { - switch_clear_flag((&runtime), SCF_API_EXPANSION); - } - } - newintval = switch_test_flag((&runtime), SCF_API_EXPANSION); - } - break; - case SCSC_THREADED_SYSTEM_EXEC: - if (intval) { - if (oldintval > -1) { - if (oldintval) { - switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } else { - switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } - } - newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } - break; - case SCSC_CALIBRATE_CLOCK: - switch_time_calibrate_clock(); - break; - case SCSC_FLUSH_DB_HANDLES: - switch_cache_db_flush_handles(); - break; - case SCSC_SEND_SIGHUP: - handle_SIGHUP(1); - break; - case SCSC_SYNC_CLOCK: - switch_time_sync(); - newintval = 0; - break; - case SCSC_SYNC_CLOCK_WHEN_IDLE: - newintval = switch_core_session_sync_clock(); - break; - case SCSC_SQL: - if (oldintval) { - switch_core_sqldb_resume(); - } else { - switch_core_sqldb_pause(); - } - break; - case SCSC_PAUSE_ALL: - if (oldintval) { - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - } else { - switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); - } - break; - case SCSC_PAUSE_INBOUND: - if (oldintval) { - switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); - } else { - switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); - } - break; - case SCSC_PAUSE_OUTBOUND: - if (oldintval) { - switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); - } else { - switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); - } - break; - case SCSC_HUPALL: - switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST); - break; - case SCSC_CANCEL_SHUTDOWN: - switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED); - break; - case SCSC_SAVE_HISTORY: - switch_console_save_history(); - break; - case SCSC_CRASH: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n"); - switch_console_save_history(); - abort(); - break; - case SCSC_SHUTDOWN_NOW: - switch_console_save_history(); - exit(0); - break; - case SCSC_SHUTDOWN_ELEGANT: - case SCSC_SHUTDOWN_ASAP: - { - int x = 19; - uint32_t count; - - switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED); - if (cmd == SCSC_SHUTDOWN_ASAP) { - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - } - - while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) { - switch_yield(500000); - if (++x == 20) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Shutdown in progress, %u session(s) remain.\nShutting down %s\n", - count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls."); - x = 0; - } - } - - if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) { - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); -#ifdef _MSC_VER - win_shutdown(); -#endif - - if (oldintval) { - switch_set_flag((&runtime), SCF_RESTART); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); -#ifdef _MSC_VER - fclose(stdin); -#endif - } - runtime.running = 0; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n"); - switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); - } - } - break; - case SCSC_PAUSE_CHECK: - newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS); - break; - case SCSC_PAUSE_INBOUND_CHECK: - newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); - break; - case SCSC_PAUSE_OUTBOUND_CHECK: - newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); - break; - case SCSC_READY_CHECK: - newintval = switch_core_ready(); - break; - case SCSC_SHUTDOWN_CHECK: - newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED); - break; - case SCSC_SHUTDOWN: - -#ifdef _MSC_VER - win_shutdown(); -#endif - - if (oldintval) { - switch_set_flag((&runtime), SCF_RESTART); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); -#ifdef _MSC_VER - fclose(stdin); -#endif - } - runtime.running = 0; - break; - case SCSC_CHECK_RUNNING: - newintval = runtime.running; - break; - case SCSC_LOGLEVEL: - if (oldintval > -1) { - runtime.hard_log_level = oldintval; - } - - if (runtime.hard_log_level > SWITCH_LOG_DEBUG) { - runtime.hard_log_level = SWITCH_LOG_DEBUG; - } - newintval = runtime.hard_log_level; - break; - case SCSC_DEBUG_LEVEL: - if (oldintval > -1) { - if (oldintval > 10) - newintval = 10; - runtime.debug_level = oldintval; - } - newintval = runtime.debug_level; - break; - case SCSC_MIN_IDLE_CPU: - { - double *dval = (double *) val; - if (dval) { - *dval = switch_core_min_idle_cpu(*dval); - } - intval = NULL; - } - break; - case SCSC_MAX_SESSIONS: - newintval = switch_core_session_limit(oldintval); - break; - case SCSC_LAST_SPS: - newintval = runtime.sps_last; - break; - case SCSC_MAX_DTMF_DURATION: - newintval = switch_core_max_dtmf_duration(oldintval); - break; - case SCSC_MIN_DTMF_DURATION: - newintval = switch_core_min_dtmf_duration(oldintval); - break; - case SCSC_DEFAULT_DTMF_DURATION: - newintval = switch_core_default_dtmf_duration(oldintval); - break; - case SCSC_SPS: - switch_mutex_lock(runtime.throttle_mutex); - if (oldintval > 0) { - runtime.sps_total = oldintval; - } - newintval = runtime.sps_total; - switch_mutex_unlock(runtime.throttle_mutex); - break; - - case SCSC_RECLAIM: - switch_core_memory_reclaim_all(); - newintval = 0; - break; - } - - if (intval) { - *intval = newintval; - } - - - return 0; -} - -SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void) -{ - return runtime.flags; -} - -SWITCH_DECLARE(switch_bool_t) switch_core_ready(void) -{ - return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE; -} - -SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void) -{ - return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; -} - -SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void) -{ - return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; -} - -SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) -{ - switch_event_t *event; - - if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down"); - switch_event_fire(&event); - } - - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - switch_set_flag((&runtime), SCF_SHUTTING_DOWN); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n"); - switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n"); - - switch_loadable_module_shutdown(); - - switch_ssl_destroy_ssl_locks(); - - if (switch_test_flag((&runtime), SCF_USE_SQL)) { - switch_core_sqldb_stop(); - } - switch_scheduler_task_thread_stop(); - - switch_rtp_shutdown(); - - if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { - switch_nat_shutdown(); - } - switch_xml_destroy(); - switch_core_session_uninit(); - switch_console_shutdown(); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n"); - switch_event_shutdown(); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n"); - switch_log_shutdown(); - - switch_core_unset_variables(); - switch_core_memory_stop(); - - if (runtime.console && runtime.console != stdout && runtime.console != stderr) { - fclose(runtime.console); - runtime.console = NULL; - } - - switch_safe_free(SWITCH_GLOBAL_dirs.base_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.log_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.db_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.script_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.run_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir); - - switch_event_destroy(&runtime.global_vars); - switch_core_hash_destroy(&runtime.ptimes); - switch_core_hash_destroy(&runtime.mime_types); - - if (IP_LIST.hash) { - switch_core_hash_destroy(&IP_LIST.hash); - } - - if (IP_LIST.pool) { - switch_core_destroy_memory_pool(&IP_LIST.pool); - } - - if (runtime.memory_pool) { - apr_pool_destroy(runtime.memory_pool); - apr_terminate(); - } - - return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen) -{ - const switch_management_interface_t *ptr; - switch_status_t status = SWITCH_STATUS_FALSE; - - if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) { - status = ptr->management_function(relative_oid, action, data, datalen); - } - - return status; -} - -SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void) -{ - switch_core_memory_reclaim_logger(); - switch_core_memory_reclaim_events(); - switch_core_memory_reclaim(); -} - - -struct system_thread_handle { - const char *cmd; - switch_thread_cond_t *cond; - switch_mutex_t *mutex; - switch_memory_pool_t *pool; - int ret; - int *fds; -}; - -static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj) -{ - struct system_thread_handle *sth = (struct system_thread_handle *) obj; - -#if 0 // if we are a luser we can never turn this back down, didn't we already set the stack size? -#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) - struct rlimit rlim; - - rlim.rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE; - rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; - if (setrlimit(RLIMIT_STACK, &rlim) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); - } -#endif -#endif - - if (sth->fds) { - dup2(sth->fds[1], STDOUT_FILENO); - } - - sth->ret = system(sth->cmd); - -#if 0 -#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) - rlim.rlim_cur = SWITCH_THREAD_STACKSIZE; - rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; - if (setrlimit(RLIMIT_STACK, &rlim) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); - } -#endif -#endif - - switch_mutex_lock(sth->mutex); - switch_thread_cond_signal(sth->cond); - switch_mutex_unlock(sth->mutex); - - switch_core_destroy_memory_pool(&sth->pool); - - return NULL; -} - - -static int switch_system_thread(const char *cmd, switch_bool_t wait) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr; - int ret = 0; - struct system_thread_handle *sth; - switch_memory_pool_t *pool; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); - return 1; - } - - if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) { - switch_core_destroy_memory_pool(&pool); - return 1; - } - - sth->pool = pool; - sth->cmd = switch_core_strdup(pool, cmd); - - switch_thread_cond_create(&sth->cond, sth->pool); - switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool); - switch_mutex_lock(sth->mutex); - - switch_threadattr_create(&thd_attr, sth->pool); - switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE); - switch_threadattr_detach_set(thd_attr, 1); - switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool); - - if (wait) { - switch_thread_cond_wait(sth->cond, sth->mutex); - ret = sth->ret; - } - switch_mutex_unlock(sth->mutex); - - return ret; -} - -SWITCH_DECLARE(int) switch_max_file_desc(void) -{ - int max = 0; - -#ifndef WIN32 -#if defined(HAVE_GETDTABLESIZE) - max = getdtablesize(); -#else - max = sysconf(_SC_OPEN_MAX); -#endif -#endif - - return max; - -} - -SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl) -{ - int open_max = switch_max_file_desc(); - int i, j; - - for (i = 3; i < open_max; i++) { - if (keep) { - for (j = 0; j < keep_ttl; j++) { - if (i == keep[j]) { - goto skip; - } - } - } - - close(i); - - skip: - - continue; - - } -} - - -#ifdef WIN32 -static int switch_system_fork(const char *cmd, switch_bool_t wait) -{ - return switch_system_thread(cmd, wait); -} - -SWITCH_DECLARE(pid_t) switch_fork(void) -{ - return -1; -} - - -#else - -SWITCH_DECLARE(pid_t) switch_fork(void) -{ - int i = fork(); - - if (!i) { - set_low_priority(); - } - - return i; -} - - - -static int switch_system_fork(const char *cmd, switch_bool_t wait) -{ - int pid; - char *dcmd = strdup(cmd); - - switch_core_set_signal_handlers(); - - pid = switch_fork(); - - if (pid) { - if (wait) { - waitpid(pid, NULL, 0); - } - free(dcmd); - } else { - switch_close_extra_files(NULL, 0); - - if (system(dcmd) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd); - } - free(dcmd); - exit(0); - } - - return 0; -} -#endif - - - -SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait) -{ - int (*sys_p)(const char *cmd, switch_bool_t wait); - - sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork; - - return sys_p(cmd, wait); - -} - - - -SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream) -{ -#ifdef WIN32 - return switch_system(cmd, SWITCH_TRUE); -#else - int fds[2], pid = 0; - - if (pipe(fds)) { - goto end; - } else { /* good to go */ - pid = switch_fork(); - - if (pid < 0) { /* ok maybe not */ - close(fds[0]); - close(fds[1]); - goto end; - } else if (pid) { /* parent */ - char buf[1024] = ""; - int bytes; - close(fds[1]); - while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) { - stream->raw_write_function(stream, (unsigned char *)buf, bytes); - } - close(fds[0]); - waitpid(pid, NULL, 0); - } else { /* child */ - switch_close_extra_files(fds, 2); - close(fds[0]); - dup2(fds[1], STDOUT_FILENO); - switch_system(cmd, SWITCH_TRUE); - close(fds[1]); - exit(0); - } - } - - end: - - return 0; - -#endif - -} - -SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max) -{ -#ifdef HAVE_SETRLIMIT - struct rlimit rlp; - - memset(&rlp, 0, sizeof(rlp)); - getrlimit(RLIMIT_STACK, &rlp); - - *cur = rlp.rlim_cur; - *max = rlp.rlim_max; - - return SWITCH_STATUS_SUCCESS; - -#else - - return SWITCH_STATUS_FALSE; - -#endif - - - -} - - -SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream) -{ -#ifdef WIN32 - stream->write_function(stream, "Capturing output not supported.\n"); - return switch_system(cmd, SWITCH_TRUE); -#else - return switch_stream_system_fork(cmd, stream); -#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: - */ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2012, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * 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 Jerris + * Paul D. Tinsley + * Marcel Barbulescu + * Joseph Sullivan + * + * + * switch_core.c -- Main Core Library + * + */ + + + +#include +#include +#include +#include +#include +#include "private/switch_core_pvt.h" +#include +#ifndef WIN32 +#include +#ifdef HAVE_SETRLIMIT +#include +#endif +#endif +#include + + +SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 }; + +/* The main runtime obj we keep this hidden for ourselves */ +struct switch_runtime runtime = { 0 }; +static void switch_load_core_config(const char *file); + +static void send_heartbeat(void) +{ + switch_event_t *event; + switch_core_time_duration_t duration; + + switch_core_measure_time(switch_core_uptime(), &duration); + + if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time", + "%u year%s, " + "%u day%s, " + "%u hour%s, " + "%u minute%s, " + "%u second%s, " + "%u millisecond%s, " + "%u microsecond%s", + duration.yr, duration.yr == 1 ? "" : "s", + duration.day, duration.day == 1 ? "" : "s", + duration.hr, duration.hr == 1 ? "" : "s", + duration.min, duration.min == 1 ? "" : "s", + duration.sec, duration.sec == 1 ? "" : "s", + duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s"); + + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", SWITCH_VERSION_FULL); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT, switch_core_uptime() / 1000); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count()); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu()); + switch_event_fire(&event); + } +} + +static char main_ip4[256] = ""; +static char main_ip6[256] = ""; + +static void check_ip(void) +{ + char guess_ip4[256] = ""; + char guess_ip6[256] = ""; + char old_ip4[256] = ""; + char old_ip6[256] = ""; + int ok4 = 1, ok6 = 1; + int mask = 0; + + gethostname(runtime.hostname, sizeof(runtime.hostname)); + switch_core_set_variable("hostname", runtime.hostname); + + switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET); + switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6); + + if (!*main_ip4) { + switch_set_string(main_ip4, guess_ip4); + } else { + if (!(ok4 = !strcmp(main_ip4, guess_ip4))) { + struct in_addr in; + + in.s_addr = mask; + switch_set_string(old_ip4, main_ip4); + switch_set_string(main_ip4, guess_ip4); + switch_core_set_variable("local_ip_v4", guess_ip4); + switch_core_set_variable("local_mask_v4", inet_ntoa(in)); + } + } + + if (!*main_ip6) { + switch_set_string(main_ip6, guess_ip6); + } else { + if (!(ok6 = !strcmp(main_ip6, guess_ip6))) { + switch_set_string(old_ip6, main_ip6); + switch_set_string(main_ip6, guess_ip6); + switch_core_set_variable("local_ip_v6", guess_ip6); + } + } + + if (!ok4 || !ok6) { + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change"); + if (!ok4) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4); + } + if (!ok6) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6); + } + switch_event_fire(&event); + } + } +} + +SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback) +{ + send_heartbeat(); + + /* reschedule this task */ + task->runtime = switch_epoch_time_now(NULL) + 20; +} + + +SWITCH_STANDARD_SCHED_FUNC(check_ip_callback) +{ + check_ip(); + + /* reschedule this task */ + task->runtime = switch_epoch_time_now(NULL) + 60; +} + + +SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console) +{ + if ((runtime.console = fopen(console, "a")) == 0) { + fprintf(stderr, "Cannot open output file %s.\n", console); + return SWITCH_STATUS_FALSE; + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(FILE *) switch_core_get_console(void) +{ + return runtime.console; +} + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) +{ + +#ifdef WIN32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + int ret; + + if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) { + if (x) *x = csbi.dwSize.X; + if (y) *y = csbi.dwSize.Y; + } + +#elif defined(TIOCGWINSZ) + struct winsize w; + ioctl(0, TIOCGWINSZ, &w); + + if (x) *x = w.ws_col; + if (y) *y = w.ws_row; +#else + if (x) *x = 80; + if (y) *y = 24; +#endif + +} + +SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel) +{ + FILE *handle = stdout; + + switch (channel) { + case SWITCH_CHANNEL_ID_LOG: + case SWITCH_CHANNEL_ID_LOG_CLEAN: + handle = runtime.console; + break; + default: + handle = runtime.console; + break; + } + + return handle; +} + + +SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler) +{ + int index, tmp_index = 0; + const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 }; + + switch_mutex_lock(runtime.global_mutex); + + for (index = 0; index < runtime.state_handler_index; index++) { + const switch_state_handler_table_t *cur = runtime.state_handlers[index]; + runtime.state_handlers[index] = NULL; + if (cur == state_handler) { + continue; + } + tmp[tmp_index++] = cur; + } + + runtime.state_handler_index = 0; + + for (index = 0; index < tmp_index; index++) { + runtime.state_handlers[runtime.state_handler_index++] = tmp[index]; + } + switch_mutex_unlock(runtime.global_mutex); +} + + +SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler) +{ + int index; + + switch_mutex_lock(runtime.global_mutex); + index = runtime.state_handler_index++; + + if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS) { + index = -1; + } else { + runtime.state_handlers[index] = state_handler; + } + + switch_mutex_unlock(runtime.global_mutex); + return index; +} + +SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index) +{ + + if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) { + return NULL; + } + + return runtime.state_handlers[index]; +} + +SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream) +{ + switch_event_header_t *hi; + + switch_mutex_lock(runtime.global_mutex); + for (hi = runtime.global_vars->headers; hi; hi = hi->next) { + stream->write_function(stream, "%s=%s\n", hi->name, hi->value); + } + switch_mutex_unlock(runtime.global_mutex); +} + +SWITCH_DECLARE(const char *) switch_core_get_hostname(void) +{ + return runtime.hostname; +} + +SWITCH_DECLARE(const char *) switch_core_get_switchname(void) +{ + if (!zstr(runtime.switchname)) return runtime.switchname; + return runtime.hostname; +} + + +SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) +{ + char *val; + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + val = (char *) switch_event_get_header(runtime.global_vars, varname); + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + return val; +} + +SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname) +{ + char *val = NULL, *v; + + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = strdup(v); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + + return val; +} + +SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool) +{ + char *val = NULL, *v; + + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = switch_core_strdup(pool, v); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + + return val; +} + +static void switch_core_unset_variables(void) +{ + switch_thread_rwlock_wrlock(runtime.global_var_rwlock); + switch_event_destroy(&runtime.global_vars); + switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); + switch_thread_rwlock_unlock(runtime.global_var_rwlock); +} + +SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value) +{ + char *val; + + if (varname) { + switch_thread_rwlock_wrlock(runtime.global_var_rwlock); + val = (char *) switch_event_get_header(runtime.global_vars, varname); + if (val) { + switch_event_del_header(runtime.global_vars, varname); + } + if (value) { + char *v = strdup(value); + switch_string_var_check(v, SWITCH_TRUE); + switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); + } else { + switch_event_del_header(runtime.global_vars, varname); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + } +} + +SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2) +{ + char *val; + + if (varname) { + switch_thread_rwlock_wrlock(runtime.global_var_rwlock); + val = (char *) switch_event_get_header(runtime.global_vars, varname); + + if (val) { + if (!val2 || strcmp(val, val2) != 0) { + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + return SWITCH_FALSE; + } + switch_event_del_header(runtime.global_vars, varname); + } else if (!zstr(val2)) { + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + return SWITCH_FALSE; + } + + if (value) { + char *v = strdup(value); + switch_string_var_check(v, SWITCH_TRUE); + switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); + } else { + switch_event_del_header(runtime.global_vars, varname); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + } + return SWITCH_TRUE; +} + +SWITCH_DECLARE(char *) switch_core_get_uuid(void) +{ + return runtime.uuid_str; +} + + +static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj) +{ + switch_core_session_t *session = obj; + switch_channel_t *channel; + switch_frame_t *read_frame; + +// switch_assert(thread != NULL); +// switch_assert(session != NULL); + + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { + return NULL; + } + + switch_mutex_lock(session->frame_read_mutex); + + channel = switch_core_session_get_channel(session); + + switch_channel_set_flag(channel, CF_SERVICE); + while (switch_channel_test_flag(channel, CF_SERVICE)) { + + if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) { + switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { + case SWITCH_STATUS_SUCCESS: + case SWITCH_STATUS_TIMEOUT: + case SWITCH_STATUS_BREAK: + break; + default: + switch_channel_clear_flag(channel, CF_SERVICE); + break; + } + } + + if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) { + switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { + case SWITCH_STATUS_SUCCESS: + case SWITCH_STATUS_TIMEOUT: + case SWITCH_STATUS_BREAK: + break; + default: + switch_channel_clear_flag(channel, CF_SERVICE); + break; + } + } + } + + switch_mutex_unlock(session->frame_read_mutex); + + switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); + switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); + + switch_core_session_rwunlock(session); + + return NULL; +} + +/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */ +SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session) +{ + switch_channel_t *channel; + switch_assert(session); + + channel = switch_core_session_get_channel(session); + switch_assert(channel); + + switch_channel_clear_flag(channel, CF_SERVICE); + switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); + switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); + + switch_core_session_kill_channel(session, SWITCH_SIG_BREAK); + +} + +SWITCH_DECLARE(void) switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video) +{ + switch_channel_t *channel; + switch_assert(session); + + channel = switch_core_session_get_channel(session); + switch_assert(channel); + + if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO); + if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO); + + switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session); +} + +/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and + a void object and trust that that the function will be run in a thread with arg This lets + you request and activate a thread without giving up any knowledge about what is in the thread + neither the core nor the calling module know anything about each other. + + This thread is expected to never exit until the application exits so the func is responsible + to make sure that is the case. + + The typical use for this is so switch_loadable_module.c can start up a thread for each module + passing the table of module methods as a session obj into the core without actually allowing + the core to have any clue and keeping switch_loadable_module.c from needing any thread code. + +*/ + +SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool) +{ + switch_thread_t *thread = NULL; + switch_threadattr_t *thd_attr = NULL; + switch_core_thread_session_t *ts; + int mypool; + + mypool = pool ? 0 : 1; + + if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n"); + return NULL; + } + + switch_threadattr_create(&thd_attr, pool); + + if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n"); + } else { + if (mypool) { + ts->pool = pool; + } + ts->objs[0] = obj; + ts->objs[1] = thread; + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); + switch_thread_create(&thread, thd_attr, func, ts, pool); + } + + return thread; +} + +SWITCH_DECLARE(void) switch_core_set_globals(void) +{ +#define BUFSIZE 1024 +#ifdef WIN32 + char lpPathBuffer[BUFSIZE]; + DWORD dwBufSize = BUFSIZE; + char base_dir[1024]; + char *lastbacklash; + char *tmp; + + GetModuleFileName(NULL, base_dir, BUFSIZE); + lastbacklash = strrchr(base_dir, '\\'); + base_dir[(lastbacklash - base_dir)] = '\0'; + /* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */ + SetCurrentDirectory(base_dir); + tmp = switch_string_replace(base_dir, "\\", "/"); + strcpy(base_dir, tmp); + free(tmp); + +#else + char base_dir[1024] = SWITCH_PREFIX_DIR; +#endif + + if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) { + switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir); + } + + if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_MOD_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_LIB_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_CONF_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_LOG_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_RUN_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_RECORDINGS_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_SOUNDS_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_STORAGE_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_DB_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_SCRIPT_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_HTDOCS_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_GRAMMAR_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_TEMP_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR); +#else +#ifdef WIN32 + GetTempPath(dwBufSize, lpPathBuffer); + lpPathBuffer[strlen(lpPathBuffer)-1] = 0; + tmp = switch_string_replace(lpPathBuffer, "\\", "/"); + strcpy(lpPathBuffer, tmp); + free(tmp); + switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp"); +#endif +#endif + } + + switch_assert(SWITCH_GLOBAL_dirs.base_dir); + switch_assert(SWITCH_GLOBAL_dirs.mod_dir); + switch_assert(SWITCH_GLOBAL_dirs.lib_dir); + switch_assert(SWITCH_GLOBAL_dirs.conf_dir); + switch_assert(SWITCH_GLOBAL_dirs.log_dir); + switch_assert(SWITCH_GLOBAL_dirs.run_dir); + switch_assert(SWITCH_GLOBAL_dirs.db_dir); + switch_assert(SWITCH_GLOBAL_dirs.script_dir); + switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir); + switch_assert(SWITCH_GLOBAL_dirs.grammar_dir); + switch_assert(SWITCH_GLOBAL_dirs.recordings_dir); + switch_assert(SWITCH_GLOBAL_dirs.sounds_dir); + switch_assert(SWITCH_GLOBAL_dirs.temp_dir); +} + + +SWITCH_DECLARE(int32_t) set_low_priority(void) +{ + + +#ifdef WIN32 + SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); +#else +#ifdef USE_SCHED_SETSCHEDULER + /* + * Try to use a normal scheduler + */ + struct sched_param sched = { 0 }; + sched.sched_priority = 0; + if (sched_setscheduler(0, SCHED_OTHER, &sched)) { + return -1; + } +#endif + +#ifdef HAVE_SETPRIORITY + /* + * setpriority() works on FreeBSD (6.2), nice() doesn't + */ + if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#else + if (nice(19) != 19) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#endif +#endif + + return 0; +} + +SWITCH_DECLARE(int32_t) set_realtime_priority(void) +{ +#ifdef WIN32 + SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); +#else +#ifdef USE_SCHED_SETSCHEDULER + /* + * Try to use a round-robin scheduler + * with a fallback if that does not work + */ + struct sched_param sched = { 0 }; + sched.sched_priority = SWITCH_PRI_LOW; + if (sched_setscheduler(0, SCHED_FIFO, &sched)) { + sched.sched_priority = 0; + if (sched_setscheduler(0, SCHED_OTHER, &sched)) { + return -1; + } + } +#endif + + + +#ifdef HAVE_SETPRIORITY + /* + * setpriority() works on FreeBSD (6.2), nice() doesn't + */ + if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#else + if (nice(-10) != -10) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#endif +#endif + return 0; +} + +SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void) +{ + return runtime.cpu_count; +} + +SWITCH_DECLARE(int32_t) set_normal_priority(void) +{ + return 0; +} + +SWITCH_DECLARE(int32_t) set_auto_priority(void) +{ +#ifndef WIN32 + runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); +#else + SYSTEM_INFO sysinfo; + GetSystemInfo( &sysinfo ); + runtime.cpu_count = sysinfo.dwNumberOfProcessors; +#endif + + if (!runtime.cpu_count) runtime.cpu_count = 1; + + /* If we have more than 1 cpu, we should use realtime priority so we can have priority threads */ + if (runtime.cpu_count > 1) { + return set_realtime_priority(); + } + + return 0; +} + +SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group) +{ +#ifndef WIN32 + uid_t runas_uid = 0; + gid_t runas_gid = 0; + struct passwd *runas_pw = NULL; + + if (user) { + /* + * Lookup user information in the system's db + */ + runas_pw = getpwnam(user); + if (!runas_pw) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user); + return -1; + } + runas_uid = runas_pw->pw_uid; + } + + if (group) { + struct group *gr = NULL; + + /* + * Lookup group information in the system's db + */ + gr = getgrnam(group); + if (!gr) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group); + return -1; + } + runas_gid = gr->gr_gid; + } + + if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) { + /* already running as the right user and group, nothing to do! */ + return 0; + } + + if (runas_uid) { +#ifdef HAVE_SETGROUPS + /* + * Drop all group memberships prior to changing anything + * or else we're going to inherit the parent's list of groups + * (which is not what we want...) + */ + if (setgroups(0, NULL) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to drop group access list\n"); + return -1; + } +#endif + if (runas_gid) { + /* + * A group has been passed, switch to it + * (without loading the user's other groups) + */ + if (setgid(runas_gid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); + return -1; + } + } else { + /* + * No group has been passed, use the user's primary group in this case + */ + if (setgid(runas_pw->pw_gid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); + return -1; + } +#ifdef HAVE_INITGROUPS + /* + * Set all the other groups the user is a member of + * (This can be really useful for fine-grained access control) + */ + if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to set group access list for user\n"); + return -1; + } +#endif + } + + /* + * Finally drop all privileges by switching to the new userid + */ + if (setuid(runas_uid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n"); + return -1; + } + } +#endif + return 0; +} + +SWITCH_DECLARE(void) switch_core_runtime_loop(int bg) +{ +#ifdef WIN32 + HANDLE shutdown_event; + char path[256] = ""; +#endif + if (bg) { + bg = 0; +#ifdef WIN32 + switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); + shutdown_event = CreateEvent(NULL, FALSE, FALSE, path); + if (shutdown_event) { + WaitForSingleObject(shutdown_event, INFINITE); + } +#else + runtime.running = 1; + while (runtime.running) { + switch_yield(1000000); + } +#endif + } else { + /* wait for console input */ + switch_console_loop(); + } +} + +SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext) +{ + if (!ext) { + return NULL; + } + return (const char *) switch_core_hash_find(runtime.mime_types, ext); +} + + +SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void) +{ + return switch_hash_first(NULL, runtime.mime_types); +} + +SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext) +{ + const char *check; + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_assert(type); + switch_assert(ext); + + check = (const char *) switch_core_hash_find(runtime.mime_types, ext); + + if (!check) { + char *ptype = switch_core_permanent_strdup(type); + char *ext_list = strdup(ext); + int argc = 0; + char *argv[20] = { 0 }; + int x; + + switch_assert(ext_list); + + if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { + + for (x = 0; x < argc; x++) { + if (argv[x] && ptype) { + switch_core_hash_insert(runtime.mime_types, argv[x], ptype); + } + } + + status = SWITCH_STATUS_SUCCESS; + } + + free(ext_list); + } + + return status; +} + +static void load_mime_types(void) +{ + char *cf = "mime.types"; + FILE *fd = NULL; + char *line_buf = NULL; + switch_size_t llen = 0; + char *mime_path = NULL; + + mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf); + switch_assert(mime_path); + + fd = fopen(mime_path, "rb"); + + if (fd == NULL) { + goto end; + } + + while ((switch_fp_read_dline(fd, &line_buf, &llen))) { + char *p; + char *type = line_buf; + + if (*line_buf == '#') { + continue; + } + + if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) { + *p = '\0'; + } + + if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) { + *p++ = '\0'; + + while (*p == ' ' || *p == '\t') { + p++; + } + + switch_core_mime_add_type(type, p); + } + + } + + switch_safe_free(line_buf); + + if (fd) { + fclose(fd); + fd = NULL; + } + + end: + + switch_safe_free(mime_path); + +} + +SWITCH_DECLARE(void) switch_core_setrlimits(void) +{ +#ifdef HAVE_SETRLIMIT + struct rlimit rlp; + + /* + Setting the stack size on FreeBSD results in an instant crash. + + If anyone knows how to fix this, + feel free to submit a patch to http://jira.freeswitch.org + */ + +#ifndef __FreeBSD__ + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; + rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; + setrlimit(RLIMIT_STACK, &rlp); +#endif + + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = 999999; + rlp.rlim_max = 999999; + setrlimit(RLIMIT_NOFILE, &rlp); + + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = RLIM_INFINITY; + rlp.rlim_max = RLIM_INFINITY; + + setrlimit(RLIMIT_CPU, &rlp); + setrlimit(RLIMIT_DATA, &rlp); + setrlimit(RLIMIT_FSIZE, &rlp); +#ifdef RLIMIT_NPROC + setrlimit(RLIMIT_NPROC, &rlp); +#endif +#ifdef RLIMIT_RTPRIO + setrlimit(RLIMIT_RTPRIO, &rlp); +#endif + +#if !defined(__OpenBSD__) && !defined(__NetBSD__) + setrlimit(RLIMIT_AS, &rlp); +#endif +#endif + return; +} + +typedef struct { + switch_memory_pool_t *pool; + switch_hash_t *hash; +} switch_ip_list_t; + +static switch_ip_list_t IP_LIST = { 0 }; + +SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token) +{ + switch_network_list_t *list; + ip_t ip, mask, net; + uint32_t bits; + char *ipv6 = strchr(ip_str,':'); + switch_bool_t ok = SWITCH_FALSE; + + switch_mutex_lock(runtime.global_mutex); + if (ipv6) { + switch_inet_pton(AF_INET6, ip_str, &ip); + } else { + switch_inet_pton(AF_INET, ip_str, &ip); + ip.v4 = htonl(ip.v4); + } + + if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) { + if (ipv6) { + ok = switch_network_list_validate_ip6_token(list, ip, token); + } else { + ok = switch_network_list_validate_ip_token(list, ip.v4, token); + } + } else if (strchr(list_name, '/')) { + if (strchr(list_name, ',')) { + char *list_name_dup = strdup(list_name); + char *argv[32]; + int argc; + + switch_assert(list_name_dup); + + if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { + int i; + for (i = 0; i < argc; i++) { + switch_parse_cidr(argv[i], &net, &mask, &bits); + if (ipv6) { + if ((ok = switch_testv6_subnet(ip, net, mask))){ + break; + } + } else { + if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) { + break; + } + } + } + } + free(list_name_dup); + } else { + switch_parse_cidr(list_name, &net, &mask, &bits); + ok = switch_test_subnet(ip.v4, net.v4, mask.v4); + } + } + switch_mutex_unlock(runtime.global_mutex); + + return ok; +} + + +SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload) +{ + switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL; + switch_network_list_t *rfc_list, *list; + char guess_ip[16] = ""; + int mask = 0; + char guess_mask[16] = ""; + char *tmp_name; + struct in_addr in; + + switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); + in.s_addr = mask; + switch_set_string(guess_mask, inet_ntoa(in)); + + switch_mutex_lock(runtime.global_mutex); + + if (IP_LIST.hash) { + switch_core_hash_destroy(&IP_LIST.hash); + } + + if (IP_LIST.pool) { + switch_core_destroy_memory_pool(&IP_LIST.pool); + } + + memset(&IP_LIST, 0, sizeof(IP_LIST)); + switch_core_new_memory_pool(&IP_LIST.pool); + switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool); + + + tmp_name = "rfc1918.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "wan.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "nat.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name); + } + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "loopback.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "localnet.auto"; + switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + + if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name); + } + switch_core_hash_insert(IP_LIST.hash, tmp_name, list); + + + if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) { + if ((x_lists = switch_xml_child(cfg, "network-lists"))) { + for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) { + const char *name = switch_xml_attr(x_list, "name"); + const char *dft = switch_xml_attr(x_list, "default"); + switch_bool_t default_type = SWITCH_TRUE; + + if (zstr(name)) { + continue; + } + + if (dft) { + default_type = switch_true(dft); + } + + if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) { + abort(); + } + + if (reload) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); + } + + + for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) { + const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL; + switch_bool_t ok = default_type; + const char *type = switch_xml_attr(x_node, "type"); + + if (type) { + ok = switch_true(type); + } + + cidr = switch_xml_attr(x_node, "cidr"); + host = switch_xml_attr(x_node, "host"); + mask = switch_xml_attr(x_node, "mask"); + domain = switch_xml_attr(x_node, "domain"); + + if (domain) { + switch_event_t *my_params = NULL; + switch_xml_t x_domain, xml_root; + switch_xml_t gt, gts, ut, uts; + + switch_event_create(&my_params, SWITCH_EVENT_GENERAL); + switch_assert(my_params); + switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain); + switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list"); + + if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain); + switch_event_destroy(&my_params); + continue; + } + + switch_event_destroy(&my_params); + + for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) { + const char *user_cidr = switch_xml_attr(ut, "cidr"); + const char *id = switch_xml_attr(ut, "id"); + + if (id && user_cidr) { + char *token = switch_mprintf("%s@%s", id, domain); + switch_assert(token); + switch_network_list_add_cidr_token(list, user_cidr, ok, token); + free(token); + } + } + + for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) { + for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) { + for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) { + for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) { + const char *user_cidr = switch_xml_attr(ut, "cidr"); + const char *id = switch_xml_attr(ut, "id"); + + if (id && user_cidr) { + char *token = switch_mprintf("%s@%s", id, domain); + switch_assert(token); + switch_network_list_add_cidr_token(list, user_cidr, ok, token); + free(token); + } + } + } + } + } + + switch_xml_free(xml_root); + } else if (cidr) { + if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); + } + } else if (host && mask) { + if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, + "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name); + } + } + + switch_core_hash_insert(IP_LIST.hash, name, list); + } + } + } + + switch_xml_free(xml); + } + + switch_mutex_unlock(runtime.global_mutex); +} + +SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration) +{ + if (duration) { + if (duration > SWITCH_MAX_DTMF_DURATION) { + duration = SWITCH_MAX_DTMF_DURATION; + } + if (duration < SWITCH_MIN_DTMF_DURATION) { + duration = SWITCH_MIN_DTMF_DURATION; + } + runtime.max_dtmf_duration = duration; + if (duration < runtime.min_dtmf_duration) { + runtime.min_dtmf_duration = duration; + } + } + return runtime.max_dtmf_duration; +} + +SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration) +{ + if (duration) { + if (duration < SWITCH_MIN_DTMF_DURATION) { + duration = SWITCH_MIN_DTMF_DURATION; + } + if (duration > SWITCH_MAX_DTMF_DURATION) { + duration = SWITCH_MAX_DTMF_DURATION; + } + runtime.default_dtmf_duration = duration; + + if (duration < runtime.min_dtmf_duration) { + runtime.min_dtmf_duration = duration; + } + + if (duration > runtime.max_dtmf_duration) { + runtime.max_dtmf_duration = duration; + } + + } + return runtime.default_dtmf_duration; +} + +SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration) +{ + if (duration) { + if (duration < SWITCH_MIN_DTMF_DURATION) { + duration = SWITCH_MIN_DTMF_DURATION; + } + if (duration > SWITCH_MAX_DTMF_DURATION) { + duration = SWITCH_MAX_DTMF_DURATION; + } + + runtime.min_dtmf_duration = duration; + + if (duration > runtime.max_dtmf_duration) { + runtime.max_dtmf_duration = duration; + } + } + return runtime.min_dtmf_duration; +} + +SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + if (cpu > -1) { + +#ifdef HAVE_CPU_SET_MACROS + cpu_set_t set; + + CPU_ZERO(&set); + CPU_SET(cpu, &set); + + if (!sched_setaffinity(0, sizeof(set), &set)) { + status = SWITCH_STATUS_SUCCESS; + } + +#else +#if WIN32 + if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) { + status = SWITCH_STATUS_SUCCESS; + } +#endif +#endif + } + + return status; +} + + +static void switch_core_set_serial(void) +{ + char buf[13] = ""; + char path[256]; + + int fd = -1, write_fd = -1; + switch_ssize_t bytes = 0; + + switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR); + + + if ((fd = open(path, O_RDONLY, 0)) < 0) { + char *ip = switch_core_get_variable_dup("local_ip_v4"); + uint32_t ipi = 0; + switch_byte_t *byte; + int i = 0; + + if (ip) { + switch_inet_pton(AF_INET, ip, &ipi); + free(ip); + ip = NULL; + } + + + byte = (switch_byte_t *) & ipi; + + for (i = 0; i < 8; i += 2) { + switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte); + byte++; + } + + switch_stun_random_string(buf + 8, 4, "0123456789abcdef"); + + if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) { + bytes = write(write_fd, buf, sizeof(buf)); + bytes++; + close(write_fd); + write_fd = -1; + } + } else { + bytes = read(fd, buf, sizeof(buf)); + close(fd); + fd = -1; + } + + switch_core_set_variable("switch_serial", buf); +} + + +SWITCH_DECLARE(int) switch_core_test_flag(int flag) +{ + return switch_test_flag((&runtime), flag); +} + + +SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err) +{ + switch_uuid_t uuid; + char guess_ip[256]; + int mask = 0; + struct in_addr in; + + + if (runtime.runlevel > 0) { + /* one per customer */ + return SWITCH_STATUS_SUCCESS; + } + + memset(&runtime, 0, sizeof(runtime)); + gethostname(runtime.hostname, sizeof(runtime.hostname)); + + runtime.max_db_handles = 50; + runtime.db_handle_timeout = 5000000; + + runtime.runlevel++; + runtime.dummy_cng_frame.data = runtime.dummy_data; + runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); + runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); + runtime.dbname = "core"; + switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG); + switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); + switch_set_flag((&runtime), SCF_CLEAR_SQL); + switch_set_flag((&runtime), SCF_API_EXPANSION); + switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); +#ifdef WIN32 + switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); +#endif + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + runtime.hard_log_level = SWITCH_LOG_DEBUG; + runtime.mailer_app = "sendmail"; + runtime.mailer_app_args = "-t"; + runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION; + runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION; + runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION; + runtime.odbc_dbtype = DBTYPE_DEFAULT; + runtime.dbname = NULL; +#ifndef WIN32 + runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); +#else + { + SYSTEM_INFO sysinfo; + GetSystemInfo( &sysinfo ); + runtime.cpu_count = sysinfo.dwNumberOfProcessors; + } +#endif + + if (!runtime.cpu_count) runtime.cpu_count = 1; + + + /* INIT APR and Create the pool context */ + if (apr_initialize() != SWITCH_STATUS_SUCCESS) { + *err = "FATAL ERROR! Could not initialize APR\n"; + return SWITCH_STATUS_MEMERR; + } + + if (!(runtime.memory_pool = switch_core_memory_init())) { + *err = "FATAL ERROR! Could not allocate memory pool\n"; + return SWITCH_STATUS_MEMERR; + } + switch_assert(runtime.memory_pool != NULL); + + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + + + switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + + switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + + switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + + switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool); + switch_core_set_globals(); + switch_core_session_init(runtime.memory_pool); + switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); + switch_core_hash_init(&runtime.mime_types, runtime.memory_pool); + switch_core_hash_init_case(&runtime.ptimes, runtime.memory_pool, SWITCH_FALSE); + load_mime_types(); + runtime.flags |= flags; + runtime.sps_total = 30; + + *err = NULL; + + if (console) { + runtime.console = stdout; + } + + switch_ssl_init_ssl_locks(); + switch_curl_init(); + + switch_core_set_variable("hostname", runtime.hostname); + switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); + switch_core_set_variable("local_ip_v4", guess_ip); + in.s_addr = mask; + switch_core_set_variable("local_mask_v4", inet_ntoa(in)); + + + switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6); + switch_core_set_variable("local_ip_v6", guess_ip); + switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir); + switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir); + switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir); + switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir); + switch_core_set_serial(); + + switch_console_init(runtime.memory_pool); + switch_event_init(runtime.memory_pool); + + if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) { + apr_terminate(); + return SWITCH_STATUS_MEMERR; + } + + if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { + switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING)); + } + + switch_log_init(runtime.memory_pool, runtime.colorize_console); + + if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; + + runtime.tipping_point = 0; + runtime.timer_affinity = -1; + runtime.microseconds_per_tick = 20000; + + switch_load_core_config("switch.conf"); + + switch_core_state_machine_init(runtime.memory_pool); + + if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { + *err = "Error activating database"; + return SWITCH_STATUS_FALSE; + } + + switch_scheduler_task_thread_start(); + + switch_nat_late_init(); + + switch_rtp_init(runtime.memory_pool); + + runtime.running = 1; + runtime.initiated = switch_time_now(); + runtime.mono_initiated = switch_mono_micro_time_now(); + + switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL); + + switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD); + + switch_uuid_get(&uuid); + switch_uuid_format(runtime.uuid_str, &uuid); + switch_core_set_variable("core_uuid", runtime.uuid_str); + + + return SWITCH_STATUS_SUCCESS; +} + + +#ifndef WIN32 +static void handle_SIGCHLD(int sig) +{ + int status = 0; + + wait(&status); + return; +} +#endif + +#ifdef TRAP_BUS +static void handle_SIGBUS(int sig) +{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Sig BUS!\n"); + return; +} +#endif + +static void handle_SIGHUP(int sig) +{ + if (sig) { + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP"); + switch_event_fire(&event); + } + } + return; +} + + +SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number) +{ + uint32_t *p; + + if ((p = switch_core_hash_find(runtime.ptimes, name))) { + return *p; + } + + return 20; +} + +static uint32_t d_30 = 30; + +static void switch_load_core_config(const char *file) +{ + switch_xml_t xml = NULL, cfg = NULL; + + switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); + switch_core_hash_insert(runtime.ptimes, "G723", &d_30); + + if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) { + switch_xml_t settings, param; + + if ((settings = switch_xml_child(cfg, "default-ptimes"))) { + for (param = switch_xml_child(settings, "codec"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "ptime"); + + if (!zstr(var) && !zstr(val)) { + uint32_t *p; + uint32_t v = switch_atoul(val); + + if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var); + continue; + } + + if (v == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var); + continue; + } + + p = switch_core_alloc(runtime.memory_pool, sizeof(*p)); + *p = v; + switch_core_hash_insert(runtime.ptimes, var, p); + } + + } + } + + if ((settings = switch_xml_child(cfg, "settings"))) { + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "value"); + + if (!strcasecmp(var, "loglevel")) { + int level; + if (*val > 47 && *val < 58) { + level = atoi(val); + } else { + level = switch_log_str2level(val); + } + + if (level != SWITCH_LOG_INVALID) { + switch_core_session_ctl(SCSC_LOGLEVEL, &level); + } +#ifdef HAVE_SETRLIMIT + } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) { + struct rlimit rlp; + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = RLIM_INFINITY; + rlp.rlim_max = RLIM_INFINITY; + setrlimit(RLIMIT_CORE, &rlp); +#endif + } else if (!strcasecmp(var, "debug-level")) { + int tmp = atoi(val); + if (tmp > -1 && tmp < 11) { + switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp); + } + } else if (!strcasecmp(var, "max-db-handles")) { + long tmp = atol(val); + + if (tmp > 4 && tmp < 5001) { + runtime.max_db_handles = (uint32_t) tmp; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n"); + } + } else if (!strcasecmp(var, "db-handle-timeout")) { + long tmp = atol(val); + + if (tmp > 0 && tmp < 5001) { + runtime.db_handle_timeout = (uint32_t) tmp * 1000000; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n"); + } + + } else if (!strcasecmp(var, "multiple-registrations")) { + runtime.multiple_registrations = switch_true(val); + } else if (!strcasecmp(var, "auto-create-schemas")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); + } else { + switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS); + } + } else if (!strcasecmp(var, "session-thread-pool")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); + } else { + switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL); + } + } else if (!strcasecmp(var, "auto-clear-sql")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_CLEAR_SQL); + } else { + switch_clear_flag((&runtime), SCF_CLEAR_SQL); + } + } else if (!strcasecmp(var, "api-expansion")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_API_EXPANSION); + } else { + switch_clear_flag((&runtime), SCF_API_EXPANSION); + } + } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) { + switch_set_flag((&runtime), SCF_EARLY_HANGUP); + } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) { + runtime.colorize_console = SWITCH_TRUE; + } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) { + runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) { + runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) { + runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) { + runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) { + runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "mailer-app-args") && val) { + runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) { + switch_core_sessions_per_second(atoi(val)); + } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) { + int tmp = atoi(val); + if (tmp > 0) { + switch_core_max_dtmf_duration((uint32_t) tmp); + } + } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) { + int tmp = atoi(val); + if (tmp > 0) { + switch_core_min_dtmf_duration((uint32_t) tmp); + } + } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) { + int tmp = atoi(val); + if (tmp > 0) { + switch_core_default_dtmf_duration((uint32_t) tmp); + } + } else if (!strcasecmp(var, "enable-use-system-time")) { + switch_time_set_use_system_time(switch_true(val)); + } else if (!strcasecmp(var, "enable-monotonic-timing")) { + switch_time_set_monotonic(switch_true(val)); + } else if (!strcasecmp(var, "enable-softtimer-timerfd")) { + switch_time_set_timerfd(switch_true(val)); + } else if (!strcasecmp(var, "enable-clock-nanosleep")) { + switch_time_set_nanosleep(switch_true(val)); + } else if (!strcasecmp(var, "enable-cond-yield")) { + switch_time_set_cond_yield(switch_true(val)); + } else if (!strcasecmp(var, "enable-timer-matrix")) { + switch_time_set_matrix(switch_true(val)); + } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) { + switch_core_session_limit(atoi(val)); + } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) { + int v = switch_true(val); + if (v) { + switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); + } else { + switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); + } + } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) { +#ifdef WIN32 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n"); +#else + int v = switch_true(val); + if (v) { + switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } else { + switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } +#endif + } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) { + switch_core_min_idle_cpu(atof(val)); + } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) { + runtime.tipping_point = atoi(val); + } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) { + int tmp = atoi(val); + + + if (tmp > runtime.cpu_count / 2) { + tmp = runtime.cpu_count / 2; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n", + runtime.cpu_count / 2); + } + + if (tmp < 1) { + tmp = 1; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n"); + } + + switch_event_launch_dispatch_threads(tmp); + + } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) { + runtime.microseconds_per_tick = 1000; + } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) { + if (!strcasecmp(val, "disabled")) { + runtime.timer_affinity = -1; + } else { + runtime.timer_affinity = atoi(val); + } + } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) { + 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() || switch_pgsql_available()) { + runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n"); + } + } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) { + switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ); + } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) { + if (!strcasecmp(val, "MSSQL")) { + runtime.odbc_dbtype = DBTYPE_MSSQL; + } else { + runtime.odbc_dbtype = DBTYPE_DEFAULT; + } +#ifdef ENABLE_ZRTP + } else if (!strcasecmp(var, "rtp-enable-zrtp")) { + switch_core_set_variable("zrtp_enabled", val); +#endif + } else if (!strcasecmp(var, "switchname") && !zstr(val)) { + runtime.switchname = switch_core_strdup(runtime.memory_pool, val); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname); + } + } + } + + if ((settings = switch_xml_child(cfg, "variables"))) { + for (param = switch_xml_child(settings, "variable"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "value"); + if (var && val) { + switch_core_set_variable(var, val); + } + } + } + + switch_xml_free(xml); + } + + +} + +SWITCH_DECLARE(const char *) switch_core_banner(void) +{ + + return ("\n" + ".=============================================================.\n" + "| _____ ______ _____ _____ ____ _ _ |\n" + "| | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | |\n" + "| | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | |\n" + "| | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | |\n" + "| |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| |\n" + "| |\n" + ".=============================================================." + "\n" + + "| Anthony Minessale II, Michael Jerris, Brian West, Others |\n" + "| FreeSWITCH (http://www.freeswitch.org) |\n" + "| Paypal Donations Appreciated: paypal@freeswitch.org |\n" + "| Brought to you by ClueCon http://www.cluecon.com/ |\n" + ".=============================================================.\n" + "\n"); +} + + +SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err) +{ + switch_event_t *event; + char *cmd; + int x = 0; + const char *use = NULL; +#include "cc.h" + + + if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_GENERR; + } + + if (runtime.runlevel > 1) { + /* one per customer */ + return SWITCH_STATUS_SUCCESS; + } + + runtime.runlevel++; + + switch_core_set_signal_handlers(); + switch_load_network_lists(SWITCH_FALSE); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n"); + if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { + *err = "Cannot load modules"; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err); + return SWITCH_STATUS_GENERR; + } + + switch_load_network_lists(SWITCH_FALSE); + + switch_load_core_config("post_load_switch.conf"); + + switch_core_set_signal_handlers(); + + if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); + switch_event_fire(&event); + } + + switch_core_screen_size(&x, NULL); + + use = (x > 100) ? cc : cc_s; + +#ifdef WIN32 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use); +#else + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", + SWITCH_SEQ_DEFAULT_COLOR, + SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE, + switch_core_banner(), + use, SWITCH_SEQ_DEFAULT_COLOR); + +#endif + + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, + "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n", + SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN, + switch_core_session_limit(0), + switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); + + + if (x < 160) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n"); + } + + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); + + if ((cmd = switch_core_get_variable_dup("api_on_startup"))) { + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + switch_console_execute(cmd, 0, &stream); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data); + free(stream.data); + free(cmd); + } + + return SWITCH_STATUS_SUCCESS; + +} + +SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration) +{ + switch_time_t temp = total_ms / 1000; + memset(duration, 0, sizeof(*duration)); + duration->mms = (uint32_t) (total_ms % 1000); + duration->ms = (uint32_t) (temp % 1000); + temp = temp / 1000; + duration->sec = (uint32_t) (temp % 60); + temp = temp / 60; + duration->min = (uint32_t) (temp % 60); + temp = temp / 60; + duration->hr = (uint32_t) (temp % 24); + temp = temp / 24; + duration->day = (uint32_t) (temp % 365); + duration->yr = (uint32_t) (temp / 365); +} + +SWITCH_DECLARE(switch_time_t) switch_core_uptime(void) +{ + return switch_mono_micro_time_now() - runtime.mono_initiated; +} + + +#ifdef _MSC_VER +static void win_shutdown(void) +{ + + HANDLE shutdown_event; + char path[512]; + /* for windows we need the event to signal for shutting down a background FreeSWITCH */ + snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); + + /* open the event so we can signal it */ + shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path); + + if (shutdown_event) { + /* signal the event to shutdown */ + SetEvent(shutdown_event); + /* cleanup */ + CloseHandle(shutdown_event); + } +} +#endif + +SWITCH_DECLARE(void) switch_core_set_signal_handlers(void) +{ + /* set signal handlers */ + signal(SIGINT, SIG_IGN); +#ifndef WIN32 + if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)) { + signal(SIGCHLD, SIG_DFL); + } else { + signal(SIGCHLD, handle_SIGCHLD); + } +#endif +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif +#ifdef SIGQUIT + signal(SIGQUIT, SIG_IGN); +#endif +#ifdef SIGPOLL + signal(SIGPOLL, SIG_IGN); +#endif +#ifdef SIGIO + signal(SIGIO, SIG_IGN); +#endif +#ifdef TRAP_BUS + signal(SIGBUS, handle_SIGBUS); +#endif +#ifdef SIGUSR1 + signal(SIGUSR1, handle_SIGHUP); +#endif + signal(SIGHUP, handle_SIGHUP); +} + +SWITCH_DECLARE(uint32_t) switch_core_debug_level(void) +{ + return runtime.debug_level; +} + + +SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val) +{ + int *intval = (int *) val; + int oldintval = 0, newintval = 0; + + if (intval) { + oldintval = *intval; + } + + if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) { + return -1; + } + + switch (cmd) { + case SCSC_RECOVER: + { + char *arg = (char *) val; + char *tech = NULL, *prof = NULL; + int r, flush = 0; + + if (!zstr(arg)) { + tech = strdup(arg); + + if ((prof = strchr(tech, ':'))) { + *prof++ = '\0'; + } + + if (!strcasecmp(tech, "flush")) { + flush++; + + if (prof) { + tech = prof; + if ((prof = strchr(tech, ':'))) { + *prof++ = '\0'; + } + } + } + + } + + if (flush) { + switch_core_recovery_flush(tech, prof); + r = -1; + } else { + r = switch_core_recovery_recover(tech, prof); + } + + switch_safe_free(tech); + return r; + + } + break; + case SCSC_DEBUG_SQL: + { + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + switch_clear_flag((&runtime), SCF_DEBUG_SQL); + newintval = 0; + } else { + switch_set_flag((&runtime), SCF_DEBUG_SQL); + newintval = 1; + } + } + break; + case SCSC_VERBOSE_EVENTS: + if (intval) { + if (oldintval > -1) { + if (oldintval) { + switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); + } else { + switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); + } + } + newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS); + } + break; + case SCSC_API_EXPANSION: + if (intval) { + if (oldintval > -1) { + if (oldintval) { + switch_set_flag((&runtime), SCF_API_EXPANSION); + } else { + switch_clear_flag((&runtime), SCF_API_EXPANSION); + } + } + newintval = switch_test_flag((&runtime), SCF_API_EXPANSION); + } + break; + case SCSC_THREADED_SYSTEM_EXEC: + if (intval) { + if (oldintval > -1) { + if (oldintval) { + switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } else { + switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } + } + newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } + break; + case SCSC_CALIBRATE_CLOCK: + switch_time_calibrate_clock(); + break; + case SCSC_FLUSH_DB_HANDLES: + switch_cache_db_flush_handles(); + break; + case SCSC_SEND_SIGHUP: + handle_SIGHUP(1); + break; + case SCSC_SYNC_CLOCK: + switch_time_sync(); + newintval = 0; + break; + case SCSC_SYNC_CLOCK_WHEN_IDLE: + newintval = switch_core_session_sync_clock(); + break; + case SCSC_SQL: + if (oldintval) { + switch_core_sqldb_resume(); + } else { + switch_core_sqldb_pause(); + } + break; + case SCSC_PAUSE_ALL: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); + } + break; + case SCSC_PAUSE_INBOUND: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + } + break; + case SCSC_PAUSE_OUTBOUND: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + } + break; + case SCSC_HUPALL: + switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST); + break; + case SCSC_CANCEL_SHUTDOWN: + switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED); + break; + case SCSC_SAVE_HISTORY: + switch_console_save_history(); + break; + case SCSC_CRASH: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n"); + switch_console_save_history(); + abort(); + break; + case SCSC_SHUTDOWN_NOW: + switch_console_save_history(); + exit(0); + break; + case SCSC_SHUTDOWN_ELEGANT: + case SCSC_SHUTDOWN_ASAP: + { + int x = 19; + uint32_t count; + + switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED); + if (cmd == SCSC_SHUTDOWN_ASAP) { + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + } + + while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) { + switch_yield(500000); + if (++x == 20) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Shutdown in progress, %u session(s) remain.\nShutting down %s\n", + count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls."); + x = 0; + } + } + + if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) { + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); +#ifdef _MSC_VER + win_shutdown(); +#endif + + if (oldintval) { + switch_set_flag((&runtime), SCF_RESTART); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); +#ifdef _MSC_VER + fclose(stdin); +#endif + } + runtime.running = 0; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n"); + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); + } + } + break; + case SCSC_PAUSE_CHECK: + newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS); + break; + case SCSC_PAUSE_INBOUND_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + break; + case SCSC_PAUSE_OUTBOUND_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + break; + case SCSC_READY_CHECK: + newintval = switch_core_ready(); + break; + case SCSC_SHUTDOWN_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED); + break; + case SCSC_SHUTDOWN: + +#ifdef _MSC_VER + win_shutdown(); +#endif + + if (oldintval) { + switch_set_flag((&runtime), SCF_RESTART); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); +#ifdef _MSC_VER + fclose(stdin); +#endif + } + runtime.running = 0; + break; + case SCSC_CHECK_RUNNING: + newintval = runtime.running; + break; + case SCSC_LOGLEVEL: + if (oldintval > -1) { + runtime.hard_log_level = oldintval; + } + + if (runtime.hard_log_level > SWITCH_LOG_DEBUG) { + runtime.hard_log_level = SWITCH_LOG_DEBUG; + } + newintval = runtime.hard_log_level; + break; + case SCSC_DEBUG_LEVEL: + if (oldintval > -1) { + if (oldintval > 10) + newintval = 10; + runtime.debug_level = oldintval; + } + newintval = runtime.debug_level; + break; + case SCSC_MIN_IDLE_CPU: + { + double *dval = (double *) val; + if (dval) { + *dval = switch_core_min_idle_cpu(*dval); + } + intval = NULL; + } + break; + case SCSC_MAX_SESSIONS: + newintval = switch_core_session_limit(oldintval); + break; + case SCSC_LAST_SPS: + newintval = runtime.sps_last; + break; + case SCSC_MAX_DTMF_DURATION: + newintval = switch_core_max_dtmf_duration(oldintval); + break; + case SCSC_MIN_DTMF_DURATION: + newintval = switch_core_min_dtmf_duration(oldintval); + break; + case SCSC_DEFAULT_DTMF_DURATION: + newintval = switch_core_default_dtmf_duration(oldintval); + break; + case SCSC_SPS: + switch_mutex_lock(runtime.throttle_mutex); + if (oldintval > 0) { + runtime.sps_total = oldintval; + } + newintval = runtime.sps_total; + switch_mutex_unlock(runtime.throttle_mutex); + break; + + case SCSC_RECLAIM: + switch_core_memory_reclaim_all(); + newintval = 0; + break; + } + + if (intval) { + *intval = newintval; + } + + + return 0; +} + +SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void) +{ + return runtime.flags; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) +{ + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down"); + switch_event_fire(&event); + } + + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + switch_set_flag((&runtime), SCF_SHUTTING_DOWN); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n"); + switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n"); + + switch_loadable_module_shutdown(); + + switch_ssl_destroy_ssl_locks(); + + if (switch_test_flag((&runtime), SCF_USE_SQL)) { + switch_core_sqldb_stop(); + } + switch_scheduler_task_thread_stop(); + + switch_rtp_shutdown(); + + if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { + switch_nat_shutdown(); + } + switch_xml_destroy(); + switch_core_session_uninit(); + switch_console_shutdown(); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n"); + switch_event_shutdown(); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n"); + switch_log_shutdown(); + + switch_core_unset_variables(); + switch_core_memory_stop(); + + if (runtime.console && runtime.console != stdout && runtime.console != stderr) { + fclose(runtime.console); + runtime.console = NULL; + } + + switch_safe_free(SWITCH_GLOBAL_dirs.base_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.log_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.db_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.script_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.run_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir); + + switch_event_destroy(&runtime.global_vars); + switch_core_hash_destroy(&runtime.ptimes); + switch_core_hash_destroy(&runtime.mime_types); + + if (IP_LIST.hash) { + switch_core_hash_destroy(&IP_LIST.hash); + } + + if (IP_LIST.pool) { + switch_core_destroy_memory_pool(&IP_LIST.pool); + } + + if (runtime.memory_pool) { + apr_pool_destroy(runtime.memory_pool); + apr_terminate(); + } + + return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen) +{ + const switch_management_interface_t *ptr; + switch_status_t status = SWITCH_STATUS_FALSE; + + if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) { + status = ptr->management_function(relative_oid, action, data, datalen); + } + + return status; +} + +SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void) +{ + switch_core_memory_reclaim_logger(); + switch_core_memory_reclaim_events(); + switch_core_memory_reclaim(); +} + + +struct system_thread_handle { + const char *cmd; + switch_thread_cond_t *cond; + switch_mutex_t *mutex; + switch_memory_pool_t *pool; + int ret; + int *fds; +}; + +static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj) +{ + struct system_thread_handle *sth = (struct system_thread_handle *) obj; + +#if 0 // if we are a luser we can never turn this back down, didn't we already set the stack size? +#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) + struct rlimit rlim; + + rlim.rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE; + rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; + if (setrlimit(RLIMIT_STACK, &rlim) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); + } +#endif +#endif + + if (sth->fds) { + dup2(sth->fds[1], STDOUT_FILENO); + } + + sth->ret = system(sth->cmd); + +#if 0 +#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) + rlim.rlim_cur = SWITCH_THREAD_STACKSIZE; + rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; + if (setrlimit(RLIMIT_STACK, &rlim) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); + } +#endif +#endif + + switch_mutex_lock(sth->mutex); + switch_thread_cond_signal(sth->cond); + switch_mutex_unlock(sth->mutex); + + switch_core_destroy_memory_pool(&sth->pool); + + return NULL; +} + + +static int switch_system_thread(const char *cmd, switch_bool_t wait) +{ + switch_thread_t *thread; + switch_threadattr_t *thd_attr; + int ret = 0; + struct system_thread_handle *sth; + switch_memory_pool_t *pool; + + if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); + return 1; + } + + if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) { + switch_core_destroy_memory_pool(&pool); + return 1; + } + + sth->pool = pool; + sth->cmd = switch_core_strdup(pool, cmd); + + switch_thread_cond_create(&sth->cond, sth->pool); + switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool); + switch_mutex_lock(sth->mutex); + + switch_threadattr_create(&thd_attr, sth->pool); + switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE); + switch_threadattr_detach_set(thd_attr, 1); + switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool); + + if (wait) { + switch_thread_cond_wait(sth->cond, sth->mutex); + ret = sth->ret; + } + switch_mutex_unlock(sth->mutex); + + return ret; +} + +SWITCH_DECLARE(int) switch_max_file_desc(void) +{ + int max = 0; + +#ifndef WIN32 +#if defined(HAVE_GETDTABLESIZE) + max = getdtablesize(); +#else + max = sysconf(_SC_OPEN_MAX); +#endif +#endif + + return max; + +} + +SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl) +{ + int open_max = switch_max_file_desc(); + int i, j; + + for (i = 3; i < open_max; i++) { + if (keep) { + for (j = 0; j < keep_ttl; j++) { + if (i == keep[j]) { + goto skip; + } + } + } + + close(i); + + skip: + + continue; + + } +} + + +#ifdef WIN32 +static int switch_system_fork(const char *cmd, switch_bool_t wait) +{ + return switch_system_thread(cmd, wait); +} + +SWITCH_DECLARE(pid_t) switch_fork(void) +{ + return -1; +} + + +#else + +SWITCH_DECLARE(pid_t) switch_fork(void) +{ + int i = fork(); + + if (!i) { + set_low_priority(); + } + + return i; +} + + + +static int switch_system_fork(const char *cmd, switch_bool_t wait) +{ + int pid; + char *dcmd = strdup(cmd); + + switch_core_set_signal_handlers(); + + pid = switch_fork(); + + if (pid) { + if (wait) { + waitpid(pid, NULL, 0); + } + free(dcmd); + } else { + switch_close_extra_files(NULL, 0); + + if (system(dcmd) == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd); + } + free(dcmd); + exit(0); + } + + return 0; +} +#endif + + + +SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait) +{ + int (*sys_p)(const char *cmd, switch_bool_t wait); + + sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork; + + return sys_p(cmd, wait); + +} + + + +SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream) +{ +#ifdef WIN32 + return switch_system(cmd, SWITCH_TRUE); +#else + int fds[2], pid = 0; + + if (pipe(fds)) { + goto end; + } else { /* good to go */ + pid = switch_fork(); + + if (pid < 0) { /* ok maybe not */ + close(fds[0]); + close(fds[1]); + goto end; + } else if (pid) { /* parent */ + char buf[1024] = ""; + int bytes; + close(fds[1]); + while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) { + stream->raw_write_function(stream, (unsigned char *)buf, bytes); + } + close(fds[0]); + waitpid(pid, NULL, 0); + } else { /* child */ + switch_close_extra_files(fds, 2); + close(fds[0]); + dup2(fds[1], STDOUT_FILENO); + switch_system(cmd, SWITCH_TRUE); + close(fds[1]); + exit(0); + } + } + + end: + + return 0; + +#endif + +} + +SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max) +{ +#ifdef HAVE_SETRLIMIT + struct rlimit rlp; + + memset(&rlp, 0, sizeof(rlp)); + getrlimit(RLIMIT_STACK, &rlp); + + *cur = rlp.rlim_cur; + *max = rlp.rlim_max; + + return SWITCH_STATUS_SUCCESS; + +#else + + return SWITCH_STATUS_FALSE; + +#endif + + + +} + + +SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream) +{ +#ifdef WIN32 + stream->write_function(stream, "Capturing output not supported.\n"); + return switch_system(cmd, SWITCH_TRUE); +#else + return switch_stream_system_fork(cmd, stream); +#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 3ea579ccc32a56d60fd2989594d094c22d516c48 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Tue, 20 Nov 2012 14:09:02 +0000 Subject: [PATCH 452/512] FS-4850: Make cache db get_handle call not return handles which are already in use. --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b776a14a87..5df382efab 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -144,7 +144,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user switch_mutex_lock(sql_manager.dbh_mutex); for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { - if (dbh_ptr->thread_hash == thread_hash && dbh_ptr->hash == hash && + if (dbh_ptr->thread_hash == thread_hash && dbh_ptr->hash == hash && !dbh_ptr->use_count && !switch_test_flag(dbh_ptr, CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { r = dbh_ptr; } From bfae89267e68ec94551b5c892fe32459219f61e0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 20 Nov 2012 10:13:05 -0600 Subject: [PATCH 453/512] revert --- src/switch_core.c | 5665 ++++++++++++++++++++++----------------------- 1 file changed, 2831 insertions(+), 2834 deletions(-) diff --git a/src/switch_core.c b/src/switch_core.c index 9bbb11956d..4682d3c002 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1,2834 +1,2831 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * 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 Jerris - * Paul D. Tinsley - * Marcel Barbulescu - * Joseph Sullivan - * - * - * switch_core.c -- Main Core Library - * - */ - - - -#include -#include -#include -#include -#include -#include "private/switch_core_pvt.h" -#include -#ifndef WIN32 -#include -#ifdef HAVE_SETRLIMIT -#include -#endif -#endif -#include - - -SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 }; - -/* The main runtime obj we keep this hidden for ourselves */ -struct switch_runtime runtime = { 0 }; -static void switch_load_core_config(const char *file); - -static void send_heartbeat(void) -{ - switch_event_t *event; - switch_core_time_duration_t duration; - - switch_core_measure_time(switch_core_uptime(), &duration); - - if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time", - "%u year%s, " - "%u day%s, " - "%u hour%s, " - "%u minute%s, " - "%u second%s, " - "%u millisecond%s, " - "%u microsecond%s", - duration.yr, duration.yr == 1 ? "" : "s", - duration.day, duration.day == 1 ? "" : "s", - duration.hr, duration.hr == 1 ? "" : "s", - duration.min, duration.min == 1 ? "" : "s", - duration.sec, duration.sec == 1 ? "" : "s", - duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s"); - - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", SWITCH_VERSION_FULL); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT, switch_core_uptime() / 1000); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count()); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu()); - switch_event_fire(&event); - } -} - -static char main_ip4[256] = ""; -static char main_ip6[256] = ""; - -static void check_ip(void) -{ - char guess_ip4[256] = ""; - char guess_ip6[256] = ""; - char old_ip4[256] = ""; - char old_ip6[256] = ""; - int ok4 = 1, ok6 = 1; - int mask = 0; - - gethostname(runtime.hostname, sizeof(runtime.hostname)); - switch_core_set_variable("hostname", runtime.hostname); - - switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET); - switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6); - - if (!*main_ip4) { - switch_set_string(main_ip4, guess_ip4); - } else { - if (!(ok4 = !strcmp(main_ip4, guess_ip4))) { - struct in_addr in; - - in.s_addr = mask; - switch_set_string(old_ip4, main_ip4); - switch_set_string(main_ip4, guess_ip4); - switch_core_set_variable("local_ip_v4", guess_ip4); - switch_core_set_variable("local_mask_v4", inet_ntoa(in)); - } - } - - if (!*main_ip6) { - switch_set_string(main_ip6, guess_ip6); - } else { - if (!(ok6 = !strcmp(main_ip6, guess_ip6))) { - switch_set_string(old_ip6, main_ip6); - switch_set_string(main_ip6, guess_ip6); - switch_core_set_variable("local_ip_v6", guess_ip6); - } - } - - if (!ok4 || !ok6) { - switch_event_t *event; - - if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change"); - if (!ok4) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4); - } - if (!ok6) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6); - } - switch_event_fire(&event); - } - } -} - -SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback) -{ - send_heartbeat(); - - /* reschedule this task */ - task->runtime = switch_epoch_time_now(NULL) + 20; -} - - -SWITCH_STANDARD_SCHED_FUNC(check_ip_callback) -{ - check_ip(); - - /* reschedule this task */ - task->runtime = switch_epoch_time_now(NULL) + 60; -} - - -SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console) -{ - if ((runtime.console = fopen(console, "a")) == 0) { - fprintf(stderr, "Cannot open output file %s.\n", console); - return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(FILE *) switch_core_get_console(void) -{ - return runtime.console; -} - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) -{ - -#ifdef WIN32 - CONSOLE_SCREEN_BUFFER_INFO csbi; - int ret; - - if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) { - if (x) *x = csbi.dwSize.X; - if (y) *y = csbi.dwSize.Y; - } - -#elif defined(TIOCGWINSZ) - struct winsize w; - ioctl(0, TIOCGWINSZ, &w); - - if (x) *x = w.ws_col; - if (y) *y = w.ws_row; -#else - if (x) *x = 80; - if (y) *y = 24; -#endif - -} - -SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel) -{ - FILE *handle = stdout; - - switch (channel) { - case SWITCH_CHANNEL_ID_LOG: - case SWITCH_CHANNEL_ID_LOG_CLEAN: - handle = runtime.console; - break; - default: - handle = runtime.console; - break; - } - - return handle; -} - - -SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler) -{ - int index, tmp_index = 0; - const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 }; - - switch_mutex_lock(runtime.global_mutex); - - for (index = 0; index < runtime.state_handler_index; index++) { - const switch_state_handler_table_t *cur = runtime.state_handlers[index]; - runtime.state_handlers[index] = NULL; - if (cur == state_handler) { - continue; - } - tmp[tmp_index++] = cur; - } - - runtime.state_handler_index = 0; - - for (index = 0; index < tmp_index; index++) { - runtime.state_handlers[runtime.state_handler_index++] = tmp[index]; - } - switch_mutex_unlock(runtime.global_mutex); -} - - -SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler) -{ - int index; - - switch_mutex_lock(runtime.global_mutex); - index = runtime.state_handler_index++; - - if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS) { - index = -1; - } else { - runtime.state_handlers[index] = state_handler; - } - - switch_mutex_unlock(runtime.global_mutex); - return index; -} - -SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index) -{ - - if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) { - return NULL; - } - - return runtime.state_handlers[index]; -} - -SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream) -{ - switch_event_header_t *hi; - - switch_mutex_lock(runtime.global_mutex); - for (hi = runtime.global_vars->headers; hi; hi = hi->next) { - stream->write_function(stream, "%s=%s\n", hi->name, hi->value); - } - switch_mutex_unlock(runtime.global_mutex); -} - -SWITCH_DECLARE(const char *) switch_core_get_hostname(void) -{ - return runtime.hostname; -} - -SWITCH_DECLARE(const char *) switch_core_get_switchname(void) -{ - if (!zstr(runtime.switchname)) return runtime.switchname; - return runtime.hostname; -} - - -SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) -{ - char *val; - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - val = (char *) switch_event_get_header(runtime.global_vars, varname); - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - return val; -} - -SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname) -{ - char *val = NULL, *v; - - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { - val = strdup(v); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - - return val; -} - -SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool) -{ - char *val = NULL, *v; - - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { - val = switch_core_strdup(pool, v); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - - return val; -} - -static void switch_core_unset_variables(void) -{ - switch_thread_rwlock_wrlock(runtime.global_var_rwlock); - switch_event_destroy(&runtime.global_vars); - switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); - switch_thread_rwlock_unlock(runtime.global_var_rwlock); -} - -SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value) -{ - char *val; - - if (varname) { - switch_thread_rwlock_wrlock(runtime.global_var_rwlock); - val = (char *) switch_event_get_header(runtime.global_vars, varname); - if (val) { - switch_event_del_header(runtime.global_vars, varname); - } - if (value) { - char *v = strdup(value); - switch_string_var_check(v, SWITCH_TRUE); - switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); - } else { - switch_event_del_header(runtime.global_vars, varname); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - } -} - -SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2) -{ - char *val; - - if (varname) { - switch_thread_rwlock_wrlock(runtime.global_var_rwlock); - val = (char *) switch_event_get_header(runtime.global_vars, varname); - - if (val) { - if (!val2 || strcmp(val, val2) != 0) { - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - return SWITCH_FALSE; - } - switch_event_del_header(runtime.global_vars, varname); - } else if (!zstr(val2)) { - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - return SWITCH_FALSE; - } - - if (value) { - char *v = strdup(value); - switch_string_var_check(v, SWITCH_TRUE); - switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); - } else { - switch_event_del_header(runtime.global_vars, varname); - } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); - } - return SWITCH_TRUE; -} - -SWITCH_DECLARE(char *) switch_core_get_uuid(void) -{ - return runtime.uuid_str; -} - - -static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj) -{ - switch_core_session_t *session = obj; - switch_channel_t *channel; - switch_frame_t *read_frame; - -// switch_assert(thread != NULL); -// switch_assert(session != NULL); - - if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { - return NULL; - } - - switch_mutex_lock(session->frame_read_mutex); - - channel = switch_core_session_get_channel(session); - - switch_channel_set_flag(channel, CF_SERVICE); - while (switch_channel_test_flag(channel, CF_SERVICE)) { - - if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) { - switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { - case SWITCH_STATUS_SUCCESS: - case SWITCH_STATUS_TIMEOUT: - case SWITCH_STATUS_BREAK: - break; - default: - switch_channel_clear_flag(channel, CF_SERVICE); - break; - } - } - - if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) { - switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { - case SWITCH_STATUS_SUCCESS: - case SWITCH_STATUS_TIMEOUT: - case SWITCH_STATUS_BREAK: - break; - default: - switch_channel_clear_flag(channel, CF_SERVICE); - break; - } - } - } - - switch_mutex_unlock(session->frame_read_mutex); - - switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); - switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); - - switch_core_session_rwunlock(session); - - return NULL; -} - -/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */ -SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session) -{ - switch_channel_t *channel; - switch_assert(session); - - channel = switch_core_session_get_channel(session); - switch_assert(channel); - - switch_channel_clear_flag(channel, CF_SERVICE); - switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); - switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); - - switch_core_session_kill_channel(session, SWITCH_SIG_BREAK); - -} - -SWITCH_DECLARE(void) switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video) -{ - switch_channel_t *channel; - switch_assert(session); - - channel = switch_core_session_get_channel(session); - switch_assert(channel); - - if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO); - if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO); - - switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session); -} - -/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and - a void object and trust that that the function will be run in a thread with arg This lets - you request and activate a thread without giving up any knowledge about what is in the thread - neither the core nor the calling module know anything about each other. - - This thread is expected to never exit until the application exits so the func is responsible - to make sure that is the case. - - The typical use for this is so switch_loadable_module.c can start up a thread for each module - passing the table of module methods as a session obj into the core without actually allowing - the core to have any clue and keeping switch_loadable_module.c from needing any thread code. - -*/ - -SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool) -{ - switch_thread_t *thread = NULL; - switch_threadattr_t *thd_attr = NULL; - switch_core_thread_session_t *ts; - int mypool; - - mypool = pool ? 0 : 1; - - if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n"); - return NULL; - } - - switch_threadattr_create(&thd_attr, pool); - - if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n"); - } else { - if (mypool) { - ts->pool = pool; - } - ts->objs[0] = obj; - ts->objs[1] = thread; - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); - switch_thread_create(&thread, thd_attr, func, ts, pool); - } - - return thread; -} - -SWITCH_DECLARE(void) switch_core_set_globals(void) -{ -#define BUFSIZE 1024 -#ifdef WIN32 - char lpPathBuffer[BUFSIZE]; - DWORD dwBufSize = BUFSIZE; - char base_dir[1024]; - char *lastbacklash; - char *tmp; - - GetModuleFileName(NULL, base_dir, BUFSIZE); - lastbacklash = strrchr(base_dir, '\\'); - base_dir[(lastbacklash - base_dir)] = '\0'; - /* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */ - SetCurrentDirectory(base_dir); - tmp = switch_string_replace(base_dir, "\\", "/"); - strcpy(base_dir, tmp); - free(tmp); - -#else - char base_dir[1024] = SWITCH_PREFIX_DIR; -#endif - - if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) { - switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir); - } - - if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_MOD_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_LIB_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_CONF_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_LOG_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_RUN_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_RECORDINGS_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_SOUNDS_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_STORAGE_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_DB_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_SCRIPT_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_HTDOCS_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_GRAMMAR_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR); -#endif - } - - if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) { -#ifdef SWITCH_TEMP_DIR - switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR); -#else -#ifdef WIN32 - GetTempPath(dwBufSize, lpPathBuffer); - lpPathBuffer[strlen(lpPathBuffer)-1] = 0; - tmp = switch_string_replace(lpPathBuffer, "\\", "/"); - strcpy(lpPathBuffer, tmp); - free(tmp); - switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer); -#else - switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp"); -#endif -#endif - } - - switch_assert(SWITCH_GLOBAL_dirs.base_dir); - switch_assert(SWITCH_GLOBAL_dirs.mod_dir); - switch_assert(SWITCH_GLOBAL_dirs.lib_dir); - switch_assert(SWITCH_GLOBAL_dirs.conf_dir); - switch_assert(SWITCH_GLOBAL_dirs.log_dir); - switch_assert(SWITCH_GLOBAL_dirs.run_dir); - switch_assert(SWITCH_GLOBAL_dirs.db_dir); - switch_assert(SWITCH_GLOBAL_dirs.script_dir); - switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir); - switch_assert(SWITCH_GLOBAL_dirs.grammar_dir); - switch_assert(SWITCH_GLOBAL_dirs.recordings_dir); - switch_assert(SWITCH_GLOBAL_dirs.sounds_dir); - switch_assert(SWITCH_GLOBAL_dirs.temp_dir); -} - - -SWITCH_DECLARE(int32_t) set_low_priority(void) -{ - - -#ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); -#else -#ifdef USE_SCHED_SETSCHEDULER - /* - * Try to use a normal scheduler - */ - struct sched_param sched = { 0 }; - sched.sched_priority = 0; - if (sched_setscheduler(0, SCHED_OTHER, &sched)) { - return -1; - } -#endif - -#ifdef HAVE_SETPRIORITY - /* - * setpriority() works on FreeBSD (6.2), nice() doesn't - */ - if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#else - if (nice(19) != 19) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#endif -#endif - - return 0; -} - -SWITCH_DECLARE(int32_t) set_realtime_priority(void) -{ -#ifdef WIN32 - SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); -#else -#ifdef USE_SCHED_SETSCHEDULER - /* - * Try to use a round-robin scheduler - * with a fallback if that does not work - */ - struct sched_param sched = { 0 }; - sched.sched_priority = SWITCH_PRI_LOW; - if (sched_setscheduler(0, SCHED_FIFO, &sched)) { - sched.sched_priority = 0; - if (sched_setscheduler(0, SCHED_OTHER, &sched)) { - return -1; - } - } -#endif - - - -#ifdef HAVE_SETPRIORITY - /* - * setpriority() works on FreeBSD (6.2), nice() doesn't - */ - if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#else - if (nice(-10) != -10) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); - return -1; - } -#endif -#endif - return 0; -} - -SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void) -{ - return runtime.cpu_count; -} - -SWITCH_DECLARE(int32_t) set_normal_priority(void) -{ - return 0; -} - -SWITCH_DECLARE(int32_t) set_auto_priority(void) -{ -#ifndef WIN32 - runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); -#else - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - runtime.cpu_count = sysinfo.dwNumberOfProcessors; -#endif - - if (!runtime.cpu_count) runtime.cpu_count = 1; - - /* If we have more than 1 cpu, we should use realtime priority so we can have priority threads */ - if (runtime.cpu_count > 1) { - return set_realtime_priority(); - } - - return 0; -} - -SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group) -{ -#ifndef WIN32 - uid_t runas_uid = 0; - gid_t runas_gid = 0; - struct passwd *runas_pw = NULL; - - if (user) { - /* - * Lookup user information in the system's db - */ - runas_pw = getpwnam(user); - if (!runas_pw) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user); - return -1; - } - runas_uid = runas_pw->pw_uid; - } - - if (group) { - struct group *gr = NULL; - - /* - * Lookup group information in the system's db - */ - gr = getgrnam(group); - if (!gr) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group); - return -1; - } - runas_gid = gr->gr_gid; - } - - if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) { - /* already running as the right user and group, nothing to do! */ - return 0; - } - - if (runas_uid) { -#ifdef HAVE_SETGROUPS - /* - * Drop all group memberships prior to changing anything - * or else we're going to inherit the parent's list of groups - * (which is not what we want...) - */ - if (setgroups(0, NULL) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to drop group access list\n"); - return -1; - } -#endif - if (runas_gid) { - /* - * A group has been passed, switch to it - * (without loading the user's other groups) - */ - if (setgid(runas_gid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); - return -1; - } - } else { - /* - * No group has been passed, use the user's primary group in this case - */ - if (setgid(runas_pw->pw_gid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); - return -1; - } -#ifdef HAVE_INITGROUPS - /* - * Set all the other groups the user is a member of - * (This can be really useful for fine-grained access control) - */ - if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to set group access list for user\n"); - return -1; - } -#endif - } - - /* - * Finally drop all privileges by switching to the new userid - */ - if (setuid(runas_uid) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n"); - return -1; - } - } -#endif - return 0; -} - -SWITCH_DECLARE(void) switch_core_runtime_loop(int bg) -{ -#ifdef WIN32 - HANDLE shutdown_event; - char path[256] = ""; -#endif - if (bg) { - bg = 0; -#ifdef WIN32 - switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); - shutdown_event = CreateEvent(NULL, FALSE, FALSE, path); - if (shutdown_event) { - WaitForSingleObject(shutdown_event, INFINITE); - } -#else - runtime.running = 1; - while (runtime.running) { - switch_yield(1000000); - } -#endif - } else { - /* wait for console input */ - switch_console_loop(); - } -} - -SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext) -{ - if (!ext) { - return NULL; - } - return (const char *) switch_core_hash_find(runtime.mime_types, ext); -} - - -SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void) -{ - return switch_hash_first(NULL, runtime.mime_types); -} - -SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext) -{ - const char *check; - switch_status_t status = SWITCH_STATUS_FALSE; - - switch_assert(type); - switch_assert(ext); - - check = (const char *) switch_core_hash_find(runtime.mime_types, ext); - - if (!check) { - char *ptype = switch_core_permanent_strdup(type); - char *ext_list = strdup(ext); - int argc = 0; - char *argv[20] = { 0 }; - int x; - - switch_assert(ext_list); - - if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - - for (x = 0; x < argc; x++) { - if (argv[x] && ptype) { - switch_core_hash_insert(runtime.mime_types, argv[x], ptype); - } - } - - status = SWITCH_STATUS_SUCCESS; - } - - free(ext_list); - } - - return status; -} - -static void load_mime_types(void) -{ - char *cf = "mime.types"; - FILE *fd = NULL; - char *line_buf = NULL; - switch_size_t llen = 0; - char *mime_path = NULL; - - mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf); - switch_assert(mime_path); - - fd = fopen(mime_path, "rb"); - - if (fd == NULL) { - goto end; - } - - while ((switch_fp_read_dline(fd, &line_buf, &llen))) { - char *p; - char *type = line_buf; - - if (*line_buf == '#') { - continue; - } - - if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) { - *p = '\0'; - } - - if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) { - *p++ = '\0'; - - while (*p == ' ' || *p == '\t') { - p++; - } - - switch_core_mime_add_type(type, p); - } - - } - - switch_safe_free(line_buf); - - if (fd) { - fclose(fd); - fd = NULL; - } - - end: - - switch_safe_free(mime_path); - -} - -SWITCH_DECLARE(void) switch_core_setrlimits(void) -{ -#ifdef HAVE_SETRLIMIT - struct rlimit rlp; - - /* - Setting the stack size on FreeBSD results in an instant crash. - - If anyone knows how to fix this, - feel free to submit a patch to http://jira.freeswitch.org - */ - -#ifndef __FreeBSD__ - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; - rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; - setrlimit(RLIMIT_STACK, &rlp); -#endif - - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = 999999; - rlp.rlim_max = 999999; - setrlimit(RLIMIT_NOFILE, &rlp); - - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = RLIM_INFINITY; - rlp.rlim_max = RLIM_INFINITY; - - setrlimit(RLIMIT_CPU, &rlp); - setrlimit(RLIMIT_DATA, &rlp); - setrlimit(RLIMIT_FSIZE, &rlp); -#ifdef RLIMIT_NPROC - setrlimit(RLIMIT_NPROC, &rlp); -#endif -#ifdef RLIMIT_RTPRIO - setrlimit(RLIMIT_RTPRIO, &rlp); -#endif - -#if !defined(__OpenBSD__) && !defined(__NetBSD__) - setrlimit(RLIMIT_AS, &rlp); -#endif -#endif - return; -} - -typedef struct { - switch_memory_pool_t *pool; - switch_hash_t *hash; -} switch_ip_list_t; - -static switch_ip_list_t IP_LIST = { 0 }; - -SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token) -{ - switch_network_list_t *list; - ip_t ip, mask, net; - uint32_t bits; - char *ipv6 = strchr(ip_str,':'); - switch_bool_t ok = SWITCH_FALSE; - - switch_mutex_lock(runtime.global_mutex); - if (ipv6) { - switch_inet_pton(AF_INET6, ip_str, &ip); - } else { - switch_inet_pton(AF_INET, ip_str, &ip); - ip.v4 = htonl(ip.v4); - } - - if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) { - if (ipv6) { - ok = switch_network_list_validate_ip6_token(list, ip, token); - } else { - ok = switch_network_list_validate_ip_token(list, ip.v4, token); - } - } else if (strchr(list_name, '/')) { - if (strchr(list_name, ',')) { - char *list_name_dup = strdup(list_name); - char *argv[32]; - int argc; - - switch_assert(list_name_dup); - - if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { - int i; - for (i = 0; i < argc; i++) { - switch_parse_cidr(argv[i], &net, &mask, &bits); - if (ipv6) { - if ((ok = switch_testv6_subnet(ip, net, mask))){ - break; - } - } else { - if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) { - break; - } - } - } - } - free(list_name_dup); - } else { - switch_parse_cidr(list_name, &net, &mask, &bits); - ok = switch_test_subnet(ip.v4, net.v4, mask.v4); - } - } - switch_mutex_unlock(runtime.global_mutex); - - return ok; -} - - -SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload) -{ - switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL; - switch_network_list_t *rfc_list, *list; - char guess_ip[16] = ""; - int mask = 0; - char guess_mask[16] = ""; - char *tmp_name; - struct in_addr in; - - switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); - in.s_addr = mask; - switch_set_string(guess_mask, inet_ntoa(in)); - - switch_mutex_lock(runtime.global_mutex); - - if (IP_LIST.hash) { - switch_core_hash_destroy(&IP_LIST.hash); - } - - if (IP_LIST.pool) { - switch_core_destroy_memory_pool(&IP_LIST.pool); - } - - memset(&IP_LIST, 0, sizeof(IP_LIST)); - switch_core_new_memory_pool(&IP_LIST.pool); - switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool); - - - tmp_name = "rfc1918.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "wan.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name); - switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE); - switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE); - switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "nat.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name); - } - switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); - switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "loopback.auto"; - switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE); - switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); - - tmp_name = "localnet.auto"; - switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); - - if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name); - } - switch_core_hash_insert(IP_LIST.hash, tmp_name, list); - - - if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) { - if ((x_lists = switch_xml_child(cfg, "network-lists"))) { - for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) { - const char *name = switch_xml_attr(x_list, "name"); - const char *dft = switch_xml_attr(x_list, "default"); - switch_bool_t default_type = SWITCH_TRUE; - - if (zstr(name)) { - continue; - } - - if (dft) { - default_type = switch_true(dft); - } - - if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) { - abort(); - } - - if (reload) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); - } - - - for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) { - const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL; - switch_bool_t ok = default_type; - const char *type = switch_xml_attr(x_node, "type"); - - if (type) { - ok = switch_true(type); - } - - cidr = switch_xml_attr(x_node, "cidr"); - host = switch_xml_attr(x_node, "host"); - mask = switch_xml_attr(x_node, "mask"); - domain = switch_xml_attr(x_node, "domain"); - - if (domain) { - switch_event_t *my_params = NULL; - switch_xml_t x_domain, xml_root; - switch_xml_t gt, gts, ut, uts; - - switch_event_create(&my_params, SWITCH_EVENT_GENERAL); - switch_assert(my_params); - switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain); - switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list"); - - if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain); - switch_event_destroy(&my_params); - continue; - } - - switch_event_destroy(&my_params); - - for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) { - const char *user_cidr = switch_xml_attr(ut, "cidr"); - const char *id = switch_xml_attr(ut, "id"); - - if (id && user_cidr) { - char *token = switch_mprintf("%s@%s", id, domain); - switch_assert(token); - switch_network_list_add_cidr_token(list, user_cidr, ok, token); - free(token); - } - } - - for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) { - for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) { - for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) { - for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) { - const char *user_cidr = switch_xml_attr(ut, "cidr"); - const char *id = switch_xml_attr(ut, "id"); - - if (id && user_cidr) { - char *token = switch_mprintf("%s@%s", id, domain); - switch_assert(token); - switch_network_list_add_cidr_token(list, user_cidr, ok, token); - free(token); - } - } - } - } - } - - switch_xml_free(xml_root); - } else if (cidr) { - if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); - } - } else if (host && mask) { - if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name); - } - } - - switch_core_hash_insert(IP_LIST.hash, name, list); - } - } - } - - switch_xml_free(xml); - } - - switch_mutex_unlock(runtime.global_mutex); -} - -SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration) -{ - if (duration) { - if (duration > SWITCH_MAX_DTMF_DURATION) { - duration = SWITCH_MAX_DTMF_DURATION; - } - if (duration < SWITCH_MIN_DTMF_DURATION) { - duration = SWITCH_MIN_DTMF_DURATION; - } - runtime.max_dtmf_duration = duration; - if (duration < runtime.min_dtmf_duration) { - runtime.min_dtmf_duration = duration; - } - } - return runtime.max_dtmf_duration; -} - -SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration) -{ - if (duration) { - if (duration < SWITCH_MIN_DTMF_DURATION) { - duration = SWITCH_MIN_DTMF_DURATION; - } - if (duration > SWITCH_MAX_DTMF_DURATION) { - duration = SWITCH_MAX_DTMF_DURATION; - } - runtime.default_dtmf_duration = duration; - - if (duration < runtime.min_dtmf_duration) { - runtime.min_dtmf_duration = duration; - } - - if (duration > runtime.max_dtmf_duration) { - runtime.max_dtmf_duration = duration; - } - - } - return runtime.default_dtmf_duration; -} - -SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration) -{ - if (duration) { - if (duration < SWITCH_MIN_DTMF_DURATION) { - duration = SWITCH_MIN_DTMF_DURATION; - } - if (duration > SWITCH_MAX_DTMF_DURATION) { - duration = SWITCH_MAX_DTMF_DURATION; - } - - runtime.min_dtmf_duration = duration; - - if (duration > runtime.max_dtmf_duration) { - runtime.max_dtmf_duration = duration; - } - } - return runtime.min_dtmf_duration; -} - -SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu) -{ - switch_status_t status = SWITCH_STATUS_FALSE; - - if (cpu > -1) { - -#ifdef HAVE_CPU_SET_MACROS - cpu_set_t set; - - CPU_ZERO(&set); - CPU_SET(cpu, &set); - - if (!sched_setaffinity(0, sizeof(set), &set)) { - status = SWITCH_STATUS_SUCCESS; - } - -#else -#if WIN32 - if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) { - status = SWITCH_STATUS_SUCCESS; - } -#endif -#endif - } - - return status; -} - - -static void switch_core_set_serial(void) -{ - char buf[13] = ""; - char path[256]; - - int fd = -1, write_fd = -1; - switch_ssize_t bytes = 0; - - switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR); - - - if ((fd = open(path, O_RDONLY, 0)) < 0) { - char *ip = switch_core_get_variable_dup("local_ip_v4"); - uint32_t ipi = 0; - switch_byte_t *byte; - int i = 0; - - if (ip) { - switch_inet_pton(AF_INET, ip, &ipi); - free(ip); - ip = NULL; - } - - - byte = (switch_byte_t *) & ipi; - - for (i = 0; i < 8; i += 2) { - switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte); - byte++; - } - - switch_stun_random_string(buf + 8, 4, "0123456789abcdef"); - - if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) { - bytes = write(write_fd, buf, sizeof(buf)); - bytes++; - close(write_fd); - write_fd = -1; - } - } else { - bytes = read(fd, buf, sizeof(buf)); - close(fd); - fd = -1; - } - - switch_core_set_variable("switch_serial", buf); -} - - -SWITCH_DECLARE(int) switch_core_test_flag(int flag) -{ - return switch_test_flag((&runtime), flag); -} - - -SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err) -{ - switch_uuid_t uuid; - char guess_ip[256]; - int mask = 0; - struct in_addr in; - - - if (runtime.runlevel > 0) { - /* one per customer */ - return SWITCH_STATUS_SUCCESS; - } - - memset(&runtime, 0, sizeof(runtime)); - gethostname(runtime.hostname, sizeof(runtime.hostname)); - - runtime.max_db_handles = 50; - runtime.db_handle_timeout = 5000000; - - runtime.runlevel++; - runtime.dummy_cng_frame.data = runtime.dummy_data; - runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); - runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); - runtime.dbname = "core"; - switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG); - switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); - switch_set_flag((&runtime), SCF_CLEAR_SQL); - switch_set_flag((&runtime), SCF_API_EXPANSION); - switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); -#ifdef WIN32 - switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); -#endif - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - runtime.hard_log_level = SWITCH_LOG_DEBUG; - runtime.mailer_app = "sendmail"; - runtime.mailer_app_args = "-t"; - runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION; - runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION; - runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION; - runtime.odbc_dbtype = DBTYPE_DEFAULT; - runtime.dbname = NULL; -#ifndef WIN32 - runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); -#else - { - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - runtime.cpu_count = sysinfo.dwNumberOfProcessors; - } -#endif - - if (!runtime.cpu_count) runtime.cpu_count = 1; - - - /* INIT APR and Create the pool context */ - if (apr_initialize() != SWITCH_STATUS_SUCCESS) { - *err = "FATAL ERROR! Could not initialize APR\n"; - return SWITCH_STATUS_MEMERR; - } - - if (!(runtime.memory_pool = switch_core_memory_init())) { - *err = "FATAL ERROR! Could not allocate memory pool\n"; - return SWITCH_STATUS_MEMERR; - } - switch_assert(runtime.memory_pool != NULL); - - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); - - - switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - - switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - - switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); - - switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool); - switch_core_set_globals(); - switch_core_session_init(runtime.memory_pool); - switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); - switch_core_hash_init(&runtime.mime_types, runtime.memory_pool); - switch_core_hash_init_case(&runtime.ptimes, runtime.memory_pool, SWITCH_FALSE); - load_mime_types(); - runtime.flags |= flags; - runtime.sps_total = 30; - - *err = NULL; - - if (console) { - runtime.console = stdout; - } - - switch_ssl_init_ssl_locks(); - switch_curl_init(); - - switch_core_set_variable("hostname", runtime.hostname); - switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); - switch_core_set_variable("local_ip_v4", guess_ip); - in.s_addr = mask; - switch_core_set_variable("local_mask_v4", inet_ntoa(in)); - - - switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6); - switch_core_set_variable("local_ip_v6", guess_ip); - switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir); - switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir); - switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir); - switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir); - switch_core_set_serial(); - - switch_console_init(runtime.memory_pool); - switch_event_init(runtime.memory_pool); - - if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) { - apr_terminate(); - return SWITCH_STATUS_MEMERR; - } - - if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { - switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING)); - } - - switch_log_init(runtime.memory_pool, runtime.colorize_console); - - if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; - - runtime.tipping_point = 0; - runtime.timer_affinity = -1; - runtime.microseconds_per_tick = 20000; - - switch_load_core_config("switch.conf"); - - switch_core_state_machine_init(runtime.memory_pool); - - if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { - *err = "Error activating database"; - return SWITCH_STATUS_FALSE; - } - - switch_scheduler_task_thread_start(); - - switch_nat_late_init(); - - switch_rtp_init(runtime.memory_pool); - - runtime.running = 1; - runtime.initiated = switch_time_now(); - runtime.mono_initiated = switch_mono_micro_time_now(); - - switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL); - - switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD); - - switch_uuid_get(&uuid); - switch_uuid_format(runtime.uuid_str, &uuid); - switch_core_set_variable("core_uuid", runtime.uuid_str); - - - return SWITCH_STATUS_SUCCESS; -} - - -#ifndef WIN32 -static void handle_SIGCHLD(int sig) -{ - int status = 0; - - wait(&status); - return; -} -#endif - -#ifdef TRAP_BUS -static void handle_SIGBUS(int sig) -{ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Sig BUS!\n"); - return; -} -#endif - -static void handle_SIGHUP(int sig) -{ - if (sig) { - switch_event_t *event; - - if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP"); - switch_event_fire(&event); - } - } - return; -} - - -SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number) -{ - uint32_t *p; - - if ((p = switch_core_hash_find(runtime.ptimes, name))) { - return *p; - } - - return 20; -} - -static uint32_t d_30 = 30; - -static void switch_load_core_config(const char *file) -{ - switch_xml_t xml = NULL, cfg = NULL; - - switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); - switch_core_hash_insert(runtime.ptimes, "G723", &d_30); - - if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) { - switch_xml_t settings, param; - - if ((settings = switch_xml_child(cfg, "default-ptimes"))) { - for (param = switch_xml_child(settings, "codec"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "ptime"); - - if (!zstr(var) && !zstr(val)) { - uint32_t *p; - uint32_t v = switch_atoul(val); - - if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var); - continue; - } - - if (v == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var); - continue; - } - - p = switch_core_alloc(runtime.memory_pool, sizeof(*p)); - *p = v; - switch_core_hash_insert(runtime.ptimes, var, p); - } - - } - } - - if ((settings = switch_xml_child(cfg, "settings"))) { - for (param = switch_xml_child(settings, "param"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - - if (!strcasecmp(var, "loglevel")) { - int level; - if (*val > 47 && *val < 58) { - level = atoi(val); - } else { - level = switch_log_str2level(val); - } - - if (level != SWITCH_LOG_INVALID) { - switch_core_session_ctl(SCSC_LOGLEVEL, &level); - } -#ifdef HAVE_SETRLIMIT - } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) { - struct rlimit rlp; - memset(&rlp, 0, sizeof(rlp)); - rlp.rlim_cur = RLIM_INFINITY; - rlp.rlim_max = RLIM_INFINITY; - setrlimit(RLIMIT_CORE, &rlp); -#endif - } else if (!strcasecmp(var, "debug-level")) { - int tmp = atoi(val); - if (tmp > -1 && tmp < 11) { - switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp); - } - } else if (!strcasecmp(var, "max-db-handles")) { - long tmp = atol(val); - - if (tmp > 4 && tmp < 5001) { - runtime.max_db_handles = (uint32_t) tmp; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n"); - } - } else if (!strcasecmp(var, "db-handle-timeout")) { - long tmp = atol(val); - - if (tmp > 0 && tmp < 5001) { - runtime.db_handle_timeout = (uint32_t) tmp * 1000000; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n"); - } - - } else if (!strcasecmp(var, "multiple-registrations")) { - runtime.multiple_registrations = switch_true(val); - } else if (!strcasecmp(var, "auto-create-schemas")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); - } else { - switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS); - } - } else if (!strcasecmp(var, "session-thread-pool")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); - } else { - switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL); - } - } else if (!strcasecmp(var, "auto-clear-sql")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_CLEAR_SQL); - } else { - switch_clear_flag((&runtime), SCF_CLEAR_SQL); - } - } else if (!strcasecmp(var, "api-expansion")) { - if (switch_true(val)) { - switch_set_flag((&runtime), SCF_API_EXPANSION); - } else { - switch_clear_flag((&runtime), SCF_API_EXPANSION); - } - } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) { - switch_set_flag((&runtime), SCF_EARLY_HANGUP); - } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) { - runtime.colorize_console = SWITCH_TRUE; - } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) { - runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) { - runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) { - runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) { - runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) { - runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "mailer-app-args") && val) { - runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val); - } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) { - switch_core_sessions_per_second(atoi(val)); - } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) { - int tmp = atoi(val); - if (tmp > 0) { - switch_core_max_dtmf_duration((uint32_t) tmp); - } - } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) { - int tmp = atoi(val); - if (tmp > 0) { - switch_core_min_dtmf_duration((uint32_t) tmp); - } - } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) { - int tmp = atoi(val); - if (tmp > 0) { - switch_core_default_dtmf_duration((uint32_t) tmp); - } - } else if (!strcasecmp(var, "enable-use-system-time")) { - switch_time_set_use_system_time(switch_true(val)); - } else if (!strcasecmp(var, "enable-monotonic-timing")) { - switch_time_set_monotonic(switch_true(val)); - } else if (!strcasecmp(var, "enable-softtimer-timerfd")) { - switch_time_set_timerfd(switch_true(val)); - } else if (!strcasecmp(var, "enable-clock-nanosleep")) { - switch_time_set_nanosleep(switch_true(val)); - } else if (!strcasecmp(var, "enable-cond-yield")) { - switch_time_set_cond_yield(switch_true(val)); - } else if (!strcasecmp(var, "enable-timer-matrix")) { - switch_time_set_matrix(switch_true(val)); - } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) { - switch_core_session_limit(atoi(val)); - } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) { - int v = switch_true(val); - if (v) { - switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); - } else { - switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); - } - } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) { -#ifdef WIN32 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n"); -#else - int v = switch_true(val); - if (v) { - switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } else { - switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } -#endif - } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) { - switch_core_min_idle_cpu(atof(val)); - } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) { - runtime.tipping_point = atoi(val); - } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) { - int tmp = atoi(val); - - - if (tmp > runtime.cpu_count / 2) { - tmp = runtime.cpu_count / 2; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n", - runtime.cpu_count / 2); - } - - if (tmp < 1) { - tmp = 1; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n"); - } - - switch_event_launch_dispatch_threads(tmp); - - } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) { - runtime.microseconds_per_tick = 1000; - } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) { - if (!strcasecmp(val, "disabled")) { - runtime.timer_affinity = -1; - } else { - runtime.timer_affinity = atoi(val); - } - } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) { - 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() || switch_pgsql_available()) { - runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n"); - } - } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) { - switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ); - } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) { - if (!strcasecmp(val, "MSSQL")) { - runtime.odbc_dbtype = DBTYPE_MSSQL; - } else { - runtime.odbc_dbtype = DBTYPE_DEFAULT; - } -#ifdef ENABLE_ZRTP - } else if (!strcasecmp(var, "rtp-enable-zrtp")) { - switch_core_set_variable("zrtp_enabled", val); -#endif - } else if (!strcasecmp(var, "switchname") && !zstr(val)) { - runtime.switchname = switch_core_strdup(runtime.memory_pool, val); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname); - } - } - } - - if ((settings = switch_xml_child(cfg, "variables"))) { - for (param = switch_xml_child(settings, "variable"); param; param = param->next) { - const char *var = switch_xml_attr_soft(param, "name"); - const char *val = switch_xml_attr_soft(param, "value"); - if (var && val) { - switch_core_set_variable(var, val); - } - } - } - - switch_xml_free(xml); - } - - -} - -SWITCH_DECLARE(const char *) switch_core_banner(void) -{ - - return ("\n" - ".=============================================================.\n" - "| _____ ______ _____ _____ ____ _ _ |\n" - "| | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | |\n" - "| | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | |\n" - "| | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | |\n" - "| |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| |\n" - "| |\n" - ".=============================================================." - "\n" - - "| Anthony Minessale II, Michael Jerris, Brian West, Others |\n" - "| FreeSWITCH (http://www.freeswitch.org) |\n" - "| Paypal Donations Appreciated: paypal@freeswitch.org |\n" - "| Brought to you by ClueCon http://www.cluecon.com/ |\n" - ".=============================================================.\n" - "\n"); -} - - -SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err) -{ - switch_event_t *event; - char *cmd; - int x = 0; - const char *use = NULL; -#include "cc.h" - - - if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_GENERR; - } - - if (runtime.runlevel > 1) { - /* one per customer */ - return SWITCH_STATUS_SUCCESS; - } - - runtime.runlevel++; - - switch_core_set_signal_handlers(); - switch_load_network_lists(SWITCH_FALSE); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n"); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n"); - if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { - *err = "Cannot load modules"; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err); - return SWITCH_STATUS_GENERR; - } - - switch_load_network_lists(SWITCH_FALSE); - - switch_load_core_config("post_load_switch.conf"); - - switch_core_set_signal_handlers(); - - if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); - switch_event_fire(&event); - } - - switch_core_screen_size(&x, NULL); - - use = (x > 100) ? cc : cc_s; - -#ifdef WIN32 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use); -#else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", - SWITCH_SEQ_DEFAULT_COLOR, - SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE, - switch_core_banner(), - use, SWITCH_SEQ_DEFAULT_COLOR); - -#endif - - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, - "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n", - SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN, - switch_core_session_limit(0), - switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); - - - if (x < 160) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n"); - } - - switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); - - if ((cmd = switch_core_get_variable_dup("api_on_startup"))) { - switch_stream_handle_t stream = { 0 }; - SWITCH_STANDARD_STREAM(stream); - switch_console_execute(cmd, 0, &stream); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data); - free(stream.data); - free(cmd); - } - - return SWITCH_STATUS_SUCCESS; - -} - -SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration) -{ - switch_time_t temp = total_ms / 1000; - memset(duration, 0, sizeof(*duration)); - duration->mms = (uint32_t) (total_ms % 1000); - duration->ms = (uint32_t) (temp % 1000); - temp = temp / 1000; - duration->sec = (uint32_t) (temp % 60); - temp = temp / 60; - duration->min = (uint32_t) (temp % 60); - temp = temp / 60; - duration->hr = (uint32_t) (temp % 24); - temp = temp / 24; - duration->day = (uint32_t) (temp % 365); - duration->yr = (uint32_t) (temp / 365); -} - -SWITCH_DECLARE(switch_time_t) switch_core_uptime(void) -{ - return switch_mono_micro_time_now() - runtime.mono_initiated; -} - - -#ifdef _MSC_VER -static void win_shutdown(void) -{ - - HANDLE shutdown_event; - char path[512]; - /* for windows we need the event to signal for shutting down a background FreeSWITCH */ - snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); - - /* open the event so we can signal it */ - shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path); - - if (shutdown_event) { - /* signal the event to shutdown */ - SetEvent(shutdown_event); - /* cleanup */ - CloseHandle(shutdown_event); - } -} -#endif - -SWITCH_DECLARE(void) switch_core_set_signal_handlers(void) -{ - /* set signal handlers */ - signal(SIGINT, SIG_IGN); -#ifndef WIN32 - if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)) { - signal(SIGCHLD, SIG_DFL); - } else { - signal(SIGCHLD, handle_SIGCHLD); - } -#endif -#ifdef SIGPIPE - signal(SIGPIPE, SIG_IGN); -#endif -#ifdef SIGQUIT - signal(SIGQUIT, SIG_IGN); -#endif -#ifdef SIGPOLL - signal(SIGPOLL, SIG_IGN); -#endif -#ifdef SIGIO - signal(SIGIO, SIG_IGN); -#endif -#ifdef TRAP_BUS - signal(SIGBUS, handle_SIGBUS); -#endif -#ifdef SIGUSR1 - signal(SIGUSR1, handle_SIGHUP); -#endif - signal(SIGHUP, handle_SIGHUP); -} - -SWITCH_DECLARE(uint32_t) switch_core_debug_level(void) -{ - return runtime.debug_level; -} - - -SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val) -{ - int *intval = (int *) val; - int oldintval = 0, newintval = 0; - - if (intval) { - oldintval = *intval; - } - - if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) { - return -1; - } - - switch (cmd) { - case SCSC_RECOVER: - { - char *arg = (char *) val; - char *tech = NULL, *prof = NULL; - int r, flush = 0; - - if (!zstr(arg)) { - tech = strdup(arg); - - if ((prof = strchr(tech, ':'))) { - *prof++ = '\0'; - } - - if (!strcasecmp(tech, "flush")) { - flush++; - - if (prof) { - tech = prof; - if ((prof = strchr(tech, ':'))) { - *prof++ = '\0'; - } - } - } - - } - - if (flush) { - switch_core_recovery_flush(tech, prof); - r = -1; - } else { - r = switch_core_recovery_recover(tech, prof); - } - - switch_safe_free(tech); - return r; - - } - break; - case SCSC_DEBUG_SQL: - { - if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { - switch_clear_flag((&runtime), SCF_DEBUG_SQL); - newintval = 0; - } else { - switch_set_flag((&runtime), SCF_DEBUG_SQL); - newintval = 1; - } - } - break; - case SCSC_VERBOSE_EVENTS: - if (intval) { - if (oldintval > -1) { - if (oldintval) { - switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); - } else { - switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); - } - } - newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS); - } - break; - case SCSC_API_EXPANSION: - if (intval) { - if (oldintval > -1) { - if (oldintval) { - switch_set_flag((&runtime), SCF_API_EXPANSION); - } else { - switch_clear_flag((&runtime), SCF_API_EXPANSION); - } - } - newintval = switch_test_flag((&runtime), SCF_API_EXPANSION); - } - break; - case SCSC_THREADED_SYSTEM_EXEC: - if (intval) { - if (oldintval > -1) { - if (oldintval) { - switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } else { - switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } - } - newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); - } - break; - case SCSC_CALIBRATE_CLOCK: - switch_time_calibrate_clock(); - break; - case SCSC_FLUSH_DB_HANDLES: - switch_cache_db_flush_handles(); - break; - case SCSC_SEND_SIGHUP: - handle_SIGHUP(1); - break; - case SCSC_SYNC_CLOCK: - switch_time_sync(); - newintval = 0; - break; - case SCSC_SYNC_CLOCK_WHEN_IDLE: - newintval = switch_core_session_sync_clock(); - break; - case SCSC_SQL: - if (oldintval) { - switch_core_sqldb_resume(); - } else { - switch_core_sqldb_pause(); - } - break; - case SCSC_PAUSE_ALL: - if (oldintval) { - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - } else { - switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); - } - break; - case SCSC_PAUSE_INBOUND: - if (oldintval) { - switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); - } else { - switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); - } - break; - case SCSC_PAUSE_OUTBOUND: - if (oldintval) { - switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); - } else { - switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); - } - break; - case SCSC_HUPALL: - switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST); - break; - case SCSC_CANCEL_SHUTDOWN: - switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED); - break; - case SCSC_SAVE_HISTORY: - switch_console_save_history(); - break; - case SCSC_CRASH: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n"); - switch_console_save_history(); - abort(); - break; - case SCSC_SHUTDOWN_NOW: - switch_console_save_history(); - exit(0); - break; - case SCSC_SHUTDOWN_ELEGANT: - case SCSC_SHUTDOWN_ASAP: - { - int x = 19; - uint32_t count; - - switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED); - if (cmd == SCSC_SHUTDOWN_ASAP) { - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - } - - while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) { - switch_yield(500000); - if (++x == 20) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Shutdown in progress, %u session(s) remain.\nShutting down %s\n", - count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls."); - x = 0; - } - } - - if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) { - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); -#ifdef _MSC_VER - win_shutdown(); -#endif - - if (oldintval) { - switch_set_flag((&runtime), SCF_RESTART); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); -#ifdef _MSC_VER - fclose(stdin); -#endif - } - runtime.running = 0; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n"); - switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); - } - } - break; - case SCSC_PAUSE_CHECK: - newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS); - break; - case SCSC_PAUSE_INBOUND_CHECK: - newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); - break; - case SCSC_PAUSE_OUTBOUND_CHECK: - newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); - break; - case SCSC_READY_CHECK: - newintval = switch_core_ready(); - break; - case SCSC_SHUTDOWN_CHECK: - newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED); - break; - case SCSC_SHUTDOWN: - -#ifdef _MSC_VER - win_shutdown(); -#endif - - if (oldintval) { - switch_set_flag((&runtime), SCF_RESTART); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); -#ifdef _MSC_VER - fclose(stdin); -#endif - } - runtime.running = 0; - break; - case SCSC_CHECK_RUNNING: - newintval = runtime.running; - break; - case SCSC_LOGLEVEL: - if (oldintval > -1) { - runtime.hard_log_level = oldintval; - } - - if (runtime.hard_log_level > SWITCH_LOG_DEBUG) { - runtime.hard_log_level = SWITCH_LOG_DEBUG; - } - newintval = runtime.hard_log_level; - break; - case SCSC_DEBUG_LEVEL: - if (oldintval > -1) { - if (oldintval > 10) - newintval = 10; - runtime.debug_level = oldintval; - } - newintval = runtime.debug_level; - break; - case SCSC_MIN_IDLE_CPU: - { - double *dval = (double *) val; - if (dval) { - *dval = switch_core_min_idle_cpu(*dval); - } - intval = NULL; - } - break; - case SCSC_MAX_SESSIONS: - newintval = switch_core_session_limit(oldintval); - break; - case SCSC_LAST_SPS: - newintval = runtime.sps_last; - break; - case SCSC_MAX_DTMF_DURATION: - newintval = switch_core_max_dtmf_duration(oldintval); - break; - case SCSC_MIN_DTMF_DURATION: - newintval = switch_core_min_dtmf_duration(oldintval); - break; - case SCSC_DEFAULT_DTMF_DURATION: - newintval = switch_core_default_dtmf_duration(oldintval); - break; - case SCSC_SPS: - switch_mutex_lock(runtime.throttle_mutex); - if (oldintval > 0) { - runtime.sps_total = oldintval; - } - newintval = runtime.sps_total; - switch_mutex_unlock(runtime.throttle_mutex); - break; - - case SCSC_RECLAIM: - switch_core_memory_reclaim_all(); - newintval = 0; - break; - } - - if (intval) { - *intval = newintval; - } - - - return 0; -} - -SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void) -{ - return runtime.flags; -} - -SWITCH_DECLARE(switch_bool_t) switch_core_ready(void) -{ - return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE; -} - -SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void) -{ - return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; -} - -SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void) -{ - return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; -} - -SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) -{ - switch_event_t *event; - - if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down"); - switch_event_fire(&event); - } - - switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); - switch_set_flag((&runtime), SCF_SHUTTING_DOWN); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n"); - switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n"); - - switch_loadable_module_shutdown(); - - switch_ssl_destroy_ssl_locks(); - - if (switch_test_flag((&runtime), SCF_USE_SQL)) { - switch_core_sqldb_stop(); - } - switch_scheduler_task_thread_stop(); - - switch_rtp_shutdown(); - - if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { - switch_nat_shutdown(); - } - switch_xml_destroy(); - switch_core_session_uninit(); - switch_console_shutdown(); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n"); - switch_event_shutdown(); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n"); - switch_log_shutdown(); - - switch_core_unset_variables(); - switch_core_memory_stop(); - - if (runtime.console && runtime.console != stdout && runtime.console != stderr) { - fclose(runtime.console); - runtime.console = NULL; - } - - switch_safe_free(SWITCH_GLOBAL_dirs.base_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.log_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.db_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.script_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.run_dir); - switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir); - - switch_event_destroy(&runtime.global_vars); - switch_core_hash_destroy(&runtime.ptimes); - switch_core_hash_destroy(&runtime.mime_types); - - if (IP_LIST.hash) { - switch_core_hash_destroy(&IP_LIST.hash); - } - - if (IP_LIST.pool) { - switch_core_destroy_memory_pool(&IP_LIST.pool); - } - - if (runtime.memory_pool) { - apr_pool_destroy(runtime.memory_pool); - apr_terminate(); - } - - return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen) -{ - const switch_management_interface_t *ptr; - switch_status_t status = SWITCH_STATUS_FALSE; - - if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) { - status = ptr->management_function(relative_oid, action, data, datalen); - } - - return status; -} - -SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void) -{ - switch_core_memory_reclaim_logger(); - switch_core_memory_reclaim_events(); - switch_core_memory_reclaim(); -} - - -struct system_thread_handle { - const char *cmd; - switch_thread_cond_t *cond; - switch_mutex_t *mutex; - switch_memory_pool_t *pool; - int ret; - int *fds; -}; - -static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj) -{ - struct system_thread_handle *sth = (struct system_thread_handle *) obj; - -#if 0 // if we are a luser we can never turn this back down, didn't we already set the stack size? -#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) - struct rlimit rlim; - - rlim.rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE; - rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; - if (setrlimit(RLIMIT_STACK, &rlim) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); - } -#endif -#endif - - if (sth->fds) { - dup2(sth->fds[1], STDOUT_FILENO); - } - - sth->ret = system(sth->cmd); - -#if 0 -#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) - rlim.rlim_cur = SWITCH_THREAD_STACKSIZE; - rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; - if (setrlimit(RLIMIT_STACK, &rlim) < 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); - } -#endif -#endif - - switch_mutex_lock(sth->mutex); - switch_thread_cond_signal(sth->cond); - switch_mutex_unlock(sth->mutex); - - switch_core_destroy_memory_pool(&sth->pool); - - return NULL; -} - - -static int switch_system_thread(const char *cmd, switch_bool_t wait) -{ - switch_thread_t *thread; - switch_threadattr_t *thd_attr; - int ret = 0; - struct system_thread_handle *sth; - switch_memory_pool_t *pool; - - if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); - return 1; - } - - if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) { - switch_core_destroy_memory_pool(&pool); - return 1; - } - - sth->pool = pool; - sth->cmd = switch_core_strdup(pool, cmd); - - switch_thread_cond_create(&sth->cond, sth->pool); - switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool); - switch_mutex_lock(sth->mutex); - - switch_threadattr_create(&thd_attr, sth->pool); - switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE); - switch_threadattr_detach_set(thd_attr, 1); - switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool); - - if (wait) { - switch_thread_cond_wait(sth->cond, sth->mutex); - ret = sth->ret; - } - switch_mutex_unlock(sth->mutex); - - return ret; -} - -SWITCH_DECLARE(int) switch_max_file_desc(void) -{ - int max = 0; - -#ifndef WIN32 -#if defined(HAVE_GETDTABLESIZE) - max = getdtablesize(); -#else - max = sysconf(_SC_OPEN_MAX); -#endif -#endif - - return max; - -} - -SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl) -{ - int open_max = switch_max_file_desc(); - int i, j; - - for (i = 3; i < open_max; i++) { - if (keep) { - for (j = 0; j < keep_ttl; j++) { - if (i == keep[j]) { - goto skip; - } - } - } - - close(i); - - skip: - - continue; - - } -} - - -#ifdef WIN32 -static int switch_system_fork(const char *cmd, switch_bool_t wait) -{ - return switch_system_thread(cmd, wait); -} - -SWITCH_DECLARE(pid_t) switch_fork(void) -{ - return -1; -} - - -#else - -SWITCH_DECLARE(pid_t) switch_fork(void) -{ - int i = fork(); - - if (!i) { - set_low_priority(); - } - - return i; -} - - - -static int switch_system_fork(const char *cmd, switch_bool_t wait) -{ - int pid; - char *dcmd = strdup(cmd); - - switch_core_set_signal_handlers(); - - pid = switch_fork(); - - if (pid) { - if (wait) { - waitpid(pid, NULL, 0); - } - free(dcmd); - } else { - switch_close_extra_files(NULL, 0); - - if (system(dcmd) == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd); - } - free(dcmd); - exit(0); - } - - return 0; -} -#endif - - - -SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait) -{ - int (*sys_p)(const char *cmd, switch_bool_t wait); - - sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork; - - return sys_p(cmd, wait); - -} - - - -SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream) -{ -#ifdef WIN32 - return switch_system(cmd, SWITCH_TRUE); -#else - int fds[2], pid = 0; - - if (pipe(fds)) { - goto end; - } else { /* good to go */ - pid = switch_fork(); - - if (pid < 0) { /* ok maybe not */ - close(fds[0]); - close(fds[1]); - goto end; - } else if (pid) { /* parent */ - char buf[1024] = ""; - int bytes; - close(fds[1]); - while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) { - stream->raw_write_function(stream, (unsigned char *)buf, bytes); - } - close(fds[0]); - waitpid(pid, NULL, 0); - } else { /* child */ - switch_close_extra_files(fds, 2); - close(fds[0]); - dup2(fds[1], STDOUT_FILENO); - switch_system(cmd, SWITCH_TRUE); - close(fds[1]); - exit(0); - } - } - - end: - - return 0; - -#endif - -} - -SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max) -{ -#ifdef HAVE_SETRLIMIT - struct rlimit rlp; - - memset(&rlp, 0, sizeof(rlp)); - getrlimit(RLIMIT_STACK, &rlp); - - *cur = rlp.rlim_cur; - *max = rlp.rlim_max; - - return SWITCH_STATUS_SUCCESS; - -#else - - return SWITCH_STATUS_FALSE; - -#endif - - - -} - - -SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream) -{ -#ifdef WIN32 - stream->write_function(stream, "Capturing output not supported.\n"); - return switch_system(cmd, SWITCH_TRUE); -#else - return switch_stream_system_fork(cmd, stream); -#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: - */ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2012, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * 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 Jerris + * Paul D. Tinsley + * Marcel Barbulescu + * Joseph Sullivan + * + * + * switch_core.c -- Main Core Library + * + */ + + + +#include +#include +#include +#include +#include +#include "private/switch_core_pvt.h" +#include +#ifndef WIN32 +#include +#ifdef HAVE_SETRLIMIT +#include +#endif +#endif +#include + + +SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 }; + +/* The main runtime obj we keep this hidden for ourselves */ +struct switch_runtime runtime = { 0 }; +static void switch_load_core_config(const char *file); + +static void send_heartbeat(void) +{ + switch_event_t *event; + switch_core_time_duration_t duration; + + switch_core_measure_time(switch_core_uptime(), &duration); + + if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time", + "%u year%s, " + "%u day%s, " + "%u hour%s, " + "%u minute%s, " + "%u second%s, " + "%u millisecond%s, " + "%u microsecond%s", + duration.yr, duration.yr == 1 ? "" : "s", + duration.day, duration.day == 1 ? "" : "s", + duration.hr, duration.hr == 1 ? "" : "s", + duration.min, duration.min == 1 ? "" : "s", + duration.sec, duration.sec == 1 ? "" : "s", + duration.ms, duration.ms == 1 ? "" : "s", duration.mms, duration.mms == 1 ? "" : "s"); + + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Version", SWITCH_VERSION_FULL); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Uptime-msec", "%"SWITCH_TIME_T_FMT, switch_core_uptime() / 1000); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count()); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu()); + switch_event_fire(&event); + } +} + +static char main_ip4[256] = ""; +static char main_ip6[256] = ""; + +static void check_ip(void) +{ + char guess_ip4[256] = ""; + char guess_ip6[256] = ""; + char old_ip4[256] = ""; + char old_ip6[256] = ""; + int ok4 = 1, ok6 = 1; + int mask = 0; + + gethostname(runtime.hostname, sizeof(runtime.hostname)); + switch_core_set_variable("hostname", runtime.hostname); + + switch_find_local_ip(guess_ip4, sizeof(guess_ip4), &mask, AF_INET); + switch_find_local_ip(guess_ip6, sizeof(guess_ip6), NULL, AF_INET6); + + if (!*main_ip4) { + switch_set_string(main_ip4, guess_ip4); + } else { + if (!(ok4 = !strcmp(main_ip4, guess_ip4))) { + struct in_addr in; + + in.s_addr = mask; + switch_set_string(old_ip4, main_ip4); + switch_set_string(main_ip4, guess_ip4); + switch_core_set_variable("local_ip_v4", guess_ip4); + switch_core_set_variable("local_mask_v4", inet_ntoa(in)); + } + } + + if (!*main_ip6) { + switch_set_string(main_ip6, guess_ip6); + } else { + if (!(ok6 = !strcmp(main_ip6, guess_ip6))) { + switch_set_string(old_ip6, main_ip6); + switch_set_string(main_ip6, guess_ip6); + switch_core_set_variable("local_ip_v6", guess_ip6); + } + } + + if (!ok4 || !ok6) { + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change"); + if (!ok4) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v4", old_ip4); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", main_ip4); + } + if (!ok6) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-previous-v6", old_ip6); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", main_ip6); + } + switch_event_fire(&event); + } + } +} + +SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback) +{ + send_heartbeat(); + + /* reschedule this task */ + task->runtime = switch_epoch_time_now(NULL) + 20; +} + + +SWITCH_STANDARD_SCHED_FUNC(check_ip_callback) +{ + check_ip(); + + /* reschedule this task */ + task->runtime = switch_epoch_time_now(NULL) + 60; +} + + +SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console) +{ + if ((runtime.console = fopen(console, "a")) == 0) { + fprintf(stderr, "Cannot open output file %s.\n", console); + return SWITCH_STATUS_FALSE; + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(FILE *) switch_core_get_console(void) +{ + return runtime.console; +} + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +SWITCH_DECLARE(void) switch_core_screen_size(int *x, int *y) +{ + +#ifdef WIN32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + int ret; + + if ((ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ), &csbi))) { + if (x) *x = csbi.dwSize.X; + if (y) *y = csbi.dwSize.Y; + } + +#elif defined(TIOCGWINSZ) + struct winsize w; + ioctl(0, TIOCGWINSZ, &w); + + if (x) *x = w.ws_col; + if (y) *y = w.ws_row; +#else + if (x) *x = 80; + if (y) *y = 24; +#endif + +} + +SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel) +{ + FILE *handle = stdout; + + switch (channel) { + case SWITCH_CHANNEL_ID_LOG: + case SWITCH_CHANNEL_ID_LOG_CLEAN: + handle = runtime.console; + break; + default: + handle = runtime.console; + break; + } + + return handle; +} + + +SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler) +{ + int index, tmp_index = 0; + const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 }; + + switch_mutex_lock(runtime.global_mutex); + + for (index = 0; index < runtime.state_handler_index; index++) { + const switch_state_handler_table_t *cur = runtime.state_handlers[index]; + runtime.state_handlers[index] = NULL; + if (cur == state_handler) { + continue; + } + tmp[tmp_index++] = cur; + } + + runtime.state_handler_index = 0; + + for (index = 0; index < tmp_index; index++) { + runtime.state_handlers[runtime.state_handler_index++] = tmp[index]; + } + switch_mutex_unlock(runtime.global_mutex); +} + + +SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler) +{ + int index; + + switch_mutex_lock(runtime.global_mutex); + index = runtime.state_handler_index++; + + if (runtime.state_handler_index >= SWITCH_MAX_STATE_HANDLERS) { + index = -1; + } else { + runtime.state_handlers[index] = state_handler; + } + + switch_mutex_unlock(runtime.global_mutex); + return index; +} + +SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index) +{ + + if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) { + return NULL; + } + + return runtime.state_handlers[index]; +} + +SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream) +{ + switch_event_header_t *hi; + + switch_mutex_lock(runtime.global_mutex); + for (hi = runtime.global_vars->headers; hi; hi = hi->next) { + stream->write_function(stream, "%s=%s\n", hi->name, hi->value); + } + switch_mutex_unlock(runtime.global_mutex); +} + +SWITCH_DECLARE(const char *) switch_core_get_hostname(void) +{ + return runtime.hostname; +} + +SWITCH_DECLARE(const char *) switch_core_get_switchname(void) +{ + if (!zstr(runtime.switchname)) return runtime.switchname; + return runtime.hostname; +} + + +SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) +{ + char *val; + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + val = (char *) switch_event_get_header(runtime.global_vars, varname); + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + return val; +} + +SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname) +{ + char *val = NULL, *v; + + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = strdup(v); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + + return val; +} + +SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool) +{ + char *val = NULL, *v; + + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = switch_core_strdup(pool, v); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + + return val; +} + +static void switch_core_unset_variables(void) +{ + switch_thread_rwlock_wrlock(runtime.global_var_rwlock); + switch_event_destroy(&runtime.global_vars); + switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); + switch_thread_rwlock_unlock(runtime.global_var_rwlock); +} + +SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *value) +{ + char *val; + + if (varname) { + switch_thread_rwlock_wrlock(runtime.global_var_rwlock); + val = (char *) switch_event_get_header(runtime.global_vars, varname); + if (val) { + switch_event_del_header(runtime.global_vars, varname); + } + if (value) { + char *v = strdup(value); + switch_string_var_check(v, SWITCH_TRUE); + switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); + } else { + switch_event_del_header(runtime.global_vars, varname); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + } +} + +SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2) +{ + char *val; + + if (varname) { + switch_thread_rwlock_wrlock(runtime.global_var_rwlock); + val = (char *) switch_event_get_header(runtime.global_vars, varname); + + if (val) { + if (!val2 || strcmp(val, val2) != 0) { + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + return SWITCH_FALSE; + } + switch_event_del_header(runtime.global_vars, varname); + } else if (!zstr(val2)) { + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + return SWITCH_FALSE; + } + + if (value) { + char *v = strdup(value); + switch_string_var_check(v, SWITCH_TRUE); + switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v); + } else { + switch_event_del_header(runtime.global_vars, varname); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); + } + return SWITCH_TRUE; +} + +SWITCH_DECLARE(char *) switch_core_get_uuid(void) +{ + return runtime.uuid_str; +} + + +static void *SWITCH_THREAD_FUNC switch_core_service_thread(switch_thread_t *thread, void *obj) +{ + switch_core_session_t *session = obj; + switch_channel_t *channel; + switch_frame_t *read_frame; + +// switch_assert(thread != NULL); +// switch_assert(session != NULL); + + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { + return NULL; + } + + switch_mutex_lock(session->frame_read_mutex); + + channel = switch_core_session_get_channel(session); + + switch_channel_set_flag(channel, CF_SERVICE); + while (switch_channel_test_flag(channel, CF_SERVICE)) { + + if (switch_channel_test_flag(channel, CF_SERVICE_AUDIO)) { + switch (switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { + case SWITCH_STATUS_SUCCESS: + case SWITCH_STATUS_TIMEOUT: + case SWITCH_STATUS_BREAK: + break; + default: + switch_channel_clear_flag(channel, CF_SERVICE); + break; + } + } + + if (switch_channel_test_flag(channel, CF_SERVICE_VIDEO) && switch_channel_test_flag(channel, CF_VIDEO)) { + switch (switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0)) { + case SWITCH_STATUS_SUCCESS: + case SWITCH_STATUS_TIMEOUT: + case SWITCH_STATUS_BREAK: + break; + default: + switch_channel_clear_flag(channel, CF_SERVICE); + break; + } + } + } + + switch_mutex_unlock(session->frame_read_mutex); + + switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); + switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); + + switch_core_session_rwunlock(session); + + return NULL; +} + +/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */ +SWITCH_DECLARE(void) switch_core_thread_session_end(switch_core_session_t *session) +{ + switch_channel_t *channel; + switch_assert(session); + + channel = switch_core_session_get_channel(session); + switch_assert(channel); + + switch_channel_clear_flag(channel, CF_SERVICE); + switch_channel_clear_flag(channel, CF_SERVICE_AUDIO); + switch_channel_clear_flag(channel, CF_SERVICE_VIDEO); + + switch_core_session_kill_channel(session, SWITCH_SIG_BREAK); + +} + +SWITCH_DECLARE(void) switch_core_service_session_av(switch_core_session_t *session, switch_bool_t audio, switch_bool_t video) +{ + switch_channel_t *channel; + switch_assert(session); + + channel = switch_core_session_get_channel(session); + switch_assert(channel); + + if (audio) switch_channel_set_flag(channel, CF_SERVICE_AUDIO); + if (video) switch_channel_set_flag(channel, CF_SERVICE_VIDEO); + + switch_core_session_launch_thread(session, (void *(*)(switch_thread_t *,void *))switch_core_service_thread, session); +} + +/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and + a void object and trust that that the function will be run in a thread with arg This lets + you request and activate a thread without giving up any knowledge about what is in the thread + neither the core nor the calling module know anything about each other. + + This thread is expected to never exit until the application exits so the func is responsible + to make sure that is the case. + + The typical use for this is so switch_loadable_module.c can start up a thread for each module + passing the table of module methods as a session obj into the core without actually allowing + the core to have any clue and keeping switch_loadable_module.c from needing any thread code. + +*/ + +SWITCH_DECLARE(switch_thread_t *) switch_core_launch_thread(switch_thread_start_t func, void *obj, switch_memory_pool_t *pool) +{ + switch_thread_t *thread = NULL; + switch_threadattr_t *thd_attr = NULL; + switch_core_thread_session_t *ts; + int mypool; + + mypool = pool ? 0 : 1; + + if (!pool && switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory pool\n"); + return NULL; + } + + switch_threadattr_create(&thd_attr, pool); + + if ((ts = switch_core_alloc(pool, sizeof(*ts))) == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not allocate memory\n"); + } else { + if (mypool) { + ts->pool = pool; + } + ts->objs[0] = obj; + ts->objs[1] = thread; + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); + switch_thread_create(&thread, thd_attr, func, ts, pool); + } + + return thread; +} + +SWITCH_DECLARE(void) switch_core_set_globals(void) +{ +#define BUFSIZE 1024 +#ifdef WIN32 + char lpPathBuffer[BUFSIZE]; + DWORD dwBufSize = BUFSIZE; + char base_dir[1024]; + char *lastbacklash; + char *tmp; + + GetModuleFileName(NULL, base_dir, BUFSIZE); + lastbacklash = strrchr(base_dir, '\\'); + base_dir[(lastbacklash - base_dir)] = '\0'; + /* set base_dir as cwd, to be able to use relative paths in scripting languages (e.g. mod_lua) when FS is running as a service or while debugging FS using visual studio */ + SetCurrentDirectory(base_dir); + tmp = switch_string_replace(base_dir, "\\", "/"); + strcpy(base_dir, tmp); + free(tmp); + +#else + char base_dir[1024] = SWITCH_PREFIX_DIR; +#endif + + if (!SWITCH_GLOBAL_dirs.base_dir && (SWITCH_GLOBAL_dirs.base_dir = (char *) malloc(BUFSIZE))) { + switch_snprintf(SWITCH_GLOBAL_dirs.base_dir, BUFSIZE, "%s", base_dir); + } + + if (!SWITCH_GLOBAL_dirs.mod_dir && (SWITCH_GLOBAL_dirs.mod_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_MOD_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s", SWITCH_MOD_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.mod_dir, BUFSIZE, "%s%smod", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.lib_dir && (SWITCH_GLOBAL_dirs.lib_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_LIB_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s", SWITCH_LIB_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.lib_dir, BUFSIZE, "%s%slib", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.conf_dir && (SWITCH_GLOBAL_dirs.conf_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_CONF_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s", SWITCH_CONF_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.conf_dir, BUFSIZE, "%s%sconf", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.log_dir && (SWITCH_GLOBAL_dirs.log_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_LOG_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s", SWITCH_LOG_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.log_dir, BUFSIZE, "%s%slog", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.run_dir && (SWITCH_GLOBAL_dirs.run_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_RUN_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s", SWITCH_RUN_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.run_dir, BUFSIZE, "%s%srun", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.recordings_dir && (SWITCH_GLOBAL_dirs.recordings_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_RECORDINGS_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s", SWITCH_RECORDINGS_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.recordings_dir, BUFSIZE, "%s%srecordings", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.sounds_dir && (SWITCH_GLOBAL_dirs.sounds_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_SOUNDS_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s", SWITCH_SOUNDS_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.sounds_dir, BUFSIZE, "%s%ssounds", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.storage_dir && (SWITCH_GLOBAL_dirs.storage_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_STORAGE_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s", SWITCH_STORAGE_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.storage_dir, BUFSIZE, "%s%sstorage", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.db_dir && (SWITCH_GLOBAL_dirs.db_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_DB_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s", SWITCH_DB_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.db_dir, BUFSIZE, "%s%sdb", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.script_dir && (SWITCH_GLOBAL_dirs.script_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_SCRIPT_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s", SWITCH_SCRIPT_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.script_dir, BUFSIZE, "%s%sscripts", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.htdocs_dir && (SWITCH_GLOBAL_dirs.htdocs_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_HTDOCS_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s", SWITCH_HTDOCS_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.htdocs_dir, BUFSIZE, "%s%shtdocs", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.grammar_dir && (SWITCH_GLOBAL_dirs.grammar_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_GRAMMAR_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s", SWITCH_GRAMMAR_DIR); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.grammar_dir, BUFSIZE, "%s%sgrammar", base_dir, SWITCH_PATH_SEPARATOR); +#endif + } + + if (!SWITCH_GLOBAL_dirs.temp_dir && (SWITCH_GLOBAL_dirs.temp_dir = (char *) malloc(BUFSIZE))) { +#ifdef SWITCH_TEMP_DIR + switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", SWITCH_TEMP_DIR); +#else +#ifdef WIN32 + GetTempPath(dwBufSize, lpPathBuffer); + lpPathBuffer[strlen(lpPathBuffer)-1] = 0; + switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer); +#else + switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp"); +#endif +#endif + } + + switch_assert(SWITCH_GLOBAL_dirs.base_dir); + switch_assert(SWITCH_GLOBAL_dirs.mod_dir); + switch_assert(SWITCH_GLOBAL_dirs.lib_dir); + switch_assert(SWITCH_GLOBAL_dirs.conf_dir); + switch_assert(SWITCH_GLOBAL_dirs.log_dir); + switch_assert(SWITCH_GLOBAL_dirs.run_dir); + switch_assert(SWITCH_GLOBAL_dirs.db_dir); + switch_assert(SWITCH_GLOBAL_dirs.script_dir); + switch_assert(SWITCH_GLOBAL_dirs.htdocs_dir); + switch_assert(SWITCH_GLOBAL_dirs.grammar_dir); + switch_assert(SWITCH_GLOBAL_dirs.recordings_dir); + switch_assert(SWITCH_GLOBAL_dirs.sounds_dir); + switch_assert(SWITCH_GLOBAL_dirs.temp_dir); +} + + +SWITCH_DECLARE(int32_t) set_low_priority(void) +{ + + +#ifdef WIN32 + SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); +#else +#ifdef USE_SCHED_SETSCHEDULER + /* + * Try to use a normal scheduler + */ + struct sched_param sched = { 0 }; + sched.sched_priority = 0; + if (sched_setscheduler(0, SCHED_OTHER, &sched)) { + return -1; + } +#endif + +#ifdef HAVE_SETPRIORITY + /* + * setpriority() works on FreeBSD (6.2), nice() doesn't + */ + if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#else + if (nice(19) != 19) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#endif +#endif + + return 0; +} + +SWITCH_DECLARE(int32_t) set_realtime_priority(void) +{ +#ifdef WIN32 + SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); +#else +#ifdef USE_SCHED_SETSCHEDULER + /* + * Try to use a round-robin scheduler + * with a fallback if that does not work + */ + struct sched_param sched = { 0 }; + sched.sched_priority = SWITCH_PRI_LOW; + if (sched_setscheduler(0, SCHED_FIFO, &sched)) { + sched.sched_priority = 0; + if (sched_setscheduler(0, SCHED_OTHER, &sched)) { + return -1; + } + } +#endif + + + +#ifdef HAVE_SETPRIORITY + /* + * setpriority() works on FreeBSD (6.2), nice() doesn't + */ + if (setpriority(PRIO_PROCESS, getpid(), -10) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#else + if (nice(-10) != -10) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n"); + return -1; + } +#endif +#endif + return 0; +} + +SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void) +{ + return runtime.cpu_count; +} + +SWITCH_DECLARE(int32_t) set_normal_priority(void) +{ + return 0; +} + +SWITCH_DECLARE(int32_t) set_auto_priority(void) +{ +#ifndef WIN32 + runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); +#else + SYSTEM_INFO sysinfo; + GetSystemInfo( &sysinfo ); + runtime.cpu_count = sysinfo.dwNumberOfProcessors; +#endif + + if (!runtime.cpu_count) runtime.cpu_count = 1; + + /* If we have more than 1 cpu, we should use realtime priority so we can have priority threads */ + if (runtime.cpu_count > 1) { + return set_realtime_priority(); + } + + return 0; +} + +SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group) +{ +#ifndef WIN32 + uid_t runas_uid = 0; + gid_t runas_gid = 0; + struct passwd *runas_pw = NULL; + + if (user) { + /* + * Lookup user information in the system's db + */ + runas_pw = getpwnam(user); + if (!runas_pw) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown user \"%s\"\n", user); + return -1; + } + runas_uid = runas_pw->pw_uid; + } + + if (group) { + struct group *gr = NULL; + + /* + * Lookup group information in the system's db + */ + gr = getgrnam(group); + if (!gr) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unknown group \"%s\"\n", group); + return -1; + } + runas_gid = gr->gr_gid; + } + + if (runas_uid && getuid() == runas_uid && (!runas_gid || runas_gid == getgid())) { + /* already running as the right user and group, nothing to do! */ + return 0; + } + + if (runas_uid) { +#ifdef HAVE_SETGROUPS + /* + * Drop all group memberships prior to changing anything + * or else we're going to inherit the parent's list of groups + * (which is not what we want...) + */ + if (setgroups(0, NULL) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to drop group access list\n"); + return -1; + } +#endif + if (runas_gid) { + /* + * A group has been passed, switch to it + * (without loading the user's other groups) + */ + if (setgid(runas_gid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); + return -1; + } + } else { + /* + * No group has been passed, use the user's primary group in this case + */ + if (setgid(runas_pw->pw_gid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change gid!\n"); + return -1; + } +#ifdef HAVE_INITGROUPS + /* + * Set all the other groups the user is a member of + * (This can be really useful for fine-grained access control) + */ + if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to set group access list for user\n"); + return -1; + } +#endif + } + + /* + * Finally drop all privileges by switching to the new userid + */ + if (setuid(runas_uid) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n"); + return -1; + } + } +#endif + return 0; +} + +SWITCH_DECLARE(void) switch_core_runtime_loop(int bg) +{ +#ifdef WIN32 + HANDLE shutdown_event; + char path[256] = ""; +#endif + if (bg) { + bg = 0; +#ifdef WIN32 + switch_snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); + shutdown_event = CreateEvent(NULL, FALSE, FALSE, path); + if (shutdown_event) { + WaitForSingleObject(shutdown_event, INFINITE); + } +#else + runtime.running = 1; + while (runtime.running) { + switch_yield(1000000); + } +#endif + } else { + /* wait for console input */ + switch_console_loop(); + } +} + +SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext) +{ + if (!ext) { + return NULL; + } + return (const char *) switch_core_hash_find(runtime.mime_types, ext); +} + + +SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void) +{ + return switch_hash_first(NULL, runtime.mime_types); +} + +SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext) +{ + const char *check; + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_assert(type); + switch_assert(ext); + + check = (const char *) switch_core_hash_find(runtime.mime_types, ext); + + if (!check) { + char *ptype = switch_core_permanent_strdup(type); + char *ext_list = strdup(ext); + int argc = 0; + char *argv[20] = { 0 }; + int x; + + switch_assert(ext_list); + + if ((argc = switch_separate_string(ext_list, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { + + for (x = 0; x < argc; x++) { + if (argv[x] && ptype) { + switch_core_hash_insert(runtime.mime_types, argv[x], ptype); + } + } + + status = SWITCH_STATUS_SUCCESS; + } + + free(ext_list); + } + + return status; +} + +static void load_mime_types(void) +{ + char *cf = "mime.types"; + FILE *fd = NULL; + char *line_buf = NULL; + switch_size_t llen = 0; + char *mime_path = NULL; + + mime_path = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.conf_dir, cf); + switch_assert(mime_path); + + fd = fopen(mime_path, "rb"); + + if (fd == NULL) { + goto end; + } + + while ((switch_fp_read_dline(fd, &line_buf, &llen))) { + char *p; + char *type = line_buf; + + if (*line_buf == '#') { + continue; + } + + if ((p = strchr(line_buf, '\r')) || (p = strchr(line_buf, '\n'))) { + *p = '\0'; + } + + if ((p = strchr(type, '\t')) || (p = strchr(type, ' '))) { + *p++ = '\0'; + + while (*p == ' ' || *p == '\t') { + p++; + } + + switch_core_mime_add_type(type, p); + } + + } + + switch_safe_free(line_buf); + + if (fd) { + fclose(fd); + fd = NULL; + } + + end: + + switch_safe_free(mime_path); + +} + +SWITCH_DECLARE(void) switch_core_setrlimits(void) +{ +#ifdef HAVE_SETRLIMIT + struct rlimit rlp; + + /* + Setting the stack size on FreeBSD results in an instant crash. + + If anyone knows how to fix this, + feel free to submit a patch to http://jira.freeswitch.org + */ + +#ifndef __FreeBSD__ + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = SWITCH_THREAD_STACKSIZE; + rlp.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; + setrlimit(RLIMIT_STACK, &rlp); +#endif + + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = 999999; + rlp.rlim_max = 999999; + setrlimit(RLIMIT_NOFILE, &rlp); + + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = RLIM_INFINITY; + rlp.rlim_max = RLIM_INFINITY; + + setrlimit(RLIMIT_CPU, &rlp); + setrlimit(RLIMIT_DATA, &rlp); + setrlimit(RLIMIT_FSIZE, &rlp); +#ifdef RLIMIT_NPROC + setrlimit(RLIMIT_NPROC, &rlp); +#endif +#ifdef RLIMIT_RTPRIO + setrlimit(RLIMIT_RTPRIO, &rlp); +#endif + +#if !defined(__OpenBSD__) && !defined(__NetBSD__) + setrlimit(RLIMIT_AS, &rlp); +#endif +#endif + return; +} + +typedef struct { + switch_memory_pool_t *pool; + switch_hash_t *hash; +} switch_ip_list_t; + +static switch_ip_list_t IP_LIST = { 0 }; + +SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token) +{ + switch_network_list_t *list; + ip_t ip, mask, net; + uint32_t bits; + char *ipv6 = strchr(ip_str,':'); + switch_bool_t ok = SWITCH_FALSE; + + switch_mutex_lock(runtime.global_mutex); + if (ipv6) { + switch_inet_pton(AF_INET6, ip_str, &ip); + } else { + switch_inet_pton(AF_INET, ip_str, &ip); + ip.v4 = htonl(ip.v4); + } + + if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) { + if (ipv6) { + ok = switch_network_list_validate_ip6_token(list, ip, token); + } else { + ok = switch_network_list_validate_ip_token(list, ip.v4, token); + } + } else if (strchr(list_name, '/')) { + if (strchr(list_name, ',')) { + char *list_name_dup = strdup(list_name); + char *argv[32]; + int argc; + + switch_assert(list_name_dup); + + if ((argc = switch_separate_string(list_name_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { + int i; + for (i = 0; i < argc; i++) { + switch_parse_cidr(argv[i], &net, &mask, &bits); + if (ipv6) { + if ((ok = switch_testv6_subnet(ip, net, mask))){ + break; + } + } else { + if ((ok = switch_test_subnet(ip.v4, net.v4, mask.v4))) { + break; + } + } + } + } + free(list_name_dup); + } else { + switch_parse_cidr(list_name, &net, &mask, &bits); + ok = switch_test_subnet(ip.v4, net.v4, mask.v4); + } + } + switch_mutex_unlock(runtime.global_mutex); + + return ok; +} + + +SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload) +{ + switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL; + switch_network_list_t *rfc_list, *list; + char guess_ip[16] = ""; + int mask = 0; + char guess_mask[16] = ""; + char *tmp_name; + struct in_addr in; + + switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); + in.s_addr = mask; + switch_set_string(guess_mask, inet_ntoa(in)); + + switch_mutex_lock(runtime.global_mutex); + + if (IP_LIST.hash) { + switch_core_hash_destroy(&IP_LIST.hash); + } + + if (IP_LIST.pool) { + switch_core_destroy_memory_pool(&IP_LIST.pool); + } + + memset(&IP_LIST, 0, sizeof(IP_LIST)); + switch_core_new_memory_pool(&IP_LIST.pool); + switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool); + + + tmp_name = "rfc1918.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "wan.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_TRUE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (allow)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "nat.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + if (switch_network_list_add_host_mask(rfc_list, guess_ip, guess_mask, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (deny) to list %s\n", guess_ip, guess_mask, tmp_name); + } + switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_TRUE); + switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "loopback.auto"; + switch_network_list_create(&rfc_list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + switch_network_list_add_cidr(rfc_list, "127.0.0.0/8", SWITCH_TRUE); + switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); + + tmp_name = "localnet.auto"; + switch_network_list_create(&list, tmp_name, SWITCH_FALSE, IP_LIST.pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (deny)\n", tmp_name); + + if (switch_network_list_add_host_mask(list, guess_ip, guess_mask, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s/%s (allow) to list %s\n", guess_ip, guess_mask, tmp_name); + } + switch_core_hash_insert(IP_LIST.hash, tmp_name, list); + + + if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) { + if ((x_lists = switch_xml_child(cfg, "network-lists"))) { + for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) { + const char *name = switch_xml_attr(x_list, "name"); + const char *dft = switch_xml_attr(x_list, "default"); + switch_bool_t default_type = SWITCH_TRUE; + + if (zstr(name)) { + continue; + } + + if (dft) { + default_type = switch_true(dft); + } + + if (switch_network_list_create(&list, name, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) { + abort(); + } + + if (reload) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny"); + } + + + for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) { + const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL; + switch_bool_t ok = default_type; + const char *type = switch_xml_attr(x_node, "type"); + + if (type) { + ok = switch_true(type); + } + + cidr = switch_xml_attr(x_node, "cidr"); + host = switch_xml_attr(x_node, "host"); + mask = switch_xml_attr(x_node, "mask"); + domain = switch_xml_attr(x_node, "domain"); + + if (domain) { + switch_event_t *my_params = NULL; + switch_xml_t x_domain, xml_root; + switch_xml_t gt, gts, ut, uts; + + switch_event_create(&my_params, SWITCH_EVENT_GENERAL); + switch_assert(my_params); + switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain); + switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list"); + + if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain); + switch_event_destroy(&my_params); + continue; + } + + switch_event_destroy(&my_params); + + for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) { + const char *user_cidr = switch_xml_attr(ut, "cidr"); + const char *id = switch_xml_attr(ut, "id"); + + if (id && user_cidr) { + char *token = switch_mprintf("%s@%s", id, domain); + switch_assert(token); + switch_network_list_add_cidr_token(list, user_cidr, ok, token); + free(token); + } + } + + for (gts = switch_xml_child(x_domain, "groups"); gts; gts = gts->next) { + for (gt = switch_xml_child(gts, "group"); gt; gt = gt->next) { + for (uts = switch_xml_child(gt, "users"); uts; uts = uts->next) { + for (ut = switch_xml_child(uts, "user"); ut; ut = ut->next) { + const char *user_cidr = switch_xml_attr(ut, "cidr"); + const char *id = switch_xml_attr(ut, "id"); + + if (id && user_cidr) { + char *token = switch_mprintf("%s@%s", id, domain); + switch_assert(token); + switch_network_list_add_cidr_token(list, user_cidr, ok, token); + free(token); + } + } + } + } + } + + switch_xml_free(xml_root); + } else if (cidr) { + if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name); + } + } else if (host && mask) { + if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, + "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name); + } + } + + switch_core_hash_insert(IP_LIST.hash, name, list); + } + } + } + + switch_xml_free(xml); + } + + switch_mutex_unlock(runtime.global_mutex); +} + +SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration) +{ + if (duration) { + if (duration > SWITCH_MAX_DTMF_DURATION) { + duration = SWITCH_MAX_DTMF_DURATION; + } + if (duration < SWITCH_MIN_DTMF_DURATION) { + duration = SWITCH_MIN_DTMF_DURATION; + } + runtime.max_dtmf_duration = duration; + if (duration < runtime.min_dtmf_duration) { + runtime.min_dtmf_duration = duration; + } + } + return runtime.max_dtmf_duration; +} + +SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration) +{ + if (duration) { + if (duration < SWITCH_MIN_DTMF_DURATION) { + duration = SWITCH_MIN_DTMF_DURATION; + } + if (duration > SWITCH_MAX_DTMF_DURATION) { + duration = SWITCH_MAX_DTMF_DURATION; + } + runtime.default_dtmf_duration = duration; + + if (duration < runtime.min_dtmf_duration) { + runtime.min_dtmf_duration = duration; + } + + if (duration > runtime.max_dtmf_duration) { + runtime.max_dtmf_duration = duration; + } + + } + return runtime.default_dtmf_duration; +} + +SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration) +{ + if (duration) { + if (duration < SWITCH_MIN_DTMF_DURATION) { + duration = SWITCH_MIN_DTMF_DURATION; + } + if (duration > SWITCH_MAX_DTMF_DURATION) { + duration = SWITCH_MAX_DTMF_DURATION; + } + + runtime.min_dtmf_duration = duration; + + if (duration > runtime.max_dtmf_duration) { + runtime.max_dtmf_duration = duration; + } + } + return runtime.min_dtmf_duration; +} + +SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + if (cpu > -1) { + +#ifdef HAVE_CPU_SET_MACROS + cpu_set_t set; + + CPU_ZERO(&set); + CPU_SET(cpu, &set); + + if (!sched_setaffinity(0, sizeof(set), &set)) { + status = SWITCH_STATUS_SUCCESS; + } + +#else +#if WIN32 + if (SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR) cpu)) { + status = SWITCH_STATUS_SUCCESS; + } +#endif +#endif + } + + return status; +} + + +static void switch_core_set_serial(void) +{ + char buf[13] = ""; + char path[256]; + + int fd = -1, write_fd = -1; + switch_ssize_t bytes = 0; + + switch_snprintf(path, sizeof(path), "%s%sfreeswitch.serial", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR); + + + if ((fd = open(path, O_RDONLY, 0)) < 0) { + char *ip = switch_core_get_variable_dup("local_ip_v4"); + uint32_t ipi = 0; + switch_byte_t *byte; + int i = 0; + + if (ip) { + switch_inet_pton(AF_INET, ip, &ipi); + free(ip); + ip = NULL; + } + + + byte = (switch_byte_t *) & ipi; + + for (i = 0; i < 8; i += 2) { + switch_snprintf(buf + i, sizeof(buf) - i, "%0.2x", *byte); + byte++; + } + + switch_stun_random_string(buf + 8, 4, "0123456789abcdef"); + + if ((write_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) >= 0) { + bytes = write(write_fd, buf, sizeof(buf)); + bytes++; + close(write_fd); + write_fd = -1; + } + } else { + bytes = read(fd, buf, sizeof(buf)); + close(fd); + fd = -1; + } + + switch_core_set_variable("switch_serial", buf); +} + + +SWITCH_DECLARE(int) switch_core_test_flag(int flag) +{ + return switch_test_flag((&runtime), flag); +} + + +SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err) +{ + switch_uuid_t uuid; + char guess_ip[256]; + int mask = 0; + struct in_addr in; + + + if (runtime.runlevel > 0) { + /* one per customer */ + return SWITCH_STATUS_SUCCESS; + } + + memset(&runtime, 0, sizeof(runtime)); + gethostname(runtime.hostname, sizeof(runtime.hostname)); + + runtime.max_db_handles = 50; + runtime.db_handle_timeout = 5000000; + + runtime.runlevel++; + runtime.dummy_cng_frame.data = runtime.dummy_data; + runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); + runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); + runtime.dbname = "core"; + switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG); + switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); + switch_set_flag((&runtime), SCF_CLEAR_SQL); + switch_set_flag((&runtime), SCF_API_EXPANSION); + switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); +#ifdef WIN32 + switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); +#endif + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + runtime.hard_log_level = SWITCH_LOG_DEBUG; + runtime.mailer_app = "sendmail"; + runtime.mailer_app_args = "-t"; + runtime.max_dtmf_duration = SWITCH_MAX_DTMF_DURATION; + runtime.default_dtmf_duration = SWITCH_DEFAULT_DTMF_DURATION; + runtime.min_dtmf_duration = SWITCH_MIN_DTMF_DURATION; + runtime.odbc_dbtype = DBTYPE_DEFAULT; + runtime.dbname = NULL; +#ifndef WIN32 + runtime.cpu_count = sysconf (_SC_NPROCESSORS_ONLN); +#else + { + SYSTEM_INFO sysinfo; + GetSystemInfo( &sysinfo ); + runtime.cpu_count = sysinfo.dwNumberOfProcessors; + } +#endif + + if (!runtime.cpu_count) runtime.cpu_count = 1; + + + /* INIT APR and Create the pool context */ + if (apr_initialize() != SWITCH_STATUS_SUCCESS) { + *err = "FATAL ERROR! Could not initialize APR\n"; + return SWITCH_STATUS_MEMERR; + } + + if (!(runtime.memory_pool = switch_core_memory_init())) { + *err = "FATAL ERROR! Could not allocate memory pool\n"; + return SWITCH_STATUS_MEMERR; + } + switch_assert(runtime.memory_pool != NULL); + + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir, SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool); + + + switch_mutex_init(&runtime.uuid_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + + switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + + switch_mutex_init(&runtime.session_hash_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + switch_mutex_init(&runtime.global_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool); + + switch_thread_rwlock_create(&runtime.global_var_rwlock, runtime.memory_pool); + switch_core_set_globals(); + switch_core_session_init(runtime.memory_pool); + switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); + switch_core_hash_init(&runtime.mime_types, runtime.memory_pool); + switch_core_hash_init_case(&runtime.ptimes, runtime.memory_pool, SWITCH_FALSE); + load_mime_types(); + runtime.flags |= flags; + runtime.sps_total = 30; + + *err = NULL; + + if (console) { + runtime.console = stdout; + } + + switch_ssl_init_ssl_locks(); + switch_curl_init(); + + switch_core_set_variable("hostname", runtime.hostname); + switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); + switch_core_set_variable("local_ip_v4", guess_ip); + in.s_addr = mask; + switch_core_set_variable("local_mask_v4", inet_ntoa(in)); + + + switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET6); + switch_core_set_variable("local_ip_v6", guess_ip); + switch_core_set_variable("base_dir", SWITCH_GLOBAL_dirs.base_dir); + switch_core_set_variable("recordings_dir", SWITCH_GLOBAL_dirs.recordings_dir); + switch_core_set_variable("sound_prefix", SWITCH_GLOBAL_dirs.sounds_dir); + switch_core_set_variable("sounds_dir", SWITCH_GLOBAL_dirs.sounds_dir); + switch_core_set_serial(); + + switch_console_init(runtime.memory_pool); + switch_event_init(runtime.memory_pool); + + if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) { + apr_terminate(); + return SWITCH_STATUS_MEMERR; + } + + if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { + switch_nat_init(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_NAT_MAPPING)); + } + + switch_log_init(runtime.memory_pool, runtime.colorize_console); + + if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; + + runtime.tipping_point = 0; + runtime.timer_affinity = -1; + runtime.microseconds_per_tick = 20000; + + switch_load_core_config("switch.conf"); + + switch_core_state_machine_init(runtime.memory_pool); + + if (switch_core_sqldb_start(runtime.memory_pool, switch_test_flag((&runtime), SCF_USE_SQL) ? SWITCH_TRUE : SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { + *err = "Error activating database"; + return SWITCH_STATUS_FALSE; + } + + switch_scheduler_task_thread_start(); + + switch_nat_late_init(); + + switch_rtp_init(runtime.memory_pool); + + runtime.running = 1; + runtime.initiated = switch_time_now(); + runtime.mono_initiated = switch_mono_micro_time_now(); + + switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL); + + switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD); + + switch_uuid_get(&uuid); + switch_uuid_format(runtime.uuid_str, &uuid); + switch_core_set_variable("core_uuid", runtime.uuid_str); + + + return SWITCH_STATUS_SUCCESS; +} + + +#ifndef WIN32 +static void handle_SIGCHLD(int sig) +{ + int status = 0; + + wait(&status); + return; +} +#endif + +#ifdef TRAP_BUS +static void handle_SIGBUS(int sig) +{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Sig BUS!\n"); + return; +} +#endif + +static void handle_SIGHUP(int sig) +{ + if (sig) { + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Trapped-Signal", "HUP"); + switch_event_fire(&event); + } + } + return; +} + + +SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number) +{ + uint32_t *p; + + if ((p = switch_core_hash_find(runtime.ptimes, name))) { + return *p; + } + + return 20; +} + +static uint32_t d_30 = 30; + +static void switch_load_core_config(const char *file) +{ + switch_xml_t xml = NULL, cfg = NULL; + + switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); + switch_core_hash_insert(runtime.ptimes, "G723", &d_30); + + if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) { + switch_xml_t settings, param; + + if ((settings = switch_xml_child(cfg, "default-ptimes"))) { + for (param = switch_xml_child(settings, "codec"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "ptime"); + + if (!zstr(var) && !zstr(val)) { + uint32_t *p; + uint32_t v = switch_atoul(val); + + if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var); + continue; + } + + if (v == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var); + continue; + } + + p = switch_core_alloc(runtime.memory_pool, sizeof(*p)); + *p = v; + switch_core_hash_insert(runtime.ptimes, var, p); + } + + } + } + + if ((settings = switch_xml_child(cfg, "settings"))) { + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "value"); + + if (!strcasecmp(var, "loglevel")) { + int level; + if (*val > 47 && *val < 58) { + level = atoi(val); + } else { + level = switch_log_str2level(val); + } + + if (level != SWITCH_LOG_INVALID) { + switch_core_session_ctl(SCSC_LOGLEVEL, &level); + } +#ifdef HAVE_SETRLIMIT + } else if (!strcasecmp(var, "dump-cores") && switch_true(val)) { + struct rlimit rlp; + memset(&rlp, 0, sizeof(rlp)); + rlp.rlim_cur = RLIM_INFINITY; + rlp.rlim_max = RLIM_INFINITY; + setrlimit(RLIMIT_CORE, &rlp); +#endif + } else if (!strcasecmp(var, "debug-level")) { + int tmp = atoi(val); + if (tmp > -1 && tmp < 11) { + switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp); + } + } else if (!strcasecmp(var, "max-db-handles")) { + long tmp = atol(val); + + if (tmp > 4 && tmp < 5001) { + runtime.max_db_handles = (uint32_t) tmp; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-db-handles must be between 5 and 5000\n"); + } + } else if (!strcasecmp(var, "db-handle-timeout")) { + long tmp = atol(val); + + if (tmp > 0 && tmp < 5001) { + runtime.db_handle_timeout = (uint32_t) tmp * 1000000; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "db-handle-timeout must be between 1 and 5000\n"); + } + + } else if (!strcasecmp(var, "multiple-registrations")) { + runtime.multiple_registrations = switch_true(val); + } else if (!strcasecmp(var, "auto-create-schemas")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); + } else { + switch_clear_flag((&runtime), SCF_AUTO_SCHEMAS); + } + } else if (!strcasecmp(var, "session-thread-pool")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_SESSION_THREAD_POOL); + } else { + switch_clear_flag((&runtime), SCF_SESSION_THREAD_POOL); + } + } else if (!strcasecmp(var, "auto-clear-sql")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_CLEAR_SQL); + } else { + switch_clear_flag((&runtime), SCF_CLEAR_SQL); + } + } else if (!strcasecmp(var, "api-expansion")) { + if (switch_true(val)) { + switch_set_flag((&runtime), SCF_API_EXPANSION); + } else { + switch_clear_flag((&runtime), SCF_API_EXPANSION); + } + } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) { + switch_set_flag((&runtime), SCF_EARLY_HANGUP); + } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) { + runtime.colorize_console = SWITCH_TRUE; + } else if (!strcasecmp(var, "core-db-pre-trans-execute") && !zstr(val)) { + runtime.core_db_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "core-db-post-trans-execute") && !zstr(val)) { + runtime.core_db_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "core-db-inner-pre-trans-execute") && !zstr(val)) { + runtime.core_db_inner_pre_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "core-db-inner-post-trans-execute") && !zstr(val)) { + runtime.core_db_inner_post_trans_execute = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) { + runtime.mailer_app = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "mailer-app-args") && val) { + runtime.mailer_app_args = switch_core_strdup(runtime.memory_pool, val); + } else if (!strcasecmp(var, "sessions-per-second") && !zstr(val)) { + switch_core_sessions_per_second(atoi(val)); + } else if (!strcasecmp(var, "max-dtmf-duration") && !zstr(val)) { + int tmp = atoi(val); + if (tmp > 0) { + switch_core_max_dtmf_duration((uint32_t) tmp); + } + } else if (!strcasecmp(var, "min-dtmf-duration") && !zstr(val)) { + int tmp = atoi(val); + if (tmp > 0) { + switch_core_min_dtmf_duration((uint32_t) tmp); + } + } else if (!strcasecmp(var, "default-dtmf-duration") && !zstr(val)) { + int tmp = atoi(val); + if (tmp > 0) { + switch_core_default_dtmf_duration((uint32_t) tmp); + } + } else if (!strcasecmp(var, "enable-use-system-time")) { + switch_time_set_use_system_time(switch_true(val)); + } else if (!strcasecmp(var, "enable-monotonic-timing")) { + switch_time_set_monotonic(switch_true(val)); + } else if (!strcasecmp(var, "enable-softtimer-timerfd")) { + switch_time_set_timerfd(switch_true(val)); + } else if (!strcasecmp(var, "enable-clock-nanosleep")) { + switch_time_set_nanosleep(switch_true(val)); + } else if (!strcasecmp(var, "enable-cond-yield")) { + switch_time_set_cond_yield(switch_true(val)); + } else if (!strcasecmp(var, "enable-timer-matrix")) { + switch_time_set_matrix(switch_true(val)); + } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) { + switch_core_session_limit(atoi(val)); + } else if (!strcasecmp(var, "verbose-channel-events") && !zstr(val)) { + int v = switch_true(val); + if (v) { + switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); + } else { + switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); + } + } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) { +#ifdef WIN32 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n"); +#else + int v = switch_true(val); + if (v) { + switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } else { + switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } +#endif + } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) { + switch_core_min_idle_cpu(atof(val)); + } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) { + runtime.tipping_point = atoi(val); + } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) { + int tmp = atoi(val); + + + if (tmp > runtime.cpu_count / 2) { + tmp = runtime.cpu_count / 2; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n", + runtime.cpu_count / 2); + } + + if (tmp < 1) { + tmp = 1; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n"); + } + + switch_event_launch_dispatch_threads(tmp); + + } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) { + runtime.microseconds_per_tick = 1000; + } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) { + if (!strcasecmp(val, "disabled")) { + runtime.timer_affinity = -1; + } else { + runtime.timer_affinity = atoi(val); + } + } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) { + 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() || switch_pgsql_available()) { + runtime.odbc_dsn = switch_core_strdup(runtime.memory_pool, val); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC AND PGSQL ARE NOT AVAILABLE!\n"); + } + } else if (!strcasecmp(var, "core-non-sqlite-db-required") && !zstr(val)) { + switch_set_flag((&runtime), SCF_CORE_NON_SQLITE_DB_REQ); + } else if (!strcasecmp(var, "core-dbtype") && !zstr(val)) { + if (!strcasecmp(val, "MSSQL")) { + runtime.odbc_dbtype = DBTYPE_MSSQL; + } else { + runtime.odbc_dbtype = DBTYPE_DEFAULT; + } +#ifdef ENABLE_ZRTP + } else if (!strcasecmp(var, "rtp-enable-zrtp")) { + switch_core_set_variable("zrtp_enabled", val); +#endif + } else if (!strcasecmp(var, "switchname") && !zstr(val)) { + runtime.switchname = switch_core_strdup(runtime.memory_pool, val); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Set switchname to %s\n", runtime.switchname); + } + } + } + + if ((settings = switch_xml_child(cfg, "variables"))) { + for (param = switch_xml_child(settings, "variable"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "value"); + if (var && val) { + switch_core_set_variable(var, val); + } + } + } + + switch_xml_free(xml); + } + + +} + +SWITCH_DECLARE(const char *) switch_core_banner(void) +{ + + return ("\n" + ".=============================================================.\n" + "| _____ ______ _____ _____ ____ _ _ |\n" + "| | ___| __ ___ ___/ ___\\ \\ / /_ _|_ _/ ___| | | | |\n" + "| | |_ | '__/ _ \\/ _ \\___ \\\\ \\ /\\ / / | | | || | | |_| | |\n" + "| | _|| | | __/ __/___) |\\ V V / | | | || |___| _ | |\n" + "| |_| |_| \\___|\\___|____/ \\_/\\_/ |___| |_| \\____|_| |_| |\n" + "| |\n" + ".=============================================================." + "\n" + + "| Anthony Minessale II, Michael Jerris, Brian West, Others |\n" + "| FreeSWITCH (http://www.freeswitch.org) |\n" + "| Paypal Donations Appreciated: paypal@freeswitch.org |\n" + "| Brought to you by ClueCon http://www.cluecon.com/ |\n" + ".=============================================================.\n" + "\n"); +} + + +SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t flags, switch_bool_t console, const char **err) +{ + switch_event_t *event; + char *cmd; + int x = 0; + const char *use = NULL; +#include "cc.h" + + + if (switch_core_init(flags, console, err) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_GENERR; + } + + if (runtime.runlevel > 1) { + /* one per customer */ + return SWITCH_STATUS_SUCCESS; + } + + runtime.runlevel++; + + switch_core_set_signal_handlers(); + switch_load_network_lists(SWITCH_FALSE); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n"); + if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { + *err = "Cannot load modules"; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err); + return SWITCH_STATUS_GENERR; + } + + switch_load_network_lists(SWITCH_FALSE); + + switch_load_core_config("post_load_switch.conf"); + + switch_core_set_signal_handlers(); + + if (switch_event_create(&event, SWITCH_EVENT_STARTUP) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready"); + switch_event_fire(&event); + } + + switch_core_screen_size(&x, NULL); + + use = (x > 100) ? cc : cc_s; + +#ifdef WIN32 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s\n\n", switch_core_banner(), use); +#else + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s%s%s%s\n\n", + SWITCH_SEQ_DEFAULT_COLOR, + SWITCH_SEQ_FYELLOW, SWITCH_SEQ_BBLUE, + switch_core_banner(), + use, SWITCH_SEQ_DEFAULT_COLOR); + +#endif + + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, + "\nFreeSWITCH Version %s (%s)\n\nFreeSWITCH Started\nMax Sessions [%u]\nSession Rate [%d]\nSQL [%s]\n", + SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN, + switch_core_session_limit(0), + switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); + + + if (x < 160) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\n[This app Best viewed at 160x60 or more..]\n"); + } + + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); + + if ((cmd = switch_core_get_variable_dup("api_on_startup"))) { + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + switch_console_execute(cmd, 0, &stream); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Startup command [%s] executed. Output:\n%s\n", cmd, (char *)stream.data); + free(stream.data); + free(cmd); + } + + return SWITCH_STATUS_SUCCESS; + +} + +SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_core_time_duration_t *duration) +{ + switch_time_t temp = total_ms / 1000; + memset(duration, 0, sizeof(*duration)); + duration->mms = (uint32_t) (total_ms % 1000); + duration->ms = (uint32_t) (temp % 1000); + temp = temp / 1000; + duration->sec = (uint32_t) (temp % 60); + temp = temp / 60; + duration->min = (uint32_t) (temp % 60); + temp = temp / 60; + duration->hr = (uint32_t) (temp % 24); + temp = temp / 24; + duration->day = (uint32_t) (temp % 365); + duration->yr = (uint32_t) (temp / 365); +} + +SWITCH_DECLARE(switch_time_t) switch_core_uptime(void) +{ + return switch_mono_micro_time_now() - runtime.mono_initiated; +} + + +#ifdef _MSC_VER +static void win_shutdown(void) +{ + + HANDLE shutdown_event; + char path[512]; + /* for windows we need the event to signal for shutting down a background FreeSWITCH */ + snprintf(path, sizeof(path), "Global\\Freeswitch.%d", getpid()); + + /* open the event so we can signal it */ + shutdown_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, path); + + if (shutdown_event) { + /* signal the event to shutdown */ + SetEvent(shutdown_event); + /* cleanup */ + CloseHandle(shutdown_event); + } +} +#endif + +SWITCH_DECLARE(void) switch_core_set_signal_handlers(void) +{ + /* set signal handlers */ + signal(SIGINT, SIG_IGN); +#ifndef WIN32 + if (switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC)) { + signal(SIGCHLD, SIG_DFL); + } else { + signal(SIGCHLD, handle_SIGCHLD); + } +#endif +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif +#ifdef SIGQUIT + signal(SIGQUIT, SIG_IGN); +#endif +#ifdef SIGPOLL + signal(SIGPOLL, SIG_IGN); +#endif +#ifdef SIGIO + signal(SIGIO, SIG_IGN); +#endif +#ifdef TRAP_BUS + signal(SIGBUS, handle_SIGBUS); +#endif +#ifdef SIGUSR1 + signal(SIGUSR1, handle_SIGHUP); +#endif + signal(SIGHUP, handle_SIGHUP); +} + +SWITCH_DECLARE(uint32_t) switch_core_debug_level(void) +{ + return runtime.debug_level; +} + + +SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val) +{ + int *intval = (int *) val; + int oldintval = 0, newintval = 0; + + if (intval) { + oldintval = *intval; + } + + if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) { + return -1; + } + + switch (cmd) { + case SCSC_RECOVER: + { + char *arg = (char *) val; + char *tech = NULL, *prof = NULL; + int r, flush = 0; + + if (!zstr(arg)) { + tech = strdup(arg); + + if ((prof = strchr(tech, ':'))) { + *prof++ = '\0'; + } + + if (!strcasecmp(tech, "flush")) { + flush++; + + if (prof) { + tech = prof; + if ((prof = strchr(tech, ':'))) { + *prof++ = '\0'; + } + } + } + + } + + if (flush) { + switch_core_recovery_flush(tech, prof); + r = -1; + } else { + r = switch_core_recovery_recover(tech, prof); + } + + switch_safe_free(tech); + return r; + + } + break; + case SCSC_DEBUG_SQL: + { + if (switch_test_flag((&runtime), SCF_DEBUG_SQL)) { + switch_clear_flag((&runtime), SCF_DEBUG_SQL); + newintval = 0; + } else { + switch_set_flag((&runtime), SCF_DEBUG_SQL); + newintval = 1; + } + } + break; + case SCSC_VERBOSE_EVENTS: + if (intval) { + if (oldintval > -1) { + if (oldintval) { + switch_set_flag((&runtime), SCF_VERBOSE_EVENTS); + } else { + switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS); + } + } + newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS); + } + break; + case SCSC_API_EXPANSION: + if (intval) { + if (oldintval > -1) { + if (oldintval) { + switch_set_flag((&runtime), SCF_API_EXPANSION); + } else { + switch_clear_flag((&runtime), SCF_API_EXPANSION); + } + } + newintval = switch_test_flag((&runtime), SCF_API_EXPANSION); + } + break; + case SCSC_THREADED_SYSTEM_EXEC: + if (intval) { + if (oldintval > -1) { + if (oldintval) { + switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } else { + switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } + } + newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC); + } + break; + case SCSC_CALIBRATE_CLOCK: + switch_time_calibrate_clock(); + break; + case SCSC_FLUSH_DB_HANDLES: + switch_cache_db_flush_handles(); + break; + case SCSC_SEND_SIGHUP: + handle_SIGHUP(1); + break; + case SCSC_SYNC_CLOCK: + switch_time_sync(); + newintval = 0; + break; + case SCSC_SYNC_CLOCK_WHEN_IDLE: + newintval = switch_core_session_sync_clock(); + break; + case SCSC_SQL: + if (oldintval) { + switch_core_sqldb_resume(); + } else { + switch_core_sqldb_pause(); + } + break; + case SCSC_PAUSE_ALL: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); + } + break; + case SCSC_PAUSE_INBOUND: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + } + break; + case SCSC_PAUSE_OUTBOUND: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + } + break; + case SCSC_HUPALL: + switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST); + break; + case SCSC_CANCEL_SHUTDOWN: + switch_clear_flag((&runtime), SCF_SHUTDOWN_REQUESTED); + break; + case SCSC_SAVE_HISTORY: + switch_console_save_history(); + break; + case SCSC_CRASH: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Declinatio Mortuus Obfirmo!\n"); + switch_console_save_history(); + abort(); + break; + case SCSC_SHUTDOWN_NOW: + switch_console_save_history(); + exit(0); + break; + case SCSC_SHUTDOWN_ELEGANT: + case SCSC_SHUTDOWN_ASAP: + { + int x = 19; + uint32_t count; + + switch_set_flag((&runtime), SCF_SHUTDOWN_REQUESTED); + if (cmd == SCSC_SHUTDOWN_ASAP) { + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + } + + while (runtime.running && switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED) && (count = switch_core_session_count())) { + switch_yield(500000); + if (++x == 20) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Shutdown in progress, %u session(s) remain.\nShutting down %s\n", + count, cmd == SCSC_SHUTDOWN_ASAP ? "ASAP" : "once there are no active calls."); + x = 0; + } + } + + if (switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED)) { + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); +#ifdef _MSC_VER + win_shutdown(); +#endif + + if (oldintval) { + switch_set_flag((&runtime), SCF_RESTART); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); +#ifdef _MSC_VER + fclose(stdin); +#endif + } + runtime.running = 0; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutdown Cancelled\n"); + switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); + } + } + break; + case SCSC_PAUSE_CHECK: + newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS); + break; + case SCSC_PAUSE_INBOUND_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + break; + case SCSC_PAUSE_OUTBOUND_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + break; + case SCSC_READY_CHECK: + newintval = switch_core_ready(); + break; + case SCSC_SHUTDOWN_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_SHUTDOWN_REQUESTED); + break; + case SCSC_SHUTDOWN: + +#ifdef _MSC_VER + win_shutdown(); +#endif + + if (oldintval) { + switch_set_flag((&runtime), SCF_RESTART); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); +#ifdef _MSC_VER + fclose(stdin); +#endif + } + runtime.running = 0; + break; + case SCSC_CHECK_RUNNING: + newintval = runtime.running; + break; + case SCSC_LOGLEVEL: + if (oldintval > -1) { + runtime.hard_log_level = oldintval; + } + + if (runtime.hard_log_level > SWITCH_LOG_DEBUG) { + runtime.hard_log_level = SWITCH_LOG_DEBUG; + } + newintval = runtime.hard_log_level; + break; + case SCSC_DEBUG_LEVEL: + if (oldintval > -1) { + if (oldintval > 10) + newintval = 10; + runtime.debug_level = oldintval; + } + newintval = runtime.debug_level; + break; + case SCSC_MIN_IDLE_CPU: + { + double *dval = (double *) val; + if (dval) { + *dval = switch_core_min_idle_cpu(*dval); + } + intval = NULL; + } + break; + case SCSC_MAX_SESSIONS: + newintval = switch_core_session_limit(oldintval); + break; + case SCSC_LAST_SPS: + newintval = runtime.sps_last; + break; + case SCSC_MAX_DTMF_DURATION: + newintval = switch_core_max_dtmf_duration(oldintval); + break; + case SCSC_MIN_DTMF_DURATION: + newintval = switch_core_min_dtmf_duration(oldintval); + break; + case SCSC_DEFAULT_DTMF_DURATION: + newintval = switch_core_default_dtmf_duration(oldintval); + break; + case SCSC_SPS: + switch_mutex_lock(runtime.throttle_mutex); + if (oldintval > 0) { + runtime.sps_total = oldintval; + } + newintval = runtime.sps_total; + switch_mutex_unlock(runtime.throttle_mutex); + break; + + case SCSC_RECLAIM: + switch_core_memory_reclaim_all(); + newintval = 0; + break; + } + + if (intval) { + *intval = newintval; + } + + + return 0; +} + +SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void) +{ + return runtime.flags; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) +{ + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down"); + switch_event_fire(&event); + } + + switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + switch_set_flag((&runtime), SCF_SHUTTING_DOWN); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n"); + switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n"); + + switch_loadable_module_shutdown(); + + switch_ssl_destroy_ssl_locks(); + + if (switch_test_flag((&runtime), SCF_USE_SQL)) { + switch_core_sqldb_stop(); + } + switch_scheduler_task_thread_stop(); + + switch_rtp_shutdown(); + + if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { + switch_nat_shutdown(); + } + switch_xml_destroy(); + switch_core_session_uninit(); + switch_console_shutdown(); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Closing Event Engine.\n"); + switch_event_shutdown(); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n"); + switch_log_shutdown(); + + switch_core_unset_variables(); + switch_core_memory_stop(); + + if (runtime.console && runtime.console != stdout && runtime.console != stderr) { + fclose(runtime.console); + runtime.console = NULL; + } + + switch_safe_free(SWITCH_GLOBAL_dirs.base_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.log_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.db_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.script_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.run_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir); + + switch_event_destroy(&runtime.global_vars); + switch_core_hash_destroy(&runtime.ptimes); + switch_core_hash_destroy(&runtime.mime_types); + + if (IP_LIST.hash) { + switch_core_hash_destroy(&IP_LIST.hash); + } + + if (IP_LIST.pool) { + switch_core_destroy_memory_pool(&IP_LIST.pool); + } + + if (runtime.memory_pool) { + apr_pool_destroy(runtime.memory_pool); + apr_terminate(); + } + + return switch_test_flag((&runtime), SCF_RESTART) ? SWITCH_STATUS_RESTART : SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen) +{ + const switch_management_interface_t *ptr; + switch_status_t status = SWITCH_STATUS_FALSE; + + if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) { + status = ptr->management_function(relative_oid, action, data, datalen); + } + + return status; +} + +SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void) +{ + switch_core_memory_reclaim_logger(); + switch_core_memory_reclaim_events(); + switch_core_memory_reclaim(); +} + + +struct system_thread_handle { + const char *cmd; + switch_thread_cond_t *cond; + switch_mutex_t *mutex; + switch_memory_pool_t *pool; + int ret; + int *fds; +}; + +static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj) +{ + struct system_thread_handle *sth = (struct system_thread_handle *) obj; + +#if 0 // if we are a luser we can never turn this back down, didn't we already set the stack size? +#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) + struct rlimit rlim; + + rlim.rlim_cur = SWITCH_SYSTEM_THREAD_STACKSIZE; + rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; + if (setrlimit(RLIMIT_STACK, &rlim) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); + } +#endif +#endif + + if (sth->fds) { + dup2(sth->fds[1], STDOUT_FILENO); + } + + sth->ret = system(sth->cmd); + +#if 0 +#if defined(HAVE_SETRLIMIT) && !defined(__FreeBSD__) + rlim.rlim_cur = SWITCH_THREAD_STACKSIZE; + rlim.rlim_max = SWITCH_SYSTEM_THREAD_STACKSIZE; + if (setrlimit(RLIMIT_STACK, &rlim) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setting stack size failed! (%s)\n", strerror(errno)); + } +#endif +#endif + + switch_mutex_lock(sth->mutex); + switch_thread_cond_signal(sth->cond); + switch_mutex_unlock(sth->mutex); + + switch_core_destroy_memory_pool(&sth->pool); + + return NULL; +} + + +static int switch_system_thread(const char *cmd, switch_bool_t wait) +{ + switch_thread_t *thread; + switch_threadattr_t *thd_attr; + int ret = 0; + struct system_thread_handle *sth; + switch_memory_pool_t *pool; + + if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); + return 1; + } + + if (!(sth = switch_core_alloc(pool, sizeof(struct system_thread_handle)))) { + switch_core_destroy_memory_pool(&pool); + return 1; + } + + sth->pool = pool; + sth->cmd = switch_core_strdup(pool, cmd); + + switch_thread_cond_create(&sth->cond, sth->pool); + switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool); + switch_mutex_lock(sth->mutex); + + switch_threadattr_create(&thd_attr, sth->pool); + switch_threadattr_stacksize_set(thd_attr, SWITCH_SYSTEM_THREAD_STACKSIZE); + switch_threadattr_detach_set(thd_attr, 1); + switch_thread_create(&thread, thd_attr, system_thread, sth, sth->pool); + + if (wait) { + switch_thread_cond_wait(sth->cond, sth->mutex); + ret = sth->ret; + } + switch_mutex_unlock(sth->mutex); + + return ret; +} + +SWITCH_DECLARE(int) switch_max_file_desc(void) +{ + int max = 0; + +#ifndef WIN32 +#if defined(HAVE_GETDTABLESIZE) + max = getdtablesize(); +#else + max = sysconf(_SC_OPEN_MAX); +#endif +#endif + + return max; + +} + +SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl) +{ + int open_max = switch_max_file_desc(); + int i, j; + + for (i = 3; i < open_max; i++) { + if (keep) { + for (j = 0; j < keep_ttl; j++) { + if (i == keep[j]) { + goto skip; + } + } + } + + close(i); + + skip: + + continue; + + } +} + + +#ifdef WIN32 +static int switch_system_fork(const char *cmd, switch_bool_t wait) +{ + return switch_system_thread(cmd, wait); +} + +SWITCH_DECLARE(pid_t) switch_fork(void) +{ + return -1; +} + + +#else + +SWITCH_DECLARE(pid_t) switch_fork(void) +{ + int i = fork(); + + if (!i) { + set_low_priority(); + } + + return i; +} + + + +static int switch_system_fork(const char *cmd, switch_bool_t wait) +{ + int pid; + char *dcmd = strdup(cmd); + + switch_core_set_signal_handlers(); + + pid = switch_fork(); + + if (pid) { + if (wait) { + waitpid(pid, NULL, 0); + } + free(dcmd); + } else { + switch_close_extra_files(NULL, 0); + + if (system(dcmd) == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to execute because of a command error : %s\n", dcmd); + } + free(dcmd); + exit(0); + } + + return 0; +} +#endif + + + +SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait) +{ + int (*sys_p)(const char *cmd, switch_bool_t wait); + + sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork; + + return sys_p(cmd, wait); + +} + + + +SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream) +{ +#ifdef WIN32 + return switch_system(cmd, SWITCH_TRUE); +#else + int fds[2], pid = 0; + + if (pipe(fds)) { + goto end; + } else { /* good to go */ + pid = switch_fork(); + + if (pid < 0) { /* ok maybe not */ + close(fds[0]); + close(fds[1]); + goto end; + } else if (pid) { /* parent */ + char buf[1024] = ""; + int bytes; + close(fds[1]); + while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) { + stream->raw_write_function(stream, (unsigned char *)buf, bytes); + } + close(fds[0]); + waitpid(pid, NULL, 0); + } else { /* child */ + switch_close_extra_files(fds, 2); + close(fds[0]); + dup2(fds[1], STDOUT_FILENO); + switch_system(cmd, SWITCH_TRUE); + close(fds[1]); + exit(0); + } + } + + end: + + return 0; + +#endif + +} + +SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max) +{ +#ifdef HAVE_SETRLIMIT + struct rlimit rlp; + + memset(&rlp, 0, sizeof(rlp)); + getrlimit(RLIMIT_STACK, &rlp); + + *cur = rlp.rlim_cur; + *max = rlp.rlim_max; + + return SWITCH_STATUS_SUCCESS; + +#else + + return SWITCH_STATUS_FALSE; + +#endif + + + +} + + +SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream) +{ +#ifdef WIN32 + stream->write_function(stream, "Capturing output not supported.\n"); + return switch_system(cmd, SWITCH_TRUE); +#else + return switch_stream_system_fork(cmd, stream); +#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 55ac6d22adb0d6383b916f4e8b11d182ed7ca9ea Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 20 Nov 2012 10:19:08 -0600 Subject: [PATCH 454/512] restore significant part of last patch --- src/switch_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/switch_core.c b/src/switch_core.c index 4682d3c002..1cc0dd0569 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -670,6 +670,9 @@ SWITCH_DECLARE(void) switch_core_set_globals(void) #ifdef WIN32 GetTempPath(dwBufSize, lpPathBuffer); lpPathBuffer[strlen(lpPathBuffer)-1] = 0; + tmp = switch_string_replace(lpPathBuffer, "\\", "/"); + strcpy(lpPathBuffer, tmp); + free(tmp); switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", lpPathBuffer); #else switch_snprintf(SWITCH_GLOBAL_dirs.temp_dir, BUFSIZE, "%s", "/tmp"); From ce885f1c31a60eafe61969513280ad587fde6eca Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 20 Nov 2012 13:45:32 -0600 Subject: [PATCH 455/512] fix occasional empty transaction --- src/switch_core_sqldb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 5df382efab..f396d18f2b 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1670,7 +1670,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, while (qm->thread_running == 1) { uint32_t i, lc; - uint32_t written, iterations = 0; + uint32_t written = 0, iterations = 0; if (sql_manager.paused) { for (i = 0; i < qm->numq; i++) { @@ -1680,7 +1680,10 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, } do { - written = do_trans(qm); + if (!qm_ttl(qm)) { + goto check; + } + written = do_trans(qm); iterations += written; } while(written == qm->max_trans); From 2ee80584886809dead128626264f75a05fbd36c0 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 20 Nov 2012 16:54:35 -0600 Subject: [PATCH 456/512] FS-4847 try this --- src/switch_utils.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index fad8530245..56a7ab06d1 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -876,12 +876,16 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, } } + if (fd > -1) { + close(fd); + fd = -1; + } if (zstr(from)) { from = "freeswitch"; } #ifdef WIN32 - switch_snprintf(buf, B64BUFFLEN, "type \"%s\" | \"%s\" -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); + switch_snprintf(buf, B64BUFFLEN, "\"%s\" -f %s %s %s < \"%s\"", runtime.mailer_app, from, runtime.mailer_app_args, to, filename); #else switch_snprintf(buf, B64BUFFLEN, "/bin/cat %s | %s -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); #endif From 27c236a03ab2715d09283924b2a5d6eef9866fd5 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 21 Nov 2012 09:41:14 -0600 Subject: [PATCH 457/512] FS-4847 test again --- src/switch_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_utils.c b/src/switch_utils.c index 56a7ab06d1..4335b4dcd3 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -885,7 +885,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, from = "freeswitch"; } #ifdef WIN32 - switch_snprintf(buf, B64BUFFLEN, "\"%s\" -f %s %s %s < \"%s\"", runtime.mailer_app, from, runtime.mailer_app_args, to, filename); + switch_snprintf(buf, B64BUFFLEN, "\"\"%s\" -f %s %s %s < \"%s\"\"", runtime.mailer_app, from, runtime.mailer_app_args, to, filename); #else switch_snprintf(buf, B64BUFFLEN, "/bin/cat %s | %s -f %s %s %s", filename, runtime.mailer_app, from, runtime.mailer_app_args, to); #endif From ffa64d6f82d8fdaad4510e88d247938b0dcf1070 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 08:54:06 -0600 Subject: [PATCH 458/512] add new lib_dir to bottom of the struct --- src/include/switch_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 15993c7993..20c83cd898 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -466,7 +466,6 @@ typedef struct { struct switch_directories { char *base_dir; char *mod_dir; - char *lib_dir; char *conf_dir; char *log_dir; char *run_dir; @@ -478,6 +477,7 @@ struct switch_directories { char *storage_dir; char *recordings_dir; char *sounds_dir; + char *lib_dir; }; typedef struct switch_directories switch_directories; From ed11a3c9501cacb9c872537725780f5775465f38 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 09:08:24 -0600 Subject: [PATCH 459/512] FS-4854 try this, it should auto detect this situation and work w/o configuration --- src/mod/endpoints/mod_dingaling/mod_dingaling.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 24a0e497a9..2878968ddf 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1264,6 +1264,9 @@ static int activate_audio_rtp(struct private_object *tech_pvt) switch_rtp_set_ssrc(tech_pvt->transports[LDL_TPORT_RTP].rtp_session, tech_pvt->transports[LDL_TPORT_RTP].ssrc); + switch_rtp_intentional_bugs(tech_pvt->transports[LDL_TPORT_RTP].rtp_session, RTP_BUG_GEN_ONE_GEN_ALL); + + if (tech_pvt->transports[LDL_TPORT_RTCP].remote_port) { switch_rtp_activate_rtcp(tech_pvt->transports[LDL_TPORT_RTP].rtp_session, MDL_RTCP_DUR, tech_pvt->transports[LDL_TPORT_RTCP].remote_port); From 812d87641414ec7f2ffe6284fd376396daad28b6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 09:11:04 -0600 Subject: [PATCH 460/512] FS-4856 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index b4d3e894a3..e1aa82a37e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2212,7 +2212,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread if (!sofia_test_pflag(profile, PFLAG_STANDBY)) { - if (++ireg_loops >= IREG_SECONDS) { + if (++ireg_loops >= profile->ireg_seconds) { time_t now = switch_epoch_time_now(NULL); sofia_reg_check_expire(profile, now, 0); ireg_loops = 0; From 624b49f2a3921082d45d643f3579a5d8f1d01dd6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 09:39:32 -0600 Subject: [PATCH 461/512] FS-4793 --resolve --- src/switch_core_media_bug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index b8b83da6bd..b0d9e8d4f9 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -247,7 +247,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_read(switch_media_bug_t *b if (read_impl.actual_samples_per_second == other_read_impl.actual_samples_per_second) { if (read_impl.decoded_bytes_per_packet < other_read_impl.decoded_bytes_per_packet) { - frame_size = other_read_impl.decoded_bytes_per_packet; + frame_size = read_impl.decoded_bytes_per_packet; } } else { if (read_impl.decoded_bytes_per_packet > other_read_impl.decoded_bytes_per_packet) { From b7e6f4ab8203f6fed897d9cb8bac62feff46e651 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 09:57:13 -0600 Subject: [PATCH 462/512] FS-4853 --- src/switch_ivr.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 18329714aa..dd5055351c 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1390,6 +1390,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_hold(switch_core_session_t *session, switch_channel_t *channel = switch_core_session_get_channel(session); const char *stream; const char *other_uuid; + switch_event_t *event; msg.message_id = SWITCH_MESSAGE_INDICATE_HOLD; msg.string_arg = message; @@ -1406,6 +1407,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_hold(switch_core_session_t *session, } } + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HOLD) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_fire(&event); + } + return SWITCH_STATUS_SUCCESS; } @@ -1428,6 +1434,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_unhold(switch_core_session_t *session switch_channel_t *channel = switch_core_session_get_channel(session); const char *other_uuid; switch_core_session_t *b_session; + switch_event_t *event; msg.message_id = SWITCH_MESSAGE_INDICATE_UNHOLD; msg.from = __FILE__; @@ -1446,6 +1453,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_unhold(switch_core_session_t *session } + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNHOLD) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_fire(&event); + } + return SWITCH_STATUS_SUCCESS; } From af786291eff1ee1b5531d155ce39ef06f5d23891 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 10:00:44 -0600 Subject: [PATCH 463/512] FS-4852 --resolve --- src/mod/endpoints/mod_sofia/sofia_reg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 79b49c1b6b..e64dab7415 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1595,8 +1595,12 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } else { sql = switch_mprintf("update sip_registrations set " "sub_host='%q', network_ip='%q',network_port='%q'," + "presence_hosts='%q', server_host='%q', orig_server_host='%q'," + "hostname='%q', orig_hostname='%q'," "expires = %ld where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'", sub_host, network_ip, network_port_c, + profile->presence_hosts ? profile->presence_hosts : "", guess_ip4, guess_ip4, + mod_sofia_globals.hostname, mod_sofia_globals.hostname, (long) switch_epoch_time_now(NULL) + (long) exptime + 60, to_user, username, reg_host, contact_str); } From 294a6016b8cff9289c1eea25990fdc7d1fe3112f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 10:32:41 -0600 Subject: [PATCH 464/512] FS-4859 --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 14 ++++++++++++-- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 5240553caa..45f73c5866 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -600,6 +600,7 @@ struct sofia_profile { sofia_dtmf_t dtmf_type; int auto_restart; switch_port_t sip_port; + switch_port_t extsipport; switch_port_t tls_sip_port; int tls_version; unsigned int tls_timeout; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index e1aa82a37e..ab45ed78b3 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3988,6 +3988,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip; } profile->sipip = switch_core_strdup(profile->pool, ip); + } else if (!strcasecmp(var, "ext-sip-port") && val) { + int tmp = atoi(val); + if (tmp > 0) profile->extsipport = tmp; } else if (!strcasecmp(var, "ext-sip-ip")) { if (!zstr(val)) { char *ip = mod_sofia_globals.guess_ip; @@ -4002,8 +4005,11 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else if (!strcasecmp(val, "auto-nat")) { ip = NULL; } else if (strcasecmp(val, "auto")) { - switch_port_t port = 0; - if (sofia_glue_ext_address_lookup(profile, NULL, &myip, &port, val, profile->pool) == SWITCH_STATUS_SUCCESS) { + if (!profile->extsipport) { + profile->extsipport = profile->sip_port; + } + + if (sofia_glue_ext_address_lookup(profile, NULL, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) { ip = myip; sofia_clear_pflag(profile, PFLAG_AUTO_NAT); } else { @@ -4687,6 +4693,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } done: + if (!profile->extsipport) { + profile->extsipport = profile->sip_port; + } + if (profile_already_started) { sofia_glue_release_profile(profile_already_started); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 37caeba651..31ea2bb66b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1373,7 +1373,7 @@ const char *sofia_glue_transport2str(const sofia_transport_t tp) char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport) { return sofia_glue_create_via(session, profile->extsipip, (sofia_glue_transport_has_tls(transport)) - ? profile->tls_sip_port : profile->sip_port, transport); + ? profile->tls_sip_port : profile->extsipport, transport); } char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport) From ea1dddf3250ed5ff89546a789a079464a769703e Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 21 Nov 2012 16:38:46 +0000 Subject: [PATCH 465/512] bump rev --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 6b46446e83..465edafc39 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.2.4], BUG-REPORT-ADDRESS) +AC_INIT([freeswitch], [1.2.5], BUG-REPORT-ADDRESS) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [2]) -AC_SUBST(SWITCH_VERSION_MICRO, [4]) +AC_SUBST(SWITCH_VERSION_MICRO, [5]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 4f9de4364f77fde81953864edc07ca4d37b14c8a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 10:46:18 -0600 Subject: [PATCH 466/512] add strerror to some file failures --- src/mod/loggers/mod_logfile/mod_logfile.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mod/loggers/mod_logfile/mod_logfile.c b/src/mod/loggers/mod_logfile/mod_logfile.c index db78909134..ee41c021a8 100644 --- a/src/mod/loggers/mod_logfile/mod_logfile.c +++ b/src/mod/loggers/mod_logfile/mod_logfile.c @@ -161,7 +161,8 @@ static switch_status_t mod_logfile_rotate(logfile_profile_t *profile) } if ((status = switch_file_rename(from_filename, to_filename, pool)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error renaming log from %s to %s\n",from_filename, to_filename); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error renaming log from %s to %s [%s]\n", + from_filename, to_filename, strerror(errno)); goto end; } } @@ -170,19 +171,19 @@ static switch_status_t mod_logfile_rotate(logfile_profile_t *profile) if (switch_file_exists(to_filename, pool) == SWITCH_STATUS_SUCCESS) { if ((status = switch_file_remove(to_filename, pool)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error removing log %s\n",to_filename); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error removing log %s [%s]\n", to_filename, strerror(errno)); goto end; } } switch_file_close(profile->log_afd); if ((status = switch_file_rename(profile->logfile, to_filename, pool)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error renaming log from %s to %s\n", profile->logfile, to_filename); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error renaming log from %s to %s [%s]\n", profile->logfile, to_filename, strerror(errno)); goto end; } if ((status = mod_logfile_openlogfile(profile, SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error reopening log %s\n",profile->logfile); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error reopening log %s\n", profile->logfile); } if (profile->suffix < profile->max_rot) { profile->suffix++; From 89f4cd75f071d8330273cbb94d56188ce6ae0843 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 21 Nov 2012 13:59:23 -0600 Subject: [PATCH 467/512] Fix 2833 Debuging --- src/switch_rtp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 73c1db88b0..e469066fce 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -341,9 +341,10 @@ static void do_2833(switch_rtp_t *rtp_session, switch_core_session_t *session); static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_size_t bytes, int *do_cng) { + #ifdef DEBUG_2833 if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); } #endif @@ -396,8 +397,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ } } #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) - packet[1], (unsigned) packet[2], (unsigned) packet[3]); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) packet[1], (unsigned) packet[2], (unsigned) packet[3]); #endif if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) { @@ -405,7 +405,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ rtp_session->dtmf_data.in_digit_seq = in_digit_seq; #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : ""); #endif @@ -414,7 +414,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ rtp_session->dtmf_data.in_digit_ts) { switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0), 0, SWITCH_DTMF_RTP }; #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); #endif switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); rtp_session->dtmf_data.in_digit_queued = 1; @@ -433,7 +433,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ if (end) { if (!rtp_session->dtmf_data.in_digit_ts && rtp_session->dtmf_data.last_in_digit_ts != ts) { #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "start with end packet %d\n", ts); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start with end packet %d\n", ts); #endif rtp_session->dtmf_data.last_in_digit_ts = ts; rtp_session->dtmf_data.in_digit_ts = ts; @@ -450,17 +450,17 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF; rtp_session->dtmf_data.flip = 0; #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "you're welcome!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n"); #endif } #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration); #endif if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) { #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); #endif switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); } @@ -481,7 +481,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ } else if (!rtp_session->dtmf_data.in_digit_ts) { #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "start %d\n", ts); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start %d\n", ts); #endif rtp_session->dtmf_data.in_digit_ts = ts; rtp_session->dtmf_data.last_in_digit_ts = ts; @@ -492,7 +492,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ rtp_session->dtmf_data.last_duration = duration; } else { #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n", key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end); #endif switch_cond_next(); @@ -2822,7 +2822,7 @@ static void do_flush(switch_rtp_t *rtp_session) if (bytes > rtp_header_len && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { handle_rfc2833(rtp_session, bytes, &do_cng); #ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "*** RTP packet handled in flush loop %d ***\n", do_cng); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "*** RTP packet handled in flush loop %d ***\n", do_cng); #endif } From 1f06fe909cec21a9aa90e556c17210be302408e2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 11:49:35 -0600 Subject: [PATCH 468/512] FS-4859 correction --- src/mod/endpoints/mod_sofia/sofia.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ab45ed78b3..092b1dca27 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4672,6 +4672,11 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } if (profile->sipip) { + + if (!profile->extsipport) { + profile->extsipport = profile->sip_port; + } + launch_sofia_profile_thread(profile); if (profile->odbc_dsn) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Connecting ODBC Profile %s [%s]\n", profile->name, url); @@ -4693,10 +4698,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } done: - if (!profile->extsipport) { - profile->extsipport = profile->sip_port; - } - if (profile_already_started) { sofia_glue_release_profile(profile_already_started); } From cf32d24b5df7aefaa4818427f7adb9a42bb0c841 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 13:06:28 -0600 Subject: [PATCH 469/512] FS-4860 --resolve This seems to have come from a malformed file_string in the ringback var --- src/mod/applications/mod_dptools/mod_dptools.c | 7 ++++++- src/switch_core_file.c | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index eefd4aad4b..d672e2a3db 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4476,8 +4476,13 @@ static switch_status_t next_file(switch_file_handle_t *handle) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error finding the folder path section in '%s'\n", path); } - } + + if (switch_file_exists(file, handle->memory_pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] does not exist.\n", file); + goto top; + } + if (switch_core_file_open(&context->fh, file, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { goto top; } diff --git a/src/switch_core_file.c b/src/switch_core_file.c index b1a1effc85..baec6f5184 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -76,6 +76,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, switch_set_flag(fh, SWITCH_FILE_FLAG_FREE_POOL); } + if (switch_directory_exists(file_path, fh->memory_pool) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] is a directory not a file.\n", file_path); + goto fail; + } if ((rhs = strstr(file_path, SWITCH_URL_SEPARATOR))) { switch_copy_string(stream_name, file_path, (rhs + 1) - file_path); @@ -198,6 +202,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, fail: + switch_clear_flag(fh, SWITCH_FILE_OPEN); + if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) { switch_core_destroy_memory_pool(&fh->memory_pool); } From e2e9938d1a478a8085a8cdc0e5c5981e68dbc1eb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 18:14:15 -0600 Subject: [PATCH 470/512] only drop re-reg once instead of permenantly --- src/mod/endpoints/mod_sofia/sofia_reg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index e64dab7415..2dbdeaf5a8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -2018,9 +2018,9 @@ void sofia_reg_handle_sip_r_register(int status, expi = (uint32_t) atoi(new_expires); if (expi > 0 && expi != sofia_private->gateway->freq) { - sofia_private->gateway->freq = expi; - sofia_private->gateway->expires_str = switch_core_sprintf(sofia_private->gateway->pool, "%d", expi); - + //sofia_private->gateway->freq = expi; + //sofia_private->gateway->expires_str = switch_core_sprintf(sofia_private->gateway->pool, "%d", expi); + if (expi > 60) { sofia_private->gateway->expires = switch_epoch_time_now(NULL) + (expi - 15); } else { From 2b2a4fb256105236df92ee18c64ae3361cd7ebf0 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 21 Nov 2012 22:04:55 -0600 Subject: [PATCH 471/512] fix compiler warning --- src/switch_core_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_file.c b/src/switch_core_file.c index baec6f5184..ae040b31be 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -42,7 +42,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, uint8_t channels, uint32_t rate, unsigned int flags, switch_memory_pool_t *pool) { char *ext; - switch_status_t status; + switch_status_t status = SWITCH_STATUS_FALSE; char stream_name[128] = ""; char *rhs = NULL; const char *spool_path = NULL; From 5dccbe4818ecdf5b93d6e073f8e14cfa5e638011 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 21:15:31 -0600 Subject: [PATCH 472/512] fix sql queue manager issues --- src/mod/endpoints/mod_sofia/sofia_presence.c | 6 ++-- src/switch_core_sqldb.c | 33 +++++++++++--------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index e11d96ff76..53b524a236 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -873,13 +873,13 @@ static void do_dialog_probe(switch_event_t *event) if (mod_sofia_globals.debug_presence > 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s DUMP DIALOG_PROBE set version sql:\n%s\n", profile->name, sql); } - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + sofia_glue_execute_sql_soon(profile, &sql, SWITCH_TRUE); switch_safe_free(sql); // The dialog_probe_callback has built up the dialogs to be included in the NOTIFY. // Now send the "full" dialog event to the triggering subscription. - sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,version, " + sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,version+1, " "'full',full_to,full_from,contact,network_ip,network_port " "from sip_subscriptions " "where hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and call_id='%q'", @@ -4543,7 +4543,7 @@ void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now) "((expires > 0 and expires <= %ld)) and profile_name='%q' and hostname='%q'", (long) now, profile->name, mod_sofia_globals.hostname); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + sofia_glue_execute_sql_soon(profile, &sql, SWITCH_TRUE); switch_safe_free(sql); sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, " diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index f396d18f2b..556306ec97 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1314,10 +1314,12 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_start(switch_sql_queue_ } -static void do_flush(switch_queue_t *q, switch_cache_db_handle_t *dbh) +static void do_flush(switch_sql_queue_manager_t *qm, int i, switch_cache_db_handle_t *dbh) { void *pop = NULL; - + switch_queue_t *q = qm->sql_queue[i]; + + switch_mutex_lock(qm->mutex); while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) { if (pop) { if (dbh) { @@ -1326,6 +1328,7 @@ static void do_flush(switch_queue_t *q, switch_cache_db_handle_t *dbh) free(pop); } } + switch_mutex_unlock(qm->mutex); } @@ -1347,7 +1350,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_destroy(switch_sql_queu for(i = 0; i < qm->numq; i++) { - do_flush(qm->sql_queue[i], NULL); + do_flush(qm, i, NULL); } pool = qm->pool; @@ -1408,7 +1411,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql); written = qm->written[pos]; size = switch_sql_queue_manager_size(qm, pos); - want = written + size; + want = written + qm->pre_written[pos] + size; switch_mutex_unlock(qm->mutex); qm_wake(qm); @@ -1563,7 +1566,9 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) if (pop) { if ((status = switch_cache_db_execute_sql(qm->event_db, (char *) pop, NULL)) == SWITCH_STATUS_SUCCESS) { + switch_mutex_lock(qm->mutex); qm->pre_written[i]++; + switch_mutex_unlock(qm->mutex); ttl++; } free(pop); @@ -1633,7 +1638,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, uint32_t sanity = 120; switch_sql_queue_manager_t *qm = (switch_sql_queue_manager_t *) obj; - uint32_t i, countdown = 0; + uint32_t i; while (!qm->event_db) { if (switch_cache_db_get_db_handle_dsn(&qm->event_db, qm->dsn) == SWITCH_STATUS_SUCCESS && qm->event_db) @@ -1674,7 +1679,7 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, if (sql_manager.paused) { for (i = 0; i < qm->numq; i++) { - do_flush(qm->sql_queue[i], NULL); + do_flush(qm, i, NULL); } goto check; } @@ -1707,21 +1712,19 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, check: - countdown = 40; - - while (--countdown && (lc = qm_ttl(qm)) < qm->max_trans / 4) { - if (lc == 0) { - switch_thread_cond_wait(qm->cond, qm->cond_mutex); - break; - } - switch_yield(5000); + if ((lc = qm_ttl(qm)) < qm->max_trans / 4) { + switch_yield(500000); + } else if (lc == 0) { + switch_thread_cond_wait(qm->cond, qm->cond_mutex); + } else { + switch_cond_next(); } } switch_mutex_unlock(qm->cond_mutex); for(i = 0; i < qm->numq; i++) { - do_flush(qm->sql_queue[i], qm->event_db); + do_flush(qm, i, qm->event_db); } qm->thread_running = 0; From e4c7eac4c31c9dd64599dea476a368d13faf3468 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 21:16:18 -0600 Subject: [PATCH 473/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 15c91a976a..367ab86350 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.6b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.6], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [6b]) +AC_SUBST(SWITCH_VERSION_MICRO, [6]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From d659f8ced401e59f1e97e62cd2dcf406c8308890 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 21:19:29 -0600 Subject: [PATCH 474/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 367ab86350..c96f9f8dd9 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.6], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.7b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [6]) +AC_SUBST(SWITCH_VERSION_MICRO, [7b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 377e093a319c6ce59fabca97740938f1cbc3fb49 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 22:22:37 -0600 Subject: [PATCH 475/512] mistake on last commit --- src/switch_core_sqldb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 556306ec97..caee1ee1f6 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1714,10 +1714,9 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, if ((lc = qm_ttl(qm)) < qm->max_trans / 4) { switch_yield(500000); - } else if (lc == 0) { - switch_thread_cond_wait(qm->cond, qm->cond_mutex); - } else { - switch_cond_next(); + if ((lc = qm_ttl(qm)) == 0) { + switch_thread_cond_wait(qm->cond, qm->cond_mutex); + } } } From c9a72c676720b93a34744792935bcbfbd03e2ccd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 22:25:19 -0600 Subject: [PATCH 476/512] debump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index c96f9f8dd9..367ab86350 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.7b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.6], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [7b]) +AC_SUBST(SWITCH_VERSION_MICRO, [6]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From c1572392945cc7982fd0ee0f4a19c72bfd7437f8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Nov 2012 22:28:18 -0600 Subject: [PATCH 477/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 367ab86350..c96f9f8dd9 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.6], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.7b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [6]) +AC_SUBST(SWITCH_VERSION_MICRO, [7b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 66e85c8d7152132e44a13545e21d406f840edf94 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 22 Nov 2012 15:19:38 -0600 Subject: [PATCH 478/512] wrong turn in albakoykee --- src/switch_core_sqldb.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index caee1ee1f6..c8cdfe049e 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1409,9 +1409,9 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_push_confirm(switch_sql switch_mutex_lock(qm->mutex); switch_queue_push(qm->sql_queue[pos], dup ? strdup(sql) : (char *)sql); - written = qm->written[pos]; + written = qm->pre_written[pos]; size = switch_sql_queue_manager_size(qm, pos); - want = written + qm->pre_written[pos] + size; + want = written + size; switch_mutex_unlock(qm->mutex); qm_wake(qm); @@ -1494,12 +1494,6 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) if (io_mutex) switch_mutex_lock(io_mutex); - switch_mutex_lock(qm->mutex); - for (i = 0; i < qm->numq; i++) { - qm->pre_written[i] = 0; - } - switch_mutex_unlock(qm->mutex); - if (!zstr(qm->pre_trans_execute)) { switch_cache_db_execute_sql_real(qm->event_db, qm->pre_trans_execute, &errmsg); if (errmsg) { @@ -1623,7 +1617,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm) switch_mutex_lock(qm->mutex); for (i = 0; i < qm->numq; i++) { - qm->written[i] += qm->pre_written[i]; + qm->written[i] = qm->pre_written[i]; } switch_mutex_unlock(qm->mutex); From 9003aaf59fed0ae12847457b131bd55f5e306d71 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 22 Nov 2012 15:20:37 -0600 Subject: [PATCH 479/512] debump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index c96f9f8dd9..367ab86350 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.7b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.6], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [7b]) +AC_SUBST(SWITCH_VERSION_MICRO, [6]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From bef343aecf9a060a7d26785ec36e8ff2abcb10f4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 22 Nov 2012 15:25:00 -0600 Subject: [PATCH 480/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 367ab86350..c96f9f8dd9 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.6], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.7b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [6]) +AC_SUBST(SWITCH_VERSION_MICRO, [7b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 671e935d349b8cbafe0272bcef3f4b50ba4a18d0 Mon Sep 17 00:00:00 2001 From: William King Date: Sun, 25 Nov 2012 18:11:04 -0800 Subject: [PATCH 481/512] FS-4872: --resolve In the case of an event injected sms message that doesn't enable blocking mode the event would be queued up indefinately. --- src/mod/applications/mod_sms/mod_sms.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mod/applications/mod_sms/mod_sms.c b/src/mod/applications/mod_sms/mod_sms.c index 15d0de6233..9fd1d896da 100644 --- a/src/mod/applications/mod_sms/mod_sms.c +++ b/src/mod/applications/mod_sms/mod_sms.c @@ -43,6 +43,8 @@ static void event_handler(switch_event_t *event) { const char *dest_proto = switch_event_get_header(event, "dest_proto"); const char *check_failure = switch_event_get_header(event, "Delivery-Failure"); + const char *check_nonblocking = switch_event_get_header(event, "Nonblocking-Delivery"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "skip_global_process", "true"); if (switch_true(check_failure)) { @@ -54,6 +56,9 @@ static void event_handler(switch_event_t *event) } else if ( check_failure && switch_false(check_failure) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS Delivery Success\n"); return; + } else if ( check_nonblocking && switch_true(check_nonblocking) ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SMS Delivery assumed successful due to being sent in non-blocking manner\n"); + return; } switch_core_chat_send(dest_proto, event); From 942e800be532b7e21a23093bc7379a45ffa6270c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 07:49:16 -0600 Subject: [PATCH 482/512] FS-4823 --resolve --- src/mod/endpoints/mod_sofia/sofia_reg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 2dbdeaf5a8..d2bea6e5ea 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -562,7 +562,8 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames switch_assert(dst); nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(profile->url), SIPTAG_TO_STR(to), NUTAG_URL(dst->contact), SIPTAG_CONTACT_STR(profile->url), - SIPTAG_CALL_ID_STR(argv[0]), TAG_END()); + TAG_END()); + //SIPTAG_CALL_ID_STR(argv[0]), TAG_END()); nua_handle_bind(nh, &mod_sofia_globals.destroy_private); nua_options(nh, NTATAG_SIP_T2(5000), From 44b4ab099577464f17c2fbaada192a8543b2a720 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 10:56:57 -0600 Subject: [PATCH 483/512] FS-4869 can you try this more centralized patch please --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index c8cdfe049e..3ad163b54e 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -152,7 +152,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user if (!r) { for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { - if (dbh_ptr->hash == hash && !dbh_ptr->use_count && !switch_test_flag(dbh_ptr, CDF_PRUNE) && + if (dbh_ptr->hash == hash && (dbh_ptr->type != SCDB_TYPE_PGSQL || !dbh_ptr->use_count) && !switch_test_flag(dbh_ptr, CDF_PRUNE) && switch_mutex_trylock(dbh_ptr->mutex) == SWITCH_STATUS_SUCCESS) { r = dbh_ptr; break; From a7f8e4259ee5b90c0bd9deb843480633ba1123a6 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 26 Nov 2012 14:26:41 -0500 Subject: [PATCH 484/512] OPENZAP-201 --resolve --- libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 8abfce78df..2c6eda0295 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -779,6 +779,9 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) case FTDM_CHANNEL_STATE_GET_CALLERID: { memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data)); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Initializing cid data!\n"); + ftdm_set_string(ftdmchan->caller_data.ani.digits, "unknown"); + ftdm_set_string(ftdmchan->caller_data.cid_name, ftdmchan->caller_data.ani.digits); ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_CALLERID_DETECT, NULL); continue; } From 0b148a85b94be33fe70b692240e0d449a59f0ef2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 11:59:29 -0600 Subject: [PATCH 485/512] this breaks the auto rate hunting code in mod_sndfile --- src/mod/applications/mod_dptools/mod_dptools.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index d672e2a3db..0cee939286 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -4478,11 +4478,6 @@ static switch_status_t next_file(switch_file_handle_t *handle) } } - if (switch_file_exists(file, handle->memory_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "File [%s] does not exist.\n", file); - goto top; - } - if (switch_core_file_open(&context->fh, file, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) { goto top; } From c7c528cd7c8104622df97a1f4e7fdc59ba6a930e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 13:52:06 -0600 Subject: [PATCH 486/512] FS-4867 --resolve --- src/include/switch_channel.h | 4 ++++ src/switch_channel.c | 15 +++++++++++++++ src/switch_core_io.c | 5 ++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index cd8cbb47f0..4225a9bd88 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -541,6 +541,10 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan \return number of digits in the queue */ SWITCH_DECLARE(switch_size_t) switch_channel_has_dtmf(_In_ switch_channel_t *channel); +SWITCH_DECLARE(switch_status_t) switch_channel_dtmf_lock(switch_channel_t *channel); +SWITCH_DECLARE(switch_status_t) switch_channel_try_dtmf_lock(switch_channel_t *channel); +SWITCH_DECLARE(switch_status_t) switch_channel_dtmf_unlock(switch_channel_t *channel); + /*! \brief Queue DTMF on a given channel diff --git a/src/switch_channel.c b/src/switch_channel.c index 5fa30564d2..903bb6be76 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -363,6 +363,21 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(switch_status_t) switch_channel_dtmf_lock(switch_channel_t *channel) +{ + return switch_mutex_lock(channel->dtmf_mutex); +} + +SWITCH_DECLARE(switch_status_t) switch_channel_try_dtmf_lock(switch_channel_t *channel) +{ + return switch_mutex_trylock(channel->dtmf_mutex); +} + +SWITCH_DECLARE(switch_status_t) switch_channel_dtmf_unlock(switch_channel_t *channel) +{ + return switch_mutex_unlock(channel->dtmf_mutex); +} + SWITCH_DECLARE(switch_size_t) switch_channel_has_dtmf(switch_channel_t *channel) { switch_size_t has; diff --git a/src/switch_core_io.c b/src/switch_core_io.c index ba4874d81f..8e99fcd472 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -151,7 +151,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi for(i = 0; i < 2; i++) { if (session->dmachine[i] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { - switch_ivr_dmachine_ping(session->dmachine[i], NULL); + if (switch_channel_try_dtmf_lock(session->channel) == SWITCH_STATUS_SUCCESS) { + switch_ivr_dmachine_ping(session->dmachine[i], NULL); + switch_channel_dtmf_unlock(session->channel); + } } } From ff43048997191ca16b3ead85ac58d790c50e1b71 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 14:04:58 -0600 Subject: [PATCH 487/512] FS-4877 --resolve --- src/mod/endpoints/mod_sofia/sofia_presence.c | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 53b524a236..7bbb0c78ac 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -939,6 +939,17 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event } if (call_id) { + if (switch_true(final)) { + sql = switch_mprintf("update sip_subscriptions set expires=%ld where " + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' " + "and call_id = '%q' ", + (long)0, + mod_sofia_globals.hostname, profile->name, + from_user, from_host, event_str, call_id); + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } + sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, " "'%q' as ct,'%q' as pt " " from sip_subscriptions where " @@ -950,6 +961,16 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event mod_sofia_globals.hostname, profile->name, from_user, from_host, event_str, call_id); } else { + if (switch_true(final)) { + sql = switch_mprintf("update sip_subscriptions set expires=%ld where " + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", + (long)0, + mod_sofia_globals.hostname, profile->name, + from_user, from_host, event_str); + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } + sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, " "'%q' as ct,'%q' as pt " " from sip_subscriptions where " From 428cd029decf824b1272612ef5af4e4953aaa547 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 15:18:58 -0600 Subject: [PATCH 488/512] FS-4868 --resolve This patch also adds freeswitch.ready() which will return false once shutdown has started --- src/include/switch_core.h | 2 + src/include/switch_cpp.h | 1 + .../src/org/freeswitch/swig/CoreSession.java | 2 +- .../src/org/freeswitch/swig/JavaSession.java | 4 + .../src/org/freeswitch/swig/freeswitch.java | 8 + .../org/freeswitch/swig/freeswitchJNI.java | 3 + .../languages/mod_java/switch_swig_wrap.cpp | 50 ++++ src/mod/languages/mod_lua/mod_lua_wrap.cpp | 19 ++ .../languages/mod_managed/freeswitch_wrap.cxx | 230 +++++++++++++++++- src/mod/languages/mod_managed/managed/swig.cs | 183 ++++++++++++-- src/mod/languages/mod_perl/freeswitch.pm | 1 + src/mod/languages/mod_perl/mod_perl_wrap.cpp | 19 ++ src/mod/languages/mod_python/freeswitch.py | 1 + .../languages/mod_python/mod_python_wrap.cpp | 14 ++ src/switch_core.c | 5 + src/switch_cpp.cpp | 5 + 16 files changed, 515 insertions(+), 32 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 210b676b1e..7b164af20a 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2042,6 +2042,8 @@ SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel); */ SWITCH_DECLARE(switch_bool_t) switch_core_ready(void); +SWITCH_DECLARE(switch_bool_t) switch_core_running(void); + /*! \brief Determines if the core is ready to take inbound calls \return SWITCH_TRUE or SWITCH_FALSE diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index 83adac6867..8f50b70fe3 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -71,6 +71,7 @@ SWITCH_DECLARE(char *) getGlobalVariable(char *var_name); SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg); SWITCH_DECLARE(void) consoleCleanLog(char *msg); +SWITCH_DECLARE(bool) running(void); SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *body = NULL, char *file = NULL, char *convert_cmd = NULL, char *convert_ext = NULL); diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java index 5b192d350d..ca8c27b123 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java @@ -177,7 +177,7 @@ public class CoreSession { return freeswitchJNI.CoreSession_recordFile(swigCPtr, this, file_name, time_limit, silence_threshold, silence_hits); } - public int originate(CoreSession a_leg_session, String dest, int timeout, SWIGTYPE_p_switch_state_handler_table_t handlers) { + protected int originate(CoreSession a_leg_session, String dest, int timeout, SWIGTYPE_p_switch_state_handler_table_t handlers) { return freeswitchJNI.CoreSession_originate(swigCPtr, this, CoreSession.getCPtr(a_leg_session), a_leg_session, dest, timeout, SWIGTYPE_p_switch_state_handler_table_t.getCPtr(handlers)); } diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/JavaSession.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/JavaSession.java index f75f1cafee..b2bf611a4e 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/JavaSession.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/JavaSession.java @@ -69,4 +69,8 @@ public class JavaSession extends CoreSession { return new SWIGTYPE_p_switch_status_t(freeswitchJNI.JavaSession_run_dtmf_callback(swigCPtr, this, SWIGTYPE_p_void.getCPtr(input), SWIGTYPE_p_switch_input_type_t.getCPtr(itype)), true); } + public int originate(JavaSession aleg, String destination, int timeout) { + return freeswitchJNI.JavaSession_originate(swigCPtr, this, JavaSession.getCPtr(aleg), aleg, destination, timeout); + } + } diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitch.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitch.java index 7d832dbea0..48c03c2f10 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitch.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitch.java @@ -25,6 +25,10 @@ public class freeswitch { freeswitchJNI.consoleCleanLog(msg); } + public static boolean running() { + return freeswitchJNI.running(); + } + public static boolean email(String to, String from, String headers, String body, String file, String convert_cmd, String convert_ext) { return freeswitchJNI.email(to, from, headers, body, file, convert_cmd, convert_ext); } @@ -62,4 +66,8 @@ public class freeswitch { return (cPtr == 0) ? null : new SWIGTYPE_p_JavaVM(cPtr, false); } + public static void setOriginateStateHandler(org.freeswitch.StateHandler stateHandler) throws java.util.TooManyListenersException { + freeswitchJNI.setOriginateStateHandler(stateHandler); + } + } diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java index 40f856cb41..cc2f7f7cf7 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java @@ -13,6 +13,7 @@ class freeswitchJNI { public final static native String getGlobalVariable(String jarg1); public final static native void consoleLog(String jarg1, String jarg2); public final static native void consoleCleanLog(String jarg1); + public final static native boolean running(); public final static native boolean email(String jarg1, String jarg2, String jarg3, String jarg4, String jarg5, String jarg6, String jarg7); public final static native long new_IVRMenu(long jarg1, IVRMenu jarg1_, String jarg2, String jarg3, String jarg4, String jarg5, String jarg6, String jarg7, String jarg8, String jarg9, String jarg10, int jarg11, int jarg12, int jarg13, int jarg14, int jarg15, int jarg16); public final static native void delete_IVRMenu(long jarg1); @@ -162,6 +163,7 @@ class freeswitchJNI { public final static native long dtmf_callback(long jarg1, long jarg2, long jarg3, long jarg4, long jarg5); public final static native void javaVM_set(long jarg1); public final static native long javaVM_get(); + public final static native void setOriginateStateHandler(org.freeswitch.StateHandler jarg1) throws java.util.TooManyListenersException; public final static native long new_JavaSession__SWIG_0(); public final static native long new_JavaSession__SWIG_1(String jarg1); public final static native long new_JavaSession__SWIG_2(long jarg1); @@ -172,5 +174,6 @@ class freeswitchJNI { public final static native void JavaSession_setHangupHook(long jarg1, JavaSession jarg1_, org.freeswitch.HangupHook jarg2); public final static native void JavaSession_check_hangup_hook(long jarg1, JavaSession jarg1_); public final static native long JavaSession_run_dtmf_callback(long jarg1, JavaSession jarg1_, long jarg2, long jarg3); + public final static native int JavaSession_originate(long jarg1, JavaSession jarg1_, long jarg2, JavaSession jarg2_, String jarg3, int jarg4); public final static native long SWIGJavaSessionUpcast(long jarg1); } diff --git a/src/mod/languages/mod_java/switch_swig_wrap.cpp b/src/mod/languages/mod_java/switch_swig_wrap.cpp index 93499b61ab..83ddb6db02 100644 --- a/src/mod/languages/mod_java/switch_swig_wrap.cpp +++ b/src/mod/languages/mod_java/switch_swig_wrap.cpp @@ -199,6 +199,7 @@ static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionC #define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else +#include "switch.h" #include "switch_cpp.h" #include "freeswitch_java.h" @@ -286,6 +287,18 @@ SWIGEXPORT void JNICALL Java_org_freeswitch_swig_freeswitchJNI_consoleCleanLog(J } +SWIGEXPORT jboolean JNICALL Java_org_freeswitch_swig_freeswitchJNI_running(JNIEnv *jenv, jclass jcls) { + jboolean jresult = 0 ; + bool result; + + (void)jenv; + (void)jcls; + result = (bool)running(); + jresult = (jboolean)result; + return jresult; +} + + SWIGEXPORT jboolean JNICALL Java_org_freeswitch_swig_freeswitchJNI_email(JNIEnv *jenv, jclass jcls, jstring jarg1, jstring jarg2, jstring jarg3, jstring jarg4, jstring jarg5, jstring jarg6, jstring jarg7) { jboolean jresult = 0 ; char *arg1 = (char *) 0 ; @@ -3176,6 +3189,16 @@ SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_javaVM_1get(JNIE } +SWIGEXPORT void JNICALL Java_org_freeswitch_swig_freeswitchJNI_setOriginateStateHandler(JNIEnv *jenv, jclass jcls, jobject jarg1) { + jobject arg1 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1; + setOriginateStateHandler(arg1); +} + + SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_new_1JavaSession_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { jlong jresult = 0 ; JavaSession *result = 0 ; @@ -3331,6 +3354,33 @@ SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_JavaSession_1run } +SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_JavaSession_1originate(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jstring jarg3, jint jarg4) { + jint jresult = 0 ; + JavaSession *arg1 = (JavaSession *) 0 ; + JavaSession *arg2 = (JavaSession *) 0 ; + char *arg3 = (char *) 0 ; + int arg4 ; + int result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(JavaSession **)&jarg1; + arg2 = *(JavaSession **)&jarg2; + arg3 = 0; + if (jarg3) { + arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3) return 0; + } + arg4 = (int)jarg4; + result = (int)(arg1)->originate(arg2,arg3,arg4); + jresult = (jint)result; + if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3); + return jresult; +} + + SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_SWIGJavaSessionUpcast(JNIEnv *jenv, jclass jcls, jlong jarg1) { jlong baseptr = 0; (void)jenv; diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 679b852a81..3f9ad57fb5 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -1627,6 +1627,24 @@ fail: } +static int _wrap_running(lua_State* L) { + int SWIG_arg = -1; + bool result; + + SWIG_check_num_args("running",0,0) + result = (bool)running(); + SWIG_arg=0; + lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + static int _wrap_email(lua_State* L) { int SWIG_arg = -1; char *arg1 = (char *) 0 ; @@ -7774,6 +7792,7 @@ static const struct luaL_reg swig_commands[] = { { "getGlobalVariable", _wrap_getGlobalVariable}, { "consoleLog", _wrap_consoleLog}, { "consoleCleanLog", _wrap_consoleCleanLog}, + { "running", _wrap_running}, { "email", _wrap_email}, { "console_log", _wrap_console_log}, { "console_clean_log", _wrap_console_clean_log}, diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index a1fed17362..4f885e481b 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -1267,6 +1267,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VA } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "execute_on_pre_originate"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -1344,6 +1355,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIAB } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "api_on_pre_originate"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -1982,6 +2004,17 @@ SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_DTMF_LOG_LEN_get() { } +SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_MAX_TRANS_get() { + int jresult ; + int result; + + result = (int) 2000; + + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_dtmf_t_digit_set(void * jarg1, char jarg2) { switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; char arg2 ; @@ -2801,6 +2834,36 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_directories_sounds_dir_get(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_directories_lib_dir_set(void * jarg1, char * jarg2) { + switch_directories *arg1 = (switch_directories *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_directories *)jarg1; + arg2 = (char *)jarg2; + { + if (arg1->lib_dir) delete [] arg1->lib_dir; + if (arg2) { + arg1->lib_dir = (char *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->lib_dir, (const char *)arg2); + } else { + arg1->lib_dir = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_directories_lib_dir_get(void * jarg1) { + char * jresult ; + switch_directories *arg1 = (switch_directories *) 0 ; + char *result = 0 ; + + arg1 = (switch_directories *)jarg1; + result = (char *) ((arg1)->lib_dir); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_directories() { void * jresult ; switch_directories *result = 0 ; @@ -8237,6 +8300,18 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_channel(void * jarg } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_mutex(void * jarg1) { + void * jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_mutex_t *result = 0 ; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_mutex_t *)switch_core_session_get_mutex(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_wake_session_thread(void * jarg1) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -8535,15 +8610,21 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall(int jarg1) { } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_hupall_matching_var(char * jarg1, char * jarg2, int jarg3) { +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_session_hupall_matching_var_ans(char * jarg1, char * jarg2, int jarg3, int jarg4) { + unsigned long jresult ; char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; switch_call_cause_t arg3 ; + switch_hup_type_t arg4 ; + uint32_t result; arg1 = (char *)jarg1; arg2 = (char *)jarg2; arg3 = (switch_call_cause_t)jarg3; - switch_core_session_hupall_matching_var((char const *)arg1,(char const *)arg2,arg3); + arg4 = (switch_hup_type_t)jarg4; + result = (uint32_t)switch_core_session_hupall_matching_var_ans((char const *)arg1,(char const *)arg2,arg3,arg4); + jresult = (unsigned long)result; + return jresult; } @@ -10712,6 +10793,16 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_ready() { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_running() { + int jresult ; + switch_bool_t result; + + result = (switch_bool_t)switch_core_running(); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_ready_inbound() { int jresult ; switch_bool_t result; @@ -11390,13 +11481,13 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_preprocess_session(void * jarg1, ch } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_stop_thread() { - switch_core_sqldb_stop_thread(); +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_pause() { + switch_core_sqldb_pause(); } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_start_thread() { - switch_core_sqldb_start_thread(); +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_sqldb_resume() { + switch_core_sqldb_resume(); } @@ -12324,6 +12415,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_recovery_flush(char * jarg1, char } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_size(void * jarg1, unsigned long jarg2) { + int jresult ; + switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; + uint32_t arg2 ; + int result; + + arg1 = (switch_sql_queue_manager_t *)jarg1; + arg2 = (uint32_t)jarg2; + result = (int)switch_sql_queue_manager_size(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_push_confirm(void * jarg1, char * jarg2, unsigned long jarg3, int jarg4) { int jresult ; switch_sql_queue_manager_t *arg1 = (switch_sql_queue_manager_t *) 0 ; @@ -12372,27 +12477,29 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_destroy(void * jarg1) } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_init_name(char * jarg1, void * jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_sql_queue_manager_init_name(char * jarg1, void * jarg2, unsigned long jarg3, char * jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9) { int jresult ; char *arg1 = (char *) 0 ; switch_sql_queue_manager_t **arg2 = (switch_sql_queue_manager_t **) 0 ; uint32_t arg3 ; char *arg4 = (char *) 0 ; - char *arg5 = (char *) 0 ; + uint32_t arg5 ; char *arg6 = (char *) 0 ; char *arg7 = (char *) 0 ; char *arg8 = (char *) 0 ; + char *arg9 = (char *) 0 ; switch_status_t result; arg1 = (char *)jarg1; arg2 = (switch_sql_queue_manager_t **)jarg2; arg3 = (uint32_t)jarg3; arg4 = (char *)jarg4; - arg5 = (char *)jarg5; + arg5 = (uint32_t)jarg5; arg6 = (char *)jarg6; arg7 = (char *)jarg7; arg8 = (char *)jarg8; - result = (switch_status_t)switch_sql_queue_manager_init_name((char const *)arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8); + arg9 = (char *)jarg9; + result = (switch_status_t)switch_sql_queue_manager_init_name((char const *)arg1,arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9); jresult = result; return jresult; } @@ -23976,6 +24083,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_session_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_cur_frame_set(void * jarg1, void * jarg2) { + switch_codec *arg1 = (switch_codec *) 0 ; + switch_frame_t *arg2 = (switch_frame_t *) 0 ; + + arg1 = (switch_codec *)jarg1; + arg2 = (switch_frame_t *)jarg2; + if (arg1) (arg1)->cur_frame = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_cur_frame_get(void * jarg1) { + void * jresult ; + switch_codec *arg1 = (switch_codec *) 0 ; + switch_frame_t *result = 0 ; + + arg1 = (switch_codec *)jarg1; + result = (switch_frame_t *) ((arg1)->cur_frame); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec() { void * jresult ; switch_codec *result = 0 ; @@ -27217,6 +27347,42 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_has_dtmf(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_dtmf_lock(void * jarg1) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_status_t result; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_status_t)switch_channel_dtmf_lock(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_try_dtmf_lock(void * jarg1) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_status_t result; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_status_t)switch_channel_try_dtmf_lock(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_dtmf_unlock(void * jarg1) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_status_t result; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_status_t)switch_channel_dtmf_unlock(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_queue_dtmf(void * jarg1, void * jarg2) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -27691,6 +27857,22 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_hold_record(void * jarg1 } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_state_thread_lock(void * jarg1) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + switch_channel_state_thread_lock(arg1); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_state_thread_unlock(void * jarg1) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + switch_channel_state_thread_unlock(arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) { int jresult ; switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; @@ -32155,6 +32337,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_uuid_exists(char * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_uuid_force_exists(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_bool_t result; + + arg1 = (char *)jarg1; + result = (switch_bool_t)switch_ivr_uuid_force_exists((char const *)arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_last_ping(void * jarg1) { int jresult ; switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; @@ -35117,15 +35311,17 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_xml_parse_section_string(char } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_std_datetime_check(void * jarg1, void * jarg2) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_std_datetime_check(void * jarg1, void * jarg2, char * jarg3) { int jresult ; switch_xml_t arg1 = (switch_xml_t) 0 ; int *arg2 = (int *) 0 ; + char *arg3 = (char *) 0 ; int result; arg1 = (switch_xml_t)jarg1; arg2 = (int *)jarg2; - result = (int)switch_xml_std_datetime_check(arg1,arg2); + arg3 = (char *)jarg3; + result = (int)switch_xml_std_datetime_check(arg1,arg2,(char const *)arg3); jresult = result; return jresult; } @@ -37107,6 +37303,16 @@ SWIGEXPORT void SWIGSTDCALL CSharp_consoleCleanLog(char * jarg1) { } +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_running() { + unsigned int jresult ; + bool result; + + result = (bool)running(); + jresult = result; + return jresult; +} + + SWIGEXPORT unsigned int SWIGSTDCALL CSharp_email(char * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7) { unsigned int jresult ; char *arg1 = (char *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index e3eea0582d..e560b2046c 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -1473,6 +1473,12 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_switch_mutex_t switch_core_session_get_mutex(SWIGTYPE_p_switch_core_session session) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_mutex(SWIGTYPE_p_switch_core_session.getCPtr(session)); + SWIGTYPE_p_switch_mutex_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_mutex_t(cPtr, false); + return ret; + } + public static switch_status_t switch_core_session_wake_session_thread(SWIGTYPE_p_switch_core_session session) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_wake_session_thread(SWIGTYPE_p_switch_core_session.getCPtr(session)); return ret; @@ -1594,8 +1600,9 @@ public class freeswitch { freeswitchPINVOKE.switch_core_session_hupall((int)cause); } - public static void switch_core_session_hupall_matching_var(string var_name, string var_val, switch_call_cause_t cause) { - freeswitchPINVOKE.switch_core_session_hupall_matching_var(var_name, var_val, (int)cause); + public static uint switch_core_session_hupall_matching_var_ans(string var_name, string var_val, switch_call_cause_t cause, switch_hup_type_t type) { + uint ret = freeswitchPINVOKE.switch_core_session_hupall_matching_var_ans(var_name, var_val, (int)cause, (int)type); + return ret; } public static switch_console_callback_match switch_core_session_findall_matching_var(string var_name, string var_val) { @@ -2344,6 +2351,11 @@ public class freeswitch { return ret; } + public static switch_bool_t switch_core_running() { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_core_running(); + return ret; + } + public static switch_bool_t switch_core_ready_inbound() { switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_core_ready_inbound(); return ret; @@ -2630,12 +2642,12 @@ public class freeswitch { return ret; } - public static void switch_core_sqldb_stop_thread() { - freeswitchPINVOKE.switch_core_sqldb_stop_thread(); + public static void switch_core_sqldb_pause() { + freeswitchPINVOKE.switch_core_sqldb_pause(); } - public static void switch_core_sqldb_start_thread() { - freeswitchPINVOKE.switch_core_sqldb_start_thread(); + public static void switch_core_sqldb_resume() { + freeswitchPINVOKE.switch_core_sqldb_resume(); } public static string switch_cache_db_type_name(switch_cache_db_handle_type_t type) { @@ -2830,6 +2842,11 @@ public class freeswitch { freeswitchPINVOKE.switch_core_recovery_flush(technology, profile_name); } + public static int switch_sql_queue_manager_size(SWIGTYPE_p_switch_sql_queue_manager qm, uint index) { + int ret = freeswitchPINVOKE.switch_sql_queue_manager_size(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), index); + return ret; + } + public static switch_status_t switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager qm, string sql, uint pos, switch_bool_t dup) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_push_confirm(SWIGTYPE_p_switch_sql_queue_manager.getCPtr(qm), sql, pos, (int)dup); return ret; @@ -2845,8 +2862,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_sql_queue_manager_init_name(string name, SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_init_name(name, SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); + public static switch_status_t switch_sql_queue_manager_init_name(string name, SWIGTYPE_p_p_switch_sql_queue_manager qmp, uint numq, string dsn, uint max_trans, string pre_trans_execute, string post_trans_execute, string inner_pre_trans_execute, string inner_post_trans_execute) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_sql_queue_manager_init_name(name, SWIGTYPE_p_p_switch_sql_queue_manager.getCPtr(qmp), numq, dsn, max_trans, pre_trans_execute, post_trans_execute, inner_pre_trans_execute, inner_post_trans_execute); return ret; } @@ -4103,6 +4120,21 @@ public class freeswitch { return ret; } + public static switch_status_t switch_channel_dtmf_lock(SWIGTYPE_p_switch_channel channel) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_dtmf_lock(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + + public static switch_status_t switch_channel_try_dtmf_lock(SWIGTYPE_p_switch_channel channel) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_try_dtmf_lock(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + + public static switch_status_t switch_channel_dtmf_unlock(SWIGTYPE_p_switch_channel channel) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_dtmf_unlock(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + public static switch_status_t switch_channel_queue_dtmf(SWIGTYPE_p_switch_channel channel, switch_dtmf_t dtmf) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_queue_dtmf(SWIGTYPE_p_switch_channel.getCPtr(channel), switch_dtmf_t.getCPtr(dtmf)); return ret; @@ -4283,6 +4315,14 @@ public class freeswitch { return ret; } + public static void switch_channel_state_thread_lock(SWIGTYPE_p_switch_channel channel) { + freeswitchPINVOKE.switch_channel_state_thread_lock(SWIGTYPE_p_switch_channel.getCPtr(channel)); + } + + public static void switch_channel_state_thread_unlock(SWIGTYPE_p_switch_channel channel) { + freeswitchPINVOKE.switch_channel_state_thread_unlock(SWIGTYPE_p_switch_channel.getCPtr(channel)); + } + public static switch_status_t switch_buffer_create(SWIGTYPE_p_apr_pool_t pool, SWIGTYPE_p_p_switch_buffer buffer, SWIGTYPE_p_switch_size_t max_len) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_buffer_create(SWIGTYPE_p_apr_pool_t.getCPtr(pool), SWIGTYPE_p_p_switch_buffer.getCPtr(buffer), SWIGTYPE_p_switch_size_t.getCPtr(max_len)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -5228,6 +5268,11 @@ public class freeswitch { return ret; } + public static switch_bool_t switch_ivr_uuid_force_exists(string uuid) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_ivr_uuid_force_exists(uuid); + return ret; + } + public static switch_status_t switch_ivr_dmachine_last_ping(SWIGTYPE_p_switch_ivr_dmachine dmachine) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_last_ping(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); return ret; @@ -5984,8 +6029,8 @@ public class freeswitch { return ret; } - public static int switch_xml_std_datetime_check(switch_xml xcond, SWIGTYPE_p_int offset) { - int ret = freeswitchPINVOKE.switch_xml_std_datetime_check(switch_xml.getCPtr(xcond), SWIGTYPE_p_int.getCPtr(offset)); + public static int switch_xml_std_datetime_check(switch_xml xcond, SWIGTYPE_p_int offset, string tzname) { + int ret = freeswitchPINVOKE.switch_xml_std_datetime_check(switch_xml.getCPtr(xcond), SWIGTYPE_p_int.getCPtr(offset), tzname); return ret; } @@ -6169,6 +6214,11 @@ public class freeswitch { freeswitchPINVOKE.consoleCleanLog(msg); } + public static bool running() { + bool ret = freeswitchPINVOKE.running(); + return ret; + } + public static bool email(string to, string from, string headers, string body, string file, string convert_cmd, string convert_ext) { bool ret = freeswitchPINVOKE.email(to, from, headers, body, file, convert_cmd, convert_ext); return ret; @@ -6289,6 +6339,7 @@ public class freeswitch { public static readonly string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE_get(); + public static readonly string SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_PRE_ANSWER_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_MEDIA_VARIABLE_get(); @@ -6296,6 +6347,7 @@ public class freeswitch { public static readonly string SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE_get(); + public static readonly string SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get(); public static readonly string SWITCH_CALL_TIMEOUT_VARIABLE = freeswitchPINVOKE.SWITCH_CALL_TIMEOUT_VARIABLE_get(); public static readonly string SWITCH_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_HOLDING_UUID_VARIABLE_get(); public static readonly string SWITCH_SOFT_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_SOFT_HOLDING_UUID_VARIABLE_get(); @@ -6354,6 +6406,7 @@ public class freeswitch { public static readonly int SWITCH_BITS_PER_BYTE = freeswitchPINVOKE.SWITCH_BITS_PER_BYTE_get(); public static readonly int SWITCH_DEFAULT_FILE_BUFFER_LEN = freeswitchPINVOKE.SWITCH_DEFAULT_FILE_BUFFER_LEN_get(); public static readonly int SWITCH_DTMF_LOG_LEN = freeswitchPINVOKE.SWITCH_DTMF_LOG_LEN_get(); + public static readonly int SWITCH_MAX_TRANS = freeswitchPINVOKE.SWITCH_MAX_TRANS_get(); public static readonly int SWITCH_MAX_STACKS = freeswitchPINVOKE.SWITCH_MAX_STACKS_get(); public static readonly int SWITCH_THREAD_STACKSIZE = freeswitchPINVOKE.SWITCH_THREAD_STACKSIZE_get(); public static readonly int SWITCH_SYSTEM_THREAD_STACKSIZE = freeswitchPINVOKE.SWITCH_SYSTEM_THREAD_STACKSIZE_get(); @@ -6868,6 +6921,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE_get")] public static extern string SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get")] + public static extern string SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get")] public static extern string SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get(); @@ -6889,6 +6945,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE_get")] public static extern string SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get")] + public static extern string SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get")] public static extern string SWITCH_CALL_TIMEOUT_VARIABLE_get(); @@ -7063,6 +7122,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_DTMF_LOG_LEN_get")] public static extern int SWITCH_DTMF_LOG_LEN_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_MAX_TRANS_get")] + public static extern int SWITCH_MAX_TRANS_get(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_digit_set")] public static extern void switch_dtmf_t_digit_set(HandleRef jarg1, char jarg2); @@ -7255,6 +7317,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_directories_sounds_dir_get")] public static extern string switch_directories_sounds_dir_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_directories_lib_dir_set")] + public static extern void switch_directories_lib_dir_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_directories_lib_dir_get")] + public static extern string switch_directories_lib_dir_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_directories")] public static extern IntPtr new_switch_directories(); @@ -8575,6 +8643,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_channel")] public static extern IntPtr switch_core_session_get_channel(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_mutex")] + public static extern IntPtr switch_core_session_get_mutex(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_wake_session_thread")] public static extern int switch_core_session_wake_session_thread(HandleRef jarg1); @@ -8650,8 +8721,8 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall")] public static extern void switch_core_session_hupall(int jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_matching_var")] - public static extern void switch_core_session_hupall_matching_var(string jarg1, string jarg2, int jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_hupall_matching_var_ans")] + public static extern uint switch_core_session_hupall_matching_var_ans(string jarg1, string jarg2, int jarg3, int jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_findall_matching_var")] public static extern IntPtr switch_core_session_findall_matching_var(string jarg1, string jarg2); @@ -9103,6 +9174,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_ready")] public static extern int switch_core_ready(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_running")] + public static extern int switch_core_running(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_ready_inbound")] public static extern int switch_core_ready_inbound(); @@ -9280,11 +9354,11 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_preprocess_session")] public static extern int switch_ivr_preprocess_session(HandleRef jarg1, string jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_stop_thread")] - public static extern void switch_core_sqldb_stop_thread(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_pause")] + public static extern void switch_core_sqldb_pause(); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_start_thread")] - public static extern void switch_core_sqldb_start_thread(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_sqldb_resume")] + public static extern void switch_core_sqldb_resume(); [DllImport("mod_managed", EntryPoint="CSharp_CACHE_DB_LEN_get")] public static extern int CACHE_DB_LEN_get(); @@ -9508,6 +9582,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_recovery_flush")] public static extern void switch_core_recovery_flush(string jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_size")] + public static extern int switch_sql_queue_manager_size(HandleRef jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_push_confirm")] public static extern int switch_sql_queue_manager_push_confirm(HandleRef jarg1, string jarg2, uint jarg3, int jarg4); @@ -9518,7 +9595,7 @@ class freeswitchPINVOKE { public static extern int switch_sql_queue_manager_destroy(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_init_name")] - public static extern int switch_sql_queue_manager_init_name(string jarg1, HandleRef jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8); + public static extern int switch_sql_queue_manager_init_name(string jarg1, HandleRef jarg2, uint jarg3, string jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9); [DllImport("mod_managed", EntryPoint="CSharp_switch_sql_queue_manager_start")] public static extern int switch_sql_queue_manager_start(HandleRef jarg1); @@ -12313,6 +12390,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_session_get")] public static extern IntPtr switch_codec_session_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_cur_frame_set")] + public static extern void switch_codec_cur_frame_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_cur_frame_get")] + public static extern IntPtr switch_codec_cur_frame_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec")] public static extern IntPtr new_switch_codec(); @@ -13078,6 +13161,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_has_dtmf")] public static extern IntPtr switch_channel_has_dtmf(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_dtmf_lock")] + public static extern int switch_channel_dtmf_lock(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_try_dtmf_lock")] + public static extern int switch_channel_try_dtmf_lock(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_dtmf_unlock")] + public static extern int switch_channel_dtmf_unlock(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_queue_dtmf")] public static extern int switch_channel_queue_dtmf(HandleRef jarg1, HandleRef jarg2); @@ -13192,6 +13284,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_record")] public static extern IntPtr switch_channel_get_hold_record(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_state_thread_lock")] + public static extern void switch_channel_state_thread_lock(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_state_thread_unlock")] + public static extern void switch_channel_state_thread_unlock(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")] public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -14101,6 +14199,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_uuid_exists")] public static extern int switch_ivr_uuid_exists(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_uuid_force_exists")] + public static extern int switch_ivr_uuid_force_exists(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_last_ping")] public static extern int switch_ivr_dmachine_last_ping(HandleRef jarg1); @@ -14762,7 +14863,7 @@ class freeswitchPINVOKE { public static extern uint switch_xml_parse_section_string(string jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_std_datetime_check")] - public static extern int switch_xml_std_datetime_check(HandleRef jarg1, HandleRef jarg2); + public static extern int switch_xml_std_datetime_check(HandleRef jarg1, HandleRef jarg2, string jarg3); [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_locate_language")] public static extern int switch_xml_locate_language(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, HandleRef jarg5, HandleRef jarg6, string jarg7); @@ -15271,6 +15372,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_consoleCleanLog")] public static extern void consoleCleanLog(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_running")] + public static extern bool running(); + [DllImport("mod_managed", EntryPoint="CSharp_email")] public static extern bool email(string jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7); @@ -21736,7 +21840,8 @@ namespace FreeSWITCH.Native { SAF_SUPPORT_NOMEDIA = (1 << 0), SAF_ROUTING_EXEC = (1 << 1), SAF_MEDIA_TAP = (1 << 2), - SAF_ZOMBIE_EXEC = (1 << 3) + SAF_ZOMBIE_EXEC = (1 << 3), + SAF_NO_LOOPBACK = (1 << 4) } } @@ -24116,6 +24221,7 @@ public enum switch_channel_flag_t { CF_OUTBOUND, CF_EARLY_MEDIA, CF_BRIDGE_ORIGINATOR, + CF_UUID_BRIDGE_ORIGINATOR, CF_TRANSFER, CF_ACCEPT_CNG, CF_REDIRECT, @@ -24197,6 +24303,7 @@ public enum switch_channel_flag_t { CF_NO_CDR, CF_EARLY_OK, CF_MEDIA_TRANS, + CF_HOLD_ON_BRIDGE, CF_FLAG_MAX } @@ -24876,6 +24983,17 @@ public class switch_codec : IDisposable { } } + public switch_frame cur_frame { + set { + freeswitchPINVOKE.switch_codec_cur_frame_set(swigCPtr, switch_frame.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_cur_frame_get(swigCPtr); + switch_frame ret = (cPtr == IntPtr.Zero) ? null : new switch_frame(cPtr, false); + return ret; + } + } + public switch_codec() : this(freeswitchPINVOKE.new_switch_codec(), true) { } @@ -26639,6 +26757,16 @@ public class switch_directories : IDisposable { } } + public string lib_dir { + set { + freeswitchPINVOKE.switch_directories_lib_dir_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_directories_lib_dir_get(swigCPtr); + return ret; + } + } + public switch_directories() : this(freeswitchPINVOKE.new_switch_directories(), true) { } @@ -28678,6 +28806,23 @@ public class switch_hold_record_t : IDisposable { namespace FreeSWITCH.Native { +public enum switch_hup_type_t { + SHT_NONE = 0, + SHT_UNANSWERED = (1 << 0), + SHT_ANSWERED = (1 << 1) +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + using System; using System.Runtime.InteropServices; diff --git a/src/mod/languages/mod_perl/freeswitch.pm b/src/mod/languages/mod_perl/freeswitch.pm index ffae0be801..17fdc67677 100644 --- a/src/mod/languages/mod_perl/freeswitch.pm +++ b/src/mod/languages/mod_perl/freeswitch.pm @@ -52,6 +52,7 @@ package freeswitch; *getGlobalVariable = *freeswitchc::getGlobalVariable; *consoleLog = *freeswitchc::consoleLog; *consoleCleanLog = *freeswitchc::consoleCleanLog; +*running = *freeswitchc::running; *email = *freeswitchc::email; *console_log = *freeswitchc::console_log; *console_clean_log = *freeswitchc::console_clean_log; diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp index dd4b385299..e2ffffeea9 100644 --- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp +++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp @@ -2051,6 +2051,24 @@ XS(_wrap_consoleCleanLog) { } +XS(_wrap_running) { + { + bool result; + int argvi = 0; + dXSARGS; + + if ((items < 0) || (items > 0)) { + SWIG_croak("Usage: running();"); + } + result = (bool)running(); + ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ; + XSRETURN(argvi); + fail: + SWIG_croak_null(); + } +} + + XS(_wrap_email) { { char *arg1 = (char *) 0 ; @@ -9642,6 +9660,7 @@ static swig_command_info swig_commands[] = { {"freeswitchc::getGlobalVariable", _wrap_getGlobalVariable}, {"freeswitchc::consoleLog", _wrap_consoleLog}, {"freeswitchc::consoleCleanLog", _wrap_consoleCleanLog}, +{"freeswitchc::running", _wrap_running}, {"freeswitchc::email", _wrap_email}, {"freeswitchc::new_IVRMenu", _wrap_new_IVRMenu}, {"freeswitchc::delete_IVRMenu", _wrap_delete_IVRMenu}, diff --git a/src/mod/languages/mod_python/freeswitch.py b/src/mod/languages/mod_python/freeswitch.py index 1df258dc0c..51e3e652f6 100644 --- a/src/mod/languages/mod_python/freeswitch.py +++ b/src/mod/languages/mod_python/freeswitch.py @@ -52,6 +52,7 @@ setGlobalVariable = _freeswitch.setGlobalVariable getGlobalVariable = _freeswitch.getGlobalVariable consoleLog = _freeswitch.consoleLog consoleCleanLog = _freeswitch.consoleCleanLog +running = _freeswitch.running email = _freeswitch.email class IVRMenu(_object): __swig_setmethods__ = {} diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index d2098edd1c..b12d4c7614 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -3133,6 +3133,19 @@ fail: } +SWIGINTERN PyObject *_wrap_running(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + bool result; + + if (!PyArg_ParseTuple(args,(char *)":running")) SWIG_fail; + result = (bool)running(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_email(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; char *arg1 = (char *) 0 ; @@ -9169,6 +9182,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"getGlobalVariable", _wrap_getGlobalVariable, METH_VARARGS, NULL}, { (char *)"consoleLog", _wrap_consoleLog, METH_VARARGS, NULL}, { (char *)"consoleCleanLog", _wrap_consoleCleanLog, METH_VARARGS, NULL}, + { (char *)"running", _wrap_running, METH_VARARGS, NULL}, { (char *)"email", _wrap_email, METH_VARARGS, NULL}, { (char *)"new_IVRMenu", _wrap_new_IVRMenu, METH_VARARGS, NULL}, { (char *)"delete_IVRMenu", _wrap_delete_IVRMenu, METH_VARARGS, NULL}, diff --git a/src/switch_core.c b/src/switch_core.c index 1cc0dd0569..23e08d857a 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2428,6 +2428,11 @@ SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void) return runtime.flags; } +SWITCH_DECLARE(switch_bool_t) switch_core_running(void) +{ + return runtime.running ? SWITCH_TRUE : SWITCH_FALSE; +} + SWITCH_DECLARE(switch_bool_t) switch_core_ready(void) { return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE; diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 64ca2fc120..f1ebe3f4e6 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -1205,6 +1205,11 @@ SWITCH_DECLARE(char *) getGlobalVariable(char *var_name) } +SWITCH_DECLARE(bool) running(void) +{ + return switch_core_running() ? true : false; +} + SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg) { return console_log(level_str, msg); From ad49dabd8c5c6ed0f2c708a9fc2ec42d08d1990a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 16:19:49 -0600 Subject: [PATCH 489/512] fix regression in media for recovered calls --- src/mod/endpoints/mod_sofia/sofia_glue.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 31ea2bb66b..388e647cc0 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3254,13 +3254,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f } - if (!sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { - if (switch_rtp_ready(tech_pvt->rtp_session)) { - if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && !switch_rtp_ready(tech_pvt->video_rtp_session)) { - goto video; - } else { - goto end; - } + if (!sofia_test_flag(tech_pvt, TFLAG_REINVITE) && !sofia_test_flag(tech_pvt, TFLAG_SDP) && switch_rtp_ready(tech_pvt->rtp_session)) { + if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && !switch_rtp_ready(tech_pvt->video_rtp_session)) { + goto video; + } else { + goto end; } } From 92945f8a01851c6833d3f0106a7b6333a7d1c507 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Nov 2012 18:09:04 -0600 Subject: [PATCH 490/512] FS-4836 --- src/switch_core_session.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index e1093c50f3..c2fb0ea8d6 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -891,9 +891,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_message(switch_core_se switch_core_session_kill_channel(session, SWITCH_SIG_BREAK); - if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_THREAD_SLEEPING)) { - switch_core_session_wake_session_thread(session); - } + switch_core_session_wake_session_thread(session); + } return status; @@ -975,9 +974,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_signal_data(switch_cor switch_core_session_kill_channel(session, SWITCH_SIG_BREAK); - if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_THREAD_SLEEPING)) { - switch_core_session_wake_session_thread(session); - } + switch_core_session_wake_session_thread(session); + } return status; @@ -1048,9 +1046,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_event(switch_core_sess *event = NULL; status = SWITCH_STATUS_SUCCESS; - if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_THREAD_SLEEPING)) { - switch_core_session_wake_session_thread(session); - } + switch_core_session_wake_session_thread(session); } } From 827b680afc3d8d4a65764ddd4655427f36dd10e4 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 27 Nov 2012 13:48:57 -0500 Subject: [PATCH 491/512] fix regressions in sql stuff --- src/mod/endpoints/mod_sofia/mod_sofia.h | 5 +++- src/mod/endpoints/mod_sofia/sofia_reg.c | 31 ++++++++++++++----------- src/switch_core_sqldb.c | 13 +++++++---- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 45f73c5866..dc62141f2e 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -859,6 +859,9 @@ struct callback_t { switch_size_t len; switch_console_callback_match_t *list; int matches; + time_t time; + const char *contact_str; + long exptime; }; typedef enum { @@ -1189,7 +1192,7 @@ switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *sess char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type); void sofia_glue_tech_simplify(private_object_t *tech_pvt); switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host); -switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host); +switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host, time_t reg_time, const char *contact_str, long exptime); switch_bool_t sofia_glue_profile_exists(const char *key); void sofia_glue_global_siptrace(switch_bool_t on); void sofia_glue_global_capture(switch_bool_t on); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index d2bea6e5ea..7961f24e08 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -524,7 +524,11 @@ int sofia_reg_find_reg_with_positive_expires_callback(void *pArg, int argc, char long int expires; char *contact = NULL; - expires = atol(argv[1]) - 60 - (long) switch_epoch_time_now(NULL); + if (argv[0] && cbt->contact_str && !strcasecmp(argv[0], cbt->contact_str)) { + expires = cbt->exptime; + } else { + expires = atol(argv[1]) - 60 - (long) cbt->time; + } if (expires > 0) { dst = sofia_glue_get_destination(argv[0]); @@ -930,7 +934,7 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p } -switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host) +switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host, time_t reg_time, const char *contact_str, long exptime) { struct callback_t cbt = { 0 }; char *sql; @@ -947,6 +951,10 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_mu sql = switch_mprintf("select contact,expires from sip_registrations where sip_user='%q'", user); } + cbt.time = reg_time; + cbt.contact_str = contact_str; + cbt.exptime = exptime; + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_find_reg_with_positive_expires_callback, &cbt); free(sql); @@ -1075,6 +1083,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand int send_pres = 0; int is_tls = 0, is_tcp = 0; char expbuf[35] = ""; + time_t reg_time = switch_epoch_time_now(NULL); + if (v_event && *v_event) pres_on_reg = switch_event_get_header(*v_event, "send-presence-on-register"); @@ -1577,7 +1587,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand 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, + switch_core_add_registration(to_user, reg_host, call_id, url, (long) reg_time + (long) exptime + 60, network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp", reg_meta); switch_safe_free(url); @@ -1590,7 +1600,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host) " "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q')", call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "", - contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime + 60, + contact_str, reg_desc, rpid, (long) reg_time + (long) exptime + 60, agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm, mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host); } else { @@ -1602,7 +1612,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand sub_host, network_ip, network_port_c, profile->presence_hosts ? profile->presence_hosts : "", guess_ip4, guess_ip4, mod_sofia_globals.hostname, mod_sofia_globals.hostname, - (long) switch_epoch_time_now(NULL) + (long) exptime + 60, + (long) reg_time + (long) exptime + 60, to_user, username, reg_host, contact_str); } @@ -1794,7 +1804,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand TAG_IF(!zstr(expbuf), SIPTAG_EXPIRES_STR(expbuf)), NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END()); - } else if ((contact_list = sofia_reg_find_reg_url_with_positive_expires_multi(profile, from_user, reg_host))) { + } else if ((contact_list = sofia_reg_find_reg_url_with_positive_expires_multi(profile, from_user, reg_host, reg_time, contact_str, exptime))) { /* all + 1 tag_i elements initialized as NULL - last one implies TAG_END() */ switch_zmalloc(contact_tags, sizeof(*contact_tags) * (contact_list->count + 1)); i = 0; @@ -2358,7 +2368,6 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (zstr(np)) { nonce_cb_t cb = { 0 }; long nc_long = 0; - int sanity = 0; first = 1; @@ -2374,13 +2383,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, switch_assert(sql != NULL); - do { - if (sanity) { - switch_yield(100000 * sanity); - } - sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nonce_callback, &cb); - } while(nc_long < 2 && ++sanity < 10 && zstr(np)); - + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_reg_nonce_callback, &cb); free(sql); //if (!sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, np, nplen)) { diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 3ad163b54e..c1381bd351 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1706,11 +1706,14 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread, check: - if ((lc = qm_ttl(qm)) < qm->max_trans / 4) { - switch_yield(500000); - if ((lc = qm_ttl(qm)) == 0) { - switch_thread_cond_wait(qm->cond, qm->cond_mutex); - } + if ((lc = qm_ttl(qm)) == 0) { + switch_thread_cond_wait(qm->cond, qm->cond_mutex); + } + + i = 4; + + while (--i > 0 && (lc = qm_ttl(qm)) < qm->max_trans / 4) { + switch_yield(50000); } } From f1a89fb016dbefe6310702a68450c21dd5a42765 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 28 Nov 2012 23:11:31 -0600 Subject: [PATCH 492/512] let mod_fifo use sql_queue_manager --- src/mod/applications/mod_fifo/mod_fifo.c | 124 +++++++++++++---------- 1 file changed, 73 insertions(+), 51 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 78e8950b40..8970803f44 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -594,6 +594,11 @@ static struct { switch_thread_t *node_thread; int debug; struct fifo_node *nodes; + char *pre_trans_execute; + char *post_trans_execute; + char *inner_pre_trans_execute; + char *inner_post_trans_execute; + switch_sql_queue_manager_t *qm; } globals; @@ -742,7 +747,29 @@ switch_cache_db_handle_t *fifo_get_db_handle(void) return dbh; } +static switch_status_t fifo_execute_sql_queued(char **sqlp, switch_bool_t sql_already_dynamic, switch_bool_t block) +{ + int index = 1; + char *sql; + switch_assert(sqlp && *sqlp); + sql = *sqlp; + + + if (switch_stristr("insert", sql)) { + index = 0; + } + + switch_sql_queue_manager_push(globals.qm, sql, index, !sql_already_dynamic); + + if (sql_already_dynamic) { + *sqlp = NULL; + } + + return SWITCH_STATUS_SUCCESS; + +} +#if 0 static switch_status_t fifo_execute_sql(char *sql, switch_mutex_t *mutex) { switch_cache_db_handle_t *dbh = NULL; @@ -771,6 +798,7 @@ static switch_status_t fifo_execute_sql(char *sql, switch_mutex_t *mutex) return status; } +#endif static switch_bool_t fifo_execute_sql_callback(switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata) { @@ -937,9 +965,7 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(consumer_session)); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); - + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); switch_channel_set_variable(consumer_channel, "fifo_status", "WAITING"); @@ -1025,8 +1051,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ switch_str_nil(msg->string_array_arg[0]), switch_str_nil(msg->string_array_arg[1]), switch_core_session_get_uuid(session)); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); goto end; default: goto end; @@ -1124,8 +1149,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ ); } - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); epoch_start = (long)switch_epoch_time_now(NULL); @@ -1381,8 +1405,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void struct call_helper *h = cbh->rows[i]; char *sql = switch_mprintf("update fifo_outbound set ring_count=ring_count+1 where uuid='%s'", h->uuid); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } @@ -1424,8 +1447,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void struct call_helper *h = cbh->rows[i]; char *sql = switch_mprintf("update fifo_outbound set ring_count=ring_count-1 " "where uuid='%q' and ring_count > 0", h->uuid); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } } @@ -1439,8 +1461,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void "outbound_fail_total_count = outbound_fail_total_count+1, " "next_avail=%ld + lag + 1 where uuid='%q' and ring_count > 0", (long) switch_epoch_time_now(NULL), h->uuid); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } } @@ -1497,8 +1518,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void for (i = 0; i < cbh->rowcount; i++) { struct call_helper *h = cbh->rows[i]; char *sql = switch_mprintf("update fifo_outbound set ring_count=ring_count-1 where uuid='%q' and ring_count > 0", h->uuid); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } end: @@ -1608,8 +1628,7 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) sql = switch_mprintf("update fifo_outbound set ring_count=ring_count+1 where uuid='%s'", h->uuid); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); status = switch_ivr_originate(NULL, &session, &cause, originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL); free(originate_string); @@ -1619,8 +1638,7 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) sql = switch_mprintf("update fifo_outbound set ring_count=ring_count-1, " "outbound_fail_count=outbound_fail_count+1, next_avail=%ld + lag + 1 where uuid='%q'", (long) switch_epoch_time_now(NULL), h->uuid); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", node->name); @@ -2123,15 +2141,12 @@ static void dec_use_count(switch_core_session_t *session, switch_bool_t send_eve sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(session)); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); del_bridge_call(outbound_id); sql = switch_mprintf("update fifo_outbound set use_count=use_count-1, stop_time=%ld, next_avail=%ld + lag + 1 where use_count > 0 and uuid='%q'", now, now, outbound_id); - - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } if (send_event) { @@ -2198,9 +2213,7 @@ SWITCH_STANDARD_APP(fifo_track_call_function) sql = switch_mprintf("update fifo_outbound set stop_time=0,start_time=%ld,outbound_fail_count=0,use_count=use_count+1,%s=%s+1,%s=%s+1 where uuid='%q'", (long) switch_epoch_time_now(NULL), col1, col1, col2, col2, data); - fifo_execute_sql(sql, globals.sql_mutex); - - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { @@ -2235,8 +2248,7 @@ static void fifo_caller_add(fifo_node_t *node, switch_core_session_t *session) switch_str_nil(switch_channel_get_variable(channel, "caller_id_number")), switch_epoch_time_now(NULL)); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); } static void fifo_caller_del(const char *uuid) @@ -2249,8 +2261,7 @@ static void fifo_caller_del(const char *uuid) sql = switch_mprintf("delete from fifo_callers"); } - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); } @@ -3018,8 +3029,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_epoch_time_now(NULL), outbound_id); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } add_bridge_call(switch_core_session_get_uuid(other_session)); @@ -3038,8 +3048,7 @@ SWITCH_STANDARD_APP(fifo_function) ); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(other_session)); @@ -3055,8 +3064,7 @@ SWITCH_STANDARD_APP(fifo_function) "outbound_call_count=outbound_call_count+1, next_avail=%ld + lag + 1 where uuid='%s' and use_count > 0", now, now, outbound_id); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); del_bridge_call(outbound_id); @@ -3088,8 +3096,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable_printf(other_channel, "fifo_bridge_seconds", "%d", epoch_end - epoch_start); sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(session)); - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); switch_core_media_bug_pause(session); @@ -4009,6 +4016,14 @@ static switch_status_t load_config(int reload, int del_all) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); } + } else if (!strcasecmp(var, "db-pre-trans-execute") && !zstr(val)) { + globals.pre_trans_execute = switch_core_strdup(globals.pool, val); + } else if (!strcasecmp(var, "db-post-trans-execute") && !zstr(val)) { + globals.post_trans_execute = switch_core_strdup(globals.pool, val); + } else if (!strcasecmp(var, "db-inner-pre-trans-execute") && !zstr(val)) { + globals.inner_pre_trans_execute = switch_core_strdup(globals.pool, val); + } else if (!strcasecmp(var, "db-inner-post-trans-execute") && !zstr(val)) { + globals.inner_post_trans_execute = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "delete-all-outbound-member-on-startup")) { delete_all_outbound_member_on_startup = switch_true(val); } @@ -4019,6 +4034,18 @@ static switch_status_t load_config(int reload, int del_all) globals.dbname = "fifo"; } + switch_sql_queue_manager_init_name("fifo", + &globals.qm, + 2, + globals.odbc_dsn ? globals.odbc_dsn : globals.dbname, + SWITCH_MAX_TRANS, + globals.pre_trans_execute, + globals.post_trans_execute, + globals.inner_pre_trans_execute, + globals.inner_post_trans_execute); + + switch_sql_queue_manager_start(globals.qm); + if (!(dbh = fifo_get_db_handle())) { @@ -4036,8 +4063,8 @@ static switch_status_t load_config(int reload, int del_all) switch_cache_db_release_db_handle(&dbh); if (!reload) { - fifo_execute_sql("update fifo_outbound set start_time=0,stop_time=0,ring_count=0,use_count=0," - "outbound_call_count=0,outbound_fail_count=0 where static=0", globals.sql_mutex); + char *sql= "update fifo_outbound set start_time=0,stop_time=0,ring_count=0,use_count=0,outbound_call_count=0,outbound_fail_count=0 where static=0"; + fifo_execute_sql_queued(&sql, SWITCH_FALSE, SWITCH_TRUE); } if (reload) { @@ -4060,8 +4087,7 @@ static switch_status_t load_config(int reload, int del_all) sql = switch_mprintf("delete from fifo_outbound where static=1 and hostname='%q'", globals.hostname); } - fifo_execute_sql(sql, globals.sql_mutex); - switch_safe_free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); if (!(node = switch_core_hash_find(globals.fifo_hash, MANUAL_QUEUE_NAME))) { node = create_node(MANUAL_QUEUE_NAME, 0, globals.sql_mutex); @@ -4214,8 +4240,7 @@ static switch_status_t load_config(int reload, int del_all) (long) switch_epoch_time_now(NULL)); switch_assert(sql); - fifo_execute_sql(sql, globals.sql_mutex); - free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); free(name_dup); node->has_outbound = 1; node->member_count++; @@ -4270,8 +4295,7 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co sql = switch_mprintf("delete from fifo_outbound where fifo_name='%q' and uuid = '%q'", fifo_name, digest); switch_assert(sql); - fifo_execute_sql(sql, globals.sql_mutex); - free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); switch_mutex_lock(globals.mutex); @@ -4293,8 +4317,7 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co digest, fifo_name, originate_string, simo_count, 0, timeout, lag, 0, (long) expires, globals.hostname, taking_calls, (long)switch_epoch_time_now(NULL)); switch_assert(sql); - fifo_execute_sql(sql, globals.sql_mutex); - free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); free(name_dup); cbt.buf = outbound_count; @@ -4329,8 +4352,7 @@ static void fifo_member_del(char *fifo_name, char *originate_string) sql = switch_mprintf("delete from fifo_outbound where fifo_name='%q' and uuid = '%q' and hostname='%q'", fifo_name, digest, globals.hostname); switch_assert(sql); - fifo_execute_sql(sql, globals.sql_mutex); - free(sql); + fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); switch_mutex_lock(globals.mutex); if (!(node = switch_core_hash_find(globals.fifo_hash, fifo_name))) { From d4f8a79299c132b9226c8b09a36f5b35f31a8a02 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 28 Nov 2012 23:12:35 -0600 Subject: [PATCH 493/512] try to improve audio stream sync --- src/mod/endpoints/mod_sofia/mod_sofia.c | 12 +++++- src/mod/endpoints/mod_sofia/mod_sofia.h | 3 ++ src/mod/endpoints/mod_sofia/sofia.c | 2 +- src/switch_channel.c | 4 +- src/switch_ivr_bridge.c | 5 ++- src/switch_ivr_originate.c | 14 +++---- src/switch_rtp.c | 55 ++++++++++++++++--------- 7 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index deedea0802..0b11abf703 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1565,7 +1565,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (switch_core_session_in_thread(session)) { de->session = session; } - sofia_process_dispatch_event(&de); + + if (de->data->e_event == nua_i_cancel || de->data->e_event == nua_i_bye) { + sofia_set_flag(tech_pvt, TFLAG_SIGDEAD); + } + + if (!sofia_test_flag(tech_pvt, TFLAG_SIGDEAD) && (switch_channel_media_up(channel) || switch_channel_get_state(channel) > CS_ROUTING)) { + sofia_queue_message(de); + } else { + sofia_process_dispatch_event(&de); + } + switch_mutex_unlock(tech_pvt->sofia_mutex); goto end; } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index dc62141f2e..44f17a320f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -353,6 +353,7 @@ typedef enum { TFLAG_PASS_ACK, TFLAG_CRYPTO_RECOVER, TFLAG_DROP_DTMF, + TFLAG_SIGDEAD, /* No new flags below this line */ TFLAG_MAX } TFLAGS; @@ -1205,6 +1206,7 @@ void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np); void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on); void sofia_process_dispatch_event(sofia_dispatch_event_t **dep); +void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep); char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool); void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now); void sofia_msg_thread_start(int idx); @@ -1215,6 +1217,7 @@ private_object_t *sofia_glue_new_pvt(switch_core_session_t *session); switch_status_t sofia_init(void); void sofia_glue_fire_events(sofia_profile_t *profile); void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event); +void sofia_queue_message(sofia_dispatch_event_t *de); /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 092b1dca27..ed3428555e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1686,7 +1686,7 @@ void sofia_msg_thread_start(int idx) } //static int foo = 0; -static void sofia_queue_message(sofia_dispatch_event_t *de) +void sofia_queue_message(sofia_dispatch_event_t *de) { int launch = 0; diff --git a/src/switch_channel.c b/src/switch_channel.c index 903bb6be76..9ac36c589a 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -291,7 +291,7 @@ SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_str2callstate(const ch SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel, const char *file, const char *func, int line) { - if (switch_channel_media_ready(channel)) { + if (switch_channel_media_up(channel)) { switch_core_session_message_t msg = { 0 }; msg.message_id = SWITCH_MESSAGE_INDICATE_AUDIO_SYNC; msg.from = channel->name; @@ -3446,7 +3446,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan switch_channel_presence(channel, "unknown", "answered", NULL); - switch_channel_audio_sync(channel); + //switch_channel_audio_sync(channel); switch_core_recovery_track(channel->session); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 7eb96b287a..b8b04cdbd0 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1232,8 +1232,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_audio_sync(caller_channel); - switch_channel_audio_sync(peer_channel); + //switch_channel_audio_sync(caller_channel); + //switch_channel_audio_sync(peer_channel); b_leg->session = peer_session; switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid)); @@ -1368,6 +1368,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_private(peer_channel, "_bridge_", b_leg); switch_channel_set_state(peer_channel, CS_EXCHANGE_MEDIA); + audio_bridge_thread(NULL, (void *) a_leg); switch_channel_clear_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index d8a555c512..52d903c79d 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -3115,7 +3115,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess do_continue: if (!read_packet) { - switch_cond_next(); + switch_yield(20000); } } @@ -3373,13 +3373,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { status = SWITCH_STATUS_SUCCESS; } else { - status = switch_channel_answer(caller_channel); + status = switch_channel_answer(caller_channel); } } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { status = SWITCH_STATUS_SUCCESS; } else { - status = switch_channel_pre_answer(caller_channel); + status = switch_channel_pre_answer(caller_channel); } } else { status = SWITCH_STATUS_SUCCESS; @@ -3707,11 +3707,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_cond_next(); } - switch_channel_audio_sync(bchan); + //switch_channel_audio_sync(bchan); - if (caller_channel) { - switch_channel_audio_sync(caller_channel); - } + //if (caller_channel) { + // switch_channel_audio_sync(caller_channel); + //} } if (oglobals.session) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index e469066fce..ec003f9569 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -67,6 +67,7 @@ static switch_port_t START_PORT = RTP_START_PORT; static switch_port_t END_PORT = RTP_END_PORT; static switch_port_t NEXT_PORT = RTP_START_PORT; static switch_mutex_t *port_lock = NULL; +static void do_flush(switch_rtp_t *rtp_session); typedef srtp_hdr_t rtp_hdr_t; @@ -2071,6 +2072,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host, rtp_session->ready = 2; rtp_session->rx_host = switch_core_strdup(rtp_session->pool, rx_host); rtp_session->rx_port = rx_port; + //switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_FLUSH); } else { switch_rtp_release_port(rx_host, rx_port); } @@ -2761,7 +2763,7 @@ SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { - switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_FLUSH); + switch (flush) { case SWITCH_RTP_FLUSH_STICK: switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_STICKY_FLUSH); @@ -2780,6 +2782,7 @@ static void do_flush(switch_rtp_t *rtp_session) { int was_blocking = 0; switch_size_t bytes; + uint32_t flushed = 0; if (!switch_rtp_ready(rtp_session) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) || @@ -2787,11 +2790,11 @@ static void do_flush(switch_rtp_t *rtp_session) ) { 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"); @@ -2869,34 +2872,35 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->last_seq && rtp_session->last_seq+1 != seq) { #ifdef DEBUG_MISSED_SEQ + //2012-11-28 18:33:11.799070 [ERR] switch_rtp.c:2883 Missed -65536 RTP frames from sequence [65536] to [-1] (missed). Time since last read [20021] switch_size_t flushed_packets_diff = rtp_session->stats.inbound.flush_packet_count - rtp_session->last_flush_packet_count; switch_size_t num_missed = (switch_size_t)seq - (rtp_session->last_seq+1); if (num_missed == 1) { /* We missed one packet */ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Missed one RTP frame with sequence [%d]%s. Time since last read [%d]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missed one RTP frame with sequence [%d]%s. Time since last read [%ld]\n", rtp_session->last_seq+1, (flushed_packets_diff == 1) ? " (flushed by FS)" : " (missed)", rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); } else { /* We missed multiple packets */ if (flushed_packets_diff == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, - "Missed %d RTP frames from sequence [%d] to [%d] (missed). Time since last read [%d]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %ld RTP frames from sequence [%d] to [%d] (missed). Time since last read [%ld]\n", num_missed, rtp_session->last_seq+1, seq-1, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); } else if (flushed_packets_diff == num_missed) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, - "Missed %d RTP frames from sequence [%d] to [%d] (flushed by FS). Time since last read [%d]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %ld RTP frames from sequence [%d] to [%d] (flushed by FS). Time since last read [%ld]\n", num_missed, rtp_session->last_seq+1, seq-1, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); } else if (num_missed > flushed_packets_diff) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, - "Missed %d RTP frames from sequence [%d] to [%d] (%d packets flushed by FS, %d packets missed)." - " Time since last read [%d]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %ld RTP frames from sequence [%d] to [%d] (%ld packets flushed by FS, %ld packets missed)." + " Time since last read [%ld]\n", num_missed, rtp_session->last_seq+1, seq-1, flushed_packets_diff, num_missed-flushed_packets_diff, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, - "Missed %d RTP frames from sequence [%d] to [%d] (%d packets flushed by FS). Time since last read [%d]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %ld RTP frames from sequence [%d] to [%d] (%ld packets flushed by FS). Time since last read [%ld]\n", num_missed, rtp_session->last_seq+1, seq-1, flushed_packets_diff, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); } @@ -3240,15 +3244,17 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (bytes) { if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) { - /* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Trigger %d\n", rtp_session->hot_hits); */ - rtp_session->hot_hits += rtp_session->samples_per_interval; + rtp_session->hot_hits++;//+= rtp_session->samples_per_interval; + + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s Trigger %d\n", + //switch_core_session_get_name(session), + // rtp_session->hot_hits); } else { rtp_session->hot_hits = 0; } } - if (rtp_session->hot_hits >= rtp_session->samples_per_second * 5) { - switch_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); + if (rtp_session->hot_hits > 1 && !rtp_session->sync_packets) {// >= (rtp_session->samples_per_second * 30)) { hot_socket = 1; } } else { @@ -3256,19 +3262,27 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - if (hot_socket) { + + if (hot_socket) { + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Skip timer\n"); rtp_session->sync_packets++; switch_core_timer_sync(&rtp_session->timer); + } else { + if (rtp_session->sync_packets) { #if 0 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Auto-Flush catching up %d packets (%d)ms.\n", rtp_session->sync_packets, (rtp_session->ms_per_packet * rtp_session->sync_packets) / 1000); #endif - rtp_session->sync_packets = 0; + //switch_core_timer_sync(&rtp_session->timer); + } else { + + switch_core_timer_next(&rtp_session->timer); } - switch_core_timer_next(&rtp_session->timer); + + rtp_session->sync_packets = 0; } } @@ -4787,3 +4801,4 @@ SWITCH_DECLARE(void *) switch_rtp_get_private(switch_rtp_t *rtp_session) * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4: */ + From fdca268aed9daa35a618cb9ac98732a44ce204fd Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 29 Nov 2012 01:33:12 -0600 Subject: [PATCH 494/512] tweak --- src/mod/applications/mod_snapshot/mod_snapshot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_snapshot/mod_snapshot.c b/src/mod/applications/mod_snapshot/mod_snapshot.c index 08c83dea00..bdbbcb4bc4 100644 --- a/src/mod/applications/mod_snapshot/mod_snapshot.c +++ b/src/mod/applications/mod_snapshot/mod_snapshot.c @@ -328,7 +328,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snapshot_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_API(api_interface, "uuid_snapshot", "Snapshot API", snapshot_function, SNAP_API_SYNTAX); - SWITCH_ADD_APP(app_interface, "snapshot", "", "", snapshot_app_function, SNAP_SYNTAX, SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "snapshot", "", "", snapshot_app_function, SNAP_SYNTAX, SAF_MEDIA_TAP); switch_console_set_complete("add uuid_snapshot ::console::list_uuid"); /* indicate that the module should continue to be loaded */ From 16eaa729b1499efb117d7c54b9f8708d18c144f5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 08:30:29 -0600 Subject: [PATCH 495/512] FS-4889 --resolve --- src/mod/applications/mod_conference/mod_conference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index d5ea7e702a..2f5456106f 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -8620,6 +8620,7 @@ static void call_setup_event_handler(switch_event_t *event) switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_status", "true"); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_call_id", call_id); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_invite_domain", domain); if (!strncasecmp(ostr, "url+", 4)) { ostr += 4; From a9267b1faf684b5d50c7014b6b9bb7645aac4757 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 08:35:28 -0600 Subject: [PATCH 496/512] add mutex around hash as this code can now be executed concurrently --- src/mod/endpoints/mod_sofia/sofia_reg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 7961f24e08..507ace4391 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1019,6 +1019,7 @@ static int debounce_check(sofia_profile_t *profile, const char *user, const char snprintf(key, sizeof(key), "%s%s", user, host); + switch_mutex_lock(profile->ireg_mutex); if ((last = switch_core_hash_find(profile->mwi_debounce_hash, key))) { if (now - *last > 30) { *last = now; @@ -1030,6 +1031,7 @@ static int debounce_check(sofia_profile_t *profile, const char *user, const char switch_core_hash_insert(profile->mwi_debounce_hash, key, last); r = 1; } + switch_mutex_unlock(profile->ireg_mutex); return r; } From 081e261956cf36c6692e1035d41cfd8f8d29475a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 08:58:44 -0600 Subject: [PATCH 497/512] FS-4883 --resolve I can add this but if it leads to issues in the loaded code we may not have resoures to investigate --- src/include/switch_core.h | 7 +++++ src/include/switch_core_db.h | 5 ++++ src/mod/languages/mod_lua/freeswitch.i | 1 + src/mod/languages/mod_lua/freeswitch_lua.cpp | 8 +++++ src/mod/languages/mod_lua/freeswitch_lua.h | 1 + src/mod/languages/mod_lua/mod_lua_wrap.cpp | 29 +++++++++++++++++++ .../languages/mod_managed/freeswitch_wrap.cxx | 28 ++++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 16 ++++++++++ src/switch_core_db.c | 17 +++++++++++ src/switch_core_sqldb.c | 23 +++++++++++++++ 10 files changed, 135 insertions(+) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 7b164af20a..68e592b9df 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2360,6 +2360,13 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach */ SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh); +/*! + \brief load an external extension to db + \param [in] dbh The handle + \param [out] the path to the extension +*/ +SWITCH_DECLARE(int) switch_cache_db_load_extension(switch_cache_db_handle_t *dbh, const char *extension); + /*! \brief Provides some feedback as to the status of the db connection pool \param [in] stream stream for status diff --git a/src/include/switch_core_db.h b/src/include/switch_core_db.h index e5fbf76a95..002a6ec7b6 100644 --- a/src/include/switch_core_db.h +++ b/src/include/switch_core_db.h @@ -462,6 +462,11 @@ SWITCH_DECLARE(void) switch_core_db_free(char *z); */ SWITCH_DECLARE(int) switch_core_db_changes(switch_core_db_t *db); +/** + * Call this routine to load an external extension + */ +SWITCH_DECLARE(int) switch_core_db_load_extension(switch_core_db_t *db, const char *extension); + /** Return values for switch_core_db_exec() and switch_core_db_step()*/ #define SWITCH_CORE_DB_OK 0 /* Successful result */ /* beginning-of-error-codes */ diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index a615fcd742..6fca226001 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -93,6 +93,7 @@ class Dbh { bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); int affected_rows(); + int load_extension(const char *extension); }; } diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 811a8a7bd6..c8918aee97 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -438,3 +438,11 @@ int Dbh::affected_rows() } return 0; } + +int Dbh::load_extension(const char *extension) +{ + if (m_connected) { + return switch_cache_db_load_extension(dbh, extension); + } + return 0; +} diff --git a/src/mod/languages/mod_lua/freeswitch_lua.h b/src/mod/languages/mod_lua/freeswitch_lua.h index 36c0afae5c..a1a289a70b 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.h +++ b/src/mod/languages/mod_lua/freeswitch_lua.h @@ -65,6 +65,7 @@ namespace LUA { bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); int affected_rows(); + int load_extension(const char *extension); }; } #endif diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 3f9ad57fb5..98c50f081d 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -7764,6 +7764,34 @@ fail: } +static int _wrap_Dbh_load_extension(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + char *arg2 = (char *) 0 ; + int result; + + SWIG_check_num_args("load_extension",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("load_extension",1,"LUA::Dbh *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("load_extension",2,"char const *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_load_extension",1,SWIGTYPE_p_LUA__Dbh); + } + + arg2 = (char *)lua_tostring(L, 2); + result = (int)(arg1)->load_extension((char const *)arg2); + SWIG_arg=0; + lua_pushnumber(L, (lua_Number) result); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + static void swig_delete_Dbh(void *obj) { LUA::Dbh *arg1 = (LUA::Dbh *) obj; delete arg1; @@ -7774,6 +7802,7 @@ static swig_lua_method swig_LUA_Dbh_methods[] = { {"test_reactive", _wrap_Dbh_test_reactive}, {"query", _wrap_Dbh_query}, {"affected_rows", _wrap_Dbh_affected_rows}, + {"load_extension", _wrap_Dbh_load_extension}, {0,0} }; static swig_lua_attribute swig_LUA_Dbh_attributes[] = { diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 4f885e481b..64f38107f7 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -5444,6 +5444,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_db_changes(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_db_load_extension(void * jarg1, char * jarg2) { + int jresult ; + switch_core_db_t *arg1 = (switch_core_db_t *) 0 ; + char *arg2 = (char *) 0 ; + int result; + + arg1 = (switch_core_db_t *)jarg1; + arg2 = (char *)jarg2; + result = (int)switch_core_db_load_extension(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_CORE_DB_OK_get() { int jresult ; int result; @@ -12035,6 +12049,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_affected_rows(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_load_extension(void * jarg1, char * jarg2) { + int jresult ; + switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + int result; + + arg1 = (switch_cache_db_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (int)switch_cache_db_load_extension(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_status(void * jarg1) { switch_stream_handle_t *arg1 = (switch_stream_handle_t *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index e560b2046c..7364cce845 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -986,6 +986,11 @@ public class freeswitch { return ret; } + public static int switch_core_db_load_extension(SWIGTYPE_p_sqlite3 db, string extension) { + int ret = freeswitchPINVOKE.switch_core_db_load_extension(SWIGTYPE_p_sqlite3.getCPtr(db), extension); + return ret; + } + public static string switch_sql_concat() { string ret = freeswitchPINVOKE.switch_sql_concat(); return ret; @@ -2698,6 +2703,11 @@ public class freeswitch { return ret; } + public static int switch_cache_db_load_extension(SWIGTYPE_p_switch_cache_db_handle dbh, string extension) { + int ret = freeswitchPINVOKE.switch_cache_db_load_extension(SWIGTYPE_p_switch_cache_db_handle.getCPtr(dbh), extension); + return ret; + } + public static void switch_cache_db_status(switch_stream_handle stream) { freeswitchPINVOKE.switch_cache_db_status(switch_stream_handle.getCPtr(stream)); } @@ -7968,6 +7978,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_db_changes")] public static extern int switch_core_db_changes(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_db_load_extension")] + public static extern int switch_core_db_load_extension(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CORE_DB_OK_get")] public static extern int SWITCH_CORE_DB_OK_get(); @@ -9489,6 +9502,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_affected_rows")] public static extern int switch_cache_db_affected_rows(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_load_extension")] + public static extern int switch_cache_db_load_extension(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_status")] public static extern void switch_cache_db_status(HandleRef jarg1); diff --git a/src/switch_core_db.c b/src/switch_core_db.c index 7cc151dc5b..6cc8896fab 100644 --- a/src/switch_core_db.c +++ b/src/switch_core_db.c @@ -178,6 +178,23 @@ SWITCH_DECLARE(int) switch_core_db_changes(switch_core_db_t *db) return sqlite3_changes(db); } +SWITCH_DECLARE(int) switch_core_db_load_extension(switch_core_db_t *db, const char *extension) +{ + int ret = 0; + char *err = NULL; + + sqlite3_enable_load_extension(db, 1); + ret = sqlite3_load_extension(db, extension, 0, &err); + sqlite3_enable_load_extension(db, 0); + + if (err) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "LOAD EXTENSION ERR [%s]\n", err); + switch_core_db_free(err); + err = NULL; + } + return ret; +} + SWITCH_DECLARE(switch_core_db_t *) switch_core_db_open_file(const char *filename) { switch_core_db_t *db; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index c1381bd351..3860af15d4 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -703,6 +703,29 @@ SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh) return 0; } +SWITCH_DECLARE(int) switch_cache_db_load_extension(switch_cache_db_handle_t *dbh, const char *extension) +{ + switch (dbh->type) { + case SCDB_TYPE_CORE_DB: + { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "try to load extension [%s]!\n", extension); + return switch_core_db_load_extension(dbh->native_handle.core_db_dbh, extension); + } + break; + case SCDB_TYPE_ODBC: + { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "load extension not supported by type ODBC!\n"); + } + break; + case SCDB_TYPE_PGSQL: + { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "load extension not supported by type PGSQL!\n"); + } + break; + } + return 0; +} + SWITCH_DECLARE(char *) switch_cache_db_execute_sql2str(switch_cache_db_handle_t *dbh, char *sql, char *str, size_t len, char **err) { From bce107b5fcf7c1854dc4dcc3bd2e6bdd2c435a88 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 09:00:03 -0600 Subject: [PATCH 498/512] FS-4883 --resolve I can add this but if it leads to issues in the loaded code we may not have resoures to investigate --- Makefile.am | 2 +- libs/sqlite/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index f1e98e05e1..6e08f68a05 100644 --- a/Makefile.am +++ b/Makefile.am @@ -472,7 +472,7 @@ libs/speex/libspeex/libspeexdsp.la: libs/speex/.update libs/sqlite/libsqlite3.la: libs/sqlite libs/sqlite/.update touch src/include/switch.h - @cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)" + @cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)" LIBREADLINE="-lreadline -lncurses -ldl" @$(TOUCH_TARGET) libs/pcre/libpcre.la: libs/pcre libs/pcre/.update diff --git a/libs/sqlite/Makefile.in b/libs/sqlite/Makefile.in index 1d01aadf34..01ff7496a9 100644 --- a/libs/sqlite/Makefile.in +++ b/libs/sqlite/Makefile.in @@ -116,7 +116,7 @@ NAWK = @AWK@ # You should not have to change anything below this line ############################################################################### -TCC += -DSQLITE_OMIT_LOAD_EXTENSION=1 +#TCC += -DSQLITE_OMIT_LOAD_EXTENSION=1 # Object files for the SQLite library. # From 435443c9f6ca3cd4772dc6563c1ca00c1f25e763 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 10:40:47 -0600 Subject: [PATCH 499/512] fix build --- libs/sqlite/src/os_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sqlite/src/os_common.h b/libs/sqlite/src/os_common.h index 863e3cde2b..cd43f93a7e 100644 --- a/libs/sqlite/src/os_common.h +++ b/libs/sqlite/src/os_common.h @@ -26,7 +26,7 @@ #ifdef MEMORY_DEBUG # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif - +#undef SQLITE_OMIT_LOAD_EXTENSION /* * When testing, this global variable stores the location of the From 03531329d3981d7bd5f568690c1d58189d2e1220 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 10:44:27 -0600 Subject: [PATCH 500/512] bring back 'make sure' it will git clean and fully reset and build latest git and wipe out any uncomitted changes, you can pass CONFIGURE_ARGS=--foo from the make command line to pass the flags to the reconfigure --- Makefile.am | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index 6e08f68a05..094701142c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -606,6 +606,10 @@ version: reinstall: modwipe uninstall install +pristine: + git clean -fdx + git reset --hard + update-clean: clean libs/openzap/Makefile python-reconf cd libs/sofia-sip && $(MAKE) clean cd libs/openzap && $(MAKE) clean @@ -618,13 +622,6 @@ swigall: @echo reswigging all sh $(switch_srcdir)/build/swigall.sh -sure: current - -speedy-sure: update-clean - $(MAKE) -j core - cd libs/sofia-sip && $(MAKE) -j - $(MAKE) -j modules - speex-reconf: cd libs/speex && autoreconf cd libs/speex && ./config.status --recheck @@ -680,6 +677,14 @@ cluecon: @echo @echo http://www.cluecon.com @sleep 5 + +sure: is-scm pristine update + git pull + sh bootstrap.sh + sh configure $(CONFIGURE_ARGS) + make $(MAKE_ARGS) + make reinstall + current: cluecon update-clean is-scm $(MAKE) update $(MAKE) all From 7e03199529d74c99efe742594b9198d37a0fa1e9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 10:47:16 -0600 Subject: [PATCH 501/512] fix build again --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 094701142c..28b076ddec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -472,7 +472,7 @@ libs/speex/libspeex/libspeexdsp.la: libs/speex/.update libs/sqlite/libsqlite3.la: libs/sqlite libs/sqlite/.update touch src/include/switch.h - @cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)" LIBREADLINE="-lreadline -lncurses -ldl" + @cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)" LIBREADLINE="-ldl" @$(TOUCH_TARGET) libs/pcre/libpcre.la: libs/pcre libs/pcre/.update From ddd6382280aa87c893b9e6bbb37d9e1a1ad3e86f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 11:00:43 -0600 Subject: [PATCH 502/512] FS-4887 --resolve --- src/switch_event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_event.c b/src/switch_event.c index 259a5fa25c..32bc5b2d2d 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1613,6 +1613,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, if (vnext) { vdata = vnext; + vnext = NULL; } else { break; } From a59a319e0dc781858d435fd300742a504b87c0a6 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 29 Nov 2012 15:21:09 -0500 Subject: [PATCH 503/512] fix full build again --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 28b076ddec..2104db9b75 100644 --- a/Makefile.am +++ b/Makefile.am @@ -472,7 +472,7 @@ libs/speex/libspeex/libspeexdsp.la: libs/speex/.update libs/sqlite/libsqlite3.la: libs/sqlite libs/sqlite/.update touch src/include/switch.h - @cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)" LIBREADLINE="-ldl" + @cd libs/sqlite && $(MAKE) CFLAGS="$(SWITCH_AM_CFLAGS)" @$(TOUCH_TARGET) libs/pcre/libpcre.la: libs/pcre libs/pcre/.update From 026da2b33d6c363739fba8b09f2d9ea61d971dc3 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Thu, 29 Nov 2012 15:42:46 -0500 Subject: [PATCH 504/512] FS-4890 --resolve I've also added the CC-Agent-Called-Time and CC-Agent-Aborted-Time in case you find this useful also. --- src/mod/applications/mod_callcenter/mod_callcenter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 2e20f3c969..076009ac53 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1762,10 +1762,13 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Hangup-Cause", switch_channel_cause2str(cause)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Aborted-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", h->member_cid_number); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called); switch_event_fire(&event); } From 685da11d0d7c2aad85c48f91be9ed14623d2fae9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 12:37:41 -0600 Subject: [PATCH 505/512] FS-4885 --resolve this is not the best solution but it will work --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 0b11abf703..f483321e36 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2403,7 +2403,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)), TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); - } else if ((ua && (switch_stristr("aastra", ua)))) { + } else if ((ua && (switch_stristr("aastra", ua) && !switch_stristr("Intelligate", ua)))) { snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" ", name, number, tech_pvt->profile->sipip); sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY); From 395b7a97997496ca0758df64521d173a24593940 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 12:59:33 -0600 Subject: [PATCH 506/512] FS-4882 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 4 ++-- src/mod/endpoints/mod_sofia/sofia_reg.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ed3428555e..a00a0d21bd 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4781,10 +4781,10 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu gateway->ping = switch_epoch_time_now(NULL) + gateway->ping_freq; sofia_reg_release_gateway(gateway); gateway->pinging = 0; - } else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) && sip && sip->sip_to) { + } else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) && sip && sip->sip_to && strchr(sip->sip_call_id->i_id, '_')) { char *sql; time_t now = switch_epoch_time_now(NULL); - const char *call_id = sip->sip_call_id->i_id; + const char *call_id = strchr(sip->sip_call_id->i_id, '_') + 1; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire registration '%s@%s' due to options failure\n", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 507ace4391..f3d3bb205b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -557,17 +557,23 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames { sofia_profile_t *profile = (sofia_profile_t *) pArg; nua_handle_t *nh; - char to[512] = ""; + char to[512] = "", call_id[512] = ""; sofia_destination_t *dst = NULL; + switch_uuid_t uuid; switch_snprintf(to, sizeof(to), "sip:%s@%s", argv[1], argv[2]); + // create call-id for OPTIONS in the form "_" + switch_uuid_get(&uuid); + switch_uuid_format(call_id, &uuid); + strcat(call_id, "_"); + strncat(call_id, argv[0], sizeof(call_id) - SWITCH_UUID_FORMATTED_LENGTH - 2); + dst = sofia_glue_get_destination(argv[3]); switch_assert(dst); nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(profile->url), SIPTAG_TO_STR(to), NUTAG_URL(dst->contact), SIPTAG_CONTACT_STR(profile->url), - TAG_END()); - //SIPTAG_CALL_ID_STR(argv[0]), TAG_END()); + SIPTAG_CALL_ID_STR(call_id), TAG_END()); nua_handle_bind(nh, &mod_sofia_globals.destroy_private); nua_options(nh, NTATAG_SIP_T2(5000), From 35f98c13506b719790d84ba571b81390753e2a43 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 13:02:30 -0600 Subject: [PATCH 507/512] FS-4841 --resolve we will remove this, it clearly is not helping --- src/switch_time.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/switch_time.c b/src/switch_time.c index 54bf9338ef..6ce27b90c4 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -150,7 +150,6 @@ SWITCH_DECLARE(void) switch_os_yield(void) #if defined(WIN32) SwitchToThread(); #else - usleep(1); sched_yield(); #endif } From b4d7c2ab2ce22b52857a067e5e4e63b0291a64af Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 29 Nov 2012 16:49:05 -0500 Subject: [PATCH 508/512] FS-4882: fix potential seg --- src/mod/endpoints/mod_sofia/sofia.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index a00a0d21bd..c74a61cfd2 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4781,7 +4781,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu gateway->ping = switch_epoch_time_now(NULL) + gateway->ping_freq; sofia_reg_release_gateway(gateway); gateway->pinging = 0; - } else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) && sip && sip->sip_to && strchr(sip->sip_call_id->i_id, '_')) { + } else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) && + sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) { char *sql; time_t now = switch_epoch_time_now(NULL); const char *call_id = strchr(sip->sip_call_id->i_id, '_') + 1; From 1073f70b6fd2c2ef892982017eab5c5572e824c6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 13:42:56 -0600 Subject: [PATCH 509/512] spread out timer skips to smooth out socket catch-up --- src/switch_rtp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index ec003f9569..8726beabe8 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3246,9 +3246,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (switch_poll(rtp_session->read_pollfd, 1, &fdr, 0) == SWITCH_STATUS_SUCCESS) { rtp_session->hot_hits++;//+= rtp_session->samples_per_interval; - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s Trigger %d\n", - //switch_core_session_get_name(session), - // rtp_session->hot_hits); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s Hot Hit %d\n", + switch_core_session_get_name(session), + rtp_session->hot_hits); } else { rtp_session->hot_hits = 0; } @@ -3262,21 +3262,21 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - - if (hot_socket) { - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Skip timer\n"); + if (hot_socket && (rtp_session->hot_hits % 10) != 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s timer while HOT\n", switch_core_session_get_name(session)); + switch_core_timer_next(&rtp_session->timer); + } else if (hot_socket) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s skip timer once\n", switch_core_session_get_name(session)); rtp_session->sync_packets++; switch_core_timer_sync(&rtp_session->timer); - } else { if (rtp_session->sync_packets) { -#if 0 - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, - "Auto-Flush catching up %d packets (%d)ms.\n", + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, + "%s Auto-Flush catching up %d packets (%d)ms.\n", + switch_core_session_get_name(session), rtp_session->sync_packets, (rtp_session->ms_per_packet * rtp_session->sync_packets) / 1000); -#endif - //switch_core_timer_sync(&rtp_session->timer); } else { switch_core_timer_next(&rtp_session->timer); From 495ed50571e62494349bd0654ba23e754443a3cc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 14:16:36 -0600 Subject: [PATCH 510/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index c96f9f8dd9..d1ccc9229a 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.7b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.7], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [7b]) +AC_SUBST(SWITCH_VERSION_MICRO, [7]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From de53b3983d6b4bbd2c6c4575317c1a944019c693 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 14:18:40 -0600 Subject: [PATCH 511/512] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index d1ccc9229a..5ff62afc36 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.3.7], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.3.8b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [3]) -AC_SUBST(SWITCH_VERSION_MICRO, [7]) +AC_SUBST(SWITCH_VERSION_MICRO, [8b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From b35ac6b3bd5c970eeeb0239fe4e174f4a1799ee5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 Nov 2012 18:34:27 -0600 Subject: [PATCH 512/512] fix auto_simplify --- src/mod/endpoints/mod_sofia/mod_sofia.c | 9 ++++++--- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 17 +++++++++++------ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index f483321e36..73c50565fe 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1097,8 +1097,9 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f if (sofia_test_flag(tech_pvt, TFLAG_SIMPLIFY) && sofia_test_flag(tech_pvt, TFLAG_GOT_ACK)) { - sofia_glue_tech_simplify(tech_pvt); - sofia_clear_flag(tech_pvt, TFLAG_SIMPLIFY); + if (sofia_glue_tech_simplify(tech_pvt)) { + sofia_clear_flag(tech_pvt, TFLAG_SIMPLIFY); + } } while (sofia_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) { @@ -1714,7 +1715,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL); - sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY); + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "sip_auto_simplify"))) { + sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY); + } if (switch_rtp_ready(tech_pvt->rtp_session)) { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 44f17a320f..146ef4fd44 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -1191,7 +1191,7 @@ uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const c void sofia_glue_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session); switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *session, const char *r_sdp); char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type); -void sofia_glue_tech_simplify(private_object_t *tech_pvt); +int sofia_glue_tech_simplify(private_object_t *tech_pvt); switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host); switch_console_callback_match_t *sofia_reg_find_reg_url_with_positive_expires_multi(sofia_profile_t *profile, const char *user, const char *host, time_t reg_time, const char *contact_str, long exptime); switch_bool_t sofia_glue_profile_exists(const char *key); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 388e647cc0..efdce9449e 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -6785,21 +6785,19 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use } -void sofia_glue_tech_simplify(private_object_t *tech_pvt) +int sofia_glue_tech_simplify(private_object_t *tech_pvt) { const char *uuid, *network_addr_a = NULL, *network_addr_b = NULL, *simplify, *simplify_other_channel; switch_channel_t *other_channel = NULL, *inbound_channel = NULL; switch_core_session_t *other_session = NULL, *inbound_session = NULL; uint8_t did_simplify = 0; + int r = 0; if (!switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED) || switch_channel_test_flag(tech_pvt->channel, CF_SIMPLIFY)) { - return; + goto end; } - - - if ((uuid = switch_channel_get_partner_uuid(tech_pvt->channel)) - && (other_session = switch_core_session_locate(uuid))) { + if ((uuid = switch_channel_get_partner_uuid(tech_pvt->channel)) && (other_session = switch_core_session_locate(uuid))) { other_channel = switch_core_session_get_channel(other_session); @@ -6807,6 +6805,8 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt) simplify = switch_channel_get_variable(tech_pvt->channel, "sip_auto_simplify"); simplify_other_channel = switch_channel_get_variable(other_channel, "sip_auto_simplify"); + r = 1; + if (switch_true(simplify) && !switch_channel_test_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR)) { network_addr_a = switch_channel_get_variable(tech_pvt->channel, "network_addr"); network_addr_b = switch_channel_get_variable(other_channel, "network_addr"); @@ -6851,6 +6851,11 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt) switch_core_session_rwunlock(other_session); } + + + end: + + return r; } void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on)