freeswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
March 2007
- 6 participants
- 392 discussions
[Freeswitch-svn] [commit] r4789 - freeswitch/branches/mikej/sofiasip-upgrade/src/mod/event_handlers/mod_cdr
by Freeswitch SVN 29 Mar '07
by Freeswitch SVN 29 Mar '07
29 Mar '07
Author: mikej
Date: Thu Mar 29 01:44:38 2007
New Revision: 4789
Modified:
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/event_handlers/mod_cdr/Makefile.am
Log:
fix bsd make compile of mod_cdr
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 01:44:38 2007
@@ -1,22 +1,9 @@
#we should set all these vars from configure, no reason to have these in each Makefile.am
-#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;`
-
+LIBTOOL = echo "`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 $(SHELL) $(switch_builddir)/libtool; fi`
AM_MAKEFLAGS=`test -n "$(VERBOSE)" || echo -s`
-
# Dirty trick to override the link output
-LIBS+=> $(MODNAME).log || error="yes" ; \
- if test -n "$(VERBOSE)" -o "$$error" = "yes"; then \
- cat $(MODNAME).log ; \
- fi ;\
- if test "$$error" = "yes"; then \
- exit 1 ;\
- fi
+LIBS+=> $(MODNAME).log || error="yes";if test -n "$(VERBOSE)" -o "$$error" = "yes";then cat $(MODNAME).log;fi;if test "$$error" = "yes";then exit 1;fi
moddir=$(prefix)/mod
1
0
29 Mar '07
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@
+@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
}
1
0
[Freeswitch-svn] [commit] r4787 - in freeswitch/trunk: . src src/include
by Freeswitch SVN 29 Mar '07
by Freeswitch SVN 29 Mar '07
29 Mar '07
Author: mikej
Date: Thu Mar 29 00:08:18 2007
New Revision: 4787
Modified:
freeswitch/trunk/configure.in
freeswitch/trunk/src/include/switch_am_config.h.in
freeswitch/trunk/src/include/switch_platform.h
freeswitch/trunk/src/switch_core.c
Log:
use autoconf determined time_t printf format specifier
Modified: freeswitch/trunk/configure.in
==============================================================================
--- freeswitch/trunk/configure.in (original)
+++ freeswitch/trunk/configure.in Thu Mar 29 00:08:18 2007
@@ -171,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)
@@ -246,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,
@@ -294,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/trunk/src/include/switch_am_config.h.in
==============================================================================
--- freeswitch/trunk/src/include/switch_am_config.h.in (original)
+++ freeswitch/trunk/src/include/switch_am_config.h.in Thu Mar 29 00:08:18 2007
@@ -15,5 +15,6 @@
@size_t_fmt@
@int64_t_fmt@
@uint64_t_fmt@
+@time_t_fmt@
#endif
Modified: freeswitch/trunk/src/include/switch_platform.h
==============================================================================
--- freeswitch/trunk/src/include/switch_platform.h (original)
+++ freeswitch/trunk/src/include/switch_platform.h Thu Mar 29 00:08:18 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/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Thu Mar 29 00:08:18 2007
@@ -402,7 +402,7 @@
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 %ld\n",
+ 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);
1
0
[Freeswitch-svn] [commit] r4786 - freeswitch/trunk/src/mod/event_handlers/mod_cdr
by Freeswitch SVN 29 Mar '07
by Freeswitch SVN 29 Mar '07
29 Mar '07
Author: mikej
Date: Wed Mar 28 22:58:02 2007
New Revision: 4786
Modified:
freeswitch/trunk/src/mod/event_handlers/mod_cdr/Makefile.am
Log:
use better tricks in mod_cdr Makefile.am so we don't get warnings about duplicate targets, and so we can move all our tricks into configure soon
Modified: freeswitch/trunk/src/mod/event_handlers/mod_cdr/Makefile.am
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_cdr/Makefile.am (original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_cdr/Makefile.am Wed Mar 28 22:58:02 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)
1
0
[Freeswitch-svn] [commit] r4785 - in freeswitch/trunk/src: . include mod/applications/mod_commands mod/applications/mod_dptools mod/applications/mod_ivrtest
by Freeswitch SVN 28 Mar '07
by Freeswitch SVN 28 Mar '07
28 Mar '07
Author: anthm
Date: Wed Mar 28 19:37:12 2007
New Revision: 4785
Modified:
freeswitch/trunk/src/include/switch_core.h
freeswitch/trunk/src/include/switch_ivr.h
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c
freeswitch/trunk/src/switch_channel.c
freeswitch/trunk/src/switch_core.c
freeswitch/trunk/src/switch_ivr.c
Log:
Addition of scheduler engine and a few applications to use it.
This patch adds a scheduler thread to the core and moves the heartbeat
event to use the new scheduler as an example.
Also The following features are implemented that use this scheduler:
sched_hangup dialplan application:
<action application="sched_hangup" data="+10 normal_clearing bleg"/>
** The cause code is optional and the optional bleg keyword will only hangup the
channel the current channel is bridged to if the call is in a bridge.
sched_transfer dialplan application:
<action application="sched_transfer" data="+10 1000 XML default"/>
** The last 2 args (dialplan and context) are optional
sched_broadcast dialplan application:
<action application="sched_broadcast" data="+10 playback:/tmp/foo.wav"/>
<action application="sched_broadcast" data="+10 playback!normal_clearing:/tmp/foo.wav"/>
** The optional !<cause_code> can be added to make the channel hangup after broadcasting the file.
sched_hangup api function:
sched_hangup +10 <uuid_string> normal_clearing
** The cause code is optional
sched_transfer api function:
sched_transfer +10 <uuid_string> 1000 XML default
** The last 2 args (dialplan and context) are optional
sched_broadcast api function:
sched_broadcast +10 <uuid_str> playback:/tmp/foo.wav
sched_broadcast +10 <uuid_str> playback!normal_clearing:/tmp/foo.wav
** The optional !<cause_code> can be added to make the channel hangup after broadcasting the file.
The new C functions in the core are documented in the doxeygen.
*NOTE* This commit should satisfy at least 2 bounties on the wiki
Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h (original)
+++ freeswitch/trunk/src/include/switch_core.h Wed Mar 28 19:37:12 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/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_ivr.h (original)
+++ freeswitch/trunk/src/include/switch_ivr.h Wed Mar 28 19:37:12 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/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h (original)
+++ freeswitch/trunk/src/include/switch_types.h Wed Mar 28 19:37:12 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/trunk/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c Wed Mar 28 19:37:12 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/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Wed Mar 28 19:37:12 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/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_ivrtest/mod_ivrtest.c Wed Mar 28 19:37:12 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/trunk/src/switch_channel.c
==============================================================================
--- freeswitch/trunk/src/switch_channel.c (original)
+++ freeswitch/trunk/src/switch_channel.c Wed Mar 28 19:37:12 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/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Wed Mar 28 19:37:12 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 %ld\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) {
@@ -2422,7 +2672,7 @@
}
if (!session->write_codec && frame->codec) {
- need_codec = TRUE;
+ return SWITCH_STATUS_FALSE;
}
if (session->bugs && !need_codec) {
@@ -3153,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;
}
@@ -3731,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);
@@ -4143,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();
@@ -4198,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);
}
@@ -4672,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);
@@ -4836,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/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Wed Mar 28 19:37:12 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;
}
1
0
Author: mikej
Date: Wed Mar 28 17:48:06 2007
New Revision: 4784
Modified:
freeswitch/trunk/configure.in
Log:
we should never include off the installed includes, only the source tree ones.
Modified: freeswitch/trunk/configure.in
==============================================================================
--- freeswitch/trunk/configure.in (original)
+++ freeswitch/trunk/configure.in Wed Mar 28 17:48:06 2007
@@ -78,8 +78,8 @@
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
1
0
Author: mikej
Date: Wed Mar 28 14:46:07 2007
New Revision: 4783
Modified:
freeswitch/trunk/Makefile.am
freeswitch/trunk/configure.in
Log:
add --disable-resample configure option to build without resampler support
Modified: freeswitch/trunk/Makefile.am
==============================================================================
--- freeswitch/trunk/Makefile.am (original)
+++ freeswitch/trunk/Makefile.am Wed Mar 28 14:46:07 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/trunk/configure.in
==============================================================================
--- freeswitch/trunk/configure.in (original)
+++ freeswitch/trunk/configure.in Wed Mar 28 14:46:07 2007
@@ -57,6 +57,26 @@
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"
1
0
[Freeswitch-svn] [commit] r4782 - in freeswitch/trunk/src: . mod/applications/mod_conference
by Freeswitch SVN 28 Mar '07
by Freeswitch SVN 28 Mar '07
28 Mar '07
Author: mikej
Date: Wed Mar 28 14:21:00 2007
New Revision: 4782
Modified:
freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
freeswitch/trunk/src/switch_core.c
freeswitch/trunk/src/switch_resample.c
Log:
add checking for successful re-sampler allocation. Add ifdefs to disable build with re-sampler.
Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c Wed Mar 28 14:21:00 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/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Wed Mar 28 14:21:00 2007
@@ -2174,11 +2174,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);
@@ -2448,6 +2452,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 +2659,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:
Modified: freeswitch/trunk/src/switch_resample.c
==============================================================================
--- freeswitch/trunk/src/switch_resample.c (original)
+++ freeswitch/trunk/src/switch_resample.c Wed Mar 28 14:21:00 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
}
1
0
[Freeswitch-svn] [commit] r4781 - in freeswitch/branches/mikej/sofiasip-upgrade: . libs/libdingaling/src src src/include src/mod/endpoints/mod_sofia src/mod/languages/mod_spidermonkey
by Freeswitch SVN 28 Mar '07
by Freeswitch SVN 28 Mar '07
28 Mar '07
Author: mikej
Date: Wed Mar 28 13:40:13 2007
New Revision: 4781
Modified:
freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am
freeswitch/branches/mikej/sofiasip-upgrade/libs/libdingaling/src/libdingaling.c
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_core.h
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_module_interfaces.h
freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_types.h
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h
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
Log:
merged changes from trunk revisions 4772-4780.
Modified: freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/Makefile.am Wed Mar 28 13:40:13 2007
@@ -221,3 +221,9 @@
megaclean: eclean modclean
rm -f `find ./libs -name \*.la`
+
+
+# Special targets
+
+coffee me_a_sandwich me_a_sammich:
+ @echo "Who do you think I am? Make it yourself!"
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/libdingaling/src/libdingaling.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/libdingaling/src/libdingaling.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/libdingaling/src/libdingaling.c Wed Mar 28 13:40:13 2007
@@ -1218,15 +1218,12 @@
static void on_log(ldl_handle_t *handle, const char *data, size_t size, int is_incoming)
{
- if (iks_is_secure(handle->parser)) {
- fprintf(stderr, "Sec");
+ if (globals.debug) {
+ globals.logger(DL_LOG_DEBUG, "\n%s%s[%s]\n",
+ iks_is_secure(handle->parser) ? "Sec" : "",
+ is_incoming ? "RECV" : "SEND",
+ data);
}
- if (is_incoming) {
- fprintf(stderr, "RECV");
- } else {
- fprintf(stderr, "SEND");
- }
- fprintf(stderr, "[%s]\n", data);
}
static void j_setup_filter(ldl_handle_t *handle)
@@ -1423,16 +1420,18 @@
break;
case IKS_NET_NODNS:
globals.logger(DL_LOG_DEBUG, "hostname lookup failed\n");
+ microsleep(1000);
+ goto fail;
case IKS_NET_NOCONN:
globals.logger(DL_LOG_DEBUG, "connection failed\n");
+ microsleep(1000);
+ goto fail;
default:
- globals.logger(DL_LOG_DEBUG, "io error %d\n", e);
- microsleep(500);
- continue;
+ globals.logger(DL_LOG_DEBUG, "io error 1 %d\n", e);
+ microsleep(1000);
+ goto fail;
}
-
-
handle->counter = opt_timeout;
if (ldl_test_flag(handle, LDL_FLAG_TLS)) {
launch_queue_thread(handle);
@@ -1456,9 +1455,9 @@
}
if (IKS_OK != e) {
- globals.logger(DL_LOG_DEBUG, "io error %d\n", e);
- microsleep(500);
- break;
+ globals.logger(DL_LOG_DEBUG, "io error 2 %d\n", e);
+ microsleep(1000);
+ goto fail;
}
@@ -1481,10 +1480,12 @@
}
}
+ fail:
iks_disconnect(handle->parser);
iks_parser_delete(handle->parser);
ldl_clear_flag_locked(handle, LDL_FLAG_CONNECTED);
ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED);
+ handle->state = CS_NEW;
}
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
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 Wed Mar 28 13:40:13 2007
@@ -856,6 +856,15 @@
\return SWITCH_STATUS_SUCCESS on suceess
*/
SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_send_dtmf(switch_core_session_t *session, switch_send_dtmf_hook_t send_dtmf);
+
+/*!
+ \brief Add an event hook to be executed when a session receives a state change signal
+ \param session session to bind hook to
+ \param state_change hook to bind
+ \return SWITCH_STATUS_SUCCESS on suceess
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_state_change(switch_core_session_t *session,
+ switch_answer_channel_hook_t state_change);
///\}
///\defgroup hashf Hash Functions
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_module_interfaces.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_module_interfaces.h (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/include/switch_module_interfaces.h Wed Mar 28 13:40:13 2007
@@ -145,6 +145,13 @@
struct switch_io_event_hook_send_dtmf *next;
};
+/*! \brief Node in which to store state change callback hooks */
+struct switch_io_event_hook_state_change {
+ /*! the send dtmf channel callback hook*/
+ switch_state_change_hook_t state_change;
+ struct switch_io_event_hook_state_change *next;
+};
+
/*! \brief A table of lists of io_event_hooks to store the event hooks associated with a session */
struct switch_io_event_hooks {
/*! a list of outgoing channel hooks */
@@ -167,6 +174,8 @@
switch_io_event_hook_waitfor_write_t *waitfor_write;
/*! a list of send dtmf hooks */
switch_io_event_hook_send_dtmf_t *send_dtmf;
+ /*! a list of state change hooks */
+ switch_io_event_hook_state_change_t *state_change;
};
/*! \brief A table of i/o routines that an endpoint interface can implement */
@@ -191,6 +200,8 @@
switch_status_t (*receive_message)(switch_core_session_t *, switch_core_session_message_t *);
/*! queue a message for another session*/
switch_status_t (*receive_event)(switch_core_session_t *, switch_event_t *);
+ /*! change a sessions channel state */
+ switch_status_t (*state_change)(switch_core_session_t *);
};
/*! \brief Abstraction of an module endpoint interface
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 Wed Mar 28 13:40:13 2007
@@ -954,6 +954,7 @@
typedef struct switch_io_event_hook_waitfor_read switch_io_event_hook_waitfor_read_t;
typedef struct switch_io_event_hook_waitfor_write switch_io_event_hook_waitfor_write_t;
typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf_t;
+typedef struct switch_io_event_hook_state_change switch_io_event_hook_state_change_t;
typedef struct switch_io_routines switch_io_routines_t;
typedef struct switch_io_event_hooks switch_io_event_hooks_t;
typedef struct switch_speech_handle switch_speech_handle_t;
@@ -989,6 +990,7 @@
typedef switch_status_t (*switch_waitfor_read_hook_t)(switch_core_session_t *, int, int);
typedef switch_status_t (*switch_waitfor_write_hook_t)(switch_core_session_t *, int, int);
typedef switch_status_t (*switch_send_dtmf_hook_t)(switch_core_session_t *, char *);
+typedef switch_status_t (*switch_state_change_hook_t)(switch_core_session_t *);
typedef struct switch_stream_handle switch_stream_handle_t;
typedef switch_status_t (*switch_stream_handle_write_function_t)(switch_stream_handle_t *handle, const char *fmt, ...);
typedef switch_status_t (*switch_api_function_t)(char *in, switch_core_session_t *session, switch_stream_handle_t *stream);
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/endpoints/mod_sofia/mod_sofia.c Wed Mar 28 13:40:13 2007
@@ -2565,8 +2565,14 @@
for (map = m->m_rtpmaps; map; map = map->rm_next) {
int32_t i;
const switch_codec_implementation_t *mimp = NULL, *near_match = NULL;
+ const char * rm_encoding;
- if (!te && !strcasecmp(map->rm_encoding, "telephone-event")) {
+
+ if (!(rm_encoding = map->rm_encoding)) {
+ rm_encoding = "";
+ }
+
+ if (!te && !strcasecmp(rm_encoding, "telephone-event")) {
te = tech_pvt->te = (switch_payload_t)map->rm_pt;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set 2833 dtmf payload to %u\n", te);
if (tech_pvt->rtp_session) {
@@ -2574,7 +2580,7 @@
}
}
- if (!cng_pt && !strcasecmp(map->rm_encoding, "CN")) {
+ if (!cng_pt && !strcasecmp(rm_encoding, "CN")) {
cng_pt = tech_pvt->cng_pt = (switch_payload_t)map->rm_pt;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", cng_pt);
if (tech_pvt->rtp_session) {
@@ -2593,11 +2599,11 @@
for (i = 0; i < tech_pvt->num_codecs; i++) {
const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Compare [%s:%d]/[%s:%d]\n",
- map->rm_encoding, map->rm_pt, imp->iananame, imp->ianacode);
+ rm_encoding, map->rm_pt, imp->iananame, imp->ianacode);
if (map->rm_pt < 96) {
match = (map->rm_pt == imp->ianacode) ? 1 : 0;
} else {
- match = strcasecmp(map->rm_encoding, imp->iananame) ? 0 : 1;
+ match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
}
if (match && (map->rm_rate == imp->samples_per_second)) {
@@ -2639,7 +2645,7 @@
}
if (mimp) {
- if ((tech_pvt->rm_encoding = switch_core_session_strdup(session, (char *)map->rm_encoding))) {
+ if ((tech_pvt->rm_encoding = switch_core_session_strdup(session, (char *)rm_encoding))) {
char tmp[50];
tech_pvt->pt = (switch_payload_t)map->rm_pt;
tech_pvt->rm_rate = map->rm_rate;
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Wed Mar 28 13:40:13 2007
@@ -43,6 +43,7 @@
static void session_destroy(JSContext *cx, JSObject *obj);
static JSBool session_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+static JSBool session_originate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
static switch_api_interface_t js_run_interface;
static struct {
@@ -79,7 +80,8 @@
typedef struct sm_loadable_module sm_loadable_module_t;
typedef enum {
- S_HUP = (1 << 0)
+ S_HUP = (1 << 0),
+ S_FREE = (1 << 1)
} session_flag_t;
struct input_callback_state {
@@ -640,7 +642,8 @@
jsval argv[4];
JSObject *Event = NULL;
- if (!jss) {
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
return SWITCH_STATUS_FALSE;
}
@@ -822,15 +825,15 @@
switch_size_t has;
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
-
while ((has = switch_channel_has_dtmf(channel))) {
switch_channel_dequeue_dtmf(channel, buf, sizeof(buf));
}
@@ -845,14 +848,14 @@
switch_event_t *event;
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
while (switch_core_session_dequeue_event(jss->session, &event) == SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&event);
@@ -877,6 +880,12 @@
int32 limit = 0;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -953,6 +962,13 @@
JSFunction *function;
switch_input_args_t args = {0};
+
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1014,6 +1030,12 @@
JSFunction *function;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1074,6 +1096,55 @@
return JS_TRUE;
}
+static void check_hangup_hook(struct js_session *jss)
+{
+ jsval argv[2] = {0};
+ int argc = 0;
+ jsval ret;
+ if (jss->on_hangup ) {
+ argv[argc++] = OBJECT_TO_JSVAL(jss->obj);
+ JS_CallFunction(jss->cx, jss->obj, jss->on_hangup, argc, argv, &ret);
+ }
+}
+
+static switch_status_t hanguphook(switch_core_session_t *session)
+{
+ switch_channel_t *channel;
+ struct js_session *jss = NULL;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+ if (switch_channel_get_state(channel) == CS_HANGUP) {
+ if ((jss = switch_channel_get_private(channel, "jss"))) {
+ check_hangup_hook(jss);
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static JSBool session_hanguphook(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ JSFunction *function;
+ struct js_session *jss;
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+
+ if ((jss = JS_GetPrivate(cx, obj)) && jss->session) {
+ if (argc > 0) {
+ if ((function = JS_ValueToFunction(cx, argv[0]))) {
+ switch_channel_t *channel = switch_core_session_get_channel(jss->session);
+ assert(channel != NULL);
+ jss->on_hangup = function;
+ switch_channel_set_private(channel, "jss", jss);
+ switch_core_session_add_event_hook_state_change(jss->session, hanguphook);
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ }
+ }
+ }
+
+ return JS_TRUE;
+}
+
static JSBool session_streamfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
struct js_session *jss = JS_GetPrivate(cx, obj);
@@ -1088,6 +1159,12 @@
JSFunction *function;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1147,16 +1224,15 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
-
-
if (argc > 1) {
char *var, *val;
@@ -1176,16 +1252,14 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
-
-
if (argc > 0) {
char *var, *val;
@@ -1220,6 +1294,12 @@
JSFunction *function;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1286,6 +1366,12 @@
int32 digits = 0, timeout = 5000;
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1321,11 +1407,42 @@
return JS_FALSE;
}
+static JSBool session_autohangup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ struct js_session *jss = JS_GetPrivate(cx, obj);
+ *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
+ if (argv[0]) {
+ JSBool tf;
+ JS_ValueToBoolean(cx, argv[0], &tf);
+ if (tf == JS_TRUE) {
+ switch_set_flag(jss, S_HUP);
+ } else {
+ switch_clear_flag(jss, S_HUP);
+ }
+ *rval = BOOLEAN_TO_JSVAL(tf);
+ }
+
+ return JS_TRUE;
+}
+
static JSBool session_answer(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1349,6 +1466,11 @@
/*Always a pessimist... sheesh!*/
*rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ return JS_TRUE;
+ }
+
if (switch_ivr_generate_xml_cdr(jss->session, &cdr) == SWITCH_STATUS_SUCCESS) {
char *xml_text;
if ((xml_text = switch_xml_toxml(cdr))) {
@@ -1366,6 +1488,12 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1384,6 +1512,12 @@
unsigned int elapsed;
int32 timeout = 60;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1419,6 +1553,12 @@
unsigned int elapsed;
int32 timeout = 60;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1451,6 +1591,12 @@
switch_channel_t *channel;
struct js_session *jss = JS_GetPrivate(cx, obj);
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1468,6 +1614,12 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
jsrefcount saveDepth;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
if (application_interface->application_function) {
saveDepth = JS_SuspendRequest(cx);
@@ -1486,17 +1638,12 @@
{
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_event_t *event;
- switch_channel_t *channel;
-
- channel = switch_core_session_get_channel(jss->session);
- assert(channel != NULL);
-
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
if (switch_core_session_dequeue_event(jss->session, &event) == SWITCH_STATUS_SUCCESS) {
JSObject *Event;
@@ -1528,6 +1675,12 @@
JSObject *Event;
struct event_obj *eo;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
if (argc > 0) {
if (JS_ValueToObject(cx, argv[0], &Event)) {
if ((eo = JS_GetPrivate(cx, Event))) {
@@ -1554,6 +1707,12 @@
char *cause_name = NULL;
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1722,10 +1881,13 @@
/*********************************************************************************/
enum session_tinyid {
SESSION_NAME, SESSION_STATE,
- PROFILE_DIALPLAN, PROFILE_CID_NAME, PROFILE_CID_NUM, PROFILE_IP, PROFILE_ANI, PROFILE_ANI_II, PROFILE_DEST, SESSION_UUID
+ PROFILE_DIALPLAN, PROFILE_CID_NAME, PROFILE_CID_NUM, PROFILE_IP, PROFILE_ANI, PROFILE_ANI_II, PROFILE_DEST, SESSION_UUID, SESSION_CAUSE
};
static JSFunctionSpec session_methods[] = {
+ {"originate", session_originate, 2},
+ {"setHangupHook", session_hanguphook, 1},
+ {"setAutoHangup", session_autohangup, 1},
{"sayPhrase", session_sayphrase, 1},
{"streamFile", session_streamfile, 1},
{"collectInput", session_collect_input, 1},
@@ -1760,6 +1922,7 @@
{"aniii", PROFILE_ANI_II, JSPROP_READONLY|JSPROP_PERMANENT},
{"destination", PROFILE_DEST, JSPROP_READONLY|JSPROP_PERMANENT},
{"uuid", SESSION_UUID, JSPROP_READONLY|JSPROP_PERMANENT},
+ {"cause", SESSION_CAUSE, JSPROP_READONLY|JSPROP_PERMANENT},
{0}
};
@@ -1767,29 +1930,40 @@
{
struct js_session *jss = JS_GetPrivate(cx, obj);
int param = 0;
- JSBool res = JS_TRUE;
- switch_channel_t *channel;
- switch_caller_profile_t *caller_profile;
- char *name;
-
- if (!jss || !jss->session) {
- return JS_FALSE;
+ switch_channel_t *channel = NULL;
+ switch_caller_profile_t *caller_profile = NULL;
+ char *name = NULL;
+
+ if (jss && jss->session) {
+ channel = switch_core_session_get_channel(jss->session);
+ assert(channel != NULL);
+ caller_profile = switch_channel_get_caller_profile(channel);
}
- channel = switch_core_session_get_channel(jss->session);
- assert(channel != NULL);
-
- caller_profile = switch_channel_get_caller_profile(channel);
-
name = JS_GetStringBytes(JS_ValueToString(cx, id));
+
/* numbers are our props anything else is a method */
if (name[0] >= 48 && name[0] <= 57) {
param = atoi(name);
} else {
return JS_TRUE;
}
-
+
+ if (!channel) {
+ switch(param) {
+ case SESSION_CAUSE:
+ *vp = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, switch_channel_cause2str(jss->cause)));
+ break;
+ default:
+ *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
+ }
+ return JS_TRUE;
+ }
+
switch(param) {
+ case SESSION_CAUSE:
+ *vp = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, switch_channel_cause2str(switch_channel_get_cause(channel))));
+ break;
case SESSION_NAME:
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_name(channel)));
break;
@@ -1835,12 +2009,12 @@
}
break;
default:
- res = JS_FALSE;
+ *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
break;
-
+
}
- return res;
+ return JS_TRUE;
}
JSClass session_class = {
@@ -1859,7 +2033,7 @@
jss->session = session;
jss->flags = flags;
jss->cx = cx;
- jss->obj = obj;
+ jss->obj = session_obj;
if ((JS_SetPrivate(cx, session_obj, jss) &&
JS_DefineProperties(cx, session_obj, session_props) &&
JS_DefineFunctions(cx, session_obj, session_methods))) {
@@ -1870,18 +2044,36 @@
return NULL;
}
-
/* Session Object */
/*********************************************************************************/
+
static JSBool session_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
+ struct js_session *jss = NULL;
+
+ assert((jss = malloc(sizeof(*jss))));
+ memset(jss, 0, sizeof(*jss));
+ jss->cx = cx;
+ jss->obj = obj;
+ switch_set_flag(jss, S_FREE);
+
+ JS_SetPrivate(cx, obj, jss);
+
+ return JS_TRUE;
+}
+
+static JSBool session_originate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ struct js_session *jss = NULL;
switch_memory_pool_t *pool = NULL;
+
+ jss = JS_GetPrivate(cx, obj);
+ jss->cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+
if (argc > 1) {
- switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
- struct js_session *jss = NULL;
JSObject *session_obj;
switch_core_session_t *session = NULL, *peer_session = NULL;
- switch_caller_profile_t *caller_profile = NULL;
+ switch_caller_profile_t *caller_profile = NULL, *orig_caller_profile = NULL;
char *dest = NULL;
char *dialplan = NULL;
char *cid_name = "";
@@ -1893,12 +2085,22 @@
char *context = "";
char *username = NULL;
char *to = NULL;
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+
+ *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
if (JS_ValueToObject(cx, argv[0], &session_obj)) {
struct js_session *old_jss = NULL;
if ((old_jss = JS_GetPrivate(cx, session_obj))) {
session = old_jss->session;
+ orig_caller_profile = switch_channel_get_caller_profile(switch_core_session_get_channel(session));
+ dialplan = orig_caller_profile->dialplan;
+ cid_name = orig_caller_profile->caller_id_name;
+ cid_num = orig_caller_profile->caller_id_number;
+ ani = orig_caller_profile->ani;
+ aniii = orig_caller_profile->aniii;
+ rdnis = orig_caller_profile->rdnis;
+ context = orig_caller_profile->context;
+ username = orig_caller_profile->username;
}
}
@@ -1906,7 +2108,7 @@
if (!strchr(dest, '/')) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Channel String\n");
- return JS_TRUE;
+ goto done;
}
if (argc > 2) {
@@ -1940,7 +2142,6 @@
to = JS_GetStringBytes(JS_ValueToString(cx, argv[11]));
}
-
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
return JS_FALSE;
@@ -1959,41 +2160,45 @@
context,
dest);
- if (switch_ivr_originate(session, &peer_session, &cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile) != SWITCH_STATUS_SUCCESS) {
+ if (switch_ivr_originate(session, &peer_session, &jss->cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot Create Outgoing Channel! [%s]\n", dest);
- return JS_TRUE;
+ goto done;
}
- *rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, switch_channel_cause2str(cause)));
-
- jss = switch_core_session_alloc(peer_session, sizeof(*jss));
jss->session = peer_session;
jss->flags = 0;
- jss->cx = cx;
- jss->obj = obj;
- JS_SetPrivate(cx, obj, jss);
- switch_set_flag(jss, S_HUP);
+
+ *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing Args\n");
}
+ done:
return JS_TRUE;
}
+
+
+
static void session_destroy(JSContext *cx, JSObject *obj)
{
struct js_session *jss;
+ switch_channel_t *channel = NULL;
if (cx && obj) {
if ((jss = JS_GetPrivate(cx, obj))) {
- if (switch_test_flag(jss, S_HUP)) {
- switch_channel_t *channel;
+ if (jss->session) {
+ channel = switch_core_session_get_channel(jss->session);
+ switch_channel_set_private(channel, "jss", NULL);
+ }
- if (jss->session) {
- channel = switch_core_session_get_channel(jss->session);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- }
+ if (channel && switch_test_flag(jss, S_HUP)) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ }
+
+ if (switch_test_flag(jss, S_FREE)) {
+ free(jss);
}
}
}
@@ -2073,8 +2278,9 @@
switch_size_t read = 0;
*rval = BOOLEAN_TO_JSVAL( JS_FALSE );
-
- if (fio) {
+
+ if (!fio) {
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
return JS_TRUE;
}
Modified: freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h Wed Mar 28 13:40:13 2007
@@ -132,6 +132,8 @@
JSContext *cx;
JSObject *obj;
unsigned int flags;
+ switch_call_cause_t cause;
+ JSFunction *on_hangup;
};
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 Wed Mar 28 13:40:13 2007
@@ -948,11 +948,13 @@
SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_caller_extension(switch_channel_t *channel)
{
- switch_caller_extension_t *extension;
+ switch_caller_extension_t *extension = NULL;
assert(channel != NULL);
switch_mutex_lock(channel->profile_mutex);
- extension = channel->caller_profile->caller_extension;
+ if (channel->caller_profile) {
+ extension = channel->caller_profile->caller_extension;
+ }
switch_mutex_unlock(channel->profile_mutex);
return extension;
}
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 Wed Mar 28 13:40:13 2007
@@ -185,7 +185,6 @@
/* The main runtime obj we keep this hidden for ourselves */
static struct switch_core_runtime runtime;
-
static void db_pick_path(char *dbname, char *buf, switch_size_t size)
{
@@ -1835,20 +1834,22 @@
SWITCH_DECLARE(switch_status_t) switch_core_session_answer_channel(switch_core_session_t *session)
{
switch_io_event_hook_answer_channel_t *ptr;
- switch_status_t status = SWITCH_STATUS_FALSE;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
assert(session != NULL);
+
if (session->endpoint_interface->io_routines->answer_channel) {
- if ((status = session->endpoint_interface->io_routines->answer_channel(session)) == SWITCH_STATUS_SUCCESS) {
- for (ptr = session->event_hooks.answer_channel; ptr; ptr = ptr->next) {
- if ((status = ptr->answer_channel(session)) != SWITCH_STATUS_SUCCESS) {
- break;
- }
+ status = session->endpoint_interface->io_routines->answer_channel(session);
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ for (ptr = session->event_hooks.answer_channel; ptr; ptr = ptr->next) {
+ if ((status = ptr->answer_channel(session)) != SWITCH_STATUS_SUCCESS) {
+ break;
}
}
- } else {
- status = SWITCH_STATUS_SUCCESS;
}
+
return status;
}
@@ -1856,19 +1857,23 @@
SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_session_t *session, switch_core_session_message_t *message)
{
switch_io_event_hook_receive_message_t *ptr;
- switch_status_t status = SWITCH_STATUS_FALSE;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
assert(session != NULL);
+
if (session->endpoint_interface->io_routines->receive_message) {
- if ((status =
- session->endpoint_interface->io_routines->receive_message(session, message)) == SWITCH_STATUS_SUCCESS) {
- for (ptr = session->event_hooks.receive_message; ptr; ptr = ptr->next) {
- if ((status = ptr->receive_message(session, message)) != SWITCH_STATUS_SUCCESS) {
- break;
- }
+ status = session->endpoint_interface->io_routines->receive_message(session, message);
+
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ for (ptr = session->event_hooks.receive_message; ptr; ptr = ptr->next) {
+ if ((status = ptr->receive_message(session, message)) != SWITCH_STATUS_SUCCESS) {
+ break;
}
}
}
+
switch_core_session_kill_channel(session, SWITCH_SIG_BREAK);
return status;
}
@@ -2874,6 +2879,31 @@
}
+SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_state_change(switch_core_session_t *session,
+ switch_answer_channel_hook_t state_change)
+
+
+{
+ switch_io_event_hook_state_change_t *hook, *ptr;
+
+ assert(state_change != NULL);
+ if ((hook = switch_core_session_alloc(session, sizeof(*hook))) != 0) {
+ hook->state_change = state_change;
+ if (!session->event_hooks.state_change) {
+ session->event_hooks.state_change = hook;
+ } else {
+ for (ptr = session->event_hooks.state_change; ptr && ptr->next; ptr = ptr->next);
+ ptr->next = hook;
+
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ return SWITCH_STATUS_MEMERR;
+
+}
+
SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_read_frame(switch_core_session_t *session,
switch_read_frame_hook_t read_frame)
{
@@ -3216,13 +3246,26 @@
SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session_t *session)
{
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_io_event_hook_state_change_t *ptr;
/* If trylock fails the signal is already awake so we needn't bother */
if (switch_mutex_trylock(session->mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_signal(session->cond);
switch_mutex_unlock(session->mutex);
}
-
+
+ if (session->endpoint_interface->io_routines->state_change) {
+ status = session->endpoint_interface->io_routines->state_change(session);
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ for (ptr = session->event_hooks.state_change; ptr; ptr = ptr->next) {
+ if ((status = ptr->state_change(session)) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
+ }
}
SWITCH_DECLARE(unsigned int) switch_core_session_running(switch_core_session_t *session)
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 Wed Mar 28 13:40:13 2007
@@ -2498,7 +2498,7 @@
switch_frame_t *read_frame = NULL;
switch_memory_pool_t *pool = NULL;
int r = 0, i, and_argc = 0, or_argc = 0;
- int32_t idx = IDX_NADA;
+ int32_t sleep_ms = 1000, try =0, retries = 1, idx = IDX_NADA;
switch_codec_t write_codec = {0};
switch_frame_t write_frame = {0};
uint8_t fdata[1024], pass = 0;
@@ -2512,6 +2512,8 @@
switch_event_t *var_event = NULL;
uint8_t fail_on_single_reject = 0;
uint8_t ring_ready = 0;
+ char *loop_data = NULL;
+
write_frame.data = fdata;
*bleg = NULL;
@@ -2605,7 +2607,7 @@
}
}
- // When using the AND operator, the fail_on_single_reject flage may be set in order to indicate that a single
+ // When using the AND operator, the fail_on_single_reject flag may be set in order to indicate that a single
// rejections should terminate the attempt rather than a timeout, answer, or rejection by all.
if ((var = switch_event_get_header(var_event, "fail_on_single_reject")) && switch_true(var)) {
fail_on_single_reject = 1;
@@ -2619,6 +2621,28 @@
early_ok = 0;
}
+ if ((var_val = switch_event_get_header(var_event, "originate_retries")) && switch_true(var_val)) {
+ int32_t tmp;
+ tmp = atoi(var_val);
+ if (tmp > 0 && tmp < 101) {
+ retries = tmp;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+ "Invalid originate_retries setting of %d ignored, value must be between 1 and 100\n", tmp);
+ }
+ }
+
+ if ((var_val = switch_event_get_header(var_event, "originate_retry_sleep_ms")) && switch_true(var_val)) {
+ int32_t tmp;
+ tmp = atoi(var_val);
+ if (tmp > 500 && tmp < 60000) {
+ sleep_ms = tmp;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+ "Invalid originate_retry_sleep_ms setting of %d ignored, value must be between 500 and 60000\n", tmp);
+ }
+ }
+
if (!cid_name_override) {
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
}
@@ -2628,517 +2652,528 @@
}
- or_argc = switch_separate_string(data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
-
- if (caller_channel && or_argc > 1 && !ringback_data) {
- switch_channel_ring_ready(caller_channel);
- sent_ring = 1;
- }
-
- for (r = 0; r < or_argc; r++) {
- uint32_t hups;
- reason = SWITCH_CAUSE_UNALLOCATED;
- memset(peer_names, 0, sizeof(peer_names));
- peer_session = NULL;
- memset(peer_sessions, 0, sizeof(peer_sessions));
- memset(peer_channels, 0, sizeof(peer_channels));
- memset(caller_profiles, 0, sizeof(caller_profiles));
- chan_type = NULL;
- chan_data = NULL;
- peer_channel = NULL;
- start = 0;
- read_frame = NULL;
- pool = NULL;
- pass = 0;
- file = NULL;
- key = NULL;
- var = NULL;
- to = 0;
- and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
-
- if (caller_channel && !sent_ring && and_argc > 1 && !ringback_data) {
+ for (try = 0; try < retries; try++) {
+ switch_safe_free(loop_data);
+ assert(loop_data = strdup(data));
+ or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
+
+ if (caller_channel && or_argc > 1 && !ringback_data) {
switch_channel_ring_ready(caller_channel);
sent_ring = 1;
}
- for (i = 0; i < and_argc; i++) {
-
- chan_type = peer_names[i];
- if ((chan_data = strchr(chan_type, '/')) != 0) {
- *chan_data = '\0';
- chan_data++;
+ for (r = 0; r < or_argc; r++) {
+ uint32_t hups;
+ reason = SWITCH_CAUSE_UNALLOCATED;
+ memset(peer_names, 0, sizeof(peer_names));
+ peer_session = NULL;
+ memset(peer_sessions, 0, sizeof(peer_sessions));
+ memset(peer_channels, 0, sizeof(peer_channels));
+ memset(caller_profiles, 0, sizeof(caller_profiles));
+ chan_type = NULL;
+ chan_data = NULL;
+ peer_channel = NULL;
+ start = 0;
+ read_frame = NULL;
+ pool = NULL;
+ pass = 0;
+ file = NULL;
+ key = NULL;
+ var = NULL;
+ to = 0;
+
+ if (try > 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Originate attempt %d/%d in %d ms\n", try + 1, retries, sleep_ms);
+ switch_yield(sleep_ms * 1000);
}
-
- if (session) {
- if (!switch_channel_ready(caller_channel)) {
- status = SWITCH_STATUS_FALSE;
- goto done;
- }
- caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel);
-
- if (!cid_name_override) {
- cid_name_override = caller_caller_profile->caller_id_name;
- }
- if (!cid_num_override) {
- cid_num_override = caller_caller_profile->caller_id_number;
- }
+ and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
+
+ if (caller_channel && !sent_ring && and_argc > 1 && !ringback_data) {
+ switch_channel_ring_ready(caller_channel);
+ sent_ring = 1;
+ }
- caller_profiles[i] = switch_caller_profile_new(switch_core_session_get_pool(session),
- caller_caller_profile->username,
- caller_caller_profile->dialplan,
- cid_name_override,
- cid_num_override,
- caller_caller_profile->network_addr,
- NULL,
- NULL,
- caller_caller_profile->rdnis,
- caller_caller_profile->source,
- caller_caller_profile->context,
- chan_data);
- caller_profiles[i]->flags = caller_caller_profile->flags;
- pool = NULL;
- } else {
- if (!cid_name_override) {
- cid_name_override = "FreeSWITCH";
- }
- if (!cid_num_override) {
- cid_num_override = "0000000000";
+ for (i = 0; i < and_argc; i++) {
+
+ chan_type = peer_names[i];
+ if ((chan_data = strchr(chan_type, '/')) != 0) {
+ *chan_data = '\0';
+ chan_data++;
}
+
+ if (session) {
+ if (!switch_channel_ready(caller_channel)) {
+ status = SWITCH_STATUS_FALSE;
+ goto done;
+ }
- if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
- status = SWITCH_STATUS_TERM;
- goto done;
- }
+ caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel);
+
+ if (!cid_name_override) {
+ cid_name_override = caller_caller_profile->caller_id_name;
+ }
+ if (!cid_num_override) {
+ cid_num_override = caller_caller_profile->caller_id_number;
+ }
- if (caller_profile_override) {
- caller_profiles[i] = switch_caller_profile_new(pool,
- caller_profile_override->username,
- caller_profile_override->dialplan,
- caller_profile_override->caller_id_name,
- caller_profile_override->caller_id_number,
- caller_profile_override->network_addr,
- caller_profile_override->ani,
- caller_profile_override->aniii,
- caller_profile_override->rdnis,
- caller_profile_override->source,
- caller_profile_override->context,
- chan_data);
- } else {
- caller_profiles[i] = switch_caller_profile_new(pool,
- NULL,
- NULL,
+ caller_profiles[i] = switch_caller_profile_new(switch_core_session_get_pool(session),
+ caller_caller_profile->username,
+ caller_caller_profile->dialplan,
cid_name_override,
cid_num_override,
+ caller_caller_profile->network_addr,
NULL,
- NULL,
- NULL,
- NULL,
- __FILE__,
NULL,
+ caller_caller_profile->rdnis,
+ caller_caller_profile->source,
+ caller_caller_profile->context,
chan_data);
+ caller_profiles[i]->flags = caller_caller_profile->flags;
+ pool = NULL;
+ } else {
+ if (!cid_name_override) {
+ cid_name_override = "FreeSWITCH";
+ }
+ if (!cid_num_override) {
+ cid_num_override = "0000000000";
+ }
+
+ if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
+ status = SWITCH_STATUS_TERM;
+ goto done;
+ }
+
+ if (caller_profile_override) {
+ caller_profiles[i] = switch_caller_profile_new(pool,
+ caller_profile_override->username,
+ caller_profile_override->dialplan,
+ caller_profile_override->caller_id_name,
+ caller_profile_override->caller_id_number,
+ caller_profile_override->network_addr,
+ caller_profile_override->ani,
+ caller_profile_override->aniii,
+ caller_profile_override->rdnis,
+ caller_profile_override->source,
+ caller_profile_override->context,
+ chan_data);
+ } else {
+ caller_profiles[i] = switch_caller_profile_new(pool,
+ NULL,
+ NULL,
+ cid_name_override,
+ cid_num_override,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ __FILE__,
+ NULL,
+ chan_data);
+ }
}
- }
- if ((reason = switch_core_session_outgoing_channel(session, chan_type, caller_profiles[i], &peer_sessions[i], &pool)) != SWITCH_CAUSE_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason));
- if (pool) {
- switch_core_destroy_memory_pool(&pool);
- }
- caller_profiles[i] = NULL;
- peer_channels[i] = NULL;
- peer_sessions[i] = NULL;
- continue;
- }
+ if ((reason = switch_core_session_outgoing_channel(session, chan_type, caller_profiles[i], &peer_sessions[i], &pool)) != SWITCH_CAUSE_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason));
+ if (pool) {
+ switch_core_destroy_memory_pool(&pool);
+ }
+ caller_profiles[i] = NULL;
+ peer_channels[i] = NULL;
+ peer_sessions[i] = NULL;
+ continue;
+ }
- switch_core_session_read_lock(peer_sessions[i]);
- pool = NULL;
+ switch_core_session_read_lock(peer_sessions[i]);
+ pool = NULL;
- peer_channels[i] = switch_core_session_get_channel(peer_sessions[i]);
- assert(peer_channels[i] != NULL);
+ peer_channels[i] = switch_core_session_get_channel(peer_sessions[i]);
+ assert(peer_channels[i] != NULL);
- if (!table) {
- table = &originate_state_handlers;
- }
+ if (!table) {
+ table = &originate_state_handlers;
+ }
- if (table) {
- switch_channel_add_state_handler(peer_channels[i], table);
- }
+ if (table) {
+ switch_channel_add_state_handler(peer_channels[i], table);
+ }
- if (switch_core_session_running(peer_sessions[i])) {
- switch_channel_set_state(peer_channels[i], CS_RING);
- } else {
- switch_core_session_thread_launch(peer_sessions[i]);
+ if (switch_core_session_running(peer_sessions[i])) {
+ switch_channel_set_state(peer_channels[i], CS_RING);
+ } else {
+ switch_core_session_thread_launch(peer_sessions[i]);
+ }
}
- }
- time(&start);
+ time(&start);
- for (;;) {
- uint32_t valid_channels = 0;
- for (i = 0; i < and_argc; i++) {
- int state;
+ for (;;) {
+ uint32_t valid_channels = 0;
+ for (i = 0; i < and_argc; i++) {
+ int state;
- if (!peer_channels[i]) {
- continue;
- }
- valid_channels++;
- state = switch_channel_get_state(peer_channels[i]);
+ if (!peer_channels[i]) {
+ continue;
+ }
+ valid_channels++;
+ state = switch_channel_get_state(peer_channels[i]);
- if (state >= CS_HANGUP) {
- goto notready;
- } else if (state >= CS_RING) {
- goto endfor1;
- }
+ if (state >= CS_HANGUP) {
+ goto notready;
+ } else if (state >= CS_RING) {
+ goto endfor1;
+ }
- if (caller_channel && !switch_channel_ready(caller_channel)) {
- goto notready;
- }
+ if (caller_channel && !switch_channel_ready(caller_channel)) {
+ goto notready;
+ }
- if ((time(NULL) - start) > (time_t)timelimit_sec) {
- to++;
- idx = IDX_CANCEL;
- goto notready;
+ if ((time(NULL) - start) > (time_t)timelimit_sec) {
+ to++;
+ idx = IDX_CANCEL;
+ goto notready;
+ }
+ switch_yield(1000);
}
- switch_yield(1000);
- }
- if (valid_channels == 0) {
- status = SWITCH_STATUS_GENERR;
- goto done;
- }
+ if (valid_channels == 0) {
+ status = SWITCH_STATUS_GENERR;
+ goto done;
+ }
- }
- endfor1:
+ }
+ endfor1:
- if (ringback_data && !switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
- switch_channel_pre_answer(caller_channel);
- }
+ if (ringback_data && !switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
+ switch_channel_pre_answer(caller_channel);
+ }
- if (session && (read_codec = switch_core_session_get_read_codec(session)) &&
- (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
+ if (session && (read_codec = switch_core_session_get_read_codec(session)) &&
+ (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
- if (!(pass = (uint8_t)switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
- if (switch_core_codec_init(&write_codec,
- "L16",
- NULL,
- read_codec->implementation->samples_per_second,
- read_codec->implementation->microseconds_per_frame / 1000,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- pool) == SWITCH_STATUS_SUCCESS) {
+ if (!(pass = (uint8_t)switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
+ if (switch_core_codec_init(&write_codec,
+ "L16",
+ NULL,
+ read_codec->implementation->samples_per_second,
+ read_codec->implementation->microseconds_per_frame / 1000,
+ 1,
+ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+ NULL,
+ pool) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
- read_codec->implementation->samples_per_second,
- read_codec->implementation->microseconds_per_frame / 1000);
- write_frame.codec = &write_codec;
- write_frame.datalen = read_codec->implementation->bytes_per_frame;
- write_frame.samples = write_frame.datalen / 2;
- memset(write_frame.data, 255, write_frame.datalen);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
+ read_codec->implementation->samples_per_second,
+ read_codec->implementation->microseconds_per_frame / 1000);
+ write_frame.codec = &write_codec;
+ write_frame.datalen = read_codec->implementation->bytes_per_frame;
+ write_frame.samples = write_frame.datalen / 2;
+ memset(write_frame.data, 255, write_frame.datalen);
- if (ringback_data) {
- char *tmp_data = NULL;
+ if (ringback_data) {
+ char *tmp_data = NULL;
- switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
- switch_buffer_create_dynamic(&ringback.loop_buffer, 512, 1024, 0);
+ switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
+ switch_buffer_create_dynamic(&ringback.loop_buffer, 512, 1024, 0);
- if (*ringback_data == '/') {
- char *ext;
+ if (*ringback_data == '/') {
+ char *ext;
- if ((ext = strrchr(ringback_data, '.'))) {
- switch_core_session_set_read_codec(session, &write_codec);
- ext++;
- } else {
- ringback.asis++;
- write_frame.codec = read_codec;
- ext = read_codec->implementation->iananame;
- tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
- ringback_data = tmp_data;
- }
+ if ((ext = strrchr(ringback_data, '.'))) {
+ switch_core_session_set_read_codec(session, &write_codec);
+ ext++;
+ } else {
+ ringback.asis++;
+ write_frame.codec = read_codec;
+ ext = read_codec->implementation->iananame;
+ tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
+ ringback_data = tmp_data;
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
- ringback.fhb.channels = read_codec->implementation->number_of_channels;
- ringback.fhb.samplerate = read_codec->implementation->samples_per_second;
- if (switch_core_file_open(&ringback.fhb,
- ringback_data,
- read_codec->implementation->number_of_channels,
- read_codec->implementation->samples_per_second,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
- switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing File\n");
- switch_safe_free(tmp_data);
- goto notready;
- }
- ringback.fh = &ringback.fhb;
+ ringback.fhb.channels = read_codec->implementation->number_of_channels;
+ ringback.fhb.samplerate = read_codec->implementation->samples_per_second;
+ if (switch_core_file_open(&ringback.fhb,
+ ringback_data,
+ read_codec->implementation->number_of_channels,
+ read_codec->implementation->samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
+ switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing File\n");
+ switch_safe_free(tmp_data);
+ goto notready;
+ }
+ ringback.fh = &ringback.fhb;
- } else {
- teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
- //ringback.ts.debug = 1;
- //ringback.ts.debug_stream = switch_core_get_console();
- if (teletone_run(&ringback.ts, ringback_data)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
- teletone_destroy_session(&ringback.ts);
- switch_buffer_destroy(&ringback.audio_buffer);
- switch_buffer_destroy(&ringback.loop_buffer);
- ringback_data = NULL;
+ } else {
+ teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
+ //ringback.ts.debug = 1;
+ //ringback.ts.debug_stream = switch_core_get_console();
+ if (teletone_run(&ringback.ts, ringback_data)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
+ teletone_destroy_session(&ringback.ts);
+ switch_buffer_destroy(&ringback.audio_buffer);
+ switch_buffer_destroy(&ringback.loop_buffer);
+ ringback_data = NULL;
+ }
}
+ switch_safe_free(tmp_data);
}
- switch_safe_free(tmp_data);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error!");
+ switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
+ read_codec = NULL;
}
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error!");
- switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
- read_codec = NULL;
}
}
- }
- if (ringback_data) {
- early_ok = 0;
- }
-
- while ((!caller_channel || switch_channel_ready(caller_channel)) &&
- check_channel_status(peer_channels, peer_sessions, and_argc, &idx, &hups, file, key, early_ok, &ring_ready)) {
-
- // When the AND operator is being used, and fail_on_single_reject is set, a hangup indicates that the call should fail.
- if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec)) || (fail_on_single_reject && hups)) {
- idx = IDX_CANCEL;
- goto notready;
+ if (ringback_data) {
+ early_ok = 0;
}
- if (peer_sessions[0] && switch_core_session_dequeue_message(peer_sessions[0], &message) == SWITCH_STATUS_SUCCESS) {
- if (session && !ringback_data && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge and no ringback */
- switch_core_session_receive_message(session, message);
+ while ((!caller_channel || switch_channel_ready(caller_channel)) &&
+ check_channel_status(peer_channels, peer_sessions, and_argc, &idx, &hups, file, key, early_ok, &ring_ready)) {
+
+ // When the AND operator is being used, and fail_on_single_reject is set, a hangup indicates that the call should fail.
+ if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec)) || (fail_on_single_reject && hups)) {
+ idx = IDX_CANCEL;
+ goto notready;
}
+
+ if (peer_sessions[0] && switch_core_session_dequeue_message(peer_sessions[0], &message) == SWITCH_STATUS_SUCCESS) {
+ if (session && !ringback_data && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge and no ringback */
+ switch_core_session_receive_message(session, message);
+ }
- if (switch_test_flag(message, SCSMF_DYNAMIC)) {
- switch_safe_free(message);
- } else {
- message = NULL;
+ if (switch_test_flag(message, SCSMF_DYNAMIC)) {
+ switch_safe_free(message);
+ } else {
+ message = NULL;
+ }
}
- }
- /* read from the channel while we wait if the audio is up on it */
- if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) &&
- (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) {
- switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
+ /* read from the channel while we wait if the audio is up on it */
+ if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) &&
+ (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) {
+ switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
- if (!SWITCH_READ_ACCEPTABLE(status)) {
- break;
- }
+ if (!SWITCH_READ_ACCEPTABLE(status)) {
+ break;
+ }
- if (ring_ready && read_frame && !pass && !switch_test_flag(read_frame, SFF_CNG) && read_frame->datalen > 1) {
- if (ringback.fh) {
- uint8_t abuf[1024];
- switch_size_t mlen, olen;
- unsigned int pos = 0;
+ if (ring_ready && read_frame && !pass && !switch_test_flag(read_frame, SFF_CNG) && read_frame->datalen > 1) {
+ if (ringback.fh) {
+ uint8_t abuf[1024];
+ switch_size_t mlen, olen;
+ unsigned int pos = 0;
- if (ringback.asis) {
- mlen = read_frame->datalen;
- } else {
- mlen = read_frame->datalen / 2;
- }
+ if (ringback.asis) {
+ mlen = read_frame->datalen;
+ } else {
+ mlen = read_frame->datalen / 2;
+ }
- olen = mlen;
- switch_core_file_read(ringback.fh, abuf, &olen);
-
- if (olen == 0) {
olen = mlen;
- ringback.fh->speed = 0;
- switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
switch_core_file_read(ringback.fh, abuf, &olen);
+
if (olen == 0) {
+ olen = mlen;
+ ringback.fh->speed = 0;
+ switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
+ switch_core_file_read(ringback.fh, abuf, &olen);
+ if (olen == 0) {
+ break;
+ }
+ }
+ write_frame.data = abuf;
+ write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
+ if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
break;
}
- }
- write_frame.data = abuf;
- write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
- if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
- break;
- }
- } else if (ringback.audio_buffer) {
- if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
- write_frame.data,
- write_frame.codec->implementation->bytes_per_frame)) <= 0) {
- switch_buffer_t *tmp;
- tmp = ringback.audio_buffer;
- ringback.audio_buffer = ringback.loop_buffer;
- ringback.loop_buffer = tmp;
+ } else if (ringback.audio_buffer) {
if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
write_frame.data,
write_frame.codec->implementation->bytes_per_frame)) <= 0) {
- break;
+ switch_buffer_t *tmp;
+ tmp = ringback.audio_buffer;
+ ringback.audio_buffer = ringback.loop_buffer;
+ ringback.loop_buffer = tmp;
+ if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
+ write_frame.data,
+ write_frame.codec->implementation->bytes_per_frame)) <= 0) {
+ break;
+ }
}
}
- }
- if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
- break;
- }
- if (ringback.loop_buffer) {
- switch_buffer_write(ringback.loop_buffer, write_frame.data, write_frame.datalen);
+ if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ if (ringback.loop_buffer) {
+ switch_buffer_write(ringback.loop_buffer, write_frame.data, write_frame.datalen);
+ }
}
- }
- } else {
- switch_yield(1000);
- }
+ } else {
+ switch_yield(1000);
+ }
- }
-
- notready:
+ }
- if (caller_channel && !switch_channel_ready(caller_channel)) {
- idx = IDX_CANCEL;
- }
+ notready:
- if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
- switch_core_session_reset(session);
- }
+ if (caller_channel && !switch_channel_ready(caller_channel)) {
+ idx = IDX_CANCEL;
+ }
- for (i = 0; i < and_argc; i++) {
- if (!peer_channels[i]) {
- continue;
+ if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
+ switch_core_session_reset(session);
}
- if (i != idx) {
- if (idx == IDX_CANCEL) {
- if (to) {
- reason = SWITCH_CAUSE_NO_ANSWER;
- } else {
- reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
- }
- } else {
- if (to) {
- reason = SWITCH_CAUSE_NO_ANSWER;
- } else if (and_argc > 1) {
- reason = SWITCH_CAUSE_LOSE_RACE;
+
+ for (i = 0; i < and_argc; i++) {
+ if (!peer_channels[i]) {
+ continue;
+ }
+ if (i != idx) {
+ if (idx == IDX_CANCEL) {
+ if (to) {
+ reason = SWITCH_CAUSE_NO_ANSWER;
+ } else {
+ reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
+ }
} else {
- reason = SWITCH_CAUSE_NO_ANSWER;
+ if (to) {
+ reason = SWITCH_CAUSE_NO_ANSWER;
+ } else if (and_argc > 1) {
+ reason = SWITCH_CAUSE_LOSE_RACE;
+ } else {
+ reason = SWITCH_CAUSE_NO_ANSWER;
+ }
}
- }
- switch_channel_hangup(peer_channels[i], reason);
+ switch_channel_hangup(peer_channels[i], reason);
+ }
}
- }
- if (idx > IDX_NADA) {
- peer_session = peer_sessions[idx];
- peer_channel = peer_channels[idx];
- } else {
- status = SWITCH_STATUS_FALSE;
- goto done;
- }
+ if (idx > IDX_NADA) {
+ peer_session = peer_sessions[idx];
+ peer_channel = peer_channels[idx];
+ } else {
+ status = SWITCH_STATUS_FALSE;
+ goto done;
+ }
- if (caller_channel) {
- if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
- switch_channel_answer(caller_channel);
- } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
- switch_channel_pre_answer(caller_channel);
+ if (caller_channel) {
+ if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
+ switch_channel_answer(caller_channel);
+ } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
+ switch_channel_pre_answer(caller_channel);
+ }
}
- }
- if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
- *bleg = peer_session;
- status = SWITCH_STATUS_SUCCESS;
- } else {
- status = SWITCH_STATUS_FALSE;
- }
+ if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
+ *bleg = peer_session;
+ status = SWITCH_STATUS_SUCCESS;
+ } else {
+ status = SWITCH_STATUS_FALSE;
+ }
- done:
- *cause = SWITCH_CAUSE_UNALLOCATED;
+ done:
+ *cause = SWITCH_CAUSE_UNALLOCATED;
- if (var_event) {
- if (peer_channel && !caller_channel) { /* install the vars from the {} params */
- switch_event_header_t *header;
- for (header = var_event->headers; header; header = header->next) {
- switch_channel_set_variable(peer_channel, header->name, header->value);
- }
- }
- switch_event_destroy(&var_event);
- }
+ if (var_event) {
+ if (peer_channel && !caller_channel) { /* install the vars from the {} params */
+ switch_event_header_t *header;
+ for (header = var_event->headers; header; header = header->next) {
+ switch_channel_set_variable(peer_channel, header->name, header->value);
+ }
+ }
+ switch_event_destroy(&var_event);
+ }
- if (status == SWITCH_STATUS_SUCCESS) {
- if (caller_channel) {
- switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", switch_channel_get_name(peer_channel));
- *cause = SWITCH_CAUSE_SUCCESS;
+ if (status == SWITCH_STATUS_SUCCESS) {
+ if (caller_channel) {
+ switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", switch_channel_get_name(peer_channel));
+ *cause = SWITCH_CAUSE_SUCCESS;
- } else {
- if (peer_channel) {
- *cause = switch_channel_get_cause(peer_channel);
} else {
- for (i = 0; i < and_argc; i++) {
- if (!peer_channels[i]) {
- continue;
+ if (peer_channel) {
+ *cause = switch_channel_get_cause(peer_channel);
+ } else {
+ for (i = 0; i < and_argc; i++) {
+ if (!peer_channels[i]) {
+ continue;
+ }
+ *cause = switch_channel_get_cause(peer_channels[i]);
+ break;
}
- *cause = switch_channel_get_cause(peer_channels[i]);
- break;
}
- }
- if (!*cause) {
- if (reason) {
- *cause = reason;
- } else if (caller_channel) {
- *cause = switch_channel_get_cause(caller_channel);
- } else {
- *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
- }
- }
+ if (!*cause) {
+ if (reason) {
+ *cause = reason;
+ } else if (caller_channel) {
+ *cause = switch_channel_get_cause(caller_channel);
+ } else {
+ *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
+ }
- if (idx == IDX_CANCEL) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
- *cause, switch_channel_cause2str(*cause));
+ if (idx == IDX_CANCEL) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
+ *cause, switch_channel_cause2str(*cause));
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Error Cause: %d [%s]\n",
- *cause, switch_channel_cause2str(*cause));
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Error Cause: %d [%s]\n",
+ *cause, switch_channel_cause2str(*cause));
+ }
}
- }
- if (caller_channel) {
- switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
- }
-
- if (!pass && write_codec.implementation) {
- switch_core_codec_destroy(&write_codec);
- }
+ if (caller_channel) {
+ switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
+ }
- if (ringback.fh) {
- switch_core_file_close(ringback.fh);
- ringback.fh = NULL;
- if (read_codec && !ringback.asis) {
- switch_core_session_set_read_codec(session, read_codec);
- switch_core_session_reset(session);
+ if (!pass && write_codec.implementation) {
+ switch_core_codec_destroy(&write_codec);
}
- } else if (ringback.audio_buffer) {
- teletone_destroy_session(&ringback.ts);
- switch_buffer_destroy(&ringback.audio_buffer);
- switch_buffer_destroy(&ringback.loop_buffer);
- }
- for (i = 0; i < and_argc; i++) {
- if (!peer_channels[i]) {
- continue;
+ if (ringback.fh) {
+ switch_core_file_close(ringback.fh);
+ ringback.fh = NULL;
+ if (read_codec && !ringback.asis) {
+ switch_core_session_set_read_codec(session, read_codec);
+ switch_core_session_reset(session);
+ }
+ } else if (ringback.audio_buffer) {
+ teletone_destroy_session(&ringback.ts);
+ switch_buffer_destroy(&ringback.audio_buffer);
+ switch_buffer_destroy(&ringback.loop_buffer);
}
- switch_core_session_rwunlock(peer_sessions[i]);
- }
- if (status == SWITCH_STATUS_SUCCESS) {
- break;
+ for (i = 0; i < and_argc; i++) {
+ if (!peer_channels[i]) {
+ continue;
+ }
+ switch_core_session_rwunlock(peer_sessions[i]);
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ goto outer_for;
+ }
}
}
-
+ outer_for:
+ switch_safe_free(loop_data);
switch_safe_free(odata);
return status;
}
1
0
28 Mar '07
Author: mikej
Date: Wed Mar 28 13:35:23 2007
New Revision: 4780
Modified:
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/RELEASE
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/configure.ac
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/Doxyfile
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sdp/run_test_sdp
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/Doxyfile
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c
freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/packages/ (props changed)
Log:
sync up to sofia-sip 1.12.6 rc (1.12.5work3)
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/RELEASE
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/RELEASE (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/RELEASE Wed Mar 28 13:35:23 2007
@@ -5,28 +5,16 @@
Changes since last release
--------------------------
-<changes since last written in freshmeat.net "Changes:" style;
- and in less than 10 lines, written in 3rd person English, with
- complete sentences />
-
-Bugs in blaa and foo have been fixed. The stack now supports
-use of foobar...
+Numerous nua bugs introduced in the release 1.12.5 have been fixed. Support
+for nextnonce in Authentication-Info header has been added. The nua engine
+now fully supports application-driven SDP.
API/ABI changes and versioning
------------------------------
-<see previous release notes at
- http://sofia-sip.sourceforge.net/relnotes/ for examples ;
- - should include all changes to public headers, and
- other important information to developers;
- - and should be updated _continuously_! />
-
-**template**: New features in API are marked with Doxytag macro @VERSION_1_XX_X.
-
libsofia-sip-ua:
-- **template**: Added foobar() function (sofia-sip/foobar.h).
-- Added tag NUTAG_AUTH_CACHE() determining when to include credentials in
- the request
+- Added tag NUTAG_AUTH_CACHE() <sofia-sip/nua_tag.h> determining when to
+ include credentials in the request
- Added kqueue and /dev/poll interfaces (su_devpoll_port_create(),
su_devpoll_clone_start(), su_kqueue_port_create(), su_kqueue_clone_start()
in <sofia-sip/su_wait.h>)
@@ -48,19 +36,8 @@
Contributors to this release
----------------------------
-<list of people who contributed to _this_ release
- - update as people's patches are added, or when you commit stuff
- - current development team members (see AUTHORS) may be omitted,
- or listed at the end of the contribur list (depending on the scope
- of the work done since the last release)
- - name of the contributor should be enough (email addresses in AUTHORS),
- plus a _brief_ description of what was contributed
- - roughly sorted by number of patches accepted
-/>
-
-- **template**: First Surname (patch to nua/soa/msg)
-- Martti Mela (kqueue interface to Max OS X and FreeBSD)
- Pekka Pessi (/dev/poll interface to Solaris, kqueue)
+- Martti Mela (kqueue interface to Max OS X and FreeBSD)
- Michael Jerris (Solaris patches)
- Colin Whittaker (sresolv patch)
@@ -72,24 +49,25 @@
The Sofia-SIP has been compiled and tested on Solaris. The /dev/poll
interface (in su_devpoll_port.c) has been added for Solaris. Likewise, the
kqueue interface (in su_kqueue_port.c) has been added for FreeBSD and Mac OS
-X.
+X. There is also select-based reactor for systems without poll().
-<information about major new features
- - new/changed/removed functionality
- - links to further documentation
- - section may be omitted for minor releases
-/>
+The client authentication in nua has been updated. The nextnonce in
+Authentication-Info or Proxy-Authentication-Info headers is now. The
+NUTAG_AUTH_CACHE() policy determines how the cached credentials are used. By
+default, the credentials are included in each request within the dialog,
+however, with the NUTAG_AUTH_CACHE(nua_auth_cache_challenged) the client
+authenticates requests only after they have been challenged.
+
+The application can now fully control the SDP negotiation (when soa is
+disabled with NUTAG_MEDIA_ENABLE(0)). The application can send UPDATE and
+PRACK requests and respond to them.
Bugs fixed in this release
--------------------------
-< notable bugs fixed in this release
- - check the sf.net bug tracker; see closed bugs,
- sorted by closing date
- - other bugs as fixed in CVS/darcs
-/>
-
-- **template**: #9499652 sf.net bug item title
+- Fixed problem logging long lines from with TPORT_LOG.
+ Problem reported by Mike Murdock and Michael Jerris.
+- Nua now includes the SDP capabilities in the response to the OPTIONS
- Fixed assertion failure because BYE destroyed a session twice.
Problem reported by Michael Jerris.
- Fixed crash caused by a 0-length UDP datagram.
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/configure.ac
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/configure.ac (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/configure.ac Wed Mar 28 13:35:23 2007
@@ -11,14 +11,14 @@
dnl ---------------------------
dnl update both the version for AC_INIT and the LIBSOFIA_SIP_UA_MAJOR_MINOR
-AC_INIT([sofia-sip], [1.12.5work])
+AC_INIT([sofia-sip], [1.12.5work3])
AC_CONFIG_SRCDIR([libsofia-sip-ua/sip/sofia-sip/sip.h])
AC_SUBST(VER_LIBSOFIA_SIP_UA_MAJOR_MINOR, [1.12])
dnl Includedir specific to this sofia version
AC_SUBST(include_sofiadir, '${includedir}/sofia-sip-1.12')
-AC_SUBST(LIBVER_SOFIA_SIP_UA_CUR, [4])
+AC_SUBST(LIBVER_SOFIA_SIP_UA_CUR, [5])
AC_SUBST(LIBVER_SOFIA_SIP_UA_REV, [0])
-AC_SUBST(LIBVER_SOFIA_SIP_UA_AGE, [4])
+AC_SUBST(LIBVER_SOFIA_SIP_UA_AGE, [5])
AC_SUBST(LIBVER_SOFIA_SIP_UA_SOVER, [0]) # CUR-AGE
AC_SUBST(LIBVER_SOFIA_SIP_UA_GLIB_CUR, [3])
AC_SUBST(LIBVER_SOFIA_SIP_UA_GLIB_REV, [0])
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/Doxyfile
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/Doxyfile (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/Doxyfile Wed Mar 28 13:35:23 2007
@@ -11,6 +11,7 @@
TAGFILES += ../docs/url.doxytags=../url
TAGFILES += ../docs/msg.doxytags=../msg
TAGFILES += ../docs/sip.doxytags=../sip
+TAGFILES += ../docs/http.doxytags=../http
TAGFILES += ../docs/sresolv.doxytags=../sresolv
TAGFILES += ../docs/tport.doxytags=../tport
TAGFILES += ../docs/nta.doxytags=../nta
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/iptsec/auth_client.c Wed Mar 28 13:35:23 2007
@@ -185,22 +185,24 @@
/** Store authentication info to authenticators.
*
- * The function auc_info() feeds the authentication data from the
- * authentication info @a info to the list of authenticators @a auc_list.
+ * The function auc_info() feeds the authentication data from the @b
+ * Authentication-Info header @a info to the list of authenticators @a
+ * auc_list.
*
* @param[in,out] auc_list list of authenticators to be updated
- * @param[in] info info to be processed
- * @param[in] crcl corresponding credential class
+ * @param[in] info info header to be processed
+ * @param[in] credential_class corresponding credential class
*
- * The authentication info can be in either Authentication-Info or in
- * Proxy-Authentication-Info headers.
- * If the header is Authentication-Info, the @a crcl should be
- * #sip_authorization_class or #http_authorization_class.
- * Likewise, If the header is Proxy-Authentication-Info, the @a crcl should
- * be #sip_proxy_authorization_class or #http_proxy_authorization_class.
-
- * The authentication into usually contains next nonce or mutual
- * authentication information. We handle only nextnonce parameter.
+ * The authentication info can be in either @AuthenticationInfo or in
+ * @ProxyAuthenticationInfo headers. If the header is @AuthenticationInfo,
+ * the @a credential_class should be #sip_authorization_class or
+ * #http_authorization_class. Likewise, If the header is
+ * @ProxyAuthenticationInfo, the @a credential_class should be
+ * #sip_proxy_authorization_class or #http_proxy_authorization_class.
+
+ * The authentication into header usually contains next nonce or mutual
+ * authentication information. Currently, only the nextnonce parameter is
+ * processed.
*
* @bug
* The result can be quite unexpected if there are more than one
@@ -214,7 +216,7 @@
* @NEW_1_12_5
*/
int auc_info(auth_client_t **auc_list,
- msg_auth_info_t const *ai,
+ msg_auth_info_t const *info,
msg_hclass_t *credential_class)
{
auth_client_t *ca;
@@ -224,7 +226,7 @@
/* Update matching authenticator */
for (ca = *auc_list; ca; ca = ca->ca_next) {
- int updated = ca_info(ca, ai, credential_class);
+ int updated = ca_info(ca, info, credential_class);
if (updated < 0)
return -1;
if (updated >= 1)
@@ -243,12 +245,12 @@
*/
static
int ca_info(auth_client_t *ca,
- msg_auth_info_t const *ai,
+ msg_auth_info_t const *info,
msg_hclass_t *credential_class)
{
- assert(ca); assert(ai);
+ assert(ca); assert(info);
- if (!ca || !ai)
+ if (!ca || !info)
return -1;
if (!ca->ca_credential_class)
@@ -263,7 +265,7 @@
|| !ca->ca_auc->auc_info)
return 0;
- return ca->ca_auc->auc_info(ca, ai);
+ return ca->ca_auc->auc_info(ca, info);
}
@@ -735,7 +737,7 @@
msg_payload_t const *body,
msg_header_t **);
static int auc_digest_info(auth_client_t *ca,
- msg_auth_info_t const *ai);
+ msg_auth_info_t const *info);
static const auth_client_plugin_t ca_digest_plugin =
{
@@ -796,14 +798,14 @@
}
static int auc_digest_info(auth_client_t *ca,
- msg_auth_info_t const *ai)
+ msg_auth_info_t const *info)
{
auth_digest_client_t *cda = (auth_digest_client_t *)ca;
su_home_t *home = ca->ca_home;
char const *nextnonce = NULL;
issize_t n;
- n = auth_get_params(home, ai->ai_params,
+ n = auth_get_params(home, info->ai_params,
"nextnonce=", &nextnonce,
NULL);
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nta/nta.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nta/nta.c Wed Mar 28 13:35:23 2007
@@ -1823,10 +1823,20 @@
if (self->sa_contact)
return 0;
- if (self->sa_vias)
- v1 = self->sa_vias;
- else
- v1 = self->sa_public_vias;
+ for (v1 = self->sa_vias ? self->sa_vias : self->sa_public_vias;
+ v1;
+ v1 = v1->v_next) {
+ if (host_is_ip_address(v1->v_host)) {
+ if (!host_is_local(v1->v_host))
+ break;
+ }
+ else if (!host_has_domain_invalid(v1->v_host)) {
+ break;
+ }
+ }
+
+ if (v1 == NULL)
+ v1 = self->sa_vias ? self->sa_vias : self->sa_public_vias;
if (!v1)
return -1;
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c Wed Mar 28 13:35:23 2007
@@ -4010,7 +4010,7 @@
else
*return_cd = NULL;
- if (!*return_pl || !*return_cd)
+ if (!*return_pl || !*return_ct)
return -1;
if (session && !*return_cd)
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h Wed Mar 28 13:35:23 2007
@@ -1262,7 +1262,9 @@
* - nua_auth_cache_challenged (1) - include credentials only when
* challenged
*
- * Corresponding tag taking reference parameter is NUTAG_AUTH_CACHE_REF()
+ * Corresponding tag taking reference parameter is NUTAG_AUTH_CACHE_REF().
+ *
+ * @NEW_1_12_6
*/
#define NUTAG_AUTH_CACHE(x) nutag_auth_cache, tag_int_v(x)
SOFIAPUBVAR tag_typedef_t nutag_auth_cache;
@@ -1270,7 +1272,7 @@
#define NUTAG_AUTH_CACHE_REF(x) nutag_auth_cache_ref, tag_int_vr(&(x))
SOFIAPUBVAR tag_typedef_t nutag_auth_cache_ref;
-/** Authentication caching policy */
+/** Authentication caching policy. @NEW_1_12_6 */
enum nua_auth_cache {
/** Include credentials within dialog (default) */
nua_auth_cache_dialog = 0,
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sdp/run_test_sdp
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sdp/run_test_sdp (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sdp/run_test_sdp Wed Mar 28 13:35:23 2007
@@ -6,7 +6,7 @@
#
test_sdp="${1:-./test_sdp}"
-tests="${2:-tests}"
+tests="${2:-${0%/*}/tests}"
if test -r $tests/message-1.sdp ; then
@@ -17,6 +17,7 @@
done
else
- echo "sdp run-tests: no tests found, skipping."
+ echo "sdp run-tests: no tests found in $tests, skipping."
+ exit 77
fi
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/Doxyfile
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/Doxyfile (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/Doxyfile Wed Mar 28 13:35:23 2007
@@ -25,4 +25,6 @@
@INCLUDE = sip.doxyaliases
+PREDEFINED += SU_HAVE_EXPERIMENTAL=1
+
IMAGE_PATH += images
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/sip/sip_util.c Wed Mar 28 13:35:23 2007
@@ -247,8 +247,8 @@
if (port || host_is_ip_address(host))
transport = NULL;
}
- else if (port && host_is_ip_address(host) &&
- strcmp(port, SIP_DEFAULT_SERV) == 0) {
+ else if (port && strcmp(port, SIP_DEFAULT_SERV) == 0 &&
+ (host_is_ip_address(host) || host_has_domain_invalid(host))) {
port = NULL;
}
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/su/su_timer.c Wed Mar 28 13:35:23 2007
@@ -157,6 +157,7 @@
unsigned char sut_set; /**< Timer is set (inserted in tree) */
};
+/** @internal Timer running status */
enum sut_running {
reset = 0, /**< Timer is not running */
run_at_intervals = 1, /**< Compensate missed wakeup calls */
Modified: freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c
==============================================================================
--- freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c (original)
+++ freeswitch/branches/mikej/sofiasip-upgrade/libs/sofia-sip/libsofia-sip-ua/tport/tport_logging.c Wed Mar 28 13:35:23 2007
@@ -221,17 +221,17 @@
n = strncspn(s, end - s, "\r\n");
if (linelen + n > MAX_LINELEN) {
- n = MAX_LINELEN - n - linelen;
+ n = MAX_LINELEN - linelen;
truncated = logged + n;
}
- su_log("%s%.*s", linelen > n ? "" : " ", (int)n, s);
+ su_log("%s%.*s", linelen > 0 ? "" : " ", (int)n, s);
s += n, linelen += n, logged += n;
if (truncated)
break;
if (s == end)
- continue;
+ break;
linelen = 0;
su_log("\n");
1
0