Allow send dtmf method(s) to be configurable. Detect remote party INFO support from 'Allow' header.
git-svn-id: http://voip.null.ro/svn/yate@5264 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
c12e643719
commit
de2b64b26b
|
@ -94,11 +94,38 @@
|
|||
; transactions unless a retransmission arrives before having a final answer
|
||||
;lazy100=no
|
||||
|
||||
; dtmfinband: bool: Generate DTMF inband by default
|
||||
;dtmfinband=no
|
||||
; check_allow_info: bool: Check 'Allow' header in INVITE and OK for INFO support
|
||||
; If enabled and INFO is not supported the 'info' dtmf method will be disabled
|
||||
; This parameter can be overridden from routing by 'ocheck_allow_info' for outgoing call leg
|
||||
; and 'icheck_allow_info' for incoming call leg
|
||||
; This parameter is ignored if info method is not enabled
|
||||
; This parameter is applied on reload for new calls only
|
||||
;check_allow_info=yes
|
||||
|
||||
; dtmfinfo: bool: Generate INFO messages to send keypad tones
|
||||
;dtmfinfo=no
|
||||
; missing_allow_info: bool: The default value for dtmf info support if
|
||||
; 'check_allow_info' is enabled and the 'Allow' header is missing
|
||||
; This parameter can be overridden from routing by 'omissing_allow_info' for outgoing call leg
|
||||
; and 'imissing_allow_info' for incoming call leg
|
||||
; This parameter is applied on reload for new calls only
|
||||
;missing_allow_info=enable
|
||||
|
||||
; dtmfmethods: string: Comma separated list of methods used to send DTMFs
|
||||
; Allowed values in list:
|
||||
; info: Use SIP INFO if initial transaction finished
|
||||
; rfc2833: Use RFC 2833 signals if remote party advertised support
|
||||
; inband: Send tones in audio stream
|
||||
; The methods will be used in the listed order
|
||||
; Defaults to 'rfc2833,info,inband' if missing or empty
|
||||
; Invalid values are ignored
|
||||
; E.g.
|
||||
; 'info,foo' leads to 'info'
|
||||
; 'foo,foo1' leads to 'rfc2833,info,inband'
|
||||
; This parameter can be overridden from routing by 'odtmfmethods' for outgoing call leg
|
||||
; and 'idtmfmethods' for incoming call leg
|
||||
; Also, this parameter can be overridden in chan.dtmf messages by a 'methods' parameter
|
||||
; NOTE: When overridden from chan.dtmf an empty or invalid 'methods' parameter will be ignored
|
||||
; This parameter is applied on reload for new calls only
|
||||
;dtmfmethods=rfc2833,info,inband
|
||||
|
||||
; rfc2833: bool: Offer RFC2833 telephone-event by default
|
||||
; A numeric payload >= 96 can be provided
|
||||
|
|
|
@ -144,6 +144,58 @@ private:
|
|||
ProtocolHolder() {} // No default
|
||||
};
|
||||
|
||||
class DtmfMethods
|
||||
{
|
||||
public:
|
||||
enum Method {
|
||||
Info,
|
||||
Rfc2833,
|
||||
Inband,
|
||||
MethodCount
|
||||
};
|
||||
inline DtmfMethods()
|
||||
{ setDefault(); }
|
||||
inline void set(int _0 = MethodCount, int _1 = MethodCount, int _2 = MethodCount) {
|
||||
m_methods[0] = _0;
|
||||
m_methods[1] = _1;
|
||||
m_methods[2] = _2;
|
||||
}
|
||||
inline void setDefault()
|
||||
{ set(Rfc2833,Info,Inband); }
|
||||
// Replace all methods from comma separated list
|
||||
// If no method is set use other or setDefEmpty (reset to default)
|
||||
// Return false if methods contain unknown methods
|
||||
bool set(const String& methods, const DtmfMethods* other, bool setDefEmpty = true);
|
||||
// Retrieve a method from deperecated parameters
|
||||
// Reset the method if the parameter is false
|
||||
// Display a message anyway if warn is not false
|
||||
// Return true if the parameter was found
|
||||
bool getDeprecatedDtmfMethod(const NamedList& list, const char* param, int method, bool* warn);
|
||||
// Reset a method
|
||||
void reset(int method);
|
||||
// Build a string list from methods
|
||||
void buildMethods(String& buf, const char* sep = ",");
|
||||
bool hasMethod(int method);
|
||||
inline void printMethods(DebugEnabler* enabler, int level, const String& str) {
|
||||
String tmp;
|
||||
buildMethods(tmp);
|
||||
Debug(enabler,level,"Built DTMF methods '%s' from '%s'",tmp.safe(),str.safe());
|
||||
}
|
||||
inline int operator[](unsigned int index) {
|
||||
if (index < MethodCount)
|
||||
return m_methods[index];
|
||||
return MethodCount;
|
||||
}
|
||||
inline DtmfMethods& operator=(const DtmfMethods& other) {
|
||||
for (int i = 0; i < MethodCount; i++)
|
||||
m_methods[i] = other.m_methods[i];
|
||||
return *this;
|
||||
}
|
||||
static const TokenDict s_methodName[];
|
||||
protected:
|
||||
int m_methods[MethodCount];
|
||||
};
|
||||
|
||||
// A SIP party holder
|
||||
class YateSIPPartyHolder : public ProtocolHolder
|
||||
{
|
||||
|
@ -883,6 +935,8 @@ private:
|
|||
MimeBody* buildSIPBody();
|
||||
// Update NAT address from params or transport
|
||||
void updateRtpNatAddress(NamedList* params = 0);
|
||||
// Process allow list. Get INFO support
|
||||
bool infoAllowed(const SIPMessage* msg);
|
||||
|
||||
SIPTransaction* m_tr;
|
||||
SIPTransaction* m_tr2;
|
||||
|
@ -907,8 +961,9 @@ private:
|
|||
Message* m_route;
|
||||
ObjList* m_routes;
|
||||
bool m_authBye;
|
||||
bool m_inband;
|
||||
bool m_info;
|
||||
bool m_checkAllowInfo; // Check Allow in INVITE and OK for INFO support
|
||||
bool m_missingAllowInfoDefVal; // Default INFO support if Allow header is missing
|
||||
DtmfMethods m_dtmfMethods;
|
||||
// REFER already running
|
||||
bool m_referring;
|
||||
// reINVITE requested or in progress
|
||||
|
@ -1037,8 +1092,6 @@ static int s_nat_refresh = 25;
|
|||
static bool s_privacy = false;
|
||||
static bool s_auto_nat = true;
|
||||
static bool s_progress = false;
|
||||
static bool s_inband = false;
|
||||
static bool s_info = false;
|
||||
static bool s_start_rtp = false;
|
||||
static bool s_ack_required = true;
|
||||
static bool s_1xx_formats = true;
|
||||
|
@ -1072,6 +1125,24 @@ static u_int64_t s_printFloodTime = 0;
|
|||
|
||||
int YateSIPEndPoint::s_evCount = 0;
|
||||
|
||||
// DTMF methods
|
||||
static bool s_checkAllowInfo = true; // Check Allow in INVITE and OK for INFO support
|
||||
static bool s_missingAllowInfoDefVal = true; // Default INFO support if Allow header is missing
|
||||
static DtmfMethods s_dtmfMethods;
|
||||
// Deprecated dtmf params warn
|
||||
static bool s_warnDtmfInfoCfg = true;
|
||||
static bool s_warnDtmfInbandCfg = true;
|
||||
static bool s_warnDtmfInfoCallExecute = true;
|
||||
static bool s_warnDtmfInbandCallExecute = true;
|
||||
static bool s_warnDtmfMethodChanDtmf = true;
|
||||
|
||||
const TokenDict DtmfMethods::s_methodName[] = {
|
||||
{ "info", Info},
|
||||
{ "rfc2833", Rfc2833},
|
||||
{ "inband", Inband},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
// Lower case proto name
|
||||
const TokenDict ProtocolHolder::s_protoLC[] = {
|
||||
{ "udp", Udp},
|
||||
|
@ -1777,6 +1848,79 @@ static void setAuthError(SIPTransaction* trans, const NamedList& params,
|
|||
}
|
||||
|
||||
|
||||
// Replace all methods from comma separated list
|
||||
// If no method is set use other or setDefEmpty (reset to default)
|
||||
bool DtmfMethods::set(const String& methods, const DtmfMethods* other, bool setDefEmpty)
|
||||
{
|
||||
set();
|
||||
bool found = false;
|
||||
bool ok = true;
|
||||
ObjList* m = methods.split(',');
|
||||
int i = 0;
|
||||
for (ObjList* o = m->skipNull(); o && i < MethodCount; o = o->skipNext()) {
|
||||
String* s = static_cast<String*>(o->get());
|
||||
int meth = lookup(s->trimBlanks(),s_methodName,MethodCount);
|
||||
if (meth != MethodCount) {
|
||||
m_methods[i++] = meth;
|
||||
found = true;
|
||||
}
|
||||
else if (*s)
|
||||
ok = false;
|
||||
}
|
||||
TelEngine::destruct(m);
|
||||
if (!found) {
|
||||
if (other)
|
||||
*this = *other;
|
||||
else if (setDefEmpty)
|
||||
setDefault();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Retrieve a method from deperecated parameters
|
||||
// Reset the method if the parameter is false
|
||||
// Display a message anyway if warn is not false
|
||||
bool DtmfMethods::getDeprecatedDtmfMethod(const NamedList& list, const char* param,
|
||||
int method, bool* warn)
|
||||
{
|
||||
String* p = list.getParam(param);
|
||||
if (!p)
|
||||
return false;
|
||||
if (!p->toBoolean())
|
||||
reset(method);
|
||||
if (warn && *warn) {
|
||||
*warn = false;
|
||||
Debug(&plugin,DebugConf,"Deprecated '%s' in '%s'. Use 'dtmfmethods' instead!",param,list.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reset a method
|
||||
void DtmfMethods::reset(int method)
|
||||
{
|
||||
for (int i = 0; i < MethodCount; i++)
|
||||
if (m_methods[i] == method) {
|
||||
m_methods[i] = MethodCount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Build a string list from methods
|
||||
void DtmfMethods::buildMethods(String& buf, const char* sep)
|
||||
{
|
||||
for (int i = 0; i < MethodCount; i++)
|
||||
buf.append(lookup(m_methods[i],s_methodName),sep);
|
||||
}
|
||||
|
||||
bool DtmfMethods::hasMethod(int method)
|
||||
{
|
||||
for (int i = 0; i < MethodCount; i++)
|
||||
if (m_methods[i] == method)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool YateSIPPartyHolder::change(String& dest, const String& src)
|
||||
{
|
||||
if (dest == src)
|
||||
|
@ -4913,7 +5057,8 @@ YateSIPConnection::YateSIPConnection(SIPEvent* ev, SIPTransaction* tr)
|
|||
YateSIPPartyHolder(driver()),
|
||||
m_tr(tr), m_tr2(0), m_hungup(false), m_byebye(true), m_cancel(false),
|
||||
m_state(Incoming), m_port(0), m_route(0), m_routes(0),
|
||||
m_authBye(true), m_inband(s_inband), m_info(s_info),
|
||||
m_authBye(true),
|
||||
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
|
||||
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0)
|
||||
{
|
||||
Debug(this,DebugAll,"YateSIPConnection::YateSIPConnection(%p,%p) [%p]",ev,tr,this);
|
||||
|
@ -4931,6 +5076,10 @@ YateSIPConnection::YateSIPConnection(SIPEvent* ev, SIPTransaction* tr)
|
|||
// Set channel SIP party
|
||||
setParty(m_tr->initialMessage()->getParty());
|
||||
updateRtpNatAddress();
|
||||
// Get dtmf methods
|
||||
s_globalMutex.lock();
|
||||
m_dtmfMethods = s_dtmfMethods;
|
||||
s_globalMutex.unlock();
|
||||
|
||||
URI uri(m_tr->getURI());
|
||||
YateSIPLine* line = plugin.findLine(m_host,m_port,uri.getUser());
|
||||
|
@ -5080,15 +5229,26 @@ YateSIPConnection::YateSIPConnection(Message& msg, const String& uri, const char
|
|||
YateSIPPartyHolder(driver()),
|
||||
m_tr(0), m_tr2(0), m_hungup(false), m_byebye(true), m_cancel(true),
|
||||
m_state(Outgoing), m_port(0), m_route(0), m_routes(0),
|
||||
m_authBye(false), m_inband(s_inband), m_info(s_info),
|
||||
m_authBye(false),
|
||||
m_checkAllowInfo(s_checkAllowInfo), m_missingAllowInfoDefVal(s_missingAllowInfoDefVal),
|
||||
m_referring(false), m_reInviting(ReinviteNone), m_lastRseq(0)
|
||||
{
|
||||
Debug(this,DebugAll,"YateSIPConnection::YateSIPConnection(%p,'%s') [%p]",
|
||||
&msg,uri.c_str(),this);
|
||||
m_targetid = target;
|
||||
setReason();
|
||||
m_inband = msg.getBoolValue(YSTRING("dtmfinband"),s_inband);
|
||||
m_info = msg.getBoolValue(YSTRING("dtmfinfo"),s_info);
|
||||
m_checkAllowInfo = msg.getBoolValue(YSTRING("ocheck_allow_info"),m_checkAllowInfo);
|
||||
m_missingAllowInfoDefVal = msg.getBoolValue(YSTRING("omissing_allow_info"),m_missingAllowInfoDefVal);
|
||||
String* meths = msg.getParam("odtmfmethods");
|
||||
s_globalMutex.lock();
|
||||
if (meths)
|
||||
m_dtmfMethods.set(*meths,&s_dtmfMethods);
|
||||
else {
|
||||
m_dtmfMethods = s_dtmfMethods;
|
||||
m_dtmfMethods.getDeprecatedDtmfMethod(msg,"dtmfinfo",DtmfMethods::Info,&s_warnDtmfInfoCallExecute);
|
||||
m_dtmfMethods.getDeprecatedDtmfMethod(msg,"dtmfinband",DtmfMethods::Inband,&s_warnDtmfInbandCallExecute);
|
||||
}
|
||||
s_globalMutex.unlock();
|
||||
m_secure = msg.getBoolValue(YSTRING("secure"),plugin.parser().secure());
|
||||
setRfc2833(msg.getParam(YSTRING("rfc2833")));
|
||||
m_rtpForward = msg.getBoolValue(YSTRING("rtp_forward"));
|
||||
|
@ -5733,6 +5893,10 @@ bool YateSIPConnection::process(SIPEvent* ev)
|
|||
}
|
||||
|
||||
if (msg->isAnswer() && ((msg->code / 100) == 2)) {
|
||||
if (m_checkAllowInfo) {
|
||||
if (m_dtmfMethods.hasMethod(DtmfMethods::Info) && !infoAllowed(msg))
|
||||
m_dtmfMethods.reset(DtmfMethods::Info);
|
||||
}
|
||||
updateTags = false;
|
||||
m_cancel = false;
|
||||
Lock lock(driver());
|
||||
|
@ -6386,58 +6550,80 @@ bool YateSIPConnection::msgTone(Message& msg, const char* tone)
|
|||
{
|
||||
if (m_hungup)
|
||||
return false;
|
||||
bool info = m_info;
|
||||
bool inband = m_inband;
|
||||
const String* method = msg.getParam(YSTRING("method"));
|
||||
if (method) {
|
||||
if ((*method == YSTRING("info")) || (*method == YSTRING("sip-info"))) {
|
||||
info = true;
|
||||
inband = false;
|
||||
}
|
||||
else if (*method == YSTRING("rfc2833")) {
|
||||
info = false;
|
||||
inband = false;
|
||||
}
|
||||
else if (*method == YSTRING("inband")) {
|
||||
info = false;
|
||||
inband = true;
|
||||
}
|
||||
}
|
||||
// RFC 2833 and inband require that we have an active local RTP stream
|
||||
if (m_rtpMedia && (m_mediaStatus == MediaStarted) && !info) {
|
||||
ObjList* l = m_rtpMedia->find("audio");
|
||||
const SDPMedia* m = static_cast<const SDPMedia*>(l ? l->get() : 0);
|
||||
if (m) {
|
||||
if (!(inband || m->rfc2833().toBoolean(true))) {
|
||||
Debug(this,DebugNote,"Forcing DTMF '%s' inband, format '%s' [%p]",
|
||||
tone,m->format().c_str(),this);
|
||||
inband = true;
|
||||
if (TelEngine::null(tone))
|
||||
return true;
|
||||
DtmfMethods methods = m_dtmfMethods;
|
||||
const String* param = msg.getParam(YSTRING("methods"));
|
||||
if (param)
|
||||
methods.set(*param,&m_dtmfMethods);
|
||||
else {
|
||||
const String* method = msg.getParam(YSTRING("method"));
|
||||
if (method) {
|
||||
if (s_warnDtmfMethodChanDtmf) {
|
||||
s_warnDtmfMethodChanDtmf = false;
|
||||
Debug(this,DebugConf,"Deprecated 'method' parameter in '%s'. Use 'methods' instead!",msg.c_str());
|
||||
}
|
||||
if (inband && dtmfInband(tone))
|
||||
return true;
|
||||
msg.setParam("targetid",m->id());
|
||||
return false;
|
||||
if ((*method == YSTRING("info")) || (*method == YSTRING("sip-info")))
|
||||
methods.set(DtmfMethods::Info);
|
||||
else if (*method == YSTRING("rfc2833"))
|
||||
methods.set(DtmfMethods::Rfc2833);
|
||||
else if (*method == YSTRING("inband"))
|
||||
methods.set(DtmfMethods::Inband);
|
||||
}
|
||||
}
|
||||
// either INFO was requested or we have no other choice
|
||||
for (; tone && *tone; tone++) {
|
||||
char c = *tone;
|
||||
for (int i = 0; i <= 16; i++) {
|
||||
if (s_dtmfs[i] == c) {
|
||||
SIPMessage* m = createDlgMsg("INFO");
|
||||
if (m) {
|
||||
bool retVal = false;
|
||||
bool ok = false;
|
||||
for (int i = 0; !ok && i < DtmfMethods::MethodCount; i++) {
|
||||
int meth = methods[i];
|
||||
if (meth == DtmfMethods::Info) {
|
||||
// Send INFO only if initial transaction finished
|
||||
if (m_tr)
|
||||
continue;
|
||||
for (; tone && *tone; tone++) {
|
||||
char c = *tone;
|
||||
for (int j = 0; j <= 16; j++) {
|
||||
if (s_dtmfs[j] != c)
|
||||
continue;
|
||||
SIPMessage* m = createDlgMsg("INFO");
|
||||
if (!m)
|
||||
break;
|
||||
copySipHeaders(*m,msg);
|
||||
String tmp;
|
||||
tmp << "Signal=" << i << "\r\n";
|
||||
tmp << "Signal=" << j << "\r\n";
|
||||
m->setBody(new MimeStringBody("application/dtmf-relay",tmp));
|
||||
plugin.ep()->engine()->addMessage(m);
|
||||
m->deref();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ok = true;
|
||||
retVal = true;
|
||||
}
|
||||
else if (meth == DtmfMethods::Rfc2833 || meth == DtmfMethods::Inband) {
|
||||
// RFC2833 and inband require media to be started
|
||||
if (!(m_rtpMedia && (m_mediaStatus == MediaStarted)))
|
||||
continue;
|
||||
ObjList* l = m_rtpMedia->find("audio");
|
||||
const SDPMedia* m = static_cast<const SDPMedia*>(l ? l->get() : 0);
|
||||
if (!m)
|
||||
continue;
|
||||
if (meth == DtmfMethods::Rfc2833) {
|
||||
ok = m->rfc2833().toBoolean(true);
|
||||
if (ok)
|
||||
msg.setParam("targetid",m->id());
|
||||
}
|
||||
else {
|
||||
ok = dtmfInband(tone);
|
||||
retVal = ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (!ok && debugAt(DebugNote)) {
|
||||
String tmp;
|
||||
methods.buildMethods(tmp);
|
||||
Debug(this,DebugNote,"Failed to send tones '%s' methods=%s [%p]",tone,tmp.c_str(),this);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool YateSIPConnection::msgText(Message& msg, const char* text)
|
||||
|
@ -6670,6 +6856,20 @@ void YateSIPConnection::callAccept(Message& msg)
|
|||
m_rtpForward = false;
|
||||
}
|
||||
m_secure = m_secure && msg.getBoolValue(YSTRING("secure"),true);
|
||||
// Update dtmf methods from message
|
||||
m_checkAllowInfo = msg.getBoolValue(YSTRING("icheck_allow_info"),m_checkAllowInfo);
|
||||
m_missingAllowInfoDefVal = msg.getBoolValue(YSTRING("imissing_allow_info"),m_missingAllowInfoDefVal);
|
||||
String* meths = msg.getParam(YSTRING("idtmfmethods"));
|
||||
if (meths) {
|
||||
DtmfMethods old = m_dtmfMethods;
|
||||
m_dtmfMethods.set(*meths,&old);
|
||||
}
|
||||
// Reset INFO?
|
||||
if (m_checkAllowInfo && m_tr && m_dtmfMethods.hasMethod(DtmfMethods::Info)) {
|
||||
Lock lock(driver());
|
||||
if (m_tr && !infoAllowed(m_tr->initialMessage()))
|
||||
m_dtmfMethods.reset(DtmfMethods::Info);
|
||||
}
|
||||
Channel::callAccept(msg);
|
||||
|
||||
if ((m_reInviting == ReinviteNone) && !m_rtpForward && !isAnswered() &&
|
||||
|
@ -6900,6 +7100,32 @@ void YateSIPConnection::updateRtpNatAddress(NamedList* params)
|
|||
Debug(this,DebugAll,"NAT address is '%s' [%p]",m_rtpNatAddr.c_str(),this);
|
||||
}
|
||||
|
||||
// Process allow list. Get INFO support
|
||||
bool YateSIPConnection::infoAllowed(const SIPMessage* msg)
|
||||
{
|
||||
static const String s_infoName = "INFO";
|
||||
if (!msg)
|
||||
return m_missingAllowInfoDefVal;
|
||||
bool ok = false;
|
||||
const MimeHeaderLine* hdr = msg->getHeader("Allow");
|
||||
if (hdr) {
|
||||
ObjList* allows = hdr->split(',');
|
||||
for (ObjList* o = allows->skipNull(); o; o = o->skipNext()) {
|
||||
String* s = static_cast<String*>(o->get());
|
||||
s->trimBlanks().toUpper();
|
||||
if (*s == s_infoName) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TelEngine::destruct(allows);
|
||||
}
|
||||
else
|
||||
ok = m_missingAllowInfoDefVal;
|
||||
Debug(this,DebugNote,"infoAllowed: info=%u [%p]",ok,this);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
YateSIPLine::YateSIPLine(const String& name)
|
||||
: String(name), Mutex(true,"YateSIPLine"),
|
||||
|
@ -7721,15 +7947,30 @@ void SIPDriver::initialize()
|
|||
s_cfg = Engine::configFile("ysipchan");
|
||||
s_globalMutex.lock();
|
||||
s_cfg.load();
|
||||
NamedList* general = s_cfg.getSection("general");
|
||||
if (general) {
|
||||
String* dtmfMethods = general->getParam("dtmfmethods");
|
||||
if (dtmfMethods) {
|
||||
if (!s_dtmfMethods.set(*dtmfMethods,0))
|
||||
s_dtmfMethods.printMethods(this,DebugConf,*dtmfMethods);
|
||||
}
|
||||
else {
|
||||
s_dtmfMethods.setDefault();
|
||||
s_dtmfMethods.getDeprecatedDtmfMethod(*general,"dtmfinfo",DtmfMethods::Info,&s_warnDtmfInfoCfg);
|
||||
s_dtmfMethods.getDeprecatedDtmfMethod(*general,"dtmfinband",DtmfMethods::Inband,&s_warnDtmfInbandCfg);
|
||||
}
|
||||
}
|
||||
else
|
||||
s_dtmfMethods.setDefault();
|
||||
s_globalMutex.unlock();
|
||||
s_checkAllowInfo = s_cfg.getBoolValue("general","check_allow_info",true);
|
||||
s_missingAllowInfoDefVal = s_cfg.getBoolValue("general","missing_allow_info",true);
|
||||
s_maxForwards = s_cfg.getIntValue("general","maxforwards",20);
|
||||
s_floodEvents = s_cfg.getIntValue("general","floodevents",100);
|
||||
s_floodProtection = s_cfg.getBoolValue("general","floodprotection",true);
|
||||
s_privacy = s_cfg.getBoolValue("general","privacy");
|
||||
s_auto_nat = s_cfg.getBoolValue("general","nat",true);
|
||||
s_progress = s_cfg.getBoolValue("general","progress",false);
|
||||
s_inband = s_cfg.getBoolValue("general","dtmfinband",false);
|
||||
s_info = s_cfg.getBoolValue("general","dtmfinfo",false);
|
||||
s_start_rtp = s_cfg.getBoolValue("general","rtp_start",false);
|
||||
s_multi_ringing = s_cfg.getBoolValue("general","multi_ringing",false);
|
||||
s_refresh_nosdp = s_cfg.getBoolValue("general","refresh_nosdp",true);
|
||||
|
@ -7788,7 +8029,6 @@ void SIPDriver::initialize()
|
|||
// Mark listeners
|
||||
m_endpoint->initializing(true);
|
||||
// Setup general listener
|
||||
NamedList* general = s_cfg.getSection("general");
|
||||
NamedList dummy("general");
|
||||
NamedList* def = general;
|
||||
if (!def)
|
||||
|
|
Loading…
Reference in New Issue