]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7773 [mod_sofia] transfer events #resolve
authorkarl anderson <karl@2600hz.com>
Thu, 2 Apr 2015 23:23:46 +0000 (19:23 -0400)
committerLuis Azedo <luis@2600hz.com>
Fri, 10 Jul 2015 18:46:10 +0000 (19:46 +0100)
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c

index 2bd475fb7ba95c4fff87f71301c4727b36418377..13fb98f63978c8aad864615ace2b4aa22e297d02 100644 (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
index 97a9a88ede9bf0159a60b9d91f542c8400f396d9..22f1699f84e8275b2d025c90f83caf927cdf5ec9 100644 (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);
                                                }
                                        }