Merge branch 'master' of git@git.freeswitch.org:freeswitch

This commit is contained in:
Joao Mesquita 2010-04-05 22:03:58 -03:00
commit 195d34bcec
21 changed files with 1773 additions and 1194 deletions

80
.gitignore vendored
View File

@ -8,10 +8,10 @@
.deps
.\#*
\#*
Debug/
Release/
All/
bin/
/Debug/
/Release/
/All/
/bin/
*.user
*.suo
*.ncb
@ -26,43 +26,47 @@ bin/
*.manifest
*.dep
*.dll
BuildLog.htm
Path
w32/Library/lastversion
w32/Library/tmpVersion.Bat
.version
AUTHORS
COPYING
ChangeLog
Makefile
Makefile.in
NEWS
README
/BuildLog.htm
/Path
/w32/Library/lastversion
/w32/Library/tmpVersion.Bat
!/w32/Console/FreeSwitchConsole.vcproj.user
!/w32/Setup/inno_setup/vcredist_x64.exe
!/w32/Setup/inno_setup/vcredist_x86.exe
/.version
/AUTHORS
/COPYING
/ChangeLog
/Makefile
/Makefile.in
/NEWS
/README
aclocal.m4
autom4te.cache
build/Makefile
build/Makefile.in
build/config/compile
build/config/config.guess
build/config/depcomp
build/config/install-sh
build/config/ltmain.sh
build/config/missing
build/freeswitch.pc
build/getlib.sh
build/getsounds.sh
build/modmake.rules
/build/Makefile
/build/Makefile.in
/build/config/compile
/build/config/config.guess
/build/config/depcomp
/build/config/install-sh
/build/config/ltmain.sh
/build/config/missing
/build/freeswitch.pc
/build/getlib.sh
/build/getsounds.sh
/build/modmake.rules
config.cache
config.log
config.status
configure
/configure
configure.lineno
freeswitch
fs_cli
fs_ivrd
libtool
modules.conf
quiet_libtool
scripts/fsxs
scripts/gentls_cert
a.out.dSYM
/freeswitch
/fs_cli
/fs_ivrd
/libtool
/modules.conf
/quiet_libtool
/scripts/fsxs
/scripts/gentls_cert
/a.out.dSYM
/freeswitch-sounds-*

2139
libs/.gitignore vendored

File diff suppressed because it is too large Load Diff

View File

@ -72,7 +72,8 @@ $(SRC)/libteletone_detect.c \
$(SRC)/libteletone_generate.c \
$(SRC)/ftdm_buffer.c \
$(SRC)/ftdm_threadmutex.c \
$(SRC)/ftdm_dso.c
$(SRC)/ftdm_dso.c \
$(SRC)/ftdm_cpu_monitor.c
library_include_HEADERS = \
$(SRC)/include/fsk.h \
@ -90,7 +91,8 @@ $(SRC)/include/ftdm_buffer.h \
$(SRC)/include/ftdm_config.h \
$(SRC)/include/ftdm_threadmutex.h \
$(SRC)/include/ftdm_dso.h \
$(SRC)/include/ftdm_types.h
$(SRC)/include/ftdm_types.h \
$(SRC)/include/ftdm_cpu_monitor.h
lib_LTLIBRARIES = libfreetdm.la
libfreetdm_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)

View File

