mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-07 22:03:50 +00:00
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)
|
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);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
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);
|
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)) {
|
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);
|
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_RECOVERY_RECOVERED "sofia::recovery_recovered"
|
||||||
#define MY_EVENT_ERROR "sofia::error"
|
#define MY_EVENT_ERROR "sofia::error"
|
||||||
#define MY_EVENT_PROFILE_START "sofia::profile_start"
|
#define MY_EVENT_PROFILE_START "sofia::profile_start"
|
||||||
|
#define MY_EVENT_NOTIFY_WATCHED_HEADER "sofia::notify_watched_header"
|
||||||
|
|
||||||
#define MULTICAST_EVENT "multicast::event"
|
#define MULTICAST_EVENT "multicast::event"
|
||||||
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
|
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
|
||||||
@ -805,6 +806,7 @@ struct private_object {
|
|||||||
sofia_cid_type_t cid_type;
|
sofia_cid_type_t cid_type;
|
||||||
uint32_t session_timeout;
|
uint32_t session_timeout;
|
||||||
enum nua_session_refresher session_refresher;
|
enum nua_session_refresher session_refresher;
|
||||||
|
char **watch_headers;
|
||||||
char *respond_phrase;
|
char *respond_phrase;
|
||||||
int respond_code;
|
int respond_code;
|
||||||
char *respond_dest;
|
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
|
//sofia_dispatch_event_t *de
|
||||||
static void our_sofia_event_callback(nua_event_t event,
|
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)) {
|
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;
|
sip_authorization_t const *authorization = NULL;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user