]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-5208 --resolve
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 8 Apr 2013 17:09:44 +0000 (12:09 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 8 Apr 2013 17:10:42 +0000 (12:10 -0500)
src/include/switch_channel.h
src/include/switch_core.h
src/include/switch_ivr.h
src/include/switch_types.h
src/mod/applications/mod_dptools/mod_dptools.c
src/switch_channel.c
src/switch_core_media_bug.c
src/switch_ivr_async.c

index 1ace3893b34aba85643b41954dd37a46928ec882..f7ace52676811ef405d694a6029a7634cad79d75 100644 (file)
@@ -275,6 +275,7 @@ SWITCH_DECLARE(const char *) switch_channel_get_hold_music(switch_channel_t *cha
 SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channel_t *channel);
 
 SWITCH_DECLARE(uint32_t) switch_channel_del_variable_prefix(switch_channel_t *channel, const char *prefix);
+SWITCH_DECLARE(switch_status_t) switch_channel_transfer_variable_prefix(switch_channel_t *orig_channel, switch_channel_t *new_channel, const char *prefix);
 
 #define switch_channel_set_variable_safe(_channel, _var, _val) switch_channel_set_variable_var_check(_channel, _var, _val, SWITCH_FALSE)
 #define switch_channel_set_variable(_channel, _var, _val) switch_channel_set_variable_var_check(_channel, _var, _val, SWITCH_TRUE)
index 1bad6377e83dd0a68518fbddfe8a7d00bd0924bb..19fe5fc08822ff1a2514dec85b52653a904042f3 100644 (file)
@@ -282,6 +282,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all_function(_In_ s
 SWITCH_DECLARE(switch_status_t) switch_core_media_bug_enumerate(switch_core_session_t *session, switch_stream_handle_t *stream);
 SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session);
 
+SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_callback(switch_core_session_t *orig_session, switch_core_session_t *new_session, 
+                                                                                                                                               switch_media_bug_callback_t callback, void * (*user_data_dup_func) (switch_core_session_t *, void *));
+
+
 /*!
   \brief Read a frame from the bug
   \param bug the bug to read from
index daa97cc36476a30ea9746f82f95aa600075a140e..b893fcf07606ae58d90408b8dbb1586161a72631 100644 (file)
@@ -277,6 +277,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(swit
   \return SWITCH_STATUS_SUCCESS if all is well
 */
 SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t *session, char *file, uint32_t limit, switch_file_handle_t *fh);
+SWITCH_DECLARE(switch_status_t) switch_ivr_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session);
 
 
 SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_pop_eavesdropper(switch_core_session_t *session, switch_core_session_t **sessionp);
index 51a9621142a417a4691fefafb1a78c4a61d0eeb1..a0e74ddb997d0dd4d4c05f70621ab8e919596a22 100644 (file)
@@ -139,6 +139,8 @@ SWITCH_BEGIN_EXTERN_C
 #define SWITCH_TRANSFER_HISTORY_VARIABLE "transfer_history"
 #define SWITCH_TRANSFER_SOURCE_VARIABLE "transfer_source"
 #define SWITCH_SENSITIVE_DTMF_VARIABLE "sensitive_dtmf"
+#define SWITCH_RECORD_POST_PROCESS_EXEC_APP_VARIABLE "record_post_process_exec_app"
+#define SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE "record_post_process_exec_api"
 
 #define SWITCH_CHANNEL_EXECUTE_ON_ANSWER_VARIABLE "execute_on_answer"
 #define SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE "execute_on_pre_answer"
index c2052bede6415844f15e10ac9e79a4dfa9d66d64..0990f6e5f0d7b43df451c9efb26bbd7a4bd25195 100755 (executable)
@@ -2267,16 +2267,19 @@ SWITCH_STANDARD_APP(att_xfer_function)
 {
        switch_core_session_t *peer_session = NULL;
        switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
-       switch_channel_t *channel, *peer_channel = NULL;
+       switch_channel_t *channel = switch_core_session_get_channel(session), *peer_channel = NULL;
        const char *bond = NULL;
        switch_core_session_t *b_session = NULL;
+       switch_bool_t follow_recording = switch_true(switch_channel_get_variable(channel, "recording_follow_attxfer"));
        
-       channel = switch_core_session_get_channel(session);
-
        bond = switch_channel_get_partner_uuid(channel);
        switch_channel_set_variable(channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, bond);
        switch_core_event_hook_add_state_change(session, tmp_hanguphook);
 
+       if (follow_recording && (b_session = switch_core_session_locate(bond))) {
+               switch_ivr_transfer_recordings(b_session, session);
+               switch_core_session_rwunlock(b_session);
+       }
 
        if (switch_ivr_originate(session, &peer_session, &cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL)
                != SWITCH_STATUS_SUCCESS || !peer_session) {
@@ -2300,23 +2303,24 @@ SWITCH_STANDARD_APP(att_xfer_function)
        }
 
        if (bond) {
-               char buf[128] = "";
                int br = 0;
 
                switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, bond);
 
                if (!switch_channel_down(peer_channel)) {
                        if (!switch_channel_ready(channel)) {
-                               switch_status_t status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond);
+                               switch_status_t status;
+
+                               if (follow_recording) {
+                                       switch_ivr_transfer_recordings(session, peer_session);
+                               }
+                               status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond);
                                att_xfer_set_result(peer_channel, status);
                                br++;
                        } else if ((b_session = switch_core_session_locate(bond))) {
                                switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
-                               switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session));
-                               switch_channel_set_variable(b_channel, "xfer_uuids", buf);
-
-                               switch_snprintf(buf, sizeof(buf), "%s %s", switch_core_session_get_uuid(peer_session), bond);
-                               switch_channel_set_variable(channel, "xfer_uuids", buf);
+                               switch_channel_set_variable_printf(b_channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), switch_core_session_get_uuid(session));
+                               switch_channel_set_variable_printf(channel, "xfer_uuids", "%s %s", switch_core_session_get_uuid(peer_session), bond);
 
                                switch_core_event_hook_add_state_change(session, hanguphook);
                                switch_core_event_hook_add_state_change(b_session, hanguphook);
index 699ad796101b4f5ecf65b72c3b04e77ed24e7b92..27a5b24d7db97902edf538e64482577a46eb1001 100644 (file)
@@ -1212,6 +1212,26 @@ SWITCH_DECLARE(uint32_t) switch_channel_del_variable_prefix(switch_channel_t *ch
        return r;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_channel_transfer_variable_prefix(switch_channel_t *orig_channel, switch_channel_t *new_channel, const char *prefix)
+{
+       switch_event_header_t *hi = NULL;
+       int x = 0;
+
+       if ((hi = switch_channel_variable_first(orig_channel))) {
+               for (; hi; hi = hi->next) {
+                       char *var = hi->name;
+                       char *val = hi->value;
+
+                       if (zstr(prefix) || !strncasecmp(var, prefix, strlen(prefix))) {
+                               x++;
+                               switch_channel_set_variable(new_channel, var, val);
+                       }
+               }
+               switch_channel_variable_last(orig_channel);
+       }
+       
+       return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+}
 
 SWITCH_DECLARE(void) switch_channel_set_presence_data_vals(switch_channel_t *channel, const char *presence_data_cols)
 {
index c340b71e634ac8f8f6d771467de7b06590f6a80c..c70dbd65790198c7330d5a2adae3b818bab28696 100644 (file)
@@ -618,6 +618,50 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch
        return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
 }
 
+
+SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_callback(switch_core_session_t *orig_session, switch_core_session_t *new_session, 
+                                                                                                                                               switch_media_bug_callback_t callback, void * (*user_data_dup_func) (switch_core_session_t *, void *))
+{
+       switch_media_bug_t *new_bug = NULL, *cur = NULL, *bp = NULL, *last = NULL;
+       int total = 0;
+
+       switch_thread_rwlock_wrlock(orig_session->bug_rwlock);
+       bp = orig_session->bugs;
+       while (bp) {
+               cur = bp;
+               bp = bp->next;
+               
+               if (cur->callback == callback) {
+                       if (last) {
+                               last->next = cur->next;
+                       } else {
+                               orig_session->bugs = cur->next;
+                       }
+
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(orig_session), SWITCH_LOG_DEBUG, "Transfering %s from %s to %s\n", cur->target,
+                                                         switch_core_session_get_name(orig_session), switch_core_session_get_name(new_session));
+
+                       switch_core_media_bug_add(new_session, cur->function, cur->target, cur->callback,
+                                                                         user_data_dup_func(new_session, cur->user_data),
+                                                                         cur->stop_time, cur->flags, &new_bug);
+                       switch_core_media_bug_destroy(cur);
+                       total++;
+               } else {
+                       last = cur;
+               }
+       }
+
+       if (!orig_session->bugs && switch_core_codec_ready(&orig_session->bug_codec)) {
+               switch_core_codec_destroy(&orig_session->bug_codec);
+       }
+
+       switch_thread_rwlock_unlock(orig_session->bug_rwlock);
+
+
+       return total ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+}
+
+
 SWITCH_DECLARE(switch_status_t) switch_core_media_bug_pop(switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop)
 {
        switch_media_bug_t *bp;
index ddb6d8c801ecba36ebb59472856b8d761ee356c2..5e34c464c44e258a5304e0f8a0795c3e10a9d0d4 100644 (file)
@@ -1184,9 +1184,9 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
                                switch_event_fire(&event);
                        }
 
-                       switch_channel_execute_on(channel, "record_post_process_exec_app");
+                       switch_channel_execute_on(channel, SWITCH_RECORD_POST_PROCESS_EXEC_APP_VARIABLE);
 
-                       if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) {
+                       if ((var = switch_channel_get_variable(channel, SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE))) {
                                char *cmd = switch_core_session_strdup(session, var);
                                char *data, *expanded = NULL;
                                switch_stream_handle_t stream = { 0 };
@@ -1260,6 +1260,31 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_record_session(switch_core_sessi
        return SWITCH_STATUS_FALSE;
 }
 
+static void* switch_ivr_record_user_data_dup(switch_core_session_t *session, void *user_data) 
+{
+       struct record_helper *rh = (struct record_helper *) user_data, *dup = NULL;
+
+       dup = switch_core_session_alloc(session, sizeof(*dup));
+       memcpy(dup, rh, sizeof(*rh));
+       dup->file = switch_core_session_strdup(session, rh->file);
+
+       return dup;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session)
+{
+       const char *var = NULL;
+       switch_channel_t *orig_channel = switch_core_session_get_channel(orig_session);
+       switch_channel_t *new_channel = switch_core_session_get_channel(new_session);
+
+       if ((var = switch_channel_get_variable(orig_channel, SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE))) {
+               switch_channel_set_variable(new_channel, SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE, var);
+       }
+       switch_channel_transfer_variable_prefix(orig_channel, new_channel, SWITCH_RECORD_POST_PROCESS_EXEC_APP_VARIABLE);
+       
+       return switch_core_media_bug_transfer_callback(orig_session, new_session, record_callback, switch_ivr_record_user_data_dup);
+}
+
 struct eavesdrop_pvt {
        switch_buffer_t *buffer;
        switch_mutex_t *mutex;