FS-2731 significantly reworked version of Emmanuel's patch to allow subscribing and notifying for the as-feature-event events. we still need a module to handle the FS events for this automatically... coming soon to a repository near you

This commit is contained in:
Raymond Chandler 2013-08-23 15:54:49 -04:00
parent a524fadf17
commit 863e6cfa3f
8 changed files with 734 additions and 414 deletions

View File

@ -98,6 +98,8 @@ static const char *EVENT_NAMES[] = {
"MESSAGE",
"PRESENCE_IN",
"NOTIFY_IN",
"PHONE_FEATURE",
"PHONE_FEATURE_SUBSCRIBE",
"PRESENCE_OUT",
"PRESENCE_PROBE",
"MESSAGE_WAITING",

View File

@ -1681,6 +1681,8 @@ typedef uint32_t switch_io_flag_t;
SWITCH_EVENT_RE_SCHEDULE - Something scheduled has been rescheduled
SWITCH_EVENT_RELOADXML - XML registry has been reloaded
SWITCH_EVENT_NOTIFY - Notification
SWITCH_EVENT_PHONE_FEATURE - Notification (DND/CFWD/etc)
SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE - Phone feature subscription
SWITCH_EVENT_SEND_MESSAGE - Message
SWITCH_EVENT_RECV_MESSAGE - Message
SWITCH_EVENT_NAT - NAT Management (new/del/status)
@ -1748,6 +1750,8 @@ typedef enum {
SWITCH_EVENT_RE_SCHEDULE,
SWITCH_EVENT_RELOADXML,
SWITCH_EVENT_NOTIFY,
SWITCH_EVENT_PHONE_FEATURE,
SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE,
SWITCH_EVENT_SEND_MESSAGE,
SWITCH_EVENT_RECV_MESSAGE,
SWITCH_EVENT_REQUEST_PARAMS,

View File

@ -4582,6 +4582,70 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
return cause;
}
static int notify_csta_callback(void *pArg, int argc, char **argv, char **columnNames)
{
nua_handle_t *nh;
sofia_profile_t *ext_profile = NULL, *profile = (sofia_profile_t *) pArg;
int i = 0;
char *user = argv[i++];
char *host = argv[i++];
char *contact_in = argv[i++];
char *profile_name = argv[i++];
char *call_id = argv[i++];
char *full_from = argv[i++];
char *full_to = argv[i++];
int expires = atoi(argv[i++]);
char *body = argv[i++];
char *ct = argv[i++];
char *id = NULL;
char *contact;
sofia_destination_t *dst = NULL;
char *route_uri = NULL;
time_t epoch_now = switch_epoch_time_now(NULL);
time_t expires_in = (expires - epoch_now);
char *extra_headers = switch_mprintf("Subscription-State: active, %d\r\n", expires_in);
if (profile_name && strcasecmp(profile_name, profile->name)) {
if ((ext_profile = sofia_glue_find_profile(profile_name))) {
profile = ext_profile;
}
}
id = switch_mprintf("sip:%s@%s", user, host);
switch_assert(id);
contact = sofia_glue_get_url_from_contact(contact_in, 1);
dst = sofia_glue_get_destination((char *) contact);
if (dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
}
//nh = nua_handle(profile->nua, NULL, NUTAG_URL(dst->contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(profile->url), TAG_END());
nh = nua_handle(profile->nua, NULL, NUTAG_URL(dst->contact), SIPTAG_FROM_STR(full_from), SIPTAG_TO_STR(full_to), SIPTAG_CONTACT_STR(profile->url), TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_notify(nh, NUTAG_NEWSUB(1),
TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
SIPTAG_EVENT_STR("as-feature-event"), SIPTAG_CONTENT_TYPE_STR(ct), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END());
switch_safe_free(route_uri);
sofia_glue_free_destination(dst);
free(id);
free(contact);
if (ext_profile) {
sofia_glue_release_profile(ext_profile);
}
return 0;
}
static int notify_callback(void *pArg, int argc, char **argv, char **columnNames)
{
@ -4655,22 +4719,69 @@ static void general_event_handler(switch_event_t *event)
const char *to_uri = switch_event_get_header(event, "to-uri");
const char *from_uri = switch_event_get_header(event, "from-uri");
const char *extra_headers = switch_event_get_header(event, "extra-headers");
const char *contact_uri = switch_event_get_header(event, "contact-uri");
const char *no_sub_state = switch_event_get_header(event, "no-sub-state");
sofia_profile_t *profile;
if (contact_uri) {
if (!es) {
es = "message-summary";
}
if (to_uri || from_uri) {
if (!ct) {
ct = "application/simple-message-summary";
}
if (!to_uri) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To-URI header\n");
if (!profile_name) {
profile_name = "default";
}
if (!(profile = sofia_glue_find_profile(profile_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile %s\n", profile_name);
return;
}
if (!from_uri) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing From-URI header\n");
return;
if (to_uri && from_uri) {
sofia_destination_t *dst = NULL;
nua_handle_t *nh;
char *route_uri = NULL;
char *sip_sub_st = NULL;
dst = sofia_glue_get_destination((char *) contact_uri);
if (dst->route_uri) {
route_uri = sofia_glue_strip_uri(dst->route_uri);
}
nh = nua_handle(profile->nua,
NULL,
NUTAG_URL(dst->contact),
SIPTAG_FROM_STR(from_uri),
SIPTAG_TO_STR(to_uri),
SIPTAG_CONTACT_STR(profile->url),
TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
if (!switch_true(no_sub_state)) {
sip_sub_st = "terminated;reason=noresource";
}
nua_notify(nh,
NUTAG_NEWSUB(1), TAG_IF(sip_sub_st, SIPTAG_SUBSCRIPTION_STATE_STR(sip_sub_st)),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
switch_safe_free(route_uri);
sofia_glue_free_destination(dst);
sofia_glue_release_profile(profile);
}
return;
} else if (to_uri || from_uri) {
if (!es) {
es = "message-summary";
}
@ -4770,6 +4881,96 @@ static void general_event_handler(switch_event_t *event)
}
break;
case SWITCH_EVENT_PHONE_FEATURE:
{
const char *profile_name = switch_event_get_header(event, "profile");
const char *user = switch_event_get_header(event, "user");
const char *host = switch_event_get_header(event, "host");
const char *call_id = switch_event_get_header(event, "call-id");
const char *csta_event = switch_event_get_header(event, "csta-event");
char *ct = "application/x-as-feature-event+xml";
sofia_profile_t *profile;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Phone Feature NOTIFY\n");
if (profile_name && user && host && (profile = sofia_glue_find_profile(profile_name))) {
char *sql;
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "we have all required vars\n");
if (csta_event) {
if (!strcmp(csta_event, "init")) {
char *boundary_string = "UniqueFreeSWITCHBoundary";
switch_stream_handle_t dnd_stream = { 0 };
char *header_name = NULL;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending multipart with DND and CFWD\n");
if ((header_name = switch_event_get_header(event, "forward_immediate"))) {
switch_stream_handle_t fwdi_stream = { 0 };
SWITCH_STANDARD_STREAM(fwdi_stream);
write_csta_xml_chunk(event, fwdi_stream, "ForwardingEvent", "forwardImmediate");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%s] is %d bytes long\n", (char *)fwdi_stream.data, (int)strlen(fwdi_stream.data));
stream.write_function(&stream, "--%s\nContent-Type: application/x-as-feature-event+xml\nContent-Length:%d\nContent-ID:<%s@%s>\n\n%s", boundary_string, strlen(fwdi_stream.data), user, host, fwdi_stream.data);
switch_safe_free(fwdi_stream.data);
}
if ((header_name = switch_event_get_header(event, "forward_busy"))) {
switch_stream_handle_t fwdb_stream = { 0 };
SWITCH_STANDARD_STREAM(fwdb_stream);
write_csta_xml_chunk(event, fwdb_stream, "ForwardingEvent", "forwardBusy");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%s] is %d bytes long\n", (char *)fwdb_stream.data, (int)strlen(fwdb_stream.data));
stream.write_function(&stream, "--%s\nContent-Type: application/x-as-feature-event+xml\nContent-Length:%d\nContent-ID:<%s@%s>\n\n%s", boundary_string, strlen(fwdb_stream.data), user, host, fwdb_stream.data);
switch_safe_free(fwdb_stream.data);
}
if ((header_name = switch_event_get_header(event, "forward_no_answer"))) {
switch_stream_handle_t fwdna_stream = { 0 };
SWITCH_STANDARD_STREAM(fwdna_stream);
write_csta_xml_chunk(event, fwdna_stream, "ForwardingEvent", "forwardNoAns");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%s] is %d bytes long\n", (char *)fwdna_stream.data, (int)strlen(fwdna_stream.data));
stream.write_function(&stream, "--%s\nContent-Type: application/x-as-feature-event+xml\nContent-Length:%d\nContent-ID:<%s@%s>\n\n%s", boundary_string, strlen(fwdna_stream.data), user, host, fwdna_stream.data);
switch_safe_free(fwdna_stream.data);
}
SWITCH_STANDARD_STREAM(dnd_stream);
write_csta_xml_chunk(event, dnd_stream, "DoNotDisturbEvent", NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%s] is %d bytes long\n", (char *)dnd_stream.data, (int)strlen(dnd_stream.data));
stream.write_function(&stream, "--%s\nContent-Type:application/x-as-feature-event+xml\nContent-Length:%d\nContent-ID:<%s@%s>\n\n%s", boundary_string, strlen(dnd_stream.data), user, host, dnd_stream.data);
switch_safe_free(dnd_stream.data);
stream.write_function(&stream, "--%s--\n", boundary_string);
ct = switch_mprintf("multipart/mixed; boundary=\"%s\"", boundary_string);
} else {
// this will need some work to handle the different types of forwarding events
write_csta_xml_chunk(event, stream, csta_event, NULL);
}
}
if (call_id) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,call_id,full_from,full_to,expires,'%q', '%q' "
"from sip_subscriptions where event='as-feature-event' and call_id='%q'", stream.data, ct, call_id);
} else {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,call_id,full_from,full_to,expires,'%q', '%q' "
"from sip_subscriptions where event='as-feature-event' and sip_user='%s' and sip_host='%q'", stream.data, ct, switch_str_nil(user), switch_str_nil(host)
);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query: %s\n", sql);
switch_safe_free(stream.data);
switch_mutex_lock(profile->ireg_mutex);
sofia_glue_execute_sql_callback(profile, NULL, sql, notify_csta_callback, profile);
switch_mutex_unlock(profile->ireg_mutex);
sofia_glue_release_profile(profile);
free(sql);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "missing something\n");
}
}
break;
case SWITCH_EVENT_SEND_MESSAGE:
{
const char *profile_name = switch_event_get_header(event, "profile");
@ -5024,6 +5225,57 @@ static void general_event_handler(switch_event_t *event)
}
}
void write_csta_xml_chunk(switch_event_t *event, switch_stream_handle_t stream, const char *csta_event, char *fwdtype)
{
const char *device = switch_event_get_header(event, "device");
if (csta_event) {
stream.write_function(&stream, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<%s xmlns=\"http://www.ecma-international.org/standards/ecma-323/csta/ed3\">\n", csta_event);
}
if (device) {
stream.write_function(&stream, " <device>%s</device>\n", device);
}
if (!strcmp(csta_event, "DoNotDisturbEvent")) {
const char *dndstatus = switch_event_get_header(event, "doNotDisturbOn");
if (dndstatus) {
stream.write_function(&stream, " <doNotDisturbOn>%s</doNotDisturbOn>\n", dndstatus);
}
} else if(!strcmp(csta_event, "ForwardingEvent")) {
const char *fwdstatus = switch_event_get_header(event, "forwardStatus");
const char *fwdto = NULL;
const char *ringcount = NULL;
if (strcmp("forwardImmediate", fwdtype)) {
fwdto = switch_event_get_header(event, "forward_immediate");
} else if (strcmp("forwardBusy", fwdtype)) {
fwdto = switch_event_get_header(event, "forward_busy");
} else if (strcmp("fowardNoAns", fwdtype)) {
fwdto = switch_event_get_header(event, "forward_no_answer");
ringcount = switch_event_get_header(event, "ringCount");
}
if (fwdtype) {
stream.write_function(&stream, " <forwardingType>%s</forwardingType>\n", fwdtype);
}
if (fwdstatus) {
stream.write_function(&stream, " <forwardStatus>%s</forwardStatus>\n", fwdstatus);
}
if (fwdto) {
stream.write_function(&stream, " <forwardTo>%s</forwardTo>\n", fwdto);
}
if (ringcount) {
stream.write_function(&stream, " <ringCount>%s</ringCount>\n", ringcount);
}
}
if (csta_event) {
stream.write_function(&stream, "</%s>\n", csta_event);
}
}
switch_status_t list_profiles_full(const char *line, const char *cursor, switch_console_callback_match_t **matches, switch_bool_t show_aliases)
{
sofia_profile_t *profile = NULL;
@ -5287,6 +5539,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind(modname, SWITCH_EVENT_PHONE_FEATURE, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind(modname, SWITCH_EVENT_SEND_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;

View File

@ -149,9 +149,9 @@ typedef enum {
typedef struct sofia_dispatch_event_s {
nua_saved_event_t event[1];
nua_handle_t *nh;
nua_event_data_t const *data;
su_time_t when;
nua_handle_t *nh;
nua_event_data_t const *data;
su_time_t when;
sip_t *sip;
nua_t *nua;
sofia_profile_t *profile;
@ -511,10 +511,10 @@ typedef enum {
} sofia_media_options_t;
typedef enum {
PAID_DEFAULT = 0,
PAID_USER,
PAID_USER_DOMAIN,
PAID_VERBATIM
PAID_DEFAULT = 0,
PAID_USER,
PAID_USER_DOMAIN,
PAID_VERBATIM
} sofia_paid_type_t;
#define MAX_RTPIP 50
@ -1117,6 +1117,7 @@ switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **i
void sofia_reg_check_socket(sofia_profile_t *profile, const char *call_id, const char *network_addr, const char *network_ip);
void sofia_reg_close_handles(sofia_profile_t *profile);
void write_csta_xml_chunk(switch_event_t *event, switch_stream_handle_t stream, const char *csta_event, char *fwd_type);
/* For Emacs:
* Local Variables:
* mode:c

View File

@ -1337,11 +1337,11 @@ static void our_sofia_event_callback(nua_event_t event,
referred_by = sofia_glue_get_url_from_contact(sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_referred_by), 0);
ref_by_user = sip->sip_referred_by->b_url->url_user;
}
else if(sip->sip_to && sip->sip_to->a_url)
{
else if(sip->sip_to && sip->sip_to->a_url)
{
referred_by = sofia_glue_get_url_from_contact(sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_to), 0);
ref_by_user = sip->sip_to->a_url->url_user;
}
ref_by_user = sip->sip_to->a_url->url_user;
}
if (sip->sip_to && sip->sip_to->a_url) {
req_user = sip->sip_to->a_url->url_user;
@ -1770,7 +1770,7 @@ void sofia_event_callback(nua_event_t event,
switch(event) {
case nua_i_terminated:
if ((status == 401 || status == 407 || status == 403) && sofia_private && sofia_private->uuid) {
if ((status == 401 || status == 407 || status == 403) && sofia_private && sofia_private->uuid) {
switch_core_session_t *session;
if ((session = switch_core_session_locate(sofia_private->uuid))) {
@ -2075,7 +2075,7 @@ void event_handler(switch_event_t *event)
}
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Expired propagated registration for %s@%s->%s\n", from_user, from_host, contact_str);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Expired propagated registration for %s@%s->%s\n", from_user, from_host, contact_str);
if (profile) {
sofia_glue_release_profile(profile);
@ -2554,6 +2554,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
TAG_IF(profile->pres_type, NUTAG_ALLOW("SUBSCRIBE")),
TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1)),
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence")),
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("as-feature-event")),
TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("dialog")),
TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("line-seize")),
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("call-info")),
@ -3616,16 +3617,16 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
mod_sofia_globals.reg_deny_binding_fetch_and_no_lookup = switch_true(val); /* remove when noone complains about the extra lookup */
if (switch_true(val)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Enabling reg-deny-binding-fetch-and-no-lookup - this functionality is "
"deprecated and will be removed - let FS devs know if you think it should stay\n");
"deprecated and will be removed - let FS devs know if you think it should stay\n");
}
} else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) {
if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) {
/* old behaviour */
mod_sofia_globals.rewrite_multicasted_fs_path = 1;
mod_sofia_globals.rewrite_multicasted_fs_path = 1;
} else if (!strcasecmp(val, "original_server_host")) {
mod_sofia_globals.rewrite_multicasted_fs_path = 2;
mod_sofia_globals.rewrite_multicasted_fs_path = 2;
} else if (!strcasecmp(val, "original_hostname")) {
mod_sofia_globals.rewrite_multicasted_fs_path = 3;
mod_sofia_globals.rewrite_multicasted_fs_path = 3;
} else {
mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE;
}
@ -4670,12 +4671,12 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
} else {
profile->timer_t4 = 4000;
}
} else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
} else {
sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
}
} else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
} else {
sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
}
} else if (!strcasecmp(var, "sip-force-expires")) {
int32_t sip_force_expires = atoi(val);
if (sip_force_expires >= 0) {
@ -5076,7 +5077,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850")
|| !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH")
|| !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) {
tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause);
}
@ -5318,7 +5319,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
redirect_dialstring = stream.data;
switch_channel_set_variable_printf(channel, "sip_redirect_count", "%d", i);
switch_channel_set_variable_printf(channel, "sip_redirect_count", "%d", i);
switch_channel_set_variable(channel, "sip_redirect_dialstring", redirect_dialstring);
switch_channel_set_variable(a_channel, "sip_redirect_dialstring", redirect_dialstring);
@ -6095,7 +6096,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
if (br_b) {
switch_core_session_t *tmp;
switch_core_session_t *tmp;
if (switch_true(switch_channel_get_variable(channel, "recording_follow_transfer")) &&
(tmp = switch_core_session_locate(br_a))) {
@ -6292,7 +6293,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
}
}
other_tech_pvt = switch_core_session_get_private(other_session);
other_tech_pvt = switch_core_session_get_private(other_session);
if(sofia_test_flag(other_tech_pvt, TFLAG_REINVITED)) {
/* The other leg won the reinvite race */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Other leg already handling reinvite, so responding with 491\n");
@ -7461,7 +7462,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if (sofia_test_pflag(profile, PFLAG_EXTENDED_INFO_PARSING)) {
if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
sip->sip_payload && sip->sip_payload->pl_data) {
sip->sip_payload && sip->sip_payload->pl_data) {
if (!strncasecmp(sip->sip_content_type->c_type, "freeswitch", 10)) {

View File

@ -3658,6 +3658,39 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_snprintf(exp_delta_str, sizeof(exp_delta_str), "%ld", exp_delta);
if (!strcmp("as-feature-event", event)) {
sip_authorization_t const *authorization = NULL;
auth_res_t auth_res = AUTH_FORBIDDEN;
char key[128] = "";
switch_event_t *v_event = NULL;
if (sip->sip_authorization) {
authorization = sip->sip_authorization;
} else if (sip->sip_proxy_authorization) {
authorization = sip->sip_proxy_authorization;
}
if (authorization) {
char network_ip[80];
sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL);
auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
(char *) sip->sip_request->rq_method_name, key, sizeof(key), network_ip, &v_event, 0,
REG_REGISTER, to_user, NULL, NULL, NULL);
} else if ( sofia_reg_handle_register(nua, profile, nh, sip, de, REG_REGISTER, key, sizeof(key), &v_event, NULL, NULL, NULL)) {
if (v_event) {
switch_event_destroy(&v_event);
}
goto end;
}
if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
goto end;
}
}
if (to_user && strchr(to_user, '+')) {
char *h;
if ((proto = (d_user = strdup(to_user)))) {
@ -3991,7 +4024,24 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_safe_free(sstr);
if (!strcasecmp(event, "message-summary")) {
if (!strcasecmp(event, "as-feature-event")) {
switch_event_t *event;
char sip_cseq[40] = "";
switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
switch_event_create(&event, SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user", from_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "host", from_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "contact", contact_str);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", call_id);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "cseq", sip_cseq);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hostname", mod_sofia_globals.hostname);
if (sip->sip_payload) {
switch_event_add_body(event, "%s", sip->sip_payload->pl_data);
}
switch_event_fire(&event);
} else if (!strcasecmp(event, "message-summary")) {
if ((sql = switch_mprintf("select proto,sip_user,'%q',sub_to_user,sub_to_host,event,contact,call_id,full_from,"
"full_via,expires,user_agent,accept,profile_name,network_ip"
" from sip_subscriptions where hostname='%q' and profile_name='%q' and "

View File

@ -1240,10 +1240,12 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
to_host = to->a_url->url_host;
}
if (!to_user)
if (!to_user) {
to_user = from_user;
if (!to_host)
}
if (!to_host) {
to_host = from_host;
}
if (!to_user || !to_host) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can not do authorization without a complete header in REGISTER request from %s:%d\n",

View File

@ -27,6 +27,7 @@
* Michael Jerris <mike@jerris.com>
* Paul D. Tinsley <pdt at jackhammer.org>
* William King <william.king@quentustech.com>
* Raymond Chandler <intralanman@freeswitch.org>
*
* switch_event.c -- Event System
*
@ -153,6 +154,8 @@ static char *EVENT_NAMES[] = {
"MESSAGE",
"PRESENCE_IN",
"NOTIFY_IN",
"PHONE_FEATURE",
"PHONE_FEATURE_SUBSCRIBE",
"PRESENCE_OUT",
"PRESENCE_PROBE",
"MESSAGE_WAITING",
@ -2066,9 +2069,9 @@ char *dp;\
olen += (len + l + block);\
cpos = c - data;\
if ((dp = realloc(data, olen))) {\
data = dp;\
c = data + cpos;\
memset(c, 0, olen - cpos);\
data = dp;\
c = data + cpos;\
memset(c, 0, olen - cpos);\
}} \
SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur)