]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9942 [mod_sofia] allow intercept for other channels
authorlazedo <luis.azedo@factorlusitano.com>
Wed, 6 Mar 2019 04:38:39 +0000 (04:38 +0000)
committerlazedo <luis.azedo@factorlusitano.com>
Tue, 26 Mar 2019 21:16:11 +0000 (21:16 +0000)
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c

index 46d215a2d5cf1156630761c500bf07e6b8428cdb..56e2c537350e4053c99a84a59e605979f61d9200 100644 (file)
@@ -964,6 +964,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
 switch_status_t sofia_proxy_sip_i_message(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip,
                                                                                  sofia_dispatch_event_t *de, tagi_t tags[]);
 void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[]);
+void sofia_handle_sip_i_invite_replaces(switch_core_session_t *session, switch_channel_t *channel, switch_channel_t *b_channel, char* uuid, private_object_t *tech_pvt, sip_call_info_t *call_info, sofia_profile_t *profile, char *is_nat, sip_t const *sip);
 
 
 void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t **sofia_private, sip_t const *sip,
index 617446e983dfbf770777a10803662c8db4695987..b070862cf4f675feb84c2f4b18ef5edb419f3430 100644 (file)
@@ -11038,182 +11038,22 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
                sofia_private_t *b_private = NULL;
                if ((b_private = nua_handle_magic(bnh))) {
                        switch_core_session_t *b_session = NULL;
-
                        if ((b_session = switch_core_session_locate(b_private->uuid))) {
                                switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
-                               const char *bridge_uuid;
-                               switch_caller_profile_t *orig_cp, *cp;
-                               //const char *sent_name, *sent_number;
-                               orig_cp = switch_channel_get_caller_profile(b_channel);
-                               tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name);
-                               tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number);
-
-                               if (!call_info) {
-                                       tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name);
-                                       tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number);
-                               }
-
-                               if (orig_cp) {
-                                       cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool, orig_cp);
-                                       switch_channel_set_originator_caller_profile(channel, cp);
-                               }
-
-#if 0
-                               sent_name = switch_channel_get_variable(b_channel, "last_sent_callee_id_name");
-                               sent_number = switch_channel_get_variable(b_channel, "last_sent_callee_id_number");
-
-                               if (!zstr(sent_name) && !zstr(sent_number)) {
-                                       tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, sent_name);
-                                       tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, sent_number);
-                               } else {
-                                       if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
-                                               tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name);
-                                               tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number);
-                                       } else {
-                                               tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name);
-                                               tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number);
-                                       }
-                               }
-#endif
-
-                               if (is_nat) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat);
-                               }
-
-                               tech_pvt->caller_profile->dialplan = "inline";
-
-                               bridge_uuid = switch_channel_get_partner_uuid(b_channel);
-
-                               if (call_info) {
-                                       switch_event_t *event = NULL;
-
-                                       if (!zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
-                                               const char *b_call_id = switch_channel_get_variable(b_channel, "sip_call_id");
-
-                                               if (b_call_id) {
-                                                       char *sql = switch_mprintf("update sip_dialogs set call_info_state='idle' where call_id='%q'", b_call_id);
-                                                       if (mod_sofia_globals.debug_sla > 1) {
-                                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
-                                                       }
-                                                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-
-                                                       switch_channel_presence(b_channel, "unknown", "idle", NULL);
-                                               }
-                                               switch_channel_set_flag(tech_pvt->channel, CF_SLA_INTERCEPT);
-                                               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_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);
-
-                                               if (switch_channel_test_flag(b_channel, CF_BRIDGE_ORIGINATOR)) {
-                                                       switch_channel_set_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR);
-                                               }
-
-                                               if (!zstr(bcp->callee_id_name)) {
-                                                       tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_name);
-                                               }
-
-                                               if (!zstr(bcp->callee_id_number)) {
-                                                       tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_number);
-                                               }
-
-
-                                               if (!zstr(bcp->caller_id_name)) {
-                                                       tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_name);
-                                               }
-
-                                               if (!zstr(bcp->caller_id_number)) {
-                                                       tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_number);
-                                               }
-
-                                               if (bcp->originatee_caller_profile) {
-                                                       switch_caller_profile_t *cp;
-
-                                                       cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool,
-                                                                                                                  bcp->originatee_caller_profile);
-
-                                                       switch_channel_set_originatee_caller_profile(tech_pvt->channel, cp);
-                                               }
-
-                                               tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
-                                                                                                                                                                                  "answer,sofia_sla:%s", b_private->uuid);
-                                       }
-                               } else {
-                                       char const *a_leg = NULL;
-                                       char const *nightmare_xfer_uuid = NULL;
-
-                                   switch_event_t *event = NULL;
-                                       if (sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id) {
-                                               a_leg = msg_header_find_param(sip->sip_replaces->rp_common, "a-leg");
-                                       }
-                                       if(a_leg && switch_true(a_leg)) {
-                                               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 ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-For"))) {
-                                                       switch_channel_set_variable(b_channel, "transfer_refer_for", nightmare_xfer_uuid);
-                                               }
-                                               if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-From"))) {
-                                                       switch_channel_set_variable(b_channel, "transfer_refer_from", nightmare_xfer_uuid);
-                                               }
-
-                                               if (!zstr(bridge_uuid)) {
-                                                       if (sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id && switch_channel_test_flag(b_channel, CF_BRIDGED) &&
-                                                               switch_true(switch_find_parameter(*(sip->sip_replaces->rp_params), "early-only", switch_core_session_get_pool(session)))) {
-                                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercept rejected\n", bridge_uuid);
-                                                               tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "hangup:CALL_REJECTED");
-                                                       } else {
-                                                                       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);
-                                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercepted\n", 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);
-                                                       if (b_data && b_app) {
-                                                               tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s:%s", b_app, b_data);
-                                                       } 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);
-                                               }
-                                       }
-                               }
-
+                               sofia_handle_sip_i_invite_replaces(session, channel, b_channel, b_private->uuid, tech_pvt, call_info, profile, is_nat, sip);
                                switch_core_session_rwunlock(b_session);
                        }
                }
                nua_handle_unref(bnh);
+       } else if (sip && sip->sip_replaces && sip->sip_replaces->rp_call_id) {
+               switch_core_session_t *b_session = NULL;
+               if ((b_session = switch_core_session_locate((char*) sip->sip_replaces->rp_call_id))) {
+                               switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
+                               sofia_handle_sip_i_invite_replaces(session, channel, b_channel, (char*) sip->sip_replaces->rp_call_id, tech_pvt, call_info, profile, is_nat, sip);
+                               switch_core_session_rwunlock(b_session);
+               }
        }
 
-
-
        if (tech_pvt->caller_profile) {
 
                int first_history_info = 1;
@@ -11428,6 +11268,183 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 
 }
 
+void sofia_handle_sip_i_invite_replaces(switch_core_session_t *session, switch_channel_t *channel, switch_channel_t *b_channel, char* uuid, private_object_t *tech_pvt, sip_call_info_t *call_info, sofia_profile_t *profile, char *is_nat, sip_t const *sip)
+{
+       const char *bridge_uuid;
+       switch_caller_profile_t *orig_cp, *cp;
+       //const char *sent_name, *sent_number;
+       orig_cp = switch_channel_get_caller_profile(b_channel);
+       tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name);
+       tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number);
+
+       if (!call_info) {
+               tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name);
+               tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number);
+       }
+
+       if (orig_cp) {
+               cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool, orig_cp);
+               switch_channel_set_originator_caller_profile(channel, cp);
+       }
+
+#if 0
+       sent_name = switch_channel_get_variable(b_channel, "last_sent_callee_id_name");
+       sent_number = switch_channel_get_variable(b_channel, "last_sent_callee_id_number");
+
+       if (!zstr(sent_name) && !zstr(sent_number)) {
+               tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, sent_name);
+               tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, sent_number);
+       } else {
+               if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
+                       tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_name);
+                       tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->callee_id_number);
+               } else {
+                       tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_name);
+                       tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, orig_cp->caller_id_number);
+               }
+       }
+#endif
+
+       if (is_nat) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Setting NAT mode based on %s\n", is_nat);
+       }
+
+       tech_pvt->caller_profile->dialplan = "inline";
+
+       bridge_uuid = switch_channel_get_partner_uuid(b_channel);
+       if (bridge_uuid) {
+               switch_core_session_t *bridge_session = NULL;
+               if ((bridge_session = switch_core_session_locate(bridge_uuid))) {
+                       switch_core_session_rwunlock(bridge_session);
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "could not locate partner_uuid %s, resetting\n", bridge_uuid);
+                       bridge_uuid = NULL;
+               }
+       }
+
+       if (call_info) {
+               switch_event_t *event = NULL;
+
+               if (!zstr(bridge_uuid) && switch_channel_test_flag(b_channel, CF_LEG_HOLDING)) {
+                       const char *b_call_id = switch_channel_get_variable(b_channel, "sip_call_id");
+
+                       if (b_call_id) {
+                               char *sql = switch_mprintf("update sip_dialogs set call_info_state='idle' where call_id='%q'", b_call_id);
+                               if (mod_sofia_globals.debug_sla > 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "QUERY SQL %s\n", sql);
+                               }
+                               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+
+                               switch_channel_presence(b_channel, "unknown", "idle", NULL);
+                       }
+                       switch_channel_set_flag(tech_pvt->channel, CF_SLA_INTERCEPT);
+                       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)
+                               && sip && sip->sip_call_id
+                               && 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);
+
+                       if (switch_channel_test_flag(b_channel, CF_BRIDGE_ORIGINATOR)) {
+                               switch_channel_set_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR);
+                       }
+
+                       if (!zstr(bcp->callee_id_name)) {
+                               tech_pvt->caller_profile->callee_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_name);
+                       }
+
+                       if (!zstr(bcp->callee_id_number)) {
+                               tech_pvt->caller_profile->callee_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->callee_id_number);
+                       }
+
+
+                       if (!zstr(bcp->caller_id_name)) {
+                               tech_pvt->caller_profile->caller_id_name = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_name);
+                       }
+
+                       if (!zstr(bcp->caller_id_number)) {
+                               tech_pvt->caller_profile->caller_id_number = switch_core_strdup(tech_pvt->caller_profile->pool, bcp->caller_id_number);
+                       }
+
+                       if (bcp->originatee_caller_profile) {
+                               switch_caller_profile_t *cp;
+
+                               cp = switch_caller_profile_dup(tech_pvt->caller_profile->pool,
+                                                                                          bcp->originatee_caller_profile);
+
+                               switch_channel_set_originatee_caller_profile(tech_pvt->channel, cp);
+                       }
+
+                       tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
+                                                                                                                                                          "answer,sofia_sla:%s", uuid);
+               }
+       } else {
+               char const *nightmare_xfer_uuid = NULL;
+               switch_event_t *event = NULL;
+               if (switch_channel_var_true(channel, "sip_replaces_a-leg")) {
+                       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)
+                               && sip && sip->sip_call_id
+                               && 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 ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-For"))) {
+                               switch_channel_set_variable(b_channel, "transfer_refer_for", nightmare_xfer_uuid);
+                       }
+                       if ((nightmare_xfer_uuid = sofia_glue_get_unknown_header(sip, "X-FS-Refer-From"))) {
+                               switch_channel_set_variable(b_channel, "transfer_refer_from", nightmare_xfer_uuid);
+                       }
+
+                       if (!zstr(bridge_uuid)) {
+                               if (sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id && switch_channel_test_flag(b_channel, CF_BRIDGED) &&
+                                       switch_true(switch_find_parameter(*(sip->sip_replaces->rp_params), "early-only", switch_core_session_get_pool(session)))) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercept rejected\n", bridge_uuid);
+                                       tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "hangup:CALL_REJECTED");
+                               } else {
+                                               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);
+                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercepted\n", bridge_uuid);
+                                               if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS)
+                                                       && sip && sip->sip_call_id
+                                                       && 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);
+                               if (b_data && b_app) {
+                                       tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,%s:%s", b_app, b_data);
+                               } 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)
+                                       && sip && sip->sip_call_id
+                                       && 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);
+                       }
+               }
+       }
+
+}
+
 void sofia_handle_sip_i_options(int status,
                                                                char const *phrase,
                                                                nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,