@ -2767,6 +2767,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
"type: %s\n"
"state: %s\n"
"last_state: %s\n"
"txgain: %3.2f\n"
"rxgain: %3.2f\n"
"cid_date: %s\n"
"cid_name: %s\n"
"cid_num: %s\n"
@ -2782,6 +2784,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre
ftdm_chan_type2str(span->channels[chan_id]->type),
ftdm_channel_state2str(span->channels[chan_id]->state),
ftdm_channel_state2str(span->channels[chan_id]->last_state),
span->channels[chan_id]->txgain,
span->channels[chan_id]->rxgain,
span->channels[chan_id]->caller_data.cid_date,
span->channels[chan_id]->caller_data.cid_name,
span->channels[chan_id]->caller_data.cid_num.digits,
@ -2808,6 +2812,8 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *
" <type>%s</type>\n"
" <state>%s</state>\n"
" <last-state>%s</last-state>\n"
" <txgain>%3.2f</txgain>\n"
" <rxgain>%3.2f</rxgain>\n"
" <cid-date>%s</cid-date>\n"
" <cid-name>%s</cid-name>\n"
" <cid-num>%s</cid-num>\n"
@ -2824,6 +2830,8 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *
ftdm_chan_type2str(span->channels[chan_id]->type),
ftdm_channel_state2str(span->channels[chan_id]->state),
ftdm_channel_state2str(span->channels[chan_id]->last_state),
span->channels[chan_id]->txgain,
span->channels[chan_id]->rxgain,
span->channels[chan_id]->caller_data.cid_date,
span->channels[chan_id]->caller_data.cid_name,
span->channels[chan_id]->caller_data.cid_num.digits,
@ -3142,6 +3150,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)
module_pool = pool;
ftdm_global_set_logger(ftdm_logger);
ftdm_cpu_monitor_disable();
if (ftdm_global_init() != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n");

View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2010, Sangoma Technologies
* Moises Silva <moy@sangoma.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* David Yat Sin <dyatsin@sangoma.com>
*
*/
#ifdef WIN32
#define _WIN32_WINNT 0x0501 // To make GetSystemTimes visible in windows.h
#include <windows.h>
#else /* LINUX */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#endif
#include "freetdm.h"
#include "ftdm_cpu_monitor.h"
struct ftdm_cpu_monitor_stats
{
/* bool, just used to retrieve the values for the first time and not calculate the percentage of idle time */
int valid_last_times;
/* last calculated percentage of idle time */
double last_percentage_of_idle_time;
#ifdef __linux__
/* all of these are the Linux jiffies last retrieved count */
unsigned long long last_user_time;
unsigned long long last_system_time;
unsigned long long last_idle_time;
unsigned long long last_nice_time;
unsigned long long last_irq_time;
unsigned long long last_soft_irq_time;
unsigned long long last_io_wait_time;
unsigned long long last_steal_time;
/* /proc/stat file descriptor used to retrieve the counters */
int procfd;
int initd;
#elif defined (WIN32) || defined (WIN64)
__int64 i64LastUserTime;
__int64 i64LastKernelTime;
__int64 i64LastIdleTime;
#else
/* Unsupported */
#endif
};
#ifdef __linux__
static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
unsigned long long *user,
unsigned long long *nice,
unsigned long long *system,
unsigned long long *idle,
unsigned long long *iowait,
unsigned long long *irq,
unsigned long long *softirq,
unsigned long long *steal)
{
// the output of proc should not change that often from one kernel to other
// see fs/proc/proc_misc.c or fs/proc/stat.c in the Linux kernel for more details
// also man 5 proc is useful
#define CPU_ELEMENTS 8 // change this if you change the format string
#define CPU_INFO_FORMAT "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu"
static const char procfile[] = "/proc/stat";
int rc = 0;
int myerrno = 0;
int elements = 0;
const char *cpustr = NULL;
char statbuff[1024];
if (!p->initd) {
p->procfd = open(procfile, O_RDONLY, 0);
if(p->procfd == -1) {
ftdm_log(FTDM_LOG_ERROR, "Failed to open CPU statistics file %s: %s\n", procfile, strerror(myerrno));
return FTDM_FAIL;
}
p->initd = 1;
} else {
lseek(p->procfd, 0L, SEEK_SET);
}
rc = read(p->procfd, statbuff, sizeof(statbuff) - 1);
if (rc <= 0) {
myerrno = errno;
ftdm_log(FTDM_LOG_ERROR, "Failed to read CPU statistics file %s: %s\n", procfile, strerror(myerrno));
return FTDM_FAIL;
}
cpustr = strstr(statbuff, "cpu ");
if (!cpustr) {
ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: missing cpu string\n");
return FTDM_FAIL;
}
elements = sscanf(cpustr, CPU_INFO_FORMAT, user, nice, system, idle, iowait, irq, softirq, steal);
if (elements != CPU_ELEMENTS) {
ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: expected %d elements, but just found %d\n", CPU_ELEMENTS, elements);
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
#endif
#ifdef __linux__
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
{
unsigned long long user, nice, system, idle, iowait, irq, softirq, steal;
unsigned long long usertime, kerneltime, idletime, totaltime, halftime;
if (ftdm_cpu_read_stats(p, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal)) {
ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics\n");
return FTDM_FAIL;
}
if (!p->valid_last_times) {
// we dont strictly need to save all of them but I feel code is more clear if we do
p->valid_last_times = 1;
p->last_user_time = user;
p->last_nice_time = nice;
p->last_system_time = system;
p->last_irq_time = irq;
p->last_soft_irq_time = softirq;
p->last_io_wait_time = iowait;
p->last_steal_time = steal;
p->last_idle_time = idle;
p->last_percentage_of_idle_time = 100.0;
*idle_percentage = p->last_percentage_of_idle_time;
return FTDM_SUCCESS;
}
usertime = (user - p->last_user_time) + (nice - p->last_nice_time);
kerneltime = (system - p->last_system_time) + (irq - p->last_irq_time) + (softirq - p->last_soft_irq_time);
kerneltime += (iowait - p->last_io_wait_time);
kerneltime += (steal - p->last_steal_time);
idletime = (idle - p->last_idle_time);
totaltime = usertime + kerneltime + idletime;
if (totaltime <= 0) {
// this may happen if not enough time has elapsed and the jiffies counters are the same than the last time we checked
// jiffies depend on timer interrupts which depend on the number of HZ compile time setting of the kernel
// typical configs set HZ to 100 (that means, 100 jiffies updates per second, that is one each 10ms)
// avoid an arithmetic exception and return the same values
*idle_percentage = p->last_percentage_of_idle_time;
return FTDM_SUCCESS;
}
halftime = totaltime / 2UL;
p->last_percentage_of_idle_time = ((100 * idletime + halftime) / totaltime);
*idle_percentage = p->last_percentage_of_idle_time;
p->last_user_time = user;
p->last_nice_time = nice;
p->last_system_time = system;
p->last_irq_time = irq;
p->last_soft_irq_time = softirq;
p->last_io_wait_time = iowait;
p->last_steal_time = steal;
p->last_idle_time = idle;
return FTDM_SUCCESS;
}
#elif defined (WIN32) || defined (WIN64)
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
{
FILETIME idleTime;
FILETIME kernelTime;
FILETIME userTime;
if (!::GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
return false;
}
__int64 i64UserTime = (__int64)userTime.dwLowDateTime | ((__int64)userTime.dwHighDateTime << 32);
__int64 i64KernelTime = (__int64)kernelTime.dwLowDateTime | ((__int64)kernelTime.dwHighDateTime << 32);
__int64 i64IdleTime = (__int64)idleTime.dwLowDateTime | ((__int64)idleTime.dwHighDateTime << 32);
if (p->valid_last_times) {
__int64 i64User = i64UserTime - p->i64LastUserTime;
__int64 i64Kernel = i64KernelTime - p->i64LastKernelTime;
__int64 i64Idle = i64IdleTime - p->i64LastIdleTime;
__int64 i64System = i64User + i64Kernel;
*idle_percentage = 100.0 * i64Idle / i64System;
} else {
*idle_percentage = 100.0;
p->valid_last_times = 1;
}
/* Remember current value for the next call */
p->i64LastUserTime = i64UserTime;
p->i64LastKernelTime = i64KernelTime;
p->i64LastIdleTime = i64IdleTime;
/* Success */
return FTDM_SUCCESS;
}
#else
/* Unsupported */
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
{
return FTDM_FAIL;
}
#endif
FT_DECLARE(struct ftdm_cpu_monitor_stats*) ftdm_new_cpu_monitor(void)
{
return calloc(1, sizeof(struct ftdm_cpu_monitor_stats));
}
FT_DECLARE(void) ftdm_delete_cpu_monitor(struct ftdm_cpu_monitor_stats *p)
{
#ifdef __linux__
close(p->procfd);
#endif
free(p);
}
/* 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:
*/

View File

@ -48,6 +48,7 @@
#ifdef FTDM_PIKA_SUPPORT
#include "ftdm_pika.h"
#endif
#include "ftdm_cpu_monitor.h"
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
@ -80,6 +81,16 @@ FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void)
#endif
}
typedef struct {
uint8_t running;
uint8_t alarm;
uint32_t interval;
uint8_t alarm_action_flags;
uint8_t set_alarm_threshold;
uint8_t reset_alarm_threshold;
ftdm_interrupt_t *interrupt;
} cpu_monitor_t;
static struct {
ftdm_hash_t *interface_hash;
ftdm_hash_t *module_hash;
@ -93,8 +104,16 @@ static struct {
uint32_t running;
ftdm_span_t *spans;
ftdm_group_t *groups;
cpu_monitor_t cpu_monitor;
} globals;
static uint8_t ftdm_cpu_monitor_disabled = 0;
enum ftdm_enum_cpu_alarm_action_flags
{
FTDM_CPU_ALARM_ACTION_WARN = (1 << 0),
FTDM_CPU_ALARM_ACTION_REJECT = (1 << 1)
};
/* enum lookup funcs */
FTDM_ENUM_NAMES(TONEMAP_NAMES, TONEMAP_STRINGS)
@ -412,7 +431,9 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
}
/* destroy final basic resources of the span data structure */
ftdm_queue_destroy(&span->pendingchans);
if (span->pendingchans) {
ftdm_queue_destroy(&span->pendingchans);
}
ftdm_mutex_unlock(span->mutex);
ftdm_mutex_destroy(&span->mutex);
ftdm_safe_free(span->signal_data);
@ -518,9 +539,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_create(ftdm_io_interface_t *fio, ftdm_span_t
status = ftdm_mutex_create(&new_span->mutex);
ftdm_assert(status == FTDM_SUCCESS, "mutex creation failed\n");
status = ftdm_queue_create(&new_span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
ftdm_assert(status == FTDM_SUCCESS, "span chans queue creation failed\n");
ftdm_set_flag(new_span, FTDM_SPAN_CONFIGURED);
new_span->span_id = ++globals.span_index;
new_span->fio = fio;
@ -1163,7 +1181,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(ftdm_channel_t *ftdmchan, ftdm_
ftdm_mutex_lock(ftdmchan->span->mutex);
ftdm_set_flag(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
ftdm_queue_enqueue(ftdmchan->span->pendingchans, ftdmchan);
if (ftdmchan->span->pendingchans) {
ftdm_queue_enqueue(ftdmchan->span->pendingchans, ftdmchan);
}
ftdm_mutex_unlock(ftdmchan->span->mutex);
ftdmchan->last_state = ftdmchan->state;
@ -1329,7 +1349,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
return FTDM_FAIL;
}
if (span->channel_request && !span->suggest_chan_id) {
if (span->channel_request && !ftdm_test_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID)) {
ftdm_set_caller_data(span, caller_data);
return span->channel_request(span, 0, direction, caller_data, ftdmchan);
}
@ -1469,6 +1489,14 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n");
return FTDM_FAIL;
}
if (globals.cpu_monitor.alarm &&
globals.cpu_monitor.alarm_action_flags & FTDM_CPU_ALARM_ACTION_REJECT) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "CPU usage alarm is on - refusing to open channel\n");
ftdm_log(FTDM_LOG_WARNING, "CPU usage alarm is on - refusing to open channel\n");
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_SWITCH_CONGESTION;
return FTDM_FAIL;
}
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY) || (status = ftdm_mutex_trylock(ftdmchan->mutex)) != FTDM_SUCCESS) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "Channel is not ready or is in use %d %d", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY), status);
@ -2006,7 +2034,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
}
break;
/* FIXME: validate user gain values */
case FTDM_COMMAND_SET_RX_GAIN:
{
ftdmchan->rxgain = FTDM_COMMAND_OBJ_FLOAT;
@ -2798,6 +2825,24 @@ FT_DECLARE(char *) ftdm_api_execute(const char *type, const char *cmd)
return rval;
}
static void ftdm_set_channels_gains(ftdm_span_t *span, int currindex, float rxgain, float txgain)
{
unsigned chan_index = 0;
if (!span->chan_count) {
return;
}
for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) {
if (!FTDM_IS_VOICE_CHANNEL(span->channels[chan_index])) {
continue;
}
ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_RX_GAIN, &rxgain);
ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_TX_GAIN, &txgain);
}
}
static ftdm_status_t ftdm_group_add_channels(const char* name, ftdm_span_t* span, int currindex);
static ftdm_status_t load_config(void)
@ -2814,6 +2859,8 @@ static ftdm_status_t load_config(void)
char group_name[80] = "default";
ftdm_io_interface_t *fio = NULL;
ftdm_analog_start_type_t tmp;
float rxgain = 0.0;
float txgain = 0.0;
ftdm_size_t len = 0;
if (!ftdm_config_open_file(&cfg, cfg_name)) {
@ -2921,6 +2968,7 @@ static ftdm_status_t load_config(void)
if (span->trunk_type == FTDM_TRUNK_FXO) {
currindex = span->chan_count;
configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_FXO, name, number);
ftdm_set_channels_gains(span, currindex, rxgain, txgain);
ftdm_group_add_channels(group_name, span, currindex);
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add FXO channels to an FXS trunk!\n");
@ -2934,6 +2982,7 @@ static ftdm_status_t load_config(void)
if (span->trunk_type == FTDM_TRUNK_FXS) {
currindex = span->chan_count;
configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_FXS, name, number);
ftdm_set_channels_gains(span, currindex, rxgain, txgain);
ftdm_group_add_channels(group_name, span, currindex);
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add FXS channels to an FXO trunk!\n");
@ -2947,6 +2996,7 @@ static ftdm_status_t load_config(void)
if (span->trunk_type == FTDM_TRUNK_EM) {
currindex = span->chan_count;
configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_EM, name, number);
ftdm_set_channels_gains(span, currindex, rxgain, txgain);
ftdm_group_add_channels(group_name, span, currindex);
} else {
ftdm_log(FTDM_LOG_WARNING, "Cannot add EM channels to a non-EM trunk!\n");
@ -2954,6 +3004,7 @@ static ftdm_status_t load_config(void)
} else if (!strcasecmp(var, "b-channel")) {
currindex = span->chan_count;
configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_B, name, number);
ftdm_set_channels_gains(span, currindex, rxgain, txgain);
ftdm_group_add_channels(group_name, span, currindex);
} else if (!strcasecmp(var, "d-channel")) {
if (d) {
@ -2972,10 +3023,19 @@ static ftdm_status_t load_config(void)
} else if (!strcasecmp(var, "cas-channel")) {
currindex = span->chan_count;
configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_CAS, name, number);
ftdm_set_channels_gains(span, currindex, rxgain, txgain);
ftdm_group_add_channels(group_name, span, currindex);
} else if (!strcasecmp(var, "dtmf_hangup")) {
span->dtmf_hangup = ftdm_strdup(val);
span->dtmf_hangup_len = strlen(val);
} else if (!strcasecmp(var, "txgain")) {
if (sscanf(val, "%f", &txgain) != 1) {
ftdm_log(FTDM_LOG_ERROR, "invalid txgain: '%s'\n", val);
}
} else if (!strcasecmp(var, "rxgain")) {
if (sscanf(val, "%f", &rxgain) != 1) {
ftdm_log(FTDM_LOG_ERROR, "invalid rxgain: '%s'\n", val);
}
} else if (!strcasecmp(var, "group")) {
len = strlen(val);
if (len >= sizeof(group_name)) {
@ -2987,6 +3047,44 @@ static ftdm_status_t load_config(void)
} else {
ftdm_log(FTDM_LOG_ERROR, "unknown span variable '%s'\n", var);
}
} else if (!strncasecmp(cfg.category, "general", 7)) {
if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) {
if (atoi(val) > 0) {
globals.cpu_monitor.interval = atoi(val);
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu monitoring interval %s\n", val);
}
} else if (!strncasecmp(var, "cpu_set_alarm_threshold", sizeof("cpu_set_alarm_threshold")-1)) {
if (atoi(val) > 0 && atoi(val) < 100) {
globals.cpu_monitor.set_alarm_threshold = atoi(val);
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm set threshold %s\n", val);
}
} else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1)) {
if (atoi(val) > 0 && atoi(val) < 100) {
globals.cpu_monitor.reset_alarm_threshold = atoi(val);
if (globals.cpu_monitor.reset_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) {
globals.cpu_monitor.reset_alarm_threshold = globals.cpu_monitor.set_alarm_threshold - 10;
ftdm_log(FTDM_LOG_ERROR, "Cpu alarm reset threshold must be lower than set threshold"
", setting threshold to %d\n", globals.cpu_monitor.reset_alarm_threshold);
}
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm reset threshold %s\n", val);
}
} else if (!strncasecmp(var, "cpu_alarm_action", sizeof("cpu_alarm_action")-1)) {
char* p = val;
do {
if (!strncasecmp(p, "reject", sizeof("reject")-1)) {
globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_REJECT;
} else if (!strncasecmp(p, "warn", sizeof("warn")-1)) {
globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_WARN;
}
p = strchr(p, ',');
if (p) {
while(*p++) if (*p != 0x20) break;
}
} while (p);
}
} else {
ftdm_log(FTDM_LOG_ERROR, "unknown param [%s] '%s' / '%s'\n", cfg.category, var, val);
}
@ -3266,6 +3364,9 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span(const char *type, ftdm_span_t *spa
va_list ap;
va_start(ap, sig_cb);
status = mod->sig_configure(span, sig_cb, ap);
if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
}
va_end(ap);
} else {
ftdm_log(FTDM_LOG_ERROR, "can't find '%s'\n", type);
@ -3512,6 +3613,85 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
return status;
}
static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
{
cpu_monitor_t *monitor = (cpu_monitor_t *)obj;
struct ftdm_cpu_monitor_stats *cpu_stats = ftdm_new_cpu_monitor();
if (!cpu_stats) {
return NULL;
}
monitor->running = 1;
while(ftdm_running()) {
double time;
if (ftdm_cpu_get_system_idle_time(cpu_stats, &time)) {
break;
}
if (monitor->alarm) {
if ((int)time >= (100 - monitor->set_alarm_threshold)) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm OFF (idle:%d)\n", (int) time);
monitor->alarm = 0;
}
if (monitor->alarm_action_flags & FTDM_CPU_ALARM_ACTION_WARN) {
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is ON (cpu usage:%d)\n", (int) (100-time));
}
} else {
if ((int)time <= (100-monitor->reset_alarm_threshold)) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm ON (idle:%d)\n", (int) time);
monitor->alarm = 1;
}
}
ftdm_interrupt_wait(monitor->interrupt, monitor->interval);
}
ftdm_delete_cpu_monitor(cpu_stats);
monitor->running = 0;
return NULL;
}
static ftdm_status_t ftdm_cpu_monitor_start(void)
{
if (ftdm_interrupt_create(&globals.cpu_monitor.interrupt, FTDM_INVALID_SOCKET) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to create CPU monitor interrupt\n");
return FTDM_FAIL;
}
if (ftdm_thread_create_detached(ftdm_cpu_monitor_run, &globals.cpu_monitor) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to create cpu monitor thread!!\n");
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
static void ftdm_cpu_monitor_stop(void)
{
if (!globals.cpu_monitor.interrupt) {
return;
}
if (!globals.cpu_monitor.running) {
return;
}
if (ftdm_interrupt_signal(globals.cpu_monitor.interrupt) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to interrupt the CPU monitor\n");
return;
}
while (globals.cpu_monitor.running) {
ftdm_sleep(10);
}
ftdm_interrupt_destroy(&globals.cpu_monitor.interrupt);
}
FT_DECLARE(void) ftdm_cpu_monitor_disable(void)
{
ftdm_cpu_monitor_disabled = 1;
}
FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
{
memset(&globals, 0, sizeof(globals));
@ -3534,14 +3714,34 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
{
int modcount = ftdm_load_modules();
int modcount = 0;
if (!globals.running) {
return FTDM_FAIL;
}
modcount = ftdm_load_modules();
ftdm_log(FTDM_LOG_NOTICE, "Modules configured: %d \n", modcount);
globals.cpu_monitor.interval = 1000;
globals.cpu_monitor.alarm_action_flags = FTDM_CPU_ALARM_ACTION_WARN | FTDM_CPU_ALARM_ACTION_REJECT;
globals.cpu_monitor.set_alarm_threshold = 80;
globals.cpu_monitor.reset_alarm_threshold = 70;
if (load_config() != FTDM_SUCCESS) {
globals.running = 0;
ftdm_log(FTDM_LOG_ERROR, "FreeTDM global configuration failed!\n");
return FTDM_FAIL;
}
if (!ftdm_cpu_monitor_disabled) {
if (ftdm_cpu_monitor_start() != FTDM_SUCCESS) {
return FTDM_FAIL;
}
}
return FTDM_SUCCESS;
}
@ -3559,6 +3759,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
globals.running = 0;
ftdm_cpu_monitor_stop();
globals.span_index = 0;
ftdm_span_close_all();

View File

@ -2385,7 +2385,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_isdn_configure_span)
if ((isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) {
span->channel_request = isdn_channel_request;
span->suggest_chan_id = 1;
ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);
}
span->state_map = &isdn_state_map;

View File

@ -1331,7 +1331,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_libpri_configure_span)
if ((isdn_data->opts & FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL)) {
span->channel_request = isdn_channel_request;
span->suggest_chan_id = 1;
ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);
}
span->state_map = &isdn_state_map;

