提交 321b68c5 authored 作者: Anthony Minessale's avatar Anthony Minessale

these aren't the droids you're looking for, move along....

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6453 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 2dd0e0eb
Wed Apr 25 16:05:00 EDT 2007
date
......@@ -48,7 +48,7 @@ extern "C" {
** Maximum numer of simultaneous connections
*********************************************************************/
#define MAX_CONN 16
#define MAX_CONN 4000
/*********************************************************************
** Server Info Definitions
......@@ -443,6 +443,7 @@ typedef struct _TServer
TList defaultfilenames;
void *defaulthandler;
abyss_bool advertise;
int running;
#ifndef _WIN32
uid_t uid;
gid_t gid;
......
......@@ -770,8 +770,8 @@ ServerRunThreaded(TServer *srv)
c[i].inUse = FALSE;
s=srv->listensock;
while( 1 )
srv->running = 1;
while( srv->running )
{
/* collect all threads resources for closed connections */
for (i=0;i<MAX_CONN;i++)
......
......@@ -41,7 +41,7 @@
#include "xmlrpc_config.h"
/* 16K is the minimum size of stack on Win32 */
#define THREAD_STACK_SIZE (16*1024)
#define THREAD_STACK_SIZE (240*1024)
/*********************************************************************
** Thread
......
......@@ -70,6 +70,11 @@ SWITCH_DECLARE(switch_status_t) switch_buffer_create(switch_memory_pool_t *pool,
SWITCH_DECLARE(switch_status_t) switch_buffer_create_dynamic(switch_buffer_t **buffer, switch_size_t blocksize, switch_size_t start_len,
switch_size_t max_len);
SWITCH_DECLARE(void) switch_buffer_add_mutex(switch_buffer_t *buffer, switch_mutex_t *mutex);
SWITCH_DECLARE(void) switch_buffer_lock(switch_buffer_t *buffer);
SWITCH_DECLARE(switch_status_t) switch_buffer_trylock(switch_buffer_t *buffer);
SWITCH_DECLARE(void) switch_buffer_unlock(switch_buffer_t *buffer);
/*! \brief Get the length of a switch_buffer_t
* \param buffer any buffer of type switch_buffer_t
* \return int size of the buffer.
......@@ -137,6 +142,8 @@ SWITCH_DECLARE(void) switch_buffer_zero(switch_buffer_t *buffer);
*/
SWITCH_DECLARE(void) switch_buffer_destroy(switch_buffer_t **buffer);
SWITCH_DECLARE(switch_size_t) switch_buffer_zwrite(switch_buffer_t *buffer, const void *data, switch_size_t datalen);
/** @} */
SWITCH_END_EXTERN_C
......
......@@ -204,7 +204,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_c
\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_eavesdrop_session(switch_core_session_t *session, const char *uuid, switch_eavesdrop_flag_t flags);
SWITCH_DECLARE(switch_status_t) switch_ivr_displace_session(switch_core_session_t *session, char *file, uint32_t limit, const char *flags);
SWITCH_DECLARE(switch_status_t) switch_ivr_stop_displace_session(switch_core_session_t *session, const char *file);
......
......@@ -165,6 +165,8 @@ SWITCH_DECLARE(void) switch_generate_sln_silence(int16_t *data, uint32_t samples
SWITCH_DECLARE(void) switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol);
///\}
SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples);
SWITCH_END_EXTERN_C
#endif
/* For Emacs:
......
......@@ -129,6 +129,12 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_BITS_PER_BYTE 8
typedef uint8_t switch_byte_t;
typedef enum {
ED_MUX_READ = (1 << 0),
ED_MUX_WRITE = (1 << 1),
ED_DTMF = (1 << 2)
} switch_eavesdrop_flag_t;
typedef enum {
SCF_NONE = 0,
SCF_USE_SQL = ( 1 << 0),
......
......@@ -87,6 +87,29 @@ SWITCH_STANDARD_APP(exe_function)
}
#define eavesdrop_SYNTAX "<uuid>"
SWITCH_STANDARD_APP(eavesdrop_function)
{
char *argv[4];
int argc;
char *lbuf = NULL;
char *uuid;
if (data && (lbuf = switch_core_session_strdup(session, data))
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
uuid = argv[0];
switch_ivr_eavesdrop_session(session, uuid, ED_DTMF);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Usage: %s\n", eavesdrop_SYNTAX);
}
}
#define SET_USER_SYNTAX "<user>@<domain>"
SWITCH_STANDARD_APP(set_user_function)
{
......@@ -1453,6 +1476,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "sched_broadcast", SCHED_BROADCAST_DESCR, SCHED_BROADCAST_DESCR, sched_broadcast_function, "[+]<time> <path> [aleg|bleg|both]", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "sched_transfer", SCHED_TRANSF_DESCR, SCHED_TRANSF_DESCR, sched_transfer_function, "[+]<time> <extension> <dialplan> <context>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "execute_extension", "Execute an extension", "Execute an extension", exe_function, EXE_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "eavesdrop", "eavesdrop on a uuid", "eavesdrop on a uuid", eavesdrop_function, eavesdrop_SYNTAX, SAF_NONE);
SWITCH_ADD_APP(app_interface, "set_user", "Set a User", "Set a User", set_user_function, SET_USER_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_NONE);
......
......@@ -2660,6 +2660,10 @@ SWITCH_STANDARD_API(voicemail_api_function)
char *path_info = NULL;
int rss = 0, xarg = 0;
if (session) {
return SWITCH_STATUS_FALSE;
}
if (stream->event) {
host = switch_event_get_header(stream->event, "http-host");
port = switch_event_get_header(stream->event, "http-port");
......
......@@ -55,6 +55,7 @@ static struct {
char *realm;
char *user;
char *pass;
TServer abyssServer;
} globals;
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_realm, globals.realm);
......@@ -353,7 +354,7 @@ abyss_bool auth_hook(TSession * r)
abyss_bool handler_hook(TSession * r)
{
//char *mime = "text/html";
char buf[512] = "HTTP/1.1 200 OK\n";
char buf[80] = "HTTP/1.1 200 OK\n";
switch_stream_handle_t stream = { 0 };
char *command;
int i, j = 0;
......@@ -542,6 +543,9 @@ abyss_bool handler_hook(TSession * r)
HTTPWrite(r, buf, (uint32_t) strlen(buf));
//HTTPWrite(r, "<pre>\n\n", 7);
/* generation of the date field */
if (DateToString(&r->date, buf)) {
ResponseAddField(r,"Date", buf);
......@@ -559,14 +563,21 @@ abyss_bool handler_hook(TSession * r)
}
snprintf(buf, sizeof(buf), "Connection: close\r\n");
ConnWrite(r->conn, buf, (uint32_t) strlen(buf));
if (switch_api_execute(command, r->query, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
ResponseStatus(r, 200);
r->done = TRUE;
} else {
ResponseStatus(r, 404);
ResponseError(r);
}
//HTTPWriteEnd(r);
SocketClose(&(r->conn->socket));
HTTPWriteEnd(r);
ConnClose(r->conn);
end:
......@@ -661,7 +672,7 @@ static xmlrpc_value *freeswitch_man(xmlrpc_env * const envP, xmlrpc_value * cons
SWITCH_MODULE_RUNTIME_FUNCTION(mod_xml_rpc_runtime)
{
TServer abyssServer;
xmlrpc_registry *registryP;
xmlrpc_env env;
char logfile[512];
......@@ -690,22 +701,23 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_xml_rpc_runtime)
}
snprintf(logfile, sizeof(logfile), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, "freeswitch_http.log");
ServerCreate(&abyssServer, "XmlRpcServer", globals.port, SWITCH_GLOBAL_dirs.htdocs_dir, logfile);
ServerCreate(&globals.abyssServer, "XmlRpcServer", globals.port, SWITCH_GLOBAL_dirs.htdocs_dir, logfile);
xmlrpc_server_abyss_set_handler(&env, &abyssServer, "/RPC2", registryP);
xmlrpc_server_abyss_set_handler(&env, &globals.abyssServer, "/RPC2", registryP);
if (ServerInit(&abyssServer) != TRUE) {
if (ServerInit(&globals.abyssServer) != TRUE) {
globals.running = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to start HTTP Port %d\n", globals.port);
return SWITCH_STATUS_TERM;
}
ServerAddHandler(&abyssServer, handler_hook);
ServerAddHandler(&abyssServer, auth_hook);
ServerAddHandler(&globals.abyssServer, handler_hook);
ServerAddHandler(&globals.abyssServer, auth_hook);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Starting HTTP Port %d, DocRoot [%s]\n", globals.port, SWITCH_GLOBAL_dirs.htdocs_dir);
while (globals.running) {
ServerRunOnce2(&abyssServer, ABYSS_FOREGROUND);
//ServerRunOnce2(&globals.abyssServer, ABYSS_FOREGROUND);
ServerRun(&globals.abyssServer);
}
......@@ -716,7 +728,9 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_xml_rpc_runtime)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_rpc_shutdown)
{
globals.abyssServer.running = 0;
globals.running = 0;
return SWITCH_STATUS_SUCCESS;
}
......
......@@ -46,6 +46,7 @@ struct switch_buffer {
switch_size_t datalen;
switch_size_t max_len;
switch_size_t blocksize;
switch_mutex_t *mutex;
uint32_t flags;
uint32_t id;
int32_t loops;
......@@ -95,6 +96,33 @@ SWITCH_DECLARE(switch_status_t) switch_buffer_create_dynamic(switch_buffer_t **b
return SWITCH_STATUS_MEMERR;
}
SWITCH_DECLARE(void) switch_buffer_add_mutex(switch_buffer_t *buffer, switch_mutex_t *mutex)
{
buffer->mutex = mutex;
}
SWITCH_DECLARE(void) switch_buffer_lock(switch_buffer_t *buffer)
{
if (buffer->mutex) {
switch_mutex_lock(buffer->mutex);
}
}
SWITCH_DECLARE(switch_status_t) switch_buffer_trylock(switch_buffer_t *buffer)
{
if (buffer->mutex) {
return switch_mutex_lock(buffer->mutex);
}
return SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(void) switch_buffer_unlock(switch_buffer_t *buffer)
{
if (buffer->mutex) {
switch_mutex_unlock(buffer->mutex);
}
}
SWITCH_DECLARE(switch_size_t) switch_buffer_len(switch_buffer_t *buffer)
{
......@@ -224,7 +252,7 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, const
}
*/
if (switch_test_flag(buffer, SWITCH_BUFFER_FLAG_DYNAMIC)) {
if (freespace < datalen) {
if (freespace < datalen && (!buffer->max_len || (buffer->datalen + datalen <= buffer->max_len))) {
switch_size_t new_size, new_block_size;
new_size = buffer->datalen + datalen;
......@@ -266,6 +294,18 @@ SWITCH_DECLARE(void) switch_buffer_zero(switch_buffer_t *buffer)
buffer->head = buffer->data;
}
SWITCH_DECLARE(switch_size_t) switch_buffer_zwrite(switch_buffer_t *buffer, const void *data, switch_size_t datalen)
{
switch_size_t w;
if (!(w = switch_buffer_write(buffer, data, datalen))) {
switch_buffer_zero(buffer);
return switch_buffer_write(buffer, data, datalen);
}
return w;
}
SWITCH_DECLARE(void) switch_buffer_destroy(switch_buffer_t **buffer)
{
if (buffer && *buffer) {
......
......@@ -150,7 +150,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
goto done;
}
if ((*frame)->codec->implementation->actual_samples_per_second != session->write_codec->implementation->actual_samples_per_second) {
if ((*frame)->codec->implementation->actual_samples_per_second != session->read_codec->implementation->actual_samples_per_second) {
do_resample = 1;
}
......@@ -246,7 +246,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
}
}
switch_mutex_unlock(bp->read_mutex);
} else if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
}
if (switch_test_flag(bp, SMBF_READ_REPLACE)) {
do_bugs = 0;
if (bp->callback) {
bp->read_replace_frame_in = read_frame;
......@@ -432,7 +434,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
need_codec = 1;
}
if (frame->codec->implementation->actual_samples_per_second != session->read_codec->implementation->actual_samples_per_second) {
if (frame->codec->implementation->actual_samples_per_second != session->write_codec->implementation->actual_samples_per_second) {
need_codec = 1;
do_resample = 1;
}
......@@ -489,6 +491,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
return status;
}
}
if (session->write_resampler) {
short *data = write_frame->data;
......@@ -509,6 +512,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
write_frame->rate = session->write_resampler->to_rate;
}
if (do_bugs) {
do_write = 1;
write_frame = frame;
goto done;
}
if (session->bugs) {
switch_media_bug_t *bp, *dp, *last = NULL;
......@@ -525,7 +534,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
if (bp->callback) {
ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_WRITE);
}
} else if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
}
if (switch_test_flag(bp, SMBF_WRITE_REPLACE)) {
do_bugs = 0;
if (bp->callback) {
bp->write_replace_frame_in = write_frame;
......@@ -561,12 +572,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
switch_thread_rwlock_unlock(session->bug_rwlock);
}
if (do_bugs) {
do_write = 1;
write_frame = frame;
goto done;
}
if (session->write_codec) {
if (write_frame->datalen == session->write_codec->implementation->bytes_per_frame) {
perfect = TRUE;
......
......@@ -130,7 +130,8 @@ static void switch_core_standard_on_execute(switch_core_session_t *session)
while (switch_channel_get_state(session->channel) == CS_EXECUTE && extension->current_application) {
char *expanded = NULL;
int nomedia = 0;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Execute %s(%s)\n",
extension->current_application->application_name, switch_str_nil(extension->current_application->application_data));
if ((application_interface = switch_loadable_module_get_application_interface(extension->current_application->application_name)) == 0) {
......@@ -138,19 +139,19 @@ static void switch_core_standard_on_execute(switch_core_session_t *session)
switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return;
}
if (switch_channel_test_flag(session->channel, CF_BYPASS_MEDIA) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application %s Cannot be used with NO_MEDIA mode!\n",
extension->current_application->application_name);
switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return;
}
if (!application_interface->application_function) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Function for %s\n", extension->current_application->application_name);
switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return;
}
if (switch_channel_test_flag(session->channel, CF_BYPASS_MEDIA) && !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA)) {
switch_ivr_media(session->uuid_str, SMF_NONE);
nomedia++;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application %s Requires media!\n",
extension->current_application->application_name);
}
if ((expanded =
switch_channel_expand_variables(session->channel,
......@@ -177,6 +178,12 @@ static void switch_core_standard_on_execute(switch_core_session_t *session)
goto top;
}
if (nomedia) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application %s Releasing media\n",
extension->current_application->application_name);
switch_ivr_nomedia(session->uuid_str, SMF_NONE);
}
extension->current_application = extension->current_application->next;
}
......
......@@ -307,6 +307,274 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_record_session(switch_core_sessi
}
struct eavesdrop_pvt {
switch_buffer_t *buffer;
switch_mutex_t *mutex;
switch_buffer_t *r_buffer;
switch_mutex_t *r_mutex;
switch_buffer_t *w_buffer;
switch_mutex_t *w_mutex;
uint32_t flags;
};
static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) user_data;
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_frame_t frame = { 0 };
frame.data = data;
frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
switch (type) {
case SWITCH_ABC_TYPE_INIT:
break;
case SWITCH_ABC_TYPE_CLOSE:
break;
case SWITCH_ABC_TYPE_WRITE:
if (ep->buffer) {
if (switch_core_media_bug_read(bug, &frame) == SWITCH_STATUS_SUCCESS) {
switch_buffer_lock(ep->buffer);
switch_buffer_zwrite(ep->buffer, frame.data, frame.datalen);
switch_buffer_unlock(ep->buffer);
}
} else {
return SWITCH_FALSE;
}
break;
case SWITCH_ABC_TYPE_READ:
break;
case SWITCH_ABC_TYPE_READ_REPLACE:
{
if (switch_test_flag(ep, ED_MUX_READ)) {
switch_frame_t *frame = switch_core_media_bug_get_read_replace_frame(bug);
if (switch_buffer_inuse(ep->r_buffer) >= frame->datalen) {
uint32_t bytes;
switch_buffer_lock(ep->r_buffer);
bytes = (uint32_t) switch_buffer_read(ep->r_buffer, data, frame->datalen);
frame->datalen = switch_merge_sln(frame->data, frame->samples, (int16_t *)data, bytes / 2) * 2;
frame->samples = frame->datalen / 2;
switch_buffer_unlock(ep->r_buffer);
switch_core_media_bug_set_read_replace_frame(bug, frame);
}
}
}
break;
case SWITCH_ABC_TYPE_WRITE_REPLACE:
{
if (switch_test_flag(ep, ED_MUX_WRITE)) {
switch_frame_t *frame = switch_core_media_bug_get_write_replace_frame(bug);
if (switch_buffer_inuse(ep->w_buffer) >= frame->datalen) {
uint32_t bytes;
switch_buffer_lock(ep->w_buffer);
bytes = (uint32_t) switch_buffer_read(ep->w_buffer, data, frame->datalen);
frame->datalen = switch_merge_sln(frame->data, frame->samples, (int16_t *)data, bytes / 2) * 2;
frame->samples = frame->datalen / 2;
switch_buffer_unlock(ep->w_buffer);
switch_core_media_bug_set_write_replace_frame(bug, frame);
}
}
}
break;
default:
break;
}
return SWITCH_TRUE;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session_t *session, const char *uuid, switch_eavesdrop_flag_t flags)
{
switch_core_session_t *tsession;
switch_status_t status = SWITCH_STATUS_FALSE;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
if ((tsession = switch_core_session_locate(uuid))) {
struct eavesdrop_pvt ep = { 0 };
switch_media_bug_t *bug = NULL;
switch_channel_t *tchannel = switch_core_session_get_channel(tsession);
switch_frame_t *read_frame, write_frame = { 0 };
switch_codec_t codec = {0};
int16_t buf[1024];
switch_codec_t *tread_codec = switch_core_session_get_read_codec(tsession);
switch_channel_pre_answer(channel);
if (switch_core_codec_init(&codec,
"L16",
NULL,
tread_codec->implementation->actual_samples_per_second,
tread_codec->implementation->microseconds_per_frame / 1000,
tread_codec->implementation->number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot init codec\n");
return status;
}
switch_core_session_set_read_codec(session, &codec);
write_frame.codec = &codec;
write_frame.data = buf;
write_frame.buflen = sizeof(buf);
write_frame.rate = read_codec->implementation->actual_samples_per_second;
ep.flags = flags;
switch_mutex_init(&ep.mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession));
switch_buffer_create_dynamic(&ep.buffer, 1024, 2048, 2048);
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, 1024, 2048, 2048);
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, 1024, 2048, 2048);
switch_buffer_add_mutex(ep.r_buffer, ep.r_mutex);
if (switch_core_media_bug_add(tsession, eavesdrop_callback, &ep, 0,
SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_REPLACE | SMBF_WRITE_REPLACE,
&bug) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot attach bug\n");
goto end;
}
while(switch_channel_ready(tchannel) && switch_channel_ready(channel)) {
uint32_t len = sizeof(buf);
switch_event_t *event = NULL;
char *fcommand = NULL;
status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
goto end;
}
if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
char *command = switch_event_get_header(event, "eavesdrop-command");
if (command) {
fcommand = command;
}
switch_event_destroy(&event);
}
if ((flags & ED_DTMF) && switch_channel_has_dtmf(channel)) {
char dtmf[128] = "";
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
fcommand = dtmf;
}
if (fcommand) {
char *d;
for(d = fcommand; *d; d++) {
int z = 1;
switch (*d) {
case '1':
switch_set_flag((&ep), ED_MUX_READ);
switch_clear_flag((&ep), ED_MUX_WRITE);
break;
case '2':
switch_set_flag((&ep), ED_MUX_WRITE);
switch_clear_flag((&ep), ED_MUX_READ);
break;
case '3':
switch_set_flag((&ep), ED_MUX_READ);
switch_set_flag((&ep), ED_MUX_WRITE);
break;
case '0':
switch_clear_flag((&ep), ED_MUX_READ);
switch_clear_flag((&ep), ED_MUX_WRITE);
break;
default:
z = 0;
break;
}
if (z) {
switch_buffer_lock(ep.r_buffer);
switch_buffer_zero(ep.r_buffer);
switch_buffer_unlock(ep.r_buffer);
switch_buffer_lock(ep.w_buffer);
switch_buffer_zero(ep.w_buffer);
switch_buffer_unlock(ep.w_buffer);
}
}
}
if (!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);
switch_buffer_lock(ep.w_buffer);
switch_buffer_zwrite(ep.w_buffer, read_frame->data, read_frame->datalen);
switch_buffer_unlock(ep.w_buffer);
}
if (len > tread_codec->implementation->samples_per_frame * 2) {
len = tread_codec->implementation->samples_per_frame * 2;
}
if (switch_buffer_inuse(ep.buffer) >= len) {
switch_buffer_lock(ep.buffer);
write_frame.datalen = switch_buffer_read(ep.buffer, buf, len);
write_frame.samples = write_frame.datalen / 2;
if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
goto end;
}
switch_buffer_unlock(ep.buffer);
}
}
end:
switch_core_codec_destroy(&codec);
if (bug) {
switch_core_media_bug_remove(tsession, &bug);
}
if (ep.buffer) {
switch_buffer_destroy(&ep.buffer);
}
if (ep.r_buffer) {
switch_buffer_destroy(&ep.r_buffer);
}
if (ep.w_buffer) {
switch_buffer_destroy(&ep.w_buffer);
}
switch_core_session_rwunlock(tsession);
status = SWITCH_STATUS_SUCCESS;
switch_core_session_set_read_codec(session, read_codec);
switch_core_session_reset(session);
}
return status;
}
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_channel_t *channel;
......
......@@ -215,6 +215,27 @@ SWITCH_DECLARE(void) switch_generate_sln_silence(int16_t *data, uint32_t samples
}
}
SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples)
{
int i;
int32_t x, z;
if (samples > other_samples) {
x = other_samples;
} else {
x = samples;
}
for(i = 0; i < x; i++) {
z = data[i] + other_data[i];
switch_normalize_to_16bit(z);
data[i] = (int16_t) z;
}
return x;
}
SWITCH_DECLARE(void) switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol)
{
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论