mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-24 13:12:03 +00:00
FS-3758 --resolve ok so I wrote my own patch but i did borrow the 2 lines of code to create a seq from the original patch! sofia changes probably need to be converted to a tag if they are to go upstream. This completely manages sub/pub from inside mod_sofia inside the db and subs can now persist and/or fail over mid dialog tested on several things like polycom/snom/yealink on SLA and presence
This commit is contained in:
@@ -537,14 +537,14 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
|
||||
if (for_everyone) {
|
||||
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||
",'%q','%q' from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
|
||||
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')", stream.data, host, user, host, host);
|
||||
",'%q',full_to,network_ip,network_port from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
|
||||
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')", stream.data, user, host, host);
|
||||
} else if (sub_call_id) {
|
||||
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||
",'%q','%q' from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
|
||||
",'%q',full_to,network_ip,network_port from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
|
||||
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%' and call_id='%q')",
|
||||
stream.data, host, user, host, host, sub_call_id);
|
||||
stream.data, user, host, host, sub_call_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -798,7 +798,7 @@ static void do_dialog_probe(sofia_profile_t *profile, switch_event_t *event)
|
||||
// The dialog_probe_callback has built up the dialogs to be included in the NOTIFY.
|
||||
// Now send the "full" dialog event to the triggering subscription.
|
||||
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,version, "
|
||||
"'full' "
|
||||
"'full',full_to,full_from,contact,expires,event,network_ip,network_port "
|
||||
"from sip_subscriptions "
|
||||
"where expires > -1 and hostname='%q' "
|
||||
"and sub_to_user='%q' and sub_to_host='%q' " "and (event='dialog') and "
|
||||
@@ -887,7 +887,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
|
||||
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
|
||||
"sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
|
||||
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed "
|
||||
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
|
||||
" sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
|
||||
"from sip_subscriptions left join sip_presence on "
|
||||
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
||||
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
||||
@@ -900,7 +901,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
|
||||
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
|
||||
"sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
|
||||
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed "
|
||||
",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
|
||||
"sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
|
||||
"from sip_subscriptions left join sip_presence on "
|
||||
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
||||
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
||||
@@ -1028,7 +1030,6 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
call_info, call_info_state, mod_sofia_globals.hostname, euser, host, euser, host, call_info);
|
||||
|
||||
}
|
||||
//printf("WTF %s\n", sql);
|
||||
|
||||
if (mod_sofia_globals.debug_sla > 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STATE SQL %s\n", sql);
|
||||
@@ -1068,7 +1069,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
|
||||
"sip_subscriptions.accept,sip_subscriptions.profile_name"
|
||||
",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',"
|
||||
"sip_subscriptions.version, '%q',sip_subscriptions.orig_proto "
|
||||
"sip_subscriptions.version, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to,"
|
||||
"sip_subscriptions.network_ip, sip_subscriptions.network_port "
|
||||
"from sip_subscriptions "
|
||||
"left join sip_presence on "
|
||||
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
||||
@@ -1638,6 +1640,111 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_presence_notify(sofia_profile_t *profile,
|
||||
const char *full_to,
|
||||
const char *full_from,
|
||||
const char *contact,
|
||||
const char *expires,
|
||||
const char *call_id,
|
||||
const char *event,
|
||||
const char *remote_ip,
|
||||
const char *remote_port,
|
||||
const char *ct,
|
||||
const char *pl,
|
||||
const char *call_info
|
||||
)
|
||||
{
|
||||
char sstr[128] = "";
|
||||
nua_handle_t *nh;
|
||||
int exptime = 0;
|
||||
char expires_str[10] = "";
|
||||
char *tmp, *route = NULL;
|
||||
sip_cseq_t *cseq = NULL;
|
||||
uint32_t callsequence;
|
||||
uint32_t now = (uint32_t) switch_epoch_time_now(NULL);
|
||||
|
||||
if (expires) {
|
||||
long ltmp = atol(expires);
|
||||
|
||||
if (ltmp > 0) {
|
||||
exptime = (ltmp - now);
|
||||
} else {
|
||||
exptime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_lock(profile->ireg_mutex);
|
||||
if (!profile->cseq_base) {
|
||||
profile->cseq_base = (now - 1312693200) * 10;
|
||||
}
|
||||
callsequence = ++profile->cseq_base;
|
||||
switch_mutex_unlock(profile->ireg_mutex);
|
||||
|
||||
|
||||
nh = nua_handle(profile->nua, NULL, TAG_END());
|
||||
cseq = sip_cseq_create(nh->nh_home, callsequence, SIP_METHOD_NOTIFY);
|
||||
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
|
||||
|
||||
if (exptime > 0) {
|
||||
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
|
||||
} else {
|
||||
switch_snprintf(sstr, sizeof(sstr), "terminated;reason=noresource");
|
||||
}
|
||||
|
||||
|
||||
tmp = (char *)contact;
|
||||
contact = sofia_glue_get_url_from_contact(tmp, 0);
|
||||
|
||||
if (remote_ip && remote_port) {
|
||||
route = switch_mprintf("sip:%s:%s", remote_ip, remote_port);
|
||||
}
|
||||
|
||||
if (mod_sofia_globals.debug_presence > 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEND PRES NOTIFY:\n"
|
||||
"route[%s]\ncontact[%s]\nto[%s]\nfrom[%s]\nurl[%s]\ncall_id[%s]\nexpires_str[%s]\n"
|
||||
"event[%s]\nct[%s]\npl[%s]\ncall_info[%s]\nexptime[%ld]\n",
|
||||
route,
|
||||
contact,
|
||||
full_to,
|
||||
full_from,
|
||||
profile->url,
|
||||
call_id,
|
||||
expires_str,
|
||||
event,
|
||||
switch_str_nil(ct),
|
||||
switch_str_nil(pl),
|
||||
switch_str_nil(call_info),
|
||||
(long)exptime
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
nua_notify(nh,
|
||||
NUTAG_NEWSUB(1),
|
||||
TAG_IF(route, NUTAG_PROXY(route)),
|
||||
NUTAG_URL(contact),
|
||||
SIPTAG_FROM_STR(full_to),
|
||||
SIPTAG_TO_STR(full_from),
|
||||
SIPTAG_CONTACT_STR(profile->url),
|
||||
SIPTAG_CALL_ID_STR(call_id),
|
||||
TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)),
|
||||
SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
|
||||
SIPTAG_EVENT_STR(event),
|
||||
TAG_IF(!zstr(ct), SIPTAG_CONTENT_TYPE_STR(ct)),
|
||||
TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
|
||||
TAG_IF(!zstr(call_info), SIPTAG_CALL_INFO_STR(call_info)),
|
||||
TAG_IF(!exptime, SIPTAG_EXPIRES_STR("0")),
|
||||
SIPTAG_CSEQ(cseq),
|
||||
TAG_END());
|
||||
|
||||
switch_safe_free(route);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
struct rfc4235_helper *sh = (struct rfc4235_helper *) pArg;
|
||||
@@ -1650,21 +1757,18 @@ static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv,
|
||||
char *event = argv[4];
|
||||
char *version = argv[5];
|
||||
char *notify_state = argv[6];
|
||||
|
||||
char *full_to = argv[7];
|
||||
char *full_from = argv[8];
|
||||
char *contact = argv[9];
|
||||
char *remote_ip = argv[10];
|
||||
char *remote_port = argv[11];
|
||||
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
nua_handle_t *nh;
|
||||
time_t exptime = switch_epoch_time_now(NULL) + 3600;
|
||||
char sstr[128] = "";
|
||||
char expires_str[10] = "";
|
||||
char *to;
|
||||
const char *pl = NULL;
|
||||
const char *ct = "application/dialog-info+xml";
|
||||
|
||||
if (!(nh = nua_handle_by_call_id(sh->profile->nua, call_id))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_DEBUG, "sofia_dialog_probe_notify_callback: could not find nua handle (old subscription)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
|
||||
"SEND DIALOG\nTo: \t%s@%s\nFrom: \t%s@%s\nCall-ID: \t%s\n",
|
||||
@@ -1698,25 +1802,25 @@ static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv,
|
||||
pl = stream.data;
|
||||
ct = "application/dialog-info+xml";
|
||||
|
||||
nua_handle_bind(nh, &mod_sofia_globals.keep_private);
|
||||
|
||||
if (expires) {
|
||||
long tmp = atol(expires);
|
||||
exptime = tmp - switch_epoch_time_now(NULL);
|
||||
}
|
||||
if (exptime > 0) {
|
||||
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
|
||||
} else {
|
||||
switch_snprintf(sstr, sizeof(sstr), "terminated;reason=timeout");
|
||||
}
|
||||
|
||||
if (mod_sofia_globals.debug_presence > 0 && pl) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "send payload:\n%s\n", pl);
|
||||
}
|
||||
|
||||
nua_notify(nh,
|
||||
TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)),
|
||||
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(pl), TAG_END());
|
||||
|
||||
send_presence_notify(sh->profile,
|
||||
full_to,
|
||||
full_from,
|
||||
contact,
|
||||
expires,
|
||||
call_id,
|
||||
event,
|
||||
remote_ip,
|
||||
remote_port,
|
||||
ct,
|
||||
pl,
|
||||
NULL
|
||||
);
|
||||
|
||||
|
||||
switch_safe_free(to);
|
||||
switch_safe_free(stream.data);
|
||||
@@ -1862,12 +1966,17 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
struct presence_helper *helper = (struct presence_helper *) pArg;
|
||||
char *pl = NULL;
|
||||
char *clean_id = NULL, *id = NULL;
|
||||
|
||||
char *proto = argv[0];
|
||||
char *user = argv[1];
|
||||
char *host = argv[2];
|
||||
char *sub_to_user = argv[3];
|
||||
char *event = argv[5];
|
||||
char *contact = argv[6];
|
||||
char *call_id = argv[7];
|
||||
char *full_from = argv[8];
|
||||
//char *full_via = argv[9];
|
||||
|
||||
char *expires = argv[10];
|
||||
char *user_agent = argv[11];
|
||||
char *profile_name = argv[13];
|
||||
@@ -1880,16 +1989,14 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
char *dialog_rpid = NULL;
|
||||
|
||||
const char *ct = "no/idea";
|
||||
nua_handle_t *nh;
|
||||
|
||||
char *to = NULL;
|
||||
char *open;
|
||||
char *prpid;
|
||||
time_t exptime = switch_epoch_time_now(NULL) + 3600;
|
||||
|
||||
int is_dialog = 0;
|
||||
sofia_profile_t *ext_profile = NULL, *profile = helper->profile;
|
||||
char sstr[128] = "";
|
||||
int kill_handle = 0;
|
||||
char expires_str[10] = "";
|
||||
|
||||
char status_line[256] = "";
|
||||
char *version = "0";
|
||||
char *presence_id = NULL;
|
||||
@@ -1897,14 +2004,17 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
int holding = 0;
|
||||
char *orig_proto = NULL;
|
||||
int skip_proto = 0;
|
||||
char *full_to = NULL;
|
||||
char *ip = NULL;
|
||||
char *port = 0;
|
||||
|
||||
|
||||
//int i;
|
||||
|
||||
//for(i = 0; i < argc; i++) {
|
||||
//printf("arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
|
||||
//}
|
||||
//DUMP_EVENT(helper->event);
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
int i;
|
||||
for(i = 0; i < argc; i++) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
|
||||
}
|
||||
DUMP_EVENT(helper->event);
|
||||
}
|
||||
|
||||
if (argc > 18) {
|
||||
if (!zstr(argv[17])) {
|
||||
@@ -1922,6 +2032,9 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
version = argv[22];
|
||||
presence_id = argv[23];
|
||||
orig_proto = argv[24];
|
||||
full_to = argv[25];
|
||||
ip = argv[26];
|
||||
port = argv[27];
|
||||
}
|
||||
|
||||
if (!zstr(presence_id) && strchr(presence_id, '@')) {
|
||||
@@ -1969,34 +2082,25 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
}
|
||||
}
|
||||
|
||||
if (!(nh = nua_handle_by_call_id(profile->nua, call_id))) {
|
||||
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find handle for call id %s\n", call_id);
|
||||
}
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (expires) {
|
||||
long tmp = atol(expires);
|
||||
if (tmp > 0) {
|
||||
exptime = tmp - switch_epoch_time_now(NULL); // - SUB_OVERLAP;
|
||||
} else {
|
||||
exptime = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rpid) {
|
||||
rpid = "unknown";
|
||||
}
|
||||
|
||||
if (!strcasecmp(proto, SOFIA_CHAT_PROTO) || skip_proto) {
|
||||
clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
|
||||
} else {
|
||||
clean_id = switch_mprintf("sip:%s+%s@%s", proto, sub_to_user, sub_to_host);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!rpid) {
|
||||
rpid = "unknown";
|
||||
}
|
||||
|
||||
// if (!strcasecmp(proto, SOFIA_CHAT_PROTO) || skip_proto) {
|
||||
// clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
|
||||
//} else {
|
||||
// clean_id = switch_mprintf("sip:%s+%s@%s", proto, sub_to_user, sub_to_host);
|
||||
//}
|
||||
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
|
||||
"SEND PRESENCE\nTo: \t%s@%s\nFrom: \t%s@%s\nCall-ID: \t%s\nProfile:\t%s [%s]\n\n",
|
||||
@@ -2220,7 +2324,6 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
if (!zstr(astate) && !zstr(uuid) &&
|
||||
helper && helper->stream.data && strcmp(helper->last_uuid, uuid) && strcasecmp(astate, "terminated") && strchr(uuid, '-')) {
|
||||
helper->stream.write_function(&helper->stream, "update sip_dialogs set state='%s' where uuid='%s';", astate, uuid);
|
||||
//printf("WTF update sip_dialogs set state='%s' where uuid='%s';\n", astate, uuid);
|
||||
switch_copy_string(helper->last_uuid, uuid, sizeof(helper->last_uuid));
|
||||
}
|
||||
|
||||
@@ -2347,40 +2450,11 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
|
||||
if (!zstr(uuid) && strchr(uuid, '-') && !zstr(status_line) && !zstr(rpid) && (zstr(register_source) || strcasecmp(register_source, "register"))) {
|
||||
char *sql = switch_mprintf("update sip_dialogs set rpid='%q',status='%q' where uuid='%q'", rpid, status_line, uuid);
|
||||
//printf("WTF %s\n", sql);
|
||||
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nua_handle_bind(nh, &mod_sofia_globals.keep_private);
|
||||
|
||||
if (helper->event && helper->event->event_id == SWITCH_EVENT_PRESENCE_OUT) {
|
||||
switch_set_string(sstr, "terminated;reason=noresource");
|
||||
switch_set_string(expires_str, "0");
|
||||
kill_handle = 1;
|
||||
} else if (exptime > 0) {
|
||||
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
|
||||
} else {
|
||||
unsigned delta = (unsigned) (exptime * -1);
|
||||
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", delta);
|
||||
switch_snprintf(expires_str, sizeof(expires_str), "%u", delta);
|
||||
if (nh && nh->nh_ds && nh->nh_ds->ds_usage) {
|
||||
nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, delta, delta);
|
||||
}
|
||||
}
|
||||
|
||||
if (mod_sofia_globals.debug_presence > 0 && pl) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "send payload:\n%s\n", pl);
|
||||
}
|
||||
|
||||
nua_notify(nh,
|
||||
TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)),
|
||||
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(pl), TAG_END());
|
||||
|
||||
nua_handle_unref(nh);
|
||||
|
||||
end:
|
||||
send_presence_notify(profile, full_to, full_from, contact, expires, call_id, event, ip, port, ct, pl, NULL);
|
||||
|
||||
switch_safe_free(free_me);
|
||||
|
||||
@@ -2393,25 +2467,24 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
|
||||
switch_safe_free(pl);
|
||||
switch_safe_free(to);
|
||||
|
||||
if (nh && kill_handle) {
|
||||
nua_handle_destroy(nh);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
char *sub_to_user = argv[3];
|
||||
char *sub_to_host = argv[15];
|
||||
//char *sub_to_user = argv[3];
|
||||
//char *sub_to_host = argv[4];
|
||||
char *event = argv[5];
|
||||
char *contact = argv[6];
|
||||
char *call_id = argv[7];
|
||||
char *full_from = argv[8];
|
||||
char *expires = argv[10];
|
||||
char *profile_name = argv[13];
|
||||
char *body = argv[15];
|
||||
char *id = NULL;
|
||||
nua_handle_t *nh;
|
||||
int expire_sec = atoi(expires);
|
||||
char *full_to = argv[16];
|
||||
char *remote_ip = argv[17];
|
||||
char *remote_port = argv[18];
|
||||
|
||||
struct mwi_helper *h = (struct mwi_helper *) pArg;
|
||||
sofia_profile_t *ext_profile = NULL, *profile = h->profile;
|
||||
|
||||
@@ -2421,31 +2494,23 @@ static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char *
|
||||
}
|
||||
}
|
||||
|
||||
if (!(nh = nua_handle_by_call_id(h->profile->nua, call_id))) {
|
||||
if (profile->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cannot find handle for %s\n", call_id);
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
send_presence_notify(profile,
|
||||
full_to,
|
||||
full_from,
|
||||
contact,
|
||||
expires,
|
||||
call_id,
|
||||
event,
|
||||
remote_ip,
|
||||
remote_port,
|
||||
"application/simple-message-summary",
|
||||
body,
|
||||
NULL
|
||||
);
|
||||
|
||||
id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
|
||||
expire_sec = (int) (expire_sec - switch_epoch_time_now(NULL));
|
||||
if (expire_sec < 0) {
|
||||
expire_sec = 3600;
|
||||
}
|
||||
|
||||
nua_handle_bind(nh, &mod_sofia_globals.keep_private);
|
||||
nua_notify(nh, SIPTAG_SUBSCRIPTION_STATE_STR("active"),
|
||||
SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), SIPTAG_PAYLOAD_STR(body), TAG_END());
|
||||
|
||||
nua_handle_unref(nh);
|
||||
|
||||
switch_safe_free(id);
|
||||
|
||||
h->total++;
|
||||
|
||||
end:
|
||||
|
||||
if (ext_profile) {
|
||||
sofia_glue_release_profile(ext_profile);
|
||||
}
|
||||
@@ -2488,14 +2553,11 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char
|
||||
char key[256] = "";
|
||||
char *data = NULL, *tmp;
|
||||
char *call_id = argv[0];
|
||||
char *expires = argv[1];
|
||||
//char *expires = argv[1];
|
||||
char *user = argv[2];
|
||||
char *host = argv[3];
|
||||
char *event = argv[4];
|
||||
int i;
|
||||
char sstr[128] = "", expires_str[128] = "";
|
||||
time_t exptime = 3600;
|
||||
nua_handle_t *nh;
|
||||
|
||||
if (mod_sofia_globals.debug_sla > 1) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
@@ -2505,19 +2567,7 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char
|
||||
|
||||
switch_snprintf(key, sizeof(key), "%s%s", user, host);
|
||||
data = switch_core_hash_find(sh->hash, key);
|
||||
|
||||
if (expires) {
|
||||
long tmp = atol(expires);
|
||||
exptime = tmp - switch_epoch_time_now(NULL);
|
||||
}
|
||||
|
||||
if (exptime > 0) {
|
||||
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
|
||||
} else {
|
||||
switch_snprintf(sstr, sizeof(sstr), "terminated;reason=noresource");
|
||||
}
|
||||
|
||||
switch_snprintf(expires_str, sizeof(expires_str), "%u", (unsigned) exptime);
|
||||
|
||||
|
||||
data = switch_core_hash_find(sh->hash, key);
|
||||
|
||||
@@ -2527,26 +2577,23 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char
|
||||
tmp = switch_core_sprintf(sh->pool, "<sip:%s>;appearance-index=*;appearance-state=idle", host);
|
||||
}
|
||||
|
||||
if (!strcasecmp(event, "line-seize") && (nh = nua_handle_by_call_id(sh->profile->nua, call_id))) {
|
||||
|
||||
if (!strcasecmp(event, "line-seize")) {
|
||||
char *hack;
|
||||
|
||||
if ((hack = (char *) switch_stristr("=seized", tmp))) {
|
||||
switch_snprintf(hack, 7, "=idle ");
|
||||
}
|
||||
nua_notify(nh,
|
||||
SIPTAG_EXPIRES_STR("0"),
|
||||
SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), SIPTAG_EVENT_STR("line-seize"), SIPTAG_CALL_INFO_STR(tmp), TAG_END());
|
||||
nua_handle_unref(nh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcasecmp(event, "call-info") && (nh = nua_handle_by_call_id(sh->profile->nua, call_id))) {
|
||||
nua_notify(nh,
|
||||
TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)),
|
||||
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR("call-info"), SIPTAG_CALL_INFO_STR(tmp), TAG_END());
|
||||
nua_handle_unref(nh);
|
||||
if (mod_sofia_globals.debug_sla > 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DB PRES NOTIFY: [%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n",
|
||||
argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], tmp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
send_presence_notify(sh->profile, argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], NULL, NULL, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2667,13 +2714,13 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
|
||||
|
||||
|
||||
if (unseize) {
|
||||
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
|
||||
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
|
||||
"from sip_subscriptions "
|
||||
"where version > -1 and expires > -1 and hostname='%q' "
|
||||
"and sub_to_user='%q' and sub_to_host='%q' "
|
||||
"and (event='call-info' or event='line-seize')", mod_sofia_globals.hostname, to_user, to_host);
|
||||
} else {
|
||||
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
|
||||
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
|
||||
"from sip_subscriptions "
|
||||
"where version > -1 and expires > -1 and hostname='%q' "
|
||||
"and sub_to_user='%q' and sub_to_host='%q' " "and (event='call-info')", mod_sofia_globals.hostname, to_user, to_host);
|
||||
@@ -2711,7 +2758,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
tagi_t tags[])
|
||||
{
|
||||
|
||||
long exp_delta;
|
||||
long exp_delta = 0;
|
||||
char exp_delta_str[30] = "";
|
||||
sip_to_t const *to;
|
||||
const char *from_user = NULL, *from_host = NULL;
|
||||
@@ -2726,6 +2773,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
const char *call_id = NULL;
|
||||
char *to_str = NULL;
|
||||
char *full_from = NULL;
|
||||
char *full_to = NULL;
|
||||
char *full_via = NULL;
|
||||
char *full_agent = NULL;
|
||||
char *sstr;
|
||||
@@ -2737,6 +2785,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
const char *contact_user;
|
||||
sofia_nat_parse_t np = { { 0 } };
|
||||
int found_proto = 0;
|
||||
char to_tag[13] = "";
|
||||
|
||||
if (!sip) {
|
||||
return;
|
||||
@@ -2750,6 +2799,8 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
return;
|
||||
}
|
||||
|
||||
switch_stun_random_string(to_tag, 12, NULL);
|
||||
|
||||
//contact_host = sip->sip_contact->m_url->url_host;
|
||||
contact_user = sip->sip_contact->m_url->url_user;
|
||||
|
||||
@@ -2757,19 +2808,6 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
|
||||
event = sip_header_as_string(nh->nh_home, (void *) sip->sip_event);
|
||||
|
||||
|
||||
/* the following could be refactored back to the calling event handler in sofia.c XXX MTK */
|
||||
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
||||
if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) {
|
||||
/* only fire this on <200 to try to avoid resubscribes. probably better ways to do this? */
|
||||
if (status < 200) {
|
||||
sofia_sla_handle_sip_i_subscribe(nua, contact_str, profile, nh, sip, de, tags);
|
||||
}
|
||||
switch_safe_free(contact_str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (to) {
|
||||
to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host);
|
||||
}
|
||||
@@ -2826,8 +2864,10 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
|
||||
call_id = sip->sip_call_id->i_id;
|
||||
full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from);
|
||||
full_to = sip_header_as_string(nh->nh_home, (void *) sip->sip_to);
|
||||
full_via = sip_header_as_string(nh->nh_home, (void *) sip->sip_via);
|
||||
|
||||
|
||||
if (sip->sip_expires && sip->sip_expires->ex_delta > 31536000) {
|
||||
sip->sip_expires->ex_delta = 31536000;
|
||||
}
|
||||
@@ -2879,6 +2919,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
} else {
|
||||
sip_accept_t *ap = sip->sip_accept;
|
||||
char accept[256] = "";
|
||||
|
||||
full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent);
|
||||
while (ap) {
|
||||
switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
|
||||
@@ -2887,13 +2928,13 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
|
||||
sql = switch_mprintf("insert into sip_subscriptions "
|
||||
"(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
|
||||
"full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip, orig_proto) "
|
||||
"values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q','%q')",
|
||||
"full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip, orig_proto, full_to) "
|
||||
"values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q','%q','%q;tag=%q')",
|
||||
proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host,
|
||||
event, contact_str, call_id, full_from, full_via,
|
||||
//sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1,
|
||||
(long) switch_epoch_time_now(NULL) + exp_delta,
|
||||
full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip, orig_proto);
|
||||
full_agent, accept, profile->name, mod_sofia_globals.hostname,
|
||||
np.network_port, np.network_ip, orig_proto, full_to, to_tag);
|
||||
|
||||
switch_assert(sql != NULL);
|
||||
|
||||
@@ -2905,15 +2946,16 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
|
||||
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||
sstr = switch_mprintf("active;expires=%ld", exp_delta);
|
||||
}
|
||||
|
||||
switch_mutex_unlock(profile->ireg_mutex);
|
||||
}
|
||||
|
||||
switch_mutex_unlock(profile->ireg_mutex);
|
||||
}
|
||||
|
||||
if (status < 200) {
|
||||
char *sticky = NULL;
|
||||
char *contactstr = profile->url, *cs = NULL;
|
||||
char *p = NULL, *new_contactstr = NULL;
|
||||
|
||||
|
||||
if (np.is_nat) {
|
||||
char params[128] = "";
|
||||
@@ -2962,8 +3004,11 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
new_contactstr = switch_mprintf("<sip:%s%s>", to_user, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sip_to_tag(nh->nh_home, sip->sip_to, to_tag);
|
||||
|
||||
nua_respond(nh, SIP_202_ACCEPTED,
|
||||
SIPTAG_TO(sip->sip_to),
|
||||
TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr)),
|
||||
NUTAG_WITH_THIS_MSG(de->data->e_msg),
|
||||
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EXPIRES_STR(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END());
|
||||
@@ -3141,6 +3186,10 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
if (full_from) {
|
||||
su_free(nh->nh_home, full_from);
|
||||
}
|
||||
if (full_to) {
|
||||
su_free(nh->nh_home, full_to);
|
||||
}
|
||||
|
||||
if (full_via) {
|
||||
su_free(nh->nh_home, full_via);
|
||||
}
|
||||
@@ -3156,7 +3205,9 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
if (!sent_reply) {
|
||||
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
|
||||
}
|
||||
|
||||
|
||||
nua_handle_destroy(nh);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3192,14 +3243,6 @@ void sofia_presence_handle_sip_r_subscribe(int status,
|
||||
return;
|
||||
}
|
||||
|
||||
/* the following could possibly be refactored back towards the calling event handler in sofia.c XXX MTK */
|
||||
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
||||
if (!strcasecmp(o->o_type, "dialog") && msg_params_find(o->o_params, "sla")) {
|
||||
sofia_sla_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sofia_private || !sofia_private->gateway) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Gateway information missing\n");
|
||||
return;
|
||||
@@ -3244,32 +3287,13 @@ void sofia_presence_handle_sip_r_subscribe(int status,
|
||||
}
|
||||
}
|
||||
|
||||
struct cpc {
|
||||
sofia_profile_t *profile;
|
||||
sofia_dispatch_event_t *de;
|
||||
};
|
||||
|
||||
static int sofia_counterpath_crutch(void *pArg, int argc, char **argv, char **columnNames)
|
||||
static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
nua_handle_t *nh;
|
||||
struct cpc *crutch = (struct cpc *) pArg;
|
||||
char *call_id = argv[0];
|
||||
char *pl = argv[1];
|
||||
char *event_type = argv[2];
|
||||
long exp_delta = atol(argv[3]);
|
||||
|
||||
if ((nh = nua_handle_by_call_id(crutch->profile->nua, call_id))) {
|
||||
char sstr[128] = "", expstr[128] = "";
|
||||
switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
|
||||
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", exp_delta);
|
||||
nua_notify(nh,
|
||||
NUTAG_WITH_THIS_MSG(crutch->de->data->e_msg),
|
||||
SIPTAG_EXPIRES_STR(expstr),
|
||||
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event_type),
|
||||
SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
|
||||
nua_handle_unref(nh);
|
||||
}
|
||||
sofia_profile_t *profile = (sofia_profile_t *) pArg;
|
||||
|
||||
send_presence_notify(profile, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3312,15 +3336,6 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
||||
from = sip->sip_from;
|
||||
payload = sip->sip_payload;
|
||||
|
||||
/* the following could instead be refactored back to the calling event handler in sofia.c XXX MTK */
|
||||
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
||||
/* also it probably is unsafe to dereference so many things in a row without testing XXX MTK */
|
||||
if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) {
|
||||
sofia_sla_handle_sip_i_publish(nua, profile, nh, sip, de, tags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
contact_str = sofia_glue_gen_contact_str(profile, sip, de, NULL);
|
||||
|
||||
if (from) {
|
||||
@@ -3407,14 +3422,12 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
||||
}
|
||||
|
||||
} else if (contact_str) {
|
||||
struct cpc crutch;
|
||||
|
||||
crutch.profile = profile;
|
||||
crutch.de = de;
|
||||
sql = switch_mprintf("select call_id,'%q','%q','%ld' from sip_subscriptions where sub_to_user='%q' and sub_to_host='%q' "
|
||||
"and contact = '%q' ", payload->pl_data ? payload->pl_data : "", event_type, exp_delta,
|
||||
from_user, from_host, contact_str);
|
||||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_counterpath_crutch, &crutch);
|
||||
sql = switch_mprintf("select full_to, full_from, contact, expires, call_id, event, network_ip, network_port, "
|
||||
"'application/pidf+xml' as ct,'%q' as pt "
|
||||
" from sip_subscriptions where sub_to_user='%q' and sub_to_host='%q' and event='%q'"
|
||||
"and contact = '%q' ", switch_str_nil(payload->pl_data), from_user, from_host, event_type);
|
||||
|
||||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, profile);
|
||||
switch_safe_free(sql);
|
||||
}
|
||||
|
||||
@@ -3636,6 +3649,30 @@ void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip)
|
||||
switch_mutex_unlock(tech_pvt->profile->flag_mutex);
|
||||
}
|
||||
|
||||
|
||||
void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now)
|
||||
{
|
||||
char *sql;
|
||||
|
||||
if (now) {
|
||||
sql = switch_mprintf("select full_to, full_from, contact, expires, call_id, event, network_ip, network_port, "
|
||||
"NULL as ct, NULL as pt "
|
||||
" from sip_subscriptions where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%q'",
|
||||
(long) now, mod_sofia_globals.hostname);
|
||||
|
||||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, profile);
|
||||
switch_safe_free(sql);
|
||||
|
||||
sql = switch_mprintf("delete from sip_subscriptions where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%q'",
|
||||
(long) now, mod_sofia_globals.hostname);
|
||||
sofia_glue_actually_execute_sql(profile, sql, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
||||
Reference in New Issue
Block a user