Merge remote branch 'origin/master'

This commit is contained in:
Moises Silva 2010-11-30 17:22:57 -05:00
commit b6d024eae6
12 changed files with 419 additions and 117 deletions

View File

@ -135,6 +135,7 @@ struct switch_core_session {
switch_mutex_t *frame_read_mutex;
switch_thread_rwlock_t *rwlock;
switch_thread_rwlock_t *io_rwlock;
void *streams[SWITCH_MAX_STREAMS];
int stream_count;

View File

@ -354,6 +354,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void);
///\ingroup core1
///\{
SWITCH_DECLARE(switch_status_t) switch_core_session_io_read_lock(switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_core_session_io_write_lock(switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_core_session_io_rwunlock(switch_core_session_t *session);
#ifdef SWITCH_DEBUG_RWLOCKS
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock(_In_ switch_core_session_t *session, const char *file, const char *func, int line);
#endif

View File

@ -874,6 +874,11 @@ SWITCH_DECLARE(void) switch_ivr_dmachine_set_input_timeout_ms(switch_ivr_dmachin
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
SWITCH_DECLARE(switch_status_t) switch_ivr_get_file_handle(switch_core_session_t *session, switch_file_handle_t **fh);
SWITCH_DECLARE(switch_status_t) switch_ivr_release_file_handle(switch_core_session_t *session, switch_file_handle_t **fh);
SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp);
/** @} */
SWITCH_END_EXTERN_C

View File

@ -3968,6 +3968,47 @@ SWITCH_STANDARD_API(uuid_getvar_function)
return SWITCH_STATUS_SUCCESS;
}
#define FILEMAN_SYNTAX "<uuid> <cmd>:<val>"
SWITCH_STANDARD_API(uuid_fileman_function)
{
switch_core_session_t *psession = NULL;
char *mycmd = NULL, *argv[4] = { 0 };
int argc = 0;
if (!zstr(cmd) && (mycmd = strdup(cmd))) {
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
if (argc >= 2 && !zstr(argv[0])) {
char *uuid = argv[0];
char *cmd = argv[1];
if ((psession = switch_core_session_locate(uuid))) {
switch_channel_t *channel;
switch_file_handle_t *fh = NULL;
channel = switch_core_session_get_channel(psession);
if (switch_ivr_get_file_handle(psession, &fh) == SWITCH_STATUS_SUCCESS) {
switch_ivr_process_fh(psession, cmd, fh);
switch_ivr_release_file_handle(psession, &fh);
}
switch_core_session_rwunlock(psession);
} else {
stream->write_function(stream, "-ERR No Such Channel!\n");
}
goto done;
}
}
stream->write_function(stream, "-USAGE: %s\n", GETVAR_SYNTAX);
done:
switch_safe_free(mycmd);
return SWITCH_STATUS_SUCCESS;
}
#define UUID_SEND_DTMF_SYNTAX "<uuid> <dtmf_data>"
SWITCH_STANDARD_API(uuid_send_dtmf_function)
{
@ -4674,6 +4715,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "uuid_display", "change display", uuid_display_function, DISPLAY_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_dump", "uuid_dump", uuid_dump_function, DUMP_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_exists", "see if a uuid exists", uuid_exists_function, EXISTS_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_fileman", "uuid_fileman", uuid_fileman_function, FILEMAN_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_flush_dtmf", "Flush dtmf on a given uuid", uuid_flush_dtmf_function, "<uuid>");
SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "uuid_getvar", uuid_getvar_function, GETVAR_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_hold", "hold", uuid_hold_function, HOLD_SYNTAX);
@ -4785,6 +4827,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_console_set_complete("add uuid_display ::console::list_uuid");
switch_console_set_complete("add uuid_dump ::console::list_uuid");
switch_console_set_complete("add uuid_exists ::console::list_uuid");
switch_console_set_complete("add uuid_fileman ::console::list_uuid");
switch_console_set_complete("add uuid_flush_dtmf ::console::list_uuid");
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
switch_console_set_complete("add uuid_hold ::console::list_uuid");

View File

@ -6744,6 +6744,42 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_destroy() {
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_io_read_lock(void * jarg1) {
int jresult ;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
switch_status_t result;
arg1 = (switch_core_session_t *)jarg1;
result = (switch_status_t)switch_core_session_io_read_lock(arg1);
jresult = result;
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_io_write_lock(void * jarg1) {
int jresult ;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
switch_status_t result;
arg1 = (switch_core_session_t *)jarg1;
result = (switch_status_t)switch_core_session_io_write_lock(arg1);
jresult = result;
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_io_rwunlock(void * jarg1) {
int jresult ;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
switch_status_t result;
arg1 = (switch_core_session_t *)jarg1;
result = (switch_status_t)switch_core_session_io_rwunlock(arg1);
jresult = result;
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_read_lock(void * jarg1) {
int jresult ;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
@ -28317,6 +28353,50 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_set_realm(void * jarg1, ch
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_get_file_handle(void * jarg1, void * jarg2) {
int jresult ;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
switch_file_handle_t **arg2 = (switch_file_handle_t **) 0 ;
switch_status_t result;
arg1 = (switch_core_session_t *)jarg1;
arg2 = (switch_file_handle_t **)jarg2;
result = (switch_status_t)switch_ivr_get_file_handle(arg1,arg2);
jresult = result;
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_release_file_handle(void * jarg1, void * jarg2) {
int jresult ;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
switch_file_handle_t **arg2 = (switch_file_handle_t **) 0 ;
switch_status_t result;
arg1 = (switch_core_session_t *)jarg1;
arg2 = (switch_file_handle_t **)jarg2;
result = (switch_status_t)switch_ivr_release_file_handle(arg1,arg2);
jresult = result;
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_process_fh(void * jarg1, char * jarg2, void * jarg3) {
int jresult ;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
char *arg2 = (char *) 0 ;
switch_file_handle_t *arg3 = (switch_file_handle_t *) 0 ;
switch_status_t result;
arg1 = (switch_core_session_t *)jarg1;
arg2 = (char *)jarg2;
arg3 = (switch_file_handle_t *)jarg3;
result = (switch_status_t)switch_ivr_process_fh(arg1,(char const *)arg2,arg3);
jresult = result;
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RTP_MAX_BUF_LEN_get() {
int jresult ;
int result;

View File

@ -1103,6 +1103,21 @@ public class freeswitch {
return ret;
}
public static switch_status_t switch_core_session_io_read_lock(SWIGTYPE_p_switch_core_session session) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_io_read_lock(SWIGTYPE_p_switch_core_session.getCPtr(session));
return ret;
}
public static switch_status_t switch_core_session_io_write_lock(SWIGTYPE_p_switch_core_session session) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_io_write_lock(SWIGTYPE_p_switch_core_session.getCPtr(session));
return ret;
}
public static switch_status_t switch_core_session_io_rwunlock(SWIGTYPE_p_switch_core_session session) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_io_rwunlock(SWIGTYPE_p_switch_core_session.getCPtr(session));
return ret;
}
public static switch_status_t switch_core_session_read_lock(SWIGTYPE_p_switch_core_session session) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_read_lock(SWIGTYPE_p_switch_core_session.getCPtr(session));
return ret;
@ -4471,6 +4486,21 @@ public class freeswitch {
return ret;
}
public static switch_status_t switch_ivr_get_file_handle(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_p_switch_file_handle fh) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_get_file_handle(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_p_switch_file_handle.getCPtr(fh));
return ret;
}
public static switch_status_t switch_ivr_release_file_handle(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_p_switch_file_handle fh) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_release_file_handle(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_p_switch_file_handle.getCPtr(fh));
return ret;
}
public static switch_status_t switch_ivr_process_fh(SWIGTYPE_p_switch_core_session session, string cmd, switch_file_handle fhp) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_process_fh(SWIGTYPE_p_switch_core_session.getCPtr(session), cmd, switch_file_handle.getCPtr(fhp));
return ret;
}
public static switch_status_t switch_rtp_add_crypto_key(SWIGTYPE_p_switch_rtp rtp_session, switch_rtp_crypto_direction_t direction, uint index, switch_rtp_crypto_key_type_t type, SWIGTYPE_p_unsigned_char key, SWIGTYPE_p_switch_size_t keylen) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_add_crypto_key(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)direction, index, (int)type, SWIGTYPE_p_unsigned_char.getCPtr(key), SWIGTYPE_p_switch_size_t.getCPtr(keylen));
if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve();
@ -7255,6 +7285,15 @@ class freeswitchPINVOKE {
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_destroy")]
public static extern int switch_core_destroy();
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_io_read_lock")]
public static extern int switch_core_session_io_read_lock(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_io_write_lock")]
public static extern int switch_core_session_io_write_lock(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_io_rwunlock")]
public static extern int switch_core_session_io_rwunlock(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_read_lock")]
public static extern int switch_core_session_read_lock(HandleRef jarg1);
@ -12244,6 +12283,15 @@ class freeswitchPINVOKE {
[DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_set_realm")]
public static extern int switch_ivr_dmachine_set_realm(HandleRef jarg1, string jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_get_file_handle")]
public static extern int switch_ivr_get_file_handle(HandleRef jarg1, HandleRef jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_release_file_handle")]
public static extern int switch_ivr_release_file_handle(HandleRef jarg1, HandleRef jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_process_fh")]
public static extern int switch_ivr_process_fh(HandleRef jarg1, string jarg2, HandleRef jarg3);
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RTP_MAX_BUF_LEN_get")]
public static extern int SWITCH_RTP_MAX_BUF_LEN_get();
@ -17119,6 +17167,36 @@ namespace FreeSWITCH.Native {
using System;
using System.Runtime.InteropServices;
public class SWIGTYPE_p_p_switch_file_handle {
private HandleRef swigCPtr;
internal SWIGTYPE_p_p_switch_file_handle(IntPtr cPtr, bool futureUse) {
swigCPtr = new HandleRef(this, cPtr);
}
protected SWIGTYPE_p_p_switch_file_handle() {
swigCPtr = new HandleRef(null, IntPtr.Zero);
}
internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_file_handle obj) {
return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
}
}
}
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
* Version 1.3.35
*
* Do not make changes to this file unless you know what you are doing--modify
* the SWIG interface file instead.
* ----------------------------------------------------------------------------- */
namespace FreeSWITCH.Native {
using System;
using System.Runtime.InteropServices;
public class SWIGTYPE_p_p_switch_frame {
private HandleRef swigCPtr;

View File

@ -9732,17 +9732,17 @@ XS(SWIG_init) {
SWIG_TypeClientData(SWIGTYPE_p_IVRMenu, (void*) "freeswitch::IVRMenu");
SWIG_TypeClientData(SWIGTYPE_p_API, (void*) "freeswitch::API");
SWIG_TypeClientData(SWIGTYPE_p_input_callback_state, (void*) "freeswitch::input_callback_state_t");
/*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
/*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
SV *sv = get_sv((char*) SWIG_prefix "S_HUP", TRUE | 0x2 | GV_ADDMULTI);
sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_HUP)));
SvREADONLY_on(sv);
} while(0) /*@SWIG@*/;
/*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
/*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
SV *sv = get_sv((char*) SWIG_prefix "S_FREE", TRUE | 0x2 | GV_ADDMULTI);
sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_FREE)));
SvREADONLY_on(sv);
} while(0) /*@SWIG@*/;
/*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
/*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do {
SV *sv = get_sv((char*) SWIG_prefix "S_RDLOCK", TRUE | 0x2 | GV_ADDMULTI);
sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_RDLOCK)));
SvREADONLY_on(sv);

View File

@ -36,6 +36,46 @@
#include "private/switch_core_pvt.h"
SWITCH_DECLARE(switch_status_t) switch_core_session_io_read_lock(switch_core_session_t *session)
{
switch_status_t status = SWITCH_STATUS_FALSE;
if (session->io_rwlock) {
if (switch_thread_rwlock_tryrdlock(session->io_rwlock) == SWITCH_STATUS_SUCCESS) {
status = SWITCH_STATUS_SUCCESS;
}
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_io_write_lock(switch_core_session_t *session)
{
switch_status_t status = SWITCH_STATUS_FALSE;
if (session->io_rwlock) {
switch_thread_rwlock_wrlock(session->io_rwlock);
status = SWITCH_STATUS_SUCCESS;
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_io_rwunlock(switch_core_session_t *session)
{
switch_status_t status = SWITCH_STATUS_FALSE;
if (session->io_rwlock) {
switch_thread_rwlock_unlock(session->io_rwlock);
status = SWITCH_STATUS_SUCCESS;
}
return status;
}
#ifdef SWITCH_DEBUG_RWLOCKS
SWITCH_DECLARE(switch_status_t) switch_core_session_perform_read_lock(switch_core_session_t *session, const char *file, const char *func, int line)
#else

View File

@ -1667,6 +1667,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
switch_thread_rwlock_create(&session->bug_rwlock, session->pool);
switch_thread_cond_create(&session->cond, session->pool);
switch_thread_rwlock_create(&session->rwlock, session->pool);
switch_thread_rwlock_create(&session->io_rwlock, session->pool);
switch_queue_create(&session->message_queue, SWITCH_MESSAGE_QUEUE_LEN, session->pool);
switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);

View File

@ -1269,120 +1269,7 @@ SWITCH_DECLARE(switch_status_t) CoreSession::process_callback_result(char *resul
this_check(SWITCH_STATUS_FALSE);
sanity_check(SWITCH_STATUS_FALSE);
if (zstr(result)) {
return SWITCH_STATUS_SUCCESS;
}
if (fhp) {
if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) {
return SWITCH_STATUS_FALSE;
}
if (!strncasecmp(result, "speed", 5)) {
char *p;
if ((p = strchr(result, ':'))) {
p++;
if (*p == '+' || *p == '-') {
int step;
if (!(step = atoi(p))) {
step = 1;
}
fhp->speed += step;
} else {
int speed = atoi(p);
fhp->speed = speed;
}
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
} else if (!strncasecmp(result, "volume", 6)) {
char *p;
if ((p = strchr(result, ':'))) {
p++;
if (*p == '+' || *p == '-') {
int step;
if (!(step = atoi(p))) {
step = 1;
}
fhp->vol += step;
} else {
int vol = atoi(p);
fhp->vol = vol;
}
return SWITCH_STATUS_SUCCESS;
}
if (fhp->vol) {
switch_normalize_volume(fhp->vol);
}
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(result, "pause")) {
if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)) {
switch_clear_flag(fhp, SWITCH_FILE_PAUSE);
} else {
switch_set_flag(fhp, SWITCH_FILE_PAUSE);
}
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(result, "stop")) {
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(result, "truncate")) {
switch_core_file_truncate(fhp, 0);
} else if (!strcasecmp(result, "restart")) {
unsigned int pos = 0;
fhp->speed = 0;
switch_core_file_seek(fhp, &pos, 0, SEEK_SET);
return SWITCH_STATUS_SUCCESS;
} else if (!strncasecmp(result, "seek", 4)) {
switch_codec_t *codec;
unsigned int samps = 0;
unsigned int pos = 0;
char *p;
codec = switch_core_session_get_read_codec(session);
if ((p = strchr(result, ':'))) {
p++;
if (*p == '+' || *p == '-') {
int step;
int32_t target;
if (!(step = atoi(p))) {
step = 1000;
}
samps = step * (codec->implementation->samples_per_second / 1000);
target = (int32_t)fhp->pos + samps;
if (target < 0) {
target = 0;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", target);
switch_core_file_seek(fhp, &pos, target, SEEK_SET);
} else {
samps = atoi(p) * (codec->implementation->samples_per_second / 1000);
if (samps < 0) {
samps = 0;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", samps);
switch_core_file_seek(fhp, &pos, samps, SEEK_SET);
}
}
return SWITCH_STATUS_SUCCESS;
}
}
if (!strcmp(result, "true") || !strcmp(result, "undefined")) {
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
return switch_ivr_process_fh(session, result, fhp);
}
/* For Emacs:

View File

@ -2563,6 +2563,124 @@ SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid)
return exists;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp)
{
if (zstr(cmd)) {
return SWITCH_STATUS_SUCCESS;
}
if (fhp) {
if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) {
return SWITCH_STATUS_FALSE;
}
if (!strncasecmp(cmd, "speed", 5)) {
char *p;
if ((p = strchr(cmd, ':'))) {
p++;
if (*p == '+' || *p == '-') {
int step;
if (!(step = atoi(p))) {
step = 1;
}
fhp->speed += step;
} else {
int speed = atoi(p);
fhp->speed = speed;
}
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
} else if (!strncasecmp(cmd, "volume", 6)) {
char *p;
if ((p = strchr(cmd, ':'))) {
p++;
if (*p == '+' || *p == '-') {
int step;
if (!(step = atoi(p))) {
step = 1;
}
fhp->vol += step;
} else {
int vol = atoi(p);
fhp->vol = vol;
}
return SWITCH_STATUS_SUCCESS;
}
if (fhp->vol) {
switch_normalize_volume(fhp->vol);
}
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(cmd, "pause")) {
if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)) {
switch_clear_flag(fhp, SWITCH_FILE_PAUSE);
} else {
switch_set_flag(fhp, SWITCH_FILE_PAUSE);
}
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(cmd, "stop")) {
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(cmd, "truncate")) {
switch_core_file_truncate(fhp, 0);
} else if (!strcasecmp(cmd, "restart")) {
unsigned int pos = 0;
fhp->speed = 0;
switch_core_file_seek(fhp, &pos, 0, SEEK_SET);
return SWITCH_STATUS_SUCCESS;
} else if (!strncasecmp(cmd, "seek", 4)) {
switch_codec_t *codec;
unsigned int samps = 0;
unsigned int pos = 0;
char *p;
codec = switch_core_session_get_read_codec(session);
if ((p = strchr(cmd, ':'))) {
p++;
if (*p == '+' || *p == '-') {
int step;
int32_t target;
if (!(step = atoi(p))) {
step = 1000;
}
samps = step * (codec->implementation->samples_per_second / 1000);
target = (int32_t)fhp->pos + samps;
if (target < 0) {
target = 0;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", target);
switch_core_file_seek(fhp, &pos, target, SEEK_SET);
} else {
samps = atoi(p) * (codec->implementation->samples_per_second / 1000);
if (samps < 0) {
samps = 0;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", samps);
switch_core_file_seek(fhp, &pos, samps, SEEK_SET);
}
}
return SWITCH_STATUS_SUCCESS;
}
}
if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) {
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
/* For Emacs:
* Local Variables:

View File

@ -913,6 +913,31 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_get_file_handle(switch_core_session_t *session, switch_file_handle_t **fh)
{
switch_file_handle_t *fhp;
switch_channel_t *channel = switch_core_session_get_channel(session);
*fh = NULL;
switch_core_session_io_read_lock(session);
if ((fhp = switch_channel_get_private(channel, "__fh"))) {
*fh = fhp;
return SWITCH_STATUS_SUCCESS;
}
switch_core_session_io_rwunlock(session);
return SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_release_file_handle(switch_core_session_t *session, switch_file_handle_t **fh)
{
*fh = NULL;
switch_core_session_io_rwunlock(session);
return SWITCH_STATUS_SUCCESS;
}
#define FILE_STARTSAMPLES 1024 * 32
#define FILE_BLOCKSIZE 1024 * 8
@ -994,6 +1019,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
}
if (play_delimiter) {
file_dup = switch_core_session_strdup(session, file);
argc = switch_separate_string(file_dup, play_delimiter, argv, (sizeof(argv) / sizeof(argv[0])));
@ -1134,6 +1161,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
status = SWITCH_STATUS_NOTFOUND;
continue;
}
switch_core_session_io_write_lock(session);
switch_channel_set_private(channel, "__fh", fh);
switch_core_session_io_rwunlock(session);
if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
asis = 1;
}
@ -1208,7 +1240,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval);
switch_core_session_io_write_lock(session);
switch_channel_set_private(channel, "__fh", NULL);
switch_core_session_io_rwunlock(session);
switch_core_file_close(fh);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
status = SWITCH_STATUS_GENERR;
continue;
@ -1228,6 +1265,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
if (switch_core_timer_init(&timer, timer_name, interval, samples, pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Setup timer failed!\n");
switch_core_codec_destroy(&codec);
switch_core_session_io_write_lock(session);
switch_channel_set_private(channel, "__fh", NULL);
switch_core_session_io_rwunlock(session);
switch_core_file_close(fh);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
status = SWITCH_STATUS_GENERR;
@ -1538,6 +1578,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
}
switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_out);
switch_core_session_io_write_lock(session);
switch_channel_set_private(channel, "__fh", NULL);
switch_core_session_io_rwunlock(session);
switch_core_file_close(fh);
if (fh->audio_buffer) {