From a7b10081c88a893d2ac0d4d3f88a45ea7559c25d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 31 Jul 2012 15:26:03 -0500 Subject: [PATCH] send notifies for refer for 4579 --- .../mod_conference/mod_conference.c | 65 +++++++++++++++++++ src/mod/endpoints/mod_sofia/sofia.c | 64 +++++++++++++++++- src/mod/endpoints/mod_sofia/sofia_presence.c | 43 +++++++++--- 3 files changed, 163 insertions(+), 9 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index d7be5e6ea5..fccdefd46e 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1325,6 +1325,49 @@ static void send_rfc_event(conference_obj_t *conference) } + +static void send_conference_notify(conference_obj_t *conference, const char *status, switch_bool_t final) +{ + switch_event_t *event; + char *name = NULL, *domain = NULL, *dup_domain = NULL; + + if (!switch_test_flag(conference, CFLAG_RFC4579)) { + return; + } + + if (!(name = conference->name)) { + name = "conference"; + } + + if (!(domain = conference->domain)) { + dup_domain = switch_core_get_variable_dup("domain"); + if (!(domain = dup_domain)) { + domain = "cluecon.com"; + } + } + + + if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA) == SWITCH_STATUS_SUCCESS) { + event->flags |= EF_UNIQ_HEADERS; + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", name); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-event", "refer"); + + if (final) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "final", "true"); + } + + + switch_event_add_body(event, "%s", status); + switch_event_fire(&event); + } + + switch_safe_free(dup_domain); + +} + + /* Gain exclusive access and add the member to the list */ static switch_status_t conference_add_member(conference_obj_t *conference, conference_member_t *member) { @@ -6459,6 +6502,11 @@ static switch_status_t conference_outcall(conference_obj_t *conference, int rdlock = 0; switch_bool_t have_flags = SWITCH_FALSE; const char *outcall_flags; + int track = 0; + + if (var_event && switch_true(switch_event_get_header(var_event, "conference_track_status"))) { + track++; + } *cause = SWITCH_CAUSE_NORMAL_CLEARING; @@ -6500,6 +6548,12 @@ static switch_status_t conference_outcall(conference_obj_t *conference, switch_mutex_lock(conference->mutex); conference->originating++; switch_mutex_unlock(conference->mutex); + + if (track) { + send_conference_notify(conference, "SIP/2.0 100 Trying\r\n", SWITCH_FALSE); + } + + status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, var_event, SOF_NO_LIMITS, cancel_cause); switch_mutex_lock(conference->mutex); conference->originating--; @@ -6511,9 +6565,18 @@ static switch_status_t conference_outcall(conference_obj_t *conference, if (caller_channel) { switch_channel_hangup(caller_channel, *cause); } + + if (track) { + send_conference_notify(conference, "SIP/2.0 481 Failure\r\n", SWITCH_TRUE); + } + goto done; } + if (track) { + send_conference_notify(conference, "SIP/2.0 200 OK\r\n", SWITCH_TRUE); + } + rdlock = 1; peer_channel = switch_core_session_get_channel(peer_session); @@ -8462,6 +8525,8 @@ static void call_setup_event_handler(switch_event_t *event) switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_invite_uri", dial_uri); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_status", "true"); + if (!strncasecmp(ostr, "url+", 4)) { ostr += 4; } else if (!switch_true(full_url) && conference->outcall_templ) { diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 6c7c0382b3..9299d9f680 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1289,10 +1289,72 @@ static void our_sofia_event_callback(nua_event_t event, switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_number", ref_by_user); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_name", ref_by_user); - DUMP_EVENT(event); switch_event_fire(&event); } + + + if (sip) { + char *sql; + sofia_nat_parse_t np = { { 0 } }; + char *contact_str; + char *proto = "sip", *orig_proto = "sip"; + const char *call_id, *full_from, *full_to, *full_via, *from_user = NULL, *from_host = NULL, *to_user, *to_host, *full_agent; + char to_tag[13] = ""; + char *event_str = "refer"; + + np.fs_path = 1; + contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np); + + 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); + + full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent); + + switch_stun_random_string(to_tag, 12, NULL); + + if (sip->sip_from) { + from_user = sip->sip_from->a_url->url_user; + from_host = sip->sip_from->a_url->url_host; + } else { + from_user = "n/a"; + from_host = "n/a"; + } + + if (sip->sip_to) { + to_user = sip->sip_to->a_url->url_user; + to_host = sip->sip_to->a_url->url_host; + } else { + to_user = "n/a"; + to_host = "n/a"; + } + + 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,version,orig_proto, full_to) " + "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q',-1,'%q','%q;tag=%q')", + proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : "", + event_str, contact_str, call_id, full_from, full_via, + (long) switch_epoch_time_now(NULL) + 60, + 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); + + + if (1 || mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s REFER SUBSCRIBE %s@%s %s@%s\n%s\n", + profile->name, from_user, from_host, to_user, to_host, sql); + } + + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + + sip_to_tag(nh->nh_home, sip->sip_to, to_tag); + } + nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); switch_safe_free(method); switch_safe_free(full_url); diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index e53a4fd267..b7b39d1feb 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -900,8 +900,20 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event const char *call_id = switch_event_get_header(event, "call_id"); const char *from_user = switch_event_get_header(event, "conference-name"); const char *from_host = switch_event_get_header(event, "conference-domain"); + const char *event_str = switch_event_get_header(event, "conference-event"); const char *notfound = switch_event_get_header(event, "notfound"); const char *body = switch_event_get_body(event); + const char *type = "application/conference-info+xml"; + int final = switch_true(switch_event_get_header(event, "final"); + + if (!event_str) { + event_str = "conference"; + } + + if (!strcasecmp(event_str, "refer")) { + type = "message/sipfrag"; + } + if (!(from_user && from_host)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Event information not given\n"); @@ -910,34 +922,49 @@ static void send_conference_data(sofia_profile_t *profile, switch_event_t *event if (switch_true(notfound)) { sql = switch_mprintf("update sip_subscriptions set expires=%ld where " - "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='conference'", + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", (long)switch_epoch_time_now(NULL), mod_sofia_globals.hostname, profile->name, - from_user, from_host); + from_user, from_host, event_str); sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } + if (switch_true(final)) { + sql = switch_mprintf("delete from sip_subscriptions where " + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", + mod_sofia_globals.hostname, profile->name, + from_user, from_host, event_str); + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } + + + + + if (call_id) { sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, " - "'application/conference-info+xml' as ct,'%q' as pt " + "'%q' as ct,'%q' as pt " " from sip_subscriptions where " - "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='conference'" + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'" "and call_id = '%q' ", switch_sql_concat(), + type, switch_str_nil(body), mod_sofia_globals.hostname, profile->name, - from_user, from_host, call_id); + from_user, from_host, event_str, call_id); } else { sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, " - "'application/conference-info+xml' as ct,'%q' as pt " + "'%q' as ct,'%q' as pt " " from sip_subscriptions where " - "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='conference'", + "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'", switch_sql_concat(), + type, switch_str_nil(body), mod_sofia_globals.hostname, profile->name, - from_user, from_host); + from_user, from_host, event_str); } sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb);