mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-13 12:40:17 +00:00
Merge branch 'master' of git.freeswitch.org:freeswitch
This commit is contained in:
commit
7f82a41a85
@ -117,7 +117,7 @@
|
|||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension name="redial">
|
<extension name="redial">
|
||||||
<condition field="destination_number" expression="^870$">
|
<condition field="destination_number" expression="^(redial|870)$">
|
||||||
<action application="transfer" data="${hash(select/${domain_name}-last_dial/${caller_id_number})}"/>
|
<action application="transfer" data="${hash(select/${domain_name}-last_dial/${caller_id_number})}"/>
|
||||||
</condition>
|
</condition>
|
||||||
</extension>
|
</extension>
|
||||||
|
@ -179,10 +179,26 @@ void MainWindow::debugConsoleTriggered()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::applyPreprocessors(QStringList cmds)
|
||||||
|
{
|
||||||
|
if (g_FSHost.getCurrentActiveCall().isNull()) return;
|
||||||
|
QString uuid = g_FSHost.getCurrentActiveCall().data()->getUuid();
|
||||||
|
foreach(QString cmd, cmds)
|
||||||
|
{
|
||||||
|
switch_stream_handle_t stream = { 0 };
|
||||||
|
SWITCH_STANDARD_STREAM(stream);
|
||||||
|
switch_api_execute("uuid_preprocess", QString("%1 %2").arg(uuid, cmd).toAscii().data(), NULL, &stream);
|
||||||
|
switch_safe_free(stream.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::prefTriggered()
|
void MainWindow::prefTriggered()
|
||||||
{
|
{
|
||||||
if (!preferences)
|
if (!preferences)
|
||||||
|
{
|
||||||
preferences = new PrefDialog();
|
preferences = new PrefDialog();
|
||||||
|
connect(preferences, SIGNAL(preprocessorsApplied(QStringList)), this, SLOT(applyPreprocessors(QStringList)));
|
||||||
|
}
|
||||||
|
|
||||||
preferences->raise();
|
preferences->raise();
|
||||||
preferences->show();
|
preferences->show();
|
||||||
|
@ -85,6 +85,7 @@ private slots:
|
|||||||
void updateCallTimers();
|
void updateCallTimers();
|
||||||
void debugConsoleTriggered();
|
void debugConsoleTriggered();
|
||||||
void debugEventsTriggered();
|
void debugEventsTriggered();
|
||||||
|
void applyPreprocessors(QStringList);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
@ -15,6 +15,7 @@ PrefDialog::PrefDialog(QWidget *parent) :
|
|||||||
|
|
||||||
_pref_accounts = new PrefAccounts(ui);
|
_pref_accounts = new PrefAccounts(ui);
|
||||||
_mod_portaudio = new PrefPortaudio(ui, this);
|
_mod_portaudio = new PrefPortaudio(ui, this);
|
||||||
|
connect(_mod_portaudio, SIGNAL(preprocessorsApplied(QStringList)), this, SIGNAL(preprocessorsApplied(QStringList)));
|
||||||
_mod_sofia = new PrefSofia(ui, this);
|
_mod_sofia = new PrefSofia(ui, this);
|
||||||
readConfig();
|
readConfig();
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,9 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
void writeConfig();
|
void writeConfig();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void preprocessorsApplied(QStringList);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readConfig();
|
void readConfig();
|
||||||
QSettings *_settings;
|
QSettings *_settings;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,28 @@ PrefPortaudio::PrefPortaudio(Ui::PrefDialog *ui, QObject *parent) :
|
|||||||
connect(_ui->PaRingdevTestBtn, SIGNAL(clicked()), this, SLOT(ringdevTest()));
|
connect(_ui->PaRingdevTestBtn, SIGNAL(clicked()), this, SLOT(ringdevTest()));
|
||||||
connect(_ui->PaLoopTestBtn, SIGNAL(clicked()), this, SLOT(loopTest()));
|
connect(_ui->PaLoopTestBtn, SIGNAL(clicked()), this, SLOT(loopTest()));
|
||||||
connect(_ui->PaRefreshDevListBtn, SIGNAL(clicked()), this, SLOT(refreshDevList()));
|
connect(_ui->PaRefreshDevListBtn, SIGNAL(clicked()), this, SLOT(refreshDevList()));
|
||||||
|
connect(_ui->btnApplyPreprocessor, SIGNAL(toggled(bool)), this, SLOT(applyPreprocessors(bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrefPortaudio::applyPreprocessors(bool state)
|
||||||
|
{
|
||||||
|
QStringList cmds;
|
||||||
|
if (!state)
|
||||||
|
{
|
||||||
|
cmds.append("stop");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_ui->checkAECRead->isChecked()) cmds.append(QString("recho_cancel=%1").arg(_ui->spinAECTail->value()));
|
||||||
|
if (_ui->checkAECWrite->isChecked()) cmds.append(QString("wecho_cancel=%1").arg(_ui->spinAECTail->value()));
|
||||||
|
if (_ui->checkESRead->isChecked()) cmds.append(QString("recho_suppress=%1").arg(_ui->spinESDb->value()));
|
||||||
|
if (_ui->checkESWrite->isChecked()) cmds.append(QString("wecho_suppress=%1").arg(_ui->spinESDb->value()));
|
||||||
|
if (_ui->checkNSRead->isChecked()) cmds.append(QString("rnoise_suppress=%1").arg(_ui->spinNSDb->value()));
|
||||||
|
if (_ui->checkNSWrite->isChecked()) cmds.append(QString("wnoise_suppress=%1").arg(_ui->spinNSDb->value()));
|
||||||
|
if (_ui->checkAGCRead->isChecked()) cmds.append(QString("ragc=%1").arg(_ui->spinAGC->value()));
|
||||||
|
if (_ui->checkAGCWrite->isChecked()) cmds.append(QString("wagc=%1").arg(_ui->spinAGC->value()));
|
||||||
|
}
|
||||||
|
emit preprocessorsApplied(cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrefPortaudio::ringdevTest()
|
void PrefPortaudio::ringdevTest()
|
||||||
|
@ -24,6 +24,11 @@ private slots:
|
|||||||
void ringdevTest();
|
void ringdevTest();
|
||||||
void loopTest();
|
void loopTest();
|
||||||
void refreshDevList();
|
void refreshDevList();
|
||||||
|
void applyPreprocessors(bool);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void preprocessorsApplied(QStringList);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getPaDevlist(void);
|
void getPaDevlist(void);
|
||||||
QSettings *_settings;
|
QSettings *_settings;
|
||||||
|
@ -326,10 +326,34 @@
|
|||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\include\freetdm.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\include\fsk.h"
|
RelativePath="..\src\include\fsk.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\include\ftdm_buffer.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\include\ftdm_config.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\include\ftdm_dso.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\include\ftdm_threadmutex.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\include\ftdm_types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\include\g711.h"
|
RelativePath="..\src\include\g711.h"
|
||||||
>
|
>
|
||||||
@ -358,34 +382,10 @@
|
|||||||
RelativePath="..\src\include\libteletone_generate.h"
|
RelativePath="..\src\include\libteletone_generate.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\src\include\freetdm.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\include\uart.h"
|
RelativePath="..\src\include\uart.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\src\include\ftdm_buffer.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\include\ftdm_config.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\include\ftdm_dso.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\include\ftdm_threadmutex.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\include\ftdm_types.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
@ -396,6 +396,38 @@
|
|||||||
RelativePath="..\src\fsk.c"
|
RelativePath="..\src\fsk.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_buffer.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_callerid.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_config.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_cpu_monitor.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_dso.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_io.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_queue.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ftdm_threadmutex.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\g711.c"
|
RelativePath="..\src\g711.c"
|
||||||
>
|
>
|
||||||
@ -420,34 +452,6 @@
|
|||||||
RelativePath="..\src\uart.c"
|
RelativePath="..\src\uart.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\src\ftdm_buffer.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\ftdm_callerid.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\ftdm_config.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\ftdm_dso.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\ftdm_io.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\ftdm_queue.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\src\ftdm_threadmutex.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
|
@ -61,6 +61,9 @@ struct ftdm_cpu_monitor_stats
|
|||||||
double last_percentage_of_idle_time;
|
double last_percentage_of_idle_time;
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
/* the cpu feature gets disabled on errors */
|
||||||
|
int disabled;
|
||||||
|
|
||||||
/* all of these are the Linux jiffies last retrieved count */
|
/* all of these are the Linux jiffies last retrieved count */
|
||||||
unsigned long long last_user_time;
|
unsigned long long last_user_time;
|
||||||
unsigned long long last_system_time;
|
unsigned long long last_system_time;
|
||||||
@ -97,15 +100,23 @@ static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
|
|||||||
{
|
{
|
||||||
// the output of proc should not change that often from one kernel to other
|
// 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
|
// see fs/proc/proc_misc.c or fs/proc/stat.c in the Linux kernel for more details
|
||||||
// also man 5 proc is useful
|
// also man 5 proc is useful.
|
||||||
#define CPU_ELEMENTS 8 // change this if you change the format string
|
#define CPU_ELEMENTS_1 7 // change this if you change the format string
|
||||||
#define CPU_INFO_FORMAT "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu"
|
#define CPU_INFO_FORMAT_1 "cpu %llu %llu %llu %llu %llu %llu %llu"
|
||||||
|
|
||||||
|
#define CPU_ELEMENTS_2 8 // change this if you change the format string
|
||||||
|
#define CPU_INFO_FORMAT_2 "cpu %llu %llu %llu %llu %llu %llu %llu %llu"
|
||||||
|
|
||||||
|
#define CPU_ELEMENTS_3 9 // change this if you change the format string
|
||||||
|
#define CPU_INFO_FORMAT_3 "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu"
|
||||||
|
|
||||||
static const char procfile[] = "/proc/stat";
|
static const char procfile[] = "/proc/stat";
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int myerrno = 0;
|
int myerrno = 0;
|
||||||
int elements = 0;
|
int elements = 0;
|
||||||
const char *cpustr = NULL;
|
const char *cpustr = NULL;
|
||||||
char statbuff[1024];
|
char statbuff[1024];
|
||||||
|
unsigned long long guest = 0;
|
||||||
|
|
||||||
if (!p->initd) {
|
if (!p->initd) {
|
||||||
p->procfd = open(procfile, O_RDONLY, 0);
|
p->procfd = open(procfile, O_RDONLY, 0);
|
||||||
@ -131,12 +142,26 @@ static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
|
|||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
elements = sscanf(cpustr, CPU_INFO_FORMAT, user, nice, system, idle, iowait, irq, softirq, steal);
|
/* test each of the known formats starting from the bigger one */
|
||||||
if (elements != CPU_ELEMENTS) {
|
elements = sscanf(cpustr, CPU_INFO_FORMAT_3, user, nice, system, idle, iowait, irq, softirq, steal, &guest);
|
||||||
ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: expected %d elements, but just found %d\n", CPU_ELEMENTS, elements);
|
if (elements == CPU_ELEMENTS_3) {
|
||||||
return FTDM_FAIL;
|
user += guest; /* guest operating system's run in user space */
|
||||||
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
return FTDM_SUCCESS;
|
|
||||||
|
elements = sscanf(cpustr, CPU_INFO_FORMAT_2, user, nice, system, idle, iowait, irq, softirq, steal);
|
||||||
|
if (elements == CPU_ELEMENTS_2) {
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = sscanf(cpustr, CPU_INFO_FORMAT_1, user, nice, system, idle, iowait, irq, softirq);
|
||||||
|
if (elements == CPU_ELEMENTS_1) {
|
||||||
|
*steal = 0;
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Unexpected format for Linux proc cpu statistics:%s\n", cpustr);
|
||||||
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -146,8 +171,13 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor
|
|||||||
unsigned long long user, nice, system, idle, iowait, irq, softirq, steal;
|
unsigned long long user, nice, system, idle, iowait, irq, softirq, steal;
|
||||||
unsigned long long usertime, kerneltime, idletime, totaltime, halftime;
|
unsigned long long usertime, kerneltime, idletime, totaltime, halftime;
|
||||||
|
|
||||||
|
*idle_percentage = 100.0;
|
||||||
|
if (p->disabled) {
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
if (ftdm_cpu_read_stats(p, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal)) {
|
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");
|
ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics - disabling cpu monitor\n");
|
||||||
|
p->disabled = 1;
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,28 +231,31 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor
|
|||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined (WIN32) || defined (WIN64)
|
#elif defined (__WINDOWS__)
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
|
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
|
||||||
{
|
{
|
||||||
FILETIME idleTime;
|
FILETIME idleTime;
|
||||||
FILETIME kernelTime;
|
FILETIME kernelTime;
|
||||||
FILETIME userTime;
|
FILETIME userTime;
|
||||||
|
int64_t i64UserTime;
|
||||||
|
int64_t i64KernelTime;
|
||||||
|
int64_t i64IdleTime;
|
||||||
|
|
||||||
if (!::GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
|
if (!GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
|
||||||
return false;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
__int64 i64UserTime = (__int64)userTime.dwLowDateTime | ((__int64)userTime.dwHighDateTime << 32);
|
i64UserTime = (int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32);
|
||||||
|
|
||||||
__int64 i64KernelTime = (__int64)kernelTime.dwLowDateTime | ((__int64)kernelTime.dwHighDateTime << 32);
|
i64KernelTime = (int64_t)kernelTime.dwLowDateTime | ((int64_t)kernelTime.dwHighDateTime << 32);
|
||||||
|
|
||||||
__int64 i64IdleTime = (__int64)idleTime.dwLowDateTime | ((__int64)idleTime.dwHighDateTime << 32);
|
i64IdleTime = (int64_t)idleTime.dwLowDateTime | ((int64_t)idleTime.dwHighDateTime << 32);
|
||||||
|
|
||||||
if (p->valid_last_times) {
|
if (p->valid_last_times) {
|
||||||
__int64 i64User = i64UserTime - p->i64LastUserTime;
|
int64_t i64User = i64UserTime - p->i64LastUserTime;
|
||||||
__int64 i64Kernel = i64KernelTime - p->i64LastKernelTime;
|
int64_t i64Kernel = i64KernelTime - p->i64LastKernelTime;
|
||||||
__int64 i64Idle = i64IdleTime - p->i64LastIdleTime;
|
int64_t i64Idle = i64IdleTime - p->i64LastIdleTime;
|
||||||
__int64 i64System = i64User + i64Kernel;
|
int64_t i64System = i64User + i64Kernel;
|
||||||
*idle_percentage = 100.0 * i64Idle / i64System;
|
*idle_percentage = 100.0 * i64Idle / i64System;
|
||||||
} else {
|
} else {
|
||||||
*idle_percentage = 100.0;
|
*idle_percentage = 100.0;
|
||||||
@ -240,7 +273,8 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_
|
|||||||
#else
|
#else
|
||||||
/* Unsupported */
|
/* Unsupported */
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
|
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
|
||||||
{
|
{'
|
||||||
|
*idle_percentate = 100.0;
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2855,6 +2855,7 @@ static ftdm_status_t load_config(void)
|
|||||||
ftdm_config_t cfg;
|
ftdm_config_t cfg;
|
||||||
char *var, *val;
|
char *var, *val;
|
||||||
int catno = -1;
|
int catno = -1;
|
||||||
|
int intparam = 0;
|
||||||
int currindex = 0;
|
int currindex = 0;
|
||||||
ftdm_span_t *span = NULL;
|
ftdm_span_t *span = NULL;
|
||||||
unsigned configured = 0, d = 0;
|
unsigned configured = 0, d = 0;
|
||||||
@ -3059,14 +3060,16 @@ static ftdm_status_t load_config(void)
|
|||||||
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu monitoring interval %s\n", val);
|
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)) {
|
} else if (!strncasecmp(var, "cpu_set_alarm_threshold", sizeof("cpu_set_alarm_threshold")-1)) {
|
||||||
if (atoi(val) > 0 && atoi(val) < 100) {
|
intparam = atoi(val);
|
||||||
globals.cpu_monitor.set_alarm_threshold = atoi(val);
|
if (intparam > 0 && intparam < 100) {
|
||||||
|
globals.cpu_monitor.set_alarm_threshold = (uint8_t)intparam;
|
||||||
} else {
|
} else {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm set threshold %s\n", val);
|
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)) {
|
} else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1)) {
|
||||||
if (atoi(val) > 0 && atoi(val) < 100) {
|
intparam = atoi(val);
|
||||||
globals.cpu_monitor.reset_alarm_threshold = atoi(val);
|
if (intparam > 0 && intparam < 100) {
|
||||||
|
globals.cpu_monitor.reset_alarm_threshold = (uint8_t)intparam;
|
||||||
if (globals.cpu_monitor.reset_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) {
|
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;
|
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"
|
ftdm_log(FTDM_LOG_ERROR, "Cpu alarm reset threshold must be lower than set threshold"
|
||||||
@ -3404,6 +3407,9 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(const char *type, ftdm_s
|
|||||||
|
|
||||||
if (mod->configure_span_signaling) {
|
if (mod->configure_span_signaling) {
|
||||||
status = mod->configure_span_signaling(span, sig_cb, parameters);
|
status = mod->configure_span_signaling(span, sig_cb, parameters);
|
||||||
|
if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
|
||||||
|
status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Module %s did not implement the signaling configuration method\n", type);
|
ftdm_log(FTDM_LOG_ERROR, "Module %s did not implement the signaling configuration method\n", type);
|
||||||
}
|
}
|
||||||
@ -3652,6 +3658,9 @@ static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
|
|||||||
ftdm_delete_cpu_monitor(cpu_stats);
|
ftdm_delete_cpu_monitor(cpu_stats);
|
||||||
monitor->running = 0;
|
monitor->running = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
UNREFERENCED_PARAMETER(me);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ftdm_status_t ftdm_cpu_monitor_start(void)
|
static ftdm_status_t ftdm_cpu_monitor_start(void)
|
||||||
|
@ -314,7 +314,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int m
|
|||||||
num++;
|
num++;
|
||||||
ints[1] = interrupt->device;
|
ints[1] = interrupt->device;
|
||||||
}
|
}
|
||||||
res = WaitForMultipleObjects(num, &ints, FALSE, ms >= 0 ? ms : INFINITE);
|
res = WaitForMultipleObjects(num, ints, FALSE, ms >= 0 ? ms : INFINITE);
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
return FTDM_TIMEOUT;
|
return FTDM_TIMEOUT;
|
||||||
@ -366,7 +366,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_signal(ftdm_interrupt_t *interrupt)
|
|||||||
{
|
{
|
||||||
ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Interrupt is null!\n");
|
ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Interrupt is null!\n");
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (!SetEvent(interrupt->interrupt)) {
|
if (!SetEvent(interrupt->event)) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt\n");
|
ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt\n");
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
@ -400,10 +400,42 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **ininterrupt)
|
|||||||
|
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interrupts[], ftdm_size_t size, int ms)
|
FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interrupts[], ftdm_size_t size, int ms)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
|
||||||
int i;
|
|
||||||
int res = 0;
|
|
||||||
int numdevices = 0;
|
int numdevices = 0;
|
||||||
|
unsigned i;
|
||||||
|
#if defined(__WINDOWS__)
|
||||||
|
DWORD res = 0;
|
||||||
|
HANDLE ints[20];
|
||||||
|
if (size > (ftdm_array_len(ints)/2)) {
|
||||||
|
/* improve if needed: dynamically allocate the list of interrupts *only* when exceeding the default size */
|
||||||
|
ftdm_log(FTDM_LOG_CRIT, "Unsupported size of interrupts: %d, implement me!\n", size);
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
ints[i] = interrupts[i]->event;
|
||||||
|
if (interrupts[i]->device != FTDM_INVALID_SOCKET) {
|
||||||
|
ints[i+numdevices] = interrupts[i]->device;
|
||||||
|
numdevices++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = WaitForMultipleObjects(size+numdevices, ints, FALSE, ms >= 0 ? ms : INFINITE);
|
||||||
|
|
||||||
|
switch (res) {
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return FTDM_TIMEOUT;
|
||||||
|
case WAIT_FAILED:
|
||||||
|
case WAIT_ABANDONED: /* is it right to fail with abandoned? */
|
||||||
|
return FTDM_FAIL;
|
||||||
|
default:
|
||||||
|
if (res >= (size+numdevices)) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Error waiting for freetdm interrupt event (WaitForSingleObject returned %d)\n", res);
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
/* fall-through to FTDM_SUCCESS at the end of the function */
|
||||||
|
}
|
||||||
|
#elif defined(__linux__)
|
||||||
|
int res = 0;
|
||||||
char pipebuf[255];
|
char pipebuf[255];
|
||||||
struct pollfd ints[size*2];
|
struct pollfd ints[size*2];
|
||||||
|
|
||||||
@ -432,6 +464,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
|||||||
return FTDM_TIMEOUT;
|
return FTDM_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for events in the pipes, NOT in the devices */
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
if (ints[i].revents & POLLIN) {
|
if (ints[i].revents & POLLIN) {
|
||||||
res = read(ints[i].fd, pipebuf, sizeof(pipebuf));
|
res = read(ints[i].fd, pipebuf, sizeof(pipebuf));
|
||||||
@ -440,7 +473,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
#endif
|
#endif
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
|
|||||||
ftdm_set_string(event.calling_name, caller_data->cid_name);
|
ftdm_set_string(event.calling_name, caller_data->cid_name);
|
||||||
ftdm_set_string(event.rdnis.digits, caller_data->rdnis.digits);
|
ftdm_set_string(event.rdnis.digits, caller_data->rdnis.digits);
|
||||||
if (strlen(caller_data->rdnis.digits)) {
|
if (strlen(caller_data->rdnis.digits)) {
|
||||||
event.rdnis.digits_count = strlen(caller_data->rdnis.digits)+1;
|
event.rdnis.digits_count = (uint8_t)strlen(caller_data->rdnis.digits)+1;
|
||||||
event.rdnis.ton = caller_data->rdnis.type;
|
event.rdnis.ton = caller_data->rdnis.type;
|
||||||
event.rdnis.npi = caller_data->rdnis.plan;
|
event.rdnis.npi = caller_data->rdnis.plan;
|
||||||
}
|
}
|
||||||
@ -474,7 +474,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(sangoma_boost_outgoing_call)
|
|||||||
ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name);
|
ftdm_set_string(event.calling_name, ftdmchan->caller_data.cid_name);
|
||||||
ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits);
|
ftdm_set_string(event.rdnis.digits, ftdmchan->caller_data.rdnis.digits);
|
||||||
if (strlen(ftdmchan->caller_data.rdnis.digits)) {
|
if (strlen(ftdmchan->caller_data.rdnis.digits)) {
|
||||||
event.rdnis.digits_count = strlen(ftdmchan->caller_data.rdnis.digits)+1;
|
event.rdnis.digits_count = (uint8_t)strlen(ftdmchan->caller_data.rdnis.digits)+1;
|
||||||
event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
|
event.rdnis.ton = ftdmchan->caller_data.rdnis.type;
|
||||||
event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
|
event.rdnis.npi = ftdmchan->caller_data.rdnis.plan;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="freetdm.lib libsangoma.lib"
|
AdditionalDependencies="freetdm.lib libsangoma.lib"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
AdditionalLibraryDirectories=""$(OutDir)";"C:\Program Files\Sangoma\lib""
|
AdditionalLibraryDirectories=""$(OutDir)";"C:\Program Files\Sangoma\api\lib\x86""
|
||||||
GenerateDebugInformation="true"
|
GenerateDebugInformation="true"
|
||||||
SubSystem="1"
|
SubSystem="1"
|
||||||
RandomizedBaseAddress="1"
|
RandomizedBaseAddress="1"
|
||||||
@ -96,6 +96,83 @@
|
|||||||
Name="VCPostBuildEventTool"
|
Name="VCPostBuildEventTool"
|
||||||
/>
|
/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="../../../src/include;../../../src/isdn/include;../../../wanpipe/include"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="freetdm.lib libsangoma.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories=""$(OutDir)";../../../wanpipe/api/lib/x86"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Debug|x64"
|
Name="Debug|x64"
|
||||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
@ -174,83 +251,6 @@
|
|||||||
Name="VCPostBuildEventTool"
|
Name="VCPostBuildEventTool"
|
||||||
/>
|
/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="2"
|
|
||||||
CharacterSet="2"
|
|
||||||
WholeProgramOptimization="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AdditionalIncludeDirectories="../../../src/include;../../../src/isdn/include;../../../wanpipe/include"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
|
||||||
RuntimeLibrary="2"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="true"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalDependencies="freetdm.lib libsangoma.lib"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories=""$(OutDir)";../../../wanpipe/api/lib/x86"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="1"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
EnableCOMDATFolding="2"
|
|
||||||
RandomizedBaseAddress="1"
|
|
||||||
DataExecutionPrevention="0"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Release|x64"
|
Name="Release|x64"
|
||||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
@ -101,8 +101,6 @@ static struct {
|
|||||||
FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
||||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
|
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
|
||||||
|
|
||||||
#define WP_INVALID_SOCKET -1
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Poll for event on a wanpipe socket
|
* \brief Poll for event on a wanpipe socket
|
||||||
* \param fd Wanpipe socket descriptor
|
* \param fd Wanpipe socket descriptor
|
||||||
@ -224,7 +222,7 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
|||||||
}
|
}
|
||||||
for(x = start; x < end; x++) {
|
for(x = start; x < end; x++) {
|
||||||
ftdm_channel_t *chan;
|
ftdm_channel_t *chan;
|
||||||
ftdm_socket_t sockfd = WP_INVALID_SOCKET;
|
ftdm_socket_t sockfd = FTDM_INVALID_SOCKET;
|
||||||
const char *dtmf = "none";
|
const char *dtmf = "none";
|
||||||
if (!strncasecmp(span->name, "smg_prid_nfas", 8) && span->trunk_type == FTDM_TRUNK_T1 && x == 24) {
|
if (!strncasecmp(span->name, "smg_prid_nfas", 8) && span->trunk_type == FTDM_TRUNK_T1 && x == 24) {
|
||||||
#ifdef LIBSANGOMA_VERSION
|
#ifdef LIBSANGOMA_VERSION
|
||||||
@ -236,7 +234,7 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
|||||||
sockfd = tdmv_api_open_span_chan(spanno, x);
|
sockfd = tdmv_api_open_span_chan(spanno, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sockfd == WP_INVALID_SOCKET) {
|
if (sockfd == FTDM_INVALID_SOCKET) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Failed to open wanpipe device span %d channel %d\n", spanno, x);
|
ftdm_log(FTDM_LOG_ERROR, "Failed to open wanpipe device span %d channel %d\n", spanno, x);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1166,9 +1164,8 @@ static FIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ftdmchan->sockfd > -1) {
|
if (ftdmchan->sockfd != FTDM_INVALID_SOCKET) {
|
||||||
close(ftdmchan->sockfd);
|
sangoma_close(&ftdmchan->sockfd);
|
||||||
ftdmchan->sockfd = WP_INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
|
@ -43,8 +43,6 @@
|
|||||||
#include "libsangoma.h"
|
#include "libsangoma.h"
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
#if defined(__WINDOWS__)
|
||||||
/* remove this when http://jira.freeswitch.org/browse/FSBUILD-259 wanpipe issue is fixed */
|
|
||||||
#define WINDOWS_BUILD_BROKEN 1
|
|
||||||
/*! Backward compatible defines - current code is all using the old names*/
|
/*! Backward compatible defines - current code is all using the old names*/
|
||||||
#define sangoma_open_tdmapi_span_chan sangoma_open_api_span_chan
|
#define sangoma_open_tdmapi_span_chan sangoma_open_api_span_chan
|
||||||
#define sangoma_open_tdmapi_span sangoma_open_api_span
|
#define sangoma_open_tdmapi_span sangoma_open_api_span
|
||||||
@ -96,8 +94,6 @@ static struct {
|
|||||||
ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
ZIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
||||||
ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
|
ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
|
||||||
|
|
||||||
#define WP_INVALID_SOCKET -1
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Poll for event on a wanpipe socket
|
* \brief Poll for event on a wanpipe socket
|
||||||
* \param fd Wanpipe socket descriptor
|
* \param fd Wanpipe socket descriptor
|
||||||
@ -219,7 +215,7 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
|
|||||||
}
|
}
|
||||||
for(x = start; x < end; x++) {
|
for(x = start; x < end; x++) {
|
||||||
zap_channel_t *chan;
|
zap_channel_t *chan;
|
||||||
zap_socket_t sockfd = WP_INVALID_SOCKET;
|
zap_socket_t sockfd = ZAP_INVALID_SOCKET;
|
||||||
const char *dtmf = "none";
|
const char *dtmf = "none";
|
||||||
if (!strncasecmp(span->name, "smg_prid_nfas", 8) && span->trunk_type == ZAP_TRUNK_T1 && x == 24) {
|
if (!strncasecmp(span->name, "smg_prid_nfas", 8) && span->trunk_type == ZAP_TRUNK_T1 && x == 24) {
|
||||||
#ifdef LIBSANGOMA_VERSION
|
#ifdef LIBSANGOMA_VERSION
|
||||||
@ -231,7 +227,7 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
|
|||||||
sockfd = tdmv_api_open_span_chan(spanno, x);
|
sockfd = tdmv_api_open_span_chan(spanno, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sockfd == WP_INVALID_SOCKET) {
|
if (sockfd == ZAP_INVALID_SOCKET) {
|
||||||
zap_log(ZAP_LOG_ERROR, "Failed to open wanpipe device span %d channel %d\n", spanno, x);
|
zap_log(ZAP_LOG_ERROR, "Failed to open wanpipe device span %d channel %d\n", spanno, x);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -587,29 +583,24 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
|
|||||||
break;
|
break;
|
||||||
case ZAP_COMMAND_ENABLE_ECHOCANCEL:
|
case ZAP_COMMAND_ENABLE_ECHOCANCEL:
|
||||||
{
|
{
|
||||||
#ifndef WINDOWS_BUILD_BROKEN
|
|
||||||
err=sangoma_tdm_enable_hwec(zchan->sockfd, &tdm_api);
|
err=sangoma_tdm_enable_hwec(zchan->sockfd, &tdm_api);
|
||||||
if (err) {
|
if (err) {
|
||||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "HWEC Enable Failed");
|
snprintf(zchan->last_error, sizeof(zchan->last_error), "HWEC Enable Failed");
|
||||||
return ZAP_FAIL;
|
return ZAP_FAIL;
|
||||||
}
|
}
|
||||||
#endif /* WINDOWS_BUILD_BROKEN */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZAP_COMMAND_DISABLE_ECHOCANCEL:
|
case ZAP_COMMAND_DISABLE_ECHOCANCEL:
|
||||||
{
|
{
|
||||||
#ifndef WINDOWS_BUILD_BROKEN
|
|
||||||
err=sangoma_tdm_disable_hwec(zchan->sockfd, &tdm_api);
|
err=sangoma_tdm_disable_hwec(zchan->sockfd, &tdm_api);
|
||||||
if (err) {
|
if (err) {
|
||||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "HWEC Disable Failed");
|
snprintf(zchan->last_error, sizeof(zchan->last_error), "HWEC Disable Failed");
|
||||||
return ZAP_FAIL;
|
return ZAP_FAIL;
|
||||||
}
|
}
|
||||||
#endif /* WINDOWS_BUILD_BROKEN */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZAP_COMMAND_ENABLE_LOOP:
|
case ZAP_COMMAND_ENABLE_LOOP:
|
||||||
{
|
{
|
||||||
#ifndef WINDOWS_BUILD_BROKEN
|
|
||||||
#ifdef WP_API_FEATURE_LOOP
|
#ifdef WP_API_FEATURE_LOOP
|
||||||
err=sangoma_tdm_enable_loop(zchan->sockfd, &tdm_api);
|
err=sangoma_tdm_enable_loop(zchan->sockfd, &tdm_api);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -617,11 +608,9 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
|
|||||||
return ZAP_FAIL;
|
return ZAP_FAIL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* WINDOWS_BUILD_BROKEN */
|
|
||||||
}
|
}
|
||||||
case ZAP_COMMAND_DISABLE_LOOP:
|
case ZAP_COMMAND_DISABLE_LOOP:
|
||||||
{
|
{
|
||||||
#ifndef WINDOWS_BUILD_BROKEN
|
|
||||||
#ifdef WP_API_FEATURE_LOOP
|
#ifdef WP_API_FEATURE_LOOP
|
||||||
err=sangoma_tdm_disable_loop(zchan->sockfd, &tdm_api);
|
err=sangoma_tdm_disable_loop(zchan->sockfd, &tdm_api);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -629,7 +618,6 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
|
|||||||
return ZAP_FAIL;
|
return ZAP_FAIL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* WINDOWS_BUILD_BROKEN */
|
|
||||||
}
|
}
|
||||||
case ZAP_COMMAND_SET_INTERVAL:
|
case ZAP_COMMAND_SET_INTERVAL:
|
||||||
{
|
{
|
||||||
@ -1163,9 +1151,8 @@ static ZIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (zchan->sockfd > -1) {
|
if (zchan->sockfd != ZAP_INVALID_SOCKET) {
|
||||||
close(zchan->sockfd);
|
sangoma_close(&zchan->sockfd);
|
||||||
zchan->sockfd = WP_INVALID_SOCKET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZAP_SUCCESS;
|
return ZAP_SUCCESS;
|
||||||
|
76
scripts/setup-git.sh
Executable file
76
scripts/setup-git.sh
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*-
|
||||||
|
##### setup git properly for FreeSWITCH
|
||||||
|
|
||||||
|
if [ ! -d .git ]; then
|
||||||
|
echo "error: must be run from within the top level of a FreeSWITCH git tree." 1>&2
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
err () {
|
||||||
|
echo "error: $1" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! git config user.name >/dev/null 2>&1; then
|
||||||
|
name=$(git config user.name)
|
||||||
|
[ -z "$name" ] \
|
||||||
|
&& [ -n "$NAME" ] && name="$NAME" || name=""
|
||||||
|
echo -n "What is your name? [$name]: "
|
||||||
|
read name_
|
||||||
|
[ -n "$name_" ] && name="$name_"
|
||||||
|
[ -z "$name" ] && err "Your name is required."
|
||||||
|
git config --global user.name "$name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! git config user.email >/dev/null 2>&1; then
|
||||||
|
email=$(git config user.email)
|
||||||
|
[ -z "$email" ] \
|
||||||
|
&& [ -n "$EMAIL" ] && email="$EMAIL" || email=""
|
||||||
|
echo -n "What is your email? [$email]: "
|
||||||
|
read email_
|
||||||
|
[ -n "$email_" ] && email="$email_"
|
||||||
|
[ -z "$email" ] && err "Your email is required."
|
||||||
|
git config --global user.email "$email"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git config branch.master.rebase true
|
||||||
|
|
||||||
|
cat 1>&2 <<EOF
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Git has been configured for FS successfully.
|
||||||
|
|
||||||
|
branch.master.rebase has been set to true
|
||||||
|
|
||||||
|
This means that when you do a 'git pull' to fetch remote changes,
|
||||||
|
your local changes will be rebased on top of the remote changes.
|
||||||
|
This does NOT rewrite history on the remote FS repo, but it does
|
||||||
|
change the commit hashes in your local tree.
|
||||||
|
|
||||||
|
If you really want to merge rather than rebasing, run:
|
||||||
|
|
||||||
|
git merge <commit>
|
||||||
|
|
||||||
|
See 'man git-config' for more information.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
[ -n "$name" ] \
|
||||||
|
&& cat 1>&2 <<EOF
|
||||||
|
|
||||||
|
Your name has been set to: $name
|
||||||
|
|
||||||
|
via 'git config --global user.name "$name"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
[ -n "$name" ] \
|
||||||
|
&& cat 1>&2 <<EOF
|
||||||
|
|
||||||
|
Your email has been set to: $email
|
||||||
|
|
||||||
|
via 'git config --global user.email "$email"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat 1>&2 <<EOF
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
EOF
|
||||||
|
|
@ -298,6 +298,10 @@ static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, ch
|
|||||||
switch_core_sprintf(pool, "[lcr_carrier=%s,lcr_rate=%s%s%s%s%s]%s%s%s%s%s", cur_route->carrier_name, cur_route->rate_str, user_rate, codec, cid,
|
switch_core_sprintf(pool, "[lcr_carrier=%s,lcr_rate=%s%s%s%s%s]%s%s%s%s%s", cur_route->carrier_name, cur_route->rate_str, user_rate, codec, cid,
|
||||||
header, cur_route->gw_prefix, cur_route->prefix, destination_number, cur_route->suffix, cur_route->gw_suffix);
|
header, cur_route->gw_prefix, cur_route->prefix, destination_number, cur_route->suffix, cur_route->gw_suffix);
|
||||||
|
|
||||||
|
if (session && (switch_string_var_check_const(data) || switch_string_has_escaped_data(data))) {
|
||||||
|
data = switch_channel_expand_variables(switch_core_session_get_channel(session), data);
|
||||||
|
}
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Returning Dialstring %s\n", data);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Returning Dialstring %s\n", data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -187,9 +187,13 @@ static void tts_commandline_speech_flush_tts(switch_speech_handle_t *sh)
|
|||||||
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
|
tts_commandline_t *info = (tts_commandline_t *) sh->private_info;
|
||||||
assert(info != NULL);
|
assert(info != NULL);
|
||||||
|
|
||||||
switch_core_file_close(info->fh);
|
if (info->fh != NULL && info->fh->file_interface != NULL) {
|
||||||
if (unlink(info->file) != 0) {
|
switch_core_file_close(info->fh);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sound file [%s] delete failed\n", info->file);
|
}
|
||||||
|
if (switch_file_exists(info->file, NULL) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (unlink(info->file) != 0) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Sound file [%s] delete failed\n", info->file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,26 +6,25 @@ package Net::Skinny;
|
|||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use IO::Socket;
|
|
||||||
|
require IO::Socket;
|
||||||
|
|
||||||
use Net::Skinny::Protocol qw/:all/;
|
use Net::Skinny::Protocol qw/:all/;
|
||||||
|
|
||||||
our(@ISA);
|
our @ISA = qw(IO::Socket::INET);
|
||||||
@ISA = qw(IO::Socket::INET);
|
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
shift->SUPER::new(PeerPort => 2000, @_);
|
shift->SUPER::new(PeerPort => 2000, @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub send_data
|
sub send_raw
|
||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
my $data = shift;
|
my $raw = shift;
|
||||||
my $len = length($data)+4;
|
my $len = length($raw)+4;
|
||||||
printf "Sending message (length=%d, type=%s (%X))", $len, Net::Skinny::Protocol::skinny_message_type2str($type), $type;
|
printf "Sending message (length=%d, type=%s (%X))", $len, Net::Skinny::Protocol::skinny_message_type2str($type), $type;
|
||||||
$self->send(
|
$self->send(pack("VVV", $len, 0, $type).$raw);
|
||||||
pack("VVV", $len, 0, $type).
|
|
||||||
$data);
|
|
||||||
printf ".\n";
|
printf ".\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,11 +32,8 @@ sub send_message
|
|||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
return Net::Skinny::Message->new(
|
my $message = Net::Skinny::Message->new($type, @_);
|
||||||
$self,
|
return $self->send_raw($message->type(), $message->raw());
|
||||||
$type,
|
|
||||||
@_
|
|
||||||
)->send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub receive_message
|
sub receive_message
|
||||||
@ -58,20 +54,26 @@ sub receive_message
|
|||||||
printf "type=%s (%X))", Net::Skinny::Protocol::skinny_message_type2str($type), $type;
|
printf "type=%s (%X))", Net::Skinny::Protocol::skinny_message_type2str($type), $type;
|
||||||
if($len > 4) {
|
if($len > 4) {
|
||||||
$self->recv($buf, $len-4);
|
$self->recv($buf, $len-4);
|
||||||
|
} else {
|
||||||
|
$buf = '';
|
||||||
}
|
}
|
||||||
printf ".\n";
|
printf ".\n";
|
||||||
|
return Net::Skinny::Message->new_raw($type, $buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub sleep
|
sub sleep
|
||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $t = shift;
|
my $t = shift;
|
||||||
|
my %args = @_;
|
||||||
|
$args{'quiet'} = 0 if not $args{'quiet'};
|
||||||
printf "Sleeping %d seconds", $t;
|
printf "Sleeping %d seconds", $t;
|
||||||
while(--$t){
|
while(--$t){
|
||||||
sleep(1);
|
sleep(1);
|
||||||
printf "." if $t % 10;
|
if(!$args{'quiet'}) {
|
||||||
printf "_" unless $t % 10;
|
printf "." if $t % 10;
|
||||||
|
printf "_" unless $t % 10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf ".\n";
|
printf ".\n";
|
||||||
}
|
}
|
||||||
|
94
src/mod/endpoints/mod_skinny/Net/Skinny/Client.pm
Normal file
94
src/mod/endpoints/mod_skinny/Net/Skinny/Client.pm
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# Copyright (c) 2010 Mathieu Parent <math.parent@gmail.com>.
|
||||||
|
# All rights reserved. This program is free software; you can redistribute it
|
||||||
|
# and/or modify it under the same terms as Perl itself.
|
||||||
|
|
||||||
|
package Net::Skinny::Client;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Config;
|
||||||
|
use threads;
|
||||||
|
use threads::shared;
|
||||||
|
use Thread::Queue;
|
||||||
|
|
||||||
|
require Net::Skinny;
|
||||||
|
use Net::Skinny::Protocol qw/:all/;
|
||||||
|
use Net::Skinny::Message;
|
||||||
|
|
||||||
|
our(@ISA);
|
||||||
|
@ISA = qw(Net::Skinny);
|
||||||
|
|
||||||
|
my $keep_alive_thread;
|
||||||
|
my $keep_alives :shared;
|
||||||
|
our $kept_self;
|
||||||
|
my $messages_send_queue;
|
||||||
|
my $messages_receive_queue;
|
||||||
|
|
||||||
|
$Config{useithreads} or die('Recompile Perl with threads to run this program.');
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
$kept_self = shift->SUPER::new(@_);
|
||||||
|
$messages_send_queue = Thread::Queue->new();
|
||||||
|
$messages_receive_queue = Thread::Queue->new();
|
||||||
|
threads->create(\&send_messages_thread_func);
|
||||||
|
threads->create(\&receive_messages_thread_func);
|
||||||
|
return $kept_self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub send_message {
|
||||||
|
my $self = shift;
|
||||||
|
$messages_send_queue->enqueue(\@_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub receive_message {
|
||||||
|
my $self = shift;
|
||||||
|
my $message = $messages_receive_queue->dequeue();
|
||||||
|
if($message->type() == 0x100) {#keepaliveack
|
||||||
|
if(1) {
|
||||||
|
lock($keep_alives);
|
||||||
|
$keep_alives--;
|
||||||
|
}
|
||||||
|
$message = $messages_receive_queue->dequeue();
|
||||||
|
}
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub launch_keep_alive_thread
|
||||||
|
{
|
||||||
|
if(!$keep_alive_thread) {
|
||||||
|
$keep_alive_thread = threads->create(\&keep_alive_thread_func);
|
||||||
|
} else {
|
||||||
|
print "keep-alive thread is already running\n";
|
||||||
|
}
|
||||||
|
return $keep_alive_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub keep_alive_thread_func
|
||||||
|
{
|
||||||
|
while($kept_self) {
|
||||||
|
if(1) {
|
||||||
|
lock($keep_alives);
|
||||||
|
$keep_alives++;
|
||||||
|
$kept_self->send_message(KEEP_ALIVE_MESSAGE);
|
||||||
|
} #mutex unlocked
|
||||||
|
$kept_self->sleep(30, quiet => 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub send_messages_thread_func
|
||||||
|
{
|
||||||
|
while(my $message = $messages_send_queue->dequeue()) {
|
||||||
|
my $type = shift @$message;
|
||||||
|
$kept_self->SUPER::send_message($type, @$message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub receive_messages_thread_func
|
||||||
|
{
|
||||||
|
while(1) {
|
||||||
|
$messages_receive_queue->enqueue($kept_self->SUPER::receive_message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -7,54 +7,96 @@ package Net::Skinny::Message;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
use threads;
|
||||||
|
use threads::shared;
|
||||||
|
|
||||||
use Net::Skinny::Protocol qw/:all/;
|
use Net::Skinny::Protocol qw/:all/;
|
||||||
|
|
||||||
use Data::Dumper;
|
sub new_empty {
|
||||||
|
|
||||||
require Exporter;
|
|
||||||
our @ISA = qw(Exporter);
|
|
||||||
our @EXPORT = qw(send);
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
my $self = {};
|
my $self = {};
|
||||||
bless $self, $class;
|
bless $self, $class;
|
||||||
$self->{'socket'} = shift;
|
$self->{'type'} = undef;
|
||||||
$self->{'type'} = shift;
|
$self->{'data'} = undef;
|
||||||
%{$self->{'data'}} = @_;
|
$self->{'raw'} = undef;
|
||||||
return $ self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub send {
|
sub new {
|
||||||
|
my $self = shift->new_empty();
|
||||||
|
$self->type(shift);
|
||||||
|
$self->data(@_) if @_;
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub new_raw {
|
||||||
|
my $self = shift->new_empty();
|
||||||
|
$self->type(shift);
|
||||||
|
$self->raw(shift);
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub type
|
||||||
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $struct = Net::Skinny::Protocol::skinny_message_struct($self->{'type'});
|
my $type = @_ ? shift : undef;
|
||||||
my $raw = '';
|
if(defined($type)) {
|
||||||
my $parsed_count = 0;
|
$self->{'type'} = $type;
|
||||||
for my $info ( @$struct) {
|
|
||||||
last if !defined($self->{'data'}{@$info[1]});
|
|
||||||
if(@$info[0] eq 'char') {
|
|
||||||
$raw .= pack("a".@$info[2], $self->{'data'}{@$info[1]});
|
|
||||||
} elsif(@$info[0] eq 'uint32_t') {
|
|
||||||
$raw .= pack("V".@$info[2], $self->{'data'}{@$info[1]});
|
|
||||||
} elsif(@$info[0] eq 'uint16_t') {
|
|
||||||
$raw .= pack("n".@$info[2], $self->{'data'}{@$info[1]});
|
|
||||||
} elsif(@$info[0] eq 'struct in_addr') {
|
|
||||||
$raw .= pack("V".@$info[2], $self->{'data'}{@$info[1]});
|
|
||||||
} elsif(@$info[0] eq 'struct station_capabilities') {
|
|
||||||
$raw .= $self->{'data'}{@$info[1]};
|
|
||||||
} else {
|
|
||||||
printf "Unknown type: %s\n", @$info[0];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$parsed_count++;
|
|
||||||
}
|
}
|
||||||
if($parsed_count != scalar(keys %{$self->{'data'}})) {
|
return $self->{'type'};
|
||||||
printf "Incomplete message (type=%s (%X)) %d out of %d\n", Net::Skinny::Protocol::skinny_message_type2str($self->{'type'}), $self->{'type'},
|
}
|
||||||
$parsed_count, scalar(keys %{$self->{'data'}});
|
|
||||||
print Dumper(@$struct);
|
sub data
|
||||||
return;
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my @data = @_;
|
||||||
|
if(@data) {
|
||||||
|
%{$self->{'data'}} = @data;
|
||||||
|
$self->{'raw'} = undef;
|
||||||
|
} elsif(!defined($self->{'data'})) {
|
||||||
|
printf "Conversion from raw to data not implemented\n";
|
||||||
}
|
}
|
||||||
$self->{'socket'}->send_data($self->{'type'}, $raw);
|
return $self->{'data'};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub raw
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $raw = shift || undef;
|
||||||
|
if(defined($raw)) {
|
||||||
|
$self->{'raw'} = $raw;
|
||||||
|
$self->{'data'} = undef;
|
||||||
|
}
|
||||||
|
if(!defined($self->{'raw'})) {
|
||||||
|
my $struct = Net::Skinny::Protocol::skinny_message_struct($self->{'type'});
|
||||||
|
my $raw = '';
|
||||||
|
my $parsed_count = 0;
|
||||||
|
for my $info ( @$struct) {
|
||||||
|
last if !defined($self->{'data'}{@$info[1]});
|
||||||
|
if(@$info[0] eq 'char') {
|
||||||
|
$raw .= pack("a".@$info[2], $self->{'data'}{@$info[1]});
|
||||||
|
} elsif(@$info[0] eq 'uint32_t') {
|
||||||
|
$raw .= pack("V".@$info[2], $self->{'data'}{@$info[1]});
|
||||||
|
} elsif(@$info[0] eq 'uint16_t') {
|
||||||
|
$raw .= pack("n".@$info[2], $self->{'data'}{@$info[1]});
|
||||||
|
} elsif(@$info[0] eq 'struct in_addr') {
|
||||||
|
$raw .= pack("V".@$info[2], $self->{'data'}{@$info[1]});
|
||||||
|
} elsif(@$info[0] eq 'struct station_capabilities') {
|
||||||
|
$raw .= $self->{'data'}{@$info[1]};
|
||||||
|
} else {
|
||||||
|
printf "Unknown type: %s\n", @$info[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$parsed_count++;
|
||||||
|
}
|
||||||
|
if($parsed_count != scalar(keys %{$self->{'data'}})) {
|
||||||
|
printf "Incomplete message (type=%s (%X)) %d out of %d\n", Net::Skinny::Protocol::skinny_message_type2str($self->{'type'}), $self->{'type'},
|
||||||
|
$parsed_count, scalar(keys %{$self->{'data'}});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$self->{'raw'} = $raw;
|
||||||
|
}
|
||||||
|
return $self->{'raw'};
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -8,7 +8,6 @@ use strict;
|
|||||||
no strict "refs";
|
no strict "refs";
|
||||||
use warnings;
|
use warnings;
|
||||||
use Carp;
|
use Carp;
|
||||||
use Data::Dumper;
|
|
||||||
|
|
||||||
require Exporter;
|
require Exporter;
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
@ -69,7 +68,6 @@ sub _find {
|
|||||||
printf "Unparsed line '%s' in %s\n", $_, $struct_name;
|
printf "Unparsed line '%s' in %s\n", $_, $struct_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#print "$name: ".Dumper($struct{$name});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@sub{@_};
|
@sub{@_};
|
||||||
@ -77,6 +75,7 @@ sub _find {
|
|||||||
|
|
||||||
sub skinny_message_type2str {
|
sub skinny_message_type2str {
|
||||||
my $message_type = shift;
|
my $message_type = shift;
|
||||||
|
return "UndefinedTypeMessage" if !defined($message_type);
|
||||||
|
|
||||||
keys %const;
|
keys %const;
|
||||||
while (my ($key, $value) = each %const) {
|
while (my ($key, $value) = each %const) {
|
||||||
|
@ -221,7 +221,7 @@ char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *l
|
|||||||
"SELECT channel_uuid, line_instance "
|
"SELECT channel_uuid, line_instance "
|
||||||
"FROM skinny_active_lines "
|
"FROM skinny_active_lines "
|
||||||
"WHERE %s AND %s AND %s "
|
"WHERE %s AND %s AND %s "
|
||||||
"ORDER BY channel_uuid DESC",
|
"ORDER BY call_state, channel_uuid", /* off hook first */
|
||||||
device_condition, line_instance_condition, call_id_condition
|
device_condition, line_instance_condition, call_id_condition
|
||||||
))) {
|
))) {
|
||||||
skinny_execute_sql_callback(profile, profile->sql_mutex, sql,
|
skinny_execute_sql_callback(profile, profile->sql_mutex, sql,
|
||||||
@ -235,14 +235,22 @@ char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *l
|
|||||||
return helper.channel_uuid;
|
return helper.channel_uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SWITCH_DEBUG_RWLOCKS
|
||||||
|
switch_core_session_t * skinny_profile_perform_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id, const char *file, const char *func, int line)
|
||||||
|
#else
|
||||||
switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id)
|
switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
char *uuid;
|
char *uuid;
|
||||||
switch_core_session_t *result = NULL;
|
switch_core_session_t *result = NULL;
|
||||||
uuid = skinny_profile_find_session_uuid(profile, listener, line_instance_p, call_id);
|
uuid = skinny_profile_find_session_uuid(profile, listener, line_instance_p, call_id);
|
||||||
|
|
||||||
if(!zstr(uuid)) {
|
if(!zstr(uuid)) {
|
||||||
|
#ifdef SWITCH_DEBUG_RWLOCKS
|
||||||
|
result = switch_core_session_perform_locate(uuid, file, func, line);
|
||||||
|
#else
|
||||||
result = switch_core_session_locate(uuid);
|
result = switch_core_session_locate(uuid);
|
||||||
|
#endif
|
||||||
if(!result) {
|
if(!result) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||||
"Unable to find session %s on %s:%d, line %d\n",
|
"Unable to find session %s on %s:%d, line %d\n",
|
||||||
@ -357,7 +365,9 @@ struct skinny_line_get_state_helper {
|
|||||||
int skinny_line_get_state_callback(void *pArg, int argc, char **argv, char **columnNames)
|
int skinny_line_get_state_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||||
{
|
{
|
||||||
struct skinny_line_get_state_helper *helper = pArg;
|
struct skinny_line_get_state_helper *helper = pArg;
|
||||||
helper->call_state = atoi(argv[0]);
|
if (helper->call_state == -1) {
|
||||||
|
helper->call_state = atoi(argv[0]);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,10 +393,12 @@ uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uin
|
|||||||
}
|
}
|
||||||
switch_assert(call_id_condition);
|
switch_assert(call_id_condition);
|
||||||
|
|
||||||
|
helper.call_state = -1;
|
||||||
if ((sql = switch_mprintf(
|
if ((sql = switch_mprintf(
|
||||||
"SELECT call_state FROM skinny_active_lines "
|
"SELECT call_state FROM skinny_active_lines "
|
||||||
"WHERE device_name='%s' AND device_instance=%d "
|
"WHERE device_name='%s' AND device_instance=%d "
|
||||||
"AND %s AND %s",
|
"AND %s AND %s "
|
||||||
|
"ORDER BY call_state, channel_uuid", /* off hook first */
|
||||||
listener->device_name, listener->device_instance,
|
listener->device_name, listener->device_instance,
|
||||||
line_instance_condition, call_id_condition
|
line_instance_condition, call_id_condition
|
||||||
))) {
|
))) {
|
||||||
@ -531,6 +543,7 @@ void tech_init(private_t *tech_pvt, skinny_profile_t *profile, switch_core_sessi
|
|||||||
switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||||
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||||
tech_pvt->call_id = ++profile->next_call_id;
|
tech_pvt->call_id = ++profile->next_call_id;
|
||||||
|
tech_pvt->party_id = tech_pvt->call_id;
|
||||||
tech_pvt->profile = profile;
|
tech_pvt->profile = profile;
|
||||||
switch_core_session_set_private(session, tech_pvt);
|
switch_core_session_set_private(session, tech_pvt);
|
||||||
tech_pvt->session = session;
|
tech_pvt->session = session;
|
||||||
@ -633,16 +646,7 @@ int channel_on_hangup_callback(void *pArg, int argc, char **argv, char **columnN
|
|||||||
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_OFF);
|
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_OFF);
|
||||||
send_clear_prompt_status(listener, line_instance, call_id);
|
send_clear_prompt_status(listener, line_instance, call_id);
|
||||||
if(call_state == SKINNY_CONNECTED) { /* calling parties */
|
if(call_state == SKINNY_CONNECTED) { /* calling parties */
|
||||||
send_close_receive_channel(listener,
|
skinny_session_stop_media(helper->tech_pvt->session, listener, line_instance);
|
||||||
call_id, /* uint32_t conference_id, */
|
|
||||||
helper->tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
|
|
||||||
call_id /* uint32_t conference_id2, */
|
|
||||||
);
|
|
||||||
send_stop_media_transmission(listener,
|
|
||||||
call_id, /* uint32_t conference_id, */
|
|
||||||
helper->tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
|
|
||||||
call_id /* uint32_t conference_id2, */
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skinny_line_set_state(listener, line_instance, call_id, SKINNY_ON_HOOK);
|
skinny_line_set_state(listener, line_instance, call_id, SKINNY_ON_HOOK);
|
||||||
@ -650,7 +654,6 @@ int channel_on_hangup_callback(void *pArg, int argc, char **argv, char **columnN
|
|||||||
/* TODO: DefineTimeDate */
|
/* TODO: DefineTimeDate */
|
||||||
send_set_speaker_mode(listener, SKINNY_SPEAKER_OFF);
|
send_set_speaker_mode(listener, SKINNY_SPEAKER_OFF);
|
||||||
send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, call_id);
|
send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, call_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1229,6 +1232,9 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
|
|||||||
switch_clear_flag_locked(listener, LFLAG_RUNNING);
|
switch_clear_flag_locked(listener, LFLAG_RUNNING);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!listener_is_ready(listener)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!request) {
|
if (!request) {
|
||||||
continue;
|
continue;
|
||||||
@ -1473,7 +1479,7 @@ static switch_status_t load_skinny_config(void)
|
|||||||
}
|
}
|
||||||
profile = switch_core_alloc(profile_pool, sizeof(skinny_profile_t));
|
profile = switch_core_alloc(profile_pool, sizeof(skinny_profile_t));
|
||||||
profile->pool = profile_pool;
|
profile->pool = profile_pool;
|
||||||
profile->name = profile_name;
|
profile->name = switch_core_strdup(profile->pool, profile_name);
|
||||||
switch_mutex_init(&profile->listener_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
switch_mutex_init(&profile->listener_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
||||||
switch_mutex_init(&profile->sql_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
switch_mutex_init(&profile->sql_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
||||||
switch_mutex_init(&profile->sock_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
switch_mutex_init(&profile->sock_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
||||||
|
@ -189,7 +189,12 @@ switch_status_t skinny_profile_dump(const skinny_profile_t *profile, switch_stre
|
|||||||
switch_status_t skinny_profile_find_listener_by_device_name(skinny_profile_t *profile, const char *device_name, listener_t **listener);
|
switch_status_t skinny_profile_find_listener_by_device_name(skinny_profile_t *profile, const char *device_name, listener_t **listener);
|
||||||
switch_status_t skinny_profile_find_listener_by_device_name_and_instance(skinny_profile_t *profile, const char *device_name, uint32_t device_instance, listener_t **listener);
|
switch_status_t skinny_profile_find_listener_by_device_name_and_instance(skinny_profile_t *profile, const char *device_name, uint32_t device_instance, listener_t **listener);
|
||||||
char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
|
char * skinny_profile_find_session_uuid(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
|
||||||
|
#ifdef SWITCH_DEBUG_RWLOCKS
|
||||||
|
switch_core_session_t * skinny_profile_perform_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id, const char *file, const char *func, int line);
|
||||||
|
#define skinny_profile_find_session(profile, listener, line_instance_p, call_id) skinny_profile_perform_find_session(profile, listener, line_instance_p, call_id, __FILE__, __SWITCH_FUNC__, __LINE__)
|
||||||
|
#else
|
||||||
switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
|
switch_core_session_t * skinny_profile_find_session(skinny_profile_t *profile, listener_t *listener, uint32_t *line_instance_p, uint32_t call_id);
|
||||||
|
#endif
|
||||||
switch_status_t dump_device(skinny_profile_t *profile, const char *device_name, switch_stream_handle_t *stream);
|
switch_status_t dump_device(skinny_profile_t *profile, const char *device_name, switch_stream_handle_t *stream);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -446,19 +446,20 @@ switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *li
|
|||||||
|
|
||||||
line_instance = *line_instance_p;
|
line_instance = *line_instance_p;
|
||||||
if((nsession = skinny_profile_find_session(listener->profile, listener, line_instance_p, 0))) {
|
if((nsession = skinny_profile_find_session(listener->profile, listener, line_instance_p, 0))) {
|
||||||
switch_core_session_rwunlock(nsession);
|
|
||||||
if(skinny_line_get_state(listener, *line_instance_p, 0) == SKINNY_OFF_HOOK) {
|
if(skinny_line_get_state(listener, *line_instance_p, 0) == SKINNY_OFF_HOOK) {
|
||||||
/* Reuse existing session */
|
/* Reuse existing session */
|
||||||
*session = nsession;
|
*session = nsession;
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
skinny_session_hold_line(nsession, listener, *line_instance_p);
|
switch_core_session_rwunlock(nsession);
|
||||||
}
|
}
|
||||||
*line_instance_p = line_instance;
|
*line_instance_p = line_instance;
|
||||||
if(*line_instance_p == 0) {
|
if(*line_instance_p == 0) {
|
||||||
*line_instance_p = 1;
|
*line_instance_p = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skinny_hold_active_calls(listener);
|
||||||
|
|
||||||
skinny_line_get(listener, *line_instance_p, &button);
|
skinny_line_get(listener, *line_instance_p, &button);
|
||||||
|
|
||||||
if (!button || !button->shortname) {
|
if (!button || !button->shortname) {
|
||||||
@ -494,7 +495,11 @@ switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *li
|
|||||||
"Error Creating Session thread\n");
|
"Error Creating Session thread\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (switch_core_session_read_lock(nsession) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT,
|
||||||
|
"Error Locking Session\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(nsession),
|
if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(nsession),
|
||||||
NULL, listener->profile->dialplan,
|
NULL, listener->profile->dialplan,
|
||||||
button->shortname, button->name,
|
button->shortname, button->name,
|
||||||
@ -543,6 +548,49 @@ done:
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct skinny_session_process_dest_helper {
|
||||||
|
private_t *tech_pvt;
|
||||||
|
listener_t *listener;
|
||||||
|
uint32_t line_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
int skinny_session_process_dest_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||||
|
{
|
||||||
|
struct skinny_session_process_dest_helper *helper = pArg;
|
||||||
|
listener_t *listener = NULL;
|
||||||
|
|
||||||
|
char *device_name = argv[0];
|
||||||
|
uint32_t device_instance = atoi(argv[1]);
|
||||||
|
/* uint32_t position = atoi(argv[2]); */
|
||||||
|
uint32_t line_instance = atoi(argv[3]);
|
||||||
|
/* char *label = argv[4]; */
|
||||||
|
/* char *value = argv[5]; */
|
||||||
|
/* char *caller_name = argv[6]; */
|
||||||
|
/* uint32_t ring_on_idle = atoi(argv[7]); */
|
||||||
|
/* uint32_t ring_on_active = atoi(argv[8]); */
|
||||||
|
/* uint32_t busy_trigger = atoi(argv[9]); */
|
||||||
|
/* char *forward_all = argv[10]; */
|
||||||
|
/* char *forward_busy = argv[11]; */
|
||||||
|
/* char *forward_noanswer = argv[12]; */
|
||||||
|
/* uint32_t noanswer_duration = atoi(argv[13]); */
|
||||||
|
/* char *channel_uuid = argv[14]; */
|
||||||
|
/* uint32_t call_id = atoi(argv[15]); */
|
||||||
|
/* uint32_t call_state = atoi(argv[16]); */
|
||||||
|
|
||||||
|
skinny_profile_find_listener_by_device_name_and_instance(helper->tech_pvt->profile, device_name, device_instance, &listener);
|
||||||
|
if(listener) {
|
||||||
|
if(!strcmp(device_name, helper->listener->device_name)
|
||||||
|
&& (device_instance == helper->listener->device_instance)
|
||||||
|
&& (line_instance == helper->line_instance)) {/* the calling line */
|
||||||
|
/* nothing */
|
||||||
|
} else {
|
||||||
|
/* TODO: capture and check what should happen here*/
|
||||||
|
skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace)
|
switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace)
|
||||||
{
|
{
|
||||||
switch_channel_t *channel = NULL;
|
switch_channel_t *channel = NULL;
|
||||||
@ -555,31 +603,43 @@ switch_status_t skinny_session_process_dest(switch_core_session_t *session, list
|
|||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
|
||||||
if(!dest) {
|
if (!dest) {
|
||||||
if(append_dest == '\0') {/* no digit yet */
|
if (backspace) { /* backspace */
|
||||||
send_start_tone(listener, SKINNY_TONE_DIALTONE, 0, line_instance, tech_pvt->call_id);
|
*tech_pvt->caller_profile->destination_number++ = '\0';
|
||||||
} else {
|
}
|
||||||
if(strlen(tech_pvt->caller_profile->destination_number) == 0) {/* first digit */
|
if (append_dest != '\0' && !backspace) {/* append digit */
|
||||||
send_stop_tone(listener, line_instance, tech_pvt->call_id);
|
|
||||||
send_select_soft_keys(listener, line_instance, tech_pvt->call_id,
|
|
||||||
SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT, 0xffff);
|
|
||||||
}
|
|
||||||
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
|
tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool,
|
||||||
"%s%c", tech_pvt->caller_profile->destination_number, append_dest);
|
"%s%c", tech_pvt->caller_profile->destination_number, append_dest);
|
||||||
}
|
}
|
||||||
|
if (strlen(tech_pvt->caller_profile->destination_number) == 0) {/* no digit yet */
|
||||||
|
send_start_tone(listener, SKINNY_TONE_DIALTONE, 0, line_instance, tech_pvt->call_id);
|
||||||
|
if(backspace) {
|
||||||
|
send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK, 0xffff);
|
||||||
|
/* TODO: How to clear the screen? */
|
||||||
|
}
|
||||||
|
} else if (strlen(tech_pvt->caller_profile->destination_number) == 1) {/* first digit */
|
||||||
|
send_stop_tone(listener, line_instance, tech_pvt->call_id);
|
||||||
|
send_select_soft_keys(listener, line_instance, tech_pvt->call_id,
|
||||||
|
SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT, 0xffff);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool,
|
tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool,
|
||||||
dest);
|
dest);
|
||||||
}
|
}
|
||||||
/* TODO Number is complete -> check against dialplan */
|
/* TODO Number is complete -> check against dialplan */
|
||||||
if((strlen(tech_pvt->caller_profile->destination_number) >= 4) || dest) {
|
if ((strlen(tech_pvt->caller_profile->destination_number) >= 4) || dest) {
|
||||||
|
struct skinny_session_process_dest_helper helper = {0};
|
||||||
send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id);
|
send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id);
|
||||||
skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_PROCEED);
|
skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_PROCEED);
|
||||||
skinny_send_call_info(session, listener, line_instance);
|
skinny_send_call_info(session, listener, line_instance);
|
||||||
skinny_session_start_media(session, listener, line_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_core_session_rwunlock(session);
|
skinny_session_start_media(session, listener, line_instance);
|
||||||
|
|
||||||
|
helper.tech_pvt = tech_pvt;
|
||||||
|
helper.listener = listener;
|
||||||
|
helper.line_instance = line_instance;
|
||||||
|
skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_process_dest_callback, &helper);
|
||||||
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -603,8 +663,6 @@ switch_status_t skinny_session_ring_out(switch_core_session_t *session, listener
|
|||||||
line_instance, tech_pvt->call_id);
|
line_instance, tech_pvt->call_id);
|
||||||
skinny_send_call_info(session, listener, line_instance);
|
skinny_send_call_info(session, listener, line_instance);
|
||||||
|
|
||||||
switch_core_session_rwunlock(session);
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,16 +701,14 @@ int skinny_session_answer_callback(void *pArg, int argc, char **argv, char **col
|
|||||||
if(!strcmp(device_name, helper->listener->device_name)
|
if(!strcmp(device_name, helper->listener->device_name)
|
||||||
&& (device_instance == helper->listener->device_instance)
|
&& (device_instance == helper->listener->device_instance)
|
||||||
&& (line_instance == helper->line_instance)) {/* the answering line */
|
&& (line_instance == helper->line_instance)) {/* the answering line */
|
||||||
|
/* nothing */
|
||||||
|
} else {
|
||||||
send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id);
|
send_define_current_time_date(listener);
|
||||||
send_set_speaker_mode(listener, SKINNY_SPEAKER_ON);
|
|
||||||
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
|
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
|
||||||
skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_OFF_HOOK);
|
skinny_line_set_state(listener, line_instance, helper->tech_pvt->call_id, SKINNY_IN_USE_REMOTELY);
|
||||||
/* send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, SKINNY_KEY_SET_OFF_HOOK, 0xffff); */
|
send_select_soft_keys(listener, line_instance, helper->tech_pvt->call_id, 10, 0x0002);
|
||||||
/* display_prompt_status(listener, 0, "\200\000",
|
send_display_prompt_status(listener, 0, "\200\037", line_instance, helper->tech_pvt->call_id);
|
||||||
line_instance, tech_pvt->call_id); */
|
send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, helper->tech_pvt->call_id);
|
||||||
send_activate_call_plane(listener, line_instance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -671,6 +727,12 @@ switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t
|
|||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
|
||||||
|
send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id);
|
||||||
|
send_set_speaker_mode(listener, SKINNY_SPEAKER_ON);
|
||||||
|
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
|
||||||
|
skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_OFF_HOOK);
|
||||||
|
send_activate_call_plane(listener, line_instance);
|
||||||
|
|
||||||
helper.tech_pvt = tech_pvt;
|
helper.tech_pvt = tech_pvt;
|
||||||
helper.listener = listener;
|
helper.listener = listener;
|
||||||
helper.line_instance = line_instance;
|
helper.line_instance = line_instance;
|
||||||
@ -679,8 +741,6 @@ switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t
|
|||||||
|
|
||||||
skinny_session_start_media(session, listener, line_instance);
|
skinny_session_start_media(session, listener, line_instance);
|
||||||
|
|
||||||
switch_core_session_rwunlock(session);
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,8 +777,6 @@ switch_status_t skinny_session_start_media(switch_core_session_t *session, liste
|
|||||||
tech_pvt->call_id);
|
tech_pvt->call_id);
|
||||||
skinny_send_call_info(session, listener, line_instance);
|
skinny_send_call_info(session, listener, line_instance);
|
||||||
|
|
||||||
switch_core_session_rwunlock(session);
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,22 +792,129 @@ switch_status_t skinny_session_hold_line(switch_core_session_t *session, listene
|
|||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
|
||||||
/* TODO */
|
skinny_session_stop_media(session, listener, line_instance);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hold is not implemented yet. Hanging up the line.\n");
|
switch_ivr_hold(session, NULL, 1);
|
||||||
|
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
send_define_current_time_date(listener);
|
||||||
|
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_WINK);
|
||||||
switch_core_session_rwunlock(session);
|
skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_HOLD);
|
||||||
|
send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_ON_HOLD, 0xffff);
|
||||||
|
send_display_prompt_status(listener, 0, "\200\003",
|
||||||
|
line_instance, tech_pvt->call_id);
|
||||||
|
skinny_send_call_info(tech_pvt->session, listener, line_instance);
|
||||||
|
send_set_speaker_mode(listener, SKINNY_SPEAKER_OFF);
|
||||||
|
send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance)
|
switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance)
|
||||||
{
|
{
|
||||||
/* TODO */
|
switch_channel_t *channel = NULL;
|
||||||
|
private_t *tech_pvt = NULL;
|
||||||
|
|
||||||
|
switch_assert(session);
|
||||||
|
switch_assert(listener);
|
||||||
|
switch_assert(listener->profile);
|
||||||
|
|
||||||
|
channel = switch_core_session_get_channel(session);
|
||||||
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
|
||||||
|
skinny_hold_active_calls(listener);
|
||||||
|
send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id);
|
||||||
|
send_set_speaker_mode(listener, SKINNY_SPEAKER_ON);
|
||||||
|
send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT, 0xffff);
|
||||||
|
skinny_session_start_media(session, listener, line_instance);
|
||||||
|
switch_ivr_unhold(session);
|
||||||
|
send_set_lamp(listener, SKINNY_BUTTON_LINE, line_instance, SKINNY_LAMP_ON);
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_status_t skinny_session_stop_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance)
|
||||||
|
{
|
||||||
|
switch_channel_t *channel = NULL;
|
||||||
|
private_t *tech_pvt = NULL;
|
||||||
|
|
||||||
|
switch_assert(session);
|
||||||
|
switch_assert(listener);
|
||||||
|
switch_assert(listener->profile);
|
||||||
|
|
||||||
|
channel = switch_core_session_get_channel(session);
|
||||||
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
|
||||||
|
send_close_receive_channel(listener,
|
||||||
|
tech_pvt->call_id, /* uint32_t conference_id, */
|
||||||
|
tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
|
||||||
|
tech_pvt->call_id /* uint32_t conference_id2, */
|
||||||
|
);
|
||||||
|
send_stop_media_transmission(listener,
|
||||||
|
tech_pvt->call_id, /* uint32_t conference_id, */
|
||||||
|
tech_pvt->party_id, /* uint32_t pass_thru_party_id, */
|
||||||
|
tech_pvt->call_id /* uint32_t conference_id2, */
|
||||||
|
);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct skinny_hold_active_calls_helper {
|
||||||
|
listener_t *listener;
|
||||||
|
};
|
||||||
|
|
||||||
|
int skinny_hold_active_calls_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||||
|
{
|
||||||
|
struct skinny_hold_active_calls_helper *helper = pArg;
|
||||||
|
switch_core_session_t *session;
|
||||||
|
|
||||||
|
/* char *device_name = argv[0]; */
|
||||||
|
/* uint32_t device_instance = atoi(argv[1]); */
|
||||||
|
/* uint32_t position = atoi(argv[2]); */
|
||||||
|
uint32_t line_instance = atoi(argv[3]);
|
||||||
|
/* char *label = argv[4]; */
|
||||||
|
/* char *value = argv[5]; */
|
||||||
|
/* char *caller_name = argv[6]; */
|
||||||
|
/* uint32_t ring_on_idle = atoi(argv[7]); */
|
||||||
|
/* uint32_t ring_on_active = atoi(argv[8]); */
|
||||||
|
/* uint32_t busy_trigger = atoi(argv[9]); */
|
||||||
|
/* char *forward_all = argv[10]; */
|
||||||
|
/* char *forward_busy = argv[11]; */
|
||||||
|
/* char *forward_noanswer = argv[12]; */
|
||||||
|
/* uint32_t noanswer_duration = atoi(argv[13]); */
|
||||||
|
/* char *channel_uuid = argv[14]; */
|
||||||
|
uint32_t call_id = atoi(argv[15]);
|
||||||
|
/* uint32_t call_state = atoi(argv[16]); */
|
||||||
|
|
||||||
|
session = skinny_profile_find_session(helper->listener->profile, helper->listener, &line_instance, call_id);
|
||||||
|
|
||||||
|
if(session) {
|
||||||
|
skinny_session_hold_line(session, helper->listener, line_instance);
|
||||||
|
switch_core_session_rwunlock(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_status_t skinny_hold_active_calls(listener_t *listener)
|
||||||
|
{
|
||||||
|
struct skinny_hold_active_calls_helper helper = {0};
|
||||||
|
char *sql;
|
||||||
|
|
||||||
|
helper.listener = listener;
|
||||||
|
|
||||||
|
if ((sql = switch_mprintf(
|
||||||
|
"SELECT skinny_lines.*, channel_uuid, call_id, call_state "
|
||||||
|
"FROM skinny_active_lines "
|
||||||
|
"INNER JOIN skinny_lines "
|
||||||
|
"ON skinny_active_lines.device_name = skinny_lines.device_name "
|
||||||
|
"AND skinny_active_lines.device_instance = skinny_lines.device_instance "
|
||||||
|
"AND skinny_active_lines.line_instance = skinny_lines.line_instance "
|
||||||
|
"WHERE skinny_lines.device_name='%s' AND skinny_lines.device_instance=%d AND call_state=%d",
|
||||||
|
listener->device_name, listener->device_instance, SKINNY_CONNECTED))) {
|
||||||
|
skinny_execute_sql_callback(listener->profile, listener->profile->sql_mutex, sql, skinny_hold_active_calls_callback, &helper);
|
||||||
|
switch_safe_free(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* SKINNY BUTTONS */
|
/* SKINNY BUTTONS */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -1480,6 +1645,9 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (xroot) {
|
||||||
|
switch_xml_free(xroot);
|
||||||
|
}
|
||||||
|
|
||||||
status = SWITCH_STATUS_SUCCESS;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
@ -1789,10 +1957,26 @@ switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_
|
|||||||
message->data.soft_key_set.total_soft_key_set_count = 11;
|
message->data.soft_key_set.total_soft_key_set_count = 11;
|
||||||
|
|
||||||
/* TODO fill the set */
|
/* TODO fill the set */
|
||||||
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[0] = SOFTKEY_REDIAL;
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[0] = SOFTKEY_NEWCALL;
|
||||||
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[1] = SOFTKEY_NEWCALL;
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL;
|
||||||
|
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL;
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[2] = SOFTKEY_ENDCALL;
|
||||||
|
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[0] = SOFTKEY_BACKSPACE;
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[2] = SOFTKEY_ENDCALL;
|
||||||
|
|
||||||
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL;
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL;
|
||||||
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ENDCALL;
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[1] = SOFTKEY_HOLD;
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[2] = SOFTKEY_NEWCALL;
|
||||||
|
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ANSWER;
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[1] = SOFTKEY_ENDCALL;
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[2] = SOFTKEY_NEWCALL;
|
||||||
|
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[0] = SOFTKEY_NEWCALL;
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[1] = SOFTKEY_RESUME;
|
||||||
|
message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[2] = SOFTKEY_ENDCALL;
|
||||||
|
|
||||||
skinny_send_reply(listener, message);
|
skinny_send_reply(listener, message);
|
||||||
|
|
||||||
@ -1931,7 +2115,6 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn
|
|||||||
case SOFTKEY_NEWCALL:
|
case SOFTKEY_NEWCALL:
|
||||||
status = skinny_create_ingoing_session(listener, &line_instance, &session);
|
status = skinny_create_ingoing_session(listener, &line_instance, &session);
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
assert(tech_pvt != NULL);
|
|
||||||
|
|
||||||
skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0);
|
skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0);
|
||||||
break;
|
break;
|
||||||
@ -1942,6 +2125,13 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn
|
|||||||
status = skinny_session_hold_line(session, listener, line_instance);
|
status = skinny_session_hold_line(session, listener, line_instance);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SOFTKEY_BACKSPACE:
|
||||||
|
session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id);
|
||||||
|
|
||||||
|
if(session) {
|
||||||
|
skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SOFTKEY_ENDCALL:
|
case SOFTKEY_ENDCALL:
|
||||||
session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id);
|
session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id);
|
||||||
|
|
||||||
@ -1967,7 +2157,7 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
|
||||||
"Unknown SoftKeyEvent type while busy: %d.\n", request->data.soft_key_event.event);
|
"Unknown SoftKeyEvent type: %d.\n", request->data.soft_key_event.event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(session) {
|
if(session) {
|
||||||
@ -2002,6 +2192,11 @@ switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_mess
|
|||||||
|
|
||||||
skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0);
|
skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(session) {
|
||||||
|
switch_core_session_rwunlock(session);
|
||||||
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2037,6 +2232,11 @@ switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_mess
|
|||||||
default:
|
default:
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(session) {
|
||||||
|
switch_core_session_rwunlock(session);
|
||||||
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2118,9 +2318,13 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste
|
|||||||
}
|
}
|
||||||
switch_channel_mark_answered(channel);
|
switch_channel_mark_answered(channel);
|
||||||
|
|
||||||
switch_core_session_rwunlock(session);
|
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
|
|
||||||
|
if(session) {
|
||||||
|
switch_core_session_rwunlock(session);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2171,6 +2375,9 @@ switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny
|
|||||||
switch_channel_queue_dtmf(channel, &dtmf);
|
switch_channel_queue_dtmf(channel, &dtmf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(session) {
|
||||||
switch_core_session_rwunlock(session);
|
switch_core_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2195,9 +2402,12 @@ switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_messa
|
|||||||
channel = switch_core_session_get_channel(session);
|
channel = switch_core_session_get_channel(session);
|
||||||
|
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(session) {
|
||||||
switch_core_session_rwunlock(session);
|
switch_core_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,6 +630,8 @@ switch_status_t skinny_session_answer(switch_core_session_t *session, listener_t
|
|||||||
switch_status_t skinny_session_start_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
switch_status_t skinny_session_start_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
||||||
switch_status_t skinny_session_hold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
switch_status_t skinny_session_hold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
||||||
switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
||||||
|
switch_status_t skinny_session_stop_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance);
|
||||||
|
switch_status_t skinny_hold_active_calls(listener_t *listener);
|
||||||
|
|
||||||
void skinny_line_get(listener_t *listener, uint32_t instance, struct line_stat_res_message **button);
|
void skinny_line_get(listener_t *listener, uint32_t instance, struct line_stat_res_message **button);
|
||||||
void skinny_speed_dial_get(listener_t *listener, uint32_t instance, struct speed_dial_stat_res_message **button);
|
void skinny_speed_dial_get(listener_t *listener, uint32_t instance, struct speed_dial_stat_res_message **button);
|
||||||
|
@ -15,6 +15,7 @@ use Sys::Hostname;
|
|||||||
use Net::Skinny;
|
use Net::Skinny;
|
||||||
use Net::Skinny::Protocol qw/:all/;
|
use Net::Skinny::Protocol qw/:all/;
|
||||||
use Net::Skinny::Message;
|
use Net::Skinny::Message;
|
||||||
|
use Net::Skinny::Client;
|
||||||
|
|
||||||
#Config
|
#Config
|
||||||
my $skinny_server = hostname;
|
my $skinny_server = hostname;
|
||||||
@ -23,13 +24,13 @@ my $device_ip = 10+256*(11+256*(12+256*13)); # 10.11.12.13
|
|||||||
#======
|
#======
|
||||||
$| = 1;
|
$| = 1;
|
||||||
|
|
||||||
my $socket = Net::Skinny->new(
|
my $socket = Net::Skinny::Client->new(
|
||||||
PeerAddr => $skinny_server,
|
PeerAddr => $skinny_server,
|
||||||
PeerPort => 2000,
|
PeerPort => 2000,
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!$socket) {
|
if(!$socket) {
|
||||||
print "Unable to connect to server\n";
|
printf "Unable to connect to server %s\n", $skinny_server;
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@ -84,11 +85,8 @@ $socket->send_message(
|
|||||||
count => 2
|
count => 2
|
||||||
);
|
);
|
||||||
|
|
||||||
for(my $i = 0; $i < 1; $i++) {
|
$socket->launch_keep_alive_thread();
|
||||||
$socket->sleep(5);
|
|
||||||
$socket->send_message(KEEP_ALIVE_MESSAGE);
|
|
||||||
$socket->receive_message(); # keepaliveack
|
|
||||||
}
|
|
||||||
$socket->sleep(5);
|
$socket->sleep(5);
|
||||||
|
|
||||||
#NewCall
|
#NewCall
|
||||||
|
@ -77,6 +77,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
const char *ct = "text/html";
|
const char *ct = "text/html";
|
||||||
sofia_destination_t *dst = NULL;
|
sofia_destination_t *dst = NULL;
|
||||||
|
char *to_uri = NULL;
|
||||||
|
|
||||||
if (!to) {
|
if (!to) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n");
|
||||||
@ -99,8 +100,16 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||||||
prof = NULL;
|
prof = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strncasecmp(user, "sip:", 4)) {
|
||||||
|
to_uri = user;
|
||||||
|
}
|
||||||
|
|
||||||
if ((host = strchr(user, '@'))) {
|
if ((host = strchr(user, '@'))) {
|
||||||
*host++ = '\0';
|
if (!to_uri) {
|
||||||
|
*host++ = '\0';
|
||||||
|
} else {
|
||||||
|
host++;
|
||||||
|
}
|
||||||
if (!prof)
|
if (!prof)
|
||||||
prof = host;
|
prof = host;
|
||||||
}
|
}
|
||||||
@ -118,7 +127,8 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||||||
host = prof;
|
host = prof;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
|
|
||||||
|
if (!to_uri && !sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find user. [%s][%s]\n", user, host);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find user. [%s][%s]\n", user, host);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -152,7 +162,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||||||
switch_safe_free(fp);
|
switch_safe_free(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dst = sofia_glue_get_destination(buf))) {
|
if (!(dst = sofia_glue_get_destination(to_uri ? to_uri : buf))) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -162,7 +172,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co
|
|||||||
status = SWITCH_STATUS_SUCCESS;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
/* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
|
/* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
|
||||||
msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
|
msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
|
||||||
SIPTAG_FROM_STR(from), NUTAG_URL(contact), SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END());
|
SIPTAG_FROM_STR(from), TAG_IF(contact, NUTAG_URL(contact)), SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END());
|
||||||
nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
|
nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
|
||||||
nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END());
|
nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END());
|
||||||
|
|
||||||
|
@ -21403,21 +21403,36 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_variable_partner(void *
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, int jarg4, int jarg5) {
|
SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, int jarg4) {
|
||||||
int jresult ;
|
int jresult ;
|
||||||
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||||
char *arg2 = (char *) 0 ;
|
char *arg2 = (char *) 0 ;
|
||||||
char *arg3 = (char *) 0 ;
|
char *arg3 = (char *) 0 ;
|
||||||
switch_bool_t arg4 ;
|
switch_bool_t arg4 ;
|
||||||
switch_bool_t arg5 ;
|
|
||||||
switch_status_t result;
|
switch_status_t result;
|
||||||
|
|
||||||
arg1 = (switch_channel_t *)jarg1;
|
arg1 = (switch_channel_t *)jarg1;
|
||||||
arg2 = (char *)jarg2;
|
arg2 = (char *)jarg2;
|
||||||
arg3 = (char *)jarg3;
|
arg3 = (char *)jarg3;
|
||||||
arg4 = (switch_bool_t)jarg4;
|
arg4 = (switch_bool_t)jarg4;
|
||||||
arg5 = (switch_bool_t)jarg5;
|
result = (switch_status_t)switch_channel_export_variable_var_check(arg1,(char const *)arg2,(char const *)arg3,arg4);
|
||||||
result = (switch_status_t)switch_channel_export_variable_var_check(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5);
|
jresult = result;
|
||||||
|
return jresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_printf(void * jarg1, char * jarg2, char * jarg3) {
|
||||||
|
int jresult ;
|
||||||
|
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
|
||||||
|
char *arg2 = (char *) 0 ;
|
||||||
|
char *arg3 = (char *) 0 ;
|
||||||
|
void *arg4 = 0 ;
|
||||||
|
switch_status_t result;
|
||||||
|
|
||||||
|
arg1 = (switch_channel_t *)jarg1;
|
||||||
|
arg2 = (char *)jarg2;
|
||||||
|
arg3 = (char *)jarg3;
|
||||||
|
result = (switch_status_t)switch_channel_export_variable_printf(arg1,(char const *)arg2,(char const *)arg3,arg4);
|
||||||
jresult = result;
|
jresult = result;
|
||||||
return jresult;
|
return jresult;
|
||||||
}
|
}
|
||||||
|
@ -2904,8 +2904,13 @@ public class freeswitch {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string value, switch_bool_t var_check, switch_bool_t nolocal) {
|
public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string value, switch_bool_t var_check) {
|
||||||
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, value, (int)var_check, (int)nolocal);
|
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, value, (int)var_check);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static switch_status_t switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel channel, string varname, string fmt) {
|
||||||
|
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, fmt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10215,7 +10220,10 @@ class freeswitchPINVOKE {
|
|||||||
public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2);
|
public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2);
|
||||||
|
|
||||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")]
|
||||||
public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, int jarg4, int jarg5);
|
public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, int jarg4);
|
||||||
|
|
||||||
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_printf")]
|
||||||
|
public static extern int switch_channel_export_variable_printf(HandleRef jarg1, string jarg2, string jarg3);
|
||||||
|
|
||||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_dup")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_dup")]
|
||||||
public static extern string switch_channel_get_variable_dup(HandleRef jarg1, string jarg2, int jarg3);
|
public static extern string switch_channel_get_variable_dup(HandleRef jarg1, string jarg2, int jarg3);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user