]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-11910: [mod_dptools] add native eavesdrop mode. use app native_eavesdrop args...
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 28 Jun 2019 23:13:33 +0000 (18:13 -0500)
committerAndrey Volk <andywolk@gmail.com>
Wed, 17 Jul 2019 19:38:23 +0000 (23:38 +0400)
src/include/switch_types.h
src/mod/applications/mod_dptools/mod_dptools.c
src/switch_ivr_async.c

index 43bbf12d03c3e8d93d51175cd47ca736dec56c75..3694739f0bc14157c11df68b1949608a33d69926 100644 (file)
@@ -351,7 +351,9 @@ typedef enum {
        ED_DTMF = (1 << 2),
        ED_COPY_DISPLAY = (1 << 3),
        ED_BRIDGE_READ = (1 << 4),
-       ED_BRIDGE_WRITE = (1 << 5)
+       ED_BRIDGE_WRITE = (1 << 5),
+       ED_TAP_READ = (1 << 6),
+       ED_TAP_WRITE = (1 << 7)
 } switch_eavesdrop_flag_enum_t;
 typedef uint32_t switch_eavesdrop_flag_t;
 
index 94fb59278a066c3e7d2127b05585c7ce8f42d18b..6b8c8ad6c4df9e2dcd1607d3bba6f66c6cae9d13 100644 (file)
@@ -896,6 +896,35 @@ static int e_callback(void *pArg, int argc, char **argv, char **columnNames)
        return 1;
 }
 
+#define native_eavesdrop_SYNTAX "<uuid> [read|write]"
+SWITCH_STANDARD_APP(native_eavesdrop_function)
+{
+       switch_eavesdrop_flag_t flags = ED_TAP_READ;
+       char *argv[2] = { 0 };
+       int argc = 0;
+       char *mydata;
+
+
+       if (zstr(data)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "INVALID ARGS usage (%s)\n", native_eavesdrop_SYNTAX);
+               return;
+       }
+       
+       mydata = switch_core_session_strdup(session, data);
+       argc = switch_split(mydata, ' ', argv);
+
+       if (argc > 1) {
+               if (switch_stristr("read", argv[1])) {
+                       flags |= ED_TAP_READ;
+               } else if (switch_stristr("write", argv[1])) {
+                       flags |= ED_TAP_WRITE;
+               }
+       }
+
+       switch_ivr_eavesdrop_session(session, argv[0], NULL, flags);    
+}
+
+
 #define eavesdrop_SYNTAX "[all | <uuid>]"
 SWITCH_STANDARD_APP(eavesdrop_function)
 {
@@ -6571,6 +6600,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
        SWITCH_ADD_APP(app_interface, "unblock_dtmf", "Stop blocking DTMF", "Stop blocking DTMF", dtmf_unblock_function, "", SAF_SUPPORT_NOMEDIA);
        SWITCH_ADD_APP(app_interface, "intercept", "intercept", "intercept", intercept_function, INTERCEPT_SYNTAX, SAF_NONE);
        SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_MEDIA_TAP);
+       SWITCH_ADD_APP(app_interface, "native_eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", native_eavesdrop_function, native_eavesdrop_SYNTAX, SAF_MEDIA_TAP);
        SWITCH_ADD_APP(app_interface, "three_way", "three way call with a uuid", "three way call with a uuid", three_way_function, threeway_SYNTAX,
                                   SAF_MEDIA_TAP);
        SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
index 7a8995f01a29150a9202226531692df818e8cb6d..e898cf393ede5d7a9d37f33260bd029da757f2d7 100644 (file)
@@ -1848,12 +1848,13 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data
        switch_core_session_t *session = switch_core_media_bug_get_session(bug);
        switch_channel_t *e_channel = switch_core_session_get_channel(ep->eavesdropper);
        int show_spy = 0;
-
+       switch_frame_t *nframe = NULL;
+       
        frame.data = data;
        frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
 
        show_spy = switch_core_media_bug_test_flag(bug, SMBF_SPY_VIDEO_STREAM) || switch_core_media_bug_test_flag(bug, SMBF_SPY_VIDEO_STREAM_BLEG);
-
+       
        if (show_spy) {
                if (!ep->set_decoded_read) {
                        ep->set_decoded_read = 1;
@@ -1891,6 +1892,12 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data
 
                switch_channel_clear_flag_recursive(switch_core_session_get_channel(session), CF_VIDEO_DECODED_READ);
 
+               break;
+       case SWITCH_ABC_TYPE_TAP_NATIVE_WRITE:
+               nframe = switch_core_media_bug_get_native_write_frame(bug);
+               break;
+       case SWITCH_ABC_TYPE_TAP_NATIVE_READ:
+               nframe = switch_core_media_bug_get_native_read_frame(bug);
                break;
        case SWITCH_ABC_TYPE_WRITE:
                break;
@@ -1901,8 +1908,6 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data
                                switch_buffer_zwrite(ep->buffer, frame.data, frame.datalen);
                                switch_buffer_unlock(ep->buffer);
                        }
-               } else {
-                       return SWITCH_FALSE;
                }
                break;
        case SWITCH_ABC_TYPE_READ:
@@ -1990,6 +1995,21 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data
                break;
        }
 
