- fxo-busy-disconnection timer for desconnection on FXO
- khomp set changes configuration - KR2GotCategory variable - Disconnection forced R2 signaling (collect call) - restricted, omits the number of origin - Option to enable/disable dial with '#' on FXS - Added KR2StrCategory - Added "khomp dump config" command - KISDNOrigTypeOfNumber, KISDNDestTypeOfNumber, KISDNOrigNumberingPlan, KISDNDestNumberingPlan, KISDNOrigPresentation - New version of commons - Updated documentation
This commit is contained in:
parent
d46ea5d346
commit
2f9357b2a7
|
@ -272,6 +272,15 @@ a FXS branch.
|
|||
<param name="fxs-bina" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Enables/disables the use of sharp (#) as an end-of-number digit on FXS
|
||||
channels for instant dialing. This does not affect special numbers which
|
||||
start on sharp, like #8 or #1.
|
||||
(default = yes)
|
||||
|
||||
<param name="fxs-sharp-dial" value="yes" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
This is the delay time to really disconnect a channel after the disconnect
|
||||
event arrive. If a connect event comes up in this interval, then the
|
||||
|
@ -312,6 +321,21 @@ you may need to set this option to 'no'.
|
|||
<param name="ignore-letter-dtmfs" value="yes"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
When there is a request to indicate busy for an incoming KFXO call, the
|
||||
ringing channel is taken off hook and then placed on hook, so it now goes
|
||||
to answered state and we can send audio throught the line.
|
||||
|
||||
If the off/on hook time interval is too short, the PSTN may ignore it, and
|
||||
keep the line in a ringing state. If it is too long, the call may be charged.
|
||||
The option below defines the delay between the line being answered and being
|
||||
disconnected, in miliseconds (from 50ms to 90000ms).
|
||||
|
||||
(default = 1250)
|
||||
|
||||
<param name="fxo-busy-disconnection" value="1250"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
For KFXO series boards, defines if audio will be allowed being sent into
|
||||
outgoing calls before it has been connected.
|
||||
|
|
|
@ -69,6 +69,6 @@
|
|||
#define COMMONS_VERSION_MINOR 1
|
||||
|
||||
#define COMMONS_AT_LEAST(x,y) \
|
||||
(COMMONS_VERSION_MAJOR > x || (COMMONS_VERSION_MAJOR == x && COMMONS_VERSION_MINOR >= y))
|
||||
((COMMONS_VERSION_MAJOR > x) || (COMMONS_VERSION_MAJOR == x && COMMONS_VERSION_MINOR >= y))
|
||||
|
||||
#endif /* _CONFIG_COMMONS_HPP_ */
|
||||
|
|
|
@ -690,6 +690,32 @@ namespace Config
|
|||
iter->second.set(object, value);
|
||||
}
|
||||
|
||||
template < typename Object >
|
||||
Messages commit(Object * const object, const std::string & name)
|
||||
{
|
||||
Messages msgs;
|
||||
|
||||
OptionMap::iterator i = _map.find(name);
|
||||
|
||||
if (i != _map.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
i->second.commit(object);
|
||||
}
|
||||
catch (Failure & e)
|
||||
{
|
||||
msgs.push_back(e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msgs.push_back(STG(FMT("unable to find option: %s") % name));
|
||||
};
|
||||
|
||||
return msgs;
|
||||
}
|
||||
|
||||
template < typename Object >
|
||||
Messages commit(Object * const object)
|
||||
{
|
||||
|
@ -718,7 +744,7 @@ namespace Config
|
|||
}
|
||||
|
||||
template < typename Object >
|
||||
bool loaded(Object * object, std::string name)
|
||||
bool loaded(Object * object, const std::string & name)
|
||||
{
|
||||
OptionMap::iterator iter = find_option(name);
|
||||
|
||||
|
|
|
@ -144,9 +144,8 @@ bool Configfile::deserialize(std::ifstream & fd)
|
|||
if (adjust(section, opt, val))
|
||||
continue;
|
||||
|
||||
_errors.push_back(STG(FMT("option '%s' does "
|
||||
"not exist or '%s' is not a valid value (at section '%s')")
|
||||
% opt % val % section->name()));
|
||||
_errors.push_back(STG(FMT("option '%s' does not exist or '%s' is not "
|
||||
"a valid value (at section '%s')") % opt % val % section->name()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -205,6 +205,15 @@ std::string K3LAPIBase::get_param(K3L_EVENT *ev, const char *name) const
|
|||
return res;
|
||||
}
|
||||
|
||||
std::string K3LAPIBase::get_param_optional(K3L_EVENT *ev, const char *name) const
|
||||
{
|
||||
std::string res;
|
||||
|
||||
(void)get_param(ev, name, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void K3LAPIBase::init(void)
|
||||
{
|
||||
if (_device_count != 0) return;
|
||||
|
|
|
@ -317,7 +317,9 @@ struct K3LAPIBase
|
|||
/* pega valores em strings de eventos */
|
||||
|
||||
KLibraryStatus get_param(K3L_EVENT *ev, const char *name, std::string &res) const;
|
||||
|
||||
std::string get_param(K3L_EVENT *ev, const char *name) const;
|
||||
std::string get_param_optional(K3L_EVENT *ev, const char *name) const;
|
||||
|
||||
/* inicializa valores em cache */
|
||||
|
||||
|
|
|
@ -52,22 +52,16 @@
|
|||
#include <refcounter.hpp>
|
||||
#include <flagger.hpp>
|
||||
|
||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
|
||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
extern "C"
|
||||
{
|
||||
#include <asterisk.h>
|
||||
#include <asterisk/localtime.h>
|
||||
#include <time.h>
|
||||
}
|
||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER)
|
||||
extern "C"
|
||||
{
|
||||
#include <callweaver/localtime.h>
|
||||
}
|
||||
#elif defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
extern "C"
|
||||
{
|
||||
#include <time.h>
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
|
||||
|
@ -424,77 +418,26 @@ struct Logger
|
|||
|
||||
if (opt._flags[Option::DATETIME])
|
||||
{
|
||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
|
||||
#if ASTERISK_AT_LEAST(1,6,0)
|
||||
struct timeval tv;
|
||||
struct ast_tm lt;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
#else
|
||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
time_t tv;
|
||||
struct tm lt;
|
||||
|
||||
time (&tv);
|
||||
#endif
|
||||
|
||||
#if ASTERISK_AT_LEAST(1,4,5)
|
||||
ast_localtime (&tv, <, NULL);
|
||||
#else
|
||||
localtime_r (&tv, <);
|
||||
#endif
|
||||
|
||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
time_t tv;
|
||||
struct tm lt;
|
||||
|
||||
time (&tv);
|
||||
|
||||
localtime_r (&tv, <);
|
||||
#endif
|
||||
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d] ")
|
||||
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour
|
||||
% lt.tm_min % lt.tm_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (opt._flags[Option::DATETIMEMS])
|
||||
{
|
||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK)
|
||||
#if ASTERISK_AT_LEAST(1,6,0)
|
||||
struct timeval tv;
|
||||
struct ast_tm lt;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
#else
|
||||
#if defined(COMMONS_LIBRARY_USING_ASTERISK) || defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
time_t tv;
|
||||
struct tm lt;
|
||||
|
||||
time (&tv);
|
||||
#endif
|
||||
|
||||
#if ASTERISK_AT_LEAST(1,4,5)
|
||||
ast_localtime (&tv, <, NULL);
|
||||
#else
|
||||
localtime_r (&tv, <);
|
||||
#endif
|
||||
|
||||
#if ASTERISK_AT_LEAST(1,6,0)
|
||||
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
||||
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
|
||||
% lt.tm_sec % (tv.tv_usec / 1000));
|
||||
#else
|
||||
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
||||
% (lt.tm_year % 100) % (lt.tm_mon + 1) % lt.tm_mday % lt.tm_hour % lt.tm_min
|
||||
% lt.tm_sec % (tv * 1000));
|
||||
#endif
|
||||
|
||||
#elif defined(COMMONS_LIBRARY_USING_CALLWEAVER) || defined(COMMONS_LIBRARY_USING_FREESWITCH)
|
||||
time_t tv;
|
||||
struct tm lt;
|
||||
|
||||
time (&tv);
|
||||
|
||||
localtime_r (&tv, <);
|
||||
|
||||
out_msg += STG(FMT("[%02d-%02d-%02d %02d:%02d:%02d:%04d] ")
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
/* This struct uses static polymorphism, and derived classes should implement *
|
||||
* the "lock/trylock/unlock()" methods for correct code compilation. *
|
||||
* The base class also features reference counting, so derived classes should *
|
||||
* implement the "unreference()" method for releasing resources. */
|
||||
* implement the "unreference_data()" method for releasing resources. */
|
||||
|
||||
template < typename Implementor >
|
||||
struct SimpleLockCommon: COUNTER_SUPER( SimpleLockCommon < Implementor > )
|
||||
|
@ -95,7 +95,7 @@ struct SimpleLockCommon: COUNTER_SUPER( SimpleLockCommon < Implementor > )
|
|||
protected:
|
||||
void unreference(void)
|
||||
{
|
||||
static_cast<Implementor*>(this)->unreference();
|
||||
static_cast<Implementor*>(this)->unreference_data();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ struct SimpleLockBasic: public SimpleLockCommon < Implementor >
|
|||
/* do nothing */
|
||||
};
|
||||
|
||||
void unreference()
|
||||
void unreference_data()
|
||||
{
|
||||
switch_mutex_destroy(_mutex);
|
||||
|
||||
|
|
|
@ -2505,9 +2505,11 @@ std::string Verbose::command(const int32 cmd_code, const int32 dev_idx, const in
|
|||
case VerboseTraits::K_CM_LOG_REQUEST:
|
||||
case VerboseTraits::K_CM_LOG_CREATE_DISPATCHER:
|
||||
case VerboseTraits::K_CM_LOG_DESTROY_DISPATCHER:
|
||||
|
||||
case VerboseTraits::K_CM_PING:
|
||||
#endif
|
||||
//#if K3L_AT_LEAST(2,1,0)
|
||||
// case VerboseTraits::K_CM_LOG_UPDATE:
|
||||
//#endif
|
||||
return show(buf, commandName(code), Target(NONE));
|
||||
#if K3L_AT_LEAST(2,1,0)
|
||||
case VerboseTraits::K_CM_START_FAX_TX:
|
||||
|
|
|
@ -29,7 +29,10 @@
|
|||
</p>
|
||||
<pre><b>Sintaxe:</b> <param name="..." value="..."/>
|
||||
</pre>
|
||||
<ul><li><b>dialplan</b>: Nome do módulo de <i>dialplan</i> em uso.
|
||||
<p><br />
|
||||
</p>
|
||||
<ul><li><b>accountcode</b>: Define o account code padrão para chamadas no Endpoint. Esta opção pode ser qualquer string alfanumérica;
|
||||
</li><li><b>dialplan</b>: Nome do módulo de <i>dialplan</i> em uso.
|
||||
</li><li><b>auto-fax-adjustment</b>: Ativa ("yes") ou desativa ("no") o ajuste automático do canal (desabilitar o cancelador de eco e a supressão DTMF) ao detectar tom de FAX;
|
||||
</li><li><b>auto-gain-control</b>: Ativa ("yes") ou desativa ("no") a ativação do controle automático de ganho (AGC) pelo Endpoint;
|
||||
</li><li><b>context-digital</b>: Contexto de entrada para ligações em placas digitais (o padrão é "khomp-DD-LL", onde "DD" será substituído, no momento da ligação, pelo número do dispositivo, "LL" pelo número do link, "CCC" pelo número do canal e "SSSS" pelo número serial do dispositivo);
|
||||
|
@ -49,6 +52,7 @@
|
|||
</li><li><b>fxs-global-orig</b>: Número inicial para numeração seqüencial de ramais das placas <b>KFXS</b> que não estiverem listadas na seção <b><fxs-branches></b> (a numeração segue ordem crescente por número da placa e número do canal físico) (o padrão é "0");
|
||||
</li><li><b>fxs-co-dialtone</b>: Seqüências de números, separados por vírgula, que disparam um tom contínuo (de central pública) em ramais FXS (ex: "0,99" faz com que, ao discar "0" ou "99", o usuário receba o tom de linha contínuo) (o padrão é vazio);
|
||||
</li><li><b>fxs-bina</b>: Quando ativada ("yes"), ligações para ramais FXS enviarão os dígitos correspondentes ao telefone de origem em sinalização BINA DTMF (o valor padrão é "no");
|
||||
</li><li><b>language</b>: Define idioma para ligações nas placas Khomp;
|
||||
</li><li><b>ignore-letter-dtmfs</b>: Define se o canal deve ignorar DTMFs incomuns detectados pela placa (A, B, C e D). Entretanto, se você necessita passar esses dígitos pela placa, você deve ajustar esta opção para "no" (o valor padrão é "yes");
|
||||
</li><li><b>input-volume</b>: Define o volume de entrada das ligações, varia de -10 a +10 ;
|
||||
</li><li><b>kommuter-activation</b>: Define se a ativação de dispositivos kommuter encontrados no sistema será feita de forma automática ("auto"), ou de forma manual ("manual") pelo usuário, através do comando "khomp kommuter on/off";
|
||||
|
@ -119,6 +123,8 @@
|
|||
<ul><li>context;
|
||||
</li><li>input-volume;
|
||||
</li><li>output-volume;
|
||||
</li><li>language;
|
||||
</li><li>accountcode;
|
||||
</li><li>calleridnum;
|
||||
</li><li>calleridname;
|
||||
</li><li>flash-to-digits.
|
||||
|
@ -1011,7 +1017,7 @@ install: ** for knowing how to proceed with the installation. **
|
|||
<p>Este configurador, por sua vez, mostra todas as opções possíveis de configuração da placa. Os parâmetros que não forem configurados assumem os valores padrão automaticamente, e são compatíveis com a maior parte dos sistemas. Maiores detalhes sobre este programa podem ser obtidos na seção de número '2'.
|
||||
</p><p><br />
|
||||
</p>
|
||||
<ul><li> <b>IMPORTANTE</b>: Para o FreeSWITCH iniciar, é preciso que a placa da khomp esteja configurada e todos módulos estejam rodando (conforme mostrado acima). <b>Caso a placa não esteja configurada, o FreeSWITCH não iniciará</b>.<br /><br />Se você deseja rodar o sistema sem a placa da Khomp, é preciso configurar o FreeSWITCH para ele não carregar o módulo da Khomp. Para isso, abra o arquivo "<i>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</i>", e comente a linha que carrega o módulo:<br />
|
||||
<ul><li> <b>IMPORTANTE</b>: Para o FreeSWITCH iniciar, é preciso que a placa da khomp esteja configurada e todos módulos estejam rodando (conforme mostrado acima). <br /><br />Se você deseja rodar o sistema sem a placa da Khomp, é preciso configurar o FreeSWITCH para ele não carregar o módulo da Khomp. Para isso, abra o arquivo <b>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</b>, e comente a linha que carrega o módulo:<br />
|
||||
</li></ul>
|
||||
<pre>
|
||||
<!-- <load module="mod_khomp" /> -->
|
||||
|
@ -1080,4 +1086,6 @@ Por fim, para carregar o servidor de processos, basta executar o seguinte comand
|
|||
O <i>script</i> <b>/etc/init.d/khompdrv</b> é responsável por carregar os módulos <i>kpci9030.ko</i> e <i>kpex8311.ko</i> no <i>kernel</i>, que deve ser realizada automaticamente na inicialização do sistema. Em caso de problemas, verifique a seção <a href="#Solu.C3.A7.C3.A3o_de_problemas" title="">Solução de problemas</a>.
|
||||
<br />
|
||||
</p><p><br />
|
||||
Para mais detalhes: <a href="http://www.khomp.com.br" class="external free" title="http://www.khomp.com.br" rel="nofollow">http://www.khomp.com.br</a>
|
||||
</p><p><br />
|
||||
</p></body></html>
|
Binary file not shown.
|
@ -6,7 +6,7 @@
|
|||
<a name="Utilizando_o_Endpoint_da_Khomp" id="Utilizando_o_Endpoint_da_Khomp"></a><h1> <span class="mw-headline"> Utilizando o <i>Endpoint</i> da Khomp </span></h1>
|
||||
<p>Após a instalação e inicialização dos serviços necessários pela Khomp, o FreeSWITCH já pode ser carregado ou inicializado.
|
||||
</p>
|
||||
<ul><li> <b>AVISO</b>: É imprescindível que o <b>FreeSWITCH</b> não seja executado utilizando a opção que desabilita o escalonamento em tempo real (-nort), <b>especialmente</b> se este estiver sendo executado lado-a-lado com servidores <i>web</i> ou servidores de banco de dados. Não realizar este procedimento pode resultar em perda de qualidade do áudio, gerando um sério comprometimento no andamento das ligações do sistema.
|
||||
<ul><li> <b>AVISO</b>: Evite usar a opção <b>-nort</b>, pois ela desabilita escalonamento em tempo real, é imprescindível que o <b>FreeSWITCH</b> esteja utilizando o escalonamento em tempo real, especialmente se este estiver sendo executado lado-a-lado com servidores <i>web</i> ou servidores de banco de dados. Utilizar a opção <b>-nort</b> pode resultar em perda de qualidade do áudio, gerando um sério comprometimento nas ligações do sistema.
|
||||
</li></ul>
|
||||
<p>Após a inicialização do FreeSWITCH, pode-se verificar se o módulo da Khomp foi carregado através do seguinte comando:<br />
|
||||
</p>
|
||||
|
|
Binary file not shown.
|
@ -6,10 +6,9 @@
|
|||
<a name="Using_the_Khomp_Endpoint" id="Using_the_Khomp_Endpoint"></a><h1> <span class="mw-headline"> Using the Khomp Endpoint </span></h1>
|
||||
<p>After installation and startup services required by Khomp, FreeSWITCH can now be loaded or initialized.
|
||||
</p>
|
||||
<ul><li><b>WARNING</b>: It is imperative that the<b>FreeSWITCH</b> is not executed using the option that disables the escalation in real time (-nort), <b>especially</b> if this is running side-by server-side with web servers or database. Failure to do so may result in loss of audio quality, causing a serious commitment on the progress of system connections.
|
||||
<ul><li><b>WARNING</b>: Avoid using the <b>-nort</b>, as it disables real-time scheduling, it is essential that the <b>FreeSwitch</b> are using real-time scheduling, especially if it is running side-by-side with <i>web</i> servers or database . Use the <b>-nort</b> may result in loss of audio quality, causing a serious commitment on the progress of system connections.
|
||||
</li></ul>
|
||||
<p>After initialization of FreeSWITCH, you can verify that the module was loaded Khomp through the following command: <br />
|
||||
</p><p><br />
|
||||
</p>
|
||||
<pre> freeswitch@hostname> module_exists mod_khomp
|
||||
</pre>
|
||||
|
|
Binary file not shown.
|
@ -30,7 +30,8 @@ If you need to set advanced parameters of the board and/or signaling, the progra
|
|||
</p>
|
||||
<pre><b>Sintaxe:</b> <param name="..." value="..."/>
|
||||
</pre>
|
||||
<ul><li><b>dialplan</b>: Name of the dialplan module in use.
|
||||
<ul><li><b>accountcode</b>: Sets the default account code to calls in the Endpoint. This option can be any alphanumeric string;
|
||||
</li><li><b>dialplan</b>: Name of the dialplan module in use.
|
||||
</li><li><b>auto-fax-adjustment</b>: Enable ("yes") or disables ("no") the automatic adjustment of the channel (disable the echo canceller and the suppression DTMF) tone to detect FAX (local option) ;
|
||||
</li><li><b>auto-gain-control</b>:Enable ("yes") or disables ("no") the activation of the automatic gain control (AGC) by the Endpoint (local option);
|
||||
</li><li><b>context-digital</b>: Context for incoming connections on digital boards (the default is "khomp-DD-LL", where "DD" will be replaced at the time of connection by the device number, "LL" by the number of the link, "CCC" by channel number and "SSSS" for the device serial number);
|
||||
|
@ -54,6 +55,7 @@ If you need to set advanced parameters of the board and/or signaling, the progra
|
|||
</li><li><b>input-volume</b>: Sets the volume gain for incoming audio (entering the board), from -10 to +10 (local option);
|
||||
</li><li><b>kommuter-activation</b>: Sets whether to activate devices kommuter found in the system will be done automatically ("auto") by the channel, or manually ("manual") by the user through the command "khomp kommuter on/off"
|
||||
</li><li><b>kommuter-timeout</b>: Sets the timeout (in seconds) for initializing the kommuter devices. If this timeout is reached without receiving notification of the channel, the devices will switch back to "off" condition. The minimum value is "0", where the links will always remain switched "on", and the maximum is "255";
|
||||
</li><li><b>language</b>: Set language to Khomp board calls;
|
||||
</li><li><b>log-to-console</b>: Set log messages to be printed on the console;
|
||||
</li><li><b>log-to-disk</b> (old "log"): Set log messages to be saved to disk;
|
||||
</li><li><b>out-of-band-DTMF</b> (former <b>dtmfsuppression</b>): Activate ("yes") or disables ("no") the removal and DTMF sending these out-of-band (local option);
|
||||
|
@ -125,6 +127,8 @@ For details, please refer to the configuration file for examples.
|
|||
</li><li>output-volume;
|
||||
</li><li>calleridnum;
|
||||
</li><li>calleridname;
|
||||
</li><li>language;
|
||||
</li><li>accountcode;
|
||||
</li><li>flash-to-digits.
|
||||
</li></ul>
|
||||
<p>Each option is separated from each other by a pipe "|" or a slash "/" and defined after the colon ":". Example:
|
||||
|
@ -1018,7 +1022,7 @@ install: ** for knowing how to proceed with the installation. **
|
|||
</pre>
|
||||
<p>This configurator, in turn, shows all possible options for card configuration. The parameters that are not configured automatically assume the default values, and are compatible with most systems. More details about this program can be obtained from the section number '2 '.
|
||||
</p>
|
||||
<ul><li> <b>ATTENTION'<i>: To start FreeSWITCH®, it is necessary that the board is configured Khomp and all modules are running (as shown above). </i></b><i>If the card is not configured, FreeSWITCH will not start<b>.<br /> <br /> If you want to run the system without the board Khomp, you need to configure FreeSWITCH for it does not load the module Khomp. To do this, open the "</b></i><b>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</b> and comment the line:<br />
|
||||
<ul><li> <b>ATTENTION</b>: To start FreeSWITCH®, it is necessary that the Khomp board is configured and all modules are running (as shown above). <br /> <br /> If you want to run the system without the Khomp board, you need to configure FreeSWITCH for it does not load the module Khomp. To do this, open the <b>/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml</b> and comment the line:<br />
|
||||
</li></ul>
|
||||
<pre>
|
||||
<!-- <load module="mod_khomp" /> -->
|
||||
|
@ -1060,7 +1064,7 @@ install: ** for knowing how to proceed with the installation. **
|
|||
<br />
|
||||
</p>
|
||||
<a name="Ap.C3.AAndice" id="Ap.C3.AAndice"></a><h1> <span class="mw-headline"> Apêndice </span></h1>
|
||||
<p>Nesta seção, encontram-se informações úteis sobre o Endpoint e componentes relacionados.
|
||||
<p>This section presents useful informations about Endpoint and related components.
|
||||
</p>
|
||||
<a name="Arrangement_of_installed_files" id="Arrangement_of_installed_files"></a><h2> <span class="mw-headline"> Arrangement of installed files </span></h2>
|
||||
<p>The directories created/modified in this facility are:
|
||||
|
@ -1084,5 +1088,6 @@ install: ** for knowing how to proceed with the installation. **
|
|||
</pre>
|
||||
<p>The script <b>/etc/init.d/khompdrv</b> is responsible for loading modules <b>kpci9030.ko</b> and <b>kpex8311.ko</b> in the kernel, which should be carried out automatically at system startup. In case of problems, check the <a href="#Troubleshooting" title="">Troubleshooting</a> section.
|
||||
</p><p><br />
|
||||
</p><p>For more details: <a href="http://www.khomp.com.br" class="external free" title="http://www.khomp.com.br" rel="nofollow">http://www.khomp.com.br</a>
|
||||
</p><p><br />
|
||||
</p></body></html>
|
Binary file not shown.
|
@ -733,17 +733,21 @@ struct Cli
|
|||
options.push_back("fxs-global-orig");
|
||||
options.push_back("fxs-co-dialtone");
|
||||
options.push_back("fxs-bina");
|
||||
options.push_back("fxs-sharp-dial");
|
||||
options.push_back("disconnect-delay");
|
||||
options.push_back("delay-ringback-co");
|
||||
options.push_back("delay-ringback-pbx");
|
||||
options.push_back("ignore-letter-dtmfs");
|
||||
options.push_back("fxo-send-pre-audio");
|
||||
options.push_back("fxo-busy-disconnection");
|
||||
options.push_back("fxs-digit-timeout");
|
||||
options.push_back("drop-collect-call");
|
||||
options.push_back("kommuter-activation");
|
||||
options.push_back("kommuter-timeout");
|
||||
options.push_back("user-transfer-digits");
|
||||
options.push_back("flash-to-digits");
|
||||
options.push_back("accountcode");
|
||||
options.push_back("audio-packet-length");
|
||||
|
||||
brief = "Get configuration options in the Khomp channel.";
|
||||
|
||||
|
@ -821,17 +825,21 @@ struct Cli
|
|||
options.push_back("fxs-global-orig");
|
||||
options.push_back("fxs-co-dialtone");
|
||||
options.push_back("fxs-bina");
|
||||
options.push_back("fxs-sharp-dial");
|
||||
options.push_back("disconnect-delay");
|
||||
options.push_back("delay-ringback-co");
|
||||
options.push_back("delay-ringback-pbx");
|
||||
options.push_back("ignore-letter-dtmfs");
|
||||
options.push_back("fxo-send-pre-audio");
|
||||
options.push_back("fxo-busy-disconnection");
|
||||
options.push_back("fxs-digit-timeout");
|
||||
options.push_back("drop-collect-call");
|
||||
options.push_back("kommuter-activation");
|
||||
options.push_back("kommuter-timeout");
|
||||
options.push_back("user-transfer-digits");
|
||||
options.push_back("flash-to-digits");
|
||||
options.push_back("accountcode");
|
||||
options.push_back("audio-packet-length");
|
||||
|
||||
brief = "Ajust configuration options in the Khomp channel.";
|
||||
|
||||
|
@ -933,6 +941,36 @@ struct Cli
|
|||
bool execute(int argc, char *argv[]);
|
||||
} KhompRevision;
|
||||
|
||||
/* khomp dump config */
|
||||
static struct _KhompDumpConfig : public Command
|
||||
{
|
||||
_KhompDumpConfig()
|
||||
{
|
||||
complete_name = "dump config";
|
||||
brief = "Dump configuration values on screen.";
|
||||
|
||||
usage = \
|
||||
"\nUsage: khomp dump config\n\n" \
|
||||
"Dump configuration values loaded on memory.\n ";
|
||||
|
||||
_commands.push_back(this);
|
||||
}
|
||||
|
||||
/* just to hide unavaible options */
|
||||
bool removeUnavaible(const std::string &s)
|
||||
{
|
||||
if(s == "atxfer" || s == "blindxfer" || s == "callgroup" ||
|
||||
s == "mohclass" || s == "native-bridge" || s == "recording" ||
|
||||
s == "record-prefix" || s == "transferdigittimeout" ||
|
||||
s == "pickupgroup" || s == "has-ctbus" ||
|
||||
s == "user-transfer-digits")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool execute(int argc, char *argv[]);
|
||||
} KhompDumpConfig;
|
||||
|
||||
/* khomp send command */
|
||||
static struct _KhompSendCommand : public Command
|
||||
{
|
||||
|
|
|
@ -231,6 +231,8 @@ struct KVoIPSeize
|
|||
|
||||
#define CM_USER_INFORMATION 0x0F
|
||||
|
||||
#define CM_USER_INFORMATION_EX 0x2B
|
||||
|
||||
#define CM_VOIP_SEIZE 0x23
|
||||
|
||||
|
||||
|
@ -369,6 +371,8 @@ struct KVoIPSeize
|
|||
|
||||
#define EV_USER_INFORMATION 0x0F
|
||||
|
||||
#define EV_USER_INFORMATION_EX 0x1D
|
||||
|
||||
#define EV_DIALED_DIGIT 0x10
|
||||
|
||||
#define EV_SIP_REGISTER_INFO 0x11
|
||||
|
@ -713,6 +717,8 @@ enum KH100CtbusFreq
|
|||
#define CM_START_CADENCE 0xA1
|
||||
|
||||
#define CM_STOP_CADENCE 0xA2
|
||||
|
||||
#define CM_SET_INPUT_MODE 0xA3
|
||||
#if !defined KR2D_H
|
||||
#define KR2D_H
|
||||
|
||||
|
@ -925,6 +931,7 @@ enum KSignGroupII
|
|||
#ifndef _KISDN_H_
|
||||
#define _KISDN_H_
|
||||
#define KMAX_USER_USER_LEN 32
|
||||
#define KMAX_USER_USER_EX_LEN 254
|
||||
#define KMAX_SUBADRESS_INFORMATION_LEN 20
|
||||
|
||||
enum KQ931Cause
|
||||
|
@ -1845,6 +1852,12 @@ struct KUserInformation
|
|||
int32 UserInfoLength;
|
||||
byte UserInfo[ KMAX_USER_USER_LEN ];
|
||||
};
|
||||
struct KUserInformationEx
|
||||
{
|
||||
int32 ProtocolDescriptor;
|
||||
int32 UserInfoLength;
|
||||
byte UserInfo[ KMAX_USER_USER_EX_LEN ];
|
||||
};
|
||||
struct KISDNSubaddressInformation
|
||||
{
|
||||
KQ931TypeOfSubaddress TypeOfSubaddress;
|
||||
|
|
|
@ -305,8 +305,6 @@ struct KhompPvt
|
|||
{
|
||||
try
|
||||
{
|
||||
//std::string type((name == "input_volume")?"input":"output");
|
||||
|
||||
int i = Strings::tolong(value);
|
||||
|
||||
if (i < -10 || i > 10)
|
||||
|
@ -614,6 +612,7 @@ public:
|
|||
|
||||
virtual bool indicateRinging();
|
||||
virtual bool sendDtmf(std::string digit);
|
||||
virtual void cleanupIndications(bool force);
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
@ -849,7 +848,31 @@ public:
|
|||
if(!name)
|
||||
return NULL;
|
||||
|
||||
return switch_core_get_variable(name);
|
||||
#if SWITCH_LESS_THAN(1,0,6)
|
||||
const char * tmp = switch_core_get_variable(name);
|
||||
|
||||
if(!tmp) return NULL;
|
||||
|
||||
const char * val = strdup(tmp);
|
||||
|
||||
return val;
|
||||
#else
|
||||
return switch_core_get_variable_dup(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void freeFSGlobalVar(const char ** val)
|
||||
{
|
||||
if(!val || !*val) return;
|
||||
|
||||
#if SWITCH_LESS_THAN(1,0,6)
|
||||
free((void *)*val);
|
||||
*val = NULL;
|
||||
#else
|
||||
char * v = (char *)*val;
|
||||
switch_safe_free(v);
|
||||
*val=NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool mixer(const char *file, const char *func, int line,
|
||||
|
|
|
@ -138,7 +138,7 @@ struct KhompPvtFXO: public KhompPvt
|
|||
|
||||
TriState _var_fax_adjust;
|
||||
|
||||
//ChanTimer::Index _idx_disconnect;
|
||||
ChanTimer::Index _busy_disconnect;
|
||||
};
|
||||
/******************************************************************************/
|
||||
KhompPvtFXO(K3LAPIBase::GenericTarget & target) : KhompPvt(target)
|
||||
|
@ -240,6 +240,7 @@ struct KhompPvtFXO: public KhompPvt
|
|||
bool autoGainControl(bool enable);
|
||||
void setAnswerInfo(int answer_info);
|
||||
bool indicateBusyUnlocked(int cause, bool sent_signaling = false);
|
||||
static void busyDisconnect(Board::KhompPvt * pvt);
|
||||
void reportFailToReceive(int fail_code);
|
||||
bool validContexts(MatchExtension::ContextListType & contexts,
|
||||
std::string extra_context = "");
|
||||
|
@ -266,13 +267,20 @@ struct KhompPvtFXO: public KhompPvt
|
|||
|
||||
virtual bool cleanup(CleanupType type = CLN_HARD)
|
||||
{
|
||||
//Board::board(_target.device)->_timers.del(callFXO()->_idx_disconnect);
|
||||
//callFXO()->_idx_disconnect.reset();
|
||||
try
|
||||
{
|
||||
Board::board(_target.device)->_timers.del(callFXO()->_busy_disconnect);
|
||||
}
|
||||
catch (K3LAPITraits::invalid_device & err)
|
||||
{
|
||||
LOG(ERROR, PVT_FMT(target(), "Unable to get device: %d!") % err.device);
|
||||
}
|
||||
|
||||
call()->_flags.clear(Kflags::CALL_WAIT_SEIZE);
|
||||
call()->_flags.clear(Kflags::EARLY_RINGBACK);
|
||||
|
||||
_transfer->clear();
|
||||
callFXO()->_busy_disconnect.reset();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
@ -312,6 +320,16 @@ struct KhompPvtFXO: public KhompPvt
|
|||
|
||||
// static void delayedDisconnect(Board::KhompPvt * pvt);
|
||||
|
||||
void cleanupIndications(bool force)
|
||||
{
|
||||
if (call()->_indication == INDICA_BUSY && !force)
|
||||
{
|
||||
DBG(FUNC, PVT_FMT(_target, "skipping busy indication cleanup on FXO channel."));
|
||||
return;
|
||||
}
|
||||
|
||||
KhompPvt::cleanupIndications(force);
|
||||
}
|
||||
};
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -272,24 +272,39 @@ struct KhompPvtISDN: public KhompPvtE1
|
|||
|
||||
bool process(std::string name, std::string value = "")
|
||||
{
|
||||
if (name == "uui")
|
||||
if ((name == "uui" ) || (name == "uui_ex"))
|
||||
{
|
||||
Strings::vector_type values;
|
||||
Strings::tokenize(value, values, "#", 2);
|
||||
|
||||
try
|
||||
if(value.find("#") != std::string::npos)
|
||||
{
|
||||
std::string uui_proto_s = values[0];
|
||||
std::string uui_data_s = values[1];
|
||||
Strings::vector_type values;
|
||||
Strings::tokenize(value, values, "#", 2);
|
||||
|
||||
_uui_descriptor = Strings::toulong(uui_proto_s);
|
||||
_uui_information.append(uui_data_s);
|
||||
try
|
||||
{
|
||||
std::string uui_proto_s = values[0];
|
||||
_uui_extended = (name == "uui_ex");
|
||||
_uui_descriptor = Strings::toulong(uui_proto_s);
|
||||
_uui_information.clear();
|
||||
|
||||
DBG(FUNC, FMT("uui adjusted (%s, '%s')!") % uui_proto_s.c_str() % uui_data_s.c_str());
|
||||
for (unsigned int i = 0; i < values[1].size(); ++i)
|
||||
_uui_information += STG(FMT("%02hhx") % ((unsigned char)values[1][i]));
|
||||
|
||||
DBG(FUNC, FMT("uui adjusted (ex=%s, proto=%s, data='%s')!")
|
||||
% (_uui_extended ? "true" : "false")
|
||||
% uui_proto_s.c_str()
|
||||
% _uui_information.c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG(ERROR, FMT("invalid %s protocol descriptor: '%s' is not a number.")
|
||||
% (_uui_extended ? "uui_ex" : "uui")
|
||||
% value.c_str());
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
else
|
||||
{
|
||||
LOG(ERROR, FMT("invalid uui protocol descriptor: '%s' is not a number.") % value.c_str());
|
||||
LOG(ERROR, FMT("invalid %s protocol descriptor, need a '#'.")
|
||||
% (_uui_extended ? "uui_ex" : "uui"))
|
||||
}
|
||||
}
|
||||
else if (name == "usr_xfer")
|
||||
|
@ -306,6 +321,7 @@ struct KhompPvtISDN: public KhompPvtE1
|
|||
|
||||
bool clear()
|
||||
{
|
||||
_uui_extended = false;
|
||||
_uui_descriptor = -1;
|
||||
_uui_information.clear();
|
||||
_isdn_cause = -1;
|
||||
|
@ -322,6 +338,7 @@ struct KhompPvtISDN: public KhompPvtE1
|
|||
long int _uui_descriptor;
|
||||
std::string _uui_information;
|
||||
long int _isdn_cause;
|
||||
bool _uui_extended;
|
||||
|
||||
/* what should we dial to trigger an user-signaled transfer? */
|
||||
/* used for xfer on user signaling */
|
||||
|
@ -330,6 +347,13 @@ struct KhompPvtISDN: public KhompPvtE1
|
|||
std::string _digits_buffer;
|
||||
std::string _qsig_number;
|
||||
|
||||
/* isdn information */
|
||||
std::string _isdn_orig_type_of_number;
|
||||
std::string _isdn_orig_numbering_plan;
|
||||
std::string _isdn_dest_type_of_number;
|
||||
std::string _isdn_dest_numbering_plan;
|
||||
std::string _isdn_orig_presentation;
|
||||
|
||||
};
|
||||
/******************************************************************************/
|
||||
KhompPvtISDN(K3LAPIBase::GenericTarget & target) : KhompPvtE1(target)
|
||||
|
@ -429,12 +453,29 @@ struct KhompPvtISDN: public KhompPvtE1
|
|||
|
||||
std::string descriptor = STG(FMT("%d") % callISDN()->_uui_descriptor);
|
||||
|
||||
setFSChannelVar("KUserInfoExtended", (callISDN()->_uui_extended ? "true" : "false"));
|
||||
setFSChannelVar("KUserInfoDescriptor", descriptor.c_str());
|
||||
setFSChannelVar("KUserInfoData", callISDN()->_uui_information.c_str());
|
||||
|
||||
callISDN()->_uui_extended = false;
|
||||
callISDN()->_uui_descriptor = -1;
|
||||
callISDN()->_uui_information.clear();
|
||||
}
|
||||
|
||||
if (!callISDN()->_isdn_orig_type_of_number.empty())
|
||||
setFSChannelVar("KISDNOrigTypeOfNumber", callISDN()->_isdn_orig_type_of_number.c_str());
|
||||
|
||||
if (!callISDN()->_isdn_dest_type_of_number.empty())
|
||||
setFSChannelVar("KISDNDestTypeOfNumber", callISDN()->_isdn_dest_type_of_number.c_str());
|
||||
|
||||
if (!callISDN()->_isdn_orig_numbering_plan.empty())
|
||||
setFSChannelVar("KISDNOrigNumberingPlan", callISDN()->_isdn_orig_numbering_plan.c_str());
|
||||
|
||||
if (!callISDN()->_isdn_dest_numbering_plan.empty())
|
||||
setFSChannelVar("KISDNDestNumberingPlan", callISDN()->_isdn_dest_numbering_plan.c_str());
|
||||
|
||||
if (!callISDN()->_isdn_orig_presentation.empty())
|
||||
setFSChannelVar("KISDNOrigPresentation", callISDN()->_isdn_orig_presentation.c_str());
|
||||
}
|
||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
||||
{
|
||||
|
@ -444,8 +485,33 @@ struct KhompPvtISDN: public KhompPvtE1
|
|||
KhompPvtE1::setSpecialVariables();
|
||||
}
|
||||
|
||||
Transfer<CallISDN, false> * _transfer;
|
||||
virtual void getSpecialVariables()
|
||||
{
|
||||
try
|
||||
{
|
||||
const char * isdn_orig_type = getFSChannelVar("KISDNOrigTypeOfNumber");
|
||||
const char * isdn_dest_type = getFSChannelVar("KISDNDestTypeOfNumber");
|
||||
const char * isdn_orig_numbering = getFSChannelVar("KISDNOrigNumberingPlan");
|
||||
const char * isdn_dest_numbering = getFSChannelVar("KISDNDestNumberingPlan");
|
||||
const char * isdn_orig_presentation = getFSChannelVar("KISDNOrigPresentation");
|
||||
|
||||
LOG(ERROR, PVT_FMT(_target,"ISDNORIG: %s") % (isdn_orig_type ? isdn_orig_type : ""));
|
||||
|
||||
callISDN()->_isdn_orig_type_of_number = (isdn_orig_type ? isdn_orig_type : "");
|
||||
callISDN()->_isdn_dest_type_of_number = (isdn_dest_type ? isdn_dest_type : "");
|
||||
callISDN()->_isdn_orig_numbering_plan = (isdn_orig_numbering ? isdn_orig_numbering : "");
|
||||
callISDN()->_isdn_dest_numbering_plan = (isdn_dest_numbering ? isdn_dest_numbering : "");
|
||||
callISDN()->_isdn_orig_presentation = (isdn_orig_presentation ? isdn_orig_presentation : "");
|
||||
}
|
||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
||||
{
|
||||
LOG(ERROR, PVT_FMT(_target, "(ISDN) %s") % err._msg.c_str());
|
||||
}
|
||||
|
||||
KhompPvt::getSpecialVariables();
|
||||
}
|
||||
|
||||
Transfer<CallISDN, false> * _transfer;
|
||||
};
|
||||
/******************************************************************************/
|
||||
/********************************* R2 Channel *********************************/
|
||||
|
@ -472,7 +538,6 @@ struct KhompPvtR2: public KhompPvtE1
|
|||
{
|
||||
LOG(ERROR, FMT("invalid r2 category: '%s' is not a number.") % value.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -555,6 +620,22 @@ struct KhompPvtR2: public KhompPvtE1
|
|||
return (CallR2 *)call();
|
||||
}
|
||||
|
||||
bool forceDisconnect(void)
|
||||
{
|
||||
char cmd[] = { 0x07, (char)(_target.object + 1) };
|
||||
|
||||
try
|
||||
{
|
||||
Globals::k3lapi.raw_command(_target.device, 0, cmd, sizeof(cmd));
|
||||
}
|
||||
catch(K3LAPI::failed_raw_command &e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
int makeCall(std::string params = "");
|
||||
bool doChannelAnswer(CommandRequest &);
|
||||
bool doChannelHangup(CommandRequest &);
|
||||
|
@ -609,9 +690,9 @@ struct KhompPvtR2: public KhompPvtE1
|
|||
/* r2 caller category */
|
||||
if (callR2()->_r2_category != -1)
|
||||
{
|
||||
setFSChannelVar("KR2GotCategory",Verbose::signGroupII((KSignGroupII)callR2()->_r2_category).c_str());
|
||||
setFSChannelVar("KR2GotCategory",STG(FMT("%d") % callR2()->_r2_category).c_str());
|
||||
setFSChannelVar("KR2StrCategory",Verbose::signGroupII((KSignGroupII)callR2()->_r2_category).c_str());
|
||||
}
|
||||
|
||||
}
|
||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
||||
{
|
||||
|
@ -834,9 +915,9 @@ struct KhompPvtFXS: public KhompPvt
|
|||
_ring_off_ext = -1;
|
||||
|
||||
_incoming_exten.clear();
|
||||
_flash_transfer.clear();
|
||||
//_flash_transfer.clear();
|
||||
|
||||
_uuid_other_session.clear();
|
||||
//_uuid_other_session.clear();
|
||||
|
||||
return Call::clear();
|
||||
}
|
||||
|
@ -850,10 +931,10 @@ struct KhompPvtFXS: public KhompPvt
|
|||
|
||||
std::string _incoming_exten;
|
||||
|
||||
ChanTimer::Index _idx_transfer;
|
||||
//ChanTimer::Index _idx_transfer;
|
||||
|
||||
std::string _flash_transfer;
|
||||
std::string _uuid_other_session;
|
||||
//std::string _flash_transfer;
|
||||
//std::string _uuid_other_session;
|
||||
|
||||
|
||||
};
|
||||
|
@ -936,9 +1017,9 @@ struct KhompPvtFXS: public KhompPvt
|
|||
std::string extra_context = "");
|
||||
bool isOK(void);
|
||||
|
||||
bool startTransfer();
|
||||
bool stopTransfer();
|
||||
bool transfer(std::string & context, bool blind = false);
|
||||
//bool startTransfer();
|
||||
//bool stopTransfer();
|
||||
//bool transfer(std::string & context, bool blind = false);
|
||||
|
||||
bool hasNumberDial() { return false; }
|
||||
|
||||
|
@ -996,7 +1077,7 @@ struct KhompPvtFXS: public KhompPvt
|
|||
|
||||
static OrigToNseqMapType generateNseqMap();
|
||||
static void dialTimer(KhompPvt * pvt);
|
||||
static void transferTimer(KhompPvt * pvt);
|
||||
//static void transferTimer(KhompPvt * pvt);
|
||||
|
||||
static std::string padOrig(std::string orig_base, unsigned int padding)
|
||||
{
|
||||
|
@ -1015,21 +1096,16 @@ struct KhompPvtFXS: public KhompPvt
|
|||
return STG(FMT(STG(FMT("%%0%dd") % orig_size)) % (orig_numb + padding));
|
||||
}
|
||||
|
||||
/*
|
||||
virtual void getSpecialVariables()
|
||||
void cleanupIndications(bool force)
|
||||
{
|
||||
try
|
||||
if (call()->_indication == INDICA_BUSY && !force)
|
||||
{
|
||||
}
|
||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
||||
{
|
||||
LOG(ERROR, PVT_FMT(_target, "(FXS) %s") % err._msg.c_str());
|
||||
DBG(FUNC, PVT_FMT(_target, "skipping busy indication cleanup on FXS channel."));
|
||||
return;
|
||||
}
|
||||
|
||||
KhompPvt::getSpecialVariables();
|
||||
KhompPvt::cleanupIndications(force);
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -108,11 +108,14 @@ struct Options
|
|||
Config::Value< bool > _recording;
|
||||
Config::Value< bool > _has_ctbus;
|
||||
Config::Value< bool > _fxs_bina;
|
||||
Config::Value< bool > _fxo_send_pre_audio;
|
||||
Config::Value< bool > _fxs_sharp_dial;
|
||||
Config::Value< bool > _drop_collect_call;
|
||||
Config::Value< bool > _ignore_letter_dtmfs;
|
||||
Config::Value< bool > _optimize_audio_path;
|
||||
|
||||
Config::Value< bool > _fxo_send_pre_audio;
|
||||
Config::Value< unsigned int > _fxo_busy_disconnection;
|
||||
|
||||
Config::Value< bool > _auto_fax_adjustment;
|
||||
Config::Value< unsigned int > _fax_adjustment_timeout;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
#define MOD_KHOMP_VERSION "1.0 - (rev: 5891)"
|
||||
#define MOD_KHOMP_VERSION "1.0 - (rev: 6034)"
|
||||
|
|
|
@ -75,6 +75,7 @@ void Cli::registerCommands(APIFunc func,switch_loadable_module_interface_t **mod
|
|||
" khomp channels unblock {all | <board> all | <board> <channel>}\n" \
|
||||
" khomp clear links [<board> [<link>]]\n" \
|
||||
" khomp clear statistics [<board> [<channel>]]\n" \
|
||||
" khomp dump config\n" \
|
||||
" khomp get <option>\n" \
|
||||
" khomp kommuter {on|off}\n" \
|
||||
" khomp kommuter count\n" \
|
||||
|
@ -128,6 +129,10 @@ void Cli::registerCommands(APIFunc func,switch_loadable_module_interface_t **mod
|
|||
/* is responsible for parse and execute all commands */
|
||||
bool Cli::parseCommands(int argc, char *argv[])
|
||||
{
|
||||
/*
|
||||
* DEBUG_CLI_CMD();
|
||||
*/
|
||||
|
||||
/* khomp summary */
|
||||
if (ARG_CMP(0, "summary"))
|
||||
return EXEC_CLI_CMD(Cli::KhompSummary);
|
||||
|
@ -164,6 +169,14 @@ bool Cli::parseCommands(int argc, char *argv[])
|
|||
return EXEC_CLI_CMD(Cli::KhompClearStatistics);
|
||||
}
|
||||
|
||||
/* khomp dump */
|
||||
else if(ARG_CMP(0, "dump"))
|
||||
{
|
||||
/* khomp dump config */
|
||||
if(ARG_CMP(1, "config"))
|
||||
return EXEC_CLI_CMD(Cli::KhompDumpConfig);
|
||||
}
|
||||
|
||||
/* khomp reset */
|
||||
else if(ARG_CMP(0, "reset"))
|
||||
{
|
||||
|
@ -285,6 +298,7 @@ Cli::_KhompShowChannels Cli::KhompShowChannels;
|
|||
Cli::_KhompShowLinks Cli::KhompShowLinks;
|
||||
Cli::_KhompShowStatistics Cli::KhompShowStatistics;
|
||||
Cli::_KhompClearLinks Cli::KhompClearLinks;
|
||||
Cli::_KhompDumpConfig Cli::KhompDumpConfig;
|
||||
Cli::_KhompClearStatistics Cli::KhompClearStatistics;
|
||||
Cli::_KhompResetLinks Cli::KhompResetLinks;
|
||||
Cli::_KhompChannelsDisconnect Cli::KhompChannelsDisconnect;
|
||||
|
@ -337,7 +351,9 @@ bool Cli::_KhompSummary::execute(int argc, char *argv[])
|
|||
K::Logger::Logg2(classe, stream, "|------------------------------------------------------------------|");
|
||||
}
|
||||
|
||||
if (k3lGetDeviceConfig(-1, ksoAPI, &apiCfg, sizeof(apiCfg)) == ksSuccess)
|
||||
const bool running = (k3lGetDeviceConfig(-1, ksoAPI, &apiCfg, sizeof(apiCfg)) == ksSuccess);
|
||||
|
||||
if(running)
|
||||
{
|
||||
switch(output_type)
|
||||
{
|
||||
|
@ -376,6 +392,28 @@ bool Cli::_KhompSummary::execute(int argc, char *argv[])
|
|||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(output_type)
|
||||
{
|
||||
case Cli::VERBOSE:
|
||||
{
|
||||
K::Logger::Logg2(classe, stream, "| Connection to KServer broken, please check system logs! |");
|
||||
} break;
|
||||
|
||||
case Cli::CONCISE:
|
||||
{
|
||||
K::Logger::Logg2(classe, stream, "CONNECTION BROKEN");
|
||||
} break;
|
||||
|
||||
case Cli::XML:
|
||||
{
|
||||
/* summary/k3lapi */
|
||||
switch_xml_t xk3lapi = switch_xml_add_child_d(root, "k3lapi",0);
|
||||
switch_xml_set_txt_d(xk3lapi, "CONNECTION BROKEN");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MOD_KHOMP_VERSION
|
||||
#define MOD_KHOMP_VERSION "unknown"
|
||||
|
@ -423,6 +461,20 @@ bool Cli::_KhompSummary::execute(int argc, char *argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
if(!running)
|
||||
{
|
||||
if (output_type == Cli::VERBOSE)
|
||||
K::Logger::Logg2(classe,stream, " ------------------------------------------------------------------");
|
||||
|
||||
if (output_type == Cli::XML)
|
||||
{
|
||||
printXMLOutput(stream);
|
||||
clearRoot();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (output_type == Cli::XML)
|
||||
{
|
||||
/* summary/board */
|
||||
|
@ -2154,6 +2206,38 @@ bool Cli::_KhompClearStatistics::execute(int argc, char *argv[])
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Cli::_KhompDumpConfig::execute(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printUsage(stream);
|
||||
return false;
|
||||
}
|
||||
|
||||
const Config::StringSet opts = Globals::options.options();
|
||||
|
||||
K::Logger::Logg2(C_CLI, stream, " ------------------------------------------------------------------------");
|
||||
K::Logger::Logg2(C_CLI, stream, "|--------------------------- Khomp Options Dump -------------------------|");
|
||||
K::Logger::Logg2(C_CLI, stream, "|------------------------------------------------------------------------|");
|
||||
|
||||
for (Config::StringSet::const_iterator itr = opts.begin(); itr != opts.end(); ++itr)
|
||||
{ try
|
||||
{
|
||||
if(removeUnavaible((*itr))) continue;
|
||||
K::Logger::Logg2(C_CLI, stream, FMT("| %-24s => %42s |")
|
||||
% (*itr) % Globals::options.get(&(Opt::_options), (*itr)));
|
||||
}
|
||||
catch(Config::EmptyValue &e)
|
||||
{
|
||||
K::Logger::Logg(C_ERROR, FMT("%s (%s)") % e.what() % (*itr));
|
||||
}
|
||||
}
|
||||
|
||||
K::Logger::Logg2(C_CLI, stream, " ------------------------------------------------------------------------");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cli::_KhompResetLinks::resetLink(unsigned int device, unsigned int link)
|
||||
{
|
||||
try
|
||||
|
@ -2718,10 +2802,18 @@ bool Cli::_KhompSet::execute(int argc, char *argv[])
|
|||
try
|
||||
{
|
||||
Globals::options.process(&Opt::_options, (const char *) argv[1], (const char *) args.c_str());
|
||||
const Config::Options::Messages msgs = Globals::options.commit(&Opt::_options, (const char *)argv[1]);
|
||||
|
||||
for (Config::Options::Messages::const_iterator i = msgs.begin(); i != msgs.end(); ++i)
|
||||
{
|
||||
K::Logger::Logg2(C_ERROR, stream, FMT("%s.") % (*i));
|
||||
}
|
||||
|
||||
K::Logger::Logg2(C_CLI, stream, FMT("Setting %s for value %s") % argv[1] % argv[2]);
|
||||
}
|
||||
catch (Config::Failure &e)
|
||||
{
|
||||
K::Logger::Logg2(C_CLI,stream, FMT("config processing error: %s.") % e.what());
|
||||
K::Logger::Logg2(C_ERROR,stream, FMT("config processing error: %s.") % e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2891,7 +2983,6 @@ bool Cli::_KhompSelectSim::execute(int argc, char *argv[])
|
|||
K::Logger::Logg2(C_CLI, stream, "ERROR: Unable to select sim card");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Strings::invalid_value & e)
|
||||
{
|
||||
|
|
|
@ -1119,12 +1119,7 @@ bool Board::KhompPvt::cleanup(CleanupType type)
|
|||
/* pára cadências e limpa estado das flags */
|
||||
stopCadence();
|
||||
|
||||
if (call()->_indication != INDICA_NONE)
|
||||
{
|
||||
call()->_indication = INDICA_NONE;
|
||||
|
||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtSilence);
|
||||
}
|
||||
cleanupIndications(true);
|
||||
|
||||
if(call()->_input_volume >= -10 && call()->_input_volume <= 10)
|
||||
setVolume("input" , Opt::_options._input_volume());
|
||||
|
@ -1152,6 +1147,15 @@ bool Board::KhompPvt::cleanup(CleanupType type)
|
|||
return true;
|
||||
}
|
||||
|
||||
void Board::KhompPvt::cleanupIndications(bool force)
|
||||
{
|
||||
if (call()->_indication != INDICA_NONE)
|
||||
{
|
||||
call()->_indication = INDICA_NONE;
|
||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtSilence);
|
||||
}
|
||||
}
|
||||
|
||||
bool Board::KhompPvt::isFree(bool just_phy)
|
||||
{
|
||||
//DBG(FUNC, DP(this, "c"));
|
||||
|
@ -1168,28 +1172,6 @@ bool Board::KhompPvt::isFree(bool just_phy)
|
|||
if(session())
|
||||
return false;
|
||||
|
||||
/*
|
||||
if (!is_gsm())
|
||||
{
|
||||
if (calls.at(0).owner != NULL)
|
||||
{
|
||||
DBG(FUNC, DP(this, "we have owner, not free!"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
|
||||
call_data_type & data = calls.at(i);
|
||||
|
||||
if (data.owner != NULL)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bool free_state = !(_call->_flags.check(Kflags::IS_INCOMING) || _call->_flags.check(Kflags::IS_OUTGOING));
|
||||
|
||||
DBG(FUNC, PVT_FMT(target(), "[free = %s]") % (free_state ? "yes" : "no"));
|
||||
|
@ -1559,7 +1541,7 @@ bool Board::KhompPvt::echoCancellation(bool enable)
|
|||
|
||||
bool Board::KhompPvt::autoGainControl(bool enable)
|
||||
{
|
||||
bool ret = command(KHOMP_LOG,(enable ? CM_ENABLE_AGC : CM_DISABLE_AGC));//, SCE_SHOW_DEBUG);
|
||||
bool ret = command(KHOMP_LOG,(enable ? CM_ENABLE_AGC : CM_DISABLE_AGC));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1625,10 +1607,11 @@ bool Board::KhompPvt::setCollectCall()
|
|||
DBG(FUNC, PVT_FMT(_target, "option drop collect call is '%s'") % (Opt::_options._drop_collect_call() ? "yes" : "no"));
|
||||
|
||||
// get global filter configuration value
|
||||
tmp_var = switch_core_get_variable_dup("KDropCollectCall");
|
||||
tmp_var = getFSGlobalVar("KDropCollectCall");
|
||||
confvalues.push_back(getTriStateValue(tmp_var));
|
||||
DBG(FUNC, PVT_FMT(_target, "global KDropCollectCall was '%s'") % (tmp_var ? tmp_var : "(empty)"));
|
||||
switch_safe_free(tmp_var);
|
||||
|
||||
freeFSGlobalVar(&tmp_var);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -2052,6 +2035,7 @@ bool Board::KhompPvt::onNoAnswer(K3L_EVENT *e)
|
|||
DBG(FUNC, PVT_FMT(_target, "Detected: \"%s\"") % Verbose::callStartInfo((KCallStartInfo)e->AddInfo).c_str());
|
||||
|
||||
// Fire a custom event about this
|
||||
/* MUST USE THE NEW EVENT SYSTEM
|
||||
switch_event_t * event;
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, KHOMP_EVENT_MAINT) == SWITCH_STATUS_SUCCESS)
|
||||
{
|
||||
|
@ -2062,6 +2046,8 @@ bool Board::KhompPvt::onNoAnswer(K3L_EVENT *e)
|
|||
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -715,37 +715,47 @@ bool BoardFXO::KhompPvtFXO::indicateBusyUnlocked(int cause, bool sent_signaling)
|
|||
|
||||
if(call()->_flags.check(Kflags::IS_INCOMING))
|
||||
{
|
||||
/* already connected or sent signaling... */
|
||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
||||
|
||||
if(!call()->_flags.check(Kflags::CONNECTED) && !sent_signaling)
|
||||
{
|
||||
//we are talking about branches, not trunks
|
||||
/* we are talking about branches, not trunks */
|
||||
command(KHOMP_LOG, CM_CONNECT);
|
||||
command(KHOMP_LOG, CM_DISCONNECT);
|
||||
}
|
||||
else
|
||||
{
|
||||
//already connected or sent signaling...
|
||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
||||
callFXO()->_busy_disconnect = Board::board(_target.device)->_timers.add(Opt::_options._fxo_busy_disconnection(), &BoardFXO::KhompPvtFXO::busyDisconnect, this);
|
||||
}
|
||||
}
|
||||
else if(call()->_flags.check(Kflags::IS_OUTGOING))
|
||||
{
|
||||
//already connected or sent signaling...
|
||||
/* already connected or sent signaling... */
|
||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
||||
}
|
||||
|
||||
DBG(FUNC,PVT_FMT(_target, "(FXO) r"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BoardFXO::KhompPvtFXO::busyDisconnect(Board::KhompPvt * pvt)
|
||||
{
|
||||
DBG(FUNC, PVT_FMT(pvt->target(), "Disconnecting FXO"));
|
||||
|
||||
try
|
||||
{
|
||||
ScopedPvtLock lock(pvt);
|
||||
pvt->command(KHOMP_LOG, CM_DISCONNECT);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG(ERROR, PVT_FMT(pvt->target(), "unable to lock the pvt !"));
|
||||
}
|
||||
}
|
||||
|
||||
void BoardFXO::KhompPvtFXO::reportFailToReceive(int fail_code)
|
||||
{
|
||||
KhompPvt::reportFailToReceive(fail_code);
|
||||
|
||||
command(KHOMP_LOG, CM_CONNECT);
|
||||
|
||||
command(KHOMP_LOG, CM_DISCONNECT);
|
||||
|
||||
}
|
||||
|
||||
bool BoardFXO::KhompPvtFXO::validContexts(
|
||||
|
|
|
@ -312,6 +312,9 @@ int BoardGSM::KhompPvtGSM::makeCall(std::string params)
|
|||
command(KHOMP_LOG, CM_DISABLE_CALL_ANSWER_INFO);
|
||||
}
|
||||
|
||||
if(!_call->_orig_addr.compare("restricted"))
|
||||
params += " orig_addr=\"restricted\"";
|
||||
|
||||
int ret = KhompPvt::makeCall(params);
|
||||
|
||||
if(ret != ksSuccess)
|
||||
|
|
|
@ -372,17 +372,36 @@ bool BoardE1::onLinkStatus(K3L_EVENT *e)
|
|||
|
||||
bool BoardE1::KhompPvtISDN::onSyncUserInformation(K3L_EVENT *e)
|
||||
{
|
||||
KUserInformation * info = (KUserInformation *) (((char*)e) + sizeof(K3L_EVENT));
|
||||
DBG(FUNC,PVT_FMT(_target, "Synchronizing"));
|
||||
|
||||
callISDN()->_uui_descriptor = info->ProtocolDescriptor;
|
||||
|
||||
/* clean string */
|
||||
callISDN()->_uui_information.clear();
|
||||
|
||||
if (info->UserInfoLength)
|
||||
if(callISDN()->_uui_extended)
|
||||
{
|
||||
/* append to a clean string */
|
||||
callISDN()->_uui_information.append((const char *)info->UserInfo, info->UserInfoLength);
|
||||
KUserInformationEx * info = (KUserInformationEx *) (((char*)e) + sizeof(K3L_EVENT));
|
||||
callISDN()->_uui_descriptor = (long int) info->ProtocolDescriptor;
|
||||
|
||||
/* clean string */
|
||||
callISDN()->_uui_information.clear();
|
||||
|
||||
if (info->UserInfoLength)
|
||||
{
|
||||
/* append to a clean string */
|
||||
for (unsigned int i = 0; i < info->UserInfoLength; ++i)
|
||||
callISDN()->_uui_information += STG(FMT("%02hhx") % ((unsigned char) info->UserInfo[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KUserInformation * info = (KUserInformation *) (((char*)e) + sizeof(K3L_EVENT));
|
||||
callISDN()->_uui_descriptor = info->ProtocolDescriptor;
|
||||
|
||||
/* clean string */
|
||||
callISDN()->_uui_information.clear();
|
||||
|
||||
if (info->UserInfoLength)
|
||||
{
|
||||
for (unsigned int i = 0; i < info->UserInfoLength; ++i)
|
||||
callISDN()->_uui_information += STG(FMT("%02hhx") % ((unsigned char) info->UserInfo[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -443,12 +462,17 @@ bool BoardE1::KhompPvtISDN::onNewCall(K3L_EVENT *e)
|
|||
|
||||
try
|
||||
{
|
||||
callISDN()->_isdn_orig_type_of_number = Globals::k3lapi.get_param(e, "isdn_orig_type_of_number");
|
||||
callISDN()->_isdn_orig_numbering_plan = Globals::k3lapi.get_param(e, "isdn_orig_numbering_plan");
|
||||
callISDN()->_isdn_dest_type_of_number = Globals::k3lapi.get_param(e, "isdn_dest_type_of_number");
|
||||
callISDN()->_isdn_dest_numbering_plan = Globals::k3lapi.get_param(e, "isdn_dest_numbering_plan");
|
||||
callISDN()->_isdn_orig_presentation = Globals::k3lapi.get_param(e, "isdn_orig_presentation");
|
||||
isdn_reverse_charge_str = Globals::k3lapi.get_param(e, "isdn_reverse_charge");
|
||||
isdn_reverse_charge = Strings::toboolean(isdn_reverse_charge_str);
|
||||
}
|
||||
catch(K3LAPI::get_param_failed & err)
|
||||
{
|
||||
/* do nothing, maybe the parameter is not sent */
|
||||
LOG(WARNING, PVT_FMT(_target, "maybe the parameter is not sent (%s)'") % err.name.c_str());
|
||||
}
|
||||
catch (Strings::invalid_value & err)
|
||||
{
|
||||
|
@ -866,25 +890,84 @@ int BoardE1::KhompPvtISDN::makeCall(std::string params)
|
|||
DBG(FUNC,PVT_FMT(_target, "got userinfo"));
|
||||
|
||||
/* grab this information first, avoiding latter side-effects */
|
||||
const char * info_data = call->_uui_information.c_str();
|
||||
size_t info_size = std::min(call->_uui_information.size(), (size_t)KMAX_USER_USER_LEN);
|
||||
const bool info_extd = call->_uui_extended;
|
||||
const long int info_desc = call->_uui_descriptor;
|
||||
const std::string info_data = call->_uui_information.c_str();
|
||||
const size_t info_size = std::min<size_t>(call->_uui_information.size(), (info_extd ? KMAX_USER_USER_EX_LEN : KMAX_USER_USER_LEN) << 1) >> 1;
|
||||
|
||||
KUserInformation info;
|
||||
bool res = true;
|
||||
|
||||
info.ProtocolDescriptor = call->_uui_descriptor;
|
||||
info.UserInfoLength = info_size;
|
||||
|
||||
memcpy((void *) info.UserInfo, (const void *) info_data, info_size);
|
||||
|
||||
if (!command(KHOMP_LOG, CM_USER_INFORMATION, (const char *)&info))
|
||||
if(info_extd)
|
||||
{
|
||||
LOG(ERROR,PVT_FMT(_target, "UUI could not be sent before dialing!"));
|
||||
KUserInformationEx info;
|
||||
|
||||
info.ProtocolDescriptor = info_desc;
|
||||
info.UserInfoLength = info_size;
|
||||
|
||||
for (unsigned int pos = 0u, index = 0u; pos < info_size; index+=2, ++pos)
|
||||
info.UserInfo[pos] = (unsigned char)Strings::toulong(info_data.substr(index,2), 16);
|
||||
|
||||
if (!command(KHOMP_LOG, CM_USER_INFORMATION_EX, (const char *) &info))
|
||||
{
|
||||
LOG(ERROR,PVT_FMT(_target, "UUI could not be sent before dialing!"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KUserInformation info;
|
||||
|
||||
info.ProtocolDescriptor = info_desc;
|
||||
info.UserInfoLength = info_size;
|
||||
|
||||
for (unsigned int pos = 0u, index = 0u; pos < info_size; index+=2, ++pos)
|
||||
info.UserInfo[pos] = (unsigned char)Strings::toulong(info_data.substr(index,2), 16);
|
||||
|
||||
if (!command(KHOMP_LOG, CM_USER_INFORMATION, (const char *) &info))
|
||||
{
|
||||
LOG(ERROR,PVT_FMT(_target, "UUI could not be sent before dialing!"));
|
||||
}
|
||||
}
|
||||
|
||||
call->_uui_extended = false;
|
||||
call->_uui_descriptor = -1;
|
||||
call->_uui_information.clear();
|
||||
}
|
||||
|
||||
if (!callISDN()->_isdn_orig_type_of_number.empty())
|
||||
{
|
||||
params += "isdn_orig_type_of_number=\"";
|
||||
params += callISDN()->_isdn_orig_type_of_number;
|
||||
params += "\" ";
|
||||
}
|
||||
|
||||
if (!callISDN()->_isdn_dest_type_of_number.empty())
|
||||
{
|
||||
params += "isdn_dest_type_of_number=\"";
|
||||
params += callISDN()->_isdn_dest_type_of_number;
|
||||
params += "\" ";
|
||||
}
|
||||
|
||||
if (!callISDN()->_isdn_orig_numbering_plan.empty())
|
||||
{
|
||||
params += "isdn_orig_numbering_plan=\"";
|
||||
params += callISDN()->_isdn_orig_numbering_plan;
|
||||
params += "\" ";
|
||||
}
|
||||
|
||||
if (!callISDN()->_isdn_dest_numbering_plan.empty())
|
||||
{
|
||||
params += "isdn_dest_numbering_plan=\"";
|
||||
params += callISDN()->_isdn_dest_numbering_plan;
|
||||
params += "\" ";
|
||||
}
|
||||
|
||||
if (!callISDN()->_isdn_orig_presentation.empty())
|
||||
{
|
||||
params += "isdn_orig_presentation=\"";
|
||||
params += callISDN()->_isdn_orig_presentation;
|
||||
params += "\" ";
|
||||
}
|
||||
|
||||
int ret = KhompPvtE1::makeCall(params);
|
||||
|
||||
call->_cleanup_upon_hangup = (ret == ksInvalidParams || ret == ksBusy);
|
||||
|
@ -995,12 +1078,6 @@ bool BoardE1::KhompPvtR2::doChannelAnswer(CommandRequest &cmd)
|
|||
// is this a collect call?
|
||||
bool has_recv_collect_call = _call->_collect_call;
|
||||
|
||||
if(has_recv_collect_call)
|
||||
DBG(FUNC, PVT_FMT(target(), "receive a collect call"));
|
||||
|
||||
if(call()->_flags.check(Kflags::DROP_COLLECT))
|
||||
DBG(FUNC, PVT_FMT(target(), "flag DROP_COLLECT == true"));
|
||||
|
||||
// do we have to drop collect calls?
|
||||
bool has_drop_collect_call = call()->_flags.check(Kflags::DROP_COLLECT);
|
||||
|
||||
|
@ -1013,29 +1090,37 @@ bool BoardE1::KhompPvtR2::doChannelAnswer(CommandRequest &cmd)
|
|||
if(do_send_ring)
|
||||
{
|
||||
call()->_flags.clear(Kflags::NEEDS_RINGBACK_CMD);
|
||||
|
||||
//TODO: callFailFromCause ??
|
||||
std::string cause = ( do_drop_call ? STG(FMT("r2_cond_b=\"%d\"") % kgbBusy) : "" );
|
||||
command(KHOMP_LOG,CM_RINGBACK,cause.c_str());
|
||||
|
||||
usleep(75000);
|
||||
}
|
||||
|
||||
if(!(do_drop_call && do_send_ring))
|
||||
if(!do_drop_call)
|
||||
{
|
||||
command(KHOMP_LOG, CM_CONNECT);
|
||||
}
|
||||
|
||||
if(has_drop_collect_call && !do_send_ring)
|
||||
if(!do_send_ring && has_drop_collect_call)
|
||||
{
|
||||
usleep(75000);
|
||||
|
||||
if(has_recv_collect_call)
|
||||
{
|
||||
usleep(75000);
|
||||
|
||||
DBG(FUNC, PVT_FMT(target(), "disconnecting collect call doChannelAnswer R2"));
|
||||
command(KHOMP_LOG,CM_DISCONNECT);
|
||||
|
||||
// thou shalt not talk anymore!
|
||||
stopListen();
|
||||
stopStream();
|
||||
|
||||
if (call()->_indication == INDICA_NONE)
|
||||
{
|
||||
call()->_indication = INDICA_BUSY;
|
||||
mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
|
||||
}
|
||||
|
||||
DBG(FUNC, PVT_FMT(_target,"forcing disconnect for collect call"));
|
||||
forceDisconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1797,6 +1882,8 @@ bool BoardE1::KhompPvtR2::onNewCall(K3L_EVENT *e)
|
|||
DBG(FUNC,PVT_FMT(_target, "Setting DROP_COLLECT flag"));
|
||||
}
|
||||
|
||||
freeFSGlobalVar(&drop_str);
|
||||
|
||||
// keeping the hardcore mode
|
||||
if (do_drop_collect && call()->_collect_call)
|
||||
{
|
||||
|
@ -2388,6 +2475,7 @@ void BoardE1::KhompPvtFXS::dialTimer(KhompPvt * pvt)
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
void BoardE1::KhompPvtFXS::transferTimer(KhompPvt * pvt)
|
||||
{
|
||||
DBG(FUNC, PVT_FMT(pvt->target(), "c"));
|
||||
|
@ -2420,7 +2508,7 @@ void BoardE1::KhompPvtFXS::transferTimer(KhompPvt * pvt)
|
|||
return;
|
||||
}
|
||||
|
||||
/* begin context adjusting + processing */
|
||||
// begin context adjusting + processing
|
||||
MatchExtension::ContextListType contexts;
|
||||
|
||||
pvt_fxs->validContexts(contexts);
|
||||
|
@ -2469,6 +2557,7 @@ void BoardE1::KhompPvtFXS::transferTimer(KhompPvt * pvt)
|
|||
DBG(FUNC, PVT_FMT(pvt->target(), "r"));
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
|
||||
{
|
||||
|
@ -2480,22 +2569,23 @@ bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
|
|||
{
|
||||
ScopedPvtLock lock(this);
|
||||
|
||||
/*
|
||||
if(!callFXS()->_uuid_other_session.empty() && session())
|
||||
{
|
||||
/*
|
||||
switch_core_session_t *hold_session;
|
||||
|
||||
if ((hold_session = switch_core_session_locate(callFXS()->_uuid_other_session.c_str())))
|
||||
{
|
||||
switch_channel_t * hold = switch_core_session_get_channel(hold_session);
|
||||
switch_channel_stop_broadcast(hold);
|
||||
switch_channel_wait_for_flag(hold, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
|
||||
switch_core_session_rwunlock(hold_session);
|
||||
}
|
||||
*/
|
||||
//switch_core_session_t *hold_session;
|
||||
|
||||
//if ((hold_session = switch_core_session_locate(callFXS()->_uuid_other_session.c_str())))
|
||||
//{
|
||||
// switch_channel_t * hold = switch_core_session_get_channel(hold_session);
|
||||
// switch_channel_stop_broadcast(hold);
|
||||
// switch_channel_wait_for_flag(hold, CF_BROADCAST, SWITCH_FALSE, 5000, NULL);
|
||||
// switch_core_session_rwunlock(hold_session);
|
||||
//}
|
||||
|
||||
try
|
||||
{
|
||||
/* get other side of the bridge */
|
||||
// get other side of the bridge
|
||||
switch_core_session_t * peer_session = getFSLockedPartnerSession();
|
||||
unlockPartner(peer_session);
|
||||
DBG(FUNC, PVT_FMT(target(), "bridge with the new session"));
|
||||
|
@ -2509,6 +2599,7 @@ bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
|
|||
|
||||
callFXS()->_uuid_other_session.clear();
|
||||
}
|
||||
*/
|
||||
|
||||
ret = KhompPvt::onChannelRelease(e);
|
||||
|
||||
|
@ -2523,7 +2614,7 @@ bool BoardE1::KhompPvtFXS::onChannelRelease(K3L_EVENT *e)
|
|||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
bool BoardE1::KhompPvtFXS::startTransfer()
|
||||
{
|
||||
DBG(FUNC, PVT_FMT(target(), "c"));
|
||||
|
@ -2596,7 +2687,7 @@ bool BoardE1::KhompPvtFXS::stopTransfer()
|
|||
|
||||
try
|
||||
{
|
||||
/* get other side of the bridge */
|
||||
// get other side of the bridge
|
||||
switch_core_session_t * peer_session = getFSLockedPartnerSession();
|
||||
switch_channel_t * peer_channel = getFSChannel(peer_session);
|
||||
|
||||
|
@ -2664,33 +2755,33 @@ static switch_status_t xferHook(switch_core_session_t *session)
|
|||
else if (state == CS_HANGUP)
|
||||
{
|
||||
switch_core_event_hook_remove_state_change(session, xferHook);
|
||||
/*
|
||||
BoardE1::KhompPvtFXS * pvt = static_cast<BoardE1::KhompPvtFXS*>(switch_core_session_get_private(session));
|
||||
|
||||
if(!pvt)
|
||||
{
|
||||
DBG(FUNC, D("pvt is NULL"));
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
//BoardE1::KhompPvtFXS * pvt = static_cast<BoardE1::KhompPvtFXS*>(switch_core_session_get_private(session));
|
||||
//
|
||||
//if(!pvt)
|
||||
//{
|
||||
// DBG(FUNC, D("pvt is NULL"));
|
||||
// return SWITCH_STATUS_FALSE;
|
||||
//}
|
||||
|
||||
try
|
||||
{
|
||||
ScopedPvtLock lock(pvt);
|
||||
//try
|
||||
//{
|
||||
// ScopedPvtLock lock(pvt);
|
||||
|
||||
if(!pvt->callFXS()->_uuid_other_session.empty())
|
||||
{
|
||||
DBG(FUNC, D("bridge after hangup"));
|
||||
std::string number = pvt->callFXS()->_uuid_other_session;
|
||||
pvt->callFXS()->_uuid_other_session.clear();
|
||||
// if(!pvt->callFXS()->_uuid_other_session.empty())
|
||||
// {
|
||||
// DBG(FUNC, D("bridge after hangup"));
|
||||
// std::string number = pvt->callFXS()->_uuid_other_session;
|
||||
// pvt->callFXS()->_uuid_other_session.clear();
|
||||
|
||||
// switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), number.c_str());
|
||||
// }
|
||||
//}
|
||||
//catch(ScopedLockFailed & err)
|
||||
//{
|
||||
// LOG(ERROR, PVT_FMT(pvt->target(), "unable to lock: %s!") % err._msg.c_str());
|
||||
//}
|
||||
|
||||
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), number.c_str());
|
||||
}
|
||||
}
|
||||
catch(ScopedLockFailed & err)
|
||||
{
|
||||
LOG(ERROR, PVT_FMT(pvt->target(), "unable to lock: %s!") % err._msg.c_str());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
@ -2716,7 +2807,7 @@ bool BoardE1::KhompPvtFXS::transfer(std::string & context, bool blind)
|
|||
|
||||
try
|
||||
{
|
||||
/* get other side of the bridge */
|
||||
// get other side of the bridge
|
||||
switch_core_session_t * peer_session = getFSLockedPartnerSession();
|
||||
switch_channel_t * peer_channel = getFSChannel(peer_session);
|
||||
|
||||
|
@ -2774,16 +2865,16 @@ bool BoardE1::KhompPvtFXS::transfer(std::string & context, bool blind)
|
|||
call()->_flags.set(Kflags::GEN_CO_RING);
|
||||
startCadence(PLAY_RINGBACK);
|
||||
|
||||
/*
|
||||
try
|
||||
{
|
||||
call()->_idx_co_ring = Board::board(_target.device)->_timers.add(Opt::_options._ringback_co_delay(), &Board::KhompPvt::coRingGen,this);
|
||||
}
|
||||
catch (K3LAPITraits::invalid_device & err)
|
||||
{
|
||||
LOG(ERROR, PVT_FMT(_target, "unable to get device: %d!") % err.device);
|
||||
}
|
||||
*/
|
||||
|
||||
//try
|
||||
//{
|
||||
// call()->_idx_co_ring = Board::board(_target.device)->_timers.add(Opt::_options._ringback_co_delay(), &Board::KhompPvt::coRingGen,this);
|
||||
//}
|
||||
//catch (K3LAPITraits::invalid_device & err)
|
||||
//{
|
||||
// LOG(ERROR, PVT_FMT(_target, "unable to get device: %d!") % err.device);
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
catch(Board::KhompPvt::InvalidSwitchChannel & err)
|
||||
|
@ -2796,6 +2887,7 @@ bool BoardE1::KhompPvtFXS::transfer(std::string & context, bool blind)
|
|||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
|
||||
{
|
||||
|
@ -2902,6 +2994,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
|
|||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if(callFXS()->_flags.check(Kflags::FXS_OFFHOOK) &&
|
||||
callFXS()->_flags.check(Kflags::FXS_FLASH_TRANSFER))
|
||||
{
|
||||
|
@ -2922,7 +3015,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
|
|||
|
||||
callFXS()->_flash_transfer += e->AddInfo;
|
||||
|
||||
/* begin context adjusting + processing */
|
||||
// begin context adjusting + processing
|
||||
MatchExtension::ContextListType contexts;
|
||||
|
||||
validContexts(contexts);
|
||||
|
@ -2949,7 +3042,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
|
|||
case MatchExtension::MATCH_MORE:
|
||||
DBG(FUNC, PVT_FMT(target(), "match more..."));
|
||||
|
||||
/* can match, will match more, and it's an external call? */
|
||||
// can match, will match more, and it's an external call?
|
||||
for (DestVectorType::const_iterator i = Opt::_options._fxs_co_dialtone().begin(); i != Opt::_options._fxs_co_dialtone().end(); i++)
|
||||
{
|
||||
if (callFXS()->_flash_transfer == (*i))
|
||||
|
@ -2975,6 +3068,7 @@ bool BoardE1::KhompPvtFXS::onDtmfDetected(K3L_EVENT *e)
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
ret = KhompPvt::onDtmfDetected(e);
|
||||
|
@ -3042,6 +3136,7 @@ bool BoardE1::KhompPvtFXS::onFlashDetected(K3L_EVENT *e)
|
|||
|
||||
/******************************************************************************/
|
||||
//Old implementation, not used
|
||||
/*
|
||||
if(callFXS()->_flags.check(Kflags::FXS_FLASH_TRANSFER))
|
||||
{
|
||||
DBG(FUNC, PVT_FMT(_target, "(FXS) transfer canceled"));
|
||||
|
@ -3078,6 +3173,7 @@ bool BoardE1::KhompPvtFXS::onFlashDetected(K3L_EVENT *e)
|
|||
DBG(FUNC, PVT_FMT(target(), "(FXS) r (unable to start transfer)"));
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
/******************************************************************************/
|
||||
|
||||
}
|
||||
|
@ -3208,6 +3304,7 @@ bool BoardE1::KhompPvtFXS::doChannelHangup(CommandRequest &cmd)
|
|||
{
|
||||
ScopedPvtLock lock(this);
|
||||
|
||||
/*
|
||||
if(!callFXS()->_uuid_other_session.empty())
|
||||
{
|
||||
DBG(FUNC,PVT_FMT(_target, "unable to transfer"));
|
||||
|
@ -3225,6 +3322,7 @@ bool BoardE1::KhompPvtFXS::doChannelHangup(CommandRequest &cmd)
|
|||
}
|
||||
callFXS()->_uuid_other_session.clear();
|
||||
}
|
||||
*/
|
||||
|
||||
if (call()->_flags.check(Kflags::IS_INCOMING))
|
||||
{
|
||||
|
|
|
@ -75,11 +75,14 @@ void Opt::initialize(void)
|
|||
Globals::options.add(Config::Option("recording", &Options::_recording, true));
|
||||
Globals::options.add(Config::Option("has-ctbus", &Options::_has_ctbus, false));
|
||||
Globals::options.add(Config::Option("fxs-bina", &Options::_fxs_bina, true));
|
||||
Globals::options.add(Config::Option("fxo-send-pre-audio", &Options::_fxo_send_pre_audio, true));
|
||||
Globals::options.add(Config::Option("fxs-sharp-dial", &Options::_fxs_sharp_dial, true));
|
||||
Globals::options.add(Config::Option("drop-collect-call", &Options::_drop_collect_call, false));
|
||||
Globals::options.add(Config::Option("ignore-letter-dtmfs", &Options::_ignore_letter_dtmfs, true));
|
||||
Globals::options.add(Config::Option("optimize-audio-path", &Options::_optimize_audio_path, false));
|
||||
|
||||
Globals::options.add(Config::Option("fxo-send-pre-audio", &Options::_fxo_send_pre_audio, true));
|
||||
Globals::options.add(Config::Option("fxo-busy-disconnection", &Options::_fxo_busy_disconnection, 1250u, 50u, 90000u));
|
||||
|
||||
Globals::options.add(Config::Option("auto-fax-adjustment", &Options::_auto_fax_adjustment, true));
|
||||
Globals::options.add(Config::Option("fax-adjustment-timeout", &Options::_fax_adjustment_timeout, 30u, 3u, 9999u));
|
||||
|
||||
|
|
|
@ -78,8 +78,6 @@ static SpecRetType processSpecAtom(std::string & atom, SpecFlagsType & flags, Sp
|
|||
return processSpecAtoms(allocstr, flags, fun);
|
||||
}
|
||||
|
||||
//Regex::Expression e("(((([bB])[ ]*([0-9]+))|(([sS])[ ]*([0-9]+)))[ ]*(([cClL])[ ]*([0-9]+)[ ]*([-][ ]*([0-9]+))?)?)|(([rR])[ ]*([0-9]+)[ ]*([-][ ]*([0-9]+))?)", Regex::E_EXTENDED);
|
||||
|
||||
Regex::Match what(allocstr, Globals::regex_allocation);
|
||||
|
||||
if (!what.matched())
|
||||
|
|
|
@ -244,19 +244,24 @@ bool MatchExtension::canMatch(std::string & context, std::string & exten,
|
|||
return true;
|
||||
}
|
||||
|
||||
size_t finished = exten.find('#');
|
||||
|
||||
if(finished != std::string::npos)
|
||||
if (Opt::_options._fxs_sharp_dial())
|
||||
{
|
||||
if(exten.size() <= 1)
|
||||
{
|
||||
DBG(FUNC, FMT("exten=%s size=%d") % exten % exten.size());
|
||||
return true;
|
||||
}
|
||||
char key_digit = '#';
|
||||
size_t finished = exten.find_last_of(key_digit);
|
||||
char last_char = exten.at(exten.size() - 1);
|
||||
|
||||
exten.erase(finished);
|
||||
DBG(FUNC, FMT("match exact!!! exten=%s") % exten);
|
||||
return false;
|
||||
if(finished != std::string::npos && last_char == key_digit)
|
||||
{
|
||||
if(exten.size() <= 1)
|
||||
{
|
||||
DBG(FUNC, FMT("exten=%s size=%d") % exten % exten.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
exten.erase(finished);
|
||||
DBG(FUNC, FMT("match exact!!! exten=%s") % exten);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue