From 72ec7b59ab1ff88d330a211ce5b3c7841d20d7b7 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Fri, 23 Apr 2010 17:09:27 -0400 Subject: [PATCH 01/30] Tweak bridge_early_media to support passthrough codecs --- src/switch_ivr_originate.c | 175 +++++++++++++++++++++++++------------ 1 file changed, 117 insertions(+), 58 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 27dd189600..a79f2eb6f3 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -372,6 +372,38 @@ static switch_bool_t monitor_callback(switch_core_session_t *session, const char return SWITCH_FALSE; } +static void inherit_codec(switch_channel_t *caller_channel, switch_core_session_t *session) +{ + const char *var = switch_channel_get_variable(caller_channel, "inherit_codec"); + switch_channel_t *channel = switch_core_session_get_channel(session); + + if (switch_true(var)) { + switch_codec_implementation_t impl = { 0 }; + switch_codec_implementation_t video_impl = { 0 }; + char tmp[128] = ""; + + + if (switch_core_session_get_read_impl(session, &impl) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_get_video_read_impl(session, &impl) == SWITCH_STATUS_SUCCESS) { + switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui,%s", + impl.iananame, impl.samples_per_second, impl.microseconds_per_packet / 1000, + video_impl.iananame); + } else { + switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui", + impl.iananame, impl.samples_per_second, impl.microseconds_per_packet / 1000); + } + switch_channel_set_variable(caller_channel, "absolute_codec_string", tmp); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Setting codec string on %s to %s\n", + switch_channel_get_name(caller_channel), tmp); + } else { + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_WARNING, + "Error inheriting codec. Channel %s has no read codec yet.\n", + switch_channel_get_name(channel)); + } + + } +} + static uint8_t check_channel_status(originate_global_t *oglobals, originate_status_t *originate_status, uint32_t len) { @@ -671,32 +703,7 @@ static uint8_t check_channel_status(originate_global_t *oglobals, originate_stat end: if (pindex > -1 && caller_channel && switch_channel_ready(caller_channel) && !switch_channel_media_ready(caller_channel)) { - const char *var = switch_channel_get_variable(caller_channel, "inherit_codec"); - if (switch_true(var)) { - switch_codec_implementation_t impl = { 0 }; - switch_codec_implementation_t video_impl = { 0 }; - char tmp[128] = ""; - - - if (switch_core_session_get_read_impl(originate_status[pindex].peer_session, &impl) == SWITCH_STATUS_SUCCESS) { - if (switch_core_session_get_video_read_impl(originate_status[pindex].peer_session, &impl) == SWITCH_STATUS_SUCCESS) { - switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui,%s", - impl.iananame, impl.samples_per_second, impl.microseconds_per_packet / 1000, - video_impl.iananame); - } else { - switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui", - impl.iananame, impl.samples_per_second, impl.microseconds_per_packet / 1000); - } - switch_channel_set_variable(caller_channel, "absolute_codec_string", tmp); - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "Setting codec string on %s to %s\n", - switch_channel_get_name(caller_channel), tmp); - } else { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(originate_status[pindex].peer_channel), SWITCH_LOG_WARNING, - "Error inheriting codec. Channel %s has no read codec yet.\n", - switch_channel_get_name(originate_status[pindex].peer_channel)); - } - - } + inherit_codec(caller_channel, originate_status[pindex].peer_session); } if (send_ringback) { @@ -1051,7 +1058,7 @@ SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switc } -static switch_status_t setup_ringback(originate_global_t *oglobals, +static switch_status_t setup_ringback(originate_global_t *oglobals, originate_status_t *originate_status, int len, const char *ringback_data, ringback_t *ringback, switch_frame_t *write_frame, switch_codec_t *write_codec) { switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -1061,6 +1068,10 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, if (!switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) { + if (oglobals->bridge_early_media > -1 && len == 1 && originate_status[0].peer_session && + switch_channel_media_ready(originate_status[0].peer_channel)) { + inherit_codec(caller_channel, originate_status[0].peer_session); + } if ((status = switch_channel_pre_answer(caller_channel)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", switch_channel_get_name(caller_channel)); @@ -1073,6 +1084,25 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) { ringback->asis++; } + } else if (oglobals->bridge_early_media > -1 && zstr(ringback_data) && len == 1 && originate_status[0].peer_session) { + switch_codec_implementation_t read_impl = { 0 }, write_impl = { 0 }; + + if (switch_channel_ready(originate_status[0].peer_channel) + && switch_core_session_get_read_impl(originate_status[0].peer_session, &read_impl) == SWITCH_STATUS_SUCCESS + && switch_core_session_get_write_impl(oglobals->session, &write_impl) == SWITCH_STATUS_SUCCESS) { + if (read_impl.impl_id == write_impl.impl_id && + read_impl.microseconds_per_packet == write_impl.microseconds_per_packet && + read_impl.actual_samples_per_second == write_impl.actual_samples_per_second) { + ringback->asis++; + write_frame->codec = switch_core_session_get_write_codec(originate_status[0].peer_session); + write_frame->datalen = write_frame->codec->implementation->decoded_bytes_per_packet; + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "bridge_early_media: passthrough enabled\n"); + } else { + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_DEBUG, "bridge_early_media: codecs don't match (%s@%uh@%di / %s@%uh@%di)\n", + read_impl.iananame, read_impl.actual_samples_per_second, read_impl.microseconds_per_packet / 1000, + write_impl.iananame, write_impl.actual_samples_per_second, write_impl.microseconds_per_packet / 1000); + } + } } if (!ringback->asis) { @@ -1553,6 +1583,7 @@ struct early_state { switch_mutex_t *mutex; switch_buffer_t *buffer; int ready; + ringback_t *ringback; }; typedef struct early_state early_state_t; @@ -1591,37 +1622,51 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * answered++; } - if (!switch_core_codec_ready((&read_codecs[i]))) { - read_codec = switch_core_session_get_read_codec(session); + if (!state->ringback->asis) { + if (!switch_core_codec_ready((&read_codecs[i]))) { + read_codec = switch_core_session_get_read_codec(session); - if (switch_core_codec_init(&read_codecs[i], - "L16", - NULL, - read_codec->implementation->actual_samples_per_second, - read_codec->implementation->microseconds_per_packet / 1000, - 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, - switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n"); - } else { - switch_core_session_set_read_codec(session, &read_codecs[i]); + if (switch_core_codec_init(&read_codecs[i], + "L16", + NULL, + read_codec->implementation->actual_samples_per_second, + read_codec->implementation->microseconds_per_packet / 1000, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, + switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n"); + } else { + switch_core_session_set_read_codec(session, &read_codecs[i]); + } } - } - status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - if (SWITCH_READ_ACCEPTABLE(status)) { - data = (int16_t *) read_frame->data; - if (datalen < read_frame->datalen) { + status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + if (SWITCH_READ_ACCEPTABLE(status)) { + data = (int16_t *) read_frame->data; + if (datalen < read_frame->datalen) { + datalen = read_frame->datalen; + } + for (x = 0; x < (int) read_frame->datalen / 2; x++) { + sample = data[x] + mux_data[x]; + switch_normalize_to_16bit(sample); + mux_data[x] = (int16_t) sample; + } + } + } else { + status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + if (SWITCH_READ_ACCEPTABLE(status)) { datalen = read_frame->datalen; } - for (x = 0; x < (int) read_frame->datalen / 2; x++) { - sample = data[x] + mux_data[x]; - switch_normalize_to_16bit(sample); - mux_data[x] = (int16_t) sample; - } - + break; } } } - if (datalen) { + + if (state->ringback->asis && datalen) { + uint16_t flen = datalen; + switch_mutex_lock(state->mutex); + switch_buffer_write(state->buffer, &flen, sizeof(uint16_t)); + switch_buffer_write(state->buffer, read_frame->data, datalen); + switch_mutex_unlock(state->mutex); + } else if (datalen) { switch_mutex_lock(state->mutex); switch_buffer_write(state->buffer, mux_data, datalen); switch_mutex_unlock(state->mutex); @@ -2758,9 +2803,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (oglobals.ringback_ok && (oglobals.ring_ready || oglobals.instant_ringback || oglobals.sending_ringback > 1 || oglobals.bridge_early_media > -1)) { if (oglobals.ringback_ok == 1) { - switch_status_t rst = setup_ringback(&oglobals, ringback_data, &ringback, &write_frame, &write_codec); - - + switch_status_t rst; + + rst = setup_ringback(&oglobals, originate_status, and_argc, ringback_data, &ringback, &write_frame, &write_codec); + if (oglobals.bridge_early_media > -1) { switch_threadattr_t *thd_attr = NULL; switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); @@ -2768,6 +2814,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess early_state.oglobals = &oglobals; early_state.originate_status = originate_status; early_state.ready = 1; + early_state.ringback = &ringback; switch_mutex_init(&early_state.mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_buffer_create_dynamic(&early_state.buffer, 1024, 1024, 0); switch_thread_create(&oglobals.ethread, thd_attr, early_thread_run, &early_state, switch_core_session_get_pool(session)); @@ -2794,12 +2841,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess continue; } - if (oglobals.bridge_early_media > -1) { + if (oglobals.bridge_early_media > -1) { write_frame.datalen = 0; switch_mutex_lock(early_state.mutex); - if (switch_buffer_inuse(early_state.buffer) >= write_frame.codec->implementation->decoded_bytes_per_packet) { - write_frame.datalen = switch_buffer_read(early_state.buffer, write_frame.data, - write_frame.codec->implementation->decoded_bytes_per_packet); + if (ringback.asis) { + uint16_t mlen; + switch_size_t buflen = switch_buffer_inuse(early_state.buffer); + if (buflen > sizeof(uint16_t)) { + switch_buffer_peek(early_state.buffer, &mlen, sizeof(uint16_t)); + if (buflen >= (mlen + sizeof(uint16_t))) { + switch_buffer_toss(early_state.buffer, sizeof(uint16_t)); + write_frame.datalen = switch_buffer_read(early_state.buffer, write_frame.data, mlen); + } + } + } else { + if (switch_buffer_inuse(early_state.buffer) >= write_frame.codec->implementation->decoded_bytes_per_packet) { + write_frame.datalen = switch_buffer_read(early_state.buffer, write_frame.data, + write_frame.codec->implementation->decoded_bytes_per_packet); + } } switch_mutex_unlock(early_state.mutex); } else if (ringback.fh) { From 32cedb2df90e77b91bd17699cc42099fdfdfdb97 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 24 Apr 2010 11:18:49 +0200 Subject: [PATCH 02/30] switch_dso.c: FreeBSD(8.0) dlerror() returns const char*, add cast to char* to avoid a warning (and abort due to -Werror) --- src/switch_dso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_dso.c b/src/switch_dso.c index 152c280d5d..fd21653063 100644 --- a/src/switch_dso.c +++ b/src/switch_dso.c @@ -131,7 +131,7 @@ void *switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err) dlerror(); if (!(addr = dlsym(lib, sym))) { - err_str = dlerror(); + err_str = (char *)dlerror(); } if (err_str) { From cac7d5558001705768901d4689f80ddacf10797b Mon Sep 17 00:00:00 2001 From: Brian West Date: Sat, 24 Apr 2010 15:05:04 -0500 Subject: [PATCH 03/30] unmap the implicit rtcp port --- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 193001fe1f..c5f9ae9634 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2189,6 +2189,7 @@ void sofia_glue_deactivate_rtp(private_object_t *tech_pvt) if (tech_pvt->local_sdp_video_port > 0 && !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_video_port + 1, SWITCH_NAT_UDP); } @@ -2200,6 +2201,7 @@ void sofia_glue_deactivate_rtp(private_object_t *tech_pvt) if (tech_pvt->local_sdp_audio_port > 0 && !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP); } } From b1f9dc416d75a42966d43ba6a425cfa0ede930ec Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Sat, 24 Apr 2010 17:48:59 -0400 Subject: [PATCH 04/30] mod_xml_cdr: add force_process_cdr var to process b leg cdr on a case by case basis when b leg cdr is disabled (XML-17) --- src/include/switch_types.h | 1 + src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 2589e2b8c3..7e9f6ae42b 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -141,6 +141,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_API_HANGUP_HOOK_VARIABLE "api_hangup_hook" #define SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE "session_in_hangup_hook" #define SWITCH_PROCESS_CDR_VARIABLE "process_cdr" +#define SWITCH_FORCE_PROCESS_CDR_VARIABLE "force_process_cdr" #define SWITCH_BRIDGE_CHANNEL_VARIABLE "bridge_channel" #define SWITCH_CHANNEL_NAME_VARIABLE "channel_name" #define SWITCH_BRIDGE_UUID_VARIABLE "bridge_uuid" diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 0f2caa0df0..3097b2144b 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -200,7 +200,10 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) is_b = channel && switch_channel_get_originator_caller_profile(channel); if (!globals.log_b && is_b) { - return SWITCH_STATUS_SUCCESS; + const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE); + if (!switch_true(force_cdr)) { + return SWITCH_STATUS_SUCCESS; + } } if (!is_b && globals.prefix_a) a_prefix = "a_"; From b2ec65a10ae77d37095c77236bec8f1af95ff4c8 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 01:13:10 -0400 Subject: [PATCH 05/30] more efficient check --- libs/esl/src/esl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 70c91a2d20..d2ca396546 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -786,7 +786,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms return ESL_FAIL; } - if (esl_mutex_trylock(handle->mutex) != ESL_SUCCESS) { + if (activity == 0 || !FD_ISSET(handle->sock, &rfds) || (esl_mutex_trylock(handle->mutex) != ESL_SUCCESS)) { return ESL_BREAK; } From add3ded40abb0ab0eed1f6580c2aaaff56722f11 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 01:30:51 -0400 Subject: [PATCH 06/30] cleanup C reserved identifer violation (JANITOR-3) --- src/include/g711.h | 4 ++-- src/include/switch_dso.h | 4 ++-- src/include/switch_nat.h | 4 ++-- src/include/switch_stun.h | 4 ++-- src/include/switch_xml.h | 4 ++-- src/mod/applications/mod_expr/conio.h | 4 ++-- src/mod/applications/mod_t38gateway/udptl.h | 4 ++-- src/mod/endpoints/mod_portaudio/pablio.h | 4 ++-- src/mod/xml_int/mod_xml_ldap/lutil_ldap.h | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/include/g711.h b/src/include/g711.h index ec75e3967c..53f3afc87e 100644 --- a/src/include/g711.h +++ b/src/include/g711.h @@ -39,8 +39,8 @@ difficult to achieve the precise transcoding procedure laid down in the G.711 specification by other means. */ -#if !defined(_G711_H_) -#define _G711_H_ +#if !defined(FREESWITCH_G711_H) +#define FREESWITCH_G711_H #ifdef __cplusplus extern "C" { diff --git a/src/include/switch_dso.h b/src/include/switch_dso.h index 052cd5b5d3..a715e02cf1 100644 --- a/src/include/switch_dso.h +++ b/src/include/switch_dso.h @@ -18,8 +18,8 @@ */ -#ifndef _SWITCH_DSO_H -#define _SWITCH_DSO_H +#ifndef FREESWITCH_DSO_H +#define FREESWITCH_DSO_H typedef int (*switch_dso_func_t) (void); #ifdef WIN32 diff --git a/src/include/switch_nat.h b/src/include/switch_nat.h index 87ba3190ff..ced175ba47 100644 --- a/src/include/switch_nat.h +++ b/src/include/switch_nat.h @@ -35,8 +35,8 @@ \ingroup core1 \{ */ -#ifndef _SWITCH_NAT_H -#define _SWITCH_NAT_H +#ifndef FREESWITCH_NAT_H +#define FREESWITCH_NAT_H SWITCH_BEGIN_EXTERN_C typedef enum { SWITCH_NAT_TYPE_NONE, diff --git a/src/include/switch_stun.h b/src/include/switch_stun.h index 75bc646933..d5df57e4fe 100644 --- a/src/include/switch_stun.h +++ b/src/include/switch_stun.h @@ -34,8 +34,8 @@ \ingroup core1 \{ */ -#ifndef _SWITCH_STUN_PARSER_H -#define _SWITCH_STUN_PARSER_H +#ifndef FREESWITCH_STUN_PARSER_H +#define FREESWITCH_STUN_PARSER_H SWITCH_BEGIN_EXTERN_C #define SWITCH_STUN_DEFAULT_PORT 3478 diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h index 0443f96ba6..9a3b72d6fa 100644 --- a/src/include/switch_xml.h +++ b/src/include/switch_xml.h @@ -53,8 +53,8 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _SWITCH_XML_H -#define _SWITCH_XML_H +#ifndef FREESWITCH_XML_H +#define FREESWITCH_XML_H #include diff --git a/src/mod/applications/mod_expr/conio.h b/src/mod/applications/mod_expr/conio.h index ec0540456f..a83971fdd6 100644 --- a/src/mod/applications/mod_expr/conio.h +++ b/src/mod/applications/mod_expr/conio.h @@ -8,8 +8,8 @@ * Offered for use in the public domain without any warranty. */ -#ifndef _CONIO_H_ -#define _CONIO_H_ +#ifndef CONIO_H +#define CONIO_H #include diff --git a/src/mod/applications/mod_t38gateway/udptl.h b/src/mod/applications/mod_t38gateway/udptl.h index b0eb1b2e5a..39740353d1 100644 --- a/src/mod/applications/mod_t38gateway/udptl.h +++ b/src/mod/applications/mod_t38gateway/udptl.h @@ -22,8 +22,8 @@ * */ -#if !defined(_UDPTL_H_) -#define _UDPTL_H_ +#if !defined(FREESWITCH_UDPTL_H) +#define FREESWITCH_UDPTL_H #define LOCAL_FAX_MAX_DATAGRAM 400 #define LOCAL_FAX_MAX_FEC_PACKETS 5 diff --git a/src/mod/endpoints/mod_portaudio/pablio.h b/src/mod/endpoints/mod_portaudio/pablio.h index 675be61748..0bd3c41e46 100644 --- a/src/mod/endpoints/mod_portaudio/pablio.h +++ b/src/mod/endpoints/mod_portaudio/pablio.h @@ -1,5 +1,5 @@ -#ifndef _PABLIO_H -#define _PABLIO_H +#ifndef PORTAUDIO_PABLIO_H +#define PORTAUDIO_PABLIO_H #ifdef __cplusplus extern "C" { diff --git a/src/mod/xml_int/mod_xml_ldap/lutil_ldap.h b/src/mod/xml_int/mod_xml_ldap/lutil_ldap.h index 48369013b4..181137cae6 100644 --- a/src/mod/xml_int/mod_xml_ldap/lutil_ldap.h +++ b/src/mod/xml_int/mod_xml_ldap/lutil_ldap.h @@ -13,8 +13,8 @@ * . */ -#ifndef _LUTIL_LDAP_H -#define _LUTIL_LDAP_H 1 +#ifndef LUTIL_LDAP_H +#define LUTIL_LDAP_H #include #include From c0a6abad73c612d9b65229a596d6008c227a6905 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 02:11:46 -0400 Subject: [PATCH 07/30] mod_xml_cdr: add leg param to query string (XML-24) --- src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 3097b2144b..b8dc08ff3f 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -337,7 +337,8 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) switch_yield(globals.delay * 1000000); } - destUrl = switch_mprintf("%s?uuid=%s", globals.urls[globals.url_index], switch_core_session_get_uuid(session)); + destUrl = switch_mprintf("%s?uuid=%s&leg=%c", globals.urls[globals.url_index], switch_core_session_get_uuid(session), + is_b ? 'b' : 'a'); curl_easy_setopt(curl_handle, CURLOPT_URL, destUrl); if (!strncasecmp(destUrl, "https", 5)) { From 97395b8c7945cda5e0ee83f6076e67475bdbd899 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 02:18:15 -0400 Subject: [PATCH 08/30] don't put ':' in to user agent string (MODSOFIA-71) --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index a9e4921344..4bd09c7f0d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -350,7 +350,7 @@ src/include/switch_version.h: src/include/switch_version.h.in .version $(libfree touch .version ; \ else \ if [ -d .git ] ; then \ - version=`git log --format="%h %ci" -1 HEAD | head -1 || echo hacked` ; \ + version=`git log --format="%h %ci" -1 HEAD | head -1 | sed -e 's|:|-|g' || echo hacked` ; \ if [ "x$$version" == "xhacked" ] ; then \ version="hacked-`date -u +%Y%m%dT%H%M%SZ`" ; \ else \ From 737d338f2a11536c34925dfbdc2196eb18b149b3 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 02:58:40 -0400 Subject: [PATCH 09/30] mod_fifo: allow multiple dtmf to exit fifo, set fifo_caller_exit_key to specify which (MODAPP-420) --- src/mod/applications/mod_fifo/mod_fifo.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 98208e9190..ba3fc2443b 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -75,6 +75,15 @@ static int sql2str_callback(void *pArg, int argc, char **argv, char **columnName return 0; } +static switch_bool_t match_key(const char *caller_exit_key, char key) +{ + while (caller_exit_key && *caller_exit_key) { + if (*caller_exit_key++ == key) { + return SWITCH_TRUE; + } + } + return SWITCH_FALSE; +} static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) { @@ -131,7 +140,7 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_channel_t *channel = switch_core_session_get_channel(session); const char *caller_exit_key = switch_channel_get_variable(channel, "fifo_caller_exit_key"); - if (caller_exit_key && dtmf->digit == *caller_exit_key) { + if (match_key(caller_exit_key, dtmf->digit)) { char *bp = buf; *bp = dtmf->digit; return SWITCH_STATUS_BREAK; @@ -230,9 +239,10 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session return SWITCH_STATUS_FALSE; } - if (caller_exit_key && *buf == *caller_exit_key) { + if (match_key(caller_exit_key, *buf)) { cd->abort = 1; return SWITCH_STATUS_FALSE; + switch_channel_set_variable(channel, "fifo_caller_exit_key", (char *)buf); } cd->next = switch_epoch_time_now(NULL) + cd->freq; cd->index++; @@ -1051,7 +1061,8 @@ SWITCH_STANDARD_APP(fifo_function) switch_ivr_collect_digits_callback(session, &args, 0, 0); } - if (caller_exit_key && *buf == *caller_exit_key) { + if (match_key(caller_exit_key, *buf)) { + switch_channel_set_variable(channel, "fifo_caller_exit_key", (char *)buf); aborted = 1; goto abort; } From 750aa7e29beafed22b40745c66cc1f222a069bf6 Mon Sep 17 00:00:00 2001 From: cseket Date: Mon, 26 Apr 2010 08:59:07 +0200 Subject: [PATCH 10/30] use force_process_cdr variable added in XML-17 --- src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c index 31a635dda3..d2ecca4dcb 100644 --- a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c +++ b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c @@ -620,7 +620,10 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) is_b = channel && switch_channel_get_originator_caller_profile(channel); if (!globals.log_b && is_b) { - return SWITCH_STATUS_SUCCESS; + const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE); + if (!switch_true(force_cdr)) { + return SWITCH_STATUS_SUCCESS; + } } if (!is_b && globals.prefix_a) a_prefix = "a_"; From 0ddd0c25a6c1ab48fda1cd4d1ba2ea0615f7e38f Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 03:11:25 -0400 Subject: [PATCH 11/30] libdingaling: fix race on shutdown causing crash (FSMOD-47) --- libs/libdingaling/src/libdingaling.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 1bebebddf5..353dd139ab 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -2179,7 +2179,11 @@ ldl_status ldl_session_get_payloads(ldl_session_t *session, ldl_payload_t **payl ldl_status ldl_global_terminate(void) { - ldl_clear_flag_locked((&globals), LDL_FLAG_READY); + if (globals.flag_mutex) { + ldl_clear_flag_locked((&globals), LDL_FLAG_READY); + } else { + ldl_clear_flag((&globals), LDL_FLAG_READY); + } return LDL_STATUS_SUCCESS; } From da195caa67f9853e91113d594d6103e4e176ff9d Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 03:21:41 -0400 Subject: [PATCH 12/30] fix build error due to missing zlib linking when using libtool 2.2 or later --- configure.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 23ff3d5680..838c1087a3 100644 --- a/configure.in +++ b/configure.in @@ -353,7 +353,6 @@ AC_SUBST(PA_LIBS) AM_CONDITIONAL([ENABLE_ZRTP],[test "x$enable_zrtp" != "xno"]) - AM_CONDITIONAL([WANT_DEBUG],[test "${enable_debug}" = "yes"]) AC_ARG_ENABLE(core-odbc-support, @@ -363,6 +362,11 @@ if test "$ac_cv_found_odbc" = "yes" ; then enable_core_odbc_support="yes" fi +AC_CHECK_LIB(z, inflateReset, have_libz=yes, have_libz=no) +if test "x$have_libz" = "xyes" ; then +APR_ADDTO(SWITCH_AM_LDFLAGS, -lz) +fi + ESL_LDFLAGS= PLATFORM_CORE_DEPLIBS= # tweak platform specific flags From 5be0640fdd2f9cc71ba9a0808c05b09cdf35a53f Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 04:14:57 -0400 Subject: [PATCH 13/30] mod_sofia: add failed call statistics to gateways (MODENDP-238) --- src/mod/endpoints/mod_sofia/mod_sofia.c | 117 +++++++++++++++++++++++- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 4 + 3 files changed, 120 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 12a69d000d..a7276a30cd 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -392,7 +392,13 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) switch_call_cause_t cause = switch_channel_get_cause(channel); int sip_cause = hangup_cause_to_sip(cause); const char *ps_cause = NULL, *use_my_cause; + const char *gateway_name = NULL; + sofia_gateway_t *gateway_ptr = NULL; + if ((gateway_name = switch_channel_get_variable(channel, "sip_gateway_name"))) { + gateway_ptr = sofia_reg_find_gateway(gateway_name); + } + switch_mutex_lock(tech_pvt->sofia_mutex); sofia_clear_flag(tech_pvt, TFLAG_RECOVERING); @@ -405,6 +411,18 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) } else { tech_pvt->profile->ib_failed_calls++; } + + if (gateway_ptr) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + gateway_ptr->ob_failed_calls++; + } else { + gateway_ptr->ib_failed_calls++; + } + } + } + + if (gateway_ptr) { + sofia_reg_release_gateway(gateway_ptr); } if (!((use_my_cause = switch_channel_get_variable(channel, "sip_ignore_remote_cause")) && switch_true(use_my_cause))) { @@ -2175,7 +2193,56 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t if (argc > 0) { if (argc == 1) { - stream->write_function(stream, "Invalid Syntax!\n"); + /* show summary of all gateways*/ + + uint32_t ib_failed = 0; + uint32_t ib = 0; + uint32_t ob_failed = 0; + uint32_t ob = 0; + + stream->write_function(stream, "%25s\t%32s\t%s\t%s\t%s\n", "Profile::Gateway-Name", " Data ", "State", "IB Calls(F/T)", "OB Calls(F/T)"); + stream->write_function(stream, "%s\n", line); + switch_mutex_lock(mod_sofia_globals.hash_mutex); + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + profile = (sofia_profile_t *) val; + if (sofia_test_pflag(profile, PFLAG_RUNNING)) { + + if (!strcmp(vvar, profile->name)) { /* not an alias */ + for (gp = profile->gateways; gp; gp = gp->next) { + char *pkey = switch_mprintf("%s::%s", profile->name, gp->name); + + switch_assert(gp->state < REG_STATE_LAST); + + c++; + ib_failed += gp->ib_failed_calls; + ib += gp->ib_calls; + ob_failed += gp->ob_failed_calls; + ob += gp->ob_calls; + + stream->write_function(stream, "%25s\t%32s\t%s\t%ld/%ld\t%ld/%ld", + pkey, gp->register_to, sofia_state_names[gp->state], + gp->ib_failed_calls, gp->ib_calls, gp->ob_failed_calls, gp->ob_calls); + + if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) { + time_t now = switch_epoch_time_now(NULL); + if (gp->retry > now) { + stream->write_function(stream, " (retry: %ds)", gp->retry - now); + } else { + stream->write_function(stream, " (retry: NEVER)"); + } + } + stream->write_function(stream, "\n"); + } + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + stream->write_function(stream, "%s\n", line); + stream->write_function(stream, "%d gateway%s: Inound(Failed/Total): %ld/%ld," + "Outbound(Failed/Total):%ld/%ld\n", c, c == 1 ? "" : "s", + ib_failed, ib, ob_failed, ob); + return SWITCH_STATUS_SUCCESS; } @@ -2205,6 +2272,8 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t stream->write_function(stream, "Status \t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); stream->write_function(stream, "CallsIN \t%d\n", gp->ib_calls); stream->write_function(stream, "CallsOUT\t%d\n", gp->ob_calls); + stream->write_function(stream, "FailedCallsIN\t%d\n", gp->ib_failed_calls); + stream->write_function(stream, "FailedCallsOUT\t%d\n", gp->ob_failed_calls); stream->write_function(stream, "%s\n", line); sofia_reg_release_gateway(gp); } else { @@ -2412,7 +2481,46 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl if (argc > 0) { if (argc == 1) { - stream->write_function(stream, "Invalid Syntax!\n"); + /* show summary of all gateways */ + + stream->write_function(stream, "%s\n", header); + stream->write_function(stream, "\n", header); + + switch_mutex_lock(mod_sofia_globals.hash_mutex); + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + profile = (sofia_profile_t *) val; + if (sofia_test_pflag(profile, PFLAG_RUNNING)) { + + if (!strcmp(vvar, profile->name)) { /* not an alias */ + for (gp = profile->gateways; gp; gp = gp->next) { + switch_assert(gp->state < REG_STATE_LAST); + + stream->write_function(stream, "\t\n"); + stream->write_function(stream, "\t\t%s\n", profile->name); + stream->write_function(stream, "\t\t%s\n", gp->register_to); + stream->write_function(stream, "\t\t%s\n", sofia_state_names[gp->state]); + stream->write_function(stream, "\t\t%ld\n", gp->ib_calls); + stream->write_function(stream, "\t\t%ld\n", gp->ob_calls); + stream->write_function(stream, "\t\t%ld\n", gp->ib_failed_calls); + stream->write_function(stream, "\t\t%ld\n", gp->ob_failed_calls); + + if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) { + time_t now = switch_epoch_time_now(NULL); + if (gp->retry > now) { + stream->write_function(stream, "\t\t%ds\n", gp->retry - now); + } else { + stream->write_function(stream, "\t\tNEVER\n"); + } + } + stream->write_function(stream, "\t\n"); + } + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + stream->write_function(stream, "\n"); + return SWITCH_STATUS_SUCCESS; } if (!strcasecmp(argv[0], "gateway")) { @@ -2440,7 +2548,8 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl stream->write_function(stream, " %s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); stream->write_function(stream, " %d\n", gp->ib_calls); stream->write_function(stream, " %d\n", gp->ob_calls); - + stream->write_function(stream, " %d\n", gp->ib_failed_calls); + stream->write_function(stream, " %d\n", gp->ob_failed_calls); stream->write_function(stream, " \n"); sofia_reg_release_gateway(gp); } else { @@ -3255,6 +3364,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session if (gateway_ptr->status != SOFIA_GATEWAY_UP) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Gateway is down!\n"); cause = SWITCH_CAUSE_NETWORK_OUT_OF_ORDER; + gateway_ptr->ob_failed_calls++; sofia_reg_release_gateway(gateway_ptr); gateway_ptr = NULL; goto error; @@ -3280,6 +3390,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session tech_pvt->transport = sofia_glue_str2transport(tp_param); if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN) { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + gateway_ptr->ob_failed_calls++; goto error; } } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index e1b1e61d53..7fe7c5fe2b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -402,6 +402,8 @@ struct sofia_gateway { switch_event_t *ob_vars; uint32_t ib_calls; uint32_t ob_calls; + uint32_t ib_failed_calls; + uint32_t ob_failed_calls; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; int failures; struct sofia_gateway *next; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 8338663e30..3d0dc95f21 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1758,6 +1758,10 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) gateway->ping_max = 0; gateway->ping_min = 0; gateway->ping_count = 0; + gateway->ib_calls = 0; + gateway->ob_calls = 0; + gateway->ib_failed_calls = 0; + gateway->ob_failed_calls = 0; if ((x_params = switch_xml_child(gateway_tag, "variables"))) { param = switch_xml_child(x_params, "variable"); From 1cc77ba2cbb19c97552a7a0bfe3f46c8ccffec70 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 04:19:51 -0400 Subject: [PATCH 14/30] core: add sound_prefix support in uuid_displace (FSCORE-550) --- src/switch_ivr_async.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 1988ccd79f..96fd188ca3 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -353,10 +353,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_ switch_media_bug_t *bug; switch_status_t status; time_t to = 0; + char *ext; + const char *prefix; displace_helper_t *dh; switch_codec_implementation_t read_impl = { 0 }; switch_core_session_get_read_impl(session, &read_impl); + if (zstr(file)) { + return SWITCH_STATUS_FALSE; + } if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; @@ -376,6 +381,34 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_ return SWITCH_STATUS_MEMERR; } + if (!(prefix = switch_channel_get_variable(channel, "sound_prefix"))) { + prefix = SWITCH_GLOBAL_dirs.base_dir; + } + + if (!strstr(file, SWITCH_URL_SEPARATOR)) { + if (!switch_is_file_path(file)) { + char *tfile = NULL; + char *e; + + if (*file == '[') { + tfile = switch_core_session_strdup(session, file); + if ((e = switch_find_end_paren(tfile, '[', ']'))) { + *e = '\0'; + file = e + 1; + } else { + tfile = NULL; + } + } + + file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "]" : "", prefix, SWITCH_PATH_SEPARATOR, file); + } + if ((ext = strrchr(file, '.'))) { + ext++; + } else { + ext = read_impl.iananame; + file = switch_core_session_sprintf(session, "%s.%s", file, ext); + } + } dh->fh.channels = read_impl.number_of_channels; dh->fh.samplerate = read_impl.actual_samples_per_second; From d0a74dd5c445e8a1540ba0a3f465ad394e033193 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 04:30:10 -0400 Subject: [PATCH 15/30] mod_spy: add support for loopback endpoint (MODAPP-416) --- src/mod/applications/mod_spy/mod_spy.c | 55 +++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c index d84fb11126..5093ad8f22 100644 --- a/src/mod/applications/mod_spy/mod_spy.c +++ b/src/mod/applications/mod_spy/mod_spy.c @@ -128,16 +128,17 @@ SWITCH_STANDARD_API(dump_hash) return SWITCH_STATUS_SUCCESS; } -static void event_handler(switch_event_t *event) +static switch_status_t process_event(switch_event_t *event) { switch_core_session_t *session = NULL; switch_channel_t *channel; - char *username[2] = { 0 }; - char *domain[2] = { 0 }; + char *username[3] = { 0 }; + char *domain[3] = { 0 }; char key[512]; char *uuid = NULL, *my_uuid = NULL; int i; + switch_thread_rwlock_rdlock(globals.spy_hash_lock); if (!globals.spy_count) { @@ -146,10 +147,15 @@ static void event_handler(switch_event_t *event) username[0] = switch_event_get_header(event, "Caller-Username"); domain[0] = switch_event_get_header(event, "variable_domain_name"); + domain[1] = switch_event_get_header(event, "variable_dialed_domain"); username[1] = switch_event_get_header(event, "variable_dialed_user"); - for (i = 0; i < 2; i++) { + username[2] = switch_event_get_header(event, "variable_user_name"); + domain[2] = switch_event_get_header(event, "variable_domain_name"); + + for (i = 0; i < 3; i++) { + if (username[i] && domain[i]) { switch_snprintf(key, sizeof(key), "%s@%s", username[i], domain[i]); @@ -159,11 +165,11 @@ static void event_handler(switch_event_t *event) } } - done: + done: switch_thread_rwlock_unlock(globals.spy_hash_lock); if (!uuid) { - return; + return SWITCH_STATUS_FALSE; } session = switch_core_session_locate(uuid); @@ -178,9 +184,46 @@ static void event_handler(switch_event_t *event) switch_channel_set_flag(channel, CF_BREAK); switch_core_session_rwunlock(session); + return SWITCH_STATUS_SUCCESS; } +static void event_handler(switch_event_t *event) +{ + if (process_event(event) != SWITCH_STATUS_SUCCESS) { + const char *peer_uuid = switch_event_get_header(event, "variable_signal_bond"); + switch_core_session_t *peer_session = NULL; + switch_channel_t *peer_channel = NULL; + switch_event_t *peer_event = NULL; + + if (!peer_uuid) { + return; + } + + if (!(peer_session = switch_core_session_locate(peer_uuid))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cant locate peer session for uuid %s\n", peer_uuid); + return; + } + + peer_channel = switch_core_session_get_channel(peer_session); + + if (switch_event_create(&peer_event, SWITCH_EVENT_CHANNEL_BRIDGE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cant create bridge event for peer channel %s\n", peer_uuid); + goto end; + } + + switch_channel_event_set_data(peer_channel, peer_event); + + end: + switch_core_session_rwunlock(peer_session); + + if (peer_event) { + process_event(peer_event); + switch_event_destroy(&peer_event); + } + } +} + #define USERSPY_SYNTAX " [uuid]" SWITCH_STANDARD_APP(userspy_function) { From 09a734bb48fc88c01c94e4a8cfe53ac24128342a Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:06:30 -0400 Subject: [PATCH 16/30] factor out timecheck function from Moc --- src/include/switch_xml.h | 2 + .../mod_dialplan_xml/mod_dialplan_xml.c | 89 +-------------- src/switch_xml.c | 101 ++++++++++++++++++ 3 files changed, 104 insertions(+), 88 deletions(-) diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h index 9a3b72d6fa..220e65df02 100644 --- a/src/include/switch_xml.h +++ b/src/include/switch_xml.h @@ -413,6 +413,8 @@ SWITCH_DECLARE(switch_status_t) switch_xml_unbind_search_function_ptr(_In_ switc ///\return the section mask SWITCH_DECLARE(switch_xml_section_t) switch_xml_parse_section_string(_In_opt_z_ const char *str); +SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond); + SWITCH_END_EXTERN_C ///\} #endif // _SWITCH_XML_H diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c index 4878011cc2..478b129f5a 100644 --- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c +++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c @@ -101,19 +101,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * switch_bool_t anti_action = SWITCH_TRUE; break_t do_break_i = BREAK_ON_FALSE; - const char *xyear = switch_xml_attr(xcond, "year"); - const char *xyday = switch_xml_attr(xcond, "yday"); - const char *xmon = switch_xml_attr(xcond, "mon"); - const char *xmday = switch_xml_attr(xcond, "mday"); - const char *xweek = switch_xml_attr(xcond, "week"); - const char *xmweek = switch_xml_attr(xcond, "mweek"); - const char *xwday = switch_xml_attr(xcond, "wday"); - const char *xhour = switch_xml_attr(xcond, "hour"); - const char *xminute = switch_xml_attr(xcond, "minute"); - const char *xminday = switch_xml_attr(xcond, "minute-of-day"); - switch_time_t ts = switch_micro_time_now(); - int time_match = -1; - switch_time_exp_t tm; + int time_match = switch_xml_std_datetime_check(xcond); switch_safe_free(field_expanded); switch_safe_free(expression_expanded); @@ -124,81 +112,6 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t * goto done; } - switch_time_exp_lt(&tm, ts); - - if (time_match && xyear) { - int test = tm.tm_year + 1900; - time_match = switch_number_cmp(xyear, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: year[%d] =~ %s (%s)\n", test, xyear, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xyday) { - int test = tm.tm_yday + 1; - time_match = switch_number_cmp(xyday, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: day of year[%d] =~ %s (%s)\n", test, xyday, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xmon) { - int test = tm.tm_mon + 1; - time_match = switch_number_cmp(xmon, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: month[%d] =~ %s (%s)\n", test, xmon, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xmday) { - int test = tm.tm_mday; - time_match = switch_number_cmp(xmday, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: day of month[%d] =~ %s (%s)\n", test, xmday, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xweek) { - int test = (int) (tm.tm_yday / 7 + 1); - time_match = switch_number_cmp(xweek, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: week of year[%d] =~ %s (%s)\n", test, xweek, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xmweek) { - /* calculate the day of the week of the first of the month (0-6) */ - int firstdow = (int) (7 - (tm.tm_mday - (tm.tm_wday + 1)) % 7) % 7; - /* calculate the week of the month (1-6) */ - int test = (int) ceil((tm.tm_mday + firstdow) / 7.0); - time_match = switch_number_cmp(xmweek, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: week of month[%d] =~ %s (%s)\n", test, xmweek, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xwday) { - int test = tm.tm_wday + 1; - time_match = switch_number_cmp(xwday, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: day of week[%d] =~ %s (%s)\n", test, xwday, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xhour) { - int test = tm.tm_hour; - time_match = switch_number_cmp(xhour, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: hour[%d] =~ %s (%s)\n", test, xhour, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xminute) { - int test = tm.tm_min; - time_match = switch_number_cmp(xminute, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: minute[%d] =~ %s (%s)\n", test, xminute, time_match ? "PASS" : "FAIL"); - } - - if (time_match && xminday) { - int test = (tm.tm_hour * 60) + (tm.tm_min + 1); - time_match = switch_number_cmp(xminday, test); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, - "Dialplan: minute of day[%d] =~ %s (%s)\n", test, xminday, time_match ? "PASS" : "FAIL"); - } - field = (char *) switch_xml_attr(xcond, "field"); if ((xexpression = switch_xml_child(xcond, "expression"))) { diff --git a/src/switch_xml.c b/src/switch_xml.c index 3c8bf76833..efda5dbe12 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2601,6 +2601,107 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_cut(switch_xml_t xml) return xml; } +SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) { + + const char *xyear = switch_xml_attr(xcond, "year"); + const char *xyday = switch_xml_attr(xcond, "yday"); + const char *xmon = switch_xml_attr(xcond, "mon"); + const char *xmday = switch_xml_attr(xcond, "mday"); + const char *xweek = switch_xml_attr(xcond, "week"); + const char *xmweek = switch_xml_attr(xcond, "mweek"); + const char *xwday = switch_xml_attr(xcond, "wday"); + const char *xhour = switch_xml_attr(xcond, "hour"); + const char *xminute = switch_xml_attr(xcond, "minute"); + const char *xminday = switch_xml_attr(xcond, "minute-of-day"); + + switch_time_t ts = switch_micro_time_now(); + int time_match = -1; + switch_time_exp_t tm; + + switch_time_exp_lt(&tm, ts); + + if (time_match && xyear) { + int test = tm.tm_year + 1900; + time_match = switch_number_cmp(xyear, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: year[%d] =~ %s (%s)\n", test, xyear, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xyday) { + int test = tm.tm_yday + 1; + time_match = switch_number_cmp(xyday, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: day of year[%d] =~ %s (%s)\n", test, xyday, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xmon) { + int test = tm.tm_mon + 1; + time_match = switch_number_cmp(xmon, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: month[%d] =~ %s (%s)\n", test, xmon, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xmday) { + int test = tm.tm_mday; + time_match = switch_number_cmp(xmday, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: day of month[%d] =~ %s (%s)\n", test, xmday, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xweek) { + int test = (int) (tm.tm_yday / 7 + 1); + time_match = switch_number_cmp(xweek, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: week of year[%d] =~ %s (%s)\n", test, xweek, time_match ? "PASS" : "FAIL"); + } + if (time_match && xweek) { + int test = (int) (tm.tm_yday / 7 + 1); + time_match = switch_number_cmp(xweek, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: week of year[%d] =~ %s (%s)\n", test, xweek, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xmweek) { + /* calculate the day of the week of the first of the month (0-6) */ + int firstdow = (int) (7 - (tm.tm_mday - (tm.tm_wday + 1)) % 7) % 7; + /* calculate the week of the month (1-6)*/ + int test = (int) ceil((tm.tm_mday + firstdow) / 7.0); + time_match = switch_number_cmp(xmweek, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime: week of month[%d] =~ %s (%s)\n", test, xmweek, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xwday) { + int test = tm.tm_wday + 1; + time_match = switch_number_cmp(xwday, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: day of week[%d] =~ %s (%s)\n", test, xwday, time_match ? "PASS" : "FAIL"); + } + if (time_match && xhour) { + int test = tm.tm_hour; + time_match = switch_number_cmp(xhour, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: hour[%d] =~ %s (%s)\n", test, xhour, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xminute) { + int test = tm.tm_min; + time_match = switch_number_cmp(xminute, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: minute[%d] =~ %s (%s)\n", test, xminute, time_match ? "PASS" : "FAIL"); + } + + if (time_match && xminday) { + int test = (tm.tm_hour * 60) + (tm.tm_min + 1); + time_match = switch_number_cmp(xminday, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: minute of day[%d] =~ %s (%s)\n", test, xminday, time_match ? "PASS" : "FAIL"); + } + + return time_match; +} + + #ifdef WIN32 /* * globbing functions for windows, part of libc on unix, this code was cut and paste from From 2a4d94cc03652341c41568c202e88c480d854d25 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:08:22 -0400 Subject: [PATCH 17/30] core: add 'critical' param on modules.conf to abort on mod load failure from Moc --- src/switch_loadable_module.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 2e37585e52..90f49ae58e 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1176,13 +1176,20 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) { switch_bool_t global = SWITCH_FALSE; const char *val = switch_xml_attr_soft(ld, "module"); + const char *critical = switch_xml_attr_soft(ld, "critical"); const char *sglobal = switch_xml_attr_soft(ld, "global"); if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val); continue; } global = switch_true(sglobal); - switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err); + + if (switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err) == SWITCH_STATUS_FALSE) { + if (critical && switch_true(critical)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val); + abort(); + } + } count++; } } From 0bd2b3a9e4621716e0f38c55dc7f1c27031e6004 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:12:26 -0400 Subject: [PATCH 18/30] tweak log --- src/switch_core_state_machine.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 46116da500..ec9c190e70 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -526,8 +526,9 @@ SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *ses switch_api_execute(cmd, expanded, use_session, &stream); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s(%s):\n%s\n", cmd, switch_str_nil(expanded), - switch_str_nil((char *) stream.data)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Hangup Command %s %s(%s):\n%s\n", + use_session ? "with Session" : "with no Session", cmd, switch_str_nil(expanded), + switch_str_nil((char *) stream.data) ); if (expanded != arg) { switch_safe_free(expanded); From 002896a4a2f468ce85166a0948139533c5d768bb Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:18:46 -0400 Subject: [PATCH 19/30] add 'direction' chan var --- src/switch_channel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_channel.c b/src/switch_channel.c index acefec30dc..e08bc4f63a 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -241,6 +241,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, (*channel)->hangup_cause = SWITCH_CAUSE_NONE; (*channel)->name = ""; (*channel)->direction = direction; + switch_channel_set_variable(*channel, "direction", switch_channel_direction(*channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"); return SWITCH_STATUS_SUCCESS; } From 2da1b5b7f983f8d6cd4c7d77b3eb99bf388c05f6 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:24:05 -0400 Subject: [PATCH 20/30] mod_sofia: add 'sofia_count_reg' api function --- src/mod/endpoints/mod_sofia/mod_sofia.c | 115 ++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index a7276a30cd..518b66ee1d 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2104,6 +2104,12 @@ const char *sofia_state_string(int state) return sofia_state_names[state]; } +struct cb_helper_sql2str { + char *buf; + size_t len; + int matches; +}; + struct cb_helper { sofia_profile_t *profile; switch_stream_handle_t *stream; @@ -2983,7 +2989,115 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName return 0; } +static int sql2str_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + struct cb_helper_sql2str *cbt = (struct cb_helper_sql2str *) pArg; + switch_copy_string(cbt->buf, argv[0], cbt->len); + cbt->matches++; + return 0; +} + +SWITCH_STANDARD_API(sofia_count_reg_function) { + char *data; + char *user = NULL; + char *domain = NULL; + char *concat = NULL; + char *profile_name = NULL; + char *p; + char *reply = "-1"; + sofia_profile_t *profile = NULL; + + if (!cmd) { + stream->write_function(stream, "%s", ""); + return SWITCH_STATUS_SUCCESS; + } + + data = strdup(cmd); + switch_assert(data); + + if ((p = strchr(data, '/'))) { + profile_name = data; + *p++ = '\0'; + user = p; + } else { + user = data; + } + + if ((domain = strchr(user, '@'))) { + *domain++ = '\0'; + if ( (concat = strchr( domain, '/')) ) { + *concat++ = '\0'; + } + } + else { + if ( (concat = strchr( user, '/')) ) { + *concat++ = '\0'; + } + } + + if (!profile_name && domain) { + profile_name = domain; + } + + if (user && profile_name) { + char *sql; + + if (!(profile = sofia_glue_find_profile(profile_name))) { + profile_name = domain; + domain = NULL; + } + + if (!profile && profile_name) { + profile = sofia_glue_find_profile(profile_name); + } + + if (profile) { + struct cb_helper_sql2str cb; + char reg_count[80] = ""; + + cb.buf = reg_count; + cb.len = sizeof(reg_count); + + if (!domain || !strchr(domain, '.')) { + domain = profile->name; + } + + if (zstr(user)) { + sql = switch_mprintf("select count(*) " + "from sip_registrations where (sip_host='%q' or presence_hosts like '%%%q%%')", + ( concat != NULL ) ? concat : "", domain, domain); + + } else { + sql = switch_mprintf("select count(*) " + "from sip_registrations where (sip_user='%q' or dir_user='%q') and (sip_host='%q' or presence_hosts like '%%%q%%')", + ( concat != NULL ) ? concat : "", user, user, domain, domain); + } + switch_assert(sql); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sql2str_callback, &cb); + switch_safe_free(sql); + if (!zstr(reg_count)) { + stream->write_function(stream, "%s", reg_count); + } else { + stream->write_function(stream, "0"); + } + reply = NULL; + + } + } + + if (reply) { + stream->write_function(stream, "%s", reply); + } + + switch_safe_free(data); + + if (profile) { + sofia_glue_release_profile(profile); + } + + return SWITCH_STATUS_SUCCESS; +} SWITCH_STANDARD_API(sofia_contact_function) { char *data; @@ -4272,6 +4386,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) SWITCH_ADD_API(api_interface, "sofia_contact", "Sofia Contacts", sofia_contact_function, "[profile/]@"); + SWITCH_ADD_API(api_interface, "sofia_count_reg", "Count Sofia registration", sofia_count_reg_function, "[profile/]@"); SWITCH_ADD_API(api_interface, "sofia_dig", "SIP DIG", sip_dig_function, ""); SWITCH_ADD_CHAT(chat_interface, SOFIA_CHAT_PROTO, sofia_presence_chat_send); From 56731c60346f27feea9656a89a0e72e792ffd7e9 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:26:54 -0400 Subject: [PATCH 21/30] mod_sofia: add EXPSECS time till reg expire and total to status return --- src/mod/endpoints/mod_sofia/mod_sofia.c | 27 ++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 518b66ee1d..aa83d4174b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2111,6 +2111,7 @@ struct cb_helper_sql2str { }; struct cb_helper { + uint32_t row_process; sofia_profile_t *profile; switch_stream_handle_t *stream; }; @@ -2121,12 +2122,17 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam { struct cb_helper *cb = (struct cb_helper *) pArg; char exp_buf[128] = ""; + int exp_secs = 0; switch_time_exp_t tm; + cb->row_process++; + if (argv[6]) { + time_t now = switch_epoch_time_now(NULL); switch_time_t etime = atoi(argv[6]); switch_size_t retsize; - + + exp_secs = etime - now; switch_time_exp_lt(&tm, switch_time_from_sec(etime)); switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm); } @@ -2136,7 +2142,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam "User: \t%s@%s\n" "Contact: \t%s\n" "Agent: \t%s\n" - "Status: \t%s(%s) EXP(%s)\n" + "Status: \t%s(%s) EXP(%s) EXPSECS(%d)\n" "Host: \t%s\n" "IP: \t%s\n" "Port: \t%s\n" @@ -2144,7 +2150,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam "Auth-Realm: \t%s\n" "MWI-Account:\t%s@%s\n\n", switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]), switch_str_nil(argv[3]), - switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, switch_str_nil(argv[11]), + switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs, switch_str_nil(argv[11]), switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]), switch_str_nil(argv[15]), switch_str_nil(argv[16]), switch_str_nil(argv[17])); return 0; @@ -2157,11 +2163,16 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum switch_time_exp_t tm; const int buflen = 2048; char xmlbuf[2048]; + int exp_secs = 0; + + cb->row_process++; if (argv[6]) { + time_t now = switch_epoch_time_now(NULL); switch_time_t etime = atoi(argv[6]); switch_size_t retsize; + exp_secs = etime - now; switch_time_exp_lt(&tm, switch_time_from_sec(etime)); switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm); } @@ -2171,7 +2182,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum cb->stream->write_function(cb->stream," %s@%s\n", switch_str_nil(argv[1]), switch_str_nil(argv[2])); cb->stream->write_function(cb->stream," %s\n", switch_amp_encode(switch_str_nil(argv[3]), xmlbuf, buflen)); cb->stream->write_function(cb->stream," %s\n", switch_str_nil(argv[7])); - cb->stream->write_function(cb->stream," %s(%s) exp(%s)\n", switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf); + cb->stream->write_function(cb->stream," %s(%s) exp(%s) expsecs(%d)\n", switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs); cb->stream->write_function(cb->stream," %s\n", switch_str_nil(argv[11])); cb->stream->write_function(cb->stream," %s\n", switch_str_nil(argv[12])); cb->stream->write_function(cb->stream," %s\n", switch_str_nil(argv[13])); @@ -2288,7 +2299,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t } else if (!strcasecmp(argv[0], "profile")) { struct cb_helper cb; char *sql = NULL; - + cb.row_process = 0; if ((argv[1]) && (profile = sofia_glue_find_profile(argv[1]))) { if (!argv[2] || (strcasecmp(argv[2], "reg") && strcasecmp(argv[2], "user"))) { stream->write_function(stream, "%s\n", line); @@ -2409,6 +2420,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, show_reg_callback, &cb); switch_safe_free(sql); + stream->write_function(stream, "Total items returned: %d\n", cb.row_process); stream->write_function(stream, "%s\n", line); sofia_glue_release_profile(profile); @@ -2564,6 +2576,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl } else if (!strcasecmp(argv[0], "profile")) { struct cb_helper cb; char *sql = NULL; + cb.row_process = 0; if ((argv[1]) && (profile = sofia_glue_find_profile(argv[1]))) { stream->write_function(stream, "%s\n", header); @@ -2982,6 +2995,8 @@ static int contact_callback(void *pArg, int argc, char **argv, char **columnName struct cb_helper *cb = (struct cb_helper *) pArg; char *contact; + cb->row_process++; + if (!zstr(argv[0]) && (contact = sofia_glue_get_url_from_contact(argv[0], 1))) { cb->stream->write_function(cb->stream, "%ssofia/%s/sip:%s,", argv[2], argv[1], sofia_glue_strip_proto(contact)); free(contact); @@ -3163,6 +3178,8 @@ SWITCH_STANDARD_API(sofia_contact_function) struct cb_helper cb; switch_stream_handle_t mystream = { 0 }; + cb.row_process = 0; + if (!domain || (!strchr(domain, '.') && strcmp(profile_name, domain))) { domain = profile->name; } From 8e718ddeea993f6a0d8549089782aba7cb8dd679 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:28:56 -0400 Subject: [PATCH 22/30] add last talking time per member to conference xml list --- src/mod/applications/mod_conference/mod_conference.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index c0cbc51d20..e2dacfd9a8 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -336,6 +336,7 @@ struct conference_member { int32_t energy_level; int32_t volume_in_level; int32_t volume_out_level; + switch_time_t last_talking; uint32_t native_rate; switch_audio_resampler_t *read_resampler; int16_t *resample_out; @@ -1912,6 +1913,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v if (diff >= diff_level || ++hangunder_hits >= hangunder) { hangover_hits = hangunder_hits = 0; + member->last_talking = switch_epoch_time_now(NULL); if (!switch_test_flag(member, MFLAG_TALKING)) { switch_event_t *event; @@ -3616,6 +3618,9 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer add_x_tag(x_member, "caller_id_number", profile->caller_id_number, toff++); + switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL) - member->last_talking); + add_x_tag(x_member, "last_talking", member->last_talking ? i : "N/A", toff++); + x_flags = switch_xml_add_child_d(x_member, "flags", count++); switch_assert(x_flags); From 822dfe104ee1c38c823c4d9c94555a4dcd3d3288 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 05:52:12 -0400 Subject: [PATCH 23/30] mod_voicemail: add 'vm-enabled' param (default true) --- .../mod_voicemail/mod_voicemail.c | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index d01205feff..abdda0a9e8 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1681,7 +1681,7 @@ static void update_mwi(vm_profile_t *profile, const char *id, const char *domain } -#define FREE_DOMAIN_ROOT() if (x_domain_root) switch_xml_free(x_domain_root); x_user = x_domain = x_domain_root = NULL +#define FREE_DOMAIN_ROOT() if (x_user) switch_xml_free(x_user); x_user = NULL static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *profile, const char *domain_name, const char *id, int auth) @@ -1689,7 +1689,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p vm_check_state_t vm_check_state = VM_CHECK_START; switch_channel_t *channel = switch_core_session_get_channel(session); switch_caller_profile_t *caller_profile = switch_channel_get_caller_profile(channel); - switch_xml_t x_domain = NULL, x_domain_root = NULL, x_user = NULL, x_params, x_param; + switch_xml_t x_user = NULL, x_params, x_param; switch_status_t status; char pass_buf[80] = "", *mypass = NULL, id_buf[80] = "", *myfolder = NULL; const char *thepass = NULL, *myid = id, *thehash = NULL, *vmhash = NULL; @@ -2083,18 +2083,37 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p switch_event_t *params; int ok = 1; - switch_event_create(¶ms, SWITCH_EVENT_GENERAL); switch_assert(params); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "destination_number", caller_profile->destination_number); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "caller_id_number", caller_id_number); - - if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"), - &x_domain_root, &x_domain, &x_user, NULL, params) != SWITCH_STATUS_SUCCESS) { + if (switch_xml_locate_user_merged("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"), + &x_user, params) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", myid, domain_name); ok = 0; } else { + switch_bool_t vm_enabled = SWITCH_TRUE; + + 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 *var = switch_xml_attr_soft(x_param, "name"); + const char *val = switch_xml_attr_soft(x_param, "value"); + + if (zstr(var) || zstr(val)) { + continue; /* Ignore empty entires */ + } + + if (!strcasecmp(var, "vm-enabled")) { + vm_enabled = !switch_false(val); + } + } + + if (!vm_enabled) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "User [%s@%s] have voicemail disabled\n", myid, domain_name); + ok = 0; + } myid = switch_core_session_strdup(session, switch_xml_attr(x_user, "id")); } @@ -2261,9 +2280,9 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p status = switch_ivr_phrase_macro(session, VM_GOODBYE_MACRO, NULL, NULL, NULL); } - if (x_domain_root) { - switch_xml_free(x_domain_root); - x_domain_root = NULL; + if (x_user) { + switch_xml_free(x_user); + x_user = NULL; } } @@ -2836,6 +2855,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p int disk_quota = 0; switch_bool_t skip_greeting = switch_true(switch_channel_get_variable(channel, "skip_greeting")); switch_bool_t skip_instructions = switch_true(switch_channel_get_variable(channel, "skip_instructions")); + switch_bool_t vm_enabled = SWITCH_TRUE; switch_channel_set_variable(channel, "skip_greeting", NULL); switch_channel_set_variable(channel, "skip_instructions", NULL); @@ -2888,12 +2908,19 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p disk_quota = atoi(val); } else if (!strcasecmp(var, "vm-alternate-greet-id")) { read_id = switch_core_session_strdup(session, val); + } else if (!strcasecmp(var, "vm-enabled")) { + vm_enabled = !switch_false(val); } else if (!strcasecmp(var, "vm-message-ext")) { vm_ext = switch_core_session_strdup(session, val); } } } + if (!vm_enabled) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "User [%s@%s] have voicemail disabled\n", id, domain_name); + ok = 0; + } + if (send_main && zstr(vm_email) && !zstr(email_addr)) { vm_email = switch_core_session_strdup(session, email_addr); if (zstr(vm_email)) { From 2ae67a4756fc1f43cee4f6e404e9a84bbe5c9a90 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 06:04:45 -0400 Subject: [PATCH 24/30] mod_sofia: add 'allow-empty-password' param (default true) --- src/mod/endpoints/mod_sofia/sofia_reg.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 676998c106..d9c60aa5a6 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1688,6 +1688,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, const char *passwd = NULL; const char *a1_hash = NULL; const char *mwi_account = NULL; + switch_bool_t allow_empty_password = SWITCH_TRUE; const char *call_id = NULL; char *sql; char *number_alias = NULL; @@ -1924,7 +1925,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (!strcasecmp(var, "mwi-account")) { mwi_account = val; } - + if (!strcasecmp(var, "allow-empty-password")) { + allow_empty_password = switch_true(val); + } if (!strcasecmp(var, "user-agent-filter")) { user_agent_filter = val; } @@ -1958,7 +1961,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (!strcasecmp(var, "mwi-account")) { mwi_account = val; } - + if (!strcasecmp(var, "allow-empty-password")) { + allow_empty_password = switch_true(val); + } if (!strcasecmp(var, "user-agent-filter")) { user_agent_filter = val; } @@ -1992,6 +1997,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (!strcasecmp(var, "mwi-account")) { mwi_account = val; } + if (!strcasecmp(var, "allow-empty-password")) { + allow_empty_password = switch_true(val); + } if (!strcasecmp(var, "user-agent-filter")) { user_agent_filter = val; } @@ -2058,6 +2066,12 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, } } + if (!allow_empty_password && zstr(passwd) && zstr(a1_hash)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Empty password denied for user %s@%s\n", username, domain_name); + ret = AUTH_FORBIDDEN; + goto end; + } + if (zstr(passwd) && zstr(a1_hash)) { ret = AUTH_OK; goto skip_auth; From a44e6c0891d3552517c8f8d6fad4fbc58c56eb71 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 06:58:36 -0400 Subject: [PATCH 25/30] add terminte-on-silence conference param --- .../mod_conference/mod_conference.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index e2dacfd9a8..04b8da03d0 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -262,6 +262,7 @@ typedef struct conference_obj { char *sound_prefix; char *special_announce; char *auto_record; + uint32_t terminate_on_silence; uint32_t max_members; char *maxmember_sound; uint32_t announce_count; @@ -336,6 +337,7 @@ struct conference_member { int32_t energy_level; int32_t volume_in_level; int32_t volume_out_level; + switch_time_t join_time; switch_time_t last_talking; uint32_t native_rate; switch_audio_resampler_t *read_resampler; @@ -639,6 +641,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe switch_mutex_lock(conference->member_mutex); switch_clear_flag(conference, CFLAG_DESTRUCT); + member->join_time = switch_epoch_time_now(NULL); member->conference = conference; member->next = conference->members; member->energy_level = conference->energy_level; @@ -1046,6 +1049,23 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v switch_mutex_unlock(imember->audio_in_mutex); } + /* Find if no one talked for more than x number of second */ + if (conference->terminate_on_silence && conference->count > 1) { + int is_talking = 0; + + for (imember = conference->members; imember; imember = imember->next) { + if (switch_epoch_time_now(NULL) - imember->join_time <= conference->terminate_on_silence) { + is_talking++; + } else if (imember->last_talking != 0 && switch_epoch_time_now(NULL) - imember->last_talking <= conference->terminate_on_silence) { + is_talking++; + } + } + if (is_talking == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Conference has been idle for over %d seconds, terminating\n", conference->terminate_on_silence); + switch_set_flag(conference, CFLAG_DESTRUCT); + } + } + /* Start recording if there's more than one participant. */ if (conference->auto_record && !conference->is_recording && conference->count > 1) { conference->is_recording = 1; @@ -3618,6 +3638,9 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer add_x_tag(x_member, "caller_id_number", profile->caller_id_number, toff++); + switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL) - member->join_time); + add_x_tag(x_member, "join_time", i, toff++); + switch_snprintf(i, sizeof(i), "%d", switch_epoch_time_now(NULL) - member->last_talking); add_x_tag(x_member, "last_talking", member->last_talking ? i : "N/A", toff++); @@ -5798,6 +5821,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_m char *suppress_events = NULL; char *verbose_events = NULL; char *auto_record = NULL; + char *terminate_on_silence = NULL; /* Validate the conference name */ if (zstr(name)) { @@ -5927,6 +5951,8 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_m verbose_events = val; } else if (!strcasecmp(var, "auto-record") && !zstr(val)) { auto_record = val; + } else if (!strcasecmp(var, "terminate-on-silence") && !zstr(val)) { + terminate_on_silence = val; } } @@ -6098,6 +6124,9 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_m if (!zstr(auto_record)) { conference->auto_record = switch_core_strdup(conference->pool, auto_record); } + if (!zstr(terminate_on_silence)) { + conference->terminate_on_silence = atoi(terminate_on_silence); + } if (!zstr(verbose_events) && switch_true(verbose_events)) { conference->verbose_events = 1; From 41557506e115e93dcc4fdb8bf44fb5af0192c5ab Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 26 Apr 2010 07:02:26 -0400 Subject: [PATCH 26/30] add xml error checking --- src/switch_xml.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/switch_xml.c b/src/switch_xml.c index efda5dbe12..947a3060e9 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -403,6 +403,10 @@ SWITCH_DECLARE(const char *) switch_xml_attr(switch_xml_t xml, const char *attr) return NULL; } + if (!root->attr) { + return NULL; + } + for (i = 0; root->attr[i] && xml->name && strcmp(xml->name, root->attr[i][0]); i++); if (!root->attr[i]) return NULL; /* no matching default attributes */ @@ -451,6 +455,9 @@ SWITCH_DECLARE(const char **) switch_xml_pi(switch_xml_t xml, const char *target return (const char **) SWITCH_XML_NIL; while (root->xml.parent) root = (switch_xml_root_t) root->xml.parent; /* root tag */ + if (!root || !root->pi) { + return (const char **) SWITCH_XML_NIL; + } while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; /* find target */ return (const char **) ((root->pi[i]) ? root->pi[i] + 1 : SWITCH_XML_NIL); @@ -463,6 +470,10 @@ static switch_xml_t switch_xml_err(switch_xml_root_t root, char *s, const char * int line = 1; char *t, fmt[SWITCH_XML_ERRL]; + if (!root || !root->s) { + return NULL; + } + for (t = root->s; t && t < s; t++) if (*t == '\n') line++; @@ -578,7 +589,13 @@ static char *switch_xml_decode(char *s, char **ent, char t) /* called when parser finds start of new tag */ static void switch_xml_open_tag(switch_xml_root_t root, char *name, char **attr) { - switch_xml_t xml = root->cur; + switch_xml_t xml; + + if (!root || !root->cur) { + return; + } + + xml = root->cur; if (xml->name) xml = switch_xml_add_child(xml, name, strlen(xml->txt)); @@ -592,10 +609,16 @@ static void switch_xml_open_tag(switch_xml_root_t root, char *name, char **attr) /* called when parser finds character content between open and closing tag */ static void switch_xml_char_content(switch_xml_root_t root, char *s, switch_size_t len, char t) { - switch_xml_t xml = root->cur; + switch_xml_t xml; char *m = s; switch_size_t l; + if (!root || !root->cur) { + return; + } + + xml = root->cur; + if (!xml || !xml->name || !len) return; /* sanity check */ @@ -632,7 +655,7 @@ static void switch_xml_char_content(switch_xml_root_t root, char *s, switch_size /* called when parser finds closing tag */ static switch_xml_t switch_xml_close_tag(switch_xml_root_t root, char *name, char *s) { - if (!root->cur || !root->cur->name || strcmp(name, root->cur->name)) + if (!root || !root->cur || !root->cur->name || strcmp(name, root->cur->name)) return switch_xml_err(root, s, "unexpected closing tag ", name); root->cur = root->cur->parent; @@ -681,7 +704,7 @@ static void switch_xml_proc_inst(switch_xml_root_t root, char *s, switch_size_t return; } - if (!root->pi[0]) { + if (!root->pi || !root->pi[0]) { root->pi = (char ***) malloc(sizeof(char **)); if (!root->pi) return; From a110ae95278f4620d184bba7bcf3ef826742126b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 26 Apr 2010 10:55:46 -0500 Subject: [PATCH 27/30] Build fixes for windows --- src/switch_ivr_originate.c | 2 +- src/switch_rtp.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index a79f2eb6f3..750da18c13 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1661,7 +1661,7 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * } if (state->ringback->asis && datalen) { - uint16_t flen = datalen; + uint16_t flen = (uint16_t)datalen; switch_mutex_lock(state->mutex); switch_buffer_write(state->buffer, &flen, sizeof(uint16_t)); switch_buffer_write(state->buffer, read_frame->data, datalen); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index d1126703e6..b8b5185745 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2130,7 +2130,7 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t "Sender Packet Count = %u, " \ "Sender Octet Count = %u\n", rtp_session->rtcp_recv_msg.header.count, - ntohs(rtp_session->rtcp_recv_msg.header.length), + ntohs((uint16_t)rtp_session->rtcp_recv_msg.header.length), ntohl(sr->ssrc), ntohl(sr->ntp_msw), ntohl(sr->ntp_lsw), @@ -2907,7 +2907,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rt rtp_session->rtcp_fresh_frame = 0; frame->ssrc = ntohl(sr->ssrc); - frame->packet_type = rtp_session->rtcp_recv_msg.header.type; + frame->packet_type = (uint16_t)rtp_session->rtcp_recv_msg.header.type; frame->ntp_msw = ntohl(sr->ntp_msw); frame->ntp_lsw = ntohl(sr->ntp_lsw); frame->timestamp = ntohl(sr->ts); @@ -3337,8 +3337,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session, struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_send_msg.body; sr->ssrc = send_msg->header.ssrc; - sr->ntp_msw = htonl(rtp_session->send_time / 1000000 + 2208988800UL); - sr->ntp_lsw = htonl(rtp_session->send_time % 1000000 * ((UINT_MAX * 1.0)/ 1000000.0)); + sr->ntp_msw = htonl((u_long)rtp_session->send_time / 1000000 + 2208988800UL); + sr->ntp_lsw = htonl((u_long)(rtp_session->send_time % 1000000 * ((UINT_MAX * 1.0)/ 1000000.0))); sr->ts = send_msg->header.ts; sr->pc = htonl(rtp_session->stats.outbound.packet_count); sr->oc = htonl((rtp_session->stats.outbound.raw_bytes - rtp_session->stats.outbound.packet_count * sizeof(srtp_hdr_t))); From 762bf62c0b23e83a4e0b61b2e1cfcc373cf9a993 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Apr 2010 16:38:05 -0500 Subject: [PATCH 28/30] FSCORE-597 --- src/switch_core_sqldb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 9e02a91c8e..1e0d4e9d89 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -958,6 +958,7 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CHANNEL_DESTROY: sql = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + printf("%s\n", sql); break; case SWITCH_EVENT_CHANNEL_UUID: { @@ -1143,7 +1144,7 @@ static void core_event_handler(switch_event_t *event) } if (sql) { - if (switch_stristr("update channels", sql)) { + if (switch_stristr("update channels", sql) || switch_stristr("delete from channels", sql)) { switch_queue_push(sql_manager.sql_queue[1], sql); } else { switch_queue_push(sql_manager.sql_queue[0], sql); From 9699e002704c2018e9dd0c043a90c2d404ec4b82 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 26 Apr 2010 18:17:39 -0500 Subject: [PATCH 29/30] MODAPP-403 --- src/mod/applications/mod_voicemail/mod_voicemail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index abdda0a9e8..b919b17c58 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1524,7 +1524,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t TRY_CODE(switch_ivr_phrase_macro(session, VM_INVALID_EXTENSION_MACRO, vm_cc, NULL, NULL)); goto get_exten; } - } else if (!strcmp(input, profile->delete_file_key) || !strcmp(input, profile->email_key)) { + } else if (!strcmp(input, profile->delete_file_key) || (!strcmp(input, profile->email_key) && !zstr(cbt->email))) { char *sql = switch_mprintf("update voicemail_msgs set flags='delete' where uuid='%s'", cbt->uuid); vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(sql); From 825bf99daa3c987e181a561341627d7626fcb4bc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 27 Apr 2010 12:49:53 -0500 Subject: [PATCH 30/30] MODENDP-304 --- src/mod/endpoints/mod_sofia/sofia_presence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 0a8a333812..2a9296bb6b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1901,7 +1901,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, full_from = sip_header_as_string(profile->home, (void *) sip->sip_from); full_via = sip_header_as_string(profile->home, (void *) sip->sip_via); - if (sip->sip_expires->ex_delta > 31536000) { + if (sip && sip->sip_expires && sip->sip_expires->ex_delta > 31536000) { sip->sip_expires->ex_delta = 31536000; }