FS-3794 please test this version

This commit is contained in:
Anthony Minessale 2012-01-26 04:46:48 -06:00
parent 62dc305092
commit b3b33ea995
6 changed files with 545 additions and 365 deletions

View File

@ -4175,7 +4175,7 @@ SWITCH_STANDARD_API(sofia_function)
} }
if (strstr(argv[2], "sla")) { if (strstr(argv[2], "sla")) {
mod_sofia_globals.debug_sla = 1; mod_sofia_globals.debug_sla = 10;
stream->write_function(stream, "+OK Debugging sla\n"); stream->write_function(stream, "+OK Debugging sla\n");
} }

View File

@ -828,6 +828,7 @@ typedef struct {
int network_port; int network_port;
const char *is_nat; const char *is_nat;
int is_auto_nat; int is_auto_nat;
int fs_path;
} sofia_nat_parse_t; } sofia_nat_parse_t;
@ -1140,7 +1141,7 @@ switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, swi
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl); void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
void sofia_glue_check_dtmf_type(private_object_t *tech_pvt); void sofia_glue_check_dtmf_type(private_object_t *tech_pvt);
void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str); void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str);
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np); char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np);
void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on); void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on);
void sofia_process_dispatch_event(sofia_dispatch_event_t **dep); void sofia_process_dispatch_event(sofia_dispatch_event_t **dep);
char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool); char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool);

View File

@ -91,7 +91,7 @@ void sofia_handle_sip_r_notify(switch_core_session_t *session, int status,
if (status >= 300 && sip && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) { if (status >= 300 && sip && sip->sip_call_id && (!sofia_private || !sofia_private->is_call)) {
char *sql; char *sql;
sql = switch_mprintf("update sip_subscriptions set expires=%ld where call_id='%q'", (long) switch_epoch_time_now(NULL), sip->sip_call_id->i_id); sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
switch_assert(sql != NULL); switch_assert(sql != NULL);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
nua_handle_destroy(nh); nua_handle_destroy(nh);
@ -3686,7 +3686,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
profile->contact_user = SOFIA_DEFAULT_CONTACT_USER; profile->contact_user = SOFIA_DEFAULT_CONTACT_USER;
sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); //sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
sofia_set_pflag(profile, PFLAG_SQL_IN_TRANS); sofia_set_pflag(profile, PFLAG_SQL_IN_TRANS);
profile->shutdown_type = "false"; profile->shutdown_type = "false";

View File

@ -5139,6 +5139,14 @@ char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup)
{ {
char *url = NULL, *e; char *url = NULL, *e;
while((e = strchr(buf, '"'))) {
buf = e+1;
}
while(*buf == ' ') {
buf++;
}
if ((url = strchr(buf, '<')) && (e = strchr(url, '>'))) { if ((url = strchr(buf, '<')) && (e = strchr(url, '>'))) {
url++; url++;
if (to_dup) { if (to_dup) {
@ -6504,9 +6512,14 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use
nua_handle_t *nh; nua_handle_t *nh;
sofia_destination_t *dst = NULL; sofia_destination_t *dst = NULL;
char *contact_str, *contact, *user_via = NULL; char *contact_str, *contact, *user_via = NULL;
char *route_uri = NULL; char *route_uri = NULL, *p;
contact = sofia_glue_get_url_from_contact((char *) o_contact, 1); contact = sofia_glue_get_url_from_contact((char *) o_contact, 1);
if ((p = strstr(contact, ";fs_"))) {
*p = '\0';
}
if (!zstr(network_ip) && sofia_glue_check_nat(profile, network_ip)) { if (!zstr(network_ip) && sofia_glue_check_nat(profile, network_ip)) {
char *ptr = NULL; char *ptr = NULL;
//const char *transport_str = NULL; //const char *transport_str = NULL;
@ -6744,7 +6757,7 @@ void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str
} }
} }
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np) char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np)
{ {
char *contact_str = NULL; char *contact_str = NULL;
const char *contact_host;//, *contact_user; const char *contact_host;//, *contact_user;
@ -6841,7 +6854,8 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sof
np->is_nat = "No contact host"; np->is_nat = "No contact host";
} }
if (np->is_nat) {
if (np->is_nat && !np->fs_path) {
contact_host = np->network_ip; contact_host = np->network_ip;
switch_snprintf(new_port, sizeof(new_port), ":%d", np->network_port); switch_snprintf(new_port, sizeof(new_port), ":%d", np->network_port);
port = NULL; port = NULL;
@ -6853,6 +6867,39 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sof
} }
ipv6 = strchr(contact_host, ':'); ipv6 = strchr(contact_host, ':');
if (np->is_nat && np->fs_path) {
char *full_contact = sip_header_as_string(nh->nh_home, (void *) contact);
char *full_contact_dup;
char *path_encoded;
int path_encoded_len;
char *path_val;
const char *tp;
full_contact_dup = sofia_glue_get_url_from_contact(full_contact, 1);
if ((tp = switch_stristr("transport=", full_contact_dup))) {
tp += 10;
}
if (zstr(tp)) {
tp = "udp";
}
path_val = switch_mprintf("sip:%s:%d;transport=%s", np->network_ip, np->network_port, tp);
path_encoded_len = (int)(strlen(path_val) * 3) + 1;
switch_zmalloc(path_encoded, path_encoded_len);
switch_copy_string(path_encoded, ";fs_path=", 10);
switch_url_encode(path_val, path_encoded + 9, path_encoded_len - 9);
contact_str = switch_mprintf("%s <%s;fs_nat=yes%s>", display, full_contact_dup, path_encoded);
free(full_contact_dup);
free(path_encoded);
free(path_val);
} else {
if (contact->m_url->url_params) { if (contact->m_url->url_params) {
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s", contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s",
display, contact->m_url->url_user, display, contact->m_url->url_user,
@ -6863,7 +6910,7 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sof
display, display,
contact->m_url->url_user, ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : ""); contact->m_url->url_user, ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : "");
} }
}
return contact_str; return contact_str;
} }

