diff --git a/conf/dialplan/default.xml b/conf/dialplan/default.xml
index aeff57d407..f03fdad84e 100644
--- a/conf/dialplan/default.xml
+++ b/conf/dialplan/default.xml
@@ -117,7 +117,7 @@
-
+
diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml
index 1d565081d9..65e5c2573d 100644
--- a/docs/phrase/phrase_en.xml
+++ b/docs/phrase/phrase_en.xml
@@ -55,7 +55,7 @@
-
+
@@ -285,7 +285,7 @@
-
+
diff --git a/libs/freetdm/src/ftdm_cpu_monitor.c b/libs/freetdm/src/ftdm_cpu_monitor.c
index 7c79a2e65c..b02f5a0d1f 100644
--- a/libs/freetdm/src/ftdm_cpu_monitor.c
+++ b/libs/freetdm/src/ftdm_cpu_monitor.c
@@ -61,6 +61,9 @@ struct ftdm_cpu_monitor_stats
double last_percentage_of_idle_time;
#ifdef __linux__
+ /* the cpu feature gets disabled on errors */
+ int disabled;
+
/* all of these are the Linux jiffies last retrieved count */
unsigned long long last_user_time;
unsigned long long last_system_time;
@@ -97,15 +100,23 @@ static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
{
// the output of proc should not change that often from one kernel to other
// see fs/proc/proc_misc.c or fs/proc/stat.c in the Linux kernel for more details
-// also man 5 proc is useful
-#define CPU_ELEMENTS 8 // change this if you change the format string
-#define CPU_INFO_FORMAT "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu"
+// also man 5 proc is useful.
+#define CPU_ELEMENTS_1 7 // change this if you change the format string
+#define CPU_INFO_FORMAT_1 "cpu %llu %llu %llu %llu %llu %llu %llu"
+
+#define CPU_ELEMENTS_2 8 // change this if you change the format string
+#define CPU_INFO_FORMAT_2 "cpu %llu %llu %llu %llu %llu %llu %llu %llu"
+
+#define CPU_ELEMENTS_3 9 // change this if you change the format string
+#define CPU_INFO_FORMAT_3 "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu"
+
static const char procfile[] = "/proc/stat";
int rc = 0;
int myerrno = 0;
int elements = 0;
const char *cpustr = NULL;
char statbuff[1024];
+ unsigned long long guest = 0;
if (!p->initd) {
p->procfd = open(procfile, O_RDONLY, 0);
@@ -131,12 +142,26 @@ static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
return FTDM_FAIL;
}
- elements = sscanf(cpustr, CPU_INFO_FORMAT, user, nice, system, idle, iowait, irq, softirq, steal);
- if (elements != CPU_ELEMENTS) {
- ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: expected %d elements, but just found %d\n", CPU_ELEMENTS, elements);
- return FTDM_FAIL;
+ /* test each of the known formats starting from the bigger one */
+ elements = sscanf(cpustr, CPU_INFO_FORMAT_3, user, nice, system, idle, iowait, irq, softirq, steal, &guest);
+ if (elements == CPU_ELEMENTS_3) {
+ user += guest; /* guest operating system's run in user space */
+ return FTDM_SUCCESS;
}
- return FTDM_SUCCESS;
+
+ elements = sscanf(cpustr, CPU_INFO_FORMAT_2, user, nice, system, idle, iowait, irq, softirq, steal);
+ if (elements == CPU_ELEMENTS_2) {
+ return FTDM_SUCCESS;
+ }
+
+ elements = sscanf(cpustr, CPU_INFO_FORMAT_1, user, nice, system, idle, iowait, irq, softirq);
+ if (elements == CPU_ELEMENTS_1) {
+ *steal = 0;
+ return FTDM_SUCCESS;
+ }
+
+ ftdm_log(FTDM_LOG_ERROR, "Unexpected format for Linux proc cpu statistics:%s\n", cpustr);
+ return FTDM_FAIL;
}
#endif
@@ -146,8 +171,13 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor
unsigned long long user, nice, system, idle, iowait, irq, softirq, steal;
unsigned long long usertime, kerneltime, idletime, totaltime, halftime;
+ *idle_percentage = 100.0;
+ if (p->disabled) {
+ return FTDM_FAIL;
+ }
if (ftdm_cpu_read_stats(p, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal)) {
- ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics\n");
+ ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics - disabling cpu monitor\n");
+ p->disabled = 1;
return FTDM_FAIL;
}
@@ -243,7 +273,8 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_
#else
/* Unsupported */
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
-{
+{'
+ *idle_percentate = 100.0;
return FTDM_FAIL;
}
#endif
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index 3e37c6930f..c62bcd5d5b 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -3350,7 +3350,7 @@ SWITCH_STANDARD_API(show_function)
}
} else if (!strcasecmp(command, "distinct_channels")) {
sprintf(sql, "select * from channels left join calls on "
- "channels.uuid=calls.caller_uuid where channels.hostname='%s' channels.uuid not in (select callee_uuid from calls where hostname='%s') order by created_epoch", hostname, hostname);
+ "channels.uuid=calls.caller_uuid where channels.hostname='%s' and channels.uuid not in (select callee_uuid from calls where hostname='%s') order by created_epoch", hostname, hostname);
if (argv[2] && !strcasecmp(argv[1], "as")) {
as = argv[2];
}
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index c85e6b6ef0..c0cbc51d20 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -3412,7 +3412,7 @@ static switch_status_t conf_api_sub_volume_in(conference_member_t *member, switc
data && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_member_data(member, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-in-member");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%u", member->volume_in_level);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%d", member->volume_in_level);
switch_event_fire(&event);
}
@@ -3439,7 +3439,7 @@ static switch_status_t conf_api_sub_volume_out(conference_member_t *member, swit
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_member_data(member, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "volume-out-member");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%u", member->volume_out_level);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Volume-Level", "%d", member->volume_out_level);
switch_event_fire(&event);
}
diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c
index 700446f03e..38cf734993 100644
--- a/src/mod/applications/mod_lcr/mod_lcr.c
+++ b/src/mod/applications/mod_lcr/mod_lcr.c
@@ -298,6 +298,10 @@ static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, ch
switch_core_sprintf(pool, "[lcr_carrier=%s,lcr_rate=%s%s%s%s%s]%s%s%s%s%s", cur_route->carrier_name, cur_route->rate_str, user_rate, codec, cid,
header, cur_route->gw_prefix, cur_route->prefix, destination_number, cur_route->suffix, cur_route->gw_suffix);
+ if (session && (switch_string_var_check_const(data) || switch_string_has_escaped_data(data))) {
+ data = switch_channel_expand_variables(switch_core_session_get_channel(session), data);
+ }
+
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Returning Dialstring %s\n", data);
return data;
}
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 6657cfd2c2..0f0abfa09a 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -242,7 +242,9 @@ char *generate_pai_str(switch_core_session_t *session)
}
if (zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_number"))) &&
- zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_number")))) {
+ zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_number"))) &&
+ zstr((callee_number = switch_channel_get_variable(tech_pvt->channel, "callee_id_number")))) {
+
callee_number = tech_pvt->caller_profile->destination_number;
}
diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c
index c9cc932928..80f7d248ee 100644
--- a/src/mod/endpoints/mod_sofia/sofia_presence.c
+++ b/src/mod/endpoints/mod_sofia/sofia_presence.c
@@ -77,6 +77,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
switch_status_t status = SWITCH_STATUS_FALSE;
const char *ct = "text/html";
sofia_destination_t *dst = NULL;
+ char *to_uri = NULL;
if (!to) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
@@ -98,9 +99,17 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
user = prof;
prof = NULL;
}
+
+ if (!strncasecmp(user, "sip:", 4)) {
+ to_uri = user;
+ }
if ((host = strchr(user, '@'))) {
- *host++ = '\0';
+ if (!to_uri) {
+ *host++ = '\0';
+ } else {
+ host++;
+ }
if (!prof)
prof = host;
}
@@ -118,7 +127,8 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
host = prof;
}
}
- if (!sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
+
+ if (!to_uri && !sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find user. [%s][%s]\n", user, host);
goto end;
}
@@ -152,7 +162,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
switch_safe_free(fp);
}
- if (!(dst = sofia_glue_get_destination(buf))) {
+ if (!(dst = sofia_glue_get_destination(to_uri ? to_uri : buf))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
goto end;
}
@@ -162,7 +172,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
status = SWITCH_STATUS_SUCCESS;
/* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
- SIPTAG_FROM_STR(from), NUTAG_URL(contact), SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END());
+ SIPTAG_FROM_STR(from), TAG_IF(contact, NUTAG_URL(contact)), SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END());
nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END());