Merge pull request #319 in FS/freeswitch from ~LAZEDO/freeswitch:feature/aditional_sofia_events to master

* commit '58043483cdb0ffdedcfa9c6dfacded7dcbe41191':
  FS-7773 [mod_sofia] transfer events #resolve
This commit is contained in:
Mike Jerris 2015-07-10 14:49:27 -05:00
commit 79af34c59b
2 changed files with 122 additions and 0 deletions

View File

@ -98,6 +98,11 @@ typedef struct private_object private_object_t;
#define MY_EVENT_PROFILE_START "sofia::profile_start"
#define MY_EVENT_NOTIFY_WATCHED_HEADER "sofia::notify_watched_header"
#define MY_EVENT_TRANSFEROR "sofia::transferor"
#define MY_EVENT_TRANSFEREE "sofia::transferee"
#define MY_EVENT_REPLACED "sofia::replaced"
#define MY_EVENT_INTERCEPTED "sofia::intercepted"
#define MULTICAST_EVENT "multicast::event"
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
#define SOFIA_CHAT_PROTO "sip"
@ -284,6 +289,7 @@ typedef enum {
PFLAG_AUTH_SUBSCRIPTIONS,
PFLAG_PROXY_REFER,
PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER,
PFLAG_FIRE_TRANFER_EVENTS,
/* No new flags below this line */
PFLAG_MAX

View File

@ -4189,6 +4189,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
//sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER);
sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
profile->shutdown_type = "false";
profile->local_network = "localnet.auto";
sofia_set_flag(profile, TFLAG_ENABLE_SOA);
@ -5451,6 +5452,12 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER);
}
} else if (!strcasecmp(var, "fire-transfer-events")) {
if(switch_true(val)) {
sofia_set_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
} else {
sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
}
}
}
@ -7812,6 +7819,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
char *full_ref_to = NULL;
nightmare_xfer_helper_t *nightmare_xfer_helper;
switch_memory_pool_t *npool;
switch_event_t *event = NULL;
if (!(profile->mflags & MFLAG_REFER)) {
nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
@ -8034,6 +8042,24 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
moh = NULL;
}
if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel_b, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
switch_event_fire(&event);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel_a, event);
switch_event_fire(&event);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(a_channel, event);
switch_event_fire(&event);
}
}
if (moh) {
char *xdest;
xdest = switch_core_session_sprintf(a_session, "endless_playback:%s,park", moh);
@ -8080,6 +8106,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
} else if (br_a && br_b) {
switch_core_session_t *tmp = NULL;
switch_event_t *event = NULL;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Attended Transfer [%s][%s]\n",
switch_str_nil(br_a), switch_str_nil(br_b));
@ -8122,6 +8149,30 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
mark_transfer_record(session, br_a, br_b);
if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel_b, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", br_a);
switch_event_fire(&event);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel_a, event);
switch_event_fire(&event);
}
if ((tmp = switch_core_session_locate(br_a))) {
switch_channel_t *tchannel = switch_core_session_get_channel(tmp);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(tchannel, event);
switch_event_fire(&event);
}
switch_core_session_rwunlock(tmp);
}
}
switch_ivr_uuid_bridge(br_a, br_b);
switch_channel_set_variable(channel_b, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER");
nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), SIPTAG_CONTENT_TYPE_STR("message/sipfrag;version=2.0"),
@ -8145,6 +8196,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
} else {
switch_core_session_t *t_session, *hup_session;
switch_channel_t *hup_channel;
switch_event_t *event = NULL;
const char *ext;
if (br_a && !br_b) {
@ -8181,6 +8233,18 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_core_media_bug_transfer_recordings(hup_session, t_session);
}
if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel_a, event);
switch_event_fire(&event);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(t_channel, event);
switch_event_fire(&event);
}
}
if (idest) {
switch_ivr_session_transfer(t_session, idest, "inline", NULL);
} else {
@ -8326,6 +8390,18 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_event_add_header_string(nightmare_xfer_helper->vars, SWITCH_STACK_BOTTOM, SOFIA_REFER_TO_VARIABLE, full_ref_to);
}
if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel_a, event);
switch_event_fire(&event);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel, event);
switch_event_fire(&event);
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Good Luck, you'll need it......\n");
launch_nightmare_xfer(nightmare_xfer_helper);
@ -8365,6 +8441,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
if (!zstr(br) && (b_session = switch_core_session_locate(br))) {
const char *var;
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
switch_event_t *event = NULL;
switch_channel_set_variable(channel, "transfer_fallback_extension", from->a_user);
if (!zstr(full_ref_by)) {
@ -8402,6 +8479,18 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_channel_set_variable(b_channel, "sip_h_X-FS-Refer-Params", refer_to->r_url->url_params);
}
if(sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)) {
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEROR) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(channel_a, event);
switch_event_fire(&event);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_TRANSFEREE) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(b_channel, event);
switch_event_fire(&event);
}
}
switch_ivr_session_transfer(b_session, exten, NULL, NULL);
switch_core_session_rwunlock(b_session);
} else {
@ -9939,6 +10028,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
switch_core_session_t *os;
switch_codec_implementation_t read_impl = { 0 };
char *codec_str = "";
switch_event_t *event = NULL;
if (!zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
olu = bridge_uuid;
@ -9969,6 +10059,13 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
switch_channel_set_flag(tech_pvt->channel, CF_SLA_INTERCEPT);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
"%sanswer,intercept:%s", codec_str, bridge_uuid);
if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
&& switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(b_channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
switch_event_fire(&event);
}
} else {
switch_caller_profile_t *bcp = switch_channel_get_caller_profile(b_channel);
@ -10007,6 +10104,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
}
} else {
char *a_leg = NULL;
switch_event_t *event = NULL;
if (sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id) {
a_leg = switch_find_parameter(*(sip->sip_replaces->rp_params), "a-leg", switch_core_session_get_pool(session));
}
@ -10014,10 +10112,22 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
switch_channel_mark_hold(b_channel, SWITCH_FALSE);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", sip->sip_replaces->rp_call_id);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s picked up on a-leg\n", sip->sip_replaces->rp_call_id);
if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
&& switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(b_channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
switch_event_fire(&event);
}
} else {
if (!zstr(bridge_uuid)) {
switch_channel_mark_hold(b_channel, SWITCH_FALSE);
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid);
if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
&& switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(b_channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id);
switch_event_fire(&event);
}
} else {
const char *b_app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE);
const char *b_data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE);
@ -10026,6 +10136,12 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
} else if (b_app) {
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s", b_app);
}
if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
&& switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_REPLACED) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(b_channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "att_xfer_replaced_by", sip->sip_call_id->i_id);
switch_event_fire(&event);
}
switch_channel_hangup(b_channel, SWITCH_CAUSE_ATTENDED_TRANSFER);
}
}