+       if (nframe) {
+               switch_frame_t frame = {0};
+               uint8_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = "";
+               
+               frame = *nframe;
+               frame.data = buf;
+               frame.codec = nframe->codec;
+               
+               memcpy(frame.data, nframe->data, nframe->datalen);
+
+               if (switch_core_session_write_frame(ep->eavesdropper, nframe, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
+                       return SWITCH_FALSE;
+               }
+       }
+       
        return SWITCH_TRUE;
 }
 
@@ -2127,9 +2147,19 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
                        goto end;
                }
 
+               if ((flags & ED_TAP_READ) || (flags & ED_TAP_WRITE)) {
+                       switch_core_session_get_real_read_impl(tsession, &tread_impl);
+                       switch_core_session_get_real_read_impl(session, &read_impl);
+                       
+                       if (strcasecmp(tread_impl.iananame, read_impl.iananame)) {
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codecs do not match which is required for this mode\n");
+                               goto end;
+                       }
+               }
+
                switch_core_session_get_read_impl(tsession, &tread_impl);
                switch_core_session_get_read_impl(session, &read_impl);
-
+               
                if ((id_name = switch_channel_get_variable(tchannel, "eavesdrop_announce_id"))) {
                        const char *tmp = switch_channel_get_variable(tchannel, "eavesdrop_announce_macro");
                        if (tmp) {
@@ -2217,18 +2247,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
 
                ep->eavesdropper = session;
                ep->flags = flags;
-               switch_mutex_init(&ep->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession));
-               switch_buffer_create_dynamic(&ep->buffer, buf_size, buf_size, buf_size);
-               switch_buffer_add_mutex(ep->buffer, ep->mutex);
-
-               switch_mutex_init(&ep->w_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession));
-               switch_buffer_create_dynamic(&ep->w_buffer, buf_size, buf_size, buf_size);
-               switch_buffer_add_mutex(ep->w_buffer, ep->w_mutex);
-
-               switch_mutex_init(&ep->r_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession));
-               switch_buffer_create_dynamic(&ep->r_buffer, buf_size, buf_size, buf_size);
-               switch_buffer_add_mutex(ep->r_buffer, ep->r_mutex);
 
+               if (!(flags & ED_TAP_READ) && !(flags & ED_TAP_WRITE)) {
+                       switch_mutex_init(&ep->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession));
+                       switch_buffer_create_dynamic(&ep->buffer, buf_size, buf_size, buf_size);
+                       switch_buffer_add_mutex(ep->buffer, ep->mutex);
+                       
+                       switch_mutex_init(&ep->w_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession));
+                       switch_buffer_create_dynamic(&ep->w_buffer, buf_size, buf_size, buf_size);
+                       switch_buffer_add_mutex(ep->w_buffer, ep->w_mutex);
+                       
+                       switch_mutex_init(&ep->r_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession));
+                       switch_buffer_create_dynamic(&ep->r_buffer, buf_size, buf_size, buf_size);
+                       switch_buffer_add_mutex(ep->r_buffer, ep->r_mutex);
+               }
+               
                if (flags & ED_BRIDGE_READ) {
                        read_flags = SMBF_READ_STREAM | SMBF_READ_REPLACE;
                }
@@ -2237,6 +2270,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
                        write_flags = SMBF_WRITE_STREAM | SMBF_WRITE_REPLACE;
                }
 
+               if (flags & ED_TAP_READ) {
+                       read_flags = SMBF_TAP_NATIVE_READ;
+                       write_flags = 0;
+               }
+
+               if (flags & ED_TAP_WRITE) {
+                       write_flags = SMBF_TAP_NATIVE_WRITE;
+                       read_flags = 0;
+               }
+               
+
                if (switch_channel_test_flag(session->channel, CF_VIDEO) && switch_channel_test_flag(tsession->channel, CF_VIDEO)) {
                        if ((vval = switch_channel_get_variable(session->channel, "eavesdrop_show_listener_video"))) {
                                if (switch_true(vval) || !strcasecmp(vval, "aleg") || !strcasecmp(vval, "bleg") || !strcasecmp(vval, "both")) {
@@ -2284,6 +2328,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
                name = cp->caller_id_name;
                num = cp->caller_id_number;
 
+               if ((flags & ED_TAP_READ) || (flags & ED_TAP_WRITE)) {
+                       flags &= ~ED_DTMF;
+                       flags &= ~ED_BRIDGE_READ;
+                       flags &= ~ED_BRIDGE_WRITE;
+               }
+               
                if (flags & ED_COPY_DISPLAY) {
                        if (switch_channel_test_flag(tchannel, CF_BRIDGE_ORIGINATOR) || !switch_channel_test_flag(tchannel, CF_BRIDGED)) {
                                name = cp->callee_id_name;
@@ -2425,7 +2475,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
                                }
                        }
 
-                       if (!switch_test_flag(read_frame, SFF_CNG)) {
+                       if (ep->r_buffer && ep->w_buffer && !switch_test_flag(read_frame, SFF_CNG)) {
                                switch_buffer_lock(ep->r_buffer);
                                switch_buffer_zwrite(ep->r_buffer, read_frame->data, read_frame->datalen);
                                switch_buffer_unlock(ep->r_buffer);
@@ -2439,7 +2489,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
                                len = tlen;
                        }
 
-                       if (switch_buffer_inuse(ep->buffer) >= len) {
+                       if (ep->buffer && switch_buffer_inuse(ep->buffer) >= len) {
                                switch_buffer_lock(ep->buffer);
                                while (switch_buffer_inuse(ep->buffer) >= len) {
                                        int tchanged = 0, changed = 0;