diff --git a/freeswitch.spec b/freeswitch.spec index f45423bba8..91b551247d 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -3,7 +3,7 @@ # spec file for package freeswitch # # includes module(s): freeswitch-devel freeswitch-codec-passthru-amr freeswitch-codec-passthru-amrwb freeswitch-codec-passthru-g729 -# freeswitch-codec-passthru-g7231 freeswitch-lua freeswitch-perl freeswitch-python freeswitch-spidermonkey freeswitch-v8 +# freeswitch-codec-passthru-g7231 freeswitch-lua freeswitch-perl freeswitch-python freeswitch-v8 # freeswitch-lan-de freeswitch-lang-en freeswitch-lang-fr freeswitch-lang-hu freeswitch-lang-ru freeswitch-freetdm # and others # @@ -151,7 +151,11 @@ BuildRequires: gcc-c++ BuildRequires: gnutls-devel BuildRequires: libtool >= 1.5.17 BuildRequires: ncurses-devel -BuildRequires: openssl-devel +BuildRequires: openssl-devel >= 1.0.1e +BuildRequires: pcre-devel +BuildRequires: speex-devel +BuildRequires: sqlite-devel +BuildRequires: libedit-devel BuildRequires: perl %if 0%{?fedora_version} >= 8 || 0%{?rhel} >= 6 BuildRequires: perl-ExtUtils-Embed @@ -184,7 +188,11 @@ Requires: libogg Requires: libvorbis Requires: curl Requires: ncurses -Requires: openssl +Requires: pcre +Requires: speex +Requires: sqlite +Requires: libedit +Requires: openssl >= 1.0.1e Requires: unixODBC Requires: libjpeg #Requires: openldap @@ -1093,13 +1101,6 @@ Requires: python %description python -%package spidermonkey -Summary: JavaScript support for the FreeSWITCH open source telephony platform -Group: System/Libraries -Requires: %{name} = %{version}-%{release} - -%description spidermonkey - %package v8 Summary: JavaScript support for the FreeSWITCH open source telephony platform, using Google V8 JavaScript engine Group: System/Libraries @@ -1429,7 +1430,7 @@ FORMATS_MODULES+=" formats/mod_ssml" # Embedded Languages # ###################################################################################################################### -LANGUAGES_MODULES="languages/mod_lua languages/mod_perl languages/mod_python languages/mod_spidermonkey " +LANGUAGES_MODULES="languages/mod_lua languages/mod_perl languages/mod_python " #LANGUAGES_MODULES+="languages/mod_v8" ###################################################################################################################### @@ -2208,15 +2209,6 @@ fi %dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/python.conf.xml -%files spidermonkey -%{MODINSTDIR}/mod_spidermonkey*.so* -%{LIBDIR}/libjs.so* -%{LIBDIR}/libnspr4.so -%{LIBDIR}/libplds4.so -%{LIBDIR}/libplc4.so -%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs -%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/spidermonkey.conf.xml - %files v8 #%{MODINSTDIR}/mod_v8*.so* #%{LIBDIR}/libv8.so @@ -2346,6 +2338,8 @@ fi # ###################################################################################################################### %changelog +* Fri Jun 02 2014 - krice@freeswitch.org +- remove mod_spidermoney as its been deprecated * Fri Feb 21 2014 - crienzo@grasshopper.com - change file owner to root * Wed Feb 19 2014 - crienzo@grasshopper.com diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index b7b764427d..6e4446524b 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -139,10 +139,10 @@ static void screen_size(int *x, int *y) #elif defined(TIOCGWINSZ) struct winsize w; - ioctl(0, TIOCGWINSZ, &w); - - if (x) *x = w.ws_col; - if (y) *y = w.ws_row; + if ( (ioctl(0, TIOCGWINSZ, &w)) >= 0 ) { + if (x) *x = w.ws_col; + if (y) *y = w.ws_row; + } #else if (x) *x = 80; if (y) *y = 24; @@ -1000,7 +1000,7 @@ static const char *inf = "Type /help to see a list of commands\n\n\n"; static void print_banner(FILE *stream, int color) { - int x; + int x = 0; const char *use = NULL; #include diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 22780dd4ac..e38a8ae003 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -100,6 +100,9 @@ typedef struct switch_device_stats_s { uint32_t held; uint32_t held_in; uint32_t held_out; + uint32_t unheld; + uint32_t unheld_in; + uint32_t unheld_out; uint32_t hup; uint32_t hup_in; uint32_t hup_out; diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 043bbbce44..312937756e 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -106,6 +106,7 @@ typedef struct switch_core_media_params_s { char *early_sdp; char *local_sdp_str; char *last_sdp_str; + char *last_sdp_response; char *stun_ip; switch_port_t stun_port; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 18a829055b..d7f5bc747e 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1184,7 +1184,7 @@ typedef enum { CCS_HELD, CCS_RING_WAIT, CCS_HANGUP, - CCS_UNHOLD + CCS_UNHELD } switch_channel_callstate_t; typedef enum { @@ -1193,6 +1193,7 @@ typedef enum { SDS_ACTIVE, SDS_ACTIVE_MULTI, SDS_HELD, + SDS_UNHELD, SDS_HANGUP } switch_device_state_t; diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 7fae227ab7..cb9b558a48 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -439,7 +439,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) int bits = 0; char *dft_fmtp = NULL; opus_codec_settings_t settings = { 0 }; - switch_status_t status = SWITCH_FALSE; + switch_status_t status = SWITCH_STATUS_SUCCESS; if ((status = opus_load_config(SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) { return status; diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index c52d0611c5..6be269e565 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -2451,232 +2451,226 @@ switch_io_routines_t dingaling_io_routines = { */ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, + switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t oflags, switch_call_cause_t *cancel_cause) { - if ((*new_session = switch_core_session_request(dingaling_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { - struct private_object *tech_pvt; - switch_channel_t *channel; - switch_caller_profile_t *caller_profile = NULL; - mdl_profile_t *mdl_profile = NULL; - ldl_session_t *dlsession = NULL; - char *profile_name; - char *callto; - char idbuf[1024]; - char *full_id = NULL; - char sess_id[11] = ""; - char *dnis = NULL; - char workspace[1024] = ""; - char *p, *u, ubuf[512] = "", *user = NULL, *f_cid_msg = NULL; - const char *cid_msg = NULL; - ldl_user_flag_t flags = LDL_FLAG_OUTBOUND; - const char *var; + struct private_object *tech_pvt; + switch_channel_t *channel; + switch_caller_profile_t *caller_profile = NULL; + mdl_profile_t *mdl_profile = NULL; + ldl_session_t *dlsession = NULL; + char *profile_name; + char *callto; + char idbuf[1024]; + char *full_id = NULL; + char sess_id[11] = ""; + char *dnis = NULL; + char workspace[1024] = ""; + char *p, *u, ubuf[512] = "", *user = NULL, *f_cid_msg = NULL; + const char *cid_msg = NULL; + ldl_user_flag_t flags = LDL_FLAG_OUTBOUND; + const char *var; + char name[128]; - switch_copy_string(workspace, outbound_profile->destination_number, sizeof(workspace)); - profile_name = workspace; - - if ((callto = strchr(profile_name, '/'))) { - *callto++ = '\0'; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Invalid URL!\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_CAUSE_INVALID_NUMBER_FORMAT; - } - - if ((dnis = strchr(callto, ':'))) { - *dnis++ = '\0'; - } - - for (p = callto; p && *p; p++) { - *p = (char) tolower(*p); - } - - if ((p = strchr(profile_name, '@'))) { - *p++ = '\0'; - u = profile_name; - profile_name = p; - switch_snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", u, profile_name); - user = ubuf; - } - - if ((mdl_profile = switch_core_hash_find(globals.profile_hash, profile_name))) { - if (!(mdl_profile->user_flags & LDL_FLAG_COMPONENT)) { - user = ldl_handle_get_login(mdl_profile->handle); - } else { - if (!user) { - const char *id_num; - - if (!(id_num = outbound_profile->caller_id_number)) { - if (!(id_num = outbound_profile->caller_id_name)) { - id_num = "nobody"; - } - } - - if (strchr(id_num, '@')) { - switch_snprintf(ubuf, sizeof(ubuf), "%s/talk", id_num); - user = ubuf; - } else { - switch_snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", id_num, profile_name); - user = ubuf; - } - } - } - - if (mdl_profile->purge) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' is marked for deletion, disallowing outgoing call\n", - mdl_profile->name); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_NORMAL_UNSPECIFIED); - return SWITCH_CAUSE_NORMAL_UNSPECIFIED; - } - - if (switch_thread_rwlock_tryrdlock(mdl_profile->rwlock) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't do read lock on profile '%s'\n", mdl_profile->name); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_NORMAL_UNSPECIFIED); - return SWITCH_CAUSE_NORMAL_UNSPECIFIED; - } - - - - - if (!ldl_handle_ready(mdl_profile->handle)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Doh! we are not logged in yet!\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - if (switch_stristr("voice.google.com", callto)) { - full_id = callto; - flags |= LDL_FLAG_GATEWAY; - } else if (!(full_id = ldl_handle_probe(mdl_profile->handle, callto, user, idbuf, sizeof(idbuf)))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Unknown Recipient!\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_NO_USER_RESPONSE); - return SWITCH_CAUSE_NO_USER_RESPONSE; - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Unknown Profile!\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - - switch_core_session_add_stream(*new_session, NULL); - if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) { - memset(tech_pvt, 0, sizeof(*tech_pvt)); - tech_pvt->profile = mdl_profile; - switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); - tech_pvt->flags |= globals.flags; - tech_pvt->flags |= mdl_profile->flags; - channel = switch_core_session_get_channel(*new_session); - switch_core_session_set_private(*new_session, tech_pvt); - tech_pvt->session = *new_session; - tech_pvt->channel = switch_core_session_get_channel(tech_pvt->session); - tech_pvt->transports[LDL_TPORT_RTP].codec_index = -1; - tech_pvt->transports[LDL_TPORT_VIDEO_RTP].codec_index = -1; - - switch_set_flag(tech_pvt, TFLAG_SECURE); - mdl_build_crypto(tech_pvt, LDL_TPORT_RTP, 1, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND); - mdl_build_crypto(tech_pvt, LDL_TPORT_VIDEO_RTP, 1, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND); - - - - if (!(tech_pvt->transports[LDL_TPORT_RTP].local_port = switch_rtp_request_port(mdl_profile->ip))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "No RTP port available!\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - tech_pvt->transports[LDL_TPORT_RTP].adv_local_port = tech_pvt->transports[LDL_TPORT_RTP].local_port; - tech_pvt->transports[LDL_TPORT_RTCP].adv_local_port = tech_pvt->transports[LDL_TPORT_RTP].local_port + 1; - if (!(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].local_port = switch_rtp_request_port(mdl_profile->ip))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "No RTP port available!\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - tech_pvt->transports[LDL_TPORT_VIDEO_RTP].adv_local_port = tech_pvt->transports[LDL_TPORT_VIDEO_RTP].local_port; - tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].adv_local_port = tech_pvt->transports[LDL_TPORT_VIDEO_RTP].local_port + 1; - - - - tech_pvt->recip = switch_core_session_strdup(*new_session, full_id); - if (dnis) { - tech_pvt->dnis = switch_core_session_strdup(*new_session, dnis); - } - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - if (outbound_profile) { - char name[128]; - - switch_snprintf(name, sizeof(name), "dingaling/%s", outbound_profile->destination_number); - switch_channel_set_name(channel, name); - - caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); - switch_channel_set_caller_profile(channel, caller_profile); - tech_pvt->caller_profile = caller_profile; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Doh! no caller profile\n"); - terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - } - - switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); - - switch_stun_random_string(sess_id, 10, "0123456789"); - tech_pvt->us = switch_core_session_strdup(*new_session, user); - tech_pvt->them = switch_core_session_strdup(*new_session, full_id); - ldl_session_create(&dlsession, mdl_profile->handle, sess_id, full_id, user, flags); - - if (session) { - switch_channel_t *calling_channel = switch_core_session_get_channel(session); - cid_msg = switch_channel_get_variable(calling_channel, "dl_cid_msg"); - } - - if (!cid_msg) { - f_cid_msg = switch_mprintf("Incoming Call From %s %s\n", outbound_profile->caller_id_name, outbound_profile->caller_id_number); - cid_msg = f_cid_msg; - } - - if ((flags & LDL_FLAG_GATEWAY)) { - cid_msg = NULL; - } - - if (cid_msg) { - char *them; - them = strdup(tech_pvt->them); - if (them) { - char *ptr; - if ((ptr = strchr(them, '/'))) { - *ptr = '\0'; - } - ldl_handle_send_msg(mdl_profile->handle, tech_pvt->us, them, "", switch_str_nil(cid_msg)); - } - switch_safe_free(them); - } - switch_safe_free(f_cid_msg); - - - ldl_session_set_private(dlsession, *new_session); - ldl_session_set_value(dlsession, "dnis", dnis); - ldl_session_set_value(dlsession, "caller_id_name", outbound_profile->caller_id_name); - ldl_session_set_value(dlsession, "caller_id_number", outbound_profile->caller_id_number); - tech_pvt->dlsession = dlsession; - - if ((var = switch_event_get_header(var_event, "absolute_codec_string"))) { - switch_channel_set_variable(channel, "absolute_codec_string", var); - } - - if (!get_codecs(tech_pvt)) { - terminate_session(new_session, __LINE__, SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL); - return SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL; - } - switch_channel_set_state(channel, CS_INIT); - return SWITCH_CAUSE_SUCCESS; + *new_session = switch_core_session_request(dingaling_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, oflags, pool); + if (!*new_session) { + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + if (!outbound_profile) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Doh! no caller profile\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } + switch_copy_string(workspace, outbound_profile->destination_number, sizeof(workspace)); + profile_name = workspace; + + if ((callto = strchr(profile_name, '/'))) { + *callto++ = '\0'; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Invalid URL!\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_CAUSE_INVALID_NUMBER_FORMAT; + } + + if ((dnis = strchr(callto, ':'))) { + *dnis++ = '\0'; + } + + for (p = callto; p && *p; p++) { + *p = (char) tolower(*p); + } + + if ((p = strchr(profile_name, '@'))) { + *p++ = '\0'; + u = profile_name; + profile_name = p; + switch_snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", u, profile_name); + user = ubuf; + } + + mdl_profile = switch_core_hash_find(globals.profile_hash, profile_name); + + if (!mdl_profile) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Unknown Profile!\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } + + if (!(mdl_profile->user_flags & LDL_FLAG_COMPONENT)) { + user = ldl_handle_get_login(mdl_profile->handle); + } else { + if (!user) { + const char *id_num; + + if (!(id_num = outbound_profile->caller_id_number)) { + if (!(id_num = outbound_profile->caller_id_name)) { + id_num = "nobody"; + } + } + + if (strchr(id_num, '@')) { + switch_snprintf(ubuf, sizeof(ubuf), "%s/talk", id_num); + user = ubuf; + } else { + switch_snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", id_num, profile_name); + user = ubuf; + } + } + } + + if (mdl_profile->purge) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' is marked for deletion, disallowing outgoing call\n", + mdl_profile->name); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_NORMAL_UNSPECIFIED); + return SWITCH_CAUSE_NORMAL_UNSPECIFIED; + } + + if (switch_thread_rwlock_tryrdlock(mdl_profile->rwlock) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't do read lock on profile '%s'\n", mdl_profile->name); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_NORMAL_UNSPECIFIED); + return SWITCH_CAUSE_NORMAL_UNSPECIFIED; + } + + if (!ldl_handle_ready(mdl_profile->handle)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Doh! we are not logged in yet!\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } + if (switch_stristr("voice.google.com", callto)) { + full_id = callto; + flags |= LDL_FLAG_GATEWAY; + } else if (!(full_id = ldl_handle_probe(mdl_profile->handle, callto, user, idbuf, sizeof(idbuf)))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_DEBUG, "Unknown Recipient!\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_NO_USER_RESPONSE); + return SWITCH_CAUSE_NO_USER_RESPONSE; + } + + switch_core_session_add_stream(*new_session, NULL); + tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)); + + if (!tech_pvt) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } + + memset(tech_pvt, 0, sizeof(*tech_pvt)); + tech_pvt->profile = mdl_profile; + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); + tech_pvt->flags |= globals.flags; + tech_pvt->flags |= mdl_profile->flags; + channel = switch_core_session_get_channel(*new_session); + switch_core_session_set_private(*new_session, tech_pvt); + tech_pvt->session = *new_session; + tech_pvt->channel = switch_core_session_get_channel(tech_pvt->session); + tech_pvt->transports[LDL_TPORT_RTP].codec_index = -1; + tech_pvt->transports[LDL_TPORT_VIDEO_RTP].codec_index = -1; + + switch_set_flag(tech_pvt, TFLAG_SECURE); + mdl_build_crypto(tech_pvt, LDL_TPORT_RTP, 1, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND); + mdl_build_crypto(tech_pvt, LDL_TPORT_VIDEO_RTP, 1, AES_CM_128_HMAC_SHA1_80, SWITCH_RTP_CRYPTO_SEND); + + if (!(tech_pvt->transports[LDL_TPORT_RTP].local_port = switch_rtp_request_port(mdl_profile->ip))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "No RTP port available!\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } + tech_pvt->transports[LDL_TPORT_RTP].adv_local_port = tech_pvt->transports[LDL_TPORT_RTP].local_port; + tech_pvt->transports[LDL_TPORT_RTCP].adv_local_port = tech_pvt->transports[LDL_TPORT_RTP].local_port + 1; + if (!(tech_pvt->transports[LDL_TPORT_VIDEO_RTP].local_port = switch_rtp_request_port(mdl_profile->ip))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "No RTP port available!\n"); + terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + } + tech_pvt->transports[LDL_TPORT_VIDEO_RTP].adv_local_port = tech_pvt->transports[LDL_TPORT_VIDEO_RTP].local_port; + tech_pvt->transports[LDL_TPORT_VIDEO_RTCP].adv_local_port = tech_pvt->transports[LDL_TPORT_VIDEO_RTP].local_port + 1; + + tech_pvt->recip = switch_core_session_strdup(*new_session, full_id); + if (dnis) { + tech_pvt->dnis = switch_core_session_strdup(*new_session, dnis); + } + + switch_snprintf(name, sizeof(name), "dingaling/%s", outbound_profile->destination_number); + switch_channel_set_name(channel, name); + + caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); + switch_channel_set_caller_profile(channel, caller_profile); + tech_pvt->caller_profile = caller_profile; + + switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); + + switch_stun_random_string(sess_id, 10, "0123456789"); + tech_pvt->us = switch_core_session_strdup(*new_session, user); + tech_pvt->them = switch_core_session_strdup(*new_session, full_id); + ldl_session_create(&dlsession, mdl_profile->handle, sess_id, full_id, user, flags); + + if (session) { + switch_channel_t *calling_channel = switch_core_session_get_channel(session); + cid_msg = switch_channel_get_variable(calling_channel, "dl_cid_msg"); + } + + if (!cid_msg) { + f_cid_msg = switch_mprintf("Incoming Call From %s %s\n", outbound_profile->caller_id_name, outbound_profile->caller_id_number); + cid_msg = f_cid_msg; + } + + if ((flags & LDL_FLAG_GATEWAY)) { + cid_msg = NULL; + } + + if (cid_msg) { + char *them; + them = strdup(tech_pvt->them); + if (them) { + char *ptr; + if ((ptr = strchr(them, '/'))) { + *ptr = '\0'; + } + ldl_handle_send_msg(mdl_profile->handle, tech_pvt->us, them, "", switch_str_nil(cid_msg)); + } + switch_safe_free(them); + } + switch_safe_free(f_cid_msg); + + ldl_session_set_private(dlsession, *new_session); + ldl_session_set_value(dlsession, "dnis", dnis); + ldl_session_set_value(dlsession, "caller_id_name", outbound_profile->caller_id_name); + ldl_session_set_value(dlsession, "caller_id_number", outbound_profile->caller_id_number); + tech_pvt->dlsession = dlsession; + + if ((var = switch_event_get_header(var_event, "absolute_codec_string"))) { + switch_channel_set_variable(channel, "absolute_codec_string", var); + } + + if (!get_codecs(tech_pvt)) { + terminate_session(new_session, __LINE__, SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL); + return SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL; + } + switch_channel_set_state(channel, CS_INIT); + return SWITCH_CAUSE_SUCCESS; } static switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches) @@ -4360,8 +4354,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi char *hint = NULL, *p, *freeme = NULL; hint = from; - if (strchr(from, '/')) { - freeme = strdup(from); + if (strchr(from, '/') && (freeme = strdup(from))) { p = strchr(freeme, '/'); *p = '\0'; from = freeme; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index c87f38a8a9..71018ddc29 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -5326,7 +5326,6 @@ static void general_event_handler(switch_event_t *event) } } switch_mutex_unlock(mod_sofia_globals.hash_mutex); - sofia_glue_restart_all_profiles(); } } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index cd148d99e8..4d971d1438 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -716,6 +716,8 @@ struct sofia_profile { int tcp_pingpong; int tcp_ping2pong; ka_type_t keepalive; + int bind_attempts; + int bind_attempt_interval; }; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 454e7109fb..0ae369dfda 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2666,7 +2666,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void int use_timer = !sofia_test_pflag(profile, PFLAG_DISABLE_TIMER); int use_rfc_5626 = sofia_test_pflag(profile, PFLAG_ENABLE_RFC5626); const char *supported = NULL; - int sanity; + int sanity, attempts = 0; switch_thread_t *worker_thread; switch_status_t st; char qname [128] = ""; @@ -2707,72 +2707,83 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void profile->tls_verify_in_subjects = su_strlst_dup_split((su_home_t *)profile->nua, profile->tls_verify_in_subjects_str, "|"); } - profile->nua = nua_create(profile->s_root, /* Event loop */ - sofia_event_callback, /* Callback for processing events */ - profile, /* Additional data to pass to callback */ - TAG_IF( ! sofia_test_pflag(profile, PFLAG_TLS) || ! profile->tls_only, NUTAG_URL(profile->bindurl)), - NTATAG_USER_VIA(1), - TPTAG_PONG2PING(1), - NUTAG_RETRY_AFTER_ENABLE(0), - TAG_IF(!strchr(profile->sipip, ':'), - SOATAG_AF(SOA_AF_IP4_ONLY)), - TAG_IF(strchr(profile->sipip, ':'), - SOATAG_AF(SOA_AF_IP6_ONLY)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), - NUTAG_SIPS_URL(profile->tls_bindurl)), - TAG_IF(profile->ws_bindurl, - NUTAG_WS_URL(profile->ws_bindurl)), - TAG_IF(profile->wss_bindurl, - NUTAG_WSS_URL(profile->wss_bindurl)), - TAG_IF(profile->tls_cert_dir, - NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_passphrase, - TPTAG_TLS_PASSPHRASE(profile->tls_passphrase)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), - TPTAG_TLS_VERIFY_POLICY(profile->tls_verify_policy)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), - TPTAG_TLS_VERIFY_DEPTH(profile->tls_verify_depth)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), - TPTAG_TLS_VERIFY_DATE(profile->tls_verify_date)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_verify_in_subjects, - TPTAG_TLS_VERIFY_SUBJECTS(profile->tls_verify_in_subjects)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), - TPTAG_TLS_CIPHERS(profile->tls_ciphers)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), - TPTAG_TLS_VERSION(profile->tls_version)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_timeout, - TPTAG_TLS_TIMEOUT(profile->tls_timeout)), - TAG_IF(!strchr(profile->sipip, ':'), - NTATAG_UDP_MTU(65535)), - TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV), - NTATAG_USE_SRV(0)), - TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_NAPTR), - NTATAG_USE_NAPTR(0)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PINGPONG), - TPTAG_PINGPONG(profile->tcp_pingpong)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PING2PONG), - TPTAG_PINGPONG(profile->tcp_ping2pong)), - TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV503), - NTATAG_SRV_503(0)), - TAG_IF(sofia_test_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE), - TPTAG_SOCKET_KEEPALIVE(profile->socket_tcp_keepalive)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_KEEPALIVE), - TPTAG_KEEPALIVE(profile->tcp_keepalive)), - NTATAG_DEFAULT_PROXY(profile->outbound_proxy), - NTATAG_SERVER_RPORT(profile->server_rport_level), - NTATAG_CLIENT_RPORT(profile->client_rport_level), - TPTAG_LOG(sofia_test_flag(profile, TFLAG_TPORT_LOG)), - TPTAG_CAPT(sofia_test_flag(profile, TFLAG_CAPTURE) ? mod_sofia_globals.capture_server : NULL), - TAG_IF(sofia_test_pflag(profile, PFLAG_SIPCOMPACT), - NTATAG_SIPFLAGS(MSG_DO_COMPACT)), - TAG_IF(profile->timer_t1, NTATAG_SIP_T1(profile->timer_t1)), - TAG_IF(profile->timer_t1x64, NTATAG_SIP_T1X64(profile->timer_t1x64)), - TAG_IF(profile->timer_t2, NTATAG_SIP_T2(profile->timer_t2)), - TAG_IF(profile->timer_t4, NTATAG_SIP_T4(profile->timer_t4)), - SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed"), - TAG_IF(sofia_test_pflag(profile, PFLAG_NO_CONNECTION_REUSE), - TPTAG_REUSE(0)), - TAG_END()); /* Last tag should always finish the sequence */ + do { + profile->nua = nua_create(profile->s_root, /* Event loop */ + sofia_event_callback, /* Callback for processing events */ + profile, /* Additional data to pass to callback */ + TAG_IF( ! sofia_test_pflag(profile, PFLAG_TLS) || ! profile->tls_only, NUTAG_URL(profile->bindurl)), + NTATAG_USER_VIA(1), + TPTAG_PONG2PING(1), + NUTAG_RETRY_AFTER_ENABLE(0), + TAG_IF(!strchr(profile->sipip, ':'), + SOATAG_AF(SOA_AF_IP4_ONLY)), + TAG_IF(strchr(profile->sipip, ':'), + SOATAG_AF(SOA_AF_IP6_ONLY)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), + NUTAG_SIPS_URL(profile->tls_bindurl)), + TAG_IF(profile->ws_bindurl, + NUTAG_WS_URL(profile->ws_bindurl)), + TAG_IF(profile->wss_bindurl, + NUTAG_WSS_URL(profile->wss_bindurl)), + TAG_IF(profile->tls_cert_dir, + NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_passphrase, + TPTAG_TLS_PASSPHRASE(profile->tls_passphrase)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), + TPTAG_TLS_VERIFY_POLICY(profile->tls_verify_policy)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), + TPTAG_TLS_VERIFY_DEPTH(profile->tls_verify_depth)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), + TPTAG_TLS_VERIFY_DATE(profile->tls_verify_date)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_verify_in_subjects, + TPTAG_TLS_VERIFY_SUBJECTS(profile->tls_verify_in_subjects)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), + TPTAG_TLS_CIPHERS(profile->tls_ciphers)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), + TPTAG_TLS_VERSION(profile->tls_version)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_timeout, + TPTAG_TLS_TIMEOUT(profile->tls_timeout)), + TAG_IF(!strchr(profile->sipip, ':'), + NTATAG_UDP_MTU(65535)), + TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV), + NTATAG_USE_SRV(0)), + TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_NAPTR), + NTATAG_USE_NAPTR(0)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PINGPONG), + TPTAG_PINGPONG(profile->tcp_pingpong)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_PING2PONG), + TPTAG_PINGPONG(profile->tcp_ping2pong)), + TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV503), + NTATAG_SRV_503(0)), + TAG_IF(sofia_test_pflag(profile, PFLAG_SOCKET_TCP_KEEPALIVE), + TPTAG_SOCKET_KEEPALIVE(profile->socket_tcp_keepalive)), + TAG_IF(sofia_test_pflag(profile, PFLAG_TCP_KEEPALIVE), + TPTAG_KEEPALIVE(profile->tcp_keepalive)), + NTATAG_DEFAULT_PROXY(profile->outbound_proxy), + NTATAG_SERVER_RPORT(profile->server_rport_level), + NTATAG_CLIENT_RPORT(profile->client_rport_level), + TPTAG_LOG(sofia_test_flag(profile, TFLAG_TPORT_LOG)), + TPTAG_CAPT(sofia_test_flag(profile, TFLAG_CAPTURE) ? mod_sofia_globals.capture_server : NULL), + TAG_IF(sofia_test_pflag(profile, PFLAG_SIPCOMPACT), + NTATAG_SIPFLAGS(MSG_DO_COMPACT)), + TAG_IF(profile->timer_t1, NTATAG_SIP_T1(profile->timer_t1)), + TAG_IF(profile->timer_t1x64, NTATAG_SIP_T1X64(profile->timer_t1x64)), + TAG_IF(profile->timer_t2, NTATAG_SIP_T2(profile->timer_t2)), + TAG_IF(profile->timer_t4, NTATAG_SIP_T4(profile->timer_t4)), + SIPTAG_ACCEPT_STR("application/sdp, multipart/mixed"), + TAG_IF(sofia_test_pflag(profile, PFLAG_NO_CONNECTION_REUSE), + TPTAG_REUSE(0)), + TAG_END()); /* Last tag should always finish the sequence */ + + if (!profile->nua) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s) ATTEMPT %d (RETRY IN %d SEC)\n", + profile->name, profile->bindurl, attempts + 1, profile->bind_attempt_interval); + if (attempts < profile->bind_attempts) { + switch_yield(1000000 * profile->bind_attempt_interval); + } + } + + } while (!profile->nua && attempts++ < profile->bind_attempts); if (!profile->nua) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s (%s)\n" @@ -4000,7 +4011,8 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->te = 101; profile->ireg_seconds = IREG_SECONDS; profile->paid_type = PAID_DEFAULT; - + profile->bind_attempts = 2; + profile->bind_attempt_interval = 5; profile->tls_verify_policy = TPTLS_VERIFY_NONE; /* lib default */ @@ -4044,6 +4056,18 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->keepalive = KA_MESSAGE; } } + } else if (!strcasecmp(var, "bind-attempts") && val) { + int ba = atoi(val) - 1; + + if (ba >= 0) { + profile->bind_attempts = ba; + } + } else if (!strcasecmp(var, "bind-attempt-interval") && val) { + int bai = atoi(val); + + if (bai >= 0) { + profile->bind_attempt_interval = bai; + } } else if (!strcasecmp(var, "shutdown-on-fail")) { profile->shutdown_type = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "sip-trace") && switch_true(val)) { @@ -5461,14 +5485,12 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status caller_profile->network_addr = switch_core_strdup(caller_profile->pool, network_ip); } - tech_pvt->mparams.last_sdp_str = NULL; + tech_pvt->mparams.last_sdp_response = NULL; if (sip->sip_payload && sip->sip_payload->pl_data) { switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE); - - tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); + tech_pvt->mparams.last_sdp_response = switch_core_session_strdup(session, sip->sip_payload->pl_data); } - if (status > 299 && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ)) { switch_channel_set_private(channel, "t38_options", NULL); switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38); @@ -6150,8 +6172,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } - if (tech_pvt && (status > 100 || switch_channel_test_flag(channel, CF_ANSWERED)) && status < 300 && !r_sdp && tech_pvt->mparams.last_sdp_str) { - r_sdp = tech_pvt->mparams.last_sdp_str; + if (tech_pvt) { + if ((status > 100 || switch_channel_test_flag(channel, CF_ANSWERED)) && status < 300 && !r_sdp && tech_pvt->mparams.last_sdp_str) { + r_sdp = tech_pvt->mparams.last_sdp_str; + } + tech_pvt->mparams.last_sdp_str = NULL; } if ((channel && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) || diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 83942c2806..50ee7d36c0 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -704,7 +704,7 @@ static void do_normal_probe(switch_event_t *event) *probe_host++ = '\0'; } probe_euser = probe_user; - if ((p = strchr(probe_euser, '+'))) { + if ((p = strchr(probe_euser, '+')) && p != probe_euser) { probe_euser = (p + 1); } @@ -841,7 +841,7 @@ static void do_dialog_probe(switch_event_t *event) *probe_host++ = '\0'; } probe_euser = probe_user; - if ((p = strchr(probe_euser, '+'))) { + if ((p = strchr(probe_euser, '+')) && p != probe_euser) { probe_euser = (p + 1); } @@ -1266,7 +1266,7 @@ static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event switch_safe_free(user); goto done; } - if ((euser = strchr(user, '+'))) { + if ((euser = strchr(user, '+')) && euser != user) { euser++; } else { euser = user; @@ -3650,6 +3650,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, char to_tag[13] = ""; char buf[80] = ""; char *orig_to_user = NULL; + char *p; if (!sip) { return; @@ -3812,7 +3813,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, orig_to_user = su_strdup(nua_handle_home(nh), to_user); - if (to_user && strchr(to_user, '+')) { + if (to_user && (p = strchr(to_user, '+')) && p != to_user) { char *h; if ((proto = (d_user = strdup(to_user)))) { if ((my_to_user = strchr(d_user, '+'))) { @@ -4809,7 +4810,7 @@ void sofia_presence_handle_sip_i_message(int status, full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from); - if ((p = strchr(to_user, '+'))) { + if ((p = strchr(to_user, '+')) && p != to_user) { switch_copy_string(proto, to_user, sizeof(proto)); p = strchr(proto, '+'); *p++ = '\0'; diff --git a/src/mod/languages/mod_perl/Makefile.am b/src/mod/languages/mod_perl/Makefile.am index 5f42ea5444..6a8f56a9fd 100644 --- a/src/mod/languages/mod_perl/Makefile.am +++ b/src/mod/languages/mod_perl/Makefile.am @@ -3,13 +3,14 @@ MODNAME=mod_perl PERL = perl PERL_LIBDIR =-L`perl -MConfig -e 'print $$Config{archlib}'`/CORE PERL_LIBS =`perl -MConfig -e 'print $$Config{libs}'` +CFLAGS_FILTER := -ansi -pedantic perldir=$(prefix)/perl mod_LTLIBRARIES = mod_perl.la perl_LTLIBRARIES = freeswitch.la mod_perl_la_SOURCES = mod_perl.c freeswitch_perl.cpp mod_perl_wrap.cpp perlxsi.c -mod_perl_la_CFLAGS = $(AM_CFLAGS) -w -mod_perl_la_CXXFLAGS = $(AM_CXXFLAGS) -w +mod_perl_la_CFLAGS = $(filter-out $(CFLAGS_FILTER),$(AM_CFLAGS)) -w +mod_perl_la_CXXFLAGS = $(filter-out $(CFLAGS_FILTER),$(AM_CXXFLAGS)) -w mod_perl_la_CPPFLAGS = -DMULTIPLICITY `$(PERL) -MExtUtils::Embed -e ccopts` -DEMBED_PERL -I$(switch_srcdir)/libs/libteletone/src/ mod_perl_la_LIBADD = $(switch_builddir)/libfreeswitch.la mod_perl_la_LDFLAGS = -avoid-version -module -no-undefined -shared `$(PERL) -MExtUtils::Embed -e ldopts` `$(PERL) -MConfig -e 'print $$Config{libs}'` diff --git a/src/switch_channel.c b/src/switch_channel.c index 7220cb8ac6..df391b9336 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -243,7 +243,7 @@ static struct switch_callstate_table CALLSTATE_CHART[] = { {"HELD", CCS_HELD}, {"RING_WAIT", CCS_RING_WAIT}, {"HANGUP", CCS_HANGUP}, - {"UNHOLD", CCS_UNHOLD}, + {"UNHELD", CCS_UNHELD}, {NULL, 0} }; @@ -257,6 +257,7 @@ static struct switch_device_state_table DEVICE_STATE_CHART[] = { {"ACTIVE", SDS_ACTIVE}, {"ACTIVE_MULTI", SDS_ACTIVE_MULTI}, {"HELD", SDS_HELD}, + {"UNHELD", SDS_UNHELD}, {"HANGUP", SDS_HANGUP}, {NULL, 0} }; @@ -268,7 +269,7 @@ SWITCH_DECLARE(void) switch_channel_perform_set_callstate(switch_channel_t *chan switch_event_t *event; switch_channel_callstate_t o_callstate = channel->callstate; - if (o_callstate == callstate) return; + if (o_callstate == callstate || o_callstate == CCS_HANGUP) return; channel->callstate = callstate; if (channel->device_node) { @@ -278,9 +279,7 @@ SWITCH_DECLARE(void) switch_channel_perform_set_callstate(switch_channel_t *chan "(%s) Callstate Change %s -> %s\n", channel->name, switch_channel_callstate2str(o_callstate), switch_channel_callstate2str(callstate)); - if (callstate != CCS_HANGUP) { - switch_channel_check_device_state(channel, channel->callstate); - } + switch_channel_check_device_state(channel, channel->callstate); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_CALLSTATE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Original-Channel-Call-State", switch_channel_callstate2str(o_callstate)); @@ -1959,7 +1958,7 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch } if (ACTIVE) { - switch_channel_set_callstate(channel, CCS_UNHOLD); + switch_channel_set_callstate(channel, CCS_UNHELD); switch_mutex_lock(channel->profile_mutex); if (channel->caller_profile->times->last_hold) { channel->caller_profile->times->hold_accum += (switch_time_now() - channel->caller_profile->times->last_hold); @@ -1969,8 +1968,11 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch channel->hold_record->off = switch_time_now(); } + if (switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_BRIDGED)) { + switch_channel_set_callstate(channel, CCS_ACTIVE); + } + switch_mutex_unlock(channel->profile_mutex); - switch_channel_set_callstate(channel, CCS_ACTIVE); } if (flag == CF_ORIGINATOR && switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_up_nosig(channel)) { @@ -4722,6 +4724,13 @@ static void fetch_device_stats(switch_device_record_t *drec) } else { drec->stats.held_out++; } + } else if (np->callstate == CCS_UNHELD) { + drec->stats.unheld++; + if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) { + drec->stats.unheld_in++; + } else { + drec->stats.unheld_out++; + } } else { if (np->callstate == CCS_EARLY) { drec->stats.early++; @@ -4906,23 +4915,27 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ fetch_device_stats(drec); - if (drec->stats.offhook == 0) { - drec->state = SDS_HANGUP; - } else { - if (drec->stats.active == 0) { - if ((drec->stats.ringing_out + drec->stats.early_out) > 0 || drec->stats.ring_wait > 0) { - drec->state = SDS_RINGING; - } else { - if (drec->stats.held > 0) { - drec->state = SDS_HELD; - } else { - drec->state = SDS_DOWN; - } - } - } else if (drec->stats.active == 1) { - drec->state = SDS_ACTIVE; + if (drec->state != SDS_HANGUP) { + if (drec->stats.offhook == 0 || drec->stats.hup == drec->stats.total) { + drec->state = SDS_HANGUP; } else { - drec->state = SDS_ACTIVE_MULTI; + if (drec->stats.active == 0) { + if ((drec->stats.ringing_out + drec->stats.early_out) > 0 || drec->stats.ring_wait > 0) { + drec->state = SDS_RINGING; + } else { + if (drec->stats.held > 0) { + drec->state = SDS_HELD; + } else if (drec->stats.unheld > 0) { + drec->state = SDS_UNHELD; + } else { + drec->state = SDS_DOWN; + } + } + } else if (drec->stats.active == 1) { + drec->state = SDS_ACTIVE; + } else { + drec->state = SDS_ACTIVE_MULTI; + } } } @@ -4960,7 +4973,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ break; } - if (drec->active_start && drec->state != SDS_ACTIVE && drec->state != SDS_ACTIVE_MULTI) { + if (callstate != CCS_UNHELD && drec->active_start && drec->state != SDS_ACTIVE && drec->state != SDS_ACTIVE_MULTI) { drec->active_stop = switch_micro_time_now(); } @@ -4984,6 +4997,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Early", "%u", drec->stats.early); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Active", "%u", drec->stats.active); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Held", "%u", drec->stats.held); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-UnHeld", "%u", drec->stats.unheld); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Legs-Hup", "%u", drec->stats.hup); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Device-Talk-Time-Start-Uepoch", "%"SWITCH_TIME_T_FMT, drec->active_start); if (drec->active_stop) { @@ -4994,7 +5008,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s device: %s\nState: %s Dev State: %s/%s Total:%u Offhook:%u " - "Ringing:%u Early:%u Active:%u Held:%u Hungup:%u Dur: %u Ringtime: %u Holdtime: %u %s\n", + "Ringing:%u Early:%u Active:%u Held:%u Unheld:%u Hungup:%u Dur: %u Ringtime: %u Holdtime: %u %s\n", switch_channel_get_name(channel), drec->device_id, switch_channel_callstate2str(callstate), @@ -5006,6 +5020,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ drec->stats.early, drec->stats.active, drec->stats.held, + drec->stats.unheld, drec->stats.hup, drec->active_stop ? (uint32_t)(drec->active_stop - drec->active_start) / 1000 : 0, drec->ring_stop ? (uint32_t)(drec->ring_stop - drec->ring_start) / 1000 : 0, diff --git a/src/switch_core_io.c b/src/switch_core_io.c index fcd51d5b04..eb294a6773 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -973,6 +973,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_mutex_unlock(session->read_codec->mutex); switch_mutex_unlock(session->codec_read_mutex); + + if (status == SWITCH_STATUS_SUCCESS && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { + switch_channel_set_callstate(session->channel, CCS_ACTIVE); + } + + return status; } diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index c37d66b35d..91fe8f7a3d 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -355,8 +355,11 @@ void switch_core_state_machine_init(switch_memory_pool_t *pool) #define STATE_MACRO(__STATE, __STATE_STR) do { \ midstate = state; \ - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State %s\n", switch_channel_get_name(session->channel), __STATE_STR); \ - switch_core_session_refresh_video(session);\ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State %s\n", switch_channel_get_name(session->channel), __STATE_STR); \ + if (state < CS_HANGUP && switch_channel_get_callstate(session->channel) == CCS_UNHELD) { \ + switch_channel_set_callstate(session->channel, CCS_ACTIVE); \ + } \ + switch_core_session_refresh_video(session); \ if (!driver_state_handler->on_##__STATE || (driver_state_handler->on_##__STATE(session) == SWITCH_STATUS_SUCCESS \ )) { \ while (do_extra_handlers && (application_state_handler = switch_channel_get_state_handler(session->channel, index++)) != 0) { \ diff --git a/src/switch_rtp.c b/src/switch_rtp.c index cf65d74d0d..9034bb9af7 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -54,7 +54,7 @@ #include #define FIR_COUNTDOWN 50 - +#define JITTER_LEAD_FRAMES 10 #define READ_INC(rtp_session) switch_mutex_lock(rtp_session->read_mutex); rtp_session->reading++ #define READ_DEC(rtp_session) switch_mutex_unlock(rtp_session->read_mutex); rtp_session->reading-- #define WRITE_INC(rtp_session) switch_mutex_lock(rtp_session->write_mutex); rtp_session->writing++ @@ -1695,6 +1695,8 @@ static void reset_jitter_seq(switch_rtp_t *rtp_session) rtp_session->stats.inbound.last_proc_time = 0; rtp_session->stats.inbound.last_processed_seq = 0; rtp_session->jitter_lead = 0; + rtp_session->consecutive_flaws = 0; + rtp_session->stats.inbound.last_flaw = 0; } static void check_jitter(switch_rtp_t *rtp_session) @@ -1710,7 +1712,7 @@ static void check_jitter(switch_rtp_t *rtp_session) return; } - if (++rtp_session->jitter_lead < 10 || !rtp_session->stats.inbound.last_proc_time) { + if (++rtp_session->jitter_lead < JITTER_LEAD_FRAMES || !rtp_session->stats.inbound.last_proc_time) { rtp_session->stats.inbound.last_proc_time = current_time; return; } @@ -4136,6 +4138,8 @@ SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp_t *rtp_session, switch_rtp if (flag == SWITCH_RTP_FLAG_DTMF_ON) { rtp_session->stats.inbound.last_processed_seq = 0; + } else if (flag == SWITCH_RTP_FLAG_PAUSE) { + reset_jitter_seq(rtp_session); } else if (flag == SWITCH_RTP_FLAG_NOBLOCK && rtp_session->sock_input) { switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE); } @@ -5689,9 +5693,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } - + if (!rtp_session->flags[SWITCH_RTP_FLAG_PAUSE] && !rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON] && !rtp_session->dtmf_data.in_digit_ts - && rtp_session->cng_count > (rtp_session->one_second * 2)) { + && rtp_session->cng_count > (rtp_session->one_second * 2) && rtp_session->jitter_lead > JITTER_LEAD_FRAMES) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "%s %s timeout\n", rtp_session_name(rtp_session), rtp_type(rtp_session));