View File

@ -880,8 +880,8 @@ static __inline__ void advance_chan_states(ftdm_channel_t *ftdmchan);
*/
static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, sangomabc_event_t *event)
{
ftdm_channel_t *ftdmchan;
ftdm_channel_t *ftdmchan = NULL;
int hangup_cause = FTDM_CAUSE_CALL_REJECTED;
if (!(ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 0))) {
if ((ftdmchan = find_ftdmchan(span, (sangomabc_short_event_t*)event, 1))) {
int r;
@ -896,7 +896,7 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
}
ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG);
ftdmchan=NULL;
ftdmchan = NULL;
}
ftdm_log(FTDM_LOG_CRIT, "START CANT FIND CHAN %d:%d\n", event->span+1,event->chan+1);
goto error;
@ -953,12 +953,13 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
return;
error:
hangup_cause = ftdmchan ? ftdmchan->caller_data.hangup_cause : FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL;
sangomabc_exec_command(mcon,
event->span,
event->chan,
0,
SIGBOOST_EVENT_CALL_START_NACK,
0, 0);
hangup_cause, 0);
}
@ -2239,7 +2240,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span)
span->get_span_sig_status = sangoma_boost_get_span_sig_status;
span->set_span_sig_status = sangoma_boost_set_span_sig_status;
span->state_map = &boost_state_map;
span->suggest_chan_id = 0;
ftdm_clear_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);
ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE);
if (sigmod_iface) {
/* the core will do the hunting */
span->channel_request = NULL;

View File

@ -654,7 +654,6 @@ struct ftdm_span {
char *type;
char *dtmf_hangup;
size_t dtmf_hangup_len;
int suggest_chan_id;
ftdm_state_map_t *state_map;
ftdm_caller_data_t default_caller_data;
ftdm_queue_t *pendingchans;
@ -825,6 +824,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_find_by_name(const char *name, ftdm_span_t *
FT_DECLARE(char *) ftdm_api_execute(const char *type, const char *cmd);
FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data);
FT_DECLARE(void) ftdm_cpu_monitor_disable(void);
FIO_CODEC_FUNCTION(fio_slin2ulaw);
FIO_CODEC_FUNCTION(fio_ulaw2slin);

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2010, Sangoma Technologies
* Moises Silva <moy@sangoma.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributors:
* David Yat Sin <dyatsin@sangoma.com>
*
*/
/*! \brief opaque cpu stats structure */
struct ftdm_cpu_monitor_stats;
/*!
* \brief create a new cpu monitor
* \return profile timer structure previously created with new_profile_timer, NULL on error
*/
FT_DECLARE(struct ftdm_cpu_monitor_stats*) ftdm_new_cpu_monitor(void);
/*!
* \brief Deletes cpu_monitor
*/
FT_DECLARE(void) ftdm_delete_cpu_monitor(struct ftdm_cpu_monitor_stats *p);
/*!
* \brief provides the percentage of idle system time
* \param p cpu_stats structure previously created with ftdm_new_cpu_monitor
* \param pointer to store the percentage of idle time
* \return -1 on error 0 for success
*/
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor_stats *p, double *idle_percentage);
/* 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:
*/

View File

@ -325,7 +325,9 @@ typedef enum {
FTDM_SPAN_STATE_CHANGE = (1 << 2),
FTDM_SPAN_SUSPENDED = (1 << 3),
FTDM_SPAN_IN_THREAD = (1 << 4),
FTDM_SPAN_STOP_THREAD = (1 << 5)
FTDM_SPAN_STOP_THREAD = (1 << 5),
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
} ftdm_span_flag_t;
typedef enum {

View File

@ -1,4 +1 @@
.svn
.gitignore
.update
configure.gnu

18
src/.gitignore vendored
View File

@ -1,9 +1,9 @@
Makefile
Makefile.in
include/stamp-h1
include/switch_am_config.h
include/switch_private.h
include/switch_private.h.in
include/switch_swigable_cpp.h
include/switch_version.h
include/switch_version.h.in
/Makefile
/Makefile.in
/include/stamp-h1
/include/switch_am_config.h
/include/switch_private.h
/include/switch_private.h.in
/include/switch_swigable_cpp.h
/include/switch_version.h
/include/switch_version.h.in

118
src/mod/.gitignore vendored
View File

@ -1,59 +1,59 @@
Makefile
Makefile.in
applications/mod_commands/Makefile
applications/mod_conference/Makefile
applications/mod_dptools/Makefile
applications/mod_enum/Makefile
applications/mod_enum/Makefile.in
applications/mod_enum/mod_enum.log
applications/mod_expr/Makefile
applications/mod_expr/Makefile.in
applications/mod_expr/mod_expr.log
applications/mod_fifo/Makefile
applications/mod_fsv/Makefile
applications/mod_limit/Makefile
applications/mod_stress/Makefile
applications/mod_stress/Makefile.in
applications/mod_t38gateway/Makefile
applications/mod_t38gateway/Makefile.in
applications/mod_valet_parking/Makefile
applications/mod_voicemail/Makefile
asr_tts/mod_unimrcp/Makefile
asr_tts/mod_unimrcp/Makefile.in
dialplans/mod_dialplan_asterisk/Makefile
dialplans/mod_dialplan_xml/Makefile
endpoints/mod_portaudio/Makefile
endpoints/mod_portaudio/Makefile.in
endpoints/mod_skinny/Makefile
endpoints/mod_skinny/Makefile.in
endpoints/mod_skypopen/Makefile
endpoints/mod_skypopen/Makefile.in
endpoints/mod_sofia/Makefile
endpoints/mod_sofia/Makefile.in
endpoints/mod_sofia/mod_sofia.log
event_handlers/mod_erlang_event/Makefile
event_handlers/mod_event_socket/Makefile
formats/mod_native_file/Makefile
formats/mod_portaudio_stream/Makefile
formats/mod_portaudio_stream/Makefile.in
formats/mod_tone_stream/Makefile
languages/mod_java/Makefile
languages/mod_lua/Makefile
languages/mod_lua/Makefile.in
languages/mod_lua/mod_lua.log
languages/mod_python/Makefile
languages/mod_spidermonkey/Makefile
languages/mod_spidermonkey/Makefile.in
languages/mod_spidermonkey/mod_spidermonkey.log
loggers/mod_console/Makefile
loggers/mod_logfile/Makefile
loggers/mod_syslog/Makefile
say/mod_say_en/Makefile
say/mod_say_ru/Makefile
applications/mod_stress/mod_stress.log
asr_tts/mod_unimrcp/mod_unimrcp.log
endpoints/mod_portaudio/mod_portaudio.log
endpoints/mod_skypopen/mod_skypopen.log
formats/mod_portaudio_stream/mod_portaudio_stream.log
languages/mod_java/freeswitch.jar
languages/mod_managed/freeswitch_wrap.cpp
/Makefile
/Makefile.in
/applications/mod_commands/Makefile
/applications/mod_conference/Makefile
/applications/mod_dptools/Makefile
/applications/mod_enum/Makefile
/applications/mod_enum/Makefile.in
/applications/mod_enum/mod_enum.log
/applications/mod_expr/Makefile
/applications/mod_expr/Makefile.in
/applications/mod_expr/mod_expr.log
/applications/mod_fifo/Makefile
/applications/mod_fsv/Makefile
/applications/mod_limit/Makefile
/applications/mod_stress/Makefile
/applications/mod_stress/Makefile.in
/applications/mod_t38gateway/Makefile
/applications/mod_t38gateway/Makefile.in
/applications/mod_valet_parking/Makefile
/applications/mod_voicemail/Makefile
/asr_tts/mod_unimrcp/Makefile
/asr_tts/mod_unimrcp/Makefile.in
/dialplans/mod_dialplan_asterisk/Makefile
/dialplans/mod_dialplan_xml/Makefile
/endpoints/mod_portaudio/Makefile
/endpoints/mod_portaudio/Makefile.in
/endpoints/mod_skinny/Makefile
/endpoints/mod_skinny/Makefile.in
/endpoints/mod_skypopen/Makefile
/endpoints/mod_skypopen/Makefile.in
/endpoints/mod_sofia/Makefile
/endpoints/mod_sofia/Makefile.in
/endpoints/mod_sofia/mod_sofia.log
/event_handlers/mod_erlang_event/Makefile
/event_handlers/mod_event_socket/Makefile
/formats/mod_native_file/Makefile
/formats/mod_portaudio_stream/Makefile
/formats/mod_portaudio_stream/Makefile.in
/formats/mod_tone_stream/Makefile
/languages/mod_java/Makefile
/languages/mod_lua/Makefile
/languages/mod_lua/Makefile.in
/languages/mod_lua/mod_lua.log
/languages/mod_python/Makefile
/languages/mod_spidermonkey/Makefile
/languages/mod_spidermonkey/Makefile.in
/languages/mod_spidermonkey/mod_spidermonkey.log
/loggers/mod_console/Makefile
/loggers/mod_logfile/Makefile
/loggers/mod_syslog/Makefile
/say/mod_say_en/Makefile
/say/mod_say_ru/Makefile
/applications/mod_stress/mod_stress.log
/asr_tts/mod_unimrcp/mod_unimrcp.log
/endpoints/mod_portaudio/mod_portaudio.log
/endpoints/mod_skypopen/mod_skypopen.log
/formats/mod_portaudio_stream/mod_portaudio_stream.log
/languages/mod_java/freeswitch.jar
/languages/mod_managed/freeswitch_wrap.cpp

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1,2 @@
!/gsmlib/gsmlib-*/aclocal.m4
!/gsmlib/gsmlib-*/configure

View File

@ -0,0 +1 @@
Makefile