FS-11910: [mod_dptools] add native eavesdrop mode. use app native_eavesdrop args <uuid> [read|write] ... default is read with no flag. Must be same codecs

This commit is contained in:
Anthony Minessale 2019-06-28 18:13:33 -05:00 committed by Andrey Volk
parent bc52339e68
commit eb31e17e6c
3 changed files with 101 additions and 19 deletions

View 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;

View 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);

View 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;