Freeswitch-trunk
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
- 14172 discussions
03 Oct '07
Author: anthm
Date: Wed Oct 3 12:44:11 2007
New Revision: 5784
Added:
freeswitch/trunk/src/softtimer.c
Removed:
freeswitch/trunk/src/mod/timers/mod_softtimer/
Modified:
freeswitch/trunk/Makefile.am
freeswitch/trunk/src/include/private/switch_core_pvt.h
freeswitch/trunk/src/include/switch_core.h
freeswitch/trunk/src/include/switch_loadable_module.h
freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
freeswitch/trunk/src/mod/endpoints/mod_alsa/mod_alsa.c
freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
freeswitch/trunk/src/mod/say/mod_say_en/mod_say_en.c
freeswitch/trunk/src/switch_channel.c
freeswitch/trunk/src/switch_console.c
freeswitch/trunk/src/switch_core.c
freeswitch/trunk/src/switch_core_session.c
freeswitch/trunk/src/switch_event.c
freeswitch/trunk/src/switch_loadable_module.c
freeswitch/trunk/src/switch_log.c
freeswitch/trunk/src/switch_scheduler.c
freeswitch/trunk/src/switch_stun.c
Log:
add softtimer to the core, begin framework for static modules and reduces calls to gettimeofday for timestamps
Modified: freeswitch/trunk/Makefile.am
==============================================================================
--- freeswitch/trunk/Makefile.am (original)
+++ freeswitch/trunk/Makefile.am Wed Oct 3 12:44:11 2007
@@ -53,6 +53,7 @@
src/switch_stun.c\
src/switch_log.c\
src/switch_xml.c\
+src/softtimer.c\
libs/stfu/stfu.c\
src/switch_cpp.cpp\
libs/libteletone/src/libteletone_detect.c\
Modified: freeswitch/trunk/src/include/private/switch_core_pvt.h
==============================================================================
--- freeswitch/trunk/src/include/private/switch_core_pvt.h (original)
+++ freeswitch/trunk/src/include/private/switch_core_pvt.h Wed Oct 3 12:44:11 2007
@@ -152,6 +152,10 @@
uint8_t running;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
uint32_t flags;
+ switch_time_t timestamp;
+ switch_mutex_t *throttle_mutex;
+ uint32_t sps_total;
+ int32_t sps;
};
extern struct switch_runtime runtime;
Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h (original)
+++ freeswitch/trunk/src/include/switch_core.h Wed Oct 3 12:44:11 2007
@@ -253,6 +253,13 @@
SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit);
/*!
+ \brief Set/Get Session Rate Limit
+ \param new_limit new value (if > 0)
+ \return the current session rate limit
+*/
+SWITCH_DECLARE(uint32_t) switch_core_sessions_per_second(uint32_t new_limit);
+
+/*!
\brief Destroy the core
\note to be called at application shutdown
*/
@@ -1464,6 +1471,7 @@
SWITCH_DECLARE(switch_loadable_module_interface_t *) switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name);
SWITCH_DECLARE(void *) switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname);
+SWITCH_DECLARE(switch_time_t) switch_timestamp_now(void);
///\}
/*!
Modified: freeswitch/trunk/src/include/switch_loadable_module.h
==============================================================================
--- freeswitch/trunk/src/include/switch_loadable_module.h (original)
+++ freeswitch/trunk/src/include/switch_loadable_module.h Wed Oct 3 12:44:11 2007
@@ -120,13 +120,16 @@
\param switch_module_load the function to call when the module is loaded
\param switch_module_runtime a function requested to be started in it's own thread once loaded
\param switch_module_shutdown the function to call when the system is shutdown
+ \param runtime start the runtime thread or not
\return the resulting status
\note only use this function if you are making a module that in turn gateways module loading to another technology
*/
SWITCH_DECLARE(switch_status_t) switch_loadable_module_build_dynamic(char *filename,
switch_module_load_t switch_module_load,
switch_module_runtime_t switch_module_runtime,
- switch_module_shutdown_t switch_module_shutdown);
+ switch_module_shutdown_t switch_module_shutdown,
+ switch_bool_t runtime);
+
/*!
\brief Retrieve the timer interface by it's registered name
@@ -312,6 +315,11 @@
///\}
+#define SWITCH_DECLARE_STATIC_MODULE(init, load, run, shut) void init(void) { \
+ switch_loadable_module_build_dynamic(__FILE__, load, run, shut, SWITCH_FALSE); \
+ }
+
+
SWITCH_END_EXTERN_C
#endif
/* For Emacs:
Modified: freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c Wed Oct 3 12:44:11 2007
@@ -112,7 +112,7 @@
switch_event_t *event = NULL;
char date[80] = "";
switch_time_exp_t tm;
- switch_time_t ts = switch_time_now();
+ switch_time_t ts = switch_timestamp_now();
switch_size_t retsize;
@@ -181,6 +181,7 @@
switch_queue_push(node->fifo, uuid);
switch_mutex_unlock(node->mutex);
+ ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "WAITING");
@@ -208,7 +209,7 @@
if (switch_channel_ready(channel)) {
switch_channel_set_state(channel, CS_HIBERNATE);
} else {
-
+ ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "ABORTED");
@@ -263,7 +264,7 @@
switch_event_fire(&event);
}
-
+ ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "WAITING");
@@ -344,6 +345,7 @@
assert(cloned_profile->next == NULL);
switch_channel_set_originatee_caller_profile(channel, cloned_profile);
+ ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "TALKING");
@@ -355,6 +357,7 @@
switch_channel_set_variable(other_channel, "fifo_target", switch_core_session_get_uuid(session));
switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
+ ts = switch_timestamp_now();
switch_time_exp_lt(&tm, ts);
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
switch_channel_set_variable(channel, "fifo_status", "WAITING");
Modified: freeswitch/trunk/src/mod/endpoints/mod_alsa/mod_alsa.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_alsa/mod_alsa.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_alsa/mod_alsa.c Wed Oct 3 12:44:11 2007
@@ -180,7 +180,7 @@
assert(channel != NULL);
- last = switch_time_now() - waitsec;
+ last = switch_timestamp_now() - waitsec;
@@ -243,7 +243,7 @@
switch_channel_mark_ring_ready(channel);
while (switch_channel_get_state(channel) == CS_INIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
- if (switch_time_now() - last >= waitsec) {
+ if (switch_timestamp_now() - last >= waitsec) {
char buf[512];
switch_event_t *event;
@@ -257,7 +257,7 @@
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", buf);
- last = switch_time_now();
+ last = switch_timestamp_now();
if (ring_file) {
unsigned int pos = 0;
switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
Modified: freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c Wed Oct 3 12:44:11 2007
@@ -1061,18 +1061,18 @@
switch_set_flag_locked(tech_pvt, TFLAG_IO);
- started = switch_time_now();
+ started = switch_timestamp_now();
/* jingle has no ringing indication so we will just pretend that we got one */
switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
switch_channel_mark_ring_ready(channel);
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
- tech_pvt->next_cand = switch_time_now() + DL_CAND_WAIT;
- tech_pvt->next_desc = switch_time_now();
+ tech_pvt->next_cand = started + DL_CAND_WAIT;
+ tech_pvt->next_desc = started;
} else {
- tech_pvt->next_cand = switch_time_now() + DL_CAND_WAIT;
- tech_pvt->next_desc = switch_time_now() + DL_CAND_WAIT;
+ tech_pvt->next_cand = started + DL_CAND_WAIT;
+ tech_pvt->next_desc = started + DL_CAND_WAIT;
}
while (!(switch_test_flag(tech_pvt, TFLAG_CODEC_READY) &&
@@ -1080,7 +1080,7 @@
switch_test_flag(tech_pvt, TFLAG_ANSWER) && switch_test_flag(tech_pvt, TFLAG_TRANSPORT_ACCEPT) &&
tech_pvt->remote_ip && tech_pvt->remote_port
&& switch_test_flag(tech_pvt, TFLAG_TRANSPORT))) {
- now = switch_time_now();
+ now = switch_timestamp_now();
elapsed = (unsigned int) ((now - started) / 1000);
if (switch_channel_get_state(channel) >= CS_HANGUP || switch_test_flag(tech_pvt, TFLAG_BYE)) {
@@ -1365,7 +1365,7 @@
#if 0
if (tech_pvt->last_read) {
- elapsed = (unsigned int) ((switch_time_now() - tech_pvt->last_read) / 1000);
+ elapsed = (unsigned int) ((switch_timestamp_now() - tech_pvt->last_read) / 1000);
if (elapsed > 60000) {
return SWITCH_STATUS_TIMEOUT;
}
@@ -1393,7 +1393,7 @@
payload = tech_pvt->read_frame.payload;
#if 0
- elapsed = (unsigned int) ((switch_time_now() - started) / 1000);
+ elapsed = (unsigned int) ((switch_timestamp_now() - started) / 1000);
if (timeout > -1) {
if (elapsed >= (unsigned int) timeout) {
@@ -1401,7 +1401,7 @@
}
}
- elapsed = (unsigned int) ((switch_time_now() - last_act) / 1000);
+ elapsed = (unsigned int) ((switch_timestamp_now() - last_act) / 1000);
if (elapsed >= hard_timeout) {
return SWITCH_STATUS_BREAK;
}
Modified: freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c Wed Oct 3 12:44:11 2007
@@ -179,7 +179,7 @@
assert(channel != NULL);
- last = switch_time_now() - waitsec;
+ last = switch_timestamp_now() - waitsec;
@@ -244,7 +244,7 @@
while (switch_channel_get_state(channel) == CS_INIT && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
switch_size_t olen = globals.timer.samples;
- if (switch_time_now() - last >= waitsec) {
+ if (switch_timestamp_now() - last >= waitsec) {
char buf[512];
switch_event_t *event;
@@ -257,7 +257,7 @@
switch_event_fire(&event);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", buf);
- last = switch_time_now();
+ last = switch_timestamp_now();
}
if (ring_file) {
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c Wed Oct 3 12:44:11 2007
@@ -1832,8 +1832,7 @@
}
if (!sofia_endpoint_interface || !(session = switch_core_session_request(sofia_endpoint_interface, NULL))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
- nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
+ nua_respond(nh, SIP_486_BUSY_HERE, TAG_END());
return;
}
Modified: freeswitch/trunk/src/mod/say/mod_say_en/mod_say_en.c
==============================================================================
--- freeswitch/trunk/src/mod/say/mod_say_en/mod_say_en.c (original)
+++ freeswitch/trunk/src/mod/say/mod_say_en/mod_say_en.c Wed Oct 3 12:44:11 2007
@@ -346,7 +346,7 @@
if ((t = atoi(tosay)) > 0) {
target = switch_time_make(t, 0);
} else {
- target = switch_time_now();
+ target = switch_timestamp_now();
}
switch_time_exp_lt(&tm, target);
Added: freeswitch/trunk/src/softtimer.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/softtimer.c Wed Oct 3 12:44:11 2007
@@ -0,0 +1,311 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct(a)yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct(a)yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Anthony Minessale II <anthmct(a)yahoo.com>
+ *
+ *
+ * softtimer.c -- Software Timer Module
+ *
+ */
+#include <switch.h>
+#include <stdio.h>
+#include "private/switch_core_pvt.h"
+
+#ifndef UINT32_MAX
+#define UINT32_MAX 0xffffffff
+#endif
+
+#define MAX_TICK UINT32_MAX - 1024
+
+struct switch_runtime runtime;
+static switch_memory_pool_t *module_pool = NULL;
+
+static struct {
+ int32_t RUNNING;
+ int32_t STARTED;
+ switch_mutex_t *mutex;
+} globals;
+
+SWITCH_MODULE_LOAD_FUNCTION(softtimer_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown);
+SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime);
+SWITCH_MODULE_DEFINITION(softtimer, softtimer_load, softtimer_shutdown, softtimer_runtime);
+
+#define MAX_ELEMENTS 1000
+
+struct timer_private {
+ switch_size_t reference;
+ switch_size_t start;
+ uint32_t roll;
+ uint32_t ready;
+};
+typedef struct timer_private timer_private_t;
+
+struct timer_matrix {
+ switch_size_t tick;
+ uint32_t count;
+ uint32_t roll;
+};
+typedef struct timer_matrix timer_matrix_t;
+
+static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1];
+
+#define IDLE_SPEED 100
+
+
+static switch_status_t timer_init(switch_timer_t *timer)
+{
+ timer_private_t *private_info;
+ int sanity = 0;
+
+ while(globals.STARTED == 0) {
+ switch_yield(100000);
+ if (++sanity == 10) {
+ break;
+ }
+ }
+
+ if (globals.RUNNING != 1 || !globals.mutex) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if ((private_info = switch_core_alloc(timer->memory_pool, sizeof(*private_info)))) {
+ switch_mutex_lock(globals.mutex);
+ TIMER_MATRIX[timer->interval].count++;
+ switch_mutex_unlock(globals.mutex);
+ timer->private_info = private_info;
+ private_info->start = private_info->reference = TIMER_MATRIX[timer->interval].tick;
+ private_info->roll = TIMER_MATRIX[timer->interval].roll;
+ private_info->ready = 1;
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ return SWITCH_STATUS_MEMERR;
+}
+
+
+#define check_roll() if (private_info->roll < TIMER_MATRIX[timer->interval].roll) {\
+ private_info->roll++;\
+ private_info->reference = private_info->start = TIMER_MATRIX[timer->interval].tick;\
+ }\
+
+
+
+static switch_status_t timer_step(switch_timer_t *timer)
+{
+ timer_private_t *private_info = timer->private_info;
+ uint64_t samples;
+
+ if (globals.RUNNING != 1 || private_info->ready == 0) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ check_roll();
+ samples = timer->samples * (private_info->reference - private_info->start);
+
+ if (samples > UINT32_MAX) {
+ private_info->start = private_info->reference;
+ samples = timer->samples;
+ }
+
+ timer->samplecount = (uint32_t) samples;
+ private_info->reference++;
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_status_t timer_next(switch_timer_t *timer)
+{
+ timer_private_t *private_info = timer->private_info;
+
+ timer_step(timer);
+
+ while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
+ check_roll();
+ switch_yield(1000);
+ }
+
+ if (globals.RUNNING == 1) {
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t timer_check(switch_timer_t *timer)
+{
+ timer_private_t *private_info = timer->private_info;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_size_t diff;
+
+ if (globals.RUNNING != 1 || !private_info->ready) {
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ check_roll();
+
+ if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
+ diff = private_info->reference - TIMER_MATRIX[timer->interval].tick;
+ } else {
+ diff = 0;
+ }
+
+ if (diff) {
+ status = SWITCH_STATUS_FALSE;
+ } else {
+ timer_step(timer);
+ }
+
+ return status;
+}
+
+
+static switch_status_t timer_destroy(switch_timer_t *timer)
+{
+ timer_private_t *private_info = timer->private_info;
+ switch_mutex_lock(globals.mutex);
+ TIMER_MATRIX[timer->interval].count--;
+ if (TIMER_MATRIX[timer->interval].count == 0) {
+ TIMER_MATRIX[timer->interval].tick = 0;
+ }
+ switch_mutex_unlock(globals.mutex);
+ private_info->ready = 0;
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+#define STEP_MS 1
+#define STEP_MIC 1000
+
+SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
+{
+ switch_time_t reference = switch_time_now();
+ uint32_t current_ms = 0;
+ uint32_t x, tick = 0;
+ switch_time_t ts = 0;
+
+ memset(&globals, 0, sizeof(globals));
+ switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
+
+ globals.STARTED = globals.RUNNING = 1;
+ switch_mutex_lock(runtime.throttle_mutex);
+ runtime.sps = runtime.sps_total;
+ switch_mutex_unlock(runtime.throttle_mutex);
+
+ while (globals.RUNNING == 1) {
+ reference += STEP_MIC;
+ while ((ts = switch_time_now()) < reference) {
+ switch_yield(STEP_MIC);
+ }
+ runtime.timestamp = ts;
+ current_ms += STEP_MS;
+ tick += STEP_MS;
+
+ if (tick >= 1000) {
+ if (runtime.sps <= 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
+ }
+ switch_mutex_lock(runtime.throttle_mutex);
+ runtime.sps = runtime.sps_total;
+ switch_mutex_unlock(runtime.throttle_mutex);
+ tick = 0;
+ }
+
+ for (x = 0; x < MAX_ELEMENTS; x++) {
+ int i = x, index;
+ if (i == 0) {
+ i = 1;
+ }
+
+ index = (current_ms % i == 0) ? i : 0;
+
+ if (TIMER_MATRIX[index].count) {
+ TIMER_MATRIX[index].tick++;
+ if (TIMER_MATRIX[index].tick == MAX_TICK) {
+ TIMER_MATRIX[index].tick = 0;
+ TIMER_MATRIX[index].roll++;
+ }
+ }
+ }
+
+ if (current_ms == MAX_ELEMENTS) {
+ current_ms = 0;
+ }
+ }
+
+ switch_mutex_lock(globals.mutex);
+ globals.RUNNING = 0;
+ switch_mutex_unlock(globals.mutex);
+
+ return SWITCH_STATUS_TERM;
+}
+
+
+SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
+{
+ switch_timer_interface_t *timer_interface;
+ module_pool = pool;
+
+ /* connect my internal structure to the blank pointer passed to me */
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
+ timer_interface->interface_name = "soft";
+ timer_interface->timer_init = timer_init;
+ timer_interface->timer_next = timer_next;
+ timer_interface->timer_step = timer_step;
+ timer_interface->timer_check = timer_check;
+ timer_interface->timer_destroy = timer_destroy;
+
+ /* indicate that the module should continue to be loaded */
+ return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown)
+{
+
+ if (globals.RUNNING) {
+ switch_mutex_lock(globals.mutex);
+ globals.RUNNING = -1;
+ switch_mutex_unlock(globals.mutex);
+
+ while (globals.RUNNING) {
+ switch_yield(10000);
+ }
+ }
+ switch_core_destroy_memory_pool(&module_pool);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
+ */
Modified: freeswitch/trunk/src/switch_channel.c
==============================================================================
--- freeswitch/trunk/src/switch_channel.c (original)
+++ freeswitch/trunk/src/switch_channel.c Wed Oct 3 12:44:11 2007
@@ -855,7 +855,7 @@
caller_profile->times->created = switch_time_now();
if (channel->caller_profile && channel->caller_profile->times) {
- channel->caller_profile->times->transferred = switch_time_now();
+ channel->caller_profile->times->transferred = caller_profile->times->created;
caller_profile->times->answered = channel->caller_profile->times->answered;
}
Modified: freeswitch/trunk/src/switch_console.c
==============================================================================
--- freeswitch/trunk/src/switch_console.c (original)
+++ freeswitch/trunk/src/switch_console.c Wed Oct 3 12:44:11 2007
@@ -151,7 +151,7 @@
switch_size_t retsize;
switch_time_exp_t tm;
switch_event_t *event;
- switch_time_exp_lt(&tm, switch_time_now());
+ switch_time_exp_lt(&tm, switch_timestamp_now());
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
if (channel == SWITCH_CHANNEL_ID_LOG) {
Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Wed Oct 3 12:44:11 2007
@@ -79,6 +79,10 @@
task->runtime = time(NULL) + 20;
}
+SWITCH_DECLARE(switch_time_t) switch_timestamp_now(void)
+{
+ return runtime.timestamp ? runtime.timestamp : switch_time_now();
+}
SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console)
{
@@ -413,12 +417,12 @@
return SWITCH_STATUS_MEMERR;
}
assert(runtime.memory_pool != NULL);
-
+ switch_mutex_init(&runtime.throttle_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
switch_core_set_globals();
switch_core_session_init(runtime.memory_pool);
switch_core_hash_init(&runtime.global_vars, runtime.memory_pool);
runtime.flags = flags;
-
+ runtime.sps_total = 30;
if (switch_xml_init(runtime.memory_pool, err) != SWITCH_STATUS_SUCCESS) {
apr_terminate();
@@ -438,6 +442,8 @@
if (switch_true(val)) {
switch_set_flag((&runtime), SCF_CRASH_PROT);
}
+ } else if (!strcasecmp(var, "sessions-per-second")) {
+ switch_core_sessions_per_second(atoi(val));
} else if (!strcasecmp(var, "max-sessions")) {
switch_core_session_limit(atoi(val));
}
@@ -582,9 +588,10 @@
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,
- "\nFreeSWITCH Version %s Started.\nCrash Protection [%s]\nMax Sessions[%u]\nSQL [%s]\n", SWITCH_VERSION_FULL,
+ "\nFreeSWITCH Version %s Started.\nCrash Protection [%s]\nMax Sessions[%u]\nSession Rate[%d]\nSQL [%s]\n", SWITCH_VERSION_FULL,
switch_test_flag((&runtime), SCF_CRASH_PROT) ? "Enabled" : "Disabled",
switch_core_session_limit(0),
+ switch_core_sessions_per_second(0),
switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"
);
Modified: freeswitch/trunk/src/switch_core_session.c
==============================================================================
--- freeswitch/trunk/src/switch_core_session.c (original)
+++ freeswitch/trunk/src/switch_core_session.c Wed Oct 3 12:44:11 2007
@@ -37,7 +37,6 @@
static struct {
switch_memory_pool_t *memory_pool;
switch_hash_t *session_table;
- switch_mutex_t *session_table_mutex;
uint32_t session_count;
uint32_t session_limit;
switch_size_t session_id;
@@ -53,7 +52,7 @@
switch_core_session_t *session = NULL;
if (uuid_str) {
- switch_mutex_lock(session_manager.session_table_mutex);
+ switch_mutex_lock(runtime.throttle_mutex);
if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
/* Acquire a read lock on the session */
#ifdef SWITCH_DEBUG_RWLOCKS
@@ -65,7 +64,7 @@
session = NULL;
}
}
- switch_mutex_unlock(session_manager.session_table_mutex);
+ switch_mutex_unlock(runtime.throttle_mutex);
}
/* if its not NULL, now it's up to you to rwunlock this */
@@ -80,7 +79,7 @@
switch_channel_t *channel;
uint32_t loops = 0;
- switch_mutex_lock(session_manager.session_table_mutex);
+ switch_mutex_lock(runtime.throttle_mutex);
for (hi = switch_hash_first(NULL, session_manager.session_table); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
if (val) {
@@ -90,7 +89,7 @@
switch_core_session_kill_channel(session, SWITCH_SIG_KILL);
}
}
- switch_mutex_unlock(session_manager.session_table_mutex);
+ switch_mutex_unlock(runtime.throttle_mutex);
while (session_manager.session_count > 0) {
switch_yield(100000);
@@ -107,7 +106,7 @@
switch_core_session_t *session = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
- switch_mutex_lock(session_manager.session_table_mutex);
+ switch_mutex_lock(runtime.throttle_mutex);
if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
/* Acquire a read lock on the session or forget it the channel is dead */
if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
@@ -117,7 +116,7 @@
switch_core_session_rwunlock(session);
}
}
- switch_mutex_unlock(session_manager.session_table_mutex);
+ switch_mutex_unlock(runtime.throttle_mutex);
return status;
}
@@ -127,7 +126,7 @@
switch_core_session_t *session = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
- switch_mutex_lock(session_manager.session_table_mutex);
+ switch_mutex_lock(runtime.throttle_mutex);
if ((session = switch_core_hash_find(session_manager.session_table, uuid_str)) != 0) {
/* Acquire a read lock on the session or forget it the channel is dead */
if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
@@ -137,7 +136,7 @@
switch_core_session_rwunlock(session);
}
}
- switch_mutex_unlock(session_manager.session_table_mutex);
+ switch_mutex_unlock(runtime.throttle_mutex);
return status;
}
@@ -645,12 +644,12 @@
switch_scheduler_del_task_group((*session)->uuid_str);
- switch_mutex_lock(session_manager.session_table_mutex);
+ switch_mutex_lock(runtime.throttle_mutex);
switch_core_hash_delete(session_manager.session_table, (*session)->uuid_str);
if (session_manager.session_count) {
session_manager.session_count--;
}
- switch_mutex_unlock(session_manager.session_table_mutex);
+ switch_mutex_unlock(runtime.throttle_mutex);
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DESTROY) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data((*session)->channel, event);
@@ -744,18 +743,25 @@
switch_core_session_t *session;
switch_uuid_t uuid;
uint32_t count = 0;
+ int32_t sps = 0;
if (!switch_core_ready() || endpoint_interface == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any sessions at this time.\n");
return NULL;
}
- switch_mutex_lock(session_manager.session_table_mutex);
+ switch_mutex_lock(runtime.throttle_mutex);
count = session_manager.session_count;
- switch_mutex_unlock(session_manager.session_table_mutex);
+ sps = --runtime.sps;
+ switch_mutex_unlock(runtime.throttle_mutex);
+
+ if (sps <= 0) {
+ //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error!\n");
+ return NULL;
+ }
if ((count + 1) > session_manager.session_limit) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n");
+ //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n");
return NULL;
}
@@ -779,6 +785,7 @@
return NULL;
}
+
switch_channel_init(session->channel, session, CS_NEW, 0);
/* The session *IS* the pool you may not alter it because you have no idea how
@@ -810,11 +817,11 @@
switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
snprintf(session->name, sizeof(session->name), "%"SWITCH_SIZE_T_FMT, session->id);
- switch_mutex_lock(session_manager.session_table_mutex);
+ switch_mutex_lock(runtime.throttle_mutex);
session->id = session_manager.session_id++;
switch_core_hash_insert(session_manager.session_table, session->uuid_str, session);
session_manager.session_count++;
- switch_mutex_unlock(session_manager.session_table_mutex);
+ switch_mutex_unlock(runtime.throttle_mutex);
return session;
}
@@ -871,6 +878,15 @@
return session_manager.session_limit;
}
+SWITCH_DECLARE(uint32_t) switch_core_sessions_per_second(uint32_t new_limit)
+{
+ if (new_limit) {
+ runtime.sps_total = new_limit;
+ }
+
+ return runtime.sps_total;
+}
+
void switch_core_session_init(switch_memory_pool_t *pool)
{
@@ -879,7 +895,6 @@
session_manager.session_id = 1;
session_manager.memory_pool = pool;
switch_core_hash_init(&session_manager.session_table, session_manager.memory_pool);
- switch_mutex_init(&session_manager.session_table_mutex, SWITCH_MUTEX_NESTED, session_manager.memory_pool);
}
void switch_core_session_uninit(void)
Modified: freeswitch/trunk/src/switch_event.c
==============================================================================
--- freeswitch/trunk/src/switch_event.c (original)
+++ freeswitch/trunk/src/switch_event.c Wed Oct 3 12:44:11 2007
@@ -870,7 +870,7 @@
switch_time_exp_t tm;
char date[80] = "";
switch_size_t retsize;
- switch_time_t ts = switch_time_now();
+ switch_time_t ts = switch_timestamp_now();
assert(BLOCK != NULL);
assert(RUNTIME_POOL != NULL);
Modified: freeswitch/trunk/src/switch_loadable_module.c
==============================================================================
--- freeswitch/trunk/src/switch_loadable_module.c (original)
+++ freeswitch/trunk/src/switch_loadable_module.c Wed Oct 3 12:44:11 2007
@@ -655,14 +655,19 @@
assert(path != NULL);
+ switch_core_new_memory_pool(&pool);
*new_module = NULL;
- status = switch_dso_load(&dso, path, loadable_modules.pool);
- if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
- abort();
+ struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
+
+ status = switch_dso_load(&dso, NULL, loadable_modules.pool);
+ status = switch_dso_sym(&interface_struct_handle, dso, struct_name);
+
+ if (!interface_struct_handle) {
+ status = switch_dso_load(&dso, path, loadable_modules.pool);
}
+
while (loading) {
if (status != APR_SUCCESS) {
switch_dso_error(dso, derr, sizeof(derr));
@@ -670,8 +675,10 @@
break;
}
- struct_name = switch_core_sprintf(pool, "%s_module_interface", filename);
- status = switch_dso_sym(&interface_struct_handle, dso, struct_name);
+ if (!interface_struct_handle) {
+ status = switch_dso_sym(&interface_struct_handle, dso, struct_name);
+ }
+
if (interface_struct_handle) {
mod_interface_functions = interface_struct_handle;
load_func_ptr = mod_interface_functions->load;
@@ -822,7 +829,8 @@
SWITCH_DECLARE(switch_status_t) switch_loadable_module_build_dynamic(char *filename,
switch_module_load_t switch_module_load,
switch_module_runtime_t switch_module_runtime,
- switch_module_shutdown_t switch_module_shutdown)
+ switch_module_shutdown_t switch_module_shutdown,
+ switch_bool_t runtime)
{
switch_loadable_module_t *module = NULL;
switch_module_load_t load_func_ptr = NULL;
@@ -890,7 +898,7 @@
if (switch_module_runtime) {
module->switch_module_runtime = switch_module_runtime;
}
- if (module->switch_module_runtime) {
+ if (runtime && module->switch_module_runtime) {
switch_core_launch_thread(switch_loadable_module_exec, module, module->pool);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Successfully Loaded [%s]\n", module_interface->module_name);
@@ -962,6 +970,8 @@
switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool);
switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED, loadable_modules.pool);
+ switch_loadable_module_load_module("", "softtimer", SWITCH_FALSE, &err);
+
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_xml_t mods, ld;
if ((mods = switch_xml_child(cfg, "modules"))) {
@@ -1036,7 +1046,7 @@
}
apr_dir_close(module_dir_handle);
}
-
+
switch_loadable_module_runtime();
return SWITCH_STATUS_SUCCESS;
Modified: freeswitch/trunk/src/switch_log.c
==============================================================================
--- freeswitch/trunk/src/switch_log.c (original)
+++ freeswitch/trunk/src/switch_log.c Wed Oct 3 12:44:11 2007
@@ -162,7 +162,7 @@
const char *filep = (file ? switch_cut_path(file) : "");
const char *funcp = (func ? func : "");
char *content = NULL;
- switch_time_t now = switch_time_now();
+ switch_time_t now = switch_timestamp_now();
uint32_t len;
const char *extra_fmt = "%s [%s] %s:%d %s()%c%s";
Modified: freeswitch/trunk/src/switch_scheduler.c
==============================================================================
--- freeswitch/trunk/src/switch_scheduler.c (original)
+++ freeswitch/trunk/src/switch_scheduler.c Wed Oct 3 12:44:11 2007
@@ -1,5 +1,6 @@
#include <switch.h>
+
struct switch_scheduler_task_container {
switch_scheduler_task_t task;
int64_t executed;
@@ -71,6 +72,7 @@
switch_mutex_lock(globals.task_mutex);
+
for (tp = globals.task_list; tp; tp = tp->next) {
if (done) {
tp->destroyed = 1;
Modified: freeswitch/trunk/src/switch_stun.c
==============================================================================
--- freeswitch/trunk/src/switch_stun.c (original)
+++ freeswitch/trunk/src/switch_stun.c Wed Oct 3 12:44:11 2007
@@ -104,7 +104,7 @@
max = (int) strlen(set);
- srand((unsigned int) switch_time_now());
+ srand((unsigned int) switch_timestamp_now());
for (x = 0; x < len; x++) {
int j = (int) (max * 1.0 * rand() / (RAND_MAX + 1.0));
1
0
03 Oct '07
Author: anthm
Date: Tue Oct 2 21:10:29 2007
New Revision: 5783
Modified:
freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c
Log:
small fix
Modified: freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c Tue Oct 2 21:10:29 2007
@@ -1595,8 +1595,8 @@
if (!switch_strlen_zero(argv[4])) {
tech_pvt->sample_rate = atoi(argv[4]);
}
-
- if (!switch_strlen_zero(argv[4])) {
+
+ if (!switch_strlen_zero(argv[5])) {
tech_pvt->codec_ms = atoi(argv[5]);
}
1
0
03 Oct '07
Author: anthm
Date: Tue Oct 2 21:03:10 2007
New Revision: 5782
Modified:
freeswitch/trunk/conf/xml_cdr.conf.xml
freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
Log:
cleanup
Modified: freeswitch/trunk/conf/xml_cdr.conf.xml
==============================================================================
--- freeswitch/trunk/conf/xml_cdr.conf.xml (original)
+++ freeswitch/trunk/conf/xml_cdr.conf.xml Tue Oct 2 21:03:10 2007
@@ -12,13 +12,13 @@
<!-- delay between retries in seconds, default is 5 seconds -->
<!-- <param name="delay" value="1"/> -->
- <!-- optional: full path to the error log dir for failed web posts if not specified its <freeswitch>/logs/xml_cdr_curl -->
- <!-- <param name="errLogDir" value="/tmp"/> -->
-
<!-- optional: if not present we do not log every record to disk -->
- <!-- per original code base /xml_cdr is appended to the directory name -->
- <!-- defined but blank value will default to freeswitchdir/log -->
- <param name="logDir" value=""/>
+ <!-- either an absolute path, a relative path assuming ${prefix}/logs or a blank value will default to ${prefix}/logs/xml_cdr -->
+ <param name="log-dir" value=""/>
+
+ <!-- optional: full path to the error log dir for failed web posts if not specified its the same as log-dir -->
+ <!-- either an absolute path, a relative path assuming ${prefix}/logs or a blank or omitted value will default to ${prefix}/logs/xml_cdr -->
+ <!-- <param name="err-log-dir" value="/tmp"/> -->
</settings>
</configuration>
Modified: freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
==============================================================================
--- freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c (original)
+++ freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c Tue Oct 2 21:03:10 2007
@@ -230,9 +230,6 @@
return SWITCH_STATUS_TERM;
}
- globals.log_dir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir);
- globals.err_log_dir = strdup(globals.log_dir);
-
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -247,21 +244,34 @@
} else if (!strcasecmp(var, "retries")) {
globals.retries = (uint32_t) atoi(val);
} else if (!strcasecmp(var, "log-dir")) {
- switch_safe_free(globals.log_dir);
- if (switch_is_file_path(val)) {
- globals.log_dir = strdup(val);
+ if (switch_strlen_zero(val)) {
+ globals.log_dir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir);
} else {
- globals.log_dir = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.log_dir, val);
+ if (switch_is_file_path(val)) {
+ globals.log_dir = strdup(val);
+ } else {
+ globals.log_dir = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.log_dir, val);
+ }
}
} else if (!strcasecmp(var, "err-log-dir")) {
- switch_safe_free(globals.err_log_dir);
- if (switch_is_file_path(val)) {
- globals.err_log_dir = strdup(val);
+ if (switch_strlen_zero(val)) {
+ globals.err_log_dir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir);
} else {
- globals.err_log_dir = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.log_dir, val);
+ if (switch_is_file_path(val)) {
+ globals.err_log_dir = strdup(val);
+ } else {
+ globals.err_log_dir = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.log_dir, val);
+ }
}
}
+ if (switch_strlen_zero(globals.err_log_dir)) {
+ if (!switch_strlen_zero(globals.log_dir)) {
+ globals.err_log_dir = strdup(globals.log_dir);
+ } else {
+ globals.err_log_dir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir);
+ }
+ }
}
}
if(globals.retries < 0) {
1
0
Author: brian
Date: Tue Oct 2 18:08:28 2007
New Revision: 5781
Modified:
freeswitch/trunk/conf/default_context.xml
Log:
Update for fifo example
Modified: freeswitch/trunk/conf/default_context.xml
==============================================================================
--- freeswitch/trunk/conf/default_context.xml (original)
+++ freeswitch/trunk/conf/default_context.xml Tue Oct 2 18:08:28 2007
@@ -150,6 +150,26 @@
</condition>
</extension>
+ <!-- Push a call into the fifo Queue (Park) -->
+ <extension name="Park Queue">
+ <condition field="destination_number" expression="400">
+ <!-- This will place the call into myqueue and play moh.wav while waiting and announce before bridge -->
+ <action application="fifo" data="in myqueue /tmp/announce.wav /tmp/moh.wav"/>
+ <!-- This is an example with MOH but no announce -->
+ <!-- <action application="fifo" data="in myqueue undef /tmp/moh.wav"/> -->
+ </condition>
+ </extension>
+
+ <!-- Pop a call out of the fifo Queue (Unpark) -->
+ <extension name="Unpark Queue">
+ <condition field="destination_number" expression="401">
+ <!-- This is "wait" mode which means the caller/agent can press * to go back and wait ending the bridge -->
+ <action application="fifo" data="out myqueue /tmp/queue-announce.wav /tmp/agent-moh.wav"/>
+ <!-- This is "nowait" which will return to the dial plan if nobody is in queue -->
+ <!-- <action application="fifo" data="out myqueue nowait"/> -->
+ </condition>
+ </extension>
+
<!-- Call *MUST* originate from mod_iax and also be dialing ext 9999-->
<extension name="9999">
<condition field="source" expression="mod_iax"/>
1
0
02 Oct '07
Author: anthm
Date: Tue Oct 2 17:53:26 2007
New Revision: 5780
Modified:
freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
Log:
update
Modified: freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c Tue Oct 2 17:53:26 2007
@@ -477,7 +477,7 @@
}
-#define FIFO_API_SYNTAX "count <fifo name>"
+#define FIFO_API_SYNTAX "list|count [<fifo name>]"
SWITCH_STANDARD_API(fifo_api_function)
{
int len = 0;
1
0
[commit] r5779 - in freeswitch/trunk/src: . include mod/applications/mod_fifo
by Freeswitch SVN 02 Oct '07
by Freeswitch SVN 02 Oct '07
02 Oct '07
Author: anthm
Date: Tue Oct 2 15:58:06 2007
New Revision: 5779
Modified:
freeswitch/trunk/src/include/switch_ivr.h
freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
freeswitch/trunk/src/switch_channel.c
freeswitch/trunk/src/switch_ivr.c
Log:
improve mod-fifo
Modified: freeswitch/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_ivr.h (original)
+++ freeswitch/trunk/src/include/switch_ivr.h Tue Oct 2 15:58:06 2007
@@ -89,6 +89,8 @@
\note on success the xml object must be freed
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_t *session, switch_xml_t * xml_cdr);
+SWITCH_DECLARE(int) switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off);
+SWITCH_DECLARE(int) switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channel_t *channel, int off);
/*!
\brief Parse command from an event
Modified: freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c Tue Oct 2 15:58:06 2007
@@ -34,6 +34,8 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load);
SWITCH_MODULE_DEFINITION(mod_fifo, mod_fifo_load, mod_fifo_shutdown, NULL);
+#define FIFO_EVENT "fifo::info"
+
static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
@@ -79,20 +81,41 @@
static struct {
switch_hash_t *fifo_hash;
+ switch_mutex_t *mutex;
switch_memory_pool_t *pool;
} globals;
+
+struct fifo_node {
+ char *name;
+ switch_mutex_t *mutex;
+ switch_queue_t *fifo;
+ switch_hash_t *caller_hash;
+ switch_hash_t *consumer_hash;
+ int caller_count;
+ int consumer_count;
+};
+
+typedef struct fifo_node fifo_node_t;
+
#define FIFO_DESC "Fifo for stacking parked calls."
#define FIFO_USAGE "<fifo name> [in [<announce file>|undef] [<music file>|undef] | out [wait|nowait] [<announce file>|undef] [<music file>|undef]]"
SWITCH_STANDARD_APP(fifo_function)
{
int argc;
char *mydata = NULL, *argv[5] = { 0 };
- switch_queue_t *fifo;
+ fifo_node_t *node;
switch_channel_t *channel;
int nowait = 0;
char *moh = NULL;
char *announce = NULL;
+ switch_event_t *event = NULL;
+ char date[80] = "";
+ switch_time_exp_t tm;
+ switch_time_t ts = switch_time_now();
+ switch_size_t retsize;
+
+
if (switch_strlen_zero(data)) {
@@ -107,11 +130,19 @@
return;
}
- if (!(fifo = switch_core_hash_find(globals.fifo_hash, argv[0]))) {
- switch_queue_create(&fifo, SWITCH_CORE_QUEUE_LEN, globals.pool);
- assert(fifo);
- switch_core_hash_insert(globals.fifo_hash, argv[0], fifo);
+ switch_mutex_lock(globals.mutex);
+ if (!(node = switch_core_hash_find(globals.fifo_hash, argv[0]))) {
+ node = switch_core_alloc(globals.pool, sizeof(*node));
+ node->name = switch_core_strdup(globals.pool, argv[0]);
+ switch_queue_create(&node->fifo, SWITCH_CORE_QUEUE_LEN, globals.pool);
+ switch_core_hash_init(&node->caller_hash, globals.pool);
+ switch_core_hash_init(&node->consumer_hash, globals.pool);
+ assert(node->fifo);
+ switch_mutex_init(&node->mutex, SWITCH_MUTEX_NESTED, globals.pool);
+ switch_core_hash_insert(globals.fifo_hash, argv[0], node);
}
+ switch_mutex_unlock(globals.mutex);
+
channel = switch_core_session_get_channel(session);
moh = switch_channel_get_variable(channel, "fifo_music");
@@ -129,7 +160,7 @@
if (argc > 2) {
announce = argv[2];
}
-
+
if (argc > 3) {
moh = argv[3];
}
@@ -143,10 +174,29 @@
}
switch_channel_set_flag(channel, CF_TAGGED);
+
+ switch_mutex_lock(node->mutex);
+ node->caller_count++;
+ switch_core_hash_insert(node->caller_hash, uuid, session);
+ switch_queue_push(node->fifo, uuid);
+ switch_mutex_unlock(node->mutex);
+
+ switch_time_exp_lt(&tm, ts);
+ switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
+ switch_channel_set_variable(channel, "fifo_status", "WAITING");
+ switch_channel_set_variable(channel, "fifo_timestamp", date);
- switch_queue_push(fifo, uuid);
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(channel, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "push");
+ switch_event_fire(&event);
+ }
+
switch_ivr_park(session, NULL);
-
+
+
+
if (switch_channel_ready(channel)) {
if (announce) {
switch_ivr_play_file(session, NULL, announce, NULL);
@@ -156,7 +206,24 @@
switch_channel_clear_flag(channel, CF_TAGGED);
if (switch_channel_ready(channel)) {
- switch_channel_set_state(channel, CS_HIBERNATE);
+ switch_channel_set_state(channel, CS_HIBERNATE);
+ } else {
+
+ switch_time_exp_lt(&tm, ts);
+ switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
+ switch_channel_set_variable(channel, "fifo_status", "ABORTED");
+ switch_channel_set_variable(channel, "fifo_timestamp", date);
+
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(channel, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "abort");
+ switch_event_fire(&event);
+ }
+ switch_mutex_lock(node->mutex);
+ node->caller_count--;
+ switch_core_hash_delete(node->caller_hash, uuid);
+ switch_mutex_unlock(node->mutex);
}
return;
@@ -179,31 +246,50 @@
check_string(announce);
check_string(moh);
-
+
if (!nowait) {
+ switch_mutex_lock(node->mutex);
+ node->consumer_count++;
+ switch_core_hash_insert(node->consumer_hash, switch_core_session_get_uuid(session), session);
+ switch_mutex_unlock(node->mutex);
switch_channel_answer(channel);
}
- for (;;) {
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(channel, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "consumer_start");
+ switch_event_fire(&event);
+ }
+
+
+ switch_time_exp_lt(&tm, ts);
+ switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
+ switch_channel_set_variable(channel, "fifo_status", "WAITING");
+ switch_channel_set_variable(channel, "fifo_timestamp", date);
+
+
+
+ while(switch_channel_ready(channel)) {
if (moh) {
args.read_frame_callback = read_frame_callback;
- args.user_data = fifo;
+ args.user_data = node->fifo;
switch_ivr_play_file(session, NULL, moh, &args);
}
- if (switch_queue_trypop(fifo, &pop) != SWITCH_STATUS_SUCCESS) {
+ if (switch_queue_trypop(node->fifo, &pop) != SWITCH_STATUS_SUCCESS) {
if (nowait) {
- return;
+ break;
}
status = switch_core_session_read_frame(session, &read_frame, -1, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
- return;
+ break;
}
continue;
}
if (!pop) {
- return;
+ break;
}
uuid = (char *) pop;
@@ -211,20 +297,40 @@
if ((other_session = switch_core_session_locate(uuid))) {
switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
switch_caller_profile_t *cloned_profile;
+
+
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(other_channel, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "caller_pop");
+ switch_event_fire(&event);
+ }
+
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(channel, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "consumer_pop");
+ switch_event_fire(&event);
+ }
+
+
if (announce) {
switch_ivr_play_file(session, NULL, announce, NULL);
} else {
switch_ivr_sleep(session, 500);
}
- switch_channel_clear_flag(other_channel, CF_CONTROLLED);
- switch_channel_clear_flag(other_channel, CF_BROADCAST);
- switch_channel_set_flag(other_channel, CF_BREAK);
- switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK);
- while (switch_channel_test_flag(other_channel, CF_TAGGED)) {
- status = switch_core_session_read_frame(session, &read_frame, -1, 0);
- if (!SWITCH_READ_ACCEPTABLE(status)) {
- break;
+
+ if (switch_channel_test_flag(other_channel, CF_TAGGED)) {
+ switch_channel_clear_flag(other_channel, CF_CONTROLLED);
+ switch_channel_clear_flag(other_channel, CF_BROADCAST);
+ switch_channel_set_flag(other_channel, CF_BREAK);
+ switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK);
+ while (switch_channel_test_flag(other_channel, CF_TAGGED)) {
+ status = switch_core_session_read_frame(session, &read_frame, -1, 0);
+ if (!SWITCH_READ_ACCEPTABLE(status)) {
+ break;
+ }
}
}
@@ -238,7 +344,29 @@
assert(cloned_profile->next == NULL);
switch_channel_set_originatee_caller_profile(channel, cloned_profile);
+ switch_time_exp_lt(&tm, ts);
+ switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
+ switch_channel_set_variable(channel, "fifo_status", "TALKING");
+ switch_channel_set_variable(channel, "fifo_target", uuid);
+ switch_channel_set_variable(channel, "fifo_timestamp", date);
+
+ switch_channel_set_variable(other_channel, "fifo_status", "TALKING");
+ switch_channel_set_variable(other_channel, "fifo_timestamp", date);
+ switch_channel_set_variable(other_channel, "fifo_target", switch_core_session_get_uuid(session));
switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
+
+ switch_time_exp_lt(&tm, ts);
+ switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
+ switch_channel_set_variable(channel, "fifo_status", "WAITING");
+ switch_channel_set_variable(channel, "fifo_timestamp", date);
+
+ switch_channel_set_variable(other_channel, "fifo_status", "DONE");
+ switch_channel_set_variable(other_channel, "fifo_timestamp", date);
+
+ switch_mutex_lock(node->mutex);
+ node->caller_count--;
+ switch_core_hash_delete(node->caller_hash, uuid);
+ switch_mutex_unlock(node->mutex);
switch_core_session_rwunlock(other_session);
if (nowait) {
done = 1;
@@ -251,23 +379,206 @@
break;
}
}
+
+
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(channel, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "consumer_stop");
+ switch_event_fire(&event);
+ }
+
+ if (!nowait) {
+ switch_mutex_lock(node->mutex);
+ switch_core_hash_delete(node->consumer_hash, switch_core_session_get_uuid(session));
+ node->consumer_count--;
+ switch_mutex_unlock(node->mutex);
+ }
+
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "USAGE %s\n", FIFO_USAGE);
}
}
+static int xml_hash(switch_xml_t xml, switch_hash_t *hash, char *container, char *tag, int cc_off, int verbose)
+{
+ switch_xml_t x_tmp, x_caller, x_cp, variables;
+ switch_hash_index_t *hi;
+ switch_core_session_t *session;
+ switch_channel_t *channel;
+ void *val;
+ const void *var;
+
+ x_tmp = switch_xml_add_child_d(xml, container, cc_off++);
+ assert(x_tmp);
+
+ for (hi = switch_hash_first(NULL, hash); hi; hi = switch_hash_next(hi)) {
+ int c_off = 0, d_off = 0;
+ char *status;
+ char *ts;
+
+ switch_hash_this(hi, &var, NULL, &val);
+ session = (switch_core_session_t *) val;
+ channel = switch_core_session_get_channel(session);
+ x_caller = switch_xml_add_child_d(x_tmp, tag, c_off++);
+ assert(x_caller);
+
+ switch_xml_set_attr_d(x_caller, "uuid", switch_core_session_get_uuid(session));
+
+ if ((status = switch_channel_get_variable(channel, "fifo_status"))) {
+ switch_xml_set_attr_d(x_caller, "status", status);
+ }
+
+ if ((ts = switch_channel_get_variable(channel, "fifo_timestamp"))) {
+ switch_xml_set_attr_d(x_caller, "timestamp", ts);
+ }
+
+ if ((ts = switch_channel_get_variable(channel, "fifo_target"))) {
+ switch_xml_set_attr_d(x_caller, "target", ts);
+ }
+
+ if (!(x_cp = switch_xml_add_child_d(x_caller, "caller_profile", d_off++))) {
+ abort();
+ }
+ if (verbose) {
+ d_off += switch_ivr_set_xml_profile_data(x_cp, switch_channel_get_caller_profile(channel), d_off);
+
+ if (!(variables = switch_xml_add_child_d(x_caller, "variables", c_off++))) {
+ abort();
+ }
+
+ switch_ivr_set_xml_chan_vars(variables, channel, c_off);
+ }
+
+ }
+
+ return cc_off;
+}
+
+static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int verbose)
+{
+
+ switch_xml_t x_fifo;
+ int cc_off = 0;
+ char tmp[35];
+
+ x_fifo = switch_xml_add_child_d(x_report, "fifo", (*off)++);;
+ assert(x_fifo);
+
+ switch_xml_set_attr_d(x_fifo, "name", node->name);
+ snprintf(tmp, sizeof(tmp), "%d", node->consumer_count);
+ switch_xml_set_attr_d(x_fifo, "consumer_count", tmp);
+ snprintf(tmp, sizeof(tmp), "%d", node->caller_count);
+ switch_xml_set_attr_d(x_fifo, "caller_count", tmp);
+
+ cc_off = xml_hash(x_fifo, node->caller_hash, "callers", "caller", cc_off, verbose);
+ cc_off = xml_hash(x_fifo, node->consumer_hash, "consumers", "consumer", cc_off, verbose);
+
+}
+
+#define FIFO_API_SYNTAX "count <fifo name>"
+SWITCH_STANDARD_API(fifo_api_function)
+{
+ int len = 0;
+ fifo_node_t *node;
+ char *data;
+ int argc = 0;
+ char *argv[5] = { 0 };
+ switch_hash_index_t *hi;
+ void *val;
+ const void *var;
+ int x = 0, verbose = 0;
+
+ if (!switch_strlen_zero(cmd)) {
+ data = strdup(cmd);
+ assert(data);
+ }
+
+ if (switch_strlen_zero(cmd) || (argc = switch_separate_string(data, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 1) {
+ stream->write_function(stream, "%s\n", FIFO_API_SYNTAX);
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ switch_mutex_lock(globals.mutex);
+ verbose = !strcasecmp(argv[0], "list_verbose");
+
+ if (!strcasecmp(argv[0], "list") || verbose) {
+ char *xml_text = NULL;
+ switch_xml_t x_report = switch_xml_new("fifo_report");
+ assert(x_report);
+
+ if (argc < 2) {
+ for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
+ switch_hash_this(hi, &var, NULL, &val);
+ node = (fifo_node_t *) val;
+ switch_mutex_lock(node->mutex);
+ list_node(node, x_report, &x, verbose);
+ switch_mutex_unlock(node->mutex);
+ }
+ } else {
+ if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
+ switch_mutex_lock(node->mutex);
+ list_node(node, x_report, &x, verbose);
+ switch_mutex_unlock(node->mutex);
+ }
+ }
+ xml_text = switch_xml_toxml(x_report);
+ assert(xml_text);
+ stream->write_function(stream, "%s\n", xml_text);
+ switch_xml_free(x_report);
+ switch_safe_free(xml_text);
+
+ } else if (!strcasecmp(argv[0], "count")) {
+ if (argc < 2) {
+ for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
+ switch_hash_this(hi, &var, NULL, &val);
+ node = (fifo_node_t *) val;
+ len = switch_queue_size(node->fifo);
+ switch_mutex_lock(node->mutex);
+ stream->write_function(stream, "%s:%d:%d:%d\n", (char *)var, node->consumer_count, node->caller_count, len);
+ switch_mutex_unlock(node->mutex);
+ x++;
+ }
+
+ if (!x) {
+ stream->write_function(stream, "none\n");
+ }
+ } else {
+ if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
+ len = switch_queue_size(node->fifo);
+ }
+ switch_mutex_lock(node->mutex);
+ stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node->caller_count, len);
+ switch_mutex_unlock(node->mutex);
+ }
+ }
+
+ switch_mutex_unlock(globals.mutex);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load)
{
switch_application_interface_t *app_interface;
+ switch_api_interface_t *commands_api_interface;
+
+
+ /* create/register custom event message type */
+ if (switch_event_reserve_subclass(FIFO_EVENT) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", FIFO_EVENT);
+ return SWITCH_STATUS_TERM;
+ }
switch_core_new_memory_pool(&globals.pool);
switch_core_hash_init(&globals.fifo_hash, globals.pool);
+ switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_APP(app_interface, "fifo", "Park with FIFO", FIFO_DESC, fifo_function, FIFO_USAGE, SAF_NONE);
-
+ SWITCH_ADD_API(commands_api_interface, "fifo", "Return data about a fifo", fifo_api_function, FIFO_API_SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
@@ -279,16 +590,19 @@
{
switch_hash_index_t *hi;
void *val, *pop;
- switch_queue_t *fifo;
-
+ fifo_node_t *node;
+ switch_mutex_lock(globals.mutex);
/* Cleanup*/
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
- fifo = (switch_queue_t *) val;
- while (switch_queue_trypop(fifo, &pop) == SWITCH_STATUS_SUCCESS) {
+ node = (fifo_node_t *) val;
+ while (switch_queue_trypop(node->fifo, &pop) == SWITCH_STATUS_SUCCESS) {
free(pop);
}
+ switch_core_hash_destroy(&node->caller_hash);
+ switch_core_hash_destroy(&node->consumer_hash);
}
+ switch_mutex_unlock(globals.mutex);
switch_core_hash_destroy(&globals.fifo_hash);
switch_core_destroy_memory_pool(&globals.pool);
return SWITCH_STATUS_SUCCESS;
Modified: freeswitch/trunk/src/switch_channel.c
==============================================================================
--- freeswitch/trunk/src/switch_channel.c (original)
+++ freeswitch/trunk/src/switch_channel.c Tue Oct 2 15:58:06 2007
@@ -404,11 +404,10 @@
if (!switch_strlen_zero(varname)) {
switch_mutex_lock(channel->profile_mutex);
+ switch_event_del_header(channel->variables, varname);
if (value) {
switch_event_add_header(channel->variables, SWITCH_STACK_BOTTOM, varname, "%s", value);
- } else {
- switch_event_del_header(channel->variables, varname);
- }
+ }
switch_mutex_unlock(channel->profile_mutex);
return SWITCH_STATUS_SUCCESS;
}
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Tue Oct 2 15:58:06 2007
@@ -1206,7 +1206,7 @@
return status;
}
-static int set_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off)
+SWITCH_DECLARE(int) switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off)
{
switch_xml_t param;
@@ -1278,14 +1278,43 @@
return off;
}
+SWITCH_DECLARE(int) switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channel_t *channel, int off)
+{
+ switch_event_header_t *hi;
+ switch_xml_t variable;
+
+ if ((hi = switch_channel_variable_first(channel))) {
+ for (; hi; hi = hi->next) {
+ char *vvar = hi->name;
+ char *vval = hi->value;
+ if (vvar && vval) {
+ if ((variable = switch_xml_add_child_d(xml, (char *) vvar, off++))) {
+ char *data;
+ char *value = (char *) vval;
+ switch_size_t dlen = strlen(value) * 3;
+
+ if ((data = malloc(dlen))) {
+ memset(data, 0, dlen);
+ switch_url_encode(value, data, dlen);
+ switch_xml_set_txt_d(variable, data);
+ free(data);
+ }
+ }
+ }
+ }
+ switch_channel_variable_last(channel);
+ }
+
+ return off;
+}
+
SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_t *session, switch_xml_t * xml_cdr)
{
switch_channel_t *channel;
switch_caller_profile_t *caller_profile;
- switch_xml_t variable, variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag,
+ switch_xml_t variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag,
x_application, x_callflow, x_inner_extension, x_apps, x_o;
switch_app_log_t *app_log;
- switch_event_header_t *hi;
char tmp[512];
int cdr_off = 0, v_off = 0;
@@ -1318,27 +1347,8 @@
}
}
-
- if ((hi = switch_channel_variable_first(channel))) {
- for (; hi; hi = hi->next) {
- char *vvar = hi->name;
- char *vval = hi->value;
- if (vvar && vval) {
- if ((variable = switch_xml_add_child_d(variables, (char *) vvar, v_off++))) {
- char *data;
- char *value = (char *) vval;
- switch_size_t dlen = strlen(value) * 3;
-
- if ((data = switch_core_session_alloc(session, dlen))) {
- switch_url_encode(value, data, dlen);
- switch_xml_set_txt_d(variable, data);
- }
- }
- }
- }
- switch_channel_variable_last(channel);
- }
-
+ switch_ivr_set_xml_chan_vars(variables, channel, v_off);
+
caller_profile = switch_channel_get_caller_profile(channel);
while (caller_profile) {
@@ -1419,7 +1429,7 @@
goto error;
}
- cp_off += set_profile_data(x_main_cp, caller_profile, 0);
+ cp_off += switch_ivr_set_xml_profile_data(x_main_cp, caller_profile, 0);
if (caller_profile->originator_caller_profile) {
switch_caller_profile_t *cp = NULL;
@@ -1432,7 +1442,7 @@
if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originator_caller_profile", off++))) {
goto error;
}
- set_profile_data(x_caller_profile, cp, 0);
+ switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0);
}
}
@@ -1446,7 +1456,7 @@
if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originatee_caller_profile", off++))) {
goto error;
}
- set_profile_data(x_caller_profile, caller_profile->originatee_caller_profile, 0);
+ switch_ivr_set_xml_profile_data(x_caller_profile, caller_profile->originatee_caller_profile, 0);
}
}
1
0
[commit] r5778 - in freeswitch/trunk/src: . mod/applications/mod_fifo mod/xml_int/mod_xml_cdr
by Freeswitch SVN 02 Oct '07
by Freeswitch SVN 02 Oct '07
02 Oct '07
Author: anthm
Date: Tue Oct 2 12:38:15 2007
New Revision: 5778
Modified:
freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
freeswitch/trunk/src/switch_channel.c
freeswitch/trunk/src/switch_ivr.c
freeswitch/trunk/src/switch_xml.c
Log:
refactor xml cdr and some cleanup
Modified: freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c Tue Oct 2 12:38:15 2007
@@ -229,12 +229,13 @@
}
switch_channel_answer(channel);
- cloned_profile = switch_caller_profile_clone(session, switch_channel_get_caller_profile(channel));
+ cloned_profile = switch_caller_profile_clone(other_session, switch_channel_get_caller_profile(channel));
assert(cloned_profile);
switch_channel_set_originator_caller_profile(other_channel, cloned_profile);
- cloned_profile = switch_caller_profile_clone(other_session, switch_channel_get_caller_profile(channel));
+ cloned_profile = switch_caller_profile_clone(session, switch_channel_get_caller_profile(other_channel));
assert(cloned_profile);
+ assert(cloned_profile->next == NULL);
switch_channel_set_originatee_caller_profile(channel, cloned_profile);
switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
Modified: freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
==============================================================================
--- freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c (original)
+++ freeswitch/trunk/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c Tue Oct 2 12:38:15 2007
@@ -36,8 +36,8 @@
static struct {
char *cred;
char *url;
- char *logDir;
- char *errLogDir;
+ char *log_dir;
+ char *err_log_dir;
uint32_t delay;
uint32_t retries;
uint32_t shutdown;
@@ -75,7 +75,7 @@
if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
/* build the XML */
- if(!(xml_text = switch_mprintf("<?xml version=\"1.0\"?>\n%s",switch_xml_toxml(cdr)) )) {
+ if(!(xml_text = switch_xml_toxml(cdr))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
goto error;
}
@@ -84,11 +84,11 @@
/* all previous functionality is retained */
if (!(logdir = switch_channel_get_variable(channel, "xml_cdr_base"))) {
- logdir = globals.logDir;
+ logdir = globals.log_dir;
}
if(!switch_strlen_zero(logdir)) {
- if ((path = switch_mprintf("%s/xml_cdr/%s.cdr.xml", logdir, switch_core_session_get_uuid(session)))) {
+ if ((path = switch_mprintf("%s/%s.cdr.xml", logdir, switch_core_session_get_uuid(session)))) {
if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
int wrote;
wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
@@ -101,7 +101,7 @@
#else
strerror_r(errno, ebuf, sizeof(ebuf));
#endif
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n", path, ebuf);
}
switch_safe_free(path);
}
@@ -163,7 +163,7 @@
/* if we are here the web post failed for some reason */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n");
- if ((path = switch_mprintf("%s/%s.cdr.xml", globals.errLogDir, switch_core_session_get_uuid(session)))) {
+ if ((path = switch_mprintf("%s/%s.cdr.xml", globals.err_log_dir, switch_core_session_get_uuid(session)))) {
if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
int wrote;
wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
@@ -229,6 +229,9 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
return SWITCH_STATUS_TERM;
}
+
+ globals.log_dir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir);
+ globals.err_log_dir = strdup(globals.log_dir);
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
@@ -243,14 +246,20 @@
globals.delay = (uint32_t) atoi(val);
} else if (!strcasecmp(var, "retries")) {
globals.retries = (uint32_t) atoi(val);
- } else if (!strcasecmp(var, "logDir")) {
- if (switch_strlen_zero(val)) {
- globals.logDir = SWITCH_GLOBAL_dirs.log_dir;
+ } else if (!strcasecmp(var, "log-dir")) {
+ switch_safe_free(globals.log_dir);
+ if (switch_is_file_path(val)) {
+ globals.log_dir = strdup(val);
+ } else {
+ globals.log_dir = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.log_dir, val);
+ }
+ } else if (!strcasecmp(var, "err-log-dir")) {
+ switch_safe_free(globals.err_log_dir);
+ if (switch_is_file_path(val)) {
+ globals.err_log_dir = strdup(val);
} else {
- globals.logDir = strdup(val);
+ globals.err_log_dir = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.log_dir, val);
}
- } else if (!strcasecmp(var, "errLogDir")) {
- globals.errLogDir = strdup(val);
}
}
@@ -265,17 +274,7 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "retries set but delay 0 setting to 5000ms\n");
globals.delay = 5000;
}
-
- if(!switch_strlen_zero(globals.url) && switch_strlen_zero(globals.errLogDir)) {
- if ((globals.errLogDir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- status = SWITCH_STATUS_FALSE;
- goto done;
- }
- }
-
-
- done:
+
switch_xml_free(xml);
return status;
}
Modified: freeswitch/trunk/src/switch_channel.c
==============================================================================
--- freeswitch/trunk/src/switch_channel.c (original)
+++ freeswitch/trunk/src/switch_channel.c Tue Oct 2 12:38:15 2007
@@ -886,6 +886,7 @@
caller_profile->next = channel->caller_profile->originator_caller_profile;
channel->caller_profile->originator_caller_profile = caller_profile;
}
+ assert(channel->caller_profile->originator_caller_profile->next != channel->caller_profile->originator_caller_profile);
switch_mutex_unlock(channel->profile_mutex);
}
@@ -898,6 +899,7 @@
caller_profile->next = channel->caller_profile->originatee_caller_profile;
channel->caller_profile->originatee_caller_profile = caller_profile;
}
+ assert(channel->caller_profile->originatee_caller_profile->next != channel->caller_profile->originatee_caller_profile);
switch_mutex_unlock(channel->profile_mutex);
}
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Tue Oct 2 12:38:15 2007
@@ -1275,15 +1275,15 @@
}
switch_xml_set_txt(param, caller_profile->chan_name);
- return 0;
+ return off;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_t *session, switch_xml_t * xml_cdr)
{
switch_channel_t *channel;
switch_caller_profile_t *caller_profile;
- switch_xml_t variable, variables, cdr, x_caller_profile, x_caller_extension, x_times, time_tag,
- x_application, x_callflow, x_inner_extension, x_apps;
+ switch_xml_t variable, variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag,
+ x_application, x_callflow, x_inner_extension, x_apps, x_o;
switch_app_log_t *app_log;
switch_event_header_t *hi;
char tmp[512];
@@ -1343,6 +1343,7 @@
while (caller_profile) {
int cf_off = 0;
+ int cp_off = 0;
if (!(x_callflow = switch_xml_add_child_d(cdr, "callflow", cdr_off++))) {
goto error;
@@ -1356,6 +1357,7 @@
if (!(x_caller_extension = switch_xml_add_child_d(x_callflow, "extension", cf_off++))) {
goto error;
}
+
switch_xml_set_attr_d(x_caller_extension, "name", caller_profile->caller_extension->extension_name);
switch_xml_set_attr_d(x_caller_extension, "number", caller_profile->caller_extension->extension_number);
if (caller_profile->caller_extension->current_application) {
@@ -1413,23 +1415,39 @@
}
- if (!(x_caller_profile = switch_xml_add_child_d(x_callflow, "caller_profile", cf_off++))) {
+ if (!(x_main_cp = switch_xml_add_child_d(x_callflow, "caller_profile", cf_off++))) {
goto error;
}
- set_profile_data(x_caller_profile, caller_profile, 0);
+
+ cp_off += set_profile_data(x_main_cp, caller_profile, 0);
if (caller_profile->originator_caller_profile) {
- if (!(x_caller_profile = switch_xml_add_child_d(x_callflow, "originator_caller_profile", cf_off++))) {
+ switch_caller_profile_t *cp = NULL;
+ int off = 0;
+ if (!(x_o = switch_xml_add_child_d(x_main_cp, "originator", cp_off++))) {
goto error;
}
- set_profile_data(x_caller_profile, caller_profile->originator_caller_profile, 0);
+
+ for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) {
+ if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originator_caller_profile", off++))) {
+ goto error;
+ }
+ set_profile_data(x_caller_profile, cp, 0);
+ }
}
if (caller_profile->originatee_caller_profile) {
- if (!(x_caller_profile = switch_xml_add_child_d(x_callflow, "originatee_caller_profile", cf_off++))) {
+ switch_caller_profile_t *cp = NULL;
+ int off = 0;
+ if (!(x_o = switch_xml_add_child_d(x_main_cp, "originatee", cp_off++))) {
goto error;
}
- set_profile_data(x_caller_profile, caller_profile->originatee_caller_profile, 0);
+ for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) {
+ if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originatee_caller_profile", off++))) {
+ goto error;
+ }
+ set_profile_data(x_caller_profile, caller_profile->originatee_caller_profile, 0);
+ }
}
Modified: freeswitch/trunk/src/switch_xml.c
==============================================================================
--- freeswitch/trunk/src/switch_xml.c (original)
+++ freeswitch/trunk/src/switch_xml.c Tue Oct 2 12:38:15 2007
@@ -1523,8 +1523,9 @@
s = malloc(max);
assert(s != NULL);
memset(s, 0, max);
-
+ len = sprintf(s, "<?xml version=\"1.0\"?>\n");
+
if (!xml || !xml->name) {
if (!(r = realloc(s, len + 1))) {
abort();
1
0
Author: anthm
Date: Mon Oct 1 20:09:49 2007
New Revision: 5777
Modified:
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/switch_ivr_bridge.c
freeswitch/trunk/src/switch_ivr_play_say.c
Log:
add read_frame_callback to input args in the core
Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h (original)
+++ freeswitch/trunk/src/include/switch_types.h Mon Oct 1 20:09:49 2007
@@ -1082,11 +1082,14 @@
typedef switch_status_t (*switch_input_callback_function_t) (switch_core_session_t *session, void *input,
switch_input_type_t input_type, void *buf, unsigned int buflen);
+typedef switch_status_t (*switch_read_frame_callback_function_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
typedef struct switch_say_interface switch_say_interface_t;
typedef struct {
switch_input_callback_function_t input_callback;
void *buf;
uint32_t buflen;
+ switch_read_frame_callback_function_t read_frame_callback;
+ void *user_data;
} switch_input_args_t;
typedef switch_status_t (*switch_say_callback_t) (switch_core_session_t *session,
char *tosay, switch_say_type_t type, switch_say_method_t method, switch_input_args_t *args);
Modified: freeswitch/trunk/src/switch_ivr_bridge.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_bridge.c (original)
+++ freeswitch/trunk/src/switch_ivr_bridge.c Mon Oct 1 20:09:49 2007
@@ -119,13 +119,14 @@
if (switch_channel_has_dtmf(chan_a)) {
char dtmf[128];
switch_channel_dequeue_dtmf(chan_a, dtmf, sizeof(dtmf));
- switch_core_session_send_dtmf(session_b, dtmf);
if (input_callback) {
if (input_callback(session_a, dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
+ switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
break;
}
}
+ switch_core_session_send_dtmf(session_b, dtmf);
}
if (switch_core_session_dequeue_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
@@ -219,7 +220,6 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a));
switch_channel_clear_flag(chan_a, CF_BRIDGED);
switch_core_session_rwunlock(session_b);
-
return NULL;
}
@@ -245,7 +245,7 @@
if (!switch_channel_test_flag(channel, CF_TRANSFER)) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- }
+ }
return SWITCH_STATUS_FALSE;
}
Modified: freeswitch/trunk/src/switch_ivr_play_say.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_play_say.c (original)
+++ freeswitch/trunk/src/switch_ivr_play_say.c Mon Oct 1 20:09:49 2007
@@ -449,6 +449,12 @@
break;
}
+ if (args && (args->read_frame_callback)) {
+ if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
+
if (fh->thresh) {
int16_t *fdata = (int16_t *) read_frame->data;
uint32_t samples = read_frame->datalen / sizeof(*fdata);
@@ -564,6 +570,12 @@
continue;
}
+ if (args && (args->read_frame_callback)) {
+ if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
+
if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(audio_buffer, write_frame.data,
read_frame->codec->implementation->bytes_per_frame)) <= 0) {
break;
@@ -997,6 +1009,12 @@
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
}
+
+ if (args && (args->read_frame_callback)) {
+ if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
}
}
@@ -1266,6 +1284,12 @@
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
}
+
+ if (args && (args->read_frame_callback)) {
+ if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
}
continue;
}
@@ -1323,6 +1347,12 @@
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
}
+
+ if (args && (args->read_frame_callback)) {
+ if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
}
}
1
0
02 Oct '07
Author: anthm
Date: Mon Oct 1 20:03:53 2007
New Revision: 5776
Modified:
freeswitch/trunk/src/mod/applications/mod_fifo/Makefile
freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
Log:
add a few things to mod_fifo
Modified: freeswitch/trunk/src/mod/applications/mod_fifo/Makefile
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_fifo/Makefile (original)
+++ freeswitch/trunk/src/mod/applications/mod_fifo/Makefile Mon Oct 1 20:03:53 2007
@@ -1,2 +1,2 @@
BASE=../../../..
-include /usr/src/freeswitch.trunk/build/modmake.rules
+include $(BASE)/build/modmake.rules
Modified: freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_fifo/mod_fifo.c Mon Oct 1 20:03:53 2007
@@ -24,8 +24,6 @@
* Contributor(s):
*
* Anthony Minessale II <anthmct(a)yahoo.com>
- * Neal Horman <neal at wanlink dot com>
- *
*
* mod_fifo.c -- FIFO
*
@@ -36,20 +34,66 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load);
SWITCH_MODULE_DEFINITION(mod_fifo, mod_fifo_load, mod_fifo_shutdown, NULL);
+
+
+static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
+{
+ switch_core_session_t *bleg;
+ switch_channel_t *channel;
+
+ bleg = (switch_core_session_t *) buf;
+
+ switch (itype) {
+ case SWITCH_INPUT_TYPE_DTMF:
+ {
+ char *dtmf = (char *) input;
+ if (*dtmf == '*') {
+ channel = switch_core_session_get_channel(session);
+ if (switch_channel_test_flag(channel, CF_ORIGINATOR)) {
+ channel = switch_core_session_get_channel(bleg);
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ return SWITCH_STATUS_BREAK;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+#define check_string(s) if (!switch_strlen_zero(s) && !strcasecmp(s, "undef")) { s = NULL; }
+
+
+static switch_status_t read_frame_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data)
+{
+ switch_queue_t *fifo = (switch_queue_t *) user_data;
+ if (switch_queue_size(fifo)) {
+ return SWITCH_STATUS_FALSE;
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
static struct {
switch_hash_t *fifo_hash;
switch_memory_pool_t *pool;
} globals;
#define FIFO_DESC "Fifo for stacking parked calls."
-#define FIFO_USAGE "<fifo name> [in <file> | out [nowait]]"
+#define FIFO_USAGE "<fifo name> [in [<announce file>|undef] [<music file>|undef] | out [wait|nowait] [<announce file>|undef] [<music file>|undef]]"
SWITCH_STANDARD_APP(fifo_function)
{
int argc;
- char *mydata = NULL, *argv[4] = { 0 };
+ char *mydata = NULL, *argv[5] = { 0 };
switch_queue_t *fifo;
switch_channel_t *channel;
int nowait = 0;
+ char *moh = NULL;
+ char *announce = NULL;
+
if (switch_strlen_zero(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Args\n");
@@ -70,7 +114,8 @@
}
channel = switch_core_session_get_channel(session);
-
+ moh = switch_channel_get_variable(channel, "fifo_music");
+ announce = switch_channel_get_variable(channel, "fifo_announce");
if (argc > 2) {
nowait = !strcasecmp(argv[2], "nowait");
@@ -78,22 +123,42 @@
if (!strcasecmp(argv[1], "in")) {
char *uuid = strdup(switch_core_session_get_uuid(session));
- char *moh = NULL;
switch_channel_answer(channel);
- moh = switch_channel_get_variable(channel, "fifo_music");
-
if (argc > 2) {
- moh = argv[2];
+ announce = argv[2];
+ }
+
+ if (argc > 3) {
+ moh = argv[3];
}
+ check_string(announce);
+ check_string(moh);
+
+
if (moh) {
switch_ivr_broadcast(uuid, moh, SMF_LOOP | SMF_ECHO_ALEG);
}
-
+
+ switch_channel_set_flag(channel, CF_TAGGED);
+
switch_queue_push(fifo, uuid);
switch_ivr_park(session, NULL);
+
+ if (switch_channel_ready(channel)) {
+ if (announce) {
+ switch_ivr_play_file(session, NULL, announce, NULL);
+ }
+ }
+
+ switch_channel_clear_flag(channel, CF_TAGGED);
+
+ if (switch_channel_ready(channel)) {
+ switch_channel_set_state(channel, CS_HIBERNATE);
+ }
+
return;
} else if (!strcasecmp(argv[1], "out")) {
void *pop;
@@ -102,12 +167,31 @@
char *uuid;
int done = 0;
switch_core_session_t *other_session;
+ switch_input_args_t args = { 0 };
+ if (argc > 3) {
+ announce = argv[3];
+ }
+
+ if (argc > 4) {
+ moh = argv[4];
+ }
+
+ check_string(announce);
+ check_string(moh);
+
if (!nowait) {
switch_channel_answer(channel);
}
+
for (;;) {
+ if (moh) {
+ args.read_frame_callback = read_frame_callback;
+ args.user_data = fifo;
+ switch_ivr_play_file(session, NULL, moh, &args);
+ }
+
if (switch_queue_trypop(fifo, &pop) != SWITCH_STATUS_SUCCESS) {
if (nowait) {
return;
@@ -126,13 +210,38 @@
if ((other_session = switch_core_session_locate(uuid))) {
switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
+ switch_caller_profile_t *cloned_profile;
+
+ if (announce) {
+ switch_ivr_play_file(session, NULL, announce, NULL);
+ } else {
+ switch_ivr_sleep(session, 500);
+ }
switch_channel_clear_flag(other_channel, CF_CONTROLLED);
switch_channel_clear_flag(other_channel, CF_BROADCAST);
switch_channel_set_flag(other_channel, CF_BREAK);
switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK);
- switch_ivr_multi_threaded_bridge(session, other_session, NULL, NULL, NULL);
+ while (switch_channel_test_flag(other_channel, CF_TAGGED)) {
+ status = switch_core_session_read_frame(session, &read_frame, -1, 0);
+ if (!SWITCH_READ_ACCEPTABLE(status)) {
+ break;
+ }
+ }
+
+ switch_channel_answer(channel);
+ cloned_profile = switch_caller_profile_clone(session, switch_channel_get_caller_profile(channel));
+ assert(cloned_profile);
+ switch_channel_set_originator_caller_profile(other_channel, cloned_profile);
+
+ cloned_profile = switch_caller_profile_clone(other_session, switch_channel_get_caller_profile(channel));
+ assert(cloned_profile);
+ switch_channel_set_originatee_caller_profile(channel, cloned_profile);
+
+ switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
switch_core_session_rwunlock(other_session);
- done = 1;
+ if (nowait) {
+ done = 1;
+ }
}
switch_safe_free(uuid);
1
0
Author: anthm
Date: Mon Oct 1 17:02:09 2007
New Revision: 5775
Modified:
freeswitch/trunk/build/modules.conf.in
Log:
doh
Modified: freeswitch/trunk/build/modules.conf.in
==============================================================================
--- freeswitch/trunk/build/modules.conf.in (original)
+++ freeswitch/trunk/build/modules.conf.in Mon Oct 1 17:02:09 2007
@@ -4,7 +4,7 @@
applications/mod_conference
applications/mod_dptools
applications/mod_enum
-applications/mode_fifo
+applications/mod_fifo
#applications/mod_ivrtest
#applications/mod_soundtouch
#applications/mod_rss
1
0