From f61ffd77f2e8d6fd4f5536880e7fc95a4c0e0695 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Nov 2012 14:04:02 -0600 Subject: [PATCH 01/90] 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 02/90] 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 03/90] 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 04/90] 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 05/90] 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 06/90] 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 07/90] 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 08/90] 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 09/90] 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 10/90] 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 11/90] 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 12/90] 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 13/90] 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 14/90] 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 15/90] 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 feb38cece2a9103ee16cd263ce51b9fc7151256d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Nov 2012 08:14:32 -0600 Subject: [PATCH 16/90] 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 17/90] 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 18/90] 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 19/90] 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 20/90] 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 21/90] 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 22/90] 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 23/90] 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 24/90] 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 25/90] 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 26/90] 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 27/90] 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 28/90] 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 29/90] 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 30/90] 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 31/90] 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 32/90] 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 33/90] 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 34/90] 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 35/90] 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 38/90] 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 39/90] 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 40/90] 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 41/90] 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 42/90] 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 43/90] 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 44/90] 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 45/90] 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 46/90] 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 47/90] 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 48/90] 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 49/90] 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 50/90] 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 51/90] 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 52/90] 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 53/90] 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 54/90] 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 55/90] 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 56/90] 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 57/90] 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 58/90] 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 59/90] 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 60/90] 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 61/90] 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 62/90] 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 63/90] 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 64/90] 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 65/90] 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 66/90] 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 67/90] 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 68/90] 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 69/90] 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 70/90] 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 71/90] 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 72/90] 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 73/90] 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 74/90] 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 75/90] 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 76/90] 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 77/90] 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 78/90] 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 79/90] 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 80/90] 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 81/90] 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 82/90] 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 83/90] 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 84/90] 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 85/90] 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 86/90] 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 87/90] 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 88/90] 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 89/90] 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 90/90] 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