View File

@ -40,6 +40,7 @@ struct state_helper {
switch_hash_t *hash; switch_hash_t *hash;
sofia_profile_t *profile; sofia_profile_t *profile;
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
int total;
}; };
@ -50,7 +51,7 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char **columnNames); static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char **columnNames);
static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv, char **columnNames); static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv, char **columnNames);
static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char **columnNames); static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char **columnNames);
static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *to_host, switch_bool_t clear, switch_bool_t unseize); static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *to_host, switch_bool_t clear, switch_bool_t unseize, const char *call_id);
static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char **columnNames); static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char **columnNames);
static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char **columnNames); static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char **columnNames);
@ -574,7 +575,7 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha
} }
static void do_normal_probe(sofia_profile_t *profile, switch_event_t *event) static void do_normal_probe(switch_event_t *event)
{ {
char *sql; char *sql;
struct resub_helper h = { 0 }; struct resub_helper h = { 0 };
@ -582,6 +583,8 @@ static void do_normal_probe(sofia_profile_t *profile, switch_event_t *event)
char *proto = switch_event_get_header(event, "proto"); char *proto = switch_event_get_header(event, "proto");
char *probe_user = NULL, *probe_euser, *probe_host, *p; char *probe_user = NULL, *probe_euser, *probe_host, *p;
struct dialog_helper dh = { { 0 } }; struct dialog_helper dh = { { 0 } };
char *sub_call_id = switch_event_get_header(event, "sub-call-id");
sofia_profile_t *profile;
//DUMP_EVENT(event); //DUMP_EVENT(event);
@ -605,6 +608,8 @@ static void do_normal_probe(sofia_profile_t *profile, switch_event_t *event)
sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs " sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs "
"where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc", "where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
probe_euser, probe_host, probe_euser, probe_host); probe_euser, probe_host, probe_euser, probe_host);
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh);
h.profile = profile; h.profile = profile;
@ -626,7 +631,7 @@ static void do_normal_probe(sofia_profile_t *profile, switch_event_t *event)
"sip_presence.rpid," "sip_presence.rpid,"
"sip_dialogs.presence_id, " "sip_dialogs.presence_id, "
"sip_presence.open_closed," "sip_presence.open_closed,"
"'%q','%q' " "'%q','%q','%q' "
"from sip_registrations " "from sip_registrations "
"left join sip_dialogs on " "left join sip_dialogs on "
@ -637,12 +642,17 @@ static void do_normal_probe(sofia_profile_t *profile, switch_event_t *event)
"left join sip_presence on " "left join sip_presence on "
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and " "(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and "
"sip_registrations.profile_name=sip_presence.profile_name) " "sip_registrations.profile_name=sip_presence.profile_name) "
"where sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and " "where sip_dialogs.call_info_state != 'seized' and "
"(sip_registrations.profile_name='%q' or sip_registrations.presence_hosts like '%%%q%%') "
"and sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and "
"(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' " "(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' "
"or sip_registrations.presence_hosts like '%%%q%%'))", "))",
dh.status, dh.rpid, dh.status, dh.rpid, switch_str_nil(sub_call_id),
switch_sql_concat(), switch_sql_concat(), switch_sql_concat(), switch_sql_concat(),
probe_euser, probe_host, probe_euser, probe_host, probe_host, probe_host); profile->name, probe_host, probe_euser, probe_host, probe_euser, probe_host, probe_host);
switch_assert(sql); switch_assert(sql);
if (mod_sofia_globals.debug_presence > 0) { if (mod_sofia_globals.debug_presence > 0) {
@ -659,6 +669,7 @@ static void do_normal_probe(sofia_profile_t *profile, switch_event_t *event)
if (!h.rowcount) { if (!h.rowcount) {
h.noreg++; h.noreg++;
switch_safe_free(sql); switch_safe_free(sql);
/* find ones with presence_id defined that are not registred */ /* find ones with presence_id defined that are not registred */
sql = switch_mprintf("select sip_from_user, sip_from_host, 'Registered', '', '', " sql = switch_mprintf("select sip_from_user, sip_from_host, 'Registered', '', '', "
"uuid, state, direction, " "uuid, state, direction, "
@ -707,13 +718,14 @@ static void do_normal_probe(sofia_profile_t *profile, switch_event_t *event)
switch_safe_free(probe_user); switch_safe_free(probe_user);
} }
static void do_dialog_probe(sofia_profile_t *profile, switch_event_t *event) static void do_dialog_probe(switch_event_t *event)
{ {
// Received SUBSCRIBE for "dialog" events. // Received SUBSCRIBE for "dialog" events.
// Return a complete list of dialogs for the monitored entity. // Return a complete list of dialogs for the monitored entity.
char *sql; char *sql;
char *to = switch_event_get_header(event, "to"); char *to = switch_event_get_header(event, "to");
char *probe_user = NULL, *probe_euser, *probe_host, *p; char *probe_user = NULL, *probe_euser, *probe_host, *p;
sofia_profile_t *profile;
if (!to || !(probe_user = strdup(to))) { if (!to || !(probe_user = strdup(to))) {
return; return;
@ -748,7 +760,7 @@ static void do_dialog_probe(sofia_profile_t *profile, switch_event_t *event)
"(sip_dialogs.sip_from_user = sip_registrations.sip_user " "(sip_dialogs.sip_from_user = sip_registrations.sip_user "
"and (sip_dialogs.sip_from_host = sip_registrations.orig_server_host or " "and (sip_dialogs.sip_from_host = sip_registrations.orig_server_host or "
"sip_dialogs.sip_from_host = sip_registrations.sip_host) ) " "sip_dialogs.sip_from_host = sip_registrations.sip_host) ) "
"where sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and " "where sip_dialogs.call_info_state != 'seized' and sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and "
"(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' " "(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' "
"or sip_registrations.presence_hosts like '%%%q%%'))", "or sip_registrations.presence_hosts like '%%%q%%'))",
probe_euser, probe_host, probe_euser, probe_host,
@ -827,9 +839,11 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
char *sql = NULL; char *sql = NULL;
char *euser = NULL, *user = NULL, *host = NULL; char *euser = NULL, *user = NULL, *host = NULL;
char *call_info = switch_event_get_header(event, "presence-call-info"); char *call_info = switch_event_get_header(event, "presence-call-info");
char *call_id = switch_event_get_header(event, "call-id");
char *presence_source = switch_event_get_header(event, "presence-source"); char *presence_source = switch_event_get_header(event, "presence-source");
char *call_info_state = switch_event_get_header(event, "presence-call-info-state"); char *call_info_state = switch_event_get_header(event, "presence-call-info-state");
switch_console_callback_match_t *matches; switch_console_callback_match_t *matches;
struct presence_helper helper = { 0 };
if (!mod_sofia_globals.running) { if (!mod_sofia_globals.running) {
return; return;
@ -961,10 +975,10 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
if (!probe_type || strcasecmp(probe_type, "dialog")) { if (!probe_type || strcasecmp(probe_type, "dialog")) {
/* NORMAL PROBE */ /* NORMAL PROBE */
do_normal_probe(profile, event); do_normal_probe(event);
} else { } else {
/* DIALOG PROBE */ /* DIALOG PROBE */
do_dialog_probe(profile, event); do_dialog_probe(event);
} }
} }
goto done; goto done;
@ -1025,7 +1039,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PROCESS PRESENCE EVENT\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PROCESS PRESENCE EVENT\n");
} }
sync_sla(profile, euser, host, SWITCH_TRUE, SWITCH_TRUE); sync_sla(profile, euser, host, SWITCH_TRUE, SWITCH_TRUE, call_id);
} }
if (!strcmp(proto, "dp")) { if (!strcmp(proto, "dp")) {
@ -1041,12 +1055,13 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_safe_free(sql); switch_safe_free(sql);
if (dh.hits && presence_source && (!strcasecmp(presence_source, "register") || switch_stristr("register", status))) { if (zstr(call_id) && (dh.hits && presence_source && (!strcasecmp(presence_source, "register") || switch_stristr("register", status)))) {
goto done; goto done;
} }
if (zstr(call_id)) {
if ((sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event," "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
@ -1062,14 +1077,35 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
"where sip_subscriptions.version > -1 and sip_subscriptions.expires > -1 and " "where sip_subscriptions.version > -1 and sip_subscriptions.expires > -1 and "
"sip_subscriptions.proto='%q' and " "sip_subscriptions.proto='%q' and "
"(event='%q' or event='%q') and sub_to_user='%q' " "(event='%q' or event='%q') and sub_to_user='%q' "
"and (sub_to_host='%q' or presence_hosts like '%%%q%%') " "and (sub_to_host='%q' or sub_to_host='%q' or sub_to_host='%q' or presence_hosts like '%%%q%%') "
"and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ", "and (sip_subscriptions.profile_name = '%q' or presence_hosts like '%%%q%%') ",
switch_str_nil(status), switch_str_nil(rpid), host, switch_str_nil(status), switch_str_nil(rpid), host,
dh.status,dh.rpid,dh.presence_id, proto, dh.status,dh.rpid,dh.presence_id, proto,
event_type, alt_event_type, euser, host, host, profile->name))) { event_type, alt_event_type, euser, host, profile->sipip,
profile->extsipip ? profile->extsipip : "N/A", host, profile->name, host);
} else {
sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.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"
",'%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.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) "
"where sip_subscriptions.event != 'line-seize' and "
"sip_subscriptions.profile_name = '%q' and sip_subscriptions.call_id='%q'",
switch_str_nil(status), switch_str_nil(rpid), host,
dh.status,dh.rpid,dh.presence_id, profile->name, call_id);
}
struct presence_helper helper = { 0 };
helper.profile = profile; helper.profile = profile;
helper.event = event; helper.event = event;
@ -1109,7 +1145,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
} }
#if 1 #if 0
if (event) { if (event) {
const char *refresh = switch_event_get_header(event, "refresh"); const char *refresh = switch_event_get_header(event, "refresh");
if (switch_true(refresh)) { if (switch_true(refresh)) {
@ -1150,7 +1186,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
} }
switch_safe_free(helper.stream.data); switch_safe_free(helper.stream.data);
helper.stream.data = NULL; helper.stream.data = NULL;
}
sofia_glue_release_profile(profile); sofia_glue_release_profile(profile);
} }
} }
@ -1331,7 +1367,7 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
char *status = argv[2]; char *status = argv[2];
char *rpid = argv[3]; char *rpid = argv[3];
char *proto = argv[4]; char *proto = argv[4];
char *call_id = NULL;
char *presence_id = NULL; char *presence_id = NULL;
char *to_user = NULL; char *to_user = NULL;
char *uuid = NULL; char *uuid = NULL;
@ -1341,7 +1377,14 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
char to_buf[128] = ""; char to_buf[128] = "";
switch_event_header_t *hp; switch_event_header_t *hp;
char *free_me = NULL; char *free_me = NULL;
int do_event = 1; int do_event = 1, i;
if (mod_sofia_globals.debug_presence > 1) {
for (i = 0; i < argc; i++) {
switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_WARNING, "sofia_presence_resub_callback: %d [%s]=[%s]\n", i, columnNames[i], argv[i]);
}
}
if (argc > 5) { if (argc > 5) {
uuid = argv[5]; uuid = argv[5];
@ -1365,6 +1408,11 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
if ((p = strchr(free_me, '@'))) *p = '\0'; if ((p = strchr(free_me, '@'))) *p = '\0';
user = free_me; user = free_me;
} }
if (argc > 16) {
call_id = argv[16];
}
} }
if (!zstr(uuid) && !switch_ivr_uuid_exists(uuid)) { if (!zstr(uuid) && !switch_ivr_uuid_exists(uuid)) {
@ -1392,6 +1440,10 @@ static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Force-Direction", "inbound"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Force-Direction", "inbound");
} }
if (!zstr(call_id)) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", call_id);
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "resub", "true"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "resub", "true");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
@ -1512,12 +1564,12 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
if (mod_sofia_globals.debug_presence > 1) { if (mod_sofia_globals.debug_presence > 1) {
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_DEBUG, "sofia_dialog_probe_callback: %d [%s]=[%s]\n", i, columnNames[i], argv[i]); switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_WARNING, "sofia_dialog_probe_callback: %d [%s]=[%s]\n", i, columnNames[i], argv[i]);
} }
} }
if (zstr(to_user) || zstr(contact_user)) { if (zstr(to_user) || zstr(contact_user)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sofia_dialog_probe_callback: not enough info to generate a dialog entry\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "sofia_dialog_probe_callback: not enough info to generate a dialog entry\n");
return 0; return 0;
} }
@ -1636,10 +1688,13 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
return 0; return 0;
} }
static void send_presence_notify(sofia_profile_t *profile, #define send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l) \
_send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,__FILE__, __SWITCH_FUNC__, __LINE__)
static void _send_presence_notify(sofia_profile_t *profile,
const char *full_to, const char *full_to,
const char *full_from, const char *full_from,
const char *contact, const char *o_contact,
const char *expires, const char *expires,
const char *call_id, const char *call_id,
const char *event, const char *event,
@ -1647,20 +1702,82 @@ static void send_presence_notify(sofia_profile_t *profile,
const char *remote_port, const char *remote_port,
const char *ct, const char *ct,
const char *pl, const char *pl,
const char *call_info const char *call_info,
const char *file, const char *func, int line
) )
{ {
char sstr[128] = ""; char sstr[128] = "";
nua_handle_t *nh; nua_handle_t *nh;
int exptime = 0; int exptime = 0;
char expires_str[10] = ""; char expires_str[10] = "";
char *tmp, *route = NULL;
sip_cseq_t *cseq = NULL; sip_cseq_t *cseq = NULL;
uint32_t callsequence; uint32_t callsequence;
uint32_t now = (uint32_t) switch_epoch_time_now(NULL); uint32_t now = (uint32_t) switch_epoch_time_now(NULL);
const char *tp;
char *our_contact = profile->url, *our_contact_dup = NULL; char *our_contact = profile->url, *our_contact_dup = NULL;
sofia_destination_t *dst = NULL;
char *contact_str, *contact, *user_via = NULL;
char *route_uri = NULL, *o_contact_dup = NULL, *tmp;
const char *tp;
tmp = (char *)o_contact;
o_contact_dup = sofia_glue_get_url_from_contact(tmp, 1);
if ((tp = switch_stristr("transport=", o_contact_dup))) {
tp += 10;
}
if (zstr(tp)) {
tp = "udp";
}
if (!switch_stristr("transport=", our_contact)) {
our_contact_dup = switch_mprintf("<%s;transport=%s>", our_contact, tp);
our_contact = our_contact_dup;
}
if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) {
char *ptr = NULL;
if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
sofia_transport_t transport = sofia_glue_str2transport(ptr);
switch (transport) {
case SOFIA_TRANSPORT_TCP:
contact_str = profile->tcp_public_contact;
break;
case SOFIA_TRANSPORT_TCP_TLS:
contact_str = profile->tls_public_contact;
break;
default:
contact_str = profile->public_url;
break;
}
user_via = sofia_glue_create_external_via(NULL, profile, transport);
} else {
user_via = sofia_glue_create_external_via(NULL, profile, SOFIA_TRANSPORT_UDP);
contact_str = profile->public_url;
}
} else {
contact_str = our_contact;
}
dst = sofia_glue_get_destination((char *) o_contact);
switch_assert(dst);
contact = sofia_glue_get_url_from_contact(dst->contact, 1);
if (dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
} else {
if (remote_ip && remote_port) {
route_uri = switch_mprintf("sip:%s:%s;transport=%s", remote_ip, remote_port, tp);
}
}
if (expires) { if (expires) {
long ltmp = atol(expires); long ltmp = atol(expires);
@ -1672,17 +1789,6 @@ static void send_presence_notify(sofia_profile_t *profile,
} }
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) { if (exptime <= 0) {
switch_snprintf(sstr, sizeof(sstr), "terminated;reason=noresource"); switch_snprintf(sstr, sizeof(sstr), "terminated;reason=noresource");
@ -1690,35 +1796,21 @@ static void send_presence_notify(sofia_profile_t *profile,
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime); switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
} }
tmp = (char *)contact;
contact = sofia_glue_get_url_from_contact(tmp, 0);
if ((tp = switch_stristr("transport=", contact))) {
tp += 10;
}
if (zstr(tp)) {
tp = "udp";
}
if (remote_ip && remote_port) {
route = switch_mprintf("sip:%s:%s;transport=%s", remote_ip, remote_port, tp);
}
if (!switch_stristr("transport=", our_contact)) {
our_contact_dup = switch_mprintf("<%s;transport=%s>", our_contact, tp);
our_contact = our_contact_dup;
}
if (mod_sofia_globals.debug_presence > 1) { if (mod_sofia_globals.debug_presence > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEND PRES NOTIFY:\n" 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" "file[%s]\nfunc[%s]\nline[%d]\n"
"profile[%s]\nvia[%s]\nip[%s]\nport[%s]\nroute[%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", "event[%s]\nct[%s]\npl[%s]\ncall_info[%s]\nexptime[%ld]\n",
route, file, func, line,
contact, profile->name,
switch_str_nil(user_via),
remote_ip,
remote_port,
route_uri,
o_contact,
full_to, full_to,
full_from, full_from,
our_contact, contact,
call_id, call_id,
expires_str, expires_str,
event, event,
@ -1727,17 +1819,31 @@ static void send_presence_notify(sofia_profile_t *profile,
switch_str_nil(call_info), switch_str_nil(call_info),
(long)exptime (long)exptime
); );
} }
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, NUTAG_URL(contact), SIPTAG_CONTACT_STR(contact_str), TAG_END());
cseq = sip_cseq_create(nh->nh_home, callsequence, SIP_METHOD_NOTIFY);
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_notify(nh, nua_notify(nh,
NUTAG_NEWSUB(1), NUTAG_NEWSUB(1),
TAG_IF(route, NUTAG_PROXY(route)), TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
NUTAG_URL(contact), TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_FROM_STR(full_to), SIPTAG_FROM_STR(full_to),
SIPTAG_TO_STR(full_from), SIPTAG_TO_STR(full_from),
SIPTAG_CONTACT_STR(our_contact),
SIPTAG_CALL_ID_STR(call_id), SIPTAG_CALL_ID_STR(call_id),
TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)), TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
@ -1749,8 +1855,14 @@ static void send_presence_notify(sofia_profile_t *profile,
SIPTAG_CSEQ(cseq), SIPTAG_CSEQ(cseq),
TAG_END()); TAG_END());
switch_safe_free(route);
switch_safe_free(our_contact_dup);
switch_safe_free(route_uri);
switch_safe_free(contact);
sofia_glue_free_destination(dst);
switch_safe_free(user_via);
switch_safe_free(o_contact_dup);
} }
@ -1779,6 +1891,13 @@ static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv,
const char *pl = NULL; const char *pl = NULL;
const char *ct = "application/dialog-info+xml"; const char *ct = "application/dialog-info+xml";
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]);
}
}
if (mod_sofia_globals.debug_presence > 0) { if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
@ -2510,6 +2629,14 @@ static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char *
struct mwi_helper *h = (struct mwi_helper *) pArg; struct mwi_helper *h = (struct mwi_helper *) pArg;
sofia_profile_t *ext_profile = NULL, *profile = h->profile; sofia_profile_t *ext_profile = NULL, *profile = h->profile;
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]);
}
}
if (profile_name && strcasecmp(profile_name, h->profile->name)) { if (profile_name && strcasecmp(profile_name, h->profile->name)) {
if ((ext_profile = sofia_glue_find_profile(profile_name))) { if ((ext_profile = sofia_glue_find_profile(profile_name))) {
profile = ext_profile; profile = ext_profile;
@ -2581,6 +2708,7 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char
char *event = argv[4]; char *event = argv[4];
int i; int i;
if (mod_sofia_globals.debug_sla > 1) { if (mod_sofia_globals.debug_sla > 1) {
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SLA3: %d [%s]=[%s]\n", i, columnNames[i], argv[i]); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SLA3: %d [%s]=[%s]\n", i, columnNames[i], argv[i]);
@ -2616,6 +2744,8 @@ static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char
send_presence_notify(sh->profile, argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], NULL, NULL, tmp); send_presence_notify(sh->profile, argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], NULL, NULL, tmp);
sh->total++;
return 0; return 0;
} }
@ -2712,11 +2842,12 @@ static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv
return 0; return 0;
} }
static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *to_host, switch_bool_t clear, switch_bool_t unseize) static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *to_host, switch_bool_t clear, switch_bool_t unseize, const char *call_id)
{ {
struct state_helper *sh; struct state_helper *sh;
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
char *sql; char *sql;
int total = 0;
switch_core_new_memory_pool(&pool); switch_core_new_memory_pool(&pool);
sh = switch_core_alloc(pool, sizeof(*sh)); sh = switch_core_alloc(pool, sizeof(*sh));
@ -2724,8 +2855,9 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
switch_core_hash_init(&sh->hash, sh->pool); switch_core_hash_init(&sh->hash, sh->pool);
sql = switch_mprintf("select sip_from_user,sip_from_host,call_info,call_info_state,uuid from sip_dialogs " sql = switch_mprintf("select sip_from_user,sip_from_host,call_info,call_info_state,uuid from sip_dialogs "
"where call_info_state is not null and hostname='%q' and ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')", "where call_info_state is not null and hostname='%q' and ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
mod_sofia_globals.hostname, to_user, to_host, to_user, to_host); "and profile_name='%q'",
mod_sofia_globals.hostname, to_user, to_host, to_user, to_host, profile->name);
if (mod_sofia_globals.debug_sla > 1) { if (mod_sofia_globals.debug_sla > 1) {
@ -2735,26 +2867,44 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
switch_safe_free(sql); switch_safe_free(sql);
if (!zstr(call_id)) {
if (unseize) {
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 call_id='%q' and profile_name='%q')", call_id, profile->name);
} else {
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 call_id='%q' and profile_name='%q'", call_id, profile->name);
}
} else {
if (unseize) { if (unseize) {
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port " 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 " "from sip_subscriptions "
"where version > -1 and expires > -1 and hostname='%q' " "where version > -1 and expires > -1 and hostname='%q' "
"and sub_to_user='%q' and sub_to_host='%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); "and (event='call-info' or event='line-seize') and (profile_name='%q' or presence_hosts like '%%%q%%')",
mod_sofia_globals.hostname, to_user, to_host, profile->name, to_host);
} else { } else {
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port " 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 " "from sip_subscriptions "
"where version > -1 and expires > -1 and hostname='%q' " "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); "and sub_to_user='%q' and sub_to_host='%q' " "and (event='call-info') and "
"(profile_name='%q' or presence_hosts like '%%%q%%')",
mod_sofia_globals.hostname, to_user, to_host, profile->name, to_host);
}
} }
if (mod_sofia_globals.debug_sla > 1) { if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
} }
sh->profile = profile; sh->profile = profile;
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, broadsoft_sla_notify_callback, sh); sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, broadsoft_sla_notify_callback, sh);
switch_safe_free(sql); switch_safe_free(sql);
total = sh->total;
sh = NULL; sh = NULL;
switch_core_destroy_memory_pool(&pool); switch_core_destroy_memory_pool(&pool);
@ -2771,6 +2921,8 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
} }
return total;
} }
void sofia_presence_handle_sip_i_subscribe(int status, void sofia_presence_handle_sip_i_subscribe(int status,
@ -2818,7 +2970,8 @@ void sofia_presence_handle_sip_i_subscribe(int status,
to = sip->sip_to; to = sip->sip_to;
contact = sip->sip_contact; contact = sip->sip_contact;
if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, de, &np))) { np.fs_path = 1;
if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np))) {
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END()); nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
return; return;
} }
@ -2937,9 +3090,9 @@ void sofia_presence_handle_sip_i_subscribe(int status,
sstr = switch_mprintf("active;expires=%ld", exp_delta); sstr = switch_mprintf("active;expires=%ld", exp_delta);
sql = switch_mprintf("update sip_subscriptions " sql = switch_mprintf("update sip_subscriptions "
"set expires=%ld,version=0 " "set version=0,expires=%ld,contact='%q' "
"where call_id='%q'", "where call_id='%q'",
(long) switch_epoch_time_now(NULL) + exp_delta, (long) switch_epoch_time_now(NULL) + exp_delta, contact_str,
call_id); call_id);
if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
@ -2950,6 +3103,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
} else { } else {
if (sub_state == nua_substate_terminated) {
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id, mod_sofia_globals.hostname); sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id, mod_sofia_globals.hostname);
if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
@ -2962,8 +3116,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
sofia_glue_actually_execute_sql(profile, sql, NULL); sofia_glue_actually_execute_sql(profile, sql, NULL);
switch_safe_free(sql); switch_safe_free(sql);
if (sub_state == nua_substate_terminated) { sstr = switch_mprintf("terminated;reason=noresource");
sstr = switch_mprintf("terminated");
} else { } else {
sip_accept_t *ap = sip->sip_accept; sip_accept_t *ap = sip->sip_accept;
char accept[256] = ""; char accept[256] = "";
@ -2980,7 +3133,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
"(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from," "(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, full_to) " "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')", "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, proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : "",
event, contact_str, call_id, full_from, full_via, event, contact_str, call_id, full_from, full_via,
(long) switch_epoch_time_now(NULL) + exp_delta, (long) switch_epoch_time_now(NULL) + exp_delta,
full_agent, accept, profile->name, mod_sofia_globals.hostname, full_agent, accept, profile->name, mod_sofia_globals.hostname,
@ -3078,10 +3231,11 @@ void sofia_presence_handle_sip_i_subscribe(int status,
p++; p++;
} }
#if 0
nua_notify(nh, nua_notify(nh,
SIPTAG_EXPIRES_STR("0"), SIPTAG_EXPIRES_STR("0"),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END()); SIPTAG_SUBSCRIPTION_STATE_STR(sstr), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END());
#endif
if (!strcasecmp(event, "line-seize")) { if (!strcasecmp(event, "line-seize")) {
if (mod_sofia_globals.debug_sla > 1) { if (mod_sofia_globals.debug_sla > 1) {
@ -3098,7 +3252,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
} }
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE); sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE, NULL);
} }
su_free(nh->nh_home, full_call_info); su_free(nh->nh_home, full_call_info);
@ -3125,8 +3279,8 @@ void sofia_presence_handle_sip_i_subscribe(int status,
sql = switch_mprintf("delete from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') " sql = switch_mprintf("delete from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
"and call_info_state='seized'", "and call_info_state='seized' and profile_name='%q'",
to_user, to_host, to_user, to_host); to_user, to_host, to_user, to_host, profile->name);
if (mod_sofia_globals.debug_sla > 1) { if (mod_sofia_globals.debug_sla > 1) {
@ -3135,20 +3289,21 @@ void sofia_presence_handle_sip_i_subscribe(int status,
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
now = switch_epoch_time_now(NULL); now = switch_epoch_time_now(NULL);
sql = switch_mprintf("insert into sip_dialogs (sip_from_user,sip_from_host,call_info,call_info_state,hostname,expires,rcd) " sql = switch_mprintf("insert into sip_dialogs (sip_from_user,sip_from_host,call_info,call_info_state,hostname,expires,rcd,profile_name) "
"values ('%q','%q','%q','seized','%q',%ld,%ld)", "values ('%q','%q','%q','seized','%q',%ld,%ld,'%q')",
to_user, to_host, switch_str_nil(p), mod_sofia_globals.hostname, switch_epoch_time_now(NULL) + exp_delta, (long)now); to_user, to_host, switch_str_nil(p), mod_sofia_globals.hostname,
switch_epoch_time_now(NULL) + exp_delta, (long)now, profile->name);
if (mod_sofia_globals.debug_sla > 1) { if (mod_sofia_globals.debug_sla > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEIZE SQL %s\n", sql); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEIZE SQL %s\n", sql);
} }
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE); sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE, NULL);
su_free(nh->nh_home, full_call_info); su_free(nh->nh_home, full_call_info);
} }
} else if (!strcasecmp(event, "call-info")) { } else if (!strcasecmp(event, "call-info")) {
sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE); sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE, call_id);
} }
} }
@ -3170,6 +3325,8 @@ void sofia_presence_handle_sip_i_subscribe(int status,
end: end:
if (strcasecmp(event, "call-info") && strcasecmp(event, "line-seize")) {
if (to_user && (strstr(to_user, "ext+") || strstr(to_user, "user+"))) { if (to_user && (strstr(to_user, "ext+") || strstr(to_user, "user+"))) {
char protocol[80]; char protocol[80];
char *p; char *p;
@ -3209,11 +3366,10 @@ void sofia_presence_handle_sip_i_subscribe(int status,
} }
} else { } else {
if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
if (!strcasecmp(event, "dialog")) {
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "probe-type", "dialog");
}
if (!strcasecmp(event, "dialog")) {
if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "probe-type", "dialog");
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name); switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
@ -3226,9 +3382,20 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sub-call-id", call_id); switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sub-call-id", call_id);
switch_event_fire(&sevent); switch_event_fire(&sevent);
} }
} else {
if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "presence-source", "subscribe");
switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "rpid", "unknown");
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_fire(&sevent);
}
}
}
} }
if (event) { if (event) {
su_free(nh->nh_home, event); su_free(nh->nh_home, event);
@ -3347,6 +3514,14 @@ static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **col
{ {
struct pres_sql_cb *cb = (struct pres_sql_cb *) pArg; struct pres_sql_cb *cb = (struct pres_sql_cb *) pArg;
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]);
}
}
send_presence_notify(cb->profile, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], NULL); send_presence_notify(cb->profile, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], NULL);
cb->ttl++; cb->ttl++;
@ -3392,7 +3567,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
from = sip->sip_from; from = sip->sip_from;
payload = sip->sip_payload; payload = sip->sip_payload;
contact_str = sofia_glue_gen_contact_str(profile, sip, de, NULL); contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, NULL);
if (from) { if (from) {
from_user = (char *) from->a_url->url_user; from_user = (char *) from->a_url->url_user;

View File

@ -1521,7 +1521,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
"user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm," "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm,"
"mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host) " "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host) "
"values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q')", "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q')",
call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : reg_host, call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "",
contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime + 60, contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime + 60,
agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm, agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm,
mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host); mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host);
@ -1553,7 +1553,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "presence-hosts", profile->presence_hosts ? profile->presence_hosts : reg_host); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "presence-hosts", profile->presence_hosts ? profile->presence_hosts : "n/a");
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);
@ -1576,38 +1576,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
"Register:\nFrom: [%s@%s]\nContact: [%s]\nExpires: [%ld]\n", to_user, reg_host, contact_str, (long) exptime); "Register:\nFrom: [%s@%s]\nContact: [%s]\nExpires: [%ld]\n", to_user, reg_host, contact_str, (long) exptime);
} }
#if 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",
(sip && sip->sip_user_agent) ? sip->sip_user_agent->g_string : "unknown");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
if (sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER) ||
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Registered");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
}
#endif
} else { } else {
int send = 1; int send = 1;
@ -1629,18 +1597,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event); switch_event_fire(&event);
} }
#if 0
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_PROTO, to_user, sub_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "unavailable");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
#endif
if (multi_reg) { if (multi_reg) {
char *icontact, *p; char *icontact, *p;