[Freeswitch-svn] [commit] r4788 - in freeswitch/branches/mikej/sofiasip-upgrade: . src src/include src/mod/applications/mod_commands src/mod/applications/mod_conference src/mod/applications/mod_dptools src/mod/applications/mod_ivrtest src/mod/event_handlers/mod_cdr
Freeswitch SVN
mikej at freeswitch.org
Thu Mar 29 00:30:20 EDT 2007
Author: mikej
Date: Thu Mar 29 00:30:19 2007
New Revision: 4788
Modified:
freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am
freeswitch/branches/mikej/sofiasip-upgrade/configure.in
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_am_config.h.in
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_core.h
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_ivr.h
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_platform.h
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_types.h
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_commands/mod_commands.c
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_conference/mod_conference.c
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_dptools/mod_dptools.c
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_ivrtest/mod_ivrtest.c
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/event_handlers/mod_cdr/Makefile.am
freeswitch/branches/mikej/sofiasip-upgrade/src/switch_channel.c
freeswitch/branches/mikej/sofiasip-upgrade/src/switch_core.c
freeswitch/branches/mikej/sofiasip-upgrade/src/switch_ivr.c
freeswitch/branches/mikej/sofiasip-upgrade/src/switch_resample.c
Log:
merged changes from trunk revisions 4781-4787.
Modified: freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am Thu Mar 29 00:30:19 2007
@@ -80,12 +80,12 @@
CORE_CFLAGS += -I$(switch_srcdir)/libs/pcre
CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include
CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include
-CORE_CFLAGS += -I$(switch_srcdir)/libs/libresample/include
+CORE_CFLAGS += $(RESAMPLE_CFLAGS)
CORE_CFLAGS += -I$(switch_srcdir)/libs/libteletone/src
CORE_LIBS = libs/apr/libapr-1.la libs/apr-util/libaprutil-1.la
CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la
-CORE_LIBS += libs/srtp/libsrtp.la libs/libresample/libresample.la
+CORE_LIBS += libs/srtp/libsrtp.la $(RESAMPLE_LIB)
lib_LTLIBRARIES = libfreeswitch.la
libfreeswitch_la_CFLAGS = $(CORE_CFLAGS) $(AM_CFLAGS)
@@ -171,9 +171,11 @@
@cd libs/srtp && $(MAKE)
@$(TOUCH_TARGET)
+if USE_INTREE_RESAMPLE
libs/libresample/libresample.la: libs/libresample libs/libresample/.update
@cd libs/libresample && $(MAKE)
@$(TOUCH_TARGET)
+endif
core: libfreeswitch.la
Modified: freeswitch/branches/mikej/sofiasip-upgrade/configure.in
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/configure.in (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/configure.in Thu Mar 29 00:30:19 2007
@@ -57,9 +57,29 @@
AM_CONDITIONAL([WANT_DEBUG],[test "${enable_debug}" = "yes"])
+# Optional Features
+
+AC_ARG_ENABLE(resample,
+[AC_HELP_STRING([--enable-resample],[build with embedded resamper])],[enable_resample="$enable_resample"],[enable_resample="yes"])
+
+# We should add checking for out of tree libresample here
+RESAMPLE_LIB=
+RESAMPLE_CFLAGS=
+if test "${enable_resample}" = "yes"; then
+ RESAMPLE_LIB="libs/libresample/libresample.la"
+ RESAMPLE_CFLAGS="-I${switch_srcdir}/libs/libresample/include"
+else
+ AC_DEFINE([DISABLE_RESAMPLE],[],[Disable the embedded resampler])
+fi
+
+AC_SUBST(RESAMPLE_LIB)
+AC_SUBST(RESAMPLE_CFLAGS)
+
+AM_CONDITIONAL([USE_INTREE_RESAMPLE],[test "${enable_resample}" = "yes"])
+
# set defaults for use on all platforms
-SWITCH_AM_CFLAGS="-I${switch_srcdir}/src/include -I${prefix}/include"
-SWITCH_AM_CXXFLAGS="-I${switch_srcdir}/src/include -I${prefix}/include"
+SWITCH_AM_CFLAGS="-I${switch_srcdir}/src/include"
+SWITCH_AM_CXXFLAGS="-I${switch_srcdir}/src/include"
SWITCH_AM_LDFLAGS="-lm -L/usr/local/lib"
#set SOLINK variable based on compiler and host
@@ -151,6 +171,7 @@
AC_CHECK_SIZEOF(long, 4)
AC_CHECK_SIZEOF(short, 2)
AC_CHECK_SIZEOF(long long, 8)
+AC_CHECK_SIZEOF(time_t, 4)
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
@@ -226,6 +247,16 @@
size_t_fmt='#error Can not determine the proper size for size_t'
fi
+if test "$ac_cv_sizeof_time_t" = "$ac_cv_sizeof_int"; then
+ time_t_fmt='#define TIME_T_FMT "d"'
+elif test "$ac_cv_sizeof_time_t" = "$ac_cv_sizeof_long"; then
+ time_t_fmt='#define TIME_T_FMT "ld"'
+elif test "$ac_cv_sizeof_time_t" = "$ac_cv_sizeof_long_long"; then
+ time_t_fmt='#define TIME_T_FMT "lld"'
+else
+ time_t_fmt='#error Can not determine the proper format specifier for time_t of size $ac_cv_sizeof_time_t'
+fi
+
# Basically, we have tried to figure out the correct format strings
# for SWITCH types which vary between platforms, but we don't always get
# it right. If you find that we don't get it right for your platform,
@@ -274,8 +305,7 @@
AC_SUBST(uint64_t_fmt)
AC_SUBST(ssize_t_fmt)
AC_SUBST(size_t_fmt)
-
-
+AC_SUBST(time_t_fmt)
AC_PATH_PROGS(ZCAT, gunzip gzcat gzip zcat)
AC_PATH_PROGS(TAR, gtar tar)
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_am_config.h.in
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_am_config.h.in (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_am_config.h.in Thu Mar 29 00:30:19 2007
@@ -15,5 +15,6 @@
@size_t_fmt@
@int64_t_fmt@
@uint64_t_fmt@
+ at time_t_fmt@
#endif
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_core.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_core.h (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_core.h Thu Mar 29 00:30:19 2007
@@ -104,17 +104,68 @@
struct switch_core_runtime;
struct switch_core_port_allocator;
+struct switch_core_scheduler_task {
+ time_t created;
+ time_t runtime;
+ uint32_t cmd_id;
+ char *group;
+ void *cmd_arg;
+ uint32_t task_id;
+};
+
+
/*!
\defgroup core1 Core Library
\ingroup FREESWITCH
\{
*/
-
///\defgroup mb1 Media Bugs
///\ingroup core1
///\{
+
+///\defgroup sched1 Scheduler
+///\ingroup core1
+///\{
+
+
+/*!
+ \brief Schedule a task in the future
+ \param runtime the time in epoch seconds to execute the task.
+ \param func the callback function to execute when the task is executed.
+ \param desc an arbitrary description of the task.
+ \param group a group id tag to link multiple tasks to a single entity.
+ \param cmd_id an arbitrary index number be used in the callback.
+ \param cmd_arg user data to be passed to the callback.
+ \param flags flags to alter behaviour
+ \return the id of the task
+*/
+SWITCH_DECLARE(uint32_t) switch_core_scheduler_add_task(time_t task_runtime,
+ switch_core_scheduler_func_t func,
+ char *desc,
+ char *group,
+ uint32_t cmd_id,
+ void *cmd_arg,
+ switch_scheduler_flag_t flags);
+
+/*!
+ \brief Delete a scheduled task
+ \param task_id the id of the task
+ \return SWITCH_STATUS_SUCCESS if the task was deleted.
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_scheduler_del_task_id(uint32_t task_id);
+
+/*!
+ \brief Delete a scheduled task based on the group name
+ \param group the group name
+ \return SWITCH_STATUS_SUCCESS if any tasks were deleted
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_scheduler_del_task_group(char *group);
+
+
+///\}
+
/*!
\brief Add a media bug to the session
\param session the session to add the bug to
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_ivr.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_ivr.h (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_ivr.h Thu Mar 29 00:30:19 2007
@@ -332,6 +332,28 @@
SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_t *session, char *extension, char *dialplan, char *context);
/*!
+ \brief Transfer an existing session to another location in the future
+ \param runtime the time (int epoch seconds) to transfer the call
+ \param uuid the uuid of the session to transfer
+ \param extension the new extension
+ \param dialplan the new dialplan (OPTIONAL, may be NULL)
+ \param context the new context (OPTIONAL, may be NULL)
+ \return the id of the task
+*/
+SWITCH_DECLARE(uint32_t) switch_ivr_schedule_transfer(time_t runtime, char *uuid, char *extension, char *dialplan, char *context);
+
+
+/*!
+ \brief Hangup an existing session in the future
+ \param runtime the time (int epoch seconds) to transfer the call
+ \param uuid the uuid of the session to hangup
+ \param cause the hanup cause code
+ \param bleg hangup up the B-Leg if possible
+ \return the id of the task
+*/
+SWITCH_DECLARE(uint32_t) switch_ivr_schedule_hangup(time_t runtime, char *uuid, switch_call_cause_t cause, switch_bool_t bleg);
+
+/*!
\brief Bridge two existing sessions
\param originator_uuid the uuid of the originator
\param originatee_uuid the uuid of the originator
@@ -384,6 +406,16 @@
SWITCH_DECLARE(switch_status_t) switch_ivr_unhold(switch_core_session_t *session);
/*!
+ \brief Signal the session to broadcast audio in the future
+ \param runtime when (in epoch time) to run the broadcast
+ \param uuid the uuid of the session to broadcast on
+ \param path the path data of the broadcast "/path/to/file.wav [<timer name>]" or "speak:<engine>|<voice>|<Text to say>"
+ \param flags flags to send to the request (SMF_ECHO_BRIDGED to send the broadcast to both sides of the call)
+ \return the id of the task
+*/
+SWITCH_DECLARE(uint32_t) switch_ivr_schedule_broadcast(time_t runtime, char *uuid, char *path, switch_media_flag_t flags);
+
+/*!
\brief Signal the session to broadcast audio
\param uuid the uuid of the session to broadcast on
\param path the path data of the broadcast "/path/to/file.wav [<timer name>]" or "speak:<engine>|<voice>|<Text to say>"
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_platform.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_platform.h (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_platform.h Thu Mar 29 00:30:19 2007
@@ -213,6 +213,12 @@
#define SWITCH_INT64_T_FMT "I64d"
#define SWITCH_UINT64_T_FMT "I64u"
+#ifdef _USE_32BIT_TIME_T
+#define TIME_T_FMT "d"
+#else
+#define TIME_T_FMT SWITCH_INT64_T_FMT
+#endif
+
#else
#ifndef SWITCH_SSIZE_T_FMT
#define SWITCH_SSIZE_T_FMT (sizeof (switch_ssize_t) == sizeof (long) ? "ld" : sizeof (switch_ssize_t) == sizeof (int) ? "d" : "lld")
@@ -230,6 +236,10 @@
#define SWITCH_UINT64_T_FMT (sizeof (long) == 8 ? "lu" : "llu")
#endif
+#ifndef TIME_T_FMT
+#define TIME_T_FMT "ld"
+#endif
+
#endif
#define SWITCH_TIME_T_FMT SWITCH_INT64_T_FMT
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_types.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_types.h (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_types.h Thu Mar 29 00:30:19 2007
@@ -168,6 +168,12 @@
} switch_management_action_t;
typedef enum {
+ SSHF_NONE = 0,
+ SSHF_OWN_THREAD = (1 << 0),
+ SSHF_FREE_ARG = (1 << 1)
+} switch_scheduler_flag_t;
+
+typedef enum {
SMF_NONE = 0,
SMF_REBRIDGE = (1 << 0),
SMF_ECHO_ALEG = (1 << 1),
@@ -910,7 +916,8 @@
SWITCH_CAUSE_LOSE_RACE = 502,
SWITCH_CAUSE_MANAGER_REQUEST = 503,
SWITCH_CAUSE_BLIND_TRANSFER = 600,
- SWITCH_CAUSE_ATTENDED_TRANSFER = 601
+ SWITCH_CAUSE_ATTENDED_TRANSFER = 601,
+ SWITCH_CAUSE_ALLOTTED_TIMEOUT = 602
} switch_call_cause_t;
typedef enum {
@@ -979,6 +986,8 @@
typedef void (*switch_application_function_t)(switch_core_session_t *, char *);
typedef void (*switch_event_callback_t)(switch_event_t *);
typedef switch_caller_extension_t *(*switch_dialplan_hunt_function_t)(switch_core_session_t *, void *);
+typedef struct switch_core_scheduler_task switch_core_scheduler_task_t;
+typedef void (*switch_core_scheduler_func_t)(switch_core_scheduler_task_t *task);
typedef switch_status_t (*switch_state_handler_t)(switch_core_session_t *);
typedef switch_status_t (*switch_outgoing_channel_hook_t)(switch_core_session_t *, switch_caller_profile_t *, switch_core_session_t *);
typedef switch_status_t (*switch_answer_channel_hook_t)(switch_core_session_t *);
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_commands/mod_commands.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_commands/mod_commands.c Thu Mar 29 00:30:19 2007
@@ -51,6 +51,9 @@
static switch_api_interface_t media_api_interface;
static switch_api_interface_t hold_api_interface;
static switch_api_interface_t broadcast_api_interface;
+static switch_api_interface_t sched_broadcast_api_interface;
+static switch_api_interface_t sched_transfer_api_interface;
+static switch_api_interface_t sched_hangup_api_interface;
static switch_status_t status_function(char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream)
{
@@ -245,6 +248,89 @@
return SWITCH_STATUS_SUCCESS;
}
+
+static switch_status_t sched_transfer_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+{
+ switch_core_session_t *session = NULL;
+ char *argv[6] = {0};
+ int argc = 0;
+
+ if (isession) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+
+ if (switch_strlen_zero(cmd) || argc < 2 || argc > 5) {
+ stream->write_function(stream, "USAGE: %s\n", sched_transfer_api_interface.syntax);
+ } else {
+ char *uuid = argv[1];
+ char *dest = argv[2];
+ char *dp = argv[3];
+ char *context = argv[4];
+ time_t when;
+
+ if (*argv[0] == '+') {
+ when = time (NULL) + atol(argv[0] + 1);
+ } else {
+ when = atol(argv[0]);
+ }
+
+ if ((session = switch_core_session_locate(uuid))) {
+ switch_ivr_schedule_transfer(when, uuid, dest, dp, context);
+ stream->write_function(stream, "OK\n");
+ switch_core_session_rwunlock(session);
+ } else {
+ stream->write_function(stream, "No Such Channel!\n");
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t sched_hangup_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+{
+ switch_core_session_t *session = NULL;
+ char *argv[4] = {0};
+ int argc = 0;
+
+ if (isession) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+
+ if (switch_strlen_zero(cmd) || argc < 1) {
+ stream->write_function(stream, "USAGE: %s\n", sched_hangup_api_interface.syntax);
+ } else {
+ char *uuid = argv[1];
+ char *cause_str = argv[2];
+ time_t when;
+ switch_call_cause_t cause = SWITCH_CAUSE_ALLOTTED_TIMEOUT;
+
+ if (*argv[0] == '+') {
+ when = time (NULL) + atol(argv[0] + 1);
+ } else {
+ when = atol(argv[0]);
+ }
+
+ if (cause_str) {
+ cause = switch_channel_str2cause(cause_str);
+ }
+
+ if ((session = switch_core_session_locate(uuid))) {
+ switch_ivr_schedule_hangup(when, uuid, cause, SWITCH_FALSE);
+ stream->write_function(stream, "OK\n");
+ switch_core_session_rwunlock(session);
+ } else {
+ stream->write_function(stream, "No Such Channel!\n");
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
static switch_status_t uuid_media_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
{
char *argv[4] = {0};
@@ -313,6 +399,50 @@
return SWITCH_STATUS_SUCCESS;
}
+
+static switch_status_t sched_broadcast_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
+{
+ char *argv[4] = {0};
+ int argc = 0;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if (isession) {
+ return status;
+ }
+
+ argc = switch_separate_string(cmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+
+ if (switch_strlen_zero(cmd) || argc < 3) {
+ stream->write_function(stream, "USAGE: %s\n", sched_broadcast_api_interface.syntax);
+ } else {
+ switch_media_flag_t flags = SMF_NONE;
+ time_t when;
+
+ if (*argv[0] == '+') {
+ when = time (NULL) + atol(argv[0] + 1);
+ } else {
+ when = atol(argv[0]);
+ }
+
+ if (argv[3]) {
+ if (!strcmp(argv[3], "both")) {
+ flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG);
+ } else if (!strcmp(argv[3], "aleg")) {
+ flags |= SMF_ECHO_ALEG;
+ } else if (!strcmp(argv[3], "bleg")) {
+ flags |= SMF_ECHO_BLEG;
+ }
+ } else {
+ flags |= SMF_ECHO_ALEG;
+ }
+
+ status = switch_ivr_schedule_broadcast(when, argv[1], argv[2], flags);
+ stream->write_function(stream, "+OK Message Scheduled\n");
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
static switch_status_t uuid_hold_function(char *cmd, switch_core_session_t *isession, switch_stream_handle_t *stream)
{
char *argv[4] = {0};
@@ -707,12 +837,36 @@
return SWITCH_STATUS_SUCCESS;
}
+static switch_api_interface_t sched_transfer_api_interface = {
+ /*.interface_name */ "sched_transfer",
+ /*.desc */ "Schedule a broadcast event to a running call",
+ /*.function */ sched_transfer_function,
+ /*.syntax */ "[+]<time> <uuid> <extension> [<dialplan>] [<context>]",
+ /*.next */ NULL
+};
+
+static switch_api_interface_t sched_broadcast_api_interface = {
+ /*.interface_name */ "sched_broadcast",
+ /*.desc */ "Schedule a broadcast event to a running call",
+ /*.function */ sched_broadcast_function,
+ /*.syntax */ "[+]<time> <uuid> <path> [aleg|bleg|both]",
+ /*.next */ &sched_transfer_api_interface
+};
+
+static switch_api_interface_t sched_hangup_api_interface = {
+ /*.interface_name */ "sched_hangup",
+ /*.desc */ "Schedule a running call to hangup",
+ /*.function */ sched_hangup_function,
+ /*.syntax */ "[+]<time> <uuid> [<cause>]",
+ /*.next */ &sched_broadcast_api_interface
+};
+
static switch_api_interface_t version_api_interface = {
/*.interface_name */ "version",
/*.desc */ "Show version of the switch",
/*.function */ version_function,
/*.syntax */ "",
- /*.next */ NULL
+ /*.next */ &sched_hangup_api_interface
};
static switch_api_interface_t help_api_interface = {
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_conference/mod_conference.c Thu Mar 29 00:30:19 2007
@@ -4070,12 +4070,15 @@
switch_audio_resampler_t **resampler = read_codec->implementation->samples_per_second > conference->rate ?
&member.read_resampler : &member.mux_resampler;
- switch_resample_create(resampler,
+ if (switch_resample_create(resampler,
read_codec->implementation->samples_per_second,
read_codec->implementation->samples_per_second * 20,
conference->rate,
conference->rate * 20,
- member.pool);
+ member.pool) != SWITCH_STATUS_SUCCESS){
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to crete resampler!\n");
+ goto done;
+ }
/* Setup an audio buffer for the resampled audio */
if (switch_buffer_create_dynamic(&member.resample_buffer, CONF_DBLOCK_SIZE, CONF_DBUFFER_SIZE, CONF_DBUFFER_MAX) != SWITCH_STATUS_SUCCESS) {
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_dptools/mod_dptools.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_dptools/mod_dptools.c Thu Mar 29 00:30:19 2007
@@ -96,6 +96,99 @@
}
}
+static void sched_transfer_function(switch_core_session_t *session, char *data)
+{
+ int argc;
+ char *argv[4] = {0};
+ char *mydata;
+
+ if (data && (mydata = switch_core_session_strdup(session, data))) {
+ if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
+ time_t when;
+
+ if (*argv[0] == '+') {
+ when = time (NULL) + atol(argv[0] + 1);
+ } else {
+ when = atol(argv[0]);
+ }
+
+ switch_ivr_schedule_transfer(when, switch_core_session_get_uuid(session), argv[1], argv[2], argv[3]);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
+ }
+ }
+}
+
+static void sched_hangup_function(switch_core_session_t *session, char *data)
+{
+ int argc;
+ char *argv[5] = {0};
+ char *mydata;
+
+ if (data && (mydata = switch_core_session_strdup(session, data))) {
+ if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
+ time_t when;
+ switch_call_cause_t cause = SWITCH_CAUSE_ALLOTTED_TIMEOUT;
+ switch_bool_t bleg = SWITCH_FALSE;
+
+ if (*argv[0] == '+') {
+ when = time (NULL) + atol(argv[0] + 1);
+ } else {
+ when = atol(argv[0]);
+ }
+
+ if (argv[1]) {
+ cause = switch_channel_str2cause(argv[1]);
+ }
+
+ if (argv[2] && !strcasecmp(argv[2], "bleg")) {
+ bleg = SWITCH_TRUE;
+ }
+
+ switch_ivr_schedule_hangup(when, switch_core_session_get_uuid(session), cause, bleg);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No time specified.\n");
+ }
+ }
+}
+
+
+static void sched_broadcast_function(switch_core_session_t *session, char *data)
+{
+ int argc;
+ char *argv[6] = {0};
+ char *mydata;
+
+ if (data && (mydata = switch_core_session_strdup(session, data))) {
+ if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
+ time_t when;
+ switch_media_flag_t flags = SMF_NONE;
+
+ if (*argv[0] == '+') {
+ when = time (NULL) + atol(argv[0] + 1);
+ } else {
+ when = atol(argv[0]);
+ }
+
+ if (argv[2]) {
+ if (!strcmp(argv[2], "both")) {
+ flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG);
+ } else if (!strcmp(argv[2], "aleg")) {
+ flags |= SMF_ECHO_ALEG;
+ } else if (!strcmp(argv[2], "bleg")) {
+ flags |= SMF_ECHO_BLEG;
+ }
+ } else {
+ flags |= SMF_ECHO_ALEG;
+ }
+
+ switch_ivr_schedule_broadcast(when, switch_core_session_get_uuid(session), argv[1], flags);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
+ }
+ }
+}
+
static void sleep_function(switch_core_session_t *session, char *data)
{
@@ -509,6 +602,7 @@
}
}
+
static switch_api_interface_t strepoch_api_interface = {
/*.interface_name */ "strepoch",
/*.desc */ "Convert a date string into epoch time",
@@ -541,6 +635,39 @@
/*.next */ &dptools_api_interface
};
+
+
+static switch_application_interface_t sched_transfer_application_interface = {
+ /*.interface_name */ "sched_transfer",
+ /*.application_function */ sched_transfer_function,
+ /*.long_desc */ "Schedule a transfer in the future",
+ /*.short_desc */ "Schedule a transfer in the future",
+ /*.syntax */ "[+]<time> <extension> <dialplan> <context>",
+ /* flags */ SAF_SUPPORT_NOMEDIA,
+ /*.next */ NULL
+};
+
+static switch_application_interface_t sched_broadcast_application_interface = {
+ /*.interface_name */ "sched_broadcast",
+ /*.application_function */ sched_broadcast_function,
+ /*.long_desc */ "Schedule a broadcast in the future",
+ /*.short_desc */ "Schedule a broadcast in the future",
+ /*.syntax */ "[+]<time> <path> [aleg|bleg|both]",
+ /* flags */ SAF_SUPPORT_NOMEDIA,
+ /*.next */ &sched_transfer_application_interface
+};
+
+static switch_application_interface_t sched_hangup_application_interface = {
+ /*.interface_name */ "sched_hangup",
+ /*.application_function */ sched_hangup_function,
+ /*.long_desc */ "Schedule a hangup in the future",
+ /*.short_desc */ "Schedule a hangup in the future",
+ /*.syntax */ "[+]<time> [<cause>]",
+ /* flags */ SAF_SUPPORT_NOMEDIA,
+ /*.next */ &sched_broadcast_application_interface
+};
+
+
static const switch_application_interface_t queuedtmf_application_interface = {
/*.interface_name */ "queue_dtmf",
/*.application_function */ queue_dtmf_function,
@@ -548,7 +675,7 @@
/* short_desc */ "Queue dtmf to be sent",
/* syntax */ "<dtmf_data>",
/* flags */ SAF_SUPPORT_NOMEDIA,
- /*.next */ NULL
+ /*.next */ &sched_hangup_application_interface
};
static const switch_application_interface_t redirect_application_interface = {
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_ivrtest/mod_ivrtest.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_ivrtest/mod_ivrtest.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/applications/mod_ivrtest/mod_ivrtest.c Thu Mar 29 00:30:19 2007
@@ -233,6 +233,7 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Done\n");
}
+#ifdef BUGTEST
static switch_bool_t bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
switch_frame_t *frame;
@@ -249,9 +250,11 @@
return SWITCH_TRUE;
}
+#endif
static void bugtest_function(switch_core_session_t *session, char *data)
{
+#ifdef BUGTEST
switch_media_bug_t *bug;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status;
@@ -264,6 +267,11 @@
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return;
}
+#endif
+ //switch_ivr_schedule_broadcast(time(NULL) + 10, switch_core_session_get_uuid(session), "/Users/anthm/sr8k.wav", SMF_ECHO_ALEG);
+ //switch_ivr_schedule_transfer(time(NULL) + 10, switch_core_session_get_uuid(session), "2000", NULL, NULL);
+ //switch_ivr_schedule_hangup(time(NULL) + 10, switch_core_session_get_uuid(session), SWITCH_CAUSE_ALLOTTED_TIMEOUT);
+
switch_ivr_play_file(session, NULL, data, NULL);
}
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/event_handlers/mod_cdr/Makefile.am
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/event_handlers/mod_cdr/Makefile.am (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/event_handlers/mod_cdr/Makefile.am Thu Mar 29 00:30:19 2007
@@ -1,7 +1,16 @@
#we should set all these vars from configure, no reason to have these in each Makefile.am
-LIBTOOL=`if test -z "$(VERBOSE)" ; then echo $(SHELL) $(switch_builddir)/quiet_libtool ;else echo $(switch_builddir)/libtool; fi;`
+#LIBTOOL = compile=`echo $<|grep .c`;link=`echo $@|grep .la;echo $@|grep .so;echo $@|grep .dll`; if test -n "$$compile"; then echo Compiling $<;fi; if test -n "$$link"; then echo Creating $@;fi; `if test -z "$(VERBOSE)" ; then echo $(SHELL) $(switch_builddir)/quiet_libtool ;else echo $(switch_builddir)/libtool; fi;`
+#LIBTOOL=`if test -z "$(VERBOSE)" ; then echo $(SHELL) $(switch_builddir)/quiet_libtool ;else echo $(switch_builddir)/libtool; fi;`
+LIBTOOL = link=`echo $@|grep .la;echo $@|grep .so;echo $@|grep .dll`; \
+ if test -n "$$link"; then echo Creating $@;fi; \
+ `if test -z "$(VERBOSE)" ; \
+ then echo $(SHELL) $(switch_builddir)/quiet_libtool ;\
+ else echo $(switch_builddir)/libtool; fi;`
+
AM_MAKEFLAGS=`test -n "$(VERBOSE)" || echo -s`
-LINK_OUTPUT_REDIR=> $(MODNAME).log || error="yes" ; \
+
+# Dirty trick to override the link output
+LIBS+=> $(MODNAME).log || error="yes" ; \
if test -n "$(VERBOSE)" -o "$$error" = "yes"; then \
cat $(MODNAME).log ; \
fi ;\
@@ -11,8 +20,6 @@
moddir=$(prefix)/mod
-
-
MODNAME=mod_cdr
mod_LTLIBRARIES = mod_cdr.la
mod_cdr_la_SOURCES = mod_cdr.cpp cdrcontainer.cpp basecdr.cpp baseregistry.cpp pddcdr.cpp csvcdr.cpp xmlcdr.cpp sqlitecdr.cpp
@@ -30,12 +37,6 @@
#mod_cdr_la_CFLAGS += -DSWITCH_QUEUE_ENHANCED
#mod_cdr_la_LDFLAGS += -lcurl
-#Override link target so we can control the output
-
-$(MODNAME).la: $(mod_cdr_la_OBJECTS) $(mod_cdr_la_DEPENDENCIES)
- @echo Creating $(MODNAME).$(DYNAMIC_LIB_EXTEN)...
- @$(CXXLINK) -rpath $(moddir) $(mod_cdr_la_LDFLAGS) $(mod_cdr_la_OBJECTS) $(mod_cdr_la_LIBADD) $(LIBS) $(LINK_OUTPUT_REDIR)
-
#Override the linstall target so we just install the .so/.dylib
install-data-am: $(DESTDIR)$(PREFIX)/$(moddir)/$(MODNAME).$(DYNAMIC_LIB_EXTEN)
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/switch_channel.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/switch_channel.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/switch_channel.c Thu Mar 29 00:30:19 2007
@@ -95,6 +95,7 @@
{ "MANAGER_REQUEST", SWITCH_CAUSE_MANAGER_REQUEST },
{ "BLIND_TRANSFER", SWITCH_CAUSE_BLIND_TRANSFER },
{ "ATTENDED_TRANSFER", SWITCH_CAUSE_ATTENDED_TRANSFER },
+ { "ALLOTTED_TIMEOUT", SWITCH_CAUSE_ALLOTTED_TIMEOUT},
{ NULL, 0 }
};
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/switch_core.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/switch_core.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/switch_core.c Thu Mar 29 00:30:19 2007
@@ -147,6 +147,19 @@
SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = {0};
+struct switch_core_scheduler_task_container {
+ switch_core_scheduler_task_t task;
+ time_t executed;
+ int in_thread;
+ int destroyed;
+ switch_core_scheduler_func_t func;
+ switch_memory_pool_t *pool;
+ uint32_t flags;
+ char *desc;
+ struct switch_core_scheduler_task_container *next;
+};
+typedef struct switch_core_scheduler_task_container switch_core_scheduler_task_container_t;
+
struct switch_core_runtime {
switch_time_t initiated;
uint32_t session_id;
@@ -169,6 +182,10 @@
uint32_t shutting_down;
uint8_t running;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+ switch_core_scheduler_task_container_t *task_list;
+ switch_mutex_t *task_mutex;
+ uint32_t task_id;
+ int task_thread_running;
};
/* Prototypes */
@@ -196,6 +213,238 @@
}
}
+static void send_heartbeat(void)
+{
+ switch_event_t *event;
+ switch_core_time_duration_t duration;
+
+ switch_core_measure_time(switch_core_uptime(), &duration);
+
+ if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time",
+ "%u year%s, "
+ "%u day%s, "
+ "%u hour%s, "
+ "%u minute%s, "
+ "%u second%s, "
+ "%u millisecond%s, "
+ "%u microsecond%s\n",
+ duration.yr, duration.yr == 1 ? "" : "s",
+ duration.day, duration.day == 1 ? "" : "s",
+ duration.hr, duration.hr == 1 ? "" : "s",
+ duration.min, duration.min == 1 ? "" : "s",
+ duration.sec, duration.sec == 1 ? "" : "s",
+ duration.ms, duration.ms == 1 ? "" : "s",
+ duration.mms, duration.mms == 1 ? "" : "s"
+ );
+
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
+ switch_event_fire(&event);
+ }
+}
+
+static void heartbeat_callback(switch_core_scheduler_task_t *task)
+{
+ send_heartbeat();
+
+ /* reschedule this task */
+ task->runtime += 20;
+}
+
+static void switch_core_scheduler_execute(switch_core_scheduler_task_container_t *tp)
+{
+ //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Executing task %u %s (%s)\n", tp->task.task_id, tp->desc, switch_str_nil(tp->task.group));
+
+ tp->func(&tp->task);
+
+ if (tp->task.runtime > tp->executed) {
+ tp->executed = 0;
+ } else {
+ tp->destroyed = 1;
+ }
+}
+
+static void *SWITCH_THREAD_FUNC task_own_thread(switch_thread_t *thread, void *obj)
+{
+ switch_core_scheduler_task_container_t *tp = (switch_core_scheduler_task_container_t *) obj;
+ switch_memory_pool_t *pool;
+
+ pool = tp->pool;
+ tp->pool = NULL;
+
+ switch_core_scheduler_execute(tp);
+ switch_core_destroy_memory_pool(&pool);
+ tp->in_thread = 0;
+
+ return NULL;
+}
+
+static int task_thread_loop(int done)
+{
+ switch_core_scheduler_task_container_t *tofree, *tp, *last = NULL;
+
+
+ switch_mutex_lock(runtime.task_mutex);
+ for (tp = runtime.task_list; tp; tp = tp->next) {
+ if (done) {
+ tp->destroyed = 1;
+ } else {
+ time_t now = time(NULL);
+ if (now >= tp->task.runtime && !tp->in_thread) {
+ tp->executed = now;
+ if (switch_test_flag(tp, SSHF_OWN_THREAD)) {
+ switch_thread_t *thread;
+ switch_threadattr_t *thd_attr;
+ assert(switch_core_new_memory_pool(&tp->pool) == SWITCH_STATUS_SUCCESS);
+ switch_threadattr_create(&thd_attr, tp->pool);
+ switch_threadattr_detach_set(thd_attr, 1);
+ tp->in_thread = 1;
+ switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool);
+ } else {
+ switch_core_scheduler_execute(tp);
+ }
+ }
+ }
+ }
+ switch_mutex_unlock(runtime.task_mutex);
+ switch_mutex_lock(runtime.task_mutex);
+ for (tp = runtime.task_list; tp; ) {
+ if (tp->destroyed && !tp->in_thread) {
+ tofree = tp;
+ tp = tp->next;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Deleting task %u %s (%s)\n",
+ tofree->task.task_id, tofree->desc, switch_str_nil(tofree->task.group));
+ if (last) {
+ last->next = tofree->next;
+ } else {
+ runtime.task_list = tofree->next;
+ }
+ switch_safe_free(tofree->task.group);
+ if (tofree->task.cmd_arg && switch_test_flag(tofree, SSHF_FREE_ARG)) {
+ free(tofree->task.cmd_arg);
+ }
+ switch_safe_free(tofree->desc);
+ free(tofree);
+ } else {
+ last = tp;
+ tp = tp->next;
+ }
+ }
+ switch_mutex_unlock(runtime.task_mutex);
+
+ return done;
+}
+
+static void *SWITCH_THREAD_FUNC switch_core_task_thread(switch_thread_t *thread, void *obj)
+{
+
+ runtime.task_thread_running = 1;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Starting task thread\n");
+ while(runtime.task_thread_running == 1) {
+ if (task_thread_loop(0)) {
+ break;
+ }
+ switch_yield(500000);
+ }
+
+ task_thread_loop(1);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Task thread ending\n");
+ runtime.task_thread_running = 0;
+
+ return NULL;
+}
+
+static void switch_core_task_thread_launch(void)
+{
+ switch_thread_t *thread;
+ switch_threadattr_t *thd_attr;
+ switch_threadattr_create(&thd_attr, runtime.memory_pool);
+ switch_threadattr_detach_set(thd_attr, 1);
+ switch_thread_create(&thread, thd_attr, switch_core_task_thread, NULL, runtime.memory_pool);
+}
+
+SWITCH_DECLARE(uint32_t) switch_core_scheduler_add_task(time_t task_runtime,
+ switch_core_scheduler_func_t func,
+ char *desc,
+ char *group,
+ uint32_t cmd_id,
+ void *cmd_arg,
+ switch_scheduler_flag_t flags)
+{
+ switch_core_scheduler_task_container_t *container, *tp;
+
+ switch_mutex_lock(runtime.task_mutex);
+ assert((container = malloc(sizeof(*container))));
+ memset(container, 0, sizeof(*container));
+ assert(func);
+ container->func = func;
+ time(&container->task.created);
+ container->task.runtime = task_runtime;
+ container->task.group = strdup(group ? group : "none");
+ container->task.cmd_id = cmd_id;
+ container->task.cmd_arg = cmd_arg;
+ container->flags = flags;
+ container->desc = strdup(desc ? desc : "none");
+
+ for (tp = runtime.task_list; tp && tp->next; tp = tp->next);
+
+ if (tp) {
+ tp->next = container;
+ } else {
+ runtime.task_list = container;
+ }
+
+ for (container->task.task_id = 0; !container->task.task_id; container->task.task_id = ++runtime.task_id);
+
+ switch_mutex_unlock(runtime.task_mutex);
+
+ tp = container;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added task %u %s (%s) to run at %"TIME_T_FMT"\n",
+ tp->task.task_id, tp->desc, switch_str_nil(tp->task.group), task_runtime);
+
+
+ return container->task.task_id;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_scheduler_del_task_id(uint32_t task_id)
+{
+ switch_core_scheduler_task_container_t *tp;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ switch_mutex_lock(runtime.task_mutex);
+ for (tp = runtime.task_list; tp; tp = tp->next) {
+ if (tp->task.task_id == task_id) {
+ tp->destroyed++;
+ status = SWITCH_STATUS_SUCCESS;
+ break;
+ }
+ }
+ switch_mutex_unlock(runtime.task_mutex);
+
+ return status;
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_scheduler_del_task_group(char *group)
+{
+ switch_core_scheduler_task_container_t *tp;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ switch_mutex_lock(runtime.task_mutex);
+ for (tp = runtime.task_list; tp; tp = tp->next) {
+ if (!strcmp(tp->task.group, group)) {
+ tp->destroyed++;
+ status = SWITCH_STATUS_SUCCESS;
+ }
+ }
+ switch_mutex_unlock(runtime.task_mutex);
+
+ return status;
+}
+
+
static void switch_core_media_bug_destroy(switch_media_bug_t *bug)
{
switch_buffer_destroy(&bug->raw_read_buffer);
@@ -2148,7 +2397,8 @@
}
if (!session->read_codec && (*frame)->codec) {
- need_codec = TRUE;
+ status = SWITCH_STATUS_FALSE;
+ goto done;
}
if (session->bugs && !need_codec) {
@@ -2174,11 +2424,15 @@
switch (status) {
case SWITCH_STATUS_RESAMPLE:
if (!session->read_resampler) {
- switch_resample_create(&session->read_resampler,
+ if (switch_resample_create(&session->read_resampler,
read_frame->codec->implementation->samples_per_second,
read_frame->codec->implementation->bytes_per_frame * 20,
session->read_codec->implementation->samples_per_second,
- session->read_codec->implementation->bytes_per_frame * 20, session->pool);
+ session->read_codec->implementation->bytes_per_frame * 20, session->pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
+ status = SWITCH_STATUS_FALSE;
+ goto done;
+ }
}
case SWITCH_STATUS_SUCCESS:
session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t);
@@ -2418,7 +2672,7 @@
}
if (!session->write_codec && frame->codec) {
- need_codec = TRUE;
+ return SWITCH_STATUS_FALSE;
}
if (session->bugs && !need_codec) {
@@ -2448,6 +2702,9 @@
session->write_codec->implementation->samples_per_second,
session->write_codec->implementation->bytes_per_frame * 20,
session->pool);
+ if (status != SWITCH_STATUS_SUCCESS) {
+ goto done;
+ }
}
break;
case SWITCH_STATUS_SUCCESS:
@@ -2652,6 +2909,9 @@
session->write_codec->implementation->samples_per_second,
session->write_codec->implementation->bytes_per_frame * 20,
session->pool);
+ if (status != SWITCH_STATUS_SUCCESS) {
+ goto done;
+ }
}
break;
case SWITCH_STATUS_SUCCESS:
@@ -3143,11 +3403,10 @@
switch_event_t *event;
const switch_application_interface_t *application_interface;
-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Standard EXECUTE\n");
+
if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Extension!\n");
- switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ switch_channel_hangup(session->channel, SWITCH_CAUSE_NORMAL_CLEARING);
return;
}
@@ -3721,6 +3980,8 @@
switch_event_t *event;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Close Channel %s\n", switch_channel_get_name((*session)->channel));
+
+ switch_core_scheduler_del_task_group((*session)->uuid_str);
switch_mutex_lock(runtime.session_table_mutex);
switch_core_hash_delete(runtime.session_table, (*session)->uuid_str);
@@ -4133,7 +4394,6 @@
char *sqlbuf = (char *) malloc(sql_len);
char *sql;
switch_size_t newlen;
- uint32_t loops = 0;
if (!runtime.event_db) {
runtime.event_db = switch_core_db_handle();
@@ -4188,38 +4448,6 @@
*sqlbuf = '\0';
}
- if (loops++ >= 5000) {
- switch_event_t *event;
- switch_core_time_duration_t duration;
-
- switch_core_measure_time(switch_core_uptime(), &duration);
-
- if (switch_event_create(&event, SWITCH_EVENT_HEARTBEAT) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Ready");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Up-Time",
- "%u year%s, "
- "%u day%s, "
- "%u hour%s, "
- "%u minute%s, "
- "%u second%s, "
- "%u millisecond%s, "
- "%u microsecond%s\n",
- duration.yr, duration.yr == 1 ? "" : "s",
- duration.day, duration.day == 1 ? "" : "s",
- duration.hr, duration.hr == 1 ? "" : "s",
- duration.min, duration.min == 1 ? "" : "s",
- duration.sec, duration.sec == 1 ? "" : "s",
- duration.ms, duration.ms == 1 ? "" : "s",
- duration.mms, duration.mms == 1 ? "" : "s"
- );
-
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
- switch_event_fire(&event);
- }
-
- loops = 0;
- }
-
if (nothing_in_queue) {
switch_yield(1000);
}
@@ -4662,11 +4890,17 @@
runtime.running = 1;
switch_core_hash_init(&runtime.session_table, runtime.memory_pool);
switch_mutex_init(&runtime.session_table_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
+ switch_mutex_init(&runtime.task_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
#ifdef CRASH_PROT
switch_core_hash_init(&runtime.stack_table, runtime.memory_pool);
#endif
+
+
+ switch_core_task_thread_launch();
runtime.initiated = switch_time_now();
+ switch_core_scheduler_add_task(time(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE);
+
switch_uuid_get(&uuid);
switch_uuid_format(runtime.uuid_str, &uuid);
@@ -4826,11 +5060,28 @@
while (switch_queue_size(runtime.sql_queue) > 0) {
switch_yield(10000);
}
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping Task Thread\n");
+ if (runtime.task_thread_running == 1) {
+ int sanity = 0;
+
+ runtime.task_thread_running = -1;
+
+ while(runtime.task_thread_running) {
+ switch_yield(100000);
+ if (++sanity > 10) {
+ break;
+ }
+ }
+ }
+
switch_core_db_close(runtime.db);
switch_core_db_close(runtime.event_db);
switch_xml_destroy();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");
switch_log_shutdown();
+
+
if(runtime.console != stdout && runtime.console != stderr) {
fclose(runtime.console);
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/switch_ivr.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/switch_ivr.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/switch_ivr.c Thu Mar 29 00:30:19 2007
@@ -130,7 +130,7 @@
if (cause_name) {
cause = switch_channel_str2cause(cause_name);
}
-
+
switch_channel_hangup(channel, cause);
} else if (cmd_hash == CMD_NOMEDIA) {
char *uuid = switch_event_get_header(event, "nomedia-uuid");
@@ -3240,6 +3240,157 @@
return SWITCH_STATUS_SUCCESS;
}
+struct hangup_helper {
+ char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+ switch_bool_t bleg;
+ switch_call_cause_t cause;
+};
+
+static void sch_hangup_callback(switch_core_scheduler_task_t *task)
+{
+ struct hangup_helper *helper;
+ switch_core_session_t *session, *other_session;
+ char *other_uuid;
+
+ assert(task);
+
+ helper = (struct hangup_helper *) task->cmd_arg;
+
+ if ((session = switch_core_session_locate(helper->uuid_str))) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+
+ if (helper->bleg) {
+ if ((other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) &&
+ (other_session = switch_core_session_locate(other_uuid))) {
+ switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
+ switch_channel_hangup(other_channel, helper->cause);
+ switch_core_session_rwunlock(other_session);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No channel to hangup\n");
+ }
+ } else {
+ switch_channel_hangup(channel, helper->cause);
+ }
+
+ switch_core_session_rwunlock(session);
+ }
+}
+
+SWITCH_DECLARE(uint32_t) switch_ivr_schedule_hangup(time_t runtime, char *uuid, switch_call_cause_t cause, switch_bool_t bleg)
+{
+ struct hangup_helper *helper;
+ size_t len = sizeof(*helper);
+
+ assert((helper = malloc(len)));
+ memset(helper, 0, len);
+
+ switch_copy_string(helper->uuid_str, uuid, sizeof(helper->uuid_str));
+ helper->cause = cause;
+ helper->bleg = bleg;
+
+ return switch_core_scheduler_add_task(runtime, sch_hangup_callback, (char *)__SWITCH_FUNC__, uuid, 0, helper, SSHF_FREE_ARG);
+}
+
+struct transfer_helper {
+ char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+ char *extension;
+ char *dialplan;
+ char *context;
+};
+
+static void sch_transfer_callback(switch_core_scheduler_task_t *task)
+{
+ struct transfer_helper *helper;
+ switch_core_session_t *session;
+
+ assert(task);
+
+ helper = (struct transfer_helper *) task->cmd_arg;
+
+ if ((session = switch_core_session_locate(helper->uuid_str))) {
+ switch_ivr_session_transfer(session, helper->extension, helper->dialplan, helper->context);
+ switch_core_session_rwunlock(session);
+ }
+
+}
+
+SWITCH_DECLARE(uint32_t) switch_ivr_schedule_transfer(time_t runtime, char *uuid, char *extension, char *dialplan, char *context)
+{
+ struct transfer_helper *helper;
+ size_t len = sizeof(*helper);
+ char *cur = NULL;
+
+ if (extension) {
+ len += strlen(extension) + 1;
+ }
+
+ if (dialplan) {
+ len += strlen(dialplan) + 1;
+ }
+
+ if (context) {
+ len += strlen(context) + 1;
+ }
+
+ assert((helper = malloc(len)));
+ memset(helper, 0, len);
+
+ switch_copy_string(helper->uuid_str, uuid, sizeof(helper->uuid_str));
+
+ cur = (char *) helper + sizeof(*helper);
+
+ if (extension) {
+ helper->extension = cur;
+ switch_copy_string(helper->extension, extension, strlen(extension) + 1);
+ cur += strlen(helper->extension) + 1;
+ }
+
+ if (dialplan) {
+ helper->dialplan = cur;
+ switch_copy_string(helper->dialplan, dialplan, strlen(dialplan) + 1);
+ cur += strlen(helper->dialplan) + 1;
+ }
+
+ if (context) {
+ helper->context = cur;
+ switch_copy_string(helper->context, context, strlen(context)+1);
+ }
+
+ return switch_core_scheduler_add_task(runtime, sch_transfer_callback, (char *)__SWITCH_FUNC__, uuid, 0, helper, SSHF_FREE_ARG);
+}
+
+
+struct broadcast_helper {
+ char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+ char *path;
+ switch_media_flag_t flags;
+};
+
+static void sch_broadcast_callback(switch_core_scheduler_task_t *task)
+{
+ struct broadcast_helper *helper;
+ assert(task);
+
+ helper = (struct broadcast_helper *) task->cmd_arg;
+ switch_ivr_broadcast(helper->uuid_str, helper->path, helper->flags);
+}
+
+SWITCH_DECLARE(uint32_t) switch_ivr_schedule_broadcast(time_t runtime, char *uuid, char *path, switch_media_flag_t flags)
+{
+ struct broadcast_helper *helper;
+ size_t len = sizeof(*helper) + strlen(path) + 1;
+
+ assert((helper = malloc(len)));
+ memset(helper, 0, len);
+
+ switch_copy_string(helper->uuid_str, uuid, sizeof(helper->uuid_str));
+ helper->flags = flags;
+ helper->path = (char *) helper + sizeof(*helper);
+ switch_copy_string(helper->path, path, len - sizeof(helper));
+
+
+ return switch_core_scheduler_add_task(runtime, sch_broadcast_callback, (char *)__SWITCH_FUNC__, uuid, 0, helper, SSHF_FREE_ARG);
+}
SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(char *uuid, char *path, switch_media_flag_t flags)
{
@@ -3249,9 +3400,15 @@
switch_event_t *event;
switch_core_session_t *other_session = NULL;
char *other_uuid = NULL;
+ char *app = "playback";
+
+ assert(path);
if ((session = switch_core_session_locate(uuid))) {
- char *app;
+ char *cause = NULL;
+ char *mypath = strdup(path);
+ char *p;
+
master = session;
channel = switch_core_session_get_channel(session);
@@ -3261,11 +3418,17 @@
switch_ivr_media(uuid, SMF_REBRIDGE);
}
- if (!strncasecmp(path, "speak:", 6)) {
- path += 6;
- app = "speak";
- } else {
- app = "playback";
+ if ((p = strchr(mypath, ':'))) {
+ app = mypath;
+ *p++ = '\0';
+ path = p;
+ }
+
+ if ((cause = strchr(app, '!'))) {
+ *cause++ = '\0';
+ if (!cause) {
+ cause = "normal_clearing";
+ }
}
if ((flags & SMF_ECHO_BLEG) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))
@@ -3299,8 +3462,21 @@
}
}
+ if (cause) {
+ if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "execute-app-name", "hangup");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "execute-app-arg", "%s", cause);
+
+ switch_core_session_queue_private_event(session, &event);
+ }
+ }
+
switch_core_session_rwunlock(session);
+ switch_safe_free(mypath);
}
+
+
return SWITCH_STATUS_SUCCESS;
}
@@ -3449,11 +3625,16 @@
switch_channel_set_variable(channel, SWITCH_BRIDGE_VARIABLE, NULL);
switch_channel_set_variable(other_channel, SWITCH_BRIDGE_VARIABLE, NULL);
- switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
+ if (switch_channel_get_state(other_channel) < CS_HANGUP &&
+ switch_true(switch_channel_get_variable(other_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE))) {
+ switch_channel_hangup(other_channel, switch_channel_get_cause(channel));
+ } else {
+ switch_channel_set_state(other_channel, CS_EXECUTE);
+ }
switch_core_session_rwunlock(other_session);
}
-
+
return SWITCH_STATUS_SUCCESS;
}
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/switch_resample.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/switch_resample.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/switch_resample.c Thu Mar 29 00:30:19 2007
@@ -31,7 +31,12 @@
*/
#include <switch.h>
#include <switch_resample.h>
+#ifndef WIN32
+#include <switch_private.h>
+#endif
+#ifndef DISABLE_RESAMPLE
#include <libresample.h>
+#endif
#define NORMFACT (float)0x8000
#define MAXSAMPLE (float)0x7FFF
#define MAXSAMPLEC (char)0x7F
@@ -52,6 +57,10 @@
switch_size_t from_size,
int to_rate, uint32_t to_size, switch_memory_pool_t *pool)
{
+#ifdef DISABLE_RESAMPLE
+ *new_resampler = NULL;
+ return SWITCH_STATUS_NOTIMPL;
+#else
switch_audio_resampler_t *resampler;
double lto_rate, lfrom_rate;
@@ -75,12 +84,16 @@
*new_resampler = resampler;
return SWITCH_STATUS_SUCCESS;
+#endif
}
SWITCH_DECLARE(uint32_t) switch_resample_process(switch_audio_resampler_t *resampler, float *src, int srclen, float *dst,
uint32_t dstlen, int last)
{
+#ifdef DISABLE_RESAMPLE
+ return 0;
+#else
int o = 0, srcused = 0, srcpos = 0, out = 0;
for (;;) {
@@ -99,11 +112,14 @@
}
}
return out;
+#endif
}
SWITCH_DECLARE(void) switch_resample_destroy(switch_audio_resampler_t *resampler)
{
+#ifndef DISABLE_RESAMPLE
resample_close(resampler->resampler);
+#endif
}
More information about the Freeswitch-svn
mailing list