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:
parent
a524fadf17
commit
863e6cfa3f
|
@ -98,6 +98,8 @@ static const char *EVENT_NAMES[] = {
|
||||||
"MESSAGE",
|
"MESSAGE",
|
||||||
"PRESENCE_IN",
|
"PRESENCE_IN",
|
||||||
"NOTIFY_IN",
|
"NOTIFY_IN",
|
||||||
|
"PHONE_FEATURE",
|
||||||
|
"PHONE_FEATURE_SUBSCRIBE",
|
||||||
"PRESENCE_OUT",
|
"PRESENCE_OUT",
|
||||||
"PRESENCE_PROBE",
|
"PRESENCE_PROBE",
|
||||||
"MESSAGE_WAITING",
|
"MESSAGE_WAITING",
|
||||||
|
|
|
@ -1681,6 +1681,8 @@ typedef uint32_t switch_io_flag_t;
|
||||||
SWITCH_EVENT_RE_SCHEDULE - Something scheduled has been rescheduled
|
SWITCH_EVENT_RE_SCHEDULE - Something scheduled has been rescheduled
|
||||||
SWITCH_EVENT_RELOADXML - XML registry has been reloaded
|
SWITCH_EVENT_RELOADXML - XML registry has been reloaded
|
||||||
SWITCH_EVENT_NOTIFY - Notification
|
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_SEND_MESSAGE - Message
|
||||||
SWITCH_EVENT_RECV_MESSAGE - Message
|
SWITCH_EVENT_RECV_MESSAGE - Message
|
||||||
SWITCH_EVENT_NAT - NAT Management (new/del/status)
|
SWITCH_EVENT_NAT - NAT Management (new/del/status)
|
||||||
|
@ -1748,6 +1750,8 @@ typedef enum {
|
||||||
SWITCH_EVENT_RE_SCHEDULE,
|
SWITCH_EVENT_RE_SCHEDULE,
|
||||||
SWITCH_EVENT_RELOADXML,
|
SWITCH_EVENT_RELOADXML,
|
||||||
SWITCH_EVENT_NOTIFY,
|
SWITCH_EVENT_NOTIFY,
|
||||||
|
SWITCH_EVENT_PHONE_FEATURE,
|
||||||
|
SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE,
|
||||||
SWITCH_EVENT_SEND_MESSAGE,
|
SWITCH_EVENT_SEND_MESSAGE,
|
||||||
SWITCH_EVENT_RECV_MESSAGE,
|
SWITCH_EVENT_RECV_MESSAGE,
|
||||||
SWITCH_EVENT_REQUEST_PARAMS,
|
SWITCH_EVENT_REQUEST_PARAMS,
|
||||||
|
|
|
@ -4582,6 +4582,70 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
|
||||||
return cause;
|
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)
|
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 *to_uri = switch_event_get_header(event, "to-uri");
|
||||||
const char *from_uri = switch_event_get_header(event, "from-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 *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;
|
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) {
|
if (!profile_name) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To-URI header\n");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!from_uri) {
|
if (to_uri && from_uri) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing From-URI header\n");
|
sofia_destination_t *dst = NULL;
|
||||||
return;
|
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) {
|
if (!es) {
|
||||||
es = "message-summary";
|
es = "message-summary";
|
||||||
}
|
}
|
||||||
|
@ -4770,6 +4881,96 @@ static void general_event_handler(switch_event_t *event)
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case SWITCH_EVENT_SEND_MESSAGE:
|
||||||
{
|
{
|
||||||
const char *profile_name = switch_event_get_header(event, "profile");
|
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)
|
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;
|
sofia_profile_t *profile = NULL;
|
||||||
|
@ -5287,6 +5539,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||||
return SWITCH_STATUS_GENERR;
|
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) {
|
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");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
|
|
|
@ -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_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 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:
|
/* For Emacs:
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* mode:c
|
* mode:c
|
||||||
|
|
|
@ -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_ALLOW("SUBSCRIBE")),
|
||||||
TAG_IF(profile->pres_type, NUTAG_ENABLEMESSAGE(1)),
|
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("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("dialog")),
|
||||||
TAG_IF((profile->pres_type || sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)), NUTAG_ALLOW_EVENTS("line-seize")),
|
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")),
|
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("call-info")),
|
||||||
|
|
|
@ -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);
|
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, '+')) {
|
if (to_user && strchr(to_user, '+')) {
|
||||||
char *h;
|
char *h;
|
||||||
if ((proto = (d_user = strdup(to_user)))) {
|
if ((proto = (d_user = strdup(to_user)))) {
|
||||||
|
@ -3991,7 +4024,24 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||||
|
|
||||||
switch_safe_free(sstr);
|
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,"
|
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"
|
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||||
" from sip_subscriptions where hostname='%q' and profile_name='%q' and "
|
" from sip_subscriptions where hostname='%q' and profile_name='%q' and "
|
||||||
|
|
|
@ -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;
|
to_host = to->a_url->url_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!to_user)
|
if (!to_user) {
|
||||||
to_user = from_user;
|
to_user = from_user;
|
||||||
if (!to_host)
|
}
|
||||||
|
if (!to_host) {
|
||||||
to_host = from_host;
|
to_host = from_host;
|
||||||
|
}
|
||||||
|
|
||||||
if (!to_user || !to_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",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can not do authorization without a complete header in REGISTER request from %s:%d\n",
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* Michael Jerris <mike@jerris.com>
|
* Michael Jerris <mike@jerris.com>
|
||||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
* Paul D. Tinsley <pdt at jackhammer.org>
|
||||||
* William King <william.king@quentustech.com>
|
* William King <william.king@quentustech.com>
|
||||||
|
* Raymond Chandler <intralanman@freeswitch.org>
|
||||||
*
|
*
|
||||||
* switch_event.c -- Event System
|
* switch_event.c -- Event System
|
||||||
*
|
*
|
||||||
|
@ -153,6 +154,8 @@ static char *EVENT_NAMES[] = {
|
||||||
"MESSAGE",
|
"MESSAGE",
|
||||||
"PRESENCE_IN",
|
"PRESENCE_IN",
|
||||||
"NOTIFY_IN",
|
"NOTIFY_IN",
|
||||||
|
"PHONE_FEATURE",
|
||||||
|
"PHONE_FEATURE_SUBSCRIBE",
|
||||||
"PRESENCE_OUT",
|
"PRESENCE_OUT",
|
||||||
"PRESENCE_PROBE",
|
"PRESENCE_PROBE",
|
||||||
"MESSAGE_WAITING",
|
"MESSAGE_WAITING",
|
||||||
|
|
Loading…
Reference in New Issue