Merge pull request #33 in FS/freeswitch from ~MOY/freeswitch:sip-watch-headers to master
* commit '3df55b9bb5325ed0f7273576264c5aa94a8a6810': Add sip_watched_headers variable to launch events when a SIP message contains a given SIP header
This commit is contained in:
commit
95c387315e
|
@ -72,6 +72,7 @@ static switch_status_t sofia_kill_channel(switch_core_session_t *session, int si
|
|||
*/
|
||||
static switch_status_t sofia_on_init(switch_core_session_t *session)
|
||||
{
|
||||
const char *hval = NULL;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
@ -89,6 +90,23 @@ static switch_status_t sofia_on_init(switch_core_session_t *session)
|
|||
switch_core_media_absorb_sdp(session);
|
||||
}
|
||||
|
||||
if ((hval = switch_channel_get_variable(channel, "sip_watch_headers"))) {
|
||||
char *dupvar = NULL;
|
||||
char *watch_headers[10];
|
||||
unsigned int numhdrs = 0;
|
||||
int i = 0;
|
||||
dupvar = switch_core_session_strdup(session, hval);
|
||||
numhdrs = switch_separate_string(dupvar, ',', watch_headers, switch_arraylen(watch_headers));
|
||||
if (numhdrs) {
|
||||
char **wheaders = switch_core_session_alloc(session, ((numhdrs+1) * sizeof(wheaders[0])));
|
||||
for (i = 0; i < numhdrs; i++) {
|
||||
wheaders[i] = watch_headers[i];
|
||||
}
|
||||
wheaders[i] = NULL;
|
||||
tech_pvt->watch_headers = wheaders;
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING) || switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING_BRIDGE)) {
|
||||
sofia_set_flag(tech_pvt, TFLAG_RECOVERED);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ typedef struct private_object private_object_t;
|
|||
#define MY_EVENT_RECOVERY_RECOVERED "sofia::recovery_recovered"
|
||||
#define MY_EVENT_ERROR "sofia::error"
|
||||
#define MY_EVENT_PROFILE_START "sofia::profile_start"
|
||||
#define MY_EVENT_NOTIFY_WATCHED_HEADER "sofia::notify_watched_header"
|
||||
|
||||
#define MULTICAST_EVENT "multicast::event"
|
||||
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
|
||||
|
@ -805,6 +806,7 @@ struct private_object {
|
|||
sofia_cid_type_t cid_type;
|
||||
uint32_t session_timeout;
|
||||
enum nua_session_refresher session_refresher;
|
||||
char **watch_headers;
|
||||
char *respond_phrase;
|
||||
int respond_code;
|
||||
char *respond_dest;
|
||||
|
|
|
@ -1272,6 +1272,21 @@ static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt)
|
|||
|
||||
}
|
||||
|
||||
static void notify_watched_header(switch_core_session_t *session, const char *msgline, const char *hdrname, const char *hdrval)
|
||||
{
|
||||
switch_event_t *event = NULL;
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Found known watched header in message '%s', %s: %s\n", msgline, hdrname, hdrval);
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_NOTIFY_WATCHED_HEADER) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SIP-Message", msgline);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Header-Name", hdrname);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Header-Value", hdrval);
|
||||
switch_channel_event_set_data(channel, event);
|
||||
switch_event_fire(&event);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed creating event of type %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER);
|
||||
}
|
||||
}
|
||||
|
||||
//sofia_dispatch_event_t *de
|
||||
static void our_sofia_event_callback(nua_event_t event,
|
||||
|
@ -1347,6 +1362,56 @@ static void our_sofia_event_callback(nua_event_t event,
|
|||
}
|
||||
}
|
||||
|
||||
if (session && tech_pvt && tech_pvt->watch_headers && sip) {
|
||||
char msgline[512];
|
||||
int hi;
|
||||
msg_header_t *h = NULL;
|
||||
if (sip->sip_request) {
|
||||
h = (msg_header_t *)sip->sip_request;
|
||||
msg_header_field_e(msgline, sizeof(msgline), h, 0);
|
||||
} else if (sip->sip_status) {
|
||||
h = (msg_header_t *)sip->sip_status;
|
||||
msg_header_field_e(msgline, sizeof(msgline), h, 0);
|
||||
}
|
||||
if (h) {
|
||||
sip_unknown_t *un = NULL;
|
||||
char buf[512];
|
||||
char *c = NULL;
|
||||
|
||||
msgline[sizeof(msgline)-1] = '\0';
|
||||
c = strchr(msgline, '\r');
|
||||
if (c) {
|
||||
*c = '\0';
|
||||
}
|
||||
|
||||
/* Faster (ie hash-based) search here would be nice? ie, make watch_headers a hash? */
|
||||
|
||||
/* Search first in the valid headers */
|
||||
for (h = h->sh_succ; h; h = h->sh_succ) {
|
||||
sip_header_t *sh = (sip_header_t *)h;
|
||||
if (!sh->sh_class->hc_name) {
|
||||
continue;
|
||||
}
|
||||
for (hi = 0; tech_pvt->watch_headers[hi]; hi++) {
|
||||
if (!strcasecmp(tech_pvt->watch_headers[hi], sh->sh_class->hc_name)) {
|
||||
msg_header_field_e(buf, sizeof(buf), h, 0);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
notify_watched_header(session, msgline, sh->sh_class->hc_name, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Search now in the unknown headers */
|
||||
for (un = sip->sip_unknown; un; un = un->un_next) {
|
||||
for (hi = 0; tech_pvt->watch_headers[hi]; hi++) {
|
||||
if (!strcasecmp(tech_pvt->watch_headers[hi], un->un_name)) {
|
||||
notify_watched_header(session, msgline, un->un_name, un->un_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sofia_test_pflag(profile, PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip && (event < nua_r_set_params || event > nua_r_authenticate)) {
|
||||
sip_authorization_t const *authorization = NULL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue