diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml
index bfbc344ba7..0477623624 100644
--- a/conf/freeswitch.xml
+++ b/conf/freeswitch.xml
@@ -113,8 +113,8 @@
-
-
+
+
@@ -268,10 +268,12 @@
-
-
-
-
+
+
+
+
+
+
@@ -296,7 +298,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c
index 8a4a8e9b59..656bf84521 100644
--- a/libs/libdingaling/src/libdingaling.c
+++ b/libs/libdingaling/src/libdingaling.c
@@ -712,7 +712,7 @@ static int on_presence(void *user_data, ikspak *pak)
if (!type || (type && strcasecmp(type, "probe"))) {
if (handle->session_callback) {
- handle->session_callback(handle, NULL, signal, to, from, status ? status : "n/a", show ? show : "n/a");
+ handle->session_callback(handle, NULL, signal, to, id, status ? status : "n/a", show ? show : "n/a");
}
}
@@ -720,7 +720,7 @@ static int on_presence(void *user_data, ikspak *pak)
return IKS_FILTER_EAT;
}
-static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message)
+static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message)
{
iks *pres;
char buf[512];
@@ -743,21 +743,28 @@ static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type,
iks_insert_attrib(pres, "type", type);
}
-
-
- if (message) {
- if ((tag = iks_insert (pres, "status"))) {
- iks_insert_cdata(tag, message ? message : "", 0);
- if ((tag = iks_insert(pres, "c"))) {
- iks_insert_attrib(tag, "node", "http://www.freeswitch.org/xmpp/client/caps");
- iks_insert_attrib(tag, "ver", "1.0.0.1");
- iks_insert_attrib(tag, "ext", "sidebar voice-v1");
- iks_insert_attrib(tag, "client", "libdingaling2");
- iks_insert_attrib(tag, "xmlns", "http://jabber.org/protocol/caps");
- }
+ if (rpid) {
+ if ((tag = iks_insert (pres, "show"))) {
+ iks_insert_cdata(tag, rpid, 0);
}
}
-
+
+ if (message) {
+ if ((tag = iks_insert (pres, "status"))) {
+ iks_insert_cdata(tag, message, 0);
+ }
+ }
+
+ if (message || rpid) {
+ if ((tag = iks_insert(pres, "c"))) {
+ iks_insert_attrib(tag, "node", "http://www.freeswitch.org/xmpp/client/caps");
+ iks_insert_attrib(tag, "ver", "1.0.0.1");
+ iks_insert_attrib(tag, "ext", "sidebar voice-v1");
+ iks_insert_attrib(tag, "client", "libdingaling");
+ iks_insert_attrib(tag, "xmlns", "http://jabber.org/protocol/caps");
+ }
+ }
+
apr_queue_push(handle->queue, pres);
}
}
@@ -1559,9 +1566,9 @@ void *ldl_handle_get_private(ldl_handle_t *handle)
return handle->private_info;
}
-void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message)
+void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message)
{
- do_presence(handle, from, to, type, message);
+ do_presence(handle, from, to, type, rpid, message);
}
void ldl_handle_send_msg(ldl_handle_t *handle, char *from, char *to, char *subject, char *body)
diff --git a/libs/libdingaling/src/libdingaling.h b/libs/libdingaling/src/libdingaling.h
index c71bb9ed64..88b9ec9303 100644
--- a/libs/libdingaling/src/libdingaling.h
+++ b/libs/libdingaling/src/libdingaling.h
@@ -369,9 +369,10 @@ void ldl_session_send_msg(ldl_session_t *session, char *subject, char *body);
\param from the from address
\param to the to address
\param type the type of presence
+ \param rpid data for the icon
\param message a status message
*/
-void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message);
+void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message);
/*!
\brief Send a message
diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
index d0f99e8df1..1a83259825 100644
--- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
+++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
@@ -94,6 +94,11 @@ static void perform_substitution(pcre *re, int match_count, char *data, char *fi
for (x = 0; x < (len-1) && x < strlen(data);) {
if (data[x] == '$') {
x++;
+
+ if (!(data[x] > 47 && data[x] < 58)) {
+ substituted[y++] = data[x-1];
+ continue;
+ }
while (data[x] > 47 && data[x] < 58) {
index[z++] = data[x];
diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c
index 8411fd5ba5..382f884936 100644
--- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c
+++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c
@@ -47,7 +47,9 @@ static switch_memory_pool_t *module_pool = NULL;
static char sub_sql[] =
"CREATE TABLE subscriptions (\n"
" sub_from VARCHAR(255),\n"
-" sub_to VARCHAR(255)\n"
+" sub_to VARCHAR(255),\n"
+" show VARCHAR(255),\n"
+" status VARCHAR(255)\n"
");\n";
@@ -186,6 +188,38 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
static ldl_status handle_response(ldl_handle_t *handle, char *id);
static switch_status_t load_config(void);
+static char *translate_rpid(char *in, char *ext)
+{
+ char *r = NULL;
+
+ if (in && (strstr(in, "null") || strstr(in, "NULL"))) {
+ in = NULL;
+ }
+
+ if (!in) {
+ in = ext;
+ }
+
+ if (!in) {
+ return NULL;
+ }
+
+ if (!strcasecmp(in, "busy")) {
+ r = "dnd";
+ }
+
+ if (!strcasecmp(in, "unavailable")) {
+ r = "dnd";
+ }
+
+ if (ext && !strcasecmp(ext, "idle")) {
+ r = "away";
+ } else if (ext && !strcasecmp(ext, "away")) {
+ r = "away";
+ }
+
+ return r;
+}
static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
{
@@ -194,16 +228,17 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
char *sub_from = argv[0];
char *sub_to = argv[1];
char *type = argv[2];
- char *show = argv[3];
+ char *rpid = argv[3];
+ char *status = argv[4];
if (switch_strlen_zero(type)) {
type = NULL;
} else if (!strcasecmp(type, "unavailable")) {
- show = NULL;
+ status = NULL;
}
-
-
- ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, show);
+ rpid = translate_rpid(rpid, status);
+
+ ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, rpid, status);
return 0;
}
@@ -215,9 +250,17 @@ static int rost_callback(void *pArg, int argc, char **argv, char **columnNames)
char *sub_from = argv[0];
char *sub_to = argv[1];
char *show = argv[2];
+ char *status = argv[3];
+ if (!strcasecmp(status, "n/a")) {
+ if (!strcasecmp(show, "dnd")) {
+ status = "Busy";
+ } else if (!strcasecmp(show, "away")) {
+ status = "Idle";
+ }
+ }
- ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show);
+ ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show, status);
return 0;
}
@@ -229,22 +272,17 @@ static void pres_event_handler(switch_event_t *event)
void *val;
char *from = switch_event_get_header(event, "from");
char *status= switch_event_get_header(event, "status");
- char *show= switch_event_get_header(event, "show");
- char *type = NULL;
+ char *rpid = switch_event_get_header(event, "rpid");
+ char *type = switch_event_get_header(event, "event_subtype");
char *sql;
switch_core_db_t *db;
char *p;
if (status && !strcasecmp(status, "n/a")) {
- status = show;
- if (status && !strcasecmp(status, "n/a")) {
- status = NULL;
- }
+ status = NULL;
}
-
-
switch(event->event_id) {
case SWITCH_EVENT_PRESENCE_IN:
if (!status) {
@@ -259,12 +297,12 @@ static void pres_event_handler(switch_event_t *event)
}
-
if ((p = strchr(from, '/'))) {
*p = '\0';
}
- sql = switch_mprintf("select *,'%q','%q' from subscriptions where sub_to='%q'", type ? type : "", status ? status : "unavailable", from);
+ sql = switch_mprintf("select sub_from, sub_to,'%q','%q','%q' from subscriptions where sub_to='%q'",
+ type ? type : "", rpid, status ? status : "unavailable", from);
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
char *errmsg;
switch_hash_this(hi, NULL, NULL, &val);
@@ -326,7 +364,7 @@ static switch_status_t chat_send(char *from, char *to, char *subject, char *body
static void roster_event_handler(switch_event_t *event)
{
char *status= switch_event_get_header(event, "status");
- char *show= switch_event_get_header(event, "show");
+ char *from= switch_event_get_header(event, "from");
char *event_type = switch_event_get_header(event, "event_type");
struct mdl_profile *profile = NULL;
switch_hash_index_t *hi;
@@ -334,19 +372,19 @@ static void roster_event_handler(switch_event_t *event)
char *sql;
switch_core_db_t *db;
-
if (status && !strcasecmp(status, "n/a")) {
- status = show;
- if (status && !strcasecmp(status, "n/a")) {
- status = NULL;
- }
+ status = NULL;
}
if (switch_strlen_zero(event_type)) {
event_type="presence";
}
- sql = switch_mprintf("select *,'%q' from subscriptions", show ? show : "unavilable");
+ if (from) {
+ sql = switch_mprintf("select *,'%q' from subscriptions where sub_from='%q'", status ? status : "", from);
+ } else {
+ sql = switch_mprintf("select *,'%q' from subscriptions", status ? status : "");
+ }
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
char *errmsg;
@@ -457,6 +495,12 @@ static void *SWITCH_THREAD_FUNC handle_thread_run(switch_thread_t *thread, void
{
ldl_handle_t *handle = obj;
struct mdl_profile *profile = NULL;
+ switch_event_t *event;
+
+ if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
+ switch_event_fire(&event);
+ }
profile = ldl_handle_get_private(handle);
globals.handles++;
@@ -1307,7 +1351,7 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session,
snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", u, profile_name);
user = ubuf;
} else {
- user = mdl_profile->login;
+ user = (char *) modname;
}
if ((mdl_profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
@@ -1554,25 +1598,6 @@ static void set_profile_val(struct mdl_profile *profile, char *var, char *val)
if (switch_true(val)) {
profile->user_flags |= LDL_FLAG_TLS;
}
- } else if (!strcasecmp(var, "component")) {
- if (switch_true(val)) {
- char dbname[256];
- switch_core_db_t *db;
-
- profile->user_flags |= LDL_FLAG_COMPONENT;
- switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool);
- snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name);
- profile->dbname = switch_core_strdup(module_pool, dbname);
-
- if ((db = switch_core_db_open_file(profile->dbname))) {
- switch_core_db_test_reactive(db, "select * from subscriptions", sub_sql);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
- return;
- }
- switch_core_db_close(db);
-
- }
} else if (!strcasecmp(var, "sasl")) {
if (!strcasecmp(val, "plain")) {
profile->user_flags |= LDL_FLAG_SASL_PLAIN;
@@ -1669,6 +1694,7 @@ static switch_status_t dl_login(char *arg, switch_core_session_t *session, switc
}
}
+
if (profile && init_profile(profile, 1) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "OK\n");
} else {
@@ -1715,7 +1741,14 @@ static switch_status_t load_config(void)
}
}
- for (xmlint = switch_xml_child(cfg, "interface"); xmlint; xmlint = xmlint->next) {
+ if (!(xmlint = switch_xml_child(cfg, "profile"))) {
+ if ((xmlint = switch_xml_child(cfg, "interface"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "!!!!!!! DEPRICATION WARNING 'interface' is now 'profile' !!!!!!!\n");
+ }
+ }
+
+ for (; xmlint; xmlint = xmlint->next) {
+ char *type = (char *) switch_xml_attr_soft(xmlint, "type");
for (param = switch_xml_child(xmlint, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
@@ -1732,6 +1765,31 @@ static switch_status_t load_config(void)
set_profile_val(profile, var, val);
}
+
+ if (type && !strcasecmp(type, "component")) {
+ char dbname[256];
+ switch_core_db_t *db;
+
+ if (!profile->login && profile->name) {
+ profile->login = switch_core_strdup(module_pool, profile->name);
+ }
+
+ switch_set_flag(profile, TFLAG_AUTO);
+ profile->message = "";
+ profile->user_flags |= LDL_FLAG_COMPONENT;
+ switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool);
+ snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name);
+ profile->dbname = switch_core_strdup(module_pool, dbname);
+
+ if ((db = switch_core_db_open_file(profile->dbname))) {
+ switch_core_db_test_reactive(db, "select * from subscriptions", sub_sql);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
+ continue;
+ }
+ switch_core_db_close(db);
+ }
+
if (profile) {
init_profile(profile, switch_test_flag(profile, TFLAG_AUTO) ? 1 : 0);
profile = NULL;
@@ -1815,7 +1873,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
case LDL_SIGNAL_SUBSCRIBE:
if ((profile->user_flags & LDL_FLAG_COMPONENT)) {
- if ((sql = switch_mprintf("insert into subscriptions values('%q','%q')", from, to))) {
+ if ((sql = switch_mprintf("insert into subscriptions values('%q','%q','%q','%q')", from, to, msg, subject))) {
execute_sql(profile->dbname, sql, profile->mutex);
switch_core_db_free(sql);
}
@@ -1829,17 +1887,30 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
}
break;
case LDL_SIGNAL_PRESENCE_IN:
+
+ if ((sql = switch_mprintf("update subscriptions set show='%q', status='%q' where sub_from='%q'", msg, subject, from))) {
+ execute_sql(profile->dbname, sql, profile->mutex);
+ switch_core_db_free(sql);
+ }
+
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", msg);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", subject);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", msg);
switch_event_fire(&event);
}
break;
+
case LDL_SIGNAL_PRESENCE_OUT:
+
+ if ((sql = switch_mprintf("update subscriptions set show='%q', status='%q' where sub_from='%q'", msg, subject, from))) {
+ execute_sql(profile->dbname, sql, profile->mutex);
+ switch_core_db_free(sql);
+ }
+
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 6c39a07a97..0ad54eeb58 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -43,9 +43,6 @@
struct outbound_reg;
typedef struct outbound_reg outbound_reg_t;
-struct sip_presence;
-typedef struct sip_presence sip_presence_t;
-
struct sofia_profile;
typedef struct sofia_profile sofia_profile_t;
#define NUA_MAGIC_T sofia_profile_t
@@ -53,7 +50,6 @@ typedef struct sofia_profile sofia_profile_t;
struct sofia_private {
switch_core_session_t *session;
outbound_reg_t *oreg;
- sip_presence_t *presence;
};
typedef struct sofia_private sofia_private_t;
@@ -86,6 +82,7 @@ static char reg_sql[] =
" host VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
" status VARCHAR(255),\n"
+" rpid VARCHAR(255),\n"
" expires INTEGER(8)"
");\n";
@@ -211,13 +208,6 @@ struct outbound_reg {
};
-struct sip_presence {
- sofia_private_t sofia_private;
- nua_handle_t *nh;
- sofia_profile_t *profile;
-};
-
-
struct sofia_profile {
int debug;
char *name;
@@ -251,7 +241,6 @@ struct sofia_profile {
switch_mutex_t *ireg_mutex;
switch_mutex_t *oreg_mutex;
outbound_reg_t *registrations;
- sip_presence_t *presence;
su_home_t *home;
switch_hash_t *profile_hash;
switch_hash_t *chat_hash;
@@ -2673,16 +2662,14 @@ static uint8_t handle_register(nua_t *nua,
switch_event_t *s_event;
char *from_user = (char *) from->a_url->url_user;
char *from_host = (char *) from->a_url->url_host;
- char contact_str[1025] = "";
+ char contact_str[1024] = "";
char buf[512];
char *passwd = NULL;
uint8_t stale = 0, ret = 0, forbidden = 0;
auth_res_t auth_res;
long exptime = 60;
switch_event_t *event;
-
-
-
+ char *rpid = "unknown";
if (sip->sip_contact) {
char *port = (char *) contact->m_url->url_port;
@@ -2824,76 +2811,84 @@ static uint8_t handle_register(nua_t *nua,
}
reg:
- if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
- sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Registered', %ld)",
- from_user,
- from_host,
- contact_str,
- (long) time(NULL) + (long)exptime);
+ if (exptime) {
+ if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
+ sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Registered', '%q', %ld)",
+ from_user,
+ from_host,
+ contact_str,
+ rpid,
+ (long) time(NULL) + (long)exptime);
- } else {
- sql = switch_mprintf("update sip_registrations set contact='%q', expires=%ld where user='%q' and host='%q'",
- contact_str,
- (long) time(NULL) + (long)exptime,
- from_user,
- from_host);
+ } else {
+ sql = switch_mprintf("update sip_registrations set contact='%q', expires=%ld, rpid='%q' where user='%q' and host='%q'",
+ contact_str,
+ (long) time(NULL) + (long)exptime,
+ rpid,
+ from_user,
+ from_host);
- }
+ }
- if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", from_host);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s", contact_str);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)exptime);
- switch_event_fire(&s_event);
- }
+ if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", from_host);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s", contact_str);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)exptime);
+ switch_event_fire(&s_event);
+ }
- if (sql) {
- execute_sql(profile->dbname, sql, profile->ireg_mutex);
- switch_safe_free(sql);
- sql = NULL;
- }
+ if (sql) {
+ execute_sql(profile->dbname, sql, profile->ireg_mutex);
+ switch_safe_free(sql);
+ sql = NULL;
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Register from [%s@%s] contact [%s] expires %ld\n",
- from_user,
- from_host,
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Register:\nFrom: [%s@%s]\nContact: [%s]\nExpires: [%ld]\n",
+ from_user,
+ from_host,
contact_str,
(long)exptime
);
-
- if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
- switch_event_fire(&event);
- }
-
- if (exptime) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Registered");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "Registered");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
} else {
+ if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q'", from_user, from_host))) {
+ execute_sql(profile->dbname, sql, profile->ireg_mutex);
+ switch_safe_free(sql);
+ sql = NULL;
+ }
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "unavailable");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "unavailable");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
}
+
+ if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
+ switch_event_fire(&event);
+ }
+
if (regtype == REG_REGISTER) {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(contact),
NUTAG_WITH_THIS(nua),
@@ -2920,9 +2915,9 @@ static int sub_reg_callback(void *pArg, int argc, char **argv, char **columnName
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", status);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", status);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
switch_event_fire(&event);
}
@@ -2935,30 +2930,31 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
char *pl;
char *id, *note;
uint32_t in = atoi(argv[0]);
- char *msg = argv[1];
- char *proto = argv[2];
- char *user = argv[3];
- char *host = argv[4];
- char *sub_to_user = argv[5];
- char *sub_to_host = argv[6];
- char *event = argv[7];
- char *contact = argv[8];
- char *callid = argv[9];
- char *full_from = argv[10];
- char *full_via = argv[11];
+ char *status = argv[1];
+ char *rpid = argv[2];
+ char *proto = argv[3];
+ char *user = argv[4];
+ char *host = argv[5];
+ char *sub_to_user = argv[6];
+ char *sub_to_host = argv[7];
+ char *event = argv[8];
+ char *contact = argv[9];
+ char *callid = argv[10];
+ char *full_from = argv[11];
+ char *full_via = argv[12];
nua_handle_t *nh;
- char *doing;
char *to;
char *open;
+ if (!rpid) {
+ rpid = "unknown";
+ }
if (in) {
- note = switch_mprintf("%s", msg);
- doing="available";
+ note = switch_mprintf("%s", status);
open = "open";
} else {
note = NULL;
- doing="unavailable";
open = "closed";
}
@@ -2984,9 +2980,8 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
"\r\n"
"\r\n"
"\r\n"
- "\r\n"
"%s\r\n"
- "", id, open, doing, note);
+ "", id, open, rpid, note);
nh = nua_handle(profile->nua, NULL, TAG_END());
@@ -3022,7 +3017,7 @@ static void sip_i_subscribe(int status,
tagi_t tags[])
{
if (sip) {
- long exp;
+ long exp, exp_raw;
sip_to_t const *to = sip->sip_to;
sip_from_t const *from = sip->sip_from;
sip_contact_t const *contact = sip->sip_contact;
@@ -3040,7 +3035,7 @@ static void sip_i_subscribe(int status,
char *full_via = NULL;
switch_core_db_t *db;
char *errmsg;
-
+ char *sstr;
if (from) {
from_user = (char *) from->a_url->url_user;
@@ -3094,9 +3089,9 @@ static void sip_i_subscribe(int status,
full_from = sip_header_as_string(profile->home, (void *)sip->sip_from);
full_via = sip_header_as_string(profile->home, (void *)sip->sip_via);
-
- exp = (long) time(NULL) + (sip->sip_expires ? sip->sip_expires->ex_delta : 60);
-
+ exp_raw = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
+ exp = (long) time(NULL) + exp_raw;
+
if ((sql = switch_mprintf("delete from sip_subscriptions where "
"proto='%q' and user='%q' and host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q';\n"
@@ -3123,27 +3118,29 @@ static void sip_i_subscribe(int status,
switch_safe_free(sql);
}
-
+ sstr = switch_mprintf("active;expires=%ld", exp_raw);
+
nua_respond(nh, SIP_202_ACCEPTED,
- SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=3600"),
+ SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
SIPTAG_FROM(sip->sip_to),
SIPTAG_TO(sip->sip_from),
SIPTAG_CONTACT_STR(to_str),
TAG_END());
-
+ switch_safe_free(sstr);
+
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
goto end;
}
- if ((sql = switch_mprintf("select 'sip+%q@%q',status from sip_registrations where user='%q' and host='%q'", to_user, to_host, to_user, to_host))) {
+ if ((sql = switch_mprintf("select 'sip+%q@%q',status,rpid from sip_registrations where user='%q' and host='%q'",
+ to_user, to_host, to_user, to_host))) {
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sub_reg_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
- switch_core_db_close(db);
switch_safe_free(sql);
}
-
+ switch_core_db_close(db);
end:
if (event) {
@@ -3449,6 +3446,7 @@ static void sip_i_publish(nua_t *nua,
sip_from_t const *from = sip->sip_from;
char *from_user = NULL;
char *from_host = NULL;
+ char *rpid = "unknown";
sip_payload_t *payload = sip->sip_payload;
char *event_type;
@@ -3458,7 +3456,7 @@ static void sip_i_publish(nua_t *nua,
}
if (payload) {
- switch_xml_t xml, note, person, tuple, status, basic;
+ switch_xml_t xml, note, person, tuple, status, basic, act;
switch_event_t *event;
uint8_t in = 0;
char *sql;
@@ -3474,6 +3472,14 @@ static void sip_i_publish(nua_t *nua,
note_txt = note->txt;
}
+ if (person && (act = switch_xml_child(person, "rpid:activities"))) {
+ if ((rpid = strchr(act->child->name, ':'))) {
+ rpid++;
+ } else {
+ rpid = act->child->name;
+ }
+ }
+
if (!strcasecmp(status_txt, "open")) {
if (switch_strlen_zero(note_txt)) {
note_txt = "Available";
@@ -3485,7 +3491,8 @@ static void sip_i_publish(nua_t *nua,
}
}
- if ((sql = switch_mprintf("update sip_registrations set status='%q' where user='%q' and host='%q'", note_txt, from_user, from_host))) {
+ if ((sql = switch_mprintf("update sip_registrations set status='%q',rpid='%q' where user='%q' and host='%q'",
+ note_txt, rpid, from_user, from_host))) {
execute_sql(profile->dbname, sql, profile->ireg_mutex);
switch_safe_free(sql);
}
@@ -3495,17 +3502,18 @@ static void sip_i_publish(nua_t *nua,
if (in) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", note_txt);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", status_txt);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "%s", event_type);
switch_event_fire(&event);
}
} else {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
@@ -3630,7 +3638,8 @@ static void sip_i_invite(nua_t *nua,
switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
set_chat_hash(tech_pvt, sip);
-
+ switch_channel_set_variable(channel, "sip_fromuser", (char *) from->a_url->url_user);
+ switch_channel_set_variable(channel, "sip_fromhost", (char *) from->a_url->url_host);
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
(char *) from->a_url->url_user,
profile->dialplan,
@@ -3840,10 +3849,12 @@ static void event_callback(nua_event_t event,
tech_pvt = switch_core_session_get_private(session);
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
- nua_event_name (event), status, phrase,
- session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "n/a"
- );
+ if (status != 100 && status != 200) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
+ nua_event_name (event), status, phrase,
+ session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "n/a"
+ );
+ }
if ((profile->pflags & PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) {
sip_authorization_t const *authorization = NULL;
@@ -3982,6 +3993,7 @@ static void event_callback(nua_event_t event,
case nua_i_active:
case nua_i_ack:
case nua_i_terminated:
+ case nua_r_set_params:
break;
default:
@@ -4144,24 +4156,17 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
switch_event_fire(&s_event);
}
- if (profile->pflags & PFLAG_PRESENCE) {
- if (!(profile->presence = switch_core_alloc(profile->pool, sizeof(*profile->presence)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- return NULL;
- }
-
- profile->presence->nh = nua_handle(profile->nua, NULL, SIPTAG_CONTACT_STR(profile->url), TAG_END());
-
- profile->presence->sofia_private.presence = profile->presence;
- nua_handle_bind(profile->presence->nh, &profile->presence->sofia_private);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Creating presence for %s\n", profile->url);
- }
switch_mutex_lock(globals.hash_mutex);
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
switch_mutex_unlock(globals.hash_mutex);
+ if (profile->pflags & PFLAG_PRESENCE) {
+ if (switch_event_create(&s_event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_NAME);
+ switch_event_fire(&s_event);
+ }
+ }
while(globals.running == 1) {
if (++ireg_loops >= IREG_SECONDS) {
@@ -4491,11 +4496,16 @@ static void event_handler(switch_event_t *event)
char *from_host = switch_event_get_header(event, "orig-from-host");
char *contact_str = switch_event_get_header(event, "orig-contact");
char *exp_str = switch_event_get_header(event, "orig-expires");
+ char *rpid = switch_event_get_header(event, "orig-rpid");
long expires = (long)time(NULL) + atol(exp_str);
char *profile_name = switch_event_get_header(event, "orig-profile-name");
sofia_profile_t *profile;
char buf[512];
+ if (!rpid) {
+ rpid = "unknown";
+ }
+
if (!profile_name || !(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, profile_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
return;
@@ -4503,17 +4513,19 @@ static void event_handler(switch_event_t *event)
if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
- sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', %ld)",
- from_user,
- from_host,
- contact_str,
- expires);
+ sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', '%q', %ld)",
+ from_user,
+ from_host,
+ contact_str,
+ rpid,
+ expires);
} else {
- sql = switch_mprintf("update sip_registrations set contact='%q', expires=%ld where user='%q' and host='%q'",
- contact_str,
- expires,
- from_user,
- from_host);
+ sql = switch_mprintf("update sip_registrations set contact='%q', rpid='%q', expires=%ld where user='%q' and host='%q'",
+ contact_str,
+ rpid,
+ expires,
+ from_user,
+ from_host);
}
@@ -4603,7 +4615,7 @@ static void cancel_presence(void)
switch_hash_index_t *hi;
void *val;
- if ((sql = switch_mprintf("select 0,'%q',* from sip_subscriptions where event='presence'"))) {
+ if ((sql = switch_mprintf("select 0,'unavailable','unavailable',* from sip_subscriptions where event='presence'"))) {
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (sofia_profile_t *) val;
@@ -4625,24 +4637,82 @@ static void cancel_presence(void)
}
+
+static char *translate_rpid(char *in, char *ext)
+{
+ char *r = NULL;
+
+ if (in && (strstr(in, "null") || strstr(in, "NULL"))) {
+ in = NULL;
+ }
+
+ if (!in) {
+ in = ext;
+ }
+
+ if (!in) {
+ return NULL;
+ }
+
+ if (!strcasecmp(in, "dnd")) {
+ r = "busy";
+ }
+
+ if (ext && !strcasecmp(ext, "away")) {
+ r = "idle";
+ }
+
+ return r;
+}
+
static void pres_event_handler(switch_event_t *event)
{
sofia_profile_t *profile;
switch_hash_index_t *hi;
void *val;
char *from = switch_event_get_header(event, "from");
+ char *rpid = switch_event_get_header(event, "rpid");
char *status= switch_event_get_header(event, "status");
- char *show= switch_event_get_header(event, "show");
char *event_type = switch_event_get_header(event, "event_type");
- char *sql = NULL;
- char *user = NULL, *host = NULL;
+ char *sql = NULL, *sql2 = NULL;
+ char *euser = NULL, *user = NULL, *host = NULL;
char *errmsg;
char *resource;
switch_core_db_t *db;
+ if (rpid && !strcasecmp(rpid, "n/a")) {
+ rpid = NULL;
+ }
+
+ if (status && !strcasecmp(status, "n/a")) {
+ status = NULL;
+ }
+
+ if (rpid) {
+ rpid = translate_rpid(rpid, status);
+ }
+
+ if (!status) {
+ status = "Available";
+
+ if (rpid) {
+ if (!strcasecmp(rpid, "busy")) {
+ status = "Busy";
+ } else if (!strcasecmp(rpid, "unavailable")) {
+ status = "Idle";
+ } else if (!strcasecmp(rpid, "away")) {
+ status = "Idle";
+ }
+ }
+ }
if (event->event_id == SWITCH_EVENT_ROSTER) {
- sql = switch_mprintf("select 1,'%q',* from sip_subscriptions where event='presence'", status ? status : "Available");
+
+ if (from) {
+ sql = switch_mprintf("select 1,'%q',%q',* from sip_subscriptions where event='presence' and full_from like '%%%q%%'", status, rpid, from);
+ } else {
+ sql = switch_mprintf("select 1,'%q',%q',* from sip_subscriptions where event='presence'", status, rpid);
+ }
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
@@ -4667,13 +4737,6 @@ static void pres_event_handler(switch_event_t *event)
return;
}
- if (status && !strcasecmp(status, "n/a")) {
- status = show;
- if (status && !strcasecmp(status, "n/a")) {
- status = NULL;
- }
- }
-
if (switch_strlen_zero(event_type)) {
event_type="presence";
}
@@ -4685,6 +4748,11 @@ static void pres_event_handler(switch_event_t *event)
if ((resource = strchr(host, '/'))) {
*resource++ = '\0';
}
+ if ((euser = strchr(user, '+'))) {
+ euser++;
+ } else {
+ euser = user;
+ }
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
return;
@@ -4701,19 +4769,12 @@ static void pres_event_handler(switch_event_t *event)
switch(event->event_id) {
case SWITCH_EVENT_PRESENCE_IN:
- if (!status) {
- status = "Available";
- }
-
- sql = switch_mprintf("select 1,'%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
- status , event_type, user, host);
+ sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
+ status , rpid, event_type, euser, host);
break;
case SWITCH_EVENT_PRESENCE_OUT:
- if (!status) {
- status = "Unavailable";
- }
- sql = switch_mprintf("select 0,'%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
- status, event_type, user, host);
+ sql = switch_mprintf("select 0,'%q','%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
+ status, rpid, event_type, euser, host);
break;
default:
break;
@@ -4734,18 +4795,19 @@ static void pres_event_handler(switch_event_t *event)
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
- switch_safe_free(sql);
-
- if ((sql = switch_mprintf("select 'sip+%q@%q',status from sip_registrations where user='%q' and host='%q'", user, host, user, host))) {
+
+
+ if ((sql2 = switch_mprintf("select 'sip+%q@%q',status,rpid from sip_registrations where user='%q' and host='%q'", euser, host, user, host))) {
switch_mutex_lock(profile->ireg_mutex);
- switch_core_db_exec(db, sql, sub_reg_callback, profile, &errmsg);
+ switch_core_db_exec(db, sql2, sub_reg_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
- switch_core_db_close(db);
- switch_safe_free(sql);
+ switch_safe_free(sql2);
}
+ switch_core_db_close(db);
}
}
+ switch_safe_free(sql);
switch_safe_free(user);
}