From 83dea0ee45a1eed53fe6c7bcac96410229c2fe3c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 10:53:33 -0600 Subject: [PATCH 01/28] FS-3024 --- src/switch_core_sqldb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 35311c9b0f..2db2a0dd46 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1409,9 +1409,13 @@ static void core_event_handler(switch_event_t *event) } break; case SWITCH_EVENT_CHANNEL_UNBRIDGE: - new_sql() = switch_mprintf("delete from calls where (caller_uuid='%s' or callee_uuid='%q') and hostname='%q'", - switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname")); - break; + { + char *uuid = switch_event_get_header_nil(event, "caller-unique-id"); + + new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", + uuid, uuid, switch_core_get_variable("hostname")); + break; + } case SWITCH_EVENT_SHUTDOWN: new_sql() = switch_mprintf("delete from channels where hostname='%q';" "delete from interfaces where hostname='%q';" From 89c5f3bf8226bf605336b66e7761fd9f753d935a Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 2 Feb 2011 11:04:39 -0600 Subject: [PATCH 02/28] FS-3023 --- src/include/switch_cpp.h | 4 ++++ .../languages/mod_managed/freeswitch_wrap.cxx | 24 +++++++++++++++++++ src/mod/languages/mod_managed/managed/swig.cs | 8 +++++++ src/switch_cpp.cpp | 7 ++++++ 4 files changed, 43 insertions(+) diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index 0bd2a8b2b0..f4a0922e58 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -68,6 +68,10 @@ Note that the first parameter to the new operator is implicitly handled by c++.. SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg); SWITCH_DECLARE(void) consoleCleanLog(char *msg); +SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *body = NULL, + char *file = NULL, char *convert_cmd = NULL, char *convert_ext = NULL); + + class CoreSession; class IVRMenu { diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index e91de6df46..71e9f99819 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -33352,6 +33352,30 @@ SWIGEXPORT void SWIGSTDCALL CSharp_consoleCleanLog(char * jarg1) { } +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_email(char * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7) { + unsigned int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) NULL ; + char *arg4 = (char *) NULL ; + char *arg5 = (char *) NULL ; + char *arg6 = (char *) NULL ; + char *arg7 = (char *) NULL ; + bool result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + result = (bool)email(arg1,arg2,arg3,arg4,arg5,arg6,arg7); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_IvrMenu(void * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, int jarg11, int jarg12, int jarg13, int jarg14, int jarg15, int jarg16) { void * jresult ; IVRMenu *arg1 = (IVRMenu *) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 1f02c3f9ee..c640199353 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -5364,6 +5364,11 @@ public class freeswitch { freeswitchPINVOKE.consoleCleanLog(msg); } + public static bool email(string to, string from, string headers, string body, string file, string convert_cmd, string convert_ext) { + bool ret = freeswitchPINVOKE.email(to, from, headers, body, file, convert_cmd, convert_ext); + return ret; + } + public static void console_log(string level_str, string msg) { freeswitchPINVOKE.console_log(level_str, msg); } @@ -13588,6 +13593,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_consoleCleanLog")] public static extern void consoleCleanLog(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_email")] + public static extern bool email(string jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_new_IvrMenu")] public static extern IntPtr new_IvrMenu(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, int jarg11, int jarg12, int jarg13, int jarg14, int jarg15, int jarg16); diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index bbcd05d21c..c62946b760 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -1195,6 +1195,13 @@ SWITCH_DECLARE(void) console_clean_log(char *msg) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_DEBUG, "%s", switch_str_nil(msg)); } +SWITCH_DECLARE(bool) email(char *to, char *from, char *headers, char *body, char *file, char *convert_cmd, char *convert_ext) +{ + if (switch_simple_email(to, from, headers, body, file, convert_cmd, convert_ext) == SWITCH_TRUE) { + return true; + } + return false; +} SWITCH_DECLARE(void) msleep(unsigned ms) { From 4ae8282e6c6df0e296113e9b4b4a1383e1af8ad7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 15:43:26 -0600 Subject: [PATCH 03/28] fix possible bad pointer in global vars (please test) --- src/include/private/switch_core_pvt.h | 1 + src/include/switch_core.h | 3 + src/include/switch_nat.h | 2 +- .../applications/mod_commands/mod_commands.c | 29 +++++++--- .../applications/mod_dptools/mod_dptools.c | 17 +++--- src/mod/applications/mod_redis/mod_redis.c | 10 ++-- .../mod_voicemail/mod_voicemail.c | 6 +- .../mod_dialplan_asterisk.c | 2 +- .../endpoints/mod_dingaling/mod_dingaling.c | 4 +- src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp | 3 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 +- src/mod/endpoints/mod_sofia/sofia.c | 11 ++-- .../mod_event_socket/mod_event_socket.c | 4 +- .../formats/mod_file_string/mod_file_string.c | 2 +- .../mod_spidermonkey/mod_spidermonkey.c | 3 +- src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c | 6 +- src/switch_channel.c | 11 ++-- src/switch_console.c | 32 +++++------ src/switch_core.c | 47 ++++++++++++++-- src/switch_core_file.c | 2 +- src/switch_core_sqldb.c | 56 +++++++++---------- src/switch_event.c | 6 +- src/switch_nat.c | 7 +++ src/switch_rtp.c | 4 +- src/switch_utils.c | 10 +++- src/switch_xml.c | 3 +- 26 files changed, 185 insertions(+), 100 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 30690b1848..05cd24d230 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -246,6 +246,7 @@ struct switch_runtime { int sql_buffer_len; int max_sql_buffer_len; switch_dbtype_t odbc_dbtype; + char hostname[256]; }; extern struct switch_runtime runtime; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 109a16901b..69b06420a3 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -759,6 +759,9 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_force_locate(_In_z_ \return the value of the desired variable */ SWITCH_DECLARE(char *) switch_core_get_variable(_In_z_ const char *varname); +SWITCH_DECLARE(char *) switch_core_get_variable_dup(_In_z_ const char *varname); +SWITCH_DECLARE(char *) switch_core_get_variable_pdup(_In_z_ const char *varname, switch_memory_pool_t *pool); +SWITCH_DECLARE(const char *) switch_core_get_hostname(void); /*! \brief Add a global variable to the core diff --git a/src/include/switch_nat.h b/src/include/switch_nat.h index bdbd51b592..9e40546345 100644 --- a/src/include/switch_nat.h +++ b/src/include/switch_nat.h @@ -49,7 +49,7 @@ typedef enum { SWITCH_NAT_TCP } switch_nat_ip_proto_t; - +SWITCH_DECLARE(const char *) switch_nat_get_type(void); /*! \brief Initilize the NAT Traversal System diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 7771b0996c..807770ac15 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -349,7 +349,7 @@ SWITCH_STANDARD_API(timer_test_function) SWITCH_STANDARD_API(group_call_function) { - char *domain; + char *domain, *dup_domain = NULL; char *group_name = NULL; char *flags; int ok = 0; @@ -392,7 +392,9 @@ SWITCH_STANDARD_API(group_call_function) if (domain) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain = dup_domain; + } } if (!zstr(domain)) { @@ -544,13 +546,14 @@ SWITCH_STANDARD_API(group_call_function) } end: - + switch_safe_free(group_name); + switch_safe_free(dup_domain); if (!ok) { stream->write_function(stream, "error/NO_ROUTE_DESTINATION"); } - + return SWITCH_STATUS_SUCCESS; } @@ -559,7 +562,7 @@ SWITCH_STANDARD_API(in_group_function) { switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group; int argc; - char *mydata = NULL, *argv[2], *user, *domain; + char *mydata = NULL, *argv[2], *user, *domain, *dup_domain = NULL; char delim = ','; switch_event_t *params = NULL; const char *rval = "false"; @@ -579,7 +582,9 @@ SWITCH_STANDARD_API(in_group_function) if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain = dup_domain; + } } switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); @@ -601,6 +606,7 @@ SWITCH_STANDARD_API(in_group_function) switch_xml_free(xml); switch_safe_free(mydata); + switch_safe_free(dup_domain); switch_event_destroy(¶ms); return SWITCH_STATUS_SUCCESS; @@ -610,7 +616,7 @@ SWITCH_STANDARD_API(user_data_function) { switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params; int argc; - char *mydata = NULL, *argv[3], *key = NULL, *type = NULL, *user, *domain; + char *mydata = NULL, *argv[3], *key = NULL, *type = NULL, *user, *domain, *dup_domain = NULL; char delim = ' '; const char *container = "params", *elem = "param"; const char *result = NULL; @@ -631,7 +637,9 @@ SWITCH_STANDARD_API(user_data_function) if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - if (!(domain = switch_core_get_variable("domain"))) { + if ((dup_domain = switch_core_get_variable("domain"))) { + domain = dup_domain; + } else { domain = "cluecon.com"; } } @@ -694,6 +702,7 @@ SWITCH_STANDARD_API(user_data_function) } switch_xml_free(xml); switch_safe_free(mydata); + switch_safe_free(dup_domain); switch_event_destroy(¶ms); return SWITCH_STATUS_SUCCESS; @@ -4375,7 +4384,9 @@ SWITCH_STANDARD_API(global_getvar_function) if (zstr(cmd)) { switch_core_dump_variables(stream); } else { - stream->write_function(stream, "%s", switch_str_nil(switch_core_get_variable(cmd))); + char *var = switch_core_get_variable_dup(cmd); + stream->write_function(stream, "%s", switch_str_nil(var)); + switch_safe_free(var); } return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 928a9b8549..4be2a64f61 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2787,7 +2787,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session if ((domain = strchr(group, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); } if (!domain) { @@ -2908,7 +2908,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable("domain"); + domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); } if (!domain) { @@ -3193,10 +3193,11 @@ static switch_status_t event_chat_send(const char *proto, const char *from, cons if (body) switch_event_add_body(event, "%s", body); if (to) { - const char *v; + char *v; switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "To", to); - if ((v = switch_core_get_variable(to))) { + if ((v = switch_core_get_variable_dup(to))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Command", v); + free(v); } } @@ -3214,15 +3215,15 @@ static switch_status_t api_chat_send(const char *proto, const char *from, const const char *body, const char *type, const char *hint) { if (to) { - const char *v; + char *v = NULL; switch_stream_handle_t stream = { 0 }; char *cmd = NULL, *arg; - if (!(v = switch_core_get_variable(to))) { - v = to; + if (!(v = switch_core_get_variable_dup(to))) { + v = strdup(to); } - cmd = strdup(v); + cmd = v; switch_assert(cmd); switch_url_decode(cmd); diff --git a/src/mod/applications/mod_redis/mod_redis.c b/src/mod/applications/mod_redis/mod_redis.c index 1e999675b1..ebf2a9e324 100755 --- a/src/mod/applications/mod_redis/mod_redis.c +++ b/src/mod/applications/mod_redis/mod_redis.c @@ -89,7 +89,7 @@ SWITCH_LIMIT_INCR(limit_incr_redis) } /* Get the keys for redis server */ - uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_variable("hostname"), realm, resource); + uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_hostname(), realm, resource); rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource); if ((pvt = switch_channel_get_private(channel, "limit_redis"))) { @@ -179,7 +179,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", (char *)p_key); switch_goto_status(SWITCH_STATUS_FALSE, end); } - p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_variable("hostname"), (char *)p_key); + p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_hostname(), (char *)p_key); if (credis_decr(redis,p_uuid_key,&uuid_val) != 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", p_uuid_key); switch_goto_status(SWITCH_STATUS_FALSE, end); @@ -193,7 +193,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis) } else { rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource); - uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_variable("hostname"), realm, resource); + uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_hostname(), realm, resource); switch_core_hash_delete(pvt->hash, (const char *) rediskey); if (credis_decr(redis, rediskey, &val) != 0) { @@ -249,13 +249,13 @@ SWITCH_LIMIT_RESET(limit_reset_redis) { REDIS redis; if (redis_factory(&redis) == SWITCH_STATUS_SUCCESS) { - char *rediskey = switch_mprintf("%s_*", switch_core_get_variable("hostname")); + char *rediskey = switch_mprintf("%s_*", switch_core_get_hostname()); int dec = 0, val = 0, keyc; char *uuids[2000]; if ((keyc = credis_keys(redis, rediskey, uuids, switch_arraylen(uuids))) > 0) { int i = 0; - int hostnamelen = strlen(switch_core_get_variable("hostname"))+1; + int hostnamelen = strlen(switch_core_get_hostname())+1; for (i = 0; i < keyc && uuids[i]; i++){ const char *key = uuids[i] + hostnamelen; diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 76870f75b9..80b011e189 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -2734,6 +2734,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t switch_memory_pool_t *pool = NULL; char *forwarded_by = NULL; char *read_flags = NORMAL_FLAG_STRING; + char *dup_domain = NULL; if (zstr(data)) { status = SWITCH_STATUS_FALSE; @@ -2781,7 +2782,9 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t } if (zstr(domain)) { - domain = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain = dup_domain; + } profile_name = domain; } @@ -2915,6 +2918,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t end: switch_safe_free(dup); + switch_safe_free(dup_domain); return status; } diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index 5869d14c3a..43534dadba 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -313,7 +313,7 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, if (session) { profile = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_profile"); } else { - profile = switch_core_get_variable("sip_profile"); + profile = switch_core_get_variable_pdup("sip_profile", switch_core_session_get_pool(session)); } if (zstr(profile)) { profile = "default"; diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 66f62b2295..9fb1f39e11 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -2049,7 +2049,7 @@ static void set_profile_val(mdl_profile_t *profile, char *var, char *val) } else if (!strcasecmp(var, "ext-rtp-ip")) { char *ip = globals.guess_ip; if (val && !strcasecmp(val, "auto-nat")) { - ip = globals.auto_nat ? switch_core_get_variable("nat_public_addr") : globals.guess_ip; + ip = globals.auto_nat ? switch_core_get_variable_pdup("nat_public_addr", module_pool) : globals.guess_ip; } else if (val && !strcasecmp(val, "auto")) { globals.auto_nat = 0; ip = globals.guess_ip; @@ -2523,7 +2523,7 @@ static switch_status_t load_config(void) memset(&globals, 0, sizeof(globals)); globals.running = 1; - globals.auto_nat = (switch_core_get_variable("nat_type") ? 1 : 0); + globals.auto_nat = (switch_nat_get_type() ? 1 : 0); switch_find_local_ip(globals.guess_ip, sizeof(globals.guess_ip), NULL, AF_INET); diff --git a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp index 1b126eb277..15009f2286 100644 --- a/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp +++ b/src/mod/endpoints/mod_khomp/src/khomp_pvt.cpp @@ -1625,9 +1625,10 @@ bool Board::KhompPvt::setCollectCall() DBG(FUNC, PVT_FMT(_target, "option drop collect call is '%s'") % (Opt::_options._drop_collect_call() ? "yes" : "no")); // get global filter configuration value - tmp_var = switch_core_get_variable("KDropCollectCall"); + tmp_var = switch_core_get_variable_dup("KDropCollectCall"); confvalues.push_back(getTriStateValue(tmp_var)); DBG(FUNC, PVT_FMT(_target, "global KDropCollectCall was '%s'") % (tmp_var ? tmp_var : "(empty)")); + switch_safe_free(tmp_var); try { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 8bceb3bba5..c78aac7933 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -3501,7 +3501,7 @@ SWITCH_STANDARD_API(sofia_contact_function) } if (zstr(domain)) { - domain = switch_core_get_variable("domain"); + domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); } if (!user) goto end; @@ -4776,7 +4776,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) mod_sofia_globals.running = 1; switch_mutex_unlock(mod_sofia_globals.mutex); - mod_sofia_globals.auto_nat = (switch_core_get_variable("nat_type") ? 1 : 0); + mod_sofia_globals.auto_nat = (switch_nat_get_type() ? 1 : 0); switch_queue_create(&mod_sofia_globals.presence_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool); switch_queue_create(&mod_sofia_globals.mwi_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 47f94b151a..825d1bf46e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1459,7 +1459,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void supported = switch_core_sprintf(profile->pool, "%s%sprecondition, path, replaces", use_100rel ? "100rel, " : "", use_timer ? "timer, " : ""); - if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_core_get_variable("nat_type")) { + if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_nat_get_type()) { if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_UDP, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created UDP nat mapping for %s port %d\n", profile->name, profile->sip_port); } @@ -1676,7 +1676,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_event_fire(&s_event); } - if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_core_get_variable("nat_type")) { + if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && switch_nat_get_type()) { if (switch_nat_del_mapping(profile->sip_port, SWITCH_NAT_UDP) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleted UDP nat mapping for %s port %d\n", profile->name, profile->sip_port); } @@ -3741,9 +3741,9 @@ switch_status_t config_sofia(int reload, char *profile_name) if (!profile->rtpip[0]) { profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip); } - - if (switch_core_get_variable("nat_type")) { - const char *ip = switch_core_get_variable("nat_public_addr"); + + if (switch_nat_get_type()) { + char *ip = switch_core_get_variable_dup("nat_public_addr"); if (ip && !strchr(profile->sipip, ':')) { if (!profile->extrtpip) { profile->extrtpip = switch_core_strdup(profile->pool, ip); @@ -3754,6 +3754,7 @@ switch_status_t config_sofia(int reload, char *profile_name) sofia_set_pflag(profile, PFLAG_AUTO_NAT); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "NAT detected setting external ip to %s\n", ip); } + switch_safe_free(ip); } if (profile->nonce_ttl < 60) { diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index f3a2c92eb3..1462e4ec54 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -2642,7 +2642,7 @@ static int config(void) } else if (!strcmp(var, "debug")) { globals.debug = atoi(val); } else if (!strcmp(var, "nat-map")) { - if (switch_true(val) && switch_core_get_variable("nat_type")) { + if (switch_true(val) && switch_nat_get_type()) { prefs.nat_map = 1; } } else if (!strcmp(var, "listen-port")) { @@ -2795,7 +2795,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime) close_socket(&listen_list.sock); - if (prefs.nat_map && switch_core_get_variable("nat_type")) { + if (prefs.nat_map && switch_nat_get_type()) { switch_nat_del_mapping(prefs.port, SWITCH_NAT_TCP); } diff --git a/src/mod/formats/mod_file_string/mod_file_string.c b/src/mod/formats/mod_file_string/mod_file_string.c index ca86cbdfcf..7e36c720aa 100644 --- a/src/mod/formats/mod_file_string/mod_file_string.c +++ b/src/mod/formats/mod_file_string/mod_file_string.c @@ -77,7 +77,7 @@ static int next_file(switch_file_handle_t *handle) if (!prefix) { - if (!(prefix = switch_core_get_variable("sound_prefix"))) { + if (!(prefix = switch_core_get_variable_pdup("sound_prefix", handle->memory_pool))) { prefix = SWITCH_GLOBAL_dirs.sounds_dir; } } diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 9eb2636f4a..1d6ee8d679 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -3378,8 +3378,9 @@ static JSBool js_global_get(JSContext * cx, JSObject * obj, uintN argc, jsval * if (argc > 0) { var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); - val = switch_core_get_variable(var_name); + val = switch_core_get_variable_dup(var_name); *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, val)); + free(val); return JS_TRUE; } diff --git a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c index 468190d887..9e61312417 100644 --- a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c +++ b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c @@ -322,6 +322,7 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name) int at = 0; char *dp; abyss_bool rval = FALSE; + char *dup_domain = NULL; p = RequestHeaderValue(r, "authorization"); @@ -354,7 +355,9 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name) if (globals.default_domain) { domain_name = globals.default_domain; } else { - domain_name = switch_core_get_variable("domain"); + if ((dup_domain = switch_core_get_variable_dup("domain"))) { + domain_name = dup_domain; + } } } } @@ -465,6 +468,7 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name) switch_safe_free(mypass1); switch_safe_free(mypass2); switch_safe_free(box); + switch_safe_free(dup_domain); return rval; } diff --git a/src/switch_channel.c b/src/switch_channel.c index 70b1879274..f750496323 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -672,7 +672,7 @@ SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channe SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup) { - const char *v = NULL, *r = NULL; + const char *v = NULL, *r = NULL, *vdup = NULL; switch_assert(channel != NULL); switch_mutex_lock(channel->profile_mutex); @@ -690,13 +690,16 @@ SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *c } if (!cp || !(v = switch_caller_get_field_by_name(cp, varname))) { - v = switch_core_get_variable(varname); + if ((vdup = switch_core_get_variable_pdup(varname, switch_core_session_get_pool(channel->session)))) { + v = vdup; + } } } - if (dup) { - if (v) + if (dup && v != vdup) { + if (v) { r = switch_core_session_strdup(channel->session, v); + } } else { r = v; } diff --git a/src/switch_console.c b/src/switch_console.c index 41bbb91ad0..c5d601b9a2 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -643,9 +643,9 @@ SWITCH_DECLARE_NONSTD(switch_status_t) switch_console_list_uuid(const char *line if (!zstr(cursor)) { sql = switch_mprintf("select distinct uuid from channels where uuid like '%q%%' and hostname='%q' order by uuid", - cursor, switch_core_get_variable("hostname")); + cursor, switch_core_get_hostname()); } else { - sql = switch_mprintf("select distinct uuid from channels where hostname='%q' order by uuid", switch_core_get_variable("hostname")); + sql = switch_mprintf("select distinct uuid from channels where hostname='%q' order by uuid", switch_core_get_hostname()); } switch_cache_db_execute_sql_callback(db, sql, uuid_callback, &h, &errmsg); @@ -764,7 +764,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch if (h.words == 0) { sql = switch_mprintf("select distinct name from interfaces where type='api' and name like '%q%%' and hostname='%q' order by name", - buf, switch_core_get_variable("hostname")); + buf, switch_core_get_hostname()); } if (sql) { @@ -792,7 +792,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch if (h.words == 0) { stream.write_function(&stream, "select distinct a1 from complete where " "a1 not in (select name from interfaces where hostname='%s') %s ", - switch_core_get_variable("hostname"), argc ? "and" : ""); + switch_core_get_hostname(), argc ? "and" : ""); } else { if (db->type == SCDB_TYPE_CORE_DB) { stream.write_function(&stream, "select distinct a%d,'%q','%q' from complete where ", h.words + 1, switch_str_nil(dup), switch_str_nil(lp)); @@ -821,7 +821,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch } } - stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_variable("hostname"), h.words + 1); + stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_hostname(), h.words + 1); switch_cache_db_execute_sql_callback(db, stream.data, comp_callback, &h, &errmsg); @@ -1794,7 +1794,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } } } - mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname")); + mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, mystream.data, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add")) { @@ -1810,7 +1810,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) } } } - mystream.write_function(&mystream, " '%s')", switch_core_get_variable("hostname")); + mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, mystream.data, 5); status = SWITCH_STATUS_SUCCESS; @@ -1827,7 +1827,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string) mystream.write_function(&mystream, "a%d = '%w'%w", x + 1, switch_str_nil(argv[x + 1]), x == argc - 2 ? "" : " and "); } } - mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_variable("hostname")); + mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, mystream.data, 1); } status = SWITCH_STATUS_SUCCESS; @@ -1863,38 +1863,38 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string) } if (!strcasecmp(argv[0], "stickyadd") && argc == 3) { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 5); switch_safe_free(sql); if (db->type == SCDB_TYPE_CORE_DB) { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } else { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%w','%w','%w')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } switch_cache_db_persistant_execute(db, sql, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "add") && argc == 3) { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 5); switch_safe_free(sql); if (db->type == SCDB_TYPE_CORE_DB) { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q','%q')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } else { sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%w','%w','%w')", - argv[1], argv[2], switch_core_get_variable("hostname")); + argv[1], argv[2], switch_core_get_hostname()); } switch_cache_db_persistant_execute(db, sql, 5); status = SWITCH_STATUS_SUCCESS; } else if (!strcasecmp(argv[0], "del") && argc == 2) { char *what = argv[1]; if (!strcasecmp(what, "*")) { - sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 1); } else { - sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_variable("hostname")); + sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_hostname()); switch_cache_db_persistant_execute(db, sql, 5); } status = SWITCH_STATUS_SUCCESS; diff --git a/src/switch_core.c b/src/switch_core.c index 43fb36d705..87543050b2 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -261,6 +261,11 @@ SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream) switch_mutex_unlock(runtime.global_mutex); } +SWITCH_DECLARE(const char *) switch_core_get_hostname(void) +{ + return runtime.hostname; +} + SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) { char *val; @@ -270,6 +275,32 @@ SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname) return val; } +SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname) +{ + char *val = NULL, *v; + + switch_mutex_lock(runtime.global_var_mutex); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = strdup(v); + } + switch_mutex_unlock(runtime.global_var_mutex); + + return val; +} + +SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch_memory_pool_t *pool) +{ + char *val = NULL, *v; + + switch_mutex_lock(runtime.global_var_mutex); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = switch_core_strdup(pool, v); + } + switch_mutex_unlock(runtime.global_var_mutex); + + return val; +} + static void switch_core_unset_variables(void) { switch_mutex_lock(runtime.global_var_mutex); @@ -1202,12 +1233,18 @@ static void switch_core_set_serial(void) if ((fd = open(path, O_RDONLY, 0)) < 0) { - char *ip = switch_core_get_variable("local_ip_v4"); + char *ip = switch_core_get_variable_dup("local_ip_v4"); uint32_t ipi = 0; switch_byte_t *byte; int i = 0; - switch_inet_pton(AF_INET, ip, &ipi); + if (ip) { + switch_inet_pton(AF_INET, ip, &ipi); + free(ip); + ip = NULL; + } + + byte = (switch_byte_t *) & ipi; for (i = 0; i < 8; i += 2) { @@ -1237,7 +1274,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc char guess_ip[256]; int mask = 0; struct in_addr in; - char hostname[256] = ""; + if (runtime.runlevel > 0) { /* one per customer */ @@ -1310,8 +1347,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.console = stdout; } - gethostname(hostname, sizeof(hostname)); - switch_core_set_variable("hostname", hostname); + gethostname(runtime.hostname, sizeof(runtime.hostname)); + switch_core_set_variable("hostname", runtime.hostname); switch_find_local_ip(guess_ip, sizeof(guess_ip), &mask, AF_INET); switch_core_set_variable("local_ip_v4", guess_ip); diff --git a/src/switch_core_file.c b/src/switch_core_file.c index 19f23546f0..fc7d223b5b 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -102,7 +102,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, } if (!spool_path) { - spool_path = switch_core_get_variable(SWITCH_AUDIO_SPOOL_PATH_VARIABLE); + spool_path = switch_core_get_variable_pdup(SWITCH_AUDIO_SPOOL_PATH_VARIABLE, fh->memory_pool); } file_path = fh->file_path; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 2db2a0dd46..73890a1e4f 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1134,7 +1134,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("insert into tasks values(%q,'%q','%q',%q, '%q')", id, switch_event_get_header_nil(event, "task-desc"), - switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", switch_core_get_hostname() ); } } @@ -1142,7 +1142,7 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_DEL_SCHEDULE: case SWITCH_EVENT_EXE_SCHEDULE: new_sql() = switch_mprintf("delete from tasks where task_id=%q and hostname='%q'", - switch_event_get_header_nil(event, "task-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "task-id"), switch_core_get_hostname()); break; case SWITCH_EVENT_RE_SCHEDULE: { @@ -1153,7 +1153,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("update tasks set task_desc='%q',task_group='%q', task_sql_manager=%q where task_id=%q and hostname='%q'", switch_event_get_header_nil(event, "task-desc"), switch_event_get_header_nil(event, "task-group"), manager ? manager : "0", id, - switch_core_get_variable("hostname")); + switch_core_get_hostname()); } } break; @@ -1163,10 +1163,10 @@ static void core_event_handler(switch_event_t *event) if (uuid) { new_sql() = switch_mprintf("delete from channels where uuid='%q' and hostname='%q'", - uuid, switch_core_get_variable("hostname")); + uuid, switch_core_get_hostname()); new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", - uuid, uuid, switch_core_get_variable("hostname")); + uuid, uuid, switch_core_get_hostname()); } } @@ -1178,12 +1178,12 @@ static void core_event_handler(switch_event_t *event) "update calls set callee_uuid='%q' where callee_uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "old-unique-id"), - switch_core_get_variable("hostname"), + switch_core_get_hostname(), switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "old-unique-id"), - switch_core_get_variable("hostname"), + switch_core_get_hostname(), switch_event_get_header_nil(event, "unique-id"), - switch_event_get_header_nil(event, "old-unique-id"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "old-unique-id"), switch_core_get_hostname() ); break; } @@ -1198,7 +1198,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "channel-call-state"), switch_event_get_header_nil(event, "caller-dialplan"), - switch_event_get_header_nil(event, "caller-context"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "caller-context"), switch_core_get_hostname() ); break; case SWITCH_EVENT_CODEC: @@ -1211,7 +1211,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-write-codec-name"), switch_event_get_header_nil(event, "channel-write-codec-rate"), switch_event_get_header_nil(event, "channel-write-codec-bit-rate"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); break; case SWITCH_EVENT_CHANNEL_HOLD: case SWITCH_EVENT_CHANNEL_UNHOLD: @@ -1223,7 +1223,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "application-data"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname() ); } @@ -1238,7 +1238,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-data"), switch_event_get_header_nil(event, "channel-call-uuid"), extra_cols, - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set " @@ -1246,7 +1246,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), switch_event_get_header_nil(event, "channel-call-uuid"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); } } @@ -1281,7 +1281,7 @@ static void core_event_handler(switch_event_t *event) switch_str_nil(name), switch_str_nil(number), switch_event_get_header_nil(event, "direction"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); name = switch_event_get_header(event, "callee-name"); number = switch_event_get_header(event, "callee-number"); @@ -1298,7 +1298,7 @@ static void core_event_handler(switch_event_t *event) { new_sql() = switch_mprintf("update channels set callstate='%q' where uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "channel-call-state"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); } break; @@ -1330,7 +1330,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), extra_cols, - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q'," @@ -1345,13 +1345,13 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); } break; default: new_sql() = switch_mprintf("update channels set state='%s' where uuid='%s' and hostname='%q'", switch_event_get_header_nil(event, "channel-state"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); break; } @@ -1377,7 +1377,7 @@ static void core_event_handler(switch_event_t *event) new_sql() = switch_mprintf("update channels set call_uuid='%q' where uuid='%s' and hostname='%q'", switch_event_get_header_nil(event, "channel-call-uuid"), - switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "unique-id"), switch_core_get_hostname()); if (runtime.odbc_dbtype == DBTYPE_DEFAULT) { func_name = "function"; @@ -1404,7 +1404,7 @@ static void core_event_handler(switch_event_t *event) callee_cid_num, switch_event_get_header_nil(event, "Other-Leg-destination-number"), switch_event_get_header_nil(event, "Other-Leg-channel-name"), - switch_event_get_header_nil(event, "Other-Leg-unique-id"), switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "Other-Leg-unique-id"), switch_core_get_hostname() ); } break; @@ -1413,14 +1413,14 @@ static void core_event_handler(switch_event_t *event) char *uuid = switch_event_get_header_nil(event, "caller-unique-id"); new_sql() = switch_mprintf("delete from calls where (caller_uuid='%q' or callee_uuid='%q') and hostname='%q'", - uuid, uuid, switch_core_get_variable("hostname")); + uuid, uuid, switch_core_get_hostname()); break; } case SWITCH_EVENT_SHUTDOWN: new_sql() = switch_mprintf("delete from channels where hostname='%q';" "delete from interfaces where hostname='%q';" "delete from calls where hostname='%q'", - switch_core_get_variable("hostname"), switch_core_get_variable("hostname"), switch_core_get_variable("hostname") + switch_core_get_hostname(), switch_core_get_hostname(), switch_core_get_hostname() ); break; case SWITCH_EVENT_LOG: @@ -1438,7 +1438,7 @@ static void core_event_handler(switch_event_t *event) switch_mprintf ("insert into interfaces (type,name,description,syntax,ikey,filename,hostname) values('%q','%q','%q','%q','%q','%q','%q')", type, name, switch_str_nil(description), switch_str_nil(syntax), switch_str_nil(key), switch_str_nil(filename), - switch_core_get_variable("hostname") + switch_core_get_hostname() ); } break; @@ -1449,7 +1449,7 @@ static void core_event_handler(switch_event_t *event) const char *name = switch_event_get_header_nil(event, "name"); if (!zstr(type) && !zstr(name)) { new_sql() = switch_mprintf("delete from interfaces where type='%q' and name='%q' and hostname='%q'", type, name, - switch_core_get_variable("hostname")); + switch_core_get_hostname()); } break; } @@ -1461,7 +1461,7 @@ static void core_event_handler(switch_event_t *event) break; } new_sql() = switch_mprintf("update channels set secure='%s' where uuid='%s' and hostname='%q'", - type, switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_variable("hostname") + type, switch_event_get_header_nil(event, "caller-unique-id"), switch_core_get_hostname() ); break; } @@ -1472,12 +1472,12 @@ static void core_event_handler(switch_event_t *event) if (!strcmp("add", op)) { new_sql() = switch_mprintf("insert into nat (port, proto, sticky, hostname) values (%s, %s, %d,'%q')", switch_event_get_header_nil(event, "port"), - switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_variable("hostname") + switch_event_get_header_nil(event, "proto"), sticky, switch_core_get_hostname() ); } else if (!strcmp("del", op)) { new_sql() = switch_mprintf("delete from nat where port=%s and proto=%s and hostname='%q'", switch_event_get_header_nil(event, "port"), - switch_event_get_header_nil(event, "proto"), switch_core_get_variable("hostname")); + switch_event_get_header_nil(event, "proto"), switch_core_get_hostname()); } else if (!strcmp("status", op)) { /* call show nat api */ } else if (!strcmp("status_response", op)) { @@ -1664,7 +1664,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ char sql[512] = ""; char *tables[] = { "channels", "calls", "interfaces", "tasks", NULL }; int i; - const char *hostname = switch_core_get_variable("hostname"); + const char *hostname = switch_core_get_hostname(); for (i = 0; tables[i]; i++) { switch_snprintf(sql, sizeof(sql), "delete from %s where hostname='%s'", tables[i], hostname); diff --git a/src/switch_event.c b/src/switch_event.c index 003fc82296..3e12ea115f 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1673,6 +1673,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const int offset = 0; int ooffset = 0; char *ptr; + char *gvar = NULL; if ((expanded = switch_event_expand_headers(event, (char *) vname)) == vname) { expanded = NULL; @@ -1689,7 +1690,9 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } if (!(sub_val = switch_event_get_header(event, vname))) { - sub_val = switch_core_get_variable(vname); + if ((gvar = switch_core_get_variable_dup(vname))) { + sub_val = gvar; + } } if (offset || ooffset) { @@ -1710,6 +1713,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } } + switch_safe_free(gvar); switch_safe_free(expanded); } else { switch_stream_handle_t stream = { 0 }; diff --git a/src/switch_nat.c b/src/switch_nat.c index 536baeedff..85b0247d6d 100644 --- a/src/switch_nat.c +++ b/src/switch_nat.c @@ -45,6 +45,7 @@ typedef struct { switch_nat_type_t nat_type; + char nat_type_str[5]; struct UPNPUrls urls; struct IGDdatas data; char *descURL; @@ -420,6 +421,7 @@ SWITCH_DECLARE(void) switch_nat_init(switch_memory_pool_t *pool) switch_core_set_variable("nat_public_addr", nat_globals.pub_addr); switch_core_set_variable("nat_private_addr", nat_globals.pvt_addr); switch_core_set_variable("nat_type", nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp"); + strncpy(nat_globals.nat_type_str, nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp", sizeof(nat_globals.nat_type_str) - 1); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "NAT detected type: %s, ExtIP: '%s'\n", nat_globals.nat_type == SWITCH_NAT_TYPE_PMP ? "pmp" : "upnp", nat_globals.pub_addr); @@ -564,6 +566,11 @@ static switch_status_t switch_nat_del_mapping_upnp(switch_port_t port, switch_na return status; } +SWITCH_DECLARE(const char *) switch_nat_get_type(void) +{ + return nat_globals.nat_type_str; +} + SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping_internal(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t * external_port, switch_bool_t sticky, switch_bool_t publish) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4acadfe2ff..e8d7558bce 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -791,8 +791,8 @@ static void zrtp_logger(int level, const char *data, int len, int offset) SWITCH_DECLARE(void) switch_rtp_init(switch_memory_pool_t *pool) { #ifdef ENABLE_ZRTP - const char *zid_string = switch_core_get_variable("switch_serial"); - const char *zrtp_enabled = switch_core_get_variable("zrtp_enabled"); + const char *zid_string = switch_core_get_variable_pdup("switch_serial", pool); + const char *zrtp_enabled = switch_core_get_variable_pdup("zrtp_enabled", pool); zrtp_config_t zrtp_config; char zrtp_cache_path[256] = ""; zrtp_on = zrtp_enabled ? switch_true(zrtp_enabled) : 0; diff --git a/src/switch_utils.c b/src/switch_utils.c index 850b07f51d..eb5ed7f830 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1154,8 +1154,8 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma { switch_status_t status = SWITCH_STATUS_FALSE; char *base; - const char *force_local_ip_v4 = switch_core_get_variable("force_local_ip_v4"); - const char *force_local_ip_v6 = switch_core_get_variable("force_local_ip_v6"); + char *force_local_ip_v4 = switch_core_get_variable_dup("force_local_ip_v4"); + char *force_local_ip_v6 = switch_core_get_variable_dup("force_local_ip_v6"); #ifdef WIN32 SOCKET tmp_socket; @@ -1176,14 +1176,20 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int *ma case AF_INET: if (force_local_ip_v4) { switch_copy_string(buf, force_local_ip_v4, len); + switch_safe_free(force_local_ip_v4); + switch_safe_free(force_local_ip_v6); return SWITCH_STATUS_SUCCESS; } case AF_INET6: if (force_local_ip_v6) { switch_copy_string(buf, force_local_ip_v6, len); + switch_safe_free(force_local_ip_v4); + switch_safe_free(force_local_ip_v6); return SWITCH_STATUS_SUCCESS; } default: + switch_safe_free(force_local_ip_v4); + switch_safe_free(force_local_ip_v6); break; } diff --git a/src/switch_xml.c b/src/switch_xml.c index 964a7694b2..4c30d986a6 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -1208,11 +1208,12 @@ static char *expand_vars(char *buf, char *ebuf, switch_size_t elen, switch_size_ var = rp; *e++ = '\0'; rp = e; - if ((val = switch_core_get_variable(var))) { + if ((val = switch_core_get_variable_dup(var))) { char *p; for (p = val; p && *p && wp <= ep; p++) { *wp++ = *p; } + free(val); } continue; } else if (err) { From 257bf9a46c44f76d8b38c90f288f364bcf1c6398 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 16:05:51 -0600 Subject: [PATCH 04/28] fix possible bad pointer in global vars (please test) --- libs/freetdm/mod_freetdm/mod_freetdm.c | 7 +++++++ libs/openzap/mod_openzap/mod_openzap.c | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 970cb5b993..2ef21cc186 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1067,9 +1067,16 @@ static const char* channel_get_variable(switch_core_session_t *session, switch_e return variable; } } + + + // This is unsafe, I don't see anywhere in the whole code where this is called with NULL session anyway. + // There is a new switch_core_get_variable_dup that will strdup it for you and then you must free it. + // That messes up the abstraction completely so I am just commenting it out for you..... + /* if ((variable = switch_core_get_variable(variable_name))) { return variable; } + */ return NULL; } diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index d52149c657..ef346b8eea 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -1234,19 +1234,19 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi zap_set_string(caller_data.ani.digits, dest); } - if ((var = switch_event_get_header(var_event, "openzap_outbound_ton")) || (var = switch_core_get_variable("openzap_outbound_ton"))) { + if ((var = switch_event_get_header(var_event, "openzap_outbound_ton"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting TON to: %s\n", var); zap_set_ton(var, &caller_data.ani.type); } else { caller_data.ani.type = outbound_profile->destination_number_ton; } - if ((var = switch_event_get_header(var_event, "openzap_custom_call_data")) || (var = switch_core_get_variable("openzap_custom_call_data"))) { + if ((var = switch_event_get_header(var_event, "openzap_custom_call_data"))) { zap_set_string((char *)caller_data.raw_data, var); caller_data.raw_data_len = strlen(var); } - if ((var = switch_event_get_header(var_event, "openzap_outbound_npi")) || (var = switch_core_get_variable("openzap_outbound_npi"))) { + if ((var = switch_event_get_header(var_event, "openzap_outbound_npi"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting NPI to: %s\n", var); zap_set_npi(var, &caller_data.ani.plan); } else { From 85913b70b43483d4d3d840d128549ddba75b56a6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 16:05:57 -0600 Subject: [PATCH 05/28] only pass publish on when you have a subscription --- src/mod/endpoints/mod_sofia/sofia_presence.c | 62 +++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 19125c600b..a38a61eab8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2570,6 +2570,19 @@ static int sofia_counterpath_crutch(void *pArg, int argc, char **argv, char **co return 0; } + +uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *contact_str) +{ + char buf[32] = ""; + char *sql; + + sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact_str='%q'", profile->name, contact_str); + + sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); + switch_safe_free(sql); + return atoi(buf); +} + void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]) { @@ -2584,7 +2597,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n char expstr[30] = ""; long exp = 0, exp_delta = 3600; char *pd_dup = NULL; - int count = 1; + int count = 1, sub_count = 0; char *contact_str; int open = 1; @@ -2667,24 +2680,25 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n count = sofia_reg_reg_count(profile, from_user, from_host); } + sub_count = sofia_presence_contact_count(profile, contact_str); /* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */ event_type = sip_header_as_string(profile->home, (void *) sip->sip_event); if (count < 2) { - if ((sql = - switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' " - " and profile_name='%q' and hostname='%q'", from_user, from_host, profile->name, mod_sofia_globals.hostname))) { + if ((sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' " + " and profile_name='%q' and hostname='%q'", + from_user, from_host, profile->name, mod_sofia_globals.hostname))) { sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } - if ((sql = - switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent," - " profile_name, hostname, open_closed) " - "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')", - from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, mod_sofia_globals.hostname, open_closed))) { - + if (sub_count > 0 && (sql = switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent," + " profile_name, hostname, open_closed) " + "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')", + from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, + mod_sofia_globals.hostname, open_closed))) { + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } @@ -2696,16 +2710,17 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n switch_safe_free(sql); } - - if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent", full_agent); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", note_txt); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type); - switch_event_fire(&event); + if (sub_count > 0) { + if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent", full_agent); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", note_txt); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type); + switch_event_fire(&event); + } } if (event_type) { @@ -2728,7 +2743,12 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta); switch_stun_random_string(etag, 8, NULL); - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END()); + + if (sub_count > 0) { + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END()); + } else { + nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END()); + } switch_safe_free(contact_str); } From f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Feb 2011 16:22:43 -0600 Subject: [PATCH 06/28] fix possible bad pointer in global vars (please test) --- fscomm/widgets/codecwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fscomm/widgets/codecwidget.cpp b/fscomm/widgets/codecwidget.cpp index 42b10febfd..2f82e1a8cc 100644 --- a/fscomm/widgets/codecwidget.cpp +++ b/fscomm/widgets/codecwidget.cpp @@ -131,6 +131,8 @@ void CodecWidget::setCodecString(QString codecList) QStringList parsed = codecList.split("{"); QString var = parsed.at(1); var = var.split("}").at(0); + // warning switch_core_get_Variable may return an unsafe pointer in some cases. + // revise to use switch_core_get_variable_dup, and then free it after you are done. var = switch_core_get_variable(var.toAscii().data()); if ( ! var.isEmpty() ) { codecList = var; From b55b4eeaeea1d1cebc5a44ffdd88b224898d5d8a Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 3 Feb 2011 10:04:25 -0600 Subject: [PATCH 07/28] VS2010 fix minor build order problem --- libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj b/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj index d841b89c0a..be91504cc2 100644 --- a/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj +++ b/libs/win32/sofia/libsofia_sip_ua_static.2010.vcxproj @@ -508,6 +508,12 @@ if not exist "$(ProjectDir)$(IntDir)\auth_client.obj" "autogen.cmd" {8b3b4c4c-13c2-446c-beb0-f412cc2cfb9a} false + + {d331904d-a00a-4694-a5a3-fcff64ab5dbe} + + + {b4b62169-5ad4-4559-8707-3d933ac5db39} + {df018947-0fff-4eb3-bdee-441dc81da7a4} false From 74a0cfd1e101413a3941c41d04ee01d8df2ae418 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 10:19:04 -0600 Subject: [PATCH 08/28] FS-3027 --- src/mod/endpoints/mod_sofia/sofia_glue.c | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index dfd6a76974..8b2f470980 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -4071,15 +4071,22 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s greedy = !!sofia_test_pflag(tech_pvt->profile, PFLAG_GREEDY); scrooge = !!sofia_test_pflag(tech_pvt->profile, PFLAG_SCROOGE); - if (!greedy || !scrooge) { - if ((val = switch_channel_get_variable(channel, "sip_codec_negotiation"))) { - if (!strcasecmp(val, "greedy")) { - greedy = 1; - } else if (!strcasecmp(val, "scrooge")) { - scrooge = 1; - greedy = 1; - } - } + if ((val = switch_channel_get_variable(channel, "sip_codec_negotiation"))) { + if (!strcasecmp(val, "generous")) { + greedy = 0; + scrooge = 0; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : generous\n" ); + } else if (!strcasecmp(val, "greedy")) { + greedy = 1; + scrooge = 0; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : greedy\n" ); + } else if (!strcasecmp(val, "scrooge")) { + scrooge = 1; + greedy = 1; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation overriding sofia inbound-codec-negotiation : scrooge\n" ); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sip_codec_negotiation ignored invalid value : '%s' \n", val ); + } } if ((tech_pvt->origin = switch_core_session_strdup(session, (char *) sdp->sdp_origin->o_username))) { From e5fb456f3bfddbf1e379c77030e8e4dd5549d12a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 11:19:24 -0600 Subject: [PATCH 09/28] doh regression --- src/switch_event.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index 3e12ea115f..b626d5b846 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1561,6 +1561,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const char *cloned_sub_val = NULL; char *func_val = NULL; int nv = 0; + char *gvar = NULL; nv = switch_string_var_check_const(in) || switch_string_has_escaped_data(in); @@ -1673,7 +1674,6 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const int offset = 0; int ooffset = 0; char *ptr; - char *gvar = NULL; if ((expanded = switch_event_expand_headers(event, (char *) vname)) == vname) { expanded = NULL; @@ -1690,6 +1690,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } if (!(sub_val = switch_event_get_header(event, vname))) { + switch_safe_free(gvar); if ((gvar = switch_core_get_variable_dup(vname))) { sub_val = gvar; } @@ -1713,7 +1714,6 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } } - switch_safe_free(gvar); switch_safe_free(expanded); } else { switch_stream_handle_t stream = { 0 }; @@ -1789,6 +1789,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } } free(indup); + switch_safe_free(gvar); return data; } From 68d08547f36777e2c091008b5e1207ca5b15e9e2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 16:27:22 -0600 Subject: [PATCH 10/28] try to improve iLBC compat --- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- src/switch_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 8b2f470980..a0b7fca2ff 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -4480,7 +4480,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1; } - if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate) { + if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc")) { /* nevermind */ match = 0; } diff --git a/src/switch_core.c b/src/switch_core.c index 87543050b2..0eb51ccab3 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1486,7 +1486,7 @@ static void switch_load_core_config(const char *file) { switch_xml_t xml = NULL, cfg = NULL; - //switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); + switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); switch_core_hash_insert(runtime.ptimes, "G723", &d_30); if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) { From 33b74ca8c710a58d245ea8903f98e0e86cffe164 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 17:06:18 -0600 Subject: [PATCH 11/28] FS-3006 --- .../endpoints/mod_portaudio/mod_portaudio.c | 1054 +++++++++++------ 1 file changed, 716 insertions(+), 338 deletions(-) diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index 8978b85fc2..baa33d456e 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -40,6 +40,8 @@ #define MY_EVENT_RINGING "portaudio::ringing" #define MY_EVENT_MAKE_CALL "portaudio::makecall" +#define MY_EVENT_CALL_HELD "portaudio::callheld" +#define MY_EVENT_CALL_RESUMED "portaudio::callresumed" #define MY_EVENT_ERROR_AUDIO_DEV "portaudio::audio_dev_error" #define SWITCH_PA_CALL_ID_VARIABLE "pa_call_id" @@ -90,12 +92,20 @@ struct private_object { switch_file_handle_t *hfh; switch_frame_t hold_frame; unsigned char holdbuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_codec_t write_codec; struct private_object *next; }; typedef struct private_object private_t; +struct audio_stream { + int indev; + int outdev; + PABLIO_Stream *stream; + switch_timer_t write_timer; + struct audio_stream *next; +}; +typedef struct audio_stream audio_stream_t; + static struct { int debug; int port; @@ -113,12 +123,13 @@ static struct { switch_hash_t *call_hash; switch_mutex_t *device_lock; switch_mutex_t *pvt_lock; + switch_mutex_t *streams_lock; switch_mutex_t *flag_mutex; switch_mutex_t *pa_mutex; int sample_rate; int codec_ms; - PABLIO_Stream *audio_stream; - PABLIO_Stream *ring_stream; + audio_stream_t *main_stream; + audio_stream_t *ring_stream; switch_codec_t read_codec; switch_codec_t write_codec; switch_frame_t read_frame; @@ -126,13 +137,20 @@ static struct { unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; unsigned char cngbuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; private_t *call_list; + audio_stream_t *stream_list; int ring_interval; GFLAGS flags; switch_timer_t read_timer; - switch_timer_t write_timer; + switch_timer_t readfile_timer; switch_timer_t hold_timer; int dual_streams; time_t deactivate_timer; + int live_stream_switch; + int no_auto_resume_call; + int no_ring_during_call; + int codecs_inited; + int stream_in_use; //only really used by playdev + int destroying_streams; } globals; @@ -164,9 +182,22 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); -static switch_status_t engage_device(int restart); -static switch_status_t engage_ring_device(void); -static void deactivate_ring_device(void); + +static switch_status_t create_codecs(int restart); +static void create_hold_event(private_t *tech_pvt, int unhold); +static audio_stream_t * find_audio_stream(int indev, int outdev, int already_locked); +static audio_stream_t * get_audio_stream(int indev, int outdev); +static audio_stream_t * create_audio_stream(int indev, int outdev); +PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters); +static switch_status_t switch_audio_stream(); +static void add_stream(audio_stream_t *stream, int already_locked); +static void remove_stream(audio_stream_t *stream, int already_locked); +static switch_status_t destroy_audio_stream(int indev, int outdev); +static switch_status_t destroy_actual_stream(audio_stream_t *stream); +static void destroy_audio_streams(); +static switch_status_t validate_main_audio_stream(); +static switch_status_t validate_ring_audio_stream(); + static int dump_info(int verbose); static switch_status_t load_config(void); static int get_dev_by_name(char *name, int in); @@ -212,9 +243,8 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) if (hold_file) { tech_pvt->hold_file = switch_core_session_strdup(session, hold_file); } - - if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - if (engage_device(0) != SWITCH_STATUS_SUCCESS) { + if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { + if (validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); return SWITCH_STATUS_FALSE; } @@ -238,7 +268,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) globals.read_codec.implementation->actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - if (engage_ring_device() != SWITCH_STATUS_SUCCESS) { + if (validate_ring_audio_stream() != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Ring Error!\n"); switch_core_file_close(&fh); @@ -263,7 +293,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) } while (switch_channel_get_state(channel) == CS_ROUTING && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) { - switch_size_t olen = globals.read_timer.samples; + switch_size_t olen = globals.readfile_timer.samples; if (switch_micro_time_now() - last >= waitsec) { char buf[512]; @@ -273,7 +303,8 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_info", buf); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id); /* left behind for backwards compatability */ + switch_channel_set_variable(channel, SWITCH_PA_CALL_ID_VARIABLE, tech_pvt->call_id); switch_channel_event_set_data(channel, event); switch_event_fire(&event); } @@ -282,7 +313,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) } if (ring_file) { - if (switch_core_timer_next(&globals.read_timer) != SWITCH_STATUS_SUCCESS) { + if (switch_core_timer_next(&globals.readfile_timer) != SWITCH_STATUS_SUCCESS) { switch_core_file_close(&fh); break; } @@ -292,8 +323,9 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) switch_core_file_seek(&fh, &pos, 0, SEEK_SET); } - if (globals.ring_stream) { - WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.write_timer); + if (globals.ring_stream && (! switch_test_flag(globals.call_list, TFLAG_MASTER) || + ( !globals.no_ring_during_call && globals.main_stream != globals.ring_stream)) ) { //if there is a ring stream and not an active call or if there is an active call and we are allowed to ring during it AND the ring stream is not the main stream + WriteAudioStream(globals.ring_stream->stream, abuf, (long) olen, &globals.ring_stream->write_timer); } } else { switch_yield(10000); @@ -303,7 +335,6 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) } if (ring_file) { - deactivate_ring_device(); switch_core_file_close(&fh); } @@ -329,27 +360,130 @@ static switch_status_t channel_on_execute(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } -static void deactivate_audio_device(void) +static audio_stream_t* find_audio_stream(int indev, int outdev, int already_locked) { - if (!globals.audio_stream) { - return; + audio_stream_t *cur_stream; + + if (! globals.stream_list) { + return NULL; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stop audio device.\n"); + if (! already_locked) { + switch_mutex_lock(globals.streams_lock); + } + cur_stream = globals.stream_list; - switch_mutex_lock(globals.device_lock); - /* LOCKED ************************************************************************************************** */ - - if (globals.audio_stream) { - if (globals.ring_stream == globals.audio_stream) { - globals.ring_stream = NULL; + while (cur_stream != NULL) { + if (cur_stream->outdev == outdev) { + if (indev == -1 || cur_stream->indev == indev) { + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } + return cur_stream; + } } - CloseAudioStream(globals.audio_stream); - globals.audio_stream = NULL; + cur_stream = cur_stream->next; + } + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } + return NULL; +} +static void destroy_audio_streams() +{ + int close_wait = 4; + globals.destroying_streams = 1; + + while (globals.stream_in_use && close_wait--) { + switch_yield(250000); + } + while (globals.stream_list != NULL) { + destroy_audio_stream(globals.stream_list->indev, globals.stream_list->outdev); + } + globals.destroying_streams = 0; +} +static switch_status_t validate_main_audio_stream() +{ + if (globals.read_timer.timer_interface) { + switch_core_timer_sync(&globals.read_timer); } - /* UNLOCKED ************************************************************************************************* */ - switch_mutex_unlock(globals.device_lock); + if (globals.main_stream) { + if (globals.main_stream->write_timer.timer_interface) { + switch_core_timer_sync(&(globals.main_stream->write_timer)); + } + + return SWITCH_STATUS_SUCCESS; + } + + globals.main_stream = get_audio_stream(globals.indev, globals.outdev); + + if (globals.main_stream) { + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +static switch_status_t validate_ring_audio_stream() +{ + if (globals.ringdev == -1) { + return SWITCH_STATUS_SUCCESS; + } + if (globals.ring_stream) { + if (globals.ring_stream->write_timer.timer_interface) { + switch_core_timer_sync(&(globals.ring_stream->write_timer)); + } + return SWITCH_STATUS_SUCCESS; + } + globals.ring_stream = get_audio_stream(-1, globals.ringdev); + if (globals.ring_stream) { + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +static switch_status_t destroy_actual_stream(audio_stream_t *stream) +{ + if (stream == NULL) { + return SWITCH_STATUS_FALSE; + } + + if (globals.main_stream == stream) { + globals.main_stream = NULL; + } + + if (globals.ring_stream == stream) { + globals.ring_stream = NULL; + } + + CloseAudioStream(stream->stream); + stream->stream = NULL; + + if (stream->write_timer.timer_interface) { + switch_core_timer_destroy(&stream->write_timer); + } + + switch_safe_free(stream); + return SWITCH_STATUS_SUCCESS; +} +static switch_status_t destroy_audio_stream(int indev, int outdev) +{ + audio_stream_t *stream; + + switch_mutex_lock(globals.streams_lock); + stream = find_audio_stream(indev, outdev,1); + if (stream == NULL) { + switch_mutex_unlock(globals.streams_lock); + return SWITCH_STATUS_FALSE; + } + + remove_stream(stream, 1); + switch_mutex_unlock(globals.streams_lock); + + destroy_actual_stream(stream); + return SWITCH_STATUS_SUCCESS; } @@ -368,34 +502,69 @@ static void destroy_codecs(void) switch_core_timer_destroy(&globals.read_timer); } - if (globals.write_timer.timer_interface) { - switch_core_timer_destroy(&globals.write_timer); + if (globals.readfile_timer.timer_interface) { + switch_core_timer_destroy(&globals.readfile_timer); } if (globals.hold_timer.timer_interface) { switch_core_timer_destroy(&globals.hold_timer); } - - + globals.codecs_inited = 0; } -static void deactivate_ring_device(void) +static void create_hold_event(private_t *tech_pvt, int unhold) { - if (!globals.ring_stream) { - return; + switch_event_t *event; + char * event_id; + + if (unhold) { + event_id = MY_EVENT_CALL_RESUMED; + } else { + event_id = MY_EVENT_CALL_HELD; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stop ring device.\n"); - switch_mutex_lock(globals.device_lock); - if (globals.ring_stream && globals.ring_stream != globals.audio_stream) { - CloseAudioStream(globals.ring_stream); + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, event_id) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(switch_core_session_get_channel(tech_pvt->session), event); + switch_event_fire(&event); } - globals.ring_stream = NULL; - switch_mutex_unlock(globals.device_lock); } +static void add_stream(audio_stream_t * stream, int already_locked) +{ + audio_stream_t *last; + if (! already_locked) { + switch_mutex_lock(globals.streams_lock); + } + for (last = globals.stream_list; last && last->next; last = last->next); + if (last == NULL) { + globals.stream_list = stream; + } else { + last->next = stream; + } + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } +} +static void remove_stream(audio_stream_t * stream, int already_locked) +{ + audio_stream_t *previous; + if (! already_locked) { + switch_mutex_lock(globals.streams_lock); + } + if (globals.stream_list == stream) { + globals.stream_list = stream->next; + } else { + for (previous = globals.stream_list; previous && previous->next && previous->next != stream; previous = previous->next) { + ; + } + previous->next = stream->next; + } + if (! already_locked) { + switch_mutex_unlock(globals.streams_lock); + } +} static void add_pvt(private_t *tech_pvt, int master) { @@ -418,8 +587,9 @@ static void add_pvt(private_t *tech_pvt, int master) if (tp == tech_pvt) { in_list = 1; } - if (master) { + if (master && switch_test_flag(tp, TFLAG_MASTER) ) { switch_clear_flag_locked(tp, TFLAG_MASTER); + create_hold_event(tp,0); } } @@ -446,11 +616,16 @@ static void add_pvt(private_t *tech_pvt, int master) static void remove_pvt(private_t *tech_pvt) { private_t *tp, *last = NULL; + int was_master = 0; switch_mutex_lock(globals.pvt_lock); for (tp = globals.call_list; tp; tp = tp->next) { - switch_clear_flag_locked(tp, TFLAG_MASTER); + if (tp == tech_pvt) { + if (switch_test_flag(tp, TFLAG_MASTER)) { + switch_clear_flag_locked(tp, TFLAG_MASTER); + was_master = 1; + } if (last) { last->next = tp->next; } else { @@ -461,10 +636,13 @@ static void remove_pvt(private_t *tech_pvt) } if (globals.call_list) { - switch_set_flag_locked(globals.call_list, TFLAG_MASTER); + if (was_master && ! globals.no_auto_resume_call) { + switch_set_flag_locked(globals.call_list, TFLAG_MASTER); + create_hold_event(globals.call_list, 1); + } } else { globals.deactivate_timer = switch_epoch_time_now(NULL) + 2; - deactivate_audio_device(); + destroy_audio_streams(); } switch_mutex_unlock(globals.pvt_lock); @@ -555,8 +733,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch int samples = 0; switch_status_t status = SWITCH_STATUS_FALSE; switch_assert(tech_pvt != NULL); - - if (!globals.audio_stream) { + + if (!globals.main_stream) { goto normal_return; } @@ -618,7 +796,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch } switch_mutex_lock(globals.device_lock); - samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer); + samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer); switch_mutex_unlock(globals.device_lock); if (samples) { @@ -635,7 +813,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch goto cng_nowait; } - normal_return: +normal_return: return status; cng_nowait: @@ -655,7 +833,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc private_t *tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); - if (!globals.audio_stream) { + if (!globals.main_stream) { return SWITCH_STATUS_FALSE; } @@ -667,9 +845,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc return SWITCH_STATUS_SUCCESS; } - if (globals.audio_stream) { + if (globals.main_stream) { if (switch_test_flag((&globals), GFLAG_EAR)) { - WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), &globals.write_timer); + WriteAudioStream(globals.main_stream->stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), &(globals.main_stream->write_timer)); } status = SWITCH_STATUS_SUCCESS; } @@ -747,7 +925,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi channel = switch_core_session_get_channel(*new_session); switch_core_session_set_private(*new_session, tech_pvt); tech_pvt->session = *new_session; - globals.flags = GFLAG_EAR | GFLAG_MOUTH; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(new_session); @@ -796,16 +973,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) switch_core_hash_init(&globals.call_hash, module_pool); switch_mutex_init(&globals.device_lock, SWITCH_MUTEX_NESTED, module_pool); switch_mutex_init(&globals.pvt_lock, SWITCH_MUTEX_NESTED, module_pool); + switch_mutex_init(&globals.streams_lock, SWITCH_MUTEX_NESTED, module_pool); switch_mutex_init(&globals.flag_mutex, SWITCH_MUTEX_NESTED, module_pool); switch_mutex_init(&globals.pa_mutex, SWITCH_MUTEX_NESTED, module_pool); - + globals.codecs_inited=0; globals.read_frame.data = globals.databuf; globals.read_frame.buflen = sizeof(globals.databuf); globals.cng_frame.data = globals.cngbuf; globals.cng_frame.buflen = sizeof(globals.cngbuf); globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2; switch_set_flag((&globals.cng_frame), SFF_CNG); - + globals.flags = GFLAG_EAR | GFLAG_MOUTH; /* dual streams makes portaudio on solaris choke */ #if defined(sun) || defined(__sun) globals.dual_streams = 0; @@ -834,6 +1012,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); return SWITCH_STATUS_GENERR; } + if (switch_event_reserve_subclass(MY_EVENT_CALL_HELD) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); + return SWITCH_STATUS_GENERR; + } + if (switch_event_reserve_subclass(MY_EVENT_CALL_RESUMED) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); + return SWITCH_STATUS_GENERR; + } if (switch_event_reserve_subclass(MY_EVENT_ERROR_AUDIO_DEV) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n"); @@ -861,9 +1047,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) switch_console_set_complete("add pa devlist"); switch_console_set_complete("add pa indev"); switch_console_set_complete("add pa outdev"); + switch_console_set_complete("add pa preparestream"); + switch_console_set_complete("add pa switchstream"); + switch_console_set_complete("add pa closestreams"); switch_console_set_complete("add pa ringdev"); switch_console_set_complete("add pa ringfile"); switch_console_set_complete("add pa play"); + switch_console_set_complete("add pa playdev"); switch_console_set_complete("add pa looptest"); /* indicate that the module should continue to be loaded */ @@ -881,9 +1071,12 @@ static switch_status_t load_config(void) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return SWITCH_STATUS_TERM; } - + destroy_audio_streams(); + destroy_codecs(); globals.dual_streams = 0; - + globals.live_stream_switch = 0; + globals.no_auto_resume_call = 0; + globals.no_ring_during_call = 0; globals.indev = globals.outdev = globals.ringdev = -1; globals.sample_rate = 8000; @@ -896,6 +1089,24 @@ static switch_status_t load_config(void) globals.debug = atoi(val); } else if (!strcmp(var, "ring-interval")) { globals.ring_interval = atoi(val); + } else if (!strcmp(var, "no-auto-resume-call")) { + if (switch_true(val)) { + globals.no_auto_resume_call = 1; + } else { + globals.no_auto_resume_call = 0; + } + } else if (!strcmp(var, "no-ring-during-call")) { + if (switch_true(val)) { + globals.no_ring_during_call = 1; + } else { + globals.no_ring_during_call = 0; + } + } else if (!strcmp(var, "live-stream-switch")) { + if (switch_true(val)) { + globals.live_stream_switch = 1; + } else { + globals.live_stream_switch = 0; + } } else if (!strcmp(var, "ring-file")) { set_global_ring_file(val); } else if (!strcmp(var, "hold-file")) { @@ -1007,8 +1218,7 @@ static switch_status_t load_config(void) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown) { - deactivate_audio_device(); - deactivate_ring_device(); + destroy_audio_streams(); destroy_codecs(); Pa_Terminate(); @@ -1017,6 +1227,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown) switch_event_free_subclass(MY_EVENT_RINGING); switch_event_free_subclass(MY_EVENT_MAKE_CALL); switch_event_free_subclass(MY_EVENT_ERROR_AUDIO_DEV); + switch_event_free_subclass(MY_EVENT_CALL_HELD); + switch_event_free_subclass(MY_EVENT_CALL_RESUMED); + switch_safe_free(globals.dialplan); switch_safe_free(globals.context); @@ -1118,7 +1331,99 @@ static void PrintSupportedStandardSampleRates(const PaStreamParameters * inputPa } /*******************************************************************/ +static switch_status_t play_dev(switch_stream_handle_t *stream, int outdev, char * file, const char * max_seconds, const char * no_close) +{ + switch_file_handle_t fh = { 0 }; + int samples = 0; + int seconds = 5; + audio_stream_t * audio_stream; + int created_stream = 0; + int wrote = 0; + switch_size_t olen; + int16_t abuf[2048]; + + if (!strcasecmp(file, "ringtest")) { + file = globals.ring_file; + } + if (outdev == -1) { + stream->write_function(stream, "Invalid output audio device\n"); + return SWITCH_STATUS_FALSE; + } + audio_stream = get_audio_stream(-1, outdev); + + fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; + + if (switch_core_file_open(&fh, file, + globals.read_codec.implementation->number_of_channels, + globals.read_codec.implementation->actual_samples_per_second, + SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "Cannot play requested file %s\n", file); + return SWITCH_STATUS_FALSE; + } + + olen = globals.read_codec.implementation->samples_per_packet; + + if (max_seconds) { + int i = atoi(max_seconds); + if (i >= 0) { + seconds = i; + } + } + + if (globals.call_list) { + switch_mutex_lock(globals.pvt_lock); + if (!globals.main_stream) { + switch_mutex_unlock(globals.pvt_lock); + return SWITCH_STATUS_FALSE; + } + + if ( switch_test_flag(globals.call_list, TFLAG_MASTER) && globals.main_stream->outdev == outdev) { /*so we are the active stream so we need to dupe it basically */ + audio_stream = create_audio_stream(-1,outdev); + created_stream=1; + } + switch_mutex_unlock(globals.pvt_lock); + } + + if (! audio_stream) { + stream->write_function(stream, "Failed to engage audio device\n"); + return SWITCH_STATUS_FALSE; + } + + + + samples = globals.read_codec.implementation->actual_samples_per_second * seconds; + globals.stream_in_use=1; + while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) { + if (globals.destroying_streams || ! audio_stream->stream) { + break; + } + + WriteAudioStream(audio_stream->stream, abuf, (long) olen, &(audio_stream->write_timer)); + wrote += (int) olen; + if (samples) { + samples -= (int) olen; + if (samples <= 0) { + break; + } + } + olen = globals.read_codec.implementation->samples_per_packet; + } + globals.stream_in_use = 0; + + switch_core_file_close(&fh); + if (! globals.call_list && ( ! no_close || strcasecmp(no_close, "no_close"))) { + destroy_audio_streams(); + } + + seconds = wrote / globals.read_codec.implementation->actual_samples_per_second; + stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz", + file, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second); + if (created_stream) { /*still need this as not added to the global pool */ + destroy_actual_stream(audio_stream); + } + return SWITCH_STATUS_SUCCESS; +} static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *stream) { int i, numDevices, prev; @@ -1200,8 +1505,7 @@ static int dump_info(int verbose) } if (verbose < 0) { - deactivate_audio_device(); - deactivate_ring_device(); + destroy_audio_streams(); destroy_codecs(); Pa_Terminate(); Pa_Initialize(); @@ -1309,36 +1613,15 @@ static int dump_info(int verbose) return err; } -static switch_status_t engage_device(int restart) +static switch_status_t create_codecs(int restart) { - PaStreamParameters inputParameters, outputParameters; - PaError err; int sample_rate = globals.sample_rate; int codec_ms = globals.codec_ms; - switch_event_t *event; - - switch_mutex_lock(globals.device_lock); - while (globals.deactivate_timer > switch_epoch_time_now(NULL)) { - switch_yield(1000000); - } - switch_mutex_unlock(globals.device_lock); - if (restart) { - deactivate_audio_device(); - deactivate_ring_device(); destroy_codecs(); } - - if (globals.read_timer.timer_interface) { - switch_core_timer_sync(&globals.read_timer); - } - - if (globals.write_timer.timer_interface) { - switch_core_timer_sync(&globals.write_timer); - } - - if (globals.audio_stream) { + if (globals.codecs_inited) { return SWITCH_STATUS_SUCCESS; } @@ -1375,20 +1658,18 @@ static switch_status_t engage_device(int restart) return SWITCH_STATUS_FALSE; } } - - - if (!globals.write_timer.timer_interface) { - if (switch_core_timer_init(&globals.write_timer, + if (!globals.readfile_timer.timer_interface) { + if (switch_core_timer_init(&globals.readfile_timer, globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, module_pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n"); switch_core_codec_destroy(&globals.read_codec); switch_core_codec_destroy(&globals.write_codec); - switch_core_timer_destroy(&globals.read_timer); return SWITCH_STATUS_FALSE; } } + if (!globals.hold_timer.timer_interface) { if (switch_core_timer_init(&globals.hold_timer, globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet, @@ -1397,106 +1678,119 @@ static switch_status_t engage_device(int restart) switch_core_codec_destroy(&globals.read_codec); switch_core_codec_destroy(&globals.write_codec); switch_core_timer_destroy(&globals.read_timer); - switch_core_timer_destroy(&globals.write_timer); + switch_core_timer_destroy(&globals.readfile_timer); + return SWITCH_STATUS_FALSE; } } - globals.read_frame.rate = sample_rate; - globals.read_frame.codec = &globals.read_codec; + globals.cng_frame.rate = globals.read_frame.rate = sample_rate; + globals.cng_frame.codec = globals.read_frame.codec = &globals.read_codec; - switch_mutex_lock(globals.device_lock); - /* LOCKED ************************************************************************************************** */ - inputParameters.device = globals.indev; - inputParameters.channelCount = 1; - inputParameters.sampleFormat = SAMPLE_TYPE; - inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; - inputParameters.hostApiSpecificStreamInfo = NULL; - outputParameters.device = globals.outdev; + globals.codecs_inited=1; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_audio_stream() +{ + audio_stream_t *stream; + if (! globals.call_list) { /* If no active calls then it will automatically switch over on next call */ + return SWITCH_STATUS_SUCCESS; + } + stream = get_audio_stream(globals.indev, globals.outdev); + if (stream == NULL) { + return SWITCH_STATUS_FALSE; + } + + globals.main_stream = stream;//TODO: need locks around here?? + + return SWITCH_STATUS_SUCCESS; +} +PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters) +{ + if (inputParameters->device != -1) { + return OpenAudioStream(stream, inputParameters, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams); + } + return OpenAudioStream(stream, NULL, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, 0); +} + +static audio_stream_t *create_audio_stream(int indev, int outdev) +{ + PaStreamParameters inputParameters, outputParameters; + PaError err; + switch_event_t *event; + audio_stream_t *stream; + + stream = malloc(sizeof(audio_stream_t)); + if (stream == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to alloc memory\n"); + return NULL; + } + memset(stream, 0, sizeof(audio_stream_t)); + stream->next = NULL; + stream->stream = NULL; + stream->indev = indev; + stream->outdev = outdev; + if (!stream->write_timer.timer_interface) { + if (switch_core_timer_init(&(stream->write_timer), + globals.timer_name, globals.codec_ms, globals.read_codec.implementation->samples_per_packet, + module_pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n"); + switch_safe_free(stream); + return NULL; + } + } + inputParameters.device = indev; + if (indev != -1) { + inputParameters.channelCount = 1; + inputParameters.sampleFormat = SAMPLE_TYPE; + inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; + inputParameters.hostApiSpecificStreamInfo = NULL; + } + outputParameters.device = outdev; outputParameters.channelCount = 1; outputParameters.sampleFormat = SAMPLE_TYPE; outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; - //err = OpenAudioStream(&globals.audio_stream, NULL/*&inputParameters*/, &outputParameters, sample_rate, paClipOff, - //globals.read_codec.implementation->samples_per_packet); - err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, - globals.read_codec.implementation->samples_per_packet, globals.dual_streams); - /* UNLOCKED ************************************************************************************************* */ + + err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters); if (err != paNoError) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n"); switch_yield(1000000); - err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, - globals.read_codec.implementation->samples_per_packet, globals.dual_streams); + err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters); } - switch_mutex_unlock(globals.device_lock); - if (err != paNoError) { + switch_safe_free(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n"); - switch_core_codec_destroy(&globals.read_codec); - switch_core_codec_destroy(&globals.write_codec); - switch_core_timer_destroy(&globals.read_timer); - switch_core_timer_destroy(&globals.write_timer); - switch_core_timer_destroy(&globals.hold_timer); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR_AUDIO_DEV) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Reason", Pa_GetErrorText(err)); switch_event_fire(&event); } - return SWITCH_STATUS_FALSE; + return NULL; } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage audio device rate: %d channels %d\n", sample_rate, outputParameters.channelCount); - - engage_ring_device(); - - return SWITCH_STATUS_SUCCESS; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created audio stream: %d channels %d\n", globals.sample_rate, outputParameters.channelCount); + return stream; } -static switch_status_t engage_ring_device(void) +audio_stream_t *get_audio_stream(int indev, int outdev) { - PaStreamParameters outputParameters = { 0 }; - PaError err; - int sample_rate = globals.sample_rate; - int channels = 1; - - if (globals.ring_stream) { - return SWITCH_STATUS_SUCCESS; + audio_stream_t *stream; + if (outdev == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error invalid output audio device\n"); } - - if (globals.ringdev == globals.outdev) { - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - globals.ring_stream = globals.audio_stream; - } else { - goto error; - } - } else { - switch_mutex_lock(globals.device_lock); - /* LOCKED ************************************************************************************************** */ - outputParameters.device = globals.ringdev; - outputParameters.channelCount = channels; - outputParameters.sampleFormat = SAMPLE_TYPE; - outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; - outputParameters.hostApiSpecificStreamInfo = NULL; - err = OpenAudioStream(&globals.ring_stream, NULL, - &outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams); - /* UNLOCKED ************************************************************************************************* */ - switch_mutex_unlock(globals.device_lock); - - if (err != paNoError) { - goto error; - } + if (create_codecs(0) != SWITCH_STATUS_SUCCESS) { + return NULL; } - - switch_yield(10000); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage ring device rate: %d channels %d\n", sample_rate, channels); - return SWITCH_STATUS_SUCCESS; - - - error: - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device\n"); - return SWITCH_STATUS_FALSE; - + stream = find_audio_stream(indev, outdev, 0); + if (stream != NULL) { + return stream; + } + stream = create_audio_stream(indev, outdev); + if (stream) { + add_stream(stream, 0); + } + return stream; } static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream) @@ -1523,6 +1817,211 @@ static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t * return SWITCH_STATUS_SUCCESS; } +static switch_status_t close_streams(char **argv, int argc, switch_stream_handle_t *stream) +{ + if (globals.call_list) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + destroy_audio_streams(); + stream->write_function(stream, "closestreams all open streams closed\n"); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_indev(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval; + + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0] + 1, 1); + } else { + devval = get_dev_by_name(argv[0], 1); + } + if (devval < 0) { + stream->write_function(stream, "indev not set (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + globals.indev = devval; + switch_audio_stream(); + stream->write_function(stream, "indev set to %d\n", devval); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_outdev(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval; + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0] + 1, 0); + } else { + devval = get_dev_by_name(argv[0], 0); + } + if (devval < 0) { + stream->write_function(stream, "outdev not set (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + + globals.outdev = devval; + switch_audio_stream(); + stream->write_function(stream, "outdev set to %d\n", devval); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t prepare_stream(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval=-2,devval2=-1; + if (! strcmp(argv[0], "#-1")) { + devval = -1; + } else if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0]+1, 1); + } + if (devval == -2) { + stream->write_function(stream, "preparestream not prepared as indev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[1] == '#') { + devval2 = get_dev_by_number(argv[1]+1, 0); + } + if (devval2 == -1) { + stream->write_function(stream, "preparestream not prepared as outdev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + + if (! get_audio_stream(devval,devval2)) { + stream->write_function(stream, "preparestream not prepared received an invalid stream back\n"); + return SWITCH_STATUS_FALSE; + } + stream->write_function(stream, "preparestream prepared indev: %d outdev: %d\n", devval, devval2); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_stream(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval =-1, devval2 = -1; + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0]+1, 1); + } + if (devval == -1) { + stream->write_function(stream, "switchstream not prepared as indev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + if (*argv[1] == '#') { + devval2 = get_dev_by_number(argv[1]+1, 0); + } + if (devval2 == -1) { + stream->write_function(stream, "switchstream not prepared as outdev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + globals.indev = devval; + globals.outdev = devval2; + if (switch_audio_stream() != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "switchstream was unable to switch\n"); + return SWITCH_STATUS_FALSE; + } + stream->write_function(stream, "switchstream switched to indev: %d outdev: %d\n", devval, devval2); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_ringdev(char **argv, int argc, switch_stream_handle_t *stream) +{ + int devval; + if (globals.call_list && ! globals.live_stream_switch) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (! strcmp(argv[0], "#-1")) { + globals.ring_stream = NULL; + globals.ringdev = -1; + stream->write_function(stream, "ringdev set to %d\n", globals.ringdev); + return SWITCH_STATUS_SUCCESS; + } else if (*argv[0] == '#') { + devval = get_dev_by_number(argv[0] + 1, 0); + } else { + devval = get_dev_by_name(argv[0], 0); + } + if (devval == -1) { + stream->write_function(stream, "ringdev not set as dev has (invalid value)\n"); + return SWITCH_STATUS_FALSE; + } + globals.ringdev = devval; + stream->write_function(stream, "ringdev set to %d\n", globals.ringdev); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t looptest(char **argv, int argc, switch_stream_handle_t *stream) +{ + int samples = 0; + int success = 0; + int i; + + if (globals.call_list) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); + return SWITCH_STATUS_FALSE; + } + if (validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "looptest Failed to engage audio device\n"); + return SWITCH_STATUS_FALSE; + } + globals.stream_in_use = 1; + for (i = 0; i < 400; i++) { + if (globals.destroying_streams || ! globals.main_stream->stream) { + break; + } + if ((samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) { + WriteAudioStream(globals.main_stream->stream, globals.read_frame.data, (long) samples, &(globals.main_stream->write_timer)); + success = 1; + } + switch_yield(10000); + } + globals.stream_in_use = 0; + + if (!success) { + stream->write_function(stream, "Failed to read any bytes from indev\n"); + return SWITCH_STATUS_FALSE; + } + destroy_audio_streams(); + stream->write_function(stream, "looptest complete\n"); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t set_ringfile(char **argv, int argc, switch_stream_handle_t *stream) +{ + if (! argv[0]) { + stream->write_function(stream, "%s", globals.ring_file); + return SWITCH_STATUS_SUCCESS; + } + if (create_codecs(0) == SWITCH_STATUS_SUCCESS) { + switch_file_handle_t fh = { 0 }; + if (switch_core_file_open(&fh, + argv[0], + globals.read_codec.implementation->number_of_channels, + globals.read_codec.implementation->actual_samples_per_second, + SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { + switch_core_file_close(&fh); + set_global_ring_file(argv[0]); + } else { + stream->write_function(stream, "ringfile Unable to open ring file %s\n", argv[0]); + return SWITCH_STATUS_FALSE; + } + } else { + stream->write_function(stream, "ringfile Failed to init codecs device\n"); + return SWITCH_STATUS_FALSE; + } + stream->write_function(stream, "ringfile set to %s", globals.ring_file); + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t *stream) { private_t *tp, *tech_pvt = NULL; @@ -1542,7 +2041,10 @@ static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t } } else if (!strcasecmp(callid, "none")) { for (tp = globals.call_list; tp; tp = tp->next) { + if (switch_test_flag(tp, TFLAG_MASTER)) { switch_clear_flag_locked(tp, TFLAG_MASTER); + create_hold_event(tp,0); + } } stream->write_function(stream, "OK\n"); goto done; @@ -1559,6 +2061,7 @@ static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t remove_pvt(tech_pvt); } add_pvt(tech_pvt, PA_MASTER); + create_hold_event(tech_pvt, 1); stream->write_function(stream, "OK\n"); } else { stream->write_function(stream, "NO SUCH CALL\n"); @@ -1609,7 +2112,6 @@ static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t switch_channel_t *channel = switch_core_session_get_channel(tp->session); switch_set_flag_locked(tp, TFLAG_ANSWER); add_pvt(tp, PA_MASTER); - deactivate_ring_device(); switch_channel_mark_answered(channel); } } else { @@ -1624,7 +2126,6 @@ static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t switch_channel_t *channel = switch_core_session_get_channel(tp->session); switch_set_flag_locked(tp, TFLAG_ANSWER); add_pvt(tp, PA_MASTER); - deactivate_ring_device(); switch_channel_mark_answered(channel); x++; break; @@ -1766,7 +2267,6 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t channel = switch_core_session_get_channel(session); switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; - globals.flags = GFLAG_EAR | GFLAG_MOUTH; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(&session); @@ -1805,9 +2305,8 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); } tech_pvt->session = session; - if ((status = engage_device(0)) == SWITCH_STATUS_SUCCESS) { + if ((status = validate_main_audio_stream()) == SWITCH_STATUS_SUCCESS) { switch_set_flag_locked(tech_pvt, TFLAG_ANSWER); - deactivate_ring_device(); switch_channel_mark_answered(channel); switch_channel_set_state(channel, CS_INIT); if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) { @@ -1855,10 +2354,11 @@ SWITCH_STANDARD_API(pa_cmd) { char *argv[1024] = { 0 }; int argc = 0; - char *mycmd = NULL, *devname = NULL; + char *mycmd = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; pa_command_t func = NULL; - int lead = 1, devval = 0; + int devval; + int lead = 1; char *wcmd = NULL, *action = NULL; char cmd_buf[1024] = ""; char *http = NULL; @@ -1878,9 +2378,15 @@ SWITCH_STANDARD_API(pa_cmd) "pa devlist [xml]\n" "pa indev #|\n" "pa outdev #|\n" + "pa preparestream # #\n" + "pa switchstream # #\n" + "pa closestreams\n" "pa ringdev #|\n" - "pa play [ringtest|]\n" - "pa ringfile [filename]\n" "pa looptest\n" "--------------------------------------------------------------------------------\n"; + "pa play [ringtest|] [seconds] [no_close]\n" + "pa playdev # [ringtest|] [seconds] [no_close]\n" + "pa ringfile [filename]\n" + "pa looptest\n" + "--------------------------------------------------------------------------------\n"; if (stream->param_event) { @@ -1973,169 +2479,42 @@ SWITCH_STANDARD_API(pa_cmd) func = switch_call; } else if (!strcasecmp(argv[0], "dtmf")) { func = dtmf_call; + } else if (!strcasecmp(argv[0], "closestreams")) { + func = close_streams; } else if (argv[1] && !strcmp(argv[0], "indev")) { - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (*argv[1] == '#') { - devval = get_dev_by_number(argv[1] + 1, 1); - } else { - devval = get_dev_by_name(argv[1], 1); - } - devname = "indev"; - if (devval > -1) { - globals.indev = devval; - //engage_device(1); - } + func = set_indev; } else if (argv[1] && !strcmp(argv[0], "outdev")) { - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (*argv[1] == '#') { - devval = get_dev_by_number(argv[1] + 1, 0); - } else { - devval = get_dev_by_name(argv[1], 0); - } - devname = "outdev"; - if (devval > -1) { - globals.outdev = devval; - //engage_device(1); - } + func = set_outdev; + } else if (argv[1] && argv[2] && !strcmp(argv[0], "preparestream")) { + func = prepare_stream; + } else if (argv[1] && argv[2] && !strcmp(argv[0], "switchstream")) { + func = switch_stream; } else if (argv[1] && !strcmp(argv[0], "ringdev")) { - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (*argv[1] == '#') { - devval = get_dev_by_number(argv[1] + 1, 0); - } else { - devval = get_dev_by_name(argv[1], 0); - } - devname = "ringdev"; - if (devval > -1) { - globals.ringdev = devval; - //engage_device(1); - } - } else if ((argv[1] && !strcasecmp(argv[0], "play"))) { - switch_file_handle_t fh = { 0 }; - char *playfile = NULL; - int samples = 0; - int seconds = 5; - int wrote = 0; - - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (!strcasecmp(argv[1], "ringtest")) { - playfile = globals.ring_file; - } else { - playfile = argv[1]; - } - - fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - if (switch_core_file_open(&fh, - playfile, - globals.read_codec.implementation->number_of_channels, - globals.read_codec.implementation->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - switch_size_t olen = globals.read_codec.implementation->samples_per_packet; - int16_t abuf[2048]; - - if (argv[2]) { - int i = atoi(argv[2]); - if (i >= 0) { - seconds = i; - } - } - - samples = globals.read_codec.implementation->actual_samples_per_second * seconds; - while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) { - WriteAudioStream(globals.audio_stream, abuf, (long) olen, &globals.read_timer); - wrote += (int) olen; - if (samples) { - samples -= (int) olen; - if (samples <= 0) { - break; - } - } - olen = globals.read_codec.implementation->samples_per_packet; - } - - switch_core_file_close(&fh); - deactivate_audio_device(); - - seconds = wrote / globals.read_codec.implementation->actual_samples_per_second; - stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz", - playfile, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second); - - - } else { - stream->write_function(stream, "Cannot play requested file %s\n", argv[1]); - } - } else { + func = set_ringdev; + } else if ((argv[1] && !strcmp(argv[0], "play"))) { + if (validate_main_audio_stream() == SWITCH_STATUS_SUCCESS) { + play_dev(stream, globals.main_stream ? globals.main_stream->outdev : -1,argv[1],argv[2], argv[3]); + }else{ stream->write_function(stream, "Failed to engage audio device\n"); } goto done; + } else if ((argv[1] && argv[2] && !strcmp(argv[0], "playdev"))) { + if (*argv[1] == '#') { + devval = get_dev_by_number(argv[1] + 1, 0); + } else { + devval = -1; + } + play_dev(stream, devval,argv[2],argv[3],argv[4]); + goto done; } else if (!strcasecmp(argv[0], "looptest")) { - if (globals.call_list) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n"); - goto done; - } - - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - int samples = 0; - int success = 0; - int i; - for (i = 0; i < 400; i++) { - if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, - globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) { - WriteAudioStream(globals.audio_stream, globals.read_frame.data, (long) samples, &globals.write_timer); - success = 1; - } - switch_yield(10000); - } - if (!success) { - stream->write_function(stream, "Failed to read any bytes from indev\n"); - } - deactivate_audio_device(); - } else { - stream->write_function(stream, "Failed to engage audio device\n"); - } - goto done; + func = looptest; } else if (!strcasecmp(argv[0], "ringfile")) { - if (argv[1]) { - if (engage_device(0) == SWITCH_STATUS_SUCCESS) { - switch_file_handle_t fh = { 0 }; - if (switch_core_file_open(&fh, - argv[1], - globals.read_codec.implementation->number_of_channels, - globals.read_codec.implementation->actual_samples_per_second, - SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { - switch_core_file_close(&fh); - set_global_ring_file(argv[1]); - } else { - stream->write_function(stream, "Unable to open ring file %s\n", argv[1]); - } - } else { - stream->write_function(stream, "Failed to engage audio device\n"); - } - } else { - stream->write_function(stream, "%s", globals.ring_file); - } - goto done; + func = set_ringfile; + } else { + stream->write_function(stream, "Unknown Command or not enough args [%s]\n", argv[0]); } + if (func) { if (http) { stream->write_function(stream, "
");
@@ -2143,21 +2522,12 @@ SWITCH_STANDARD_API(pa_cmd)
 
 		switch_mutex_lock(globals.pa_mutex);
 		status = func(&argv[lead], argc - lead, stream);
+		status = SWITCH_STATUS_SUCCESS; /*if func was defined we want to always return success as the command was found */
 		switch_mutex_unlock(globals.pa_mutex);
 
 		if (http) {
 			stream->write_function(stream, "\n\n
"); } - } else { - if (devname) { - if (devval > -1) { - stream->write_function(stream, "%s set to %d\n", devname, devval); - } else { - stream->write_function(stream, "%s not set (invalid value)\n", devname); - } - } else { - stream->write_function(stream, "Unknown Command [%s]\n", argv[0]); - } } done: @@ -2171,6 +2541,14 @@ SWITCH_STANDARD_API(pa_cmd) " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " "

" "\n" "" From e79174cacf6abb943fe34840a5261b940b281c91 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 19:32:14 -0600 Subject: [PATCH 12/28] fix regression from d72cde9b76a856cf002366300bea02c26db44ffb --- src/switch_core_session.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 4836aae73f..d2e28de523 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1865,6 +1865,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *ap SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg) { switch_event_t *execute_event; + char *ap, *arp; + + if (!arg && strstr(app, "::")) { + ap = switch_core_session_strdup(session, app); + app = ap; + + if ((arp = strstr(ap, "::"))) { + *arp = '\0'; + arg = arp + 2; + } + } if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); @@ -1894,6 +1905,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag switch_application_interface_t *application_interface; switch_status_t status = SWITCH_STATUS_SUCCESS; + if (!arg && strstr(app, "::")) { + return switch_core_session_execute_application_async(session, app, arg); + } + if (switch_channel_down(session->channel)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is hungup, aborting execution of application: %s\n", app); return SWITCH_STATUS_FALSE; From bdf678e401a8077aab06b9c04004c92ef6631e26 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 20:12:36 -0600 Subject: [PATCH 13/28] dont run execute_on_fsk when there was no data collected --- src/mod/applications/mod_fsk/mod_fsk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fsk/mod_fsk.c b/src/mod/applications/mod_fsk/mod_fsk.c index 9802353075..0291707c62 100644 --- a/src/mod/applications/mod_fsk/mod_fsk.c +++ b/src/mod/applications/mod_fsk/mod_fsk.c @@ -220,6 +220,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat char *sp; switch_event_t *event; const char *app_var; + int total = 0; switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA); @@ -255,6 +256,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat } if (varname && val) { + total++; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n", switch_channel_get_name(channel), varname, val); switch_channel_set_variable(channel, varname, val); @@ -270,7 +272,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat } } - if ((app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) { + if (total && (app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) { char *app_arg; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n", From dc436b82a52da05686ac178ad7854556e9688ed8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 3 Feb 2011 20:42:17 -0600 Subject: [PATCH 14/28] block control-z from fs cli and print a warning how to exit properly --- libs/esl/fs_cli.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 1e3bf04ca1..19e8d7f82a 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -8,6 +8,7 @@ #include #define CMD_BUFLEN 1024 +static int WARN_STOP = 0; #ifdef WIN32 #define strdup(src) _strdup(src) @@ -535,6 +536,13 @@ static BOOL console_readConsole(HANDLE conIn, char* buf, int len, int* pRed, int static void handle_SIGINT(int sig) { if (sig); + + WARN_STOP = 1; + + signal(SIGINT, handle_SIGINT); +#ifdef SIGTSTP + signal(SIGTSTP, handle_SIGINT); +#endif return; } @@ -581,6 +589,12 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) while(thread_running && handle->connected) { esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL); + + if (WARN_STOP) { + printf("Type control-D or /exit or /quit or /bye to exit.\n\n"); + WARN_STOP = 0; + } + if (status == ESL_FAIL) { esl_log(ESL_LOG_WARNING, "Disconnected.\n"); running = -1; thread_running = 0; @@ -1023,6 +1037,9 @@ int main(int argc, char *argv[]) } signal(SIGINT, handle_SIGINT); +#ifdef SIGTSTP + signal(SIGTSTP, handle_SIGINT); +#endif #ifdef SIGQUIT signal(SIGQUIT, handle_SIGQUIT); #endif From 2d190b37abe00999a2e76861b8c88f0053e0b78f Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 3 Feb 2011 23:46:19 -0600 Subject: [PATCH 15/28] fix iLBC under windows --- libs/ilbc/src/iLBC_decode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/ilbc/src/iLBC_decode.c b/libs/ilbc/src/iLBC_decode.c index fc46fe408c..9fc7a24bb4 100644 --- a/libs/ilbc/src/iLBC_decode.c +++ b/libs/ilbc/src/iLBC_decode.c @@ -47,7 +47,9 @@ { fld dbl frndint + fstp dbl } + return (long int) dbl; } #elif defined (_WIN64) #include From b6ac001276961761b14a89270da02498b4d3e740 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 08:44:11 -0600 Subject: [PATCH 16/28] fix regression from f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59 --- src/mod/applications/mod_dptools/mod_dptools.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 4be2a64f61..0b16492e14 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2887,7 +2887,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, switch_call_cause_t *cancel_cause) { switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params; - char *user = NULL, *domain = NULL; + char *user = NULL, *domain = NULL, *dup_domain = NULL; const char *dest = NULL; static switch_call_cause_t cause = SWITCH_CAUSE_NONE; unsigned int timelimit = 60; @@ -2908,7 +2908,8 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, if ((domain = strchr(user, '@'))) { *domain++ = '\0'; } else { - domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); + domain = switch_core_get_variable_dup("domain"); + dup_domain = domain; } if (!domain) { @@ -3115,6 +3116,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, } switch_safe_free(user); + switch_safe_free(dup_domain); return cause; } From 46f6c6e42d2775ccfecb8f445ebbaaf32ab34df7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 08:56:30 -0600 Subject: [PATCH 17/28] fix regression from f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59 --- src/mod/applications/mod_dptools/mod_dptools.c | 4 +++- .../dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 0b16492e14..f7bf86b4c7 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2774,7 +2774,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session switch_originate_flag_t myflags = SOF_NONE; char *cid_name_override = NULL; char *cid_num_override = NULL; - char *domain = NULL; + char *domain = NULL, *dup_domain = NULL; switch_channel_t *new_channel = NULL; unsigned int timelimit = 60; const char *skip, *var; @@ -2788,6 +2788,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session *domain++ = '\0'; } else { domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session)); + dup_domain = domain; } if (!domain) { @@ -2859,6 +2860,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session switch_safe_free(template); switch_safe_free(group); + switch_safe_free(dup_domain); if (cause == SWITCH_CAUSE_NONE) { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index 43534dadba..3bc5cb4a3d 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -309,11 +309,13 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, switch_call_cause_t *cancel_cause) { const char *profile; + char *dup_profile = NULL; if (session) { profile = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_profile"); } else { - profile = switch_core_get_variable_pdup("sip_profile", switch_core_session_get_pool(session)); + dup_profile = switch_core_get_variable_dup("sip_profile"); + profile = dup_profile; } if (zstr(profile)) { profile = "default"; @@ -323,6 +325,8 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session, UNPROTECT_INTERFACE(sip_endpoint_interface); + switch_safe_free(dup_profile); + return switch_core_session_outgoing_channel(session, var_event, "sofia", outbound_profile, new_session, pool, SOF_NONE, cancel_cause); } From 2ec2a9b0d335a8d6a30ab5a92448ac3ad63649ff Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 09:40:04 -0600 Subject: [PATCH 18/28] skip blocking writes on fs_cli to avoid backing up event socket --- libs/esl/fs_cli.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 19e8d7f82a..a70d63fab5 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -589,22 +589,36 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) while(thread_running && handle->connected) { esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL); - - if (WARN_STOP) { - printf("Type control-D or /exit or /quit or /bye to exit.\n\n"); - WARN_STOP = 0; - } + int aok = 1; if (status == ESL_FAIL) { - esl_log(ESL_LOG_WARNING, "Disconnected.\n"); + if (aok) esl_log(ESL_LOG_WARNING, "Disconnected.\n"); running = -1; thread_running = 0; } else if (status == ESL_SUCCESS) { +#ifndef WIN32 + fd_set can_write; + int fd; + struct timeval to; + + fd = fileno(stdout); + memset(&to, 0, sizeof(to)); + FD_ZERO(&can_write); + FD_SET(fd, &can_write); + to.tv_sec = 0; + to.tv_usec = 100000; + if (select(fd + 1, NULL, &can_write, NULL, &to) > 0) { + aok = FD_ISSET(fd, &can_write); + } else { + aok = 0; + } +#endif + if (handle->last_event) { const char *type = esl_event_get_header(handle->last_event, "content-type"); int known = 0; if (!esl_strlen_zero(type)) { - if (!strcasecmp(type, "log/data")) { + if (aok && !strcasecmp(type, "log/data")) { const char *userdata = esl_event_get_header(handle->last_event, "user-data"); if (esl_strlen_zero(userdata) || esl_strlen_zero(filter_uuid) || !strcasecmp(filter_uuid, userdata)) { @@ -631,7 +645,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) } else if (!strcasecmp(type, "text/disconnect-notice")) { running = -1; thread_running = 0; known++; - } else if (!strcasecmp(type, "text/event-plain")) { + } else if (aok && !strcasecmp(type, "text/event-plain")) { char *foo; esl_event_serialize(handle->last_ievent, &foo, ESL_FALSE); printf("RECV EVENT\n%s\n", foo); @@ -641,7 +655,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) } } - if (!known) { + if (aok && !known) { char *foo; printf("INCOMING DATA [%s]\n%s\n", type, handle->last_event->body ? handle->last_event->body : ""); esl_event_serialize(handle->last_event, &foo, ESL_FALSE); @@ -651,6 +665,11 @@ static void *msg_thread_run(esl_thread_t *me, void *obj) } } + if (WARN_STOP) { + if (aok) printf("Type control-D or /exit or /quit or /bye to exit.\n\n"); + WARN_STOP = 0; + } + usleep(1000); } From 36f6218b8bba3233cf3fb501b01a0288a08e9f00 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 10:58:26 -0600 Subject: [PATCH 19/28] add sanity check on jitterbuffer debug --- src/switch_rtp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index e8d7558bce..4df867aa64 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1875,6 +1875,10 @@ static void jb_logger(const char *file, const char *func, int line, int level, c SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name) { + if (!switch_rtp_ready(rtp_session)) { + return SWITCH_STATUS_FALSE; + } + stfu_n_debug(rtp_session->jb, name); stfu_global_set_logger(jb_logger); From e9e33f5160fb5272c4f912dac6a29415215bba1c Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 4 Feb 2011 12:48:07 -0600 Subject: [PATCH 20/28] FS-3033 VS2010 libportaudio project improvements for DirectX builds and switch to build DirectX by default --- Freeswitch.2010.sln | 24 ++-- .../build/msvc/portaudio.2010.vcxproj | 136 ++++-------------- 2 files changed, 43 insertions(+), 117 deletions(-) diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln index edee701d51..464cb2e273 100644 --- a/Freeswitch.2010.sln +++ b/Freeswitch.2010.sln @@ -1569,18 +1569,18 @@ Global {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64 Setup.ActiveCfg = Release DirectSound|x64 {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64 Setup.Build.0 = Release DirectSound|x64 {0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x86 Setup.ActiveCfg = Release DirectSound|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64 Setup.ActiveCfg = Debug|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x86 Setup.ActiveCfg = Debug|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release|Win32 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64 Setup.ActiveCfg = Release|x64 - {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x86 Setup.ActiveCfg = Release|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64 Setup.ActiveCfg = Debug DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x86 Setup.ActiveCfg = Debug DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release DirectSound|Win32 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64 Setup.ActiveCfg = Release DirectSound|x64 + {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x86 Setup.ActiveCfg = Release DirectSound|Win32 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|Win32.ActiveCfg = Release|x64 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.ActiveCfg = Release|x64 {08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.Build.0 = Release|x64 diff --git a/libs/portaudio/build/msvc/portaudio.2010.vcxproj b/libs/portaudio/build/msvc/portaudio.2010.vcxproj index b4eca56713..10b4c25fd9 100644 --- a/libs/portaudio/build/msvc/portaudio.2010.vcxproj +++ b/libs/portaudio/build/msvc/portaudio.2010.vcxproj @@ -41,11 +41,11 @@ - DynamicLibrary + StaticLibrary false - DynamicLibrary + StaticLibrary false @@ -57,11 +57,11 @@ false - DynamicLibrary + StaticLibrary false - DynamicLibrary + StaticLibrary false @@ -77,9 +77,11 @@ + + @@ -92,10 +94,12 @@ + + @@ -110,18 +114,6 @@ <_ProjectFileVersion>10.0.30319.1 - $(Configuration)\ - $(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Configuration)\ - $(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false @@ -231,45 +223,23 @@ true true Win32 - .\Debug_x86/portaudio.tlb - - Disabled ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) + WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL - $(Platform)\$(Configuration)/portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true - ProgramDatabase _DEBUG;%(PreprocessorDefinitions) 0x0409 - - ksuser.lib;%(AdditionalDependencies) - $(Platform)\$(Configuration)\portaudio_x86.dll - true - .\portaudio.def - true - $(Platform)\$(Configuration)\portaudio_x86.pdb - false - - - $(Platform)\$(Configuration)\portaudio_x86.lib - MachineX86 - true - $(Platform)\$(Configuration)\portaudio.bsc @@ -278,45 +248,23 @@ true true X64 - .\Debug_x86/portaudio.tlb - - Disabled ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) + WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL - $(Platform)\$(Configuration)\portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true - ProgramDatabase _DEBUG;%(PreprocessorDefinitions) 0x0409 - - ksuser.lib;%(AdditionalDependencies) - $(Platform)\$(Configuration)\portaudio_x64.dll - true - .\portaudio.def - true - $(Platform)\$(Configuration)/portaudio_x64.pdb - false - - - $(Platform)\$(Configuration)\portaudio_x64.lib - MachineX64 - true - $(Platform)\$(Configuration)/portaudio_x64.bsc @@ -325,22 +273,15 @@ true true Win32 - .\Release_x86/portaudio.tlb - - MaxSpeed - OnlyExplicitInline + Default ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;%(PreprocessorDefinitions) + WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;%(PreprocessorDefinitions) true MultiThreadedDLL true - $(Platform)\$(Configuration)/portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true @@ -348,20 +289,8 @@ NDEBUG;%(PreprocessorDefinitions) 0x0409 - - $(Platform)\$(Configuration)\portaudio_x86.dll - true - .\portaudio.def - $(Platform)\$(Configuration)\portaudio_x86.pdb - false - - - $(Platform)\$(Configuration)\portaudio_x86.lib - MachineX86 - true - $(Platform)\$(Configuration)\portaudio.bsc @@ -370,22 +299,15 @@ true true X64 - .\Release_x86/portaudio.tlb - - MaxSpeed - OnlyExplicitInline - ..\..\src\common;..\..\include;.\;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + Default + ..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;%(PreprocessorDefinitions) true MultiThreadedDLL true - $(Platform)\$(Configuration)\portaudio.pch - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ Level3 true @@ -393,20 +315,8 @@ NDEBUG;%(PreprocessorDefinitions) 0x0409 - - $(Platform)\$(Configuration)\portaudio_x64.dll - true - .\portaudio.def - $(Platform)\$(Configuration)/portaudio_x64.pdb - false - - - $(Platform)\$(Configuration)/portaudio_x64.lib - MachineX64 - true - $(Platform)\$(Configuration)\portaudio_x64.bsc @@ -594,6 +504,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -605,6 +516,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -618,6 +530,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -629,6 +542,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -642,6 +556,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -653,6 +568,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -666,6 +582,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -677,6 +594,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -690,6 +608,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -701,6 +620,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -714,6 +634,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -725,6 +646,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -738,6 +660,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -749,6 +672,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -762,6 +686,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true @@ -773,6 +698,7 @@ true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + true ..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true From f4481b05ab8ae1faf6eedb438085e688371e79c6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 13:05:48 -0600 Subject: [PATCH 21/28] fix sql err --- 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 a38a61eab8..2313cb7a1a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2576,7 +2576,7 @@ uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *cont char buf[32] = ""; char *sql; - sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact_str='%q'", profile->name, contact_str); + sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact='%q'", profile->name, contact_str); sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); switch_safe_free(sql); From b8b7266abb7a6c081ad1e1531aea69daf5d7509c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 13:11:31 -0600 Subject: [PATCH 22/28] add default to conf to demonstrate min-idle-cpu --- conf/autoload_configs/switch.conf.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index 8342f120fc..32cb76f08a 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -23,6 +23,10 @@ + + + + + diff --git a/src/mod/codecs/mod_opus/Makefile b/src/mod/codecs/mod_opus/Makefile new file mode 100644 index 0000000000..a34695678b --- /dev/null +++ b/src/mod/codecs/mod_opus/Makefile @@ -0,0 +1,28 @@ +BASE=../../../.. + +OPUS=opus-0.9.0 + +OPUS_DIR=$(switch_srcdir)/libs/$(OPUS) +OPUS_BUILDDIR=$(switch_builddir)/libs/$(OPUS) +LOCAL_CFLAGS=-I$(OPUS_DIR)/src -g -O2 + +IETF_LA=$(OPUS_BUILDDIR)/src/.libs/libietfcodec.a +CELT_LA=$(OPUS_BUILDDIR)/celt/libcelt/.libs/libcelt0.a +SILK_LA=$(OPUS_BUILDDIR)/silk/.libs/libSKP_SILK_SDK.a + +LOCAL_LIBADD=$(IETF_LA) $(CELT_LA) $(SILK_LA) -lm -lz + +include $(BASE)/build/modmake.rules + +$(OPUS_DIR): + $(GETLIB) $(OPUS).tar.gz + +$(OPUS_BUILDDIR)/Makefile: $(OPUS_DIR) + mkdir -p $(OPUS_BUILDDIR) + cd $(OPUS_BUILDDIR) && $(DEFAULT_VARS) $(OPUS_DIR)/configure --disable-shared --with-pic --srcdir=$(OPUS_DIR) + $(TOUCH_TARGET) + +$(IETF_LA): $(OPUS_BUILDDIR)/Makefile + cd $(OPUS_BUILDDIR) && $(MAKE) + $(TOUCH_TARGET) + diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c new file mode 100644 index 0000000000..341254fe0c --- /dev/null +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -0,0 +1,209 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Brian K. West + * + * mod_opus.c -- The OPUS ultra-low delay audio codec (http://www.opus-codec.org/) + * + */ + +#include "switch.h" +#include "opus.h" + + +SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load); +SWITCH_MODULE_DEFINITION(mod_opus, mod_opus_load, NULL, NULL); + +struct opus_context { + OpusEncoder *encoder_object; + OpusDecoder *decoder_object; + int frame_size; +}; + +static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) +{ + struct opus_context *context = NULL; + int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); + int decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + + if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { + return SWITCH_STATUS_FALSE; + } + + context->frame_size = codec->implementation->samples_per_packet; + + if (encoding) { + /* come up with a way to specify these */ + int bitrate_bps = codec->implementation->bits_per_second; + int mode = MODE_HYBRID; + int use_vbr = 1; + int complexity = 10; + int use_inbandfec = 1; + int use_dtx = 1; + int bandwidth = BANDWIDTH_FULLBAND; + + context->encoder_object = opus_encoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels); + + opus_encoder_ctl(context->encoder_object, OPUS_SET_MODE(mode)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(bandwidth)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR_FLAG(use_vbr)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX_FLAG(use_dtx)); + + } + + if (decoding) { + context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels); + } + + codec->private_info = context; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_opus_destroy(switch_codec_t *codec) +{ + codec->private_info = NULL; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_opus_encode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *decoded_data, + uint32_t decoded_data_len, + uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, + unsigned int *flag) +{ + struct opus_context *context = codec->private_info; + int bytes = 0; + int len = (int) *encoded_data_len; + + if (!context) { + return SWITCH_STATUS_FALSE; + } + + if (len > 1275) len = 1275; + + bytes = opus_encode(context->encoder_object, (void *) decoded_data, decoded_data_len / 2, (unsigned char *) encoded_data, len); + + if (bytes > 0) { + *encoded_data_len = (uint32_t) bytes; + return SWITCH_STATUS_SUCCESS; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error!\n"); + return SWITCH_STATUS_GENERR; +} + +static switch_status_t switch_opus_decode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *encoded_data, + uint32_t encoded_data_len, + uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, + unsigned int *flag) +{ + struct opus_context *context = codec->private_info; + int samples = 0; + + if (!context) { + return SWITCH_STATUS_FALSE; + } + + samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, *decoded_data_len); + + if (samples < 0) { + return SWITCH_STATUS_GENERR; + } + + *decoded_data_len = samples * 2; + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) +{ + switch_codec_interface_t *codec_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA)"); + + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 115, /* the IANA code number */ + "OPUS", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + 48000, /* actual samples transferred per second */ + 32000, /* bits transferred per second */ + 10000, /* number of microseconds per frame */ + 80, /* number of samples per frame */ + 960, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + + + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 115, /* the IANA code number */ + "OPUS", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + 48000, /* actual samples transferred per second */ + 32000, /* bits transferred per second */ + 20000, /* number of microseconds per frame */ + 160, /* number of samples per frame */ + 1920, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + + + + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ From e7d68a79dc7838d74e7b8985494dcde532910d32 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 16:02:31 -0600 Subject: [PATCH 26/28] change signalling name to avoid polluting the namespace before its ready --- src/mod/codecs/mod_opus/mod_opus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 341254fe0c..ddb5a7ac83 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -151,11 +151,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); - SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA)"); + SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)"); switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 115, /* the IANA code number */ - "OPUS", /* the IANA code name */ + "Opus-0.9.0",/* the IANA code name */ NULL, /* default fmtp to send (can be overridden by the init function) */ 48000, /* samples transferred per second */ 48000, /* actual samples transferred per second */ @@ -174,7 +174,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 115, /* the IANA code number */ - "OPUS", /* the IANA code name */ + "Opus-0.9.0", /* the IANA code name */ NULL, /* default fmtp to send (can be overridden by the init function) */ 48000, /* samples transferred per second */ 48000, /* actual samples transferred per second */ From 998a04d2cfa361a4d600175809d5fef02374c720 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 16:25:00 -0600 Subject: [PATCH 27/28] add 10 20 and 40ms --- src/mod/codecs/mod_opus/mod_opus.c | 69 +++++++++++++----------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index ddb5a7ac83..0234ed8541 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -147,52 +147,43 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) { switch_codec_interface_t *codec_interface; + int samples = 80; + int bytes = 960; + int mss = 10000; + int x = 0; + int rate = 48000; + int bits = 32000; /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)"); - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 115, /* the IANA code number */ - "Opus-0.9.0",/* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 48000, /* samples transferred per second */ - 48000, /* actual samples transferred per second */ - 32000, /* bits transferred per second */ - 10000, /* number of microseconds per frame */ - 80, /* number of samples per frame */ - 960, /* number of bytes per frame decompressed */ - 0, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet */ - switch_opus_init, /* function to initialize a codec handle using this implementation */ - switch_opus_encode, /* function to encode raw data into encoded data */ - switch_opus_decode, /* function to decode encoded data into raw data */ - switch_opus_destroy); /* deinitalize a codec handle using this implementation */ - - - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 115, /* the IANA code number */ - "Opus-0.9.0", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 48000, /* samples transferred per second */ - 48000, /* actual samples transferred per second */ - 32000, /* bits transferred per second */ - 20000, /* number of microseconds per frame */ - 160, /* number of samples per frame */ - 1920, /* number of bytes per frame decompressed */ - 0, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet */ - switch_opus_init, /* function to initialize a codec handle using this implementation */ - switch_opus_encode, /* function to encode raw data into encoded data */ - switch_opus_decode, /* function to decode encoded data into raw data */ - switch_opus_destroy); /* deinitalize a codec handle using this implementation */ - - - + for (x = 0; x < 3; x++) { + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 115, /* the IANA code number */ + "Opus-0.9.0",/* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + rate, /* samples transferred per second */ + rate, /* actual samples transferred per second */ + bits, /* bits transferred per second */ + mss, /* number of microseconds per frame */ + samples, /* number of samples per frame */ + bytes, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + + bytes *= 2; + samples *= 2; + mss *= 2; + } + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } From 294436486302d0547b34ba26e5fa402c4ebaa58f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Feb 2011 16:53:38 -0600 Subject: [PATCH 28/28] nm 40 doesn't work yet --- src/mod/codecs/mod_opus/mod_opus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 0234ed8541..b9a31208a4 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -159,7 +159,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)"); - for (x = 0; x < 3; x++) { + for (x = 0; x < 2; x++) { switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 115, /* the IANA code number */ "Opus-0.9.0",/* the IANA code name */