Added capability to mark or block duplicate DTMFs detected by different methods.
git-svn-id: http://yate.null.ro/svn/yate/trunk@1954 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
49ef252006
commit
0f630bd627
|
@ -105,3 +105,6 @@ h323chan.yate=yes
|
||||||
|
|
||||||
; maxchans: int: Maximum number of channels running at once in each driver
|
; maxchans: int: Maximum number of channels running at once in each driver
|
||||||
;maxchans=0
|
;maxchans=0
|
||||||
|
|
||||||
|
; dtmfdups: bool: Allow duplicate DTMFs (detected with different methods)
|
||||||
|
;dtmfdups=disable
|
||||||
|
|
|
@ -282,7 +282,7 @@ Channel::Channel(Driver* driver, const char* id, bool outgoing)
|
||||||
: CallEndpoint(id),
|
: CallEndpoint(id),
|
||||||
m_driver(driver), m_outgoing(outgoing),
|
m_driver(driver), m_outgoing(outgoing),
|
||||||
m_timeout(0), m_maxcall(0),
|
m_timeout(0), m_maxcall(0),
|
||||||
m_sequence(0), m_answered(false)
|
m_dtmfSeq(0), m_answered(false)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ Channel::Channel(Driver& driver, const char* id, bool outgoing)
|
||||||
: CallEndpoint(id),
|
: CallEndpoint(id),
|
||||||
m_driver(&driver), m_outgoing(outgoing),
|
m_driver(&driver), m_outgoing(outgoing),
|
||||||
m_timeout(0), m_maxcall(0),
|
m_timeout(0), m_maxcall(0),
|
||||||
m_sequence(0), m_answered(false)
|
m_dtmfSeq(0), m_answered(false)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -435,11 +435,6 @@ void Channel::complete(Message& msg, bool minimal) const
|
||||||
msg.setParam("id",id());
|
msg.setParam("id",id());
|
||||||
if (m_driver)
|
if (m_driver)
|
||||||
msg.setParam("module",m_driver->name());
|
msg.setParam("module",m_driver->name());
|
||||||
if ((msg == "chan.dtmf") && !msg.getParam("sequence")) {
|
|
||||||
// need to add sequence number used to detect reorders
|
|
||||||
Lock lock(mutex());
|
|
||||||
msg.addParam("sequence",String(m_sequence++));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minimal)
|
if (minimal)
|
||||||
return;
|
return;
|
||||||
|
@ -568,6 +563,14 @@ bool Channel::msgMasquerade(Message& msg)
|
||||||
Debug(this,DebugInfo,"Masquerading ringing operation [%p]",this);
|
Debug(this,DebugInfo,"Masquerading ringing operation [%p]",this);
|
||||||
status("ringing");
|
status("ringing");
|
||||||
}
|
}
|
||||||
|
else if (msg == "chan.dtmf") {
|
||||||
|
// add sequence, stop the message if it was a disallowed DTMF duplicate
|
||||||
|
if (dtmfSequence(msg) && m_driver && !m_driver->m_dtmfDups) {
|
||||||
|
Debug(this,DebugInfo,"Stopping duplicate DTMF '%s' [%p]",
|
||||||
|
msg.getValue("text"),this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,6 +687,41 @@ void Channel::callRejected(const char* error, const char* reason, const Message*
|
||||||
status("rejected");
|
status("rejected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Channel::dtmfSequence(Message& msg)
|
||||||
|
{
|
||||||
|
if ((msg != "chan.dtmf") || msg.getParam("sequence"))
|
||||||
|
return false;
|
||||||
|
bool duplicate = false;
|
||||||
|
const String* detected = msg.getParam("detected");
|
||||||
|
const String* text = msg.getParam("text");
|
||||||
|
Lock lock(mutex());
|
||||||
|
unsigned int seq = m_dtmfSeq;
|
||||||
|
if (text && detected && (*text == m_dtmfText) && (*detected != m_dtmfDetected))
|
||||||
|
duplicate = true;
|
||||||
|
else {
|
||||||
|
seq = ++m_dtmfSeq;
|
||||||
|
m_dtmfText = text;
|
||||||
|
m_dtmfDetected = detected;
|
||||||
|
}
|
||||||
|
// need to add sequence number used to detect reorders
|
||||||
|
msg.addParam("sequence",String(seq));
|
||||||
|
msg.addParam("duplicate",String::boolText(duplicate));
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Channel::dtmfEnqueue(Message* msg)
|
||||||
|
{
|
||||||
|
if (!msg)
|
||||||
|
return false;
|
||||||
|
if (dtmfSequence(*msg) && m_driver && !m_driver->m_dtmfDups) {
|
||||||
|
Debug(this,DebugInfo,"Dropping duplicate DTMF '%s' [%p]",
|
||||||
|
msg->getValue("text"),this);
|
||||||
|
TelEngine::destruct(msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Engine::enqueue(msg);
|
||||||
|
}
|
||||||
|
|
||||||
bool Channel::dtmfInband(const char* tone)
|
bool Channel::dtmfInband(const char* tone)
|
||||||
{
|
{
|
||||||
if (null(tone))
|
if (null(tone))
|
||||||
|
@ -1038,7 +1076,7 @@ Driver::Driver(const char* name, const char* type)
|
||||||
m_init(false), m_varchan(true),
|
m_init(false), m_varchan(true),
|
||||||
m_routing(0), m_routed(0), m_total(0),
|
m_routing(0), m_routed(0), m_total(0),
|
||||||
m_nextid(0), m_timeout(0),
|
m_nextid(0), m_timeout(0),
|
||||||
m_maxroute(0), m_maxchans(0)
|
m_maxroute(0), m_maxchans(0), m_dtmfDups(false)
|
||||||
{
|
{
|
||||||
m_prefix << name << "/";
|
m_prefix << name << "/";
|
||||||
}
|
}
|
||||||
|
@ -1323,6 +1361,7 @@ void Driver::loadLimits()
|
||||||
timeout(Engine::config().getIntValue("telephony","timeout"));
|
timeout(Engine::config().getIntValue("telephony","timeout"));
|
||||||
maxRoute(Engine::config().getIntValue("telephony","maxroute"));
|
maxRoute(Engine::config().getIntValue("telephony","maxroute"));
|
||||||
maxChans(Engine::config().getIntValue("telephony","maxchans"));
|
maxChans(Engine::config().getIntValue("telephony","maxchans"));
|
||||||
|
dtmfDups(Engine::config().getBoolValue("telephony","dtmfdups"));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Driver::nextid()
|
unsigned int Driver::nextid()
|
||||||
|
|
|
@ -1370,7 +1370,8 @@ void YateH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned
|
||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
m->addParam("text",buf);
|
m->addParam("text",buf);
|
||||||
m->addParam("duration",String(duration));
|
m->addParam("duration",String(duration));
|
||||||
Engine::enqueue(m);
|
m->addParam("detected","h323");
|
||||||
|
m_chan->dtmfEnqueue(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void YateH323Connection::OnUserInputString(const PString &value)
|
void YateH323Connection::OnUserInputString(const PString &value)
|
||||||
|
|
|
@ -1655,7 +1655,8 @@ void AnalogChannel::evDigits(const char* text, bool tone)
|
||||||
m->addParam("text",text);
|
m->addParam("text",text);
|
||||||
if (!tone)
|
if (!tone)
|
||||||
m->addParam("pulse",String::boolText(true));
|
m->addParam("pulse",String::boolText(true));
|
||||||
Engine::enqueue(m);
|
m->addParam("detected","analog");
|
||||||
|
dtmfEnqueue(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line got off hook. Terminate ringing
|
// Line got off hook. Terminate ringing
|
||||||
|
@ -2334,6 +2335,7 @@ void AnalogCallRec::evDigits(bool fxsEvent, const char* text, bool tone)
|
||||||
if (!tone)
|
if (!tone)
|
||||||
m->addParam("pulse",String::boolText(true));
|
m->addParam("pulse",String::boolText(true));
|
||||||
m->addParam("sender",callertype(fxsEvent));
|
m->addParam("sender",callertype(fxsEvent));
|
||||||
|
m->addParam("detected","analog");
|
||||||
Engine::enqueue(m);
|
Engine::enqueue(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -386,6 +386,7 @@ void MGCPWrapper::gotDTMF(char tone)
|
||||||
m->addParam("id",m_master);
|
m->addParam("id",m_master);
|
||||||
m->addParam("message","chan.dtmf");
|
m->addParam("message","chan.dtmf");
|
||||||
m->addParam("text",buf);
|
m->addParam("text",buf);
|
||||||
|
m->addParam("detected","mgcp");
|
||||||
Engine::enqueue(m);
|
Engine::enqueue(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -884,7 +884,7 @@ void SigChannel::evInfo(SignallingEvent* event)
|
||||||
Message* m = message("chan.dtmf");
|
Message* m = message("chan.dtmf");
|
||||||
m->addParam("text",tmp);
|
m->addParam("text",tmp);
|
||||||
m->addParam("detected",inband ? "inband" : "signal");
|
m->addParam("detected",inband ? "inband" : "signal");
|
||||||
Engine::enqueue(m);
|
dtmfEnqueue(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1563,7 +1563,7 @@ void YIAXConnection::handleEvent(IAXEvent* event)
|
||||||
Message* m = message("chan.dtmf");
|
Message* m = message("chan.dtmf");
|
||||||
m->addParam("text",dtmf);
|
m->addParam("text",dtmf);
|
||||||
m->addParam("detected","iax-event");
|
m->addParam("detected","iax-event");
|
||||||
Engine::enqueue(m);
|
dtmfEnqueue(m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IAXEvent::Noise:
|
case IAXEvent::Noise:
|
||||||
|
|
|
@ -1351,7 +1351,8 @@ void YJGConnection::handleEvent(JGEvent* event)
|
||||||
if (event->reason() == "button-up" && event->text()) {
|
if (event->reason() == "button-up" && event->text()) {
|
||||||
Message* m = message("chan.dtmf");
|
Message* m = message("chan.dtmf");
|
||||||
m->addParam("text",event->text());
|
m->addParam("text",event->text());
|
||||||
Engine::enqueue(m);
|
m->addParam("detected","jingle");
|
||||||
|
dtmfEnqueue(m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case JGSession::ActDtmfMethod:
|
case JGSession::ActDtmfMethod:
|
||||||
|
|
|
@ -3313,7 +3313,7 @@ void YateSIPConnection::doInfo(SIPTransaction* t)
|
||||||
copySipHeaders(*msg,*t->initialMessage());
|
copySipHeaders(*msg,*t->initialMessage());
|
||||||
msg->addParam("text",tmp);
|
msg->addParam("text",tmp);
|
||||||
msg->addParam("detected","sip-info");
|
msg->addParam("detected","sip-info");
|
||||||
Engine::enqueue(msg);
|
dtmfEnqueue(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
yatephone.h
26
yatephone.h
|
@ -1491,7 +1491,9 @@ private:
|
||||||
bool m_outgoing;
|
bool m_outgoing;
|
||||||
u_int64_t m_timeout;
|
u_int64_t m_timeout;
|
||||||
u_int64_t m_maxcall;
|
u_int64_t m_maxcall;
|
||||||
mutable unsigned int m_sequence;
|
unsigned int m_dtmfSeq;
|
||||||
|
String m_dtmfText;
|
||||||
|
String m_dtmfDetected;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String m_status;
|
String m_status;
|
||||||
|
@ -1867,6 +1869,20 @@ protected:
|
||||||
inline void setOutgoing(bool outgoing = true)
|
inline void setOutgoing(bool outgoing = true)
|
||||||
{ m_outgoing = outgoing; }
|
{ m_outgoing = outgoing; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add sequence number to chan.dtmf message, check for duplicates
|
||||||
|
* @param msg chan.dtmf message to apply sequence number
|
||||||
|
* @return True if the message is a duplicate (same tone, different method)
|
||||||
|
*/
|
||||||
|
bool dtmfSequence(Message& msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add sequence number to chan.dtmf and enqueue it, delete if duplicate
|
||||||
|
* @param msg chan.dtmf message to sequence and enqueue
|
||||||
|
* @return True if the message was enqueued, false if was a duplicate
|
||||||
|
*/
|
||||||
|
bool dtmfEnqueue(Message* msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to install an override data source to send DTMF inband.
|
* Attempt to install an override data source to send DTMF inband.
|
||||||
* Needs a tone generator module capable to override with "tone/dtmfstr/xyz"
|
* Needs a tone generator module capable to override with "tone/dtmfstr/xyz"
|
||||||
|
@ -1909,6 +1925,7 @@ private:
|
||||||
int m_timeout;
|
int m_timeout;
|
||||||
int m_maxroute;
|
int m_maxroute;
|
||||||
int m_maxchans;
|
int m_maxchans;
|
||||||
|
bool m_dtmfDups;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -2121,6 +2138,13 @@ protected:
|
||||||
inline void maxChans(int ncalls)
|
inline void maxChans(int ncalls)
|
||||||
{ m_maxchans = ncalls; }
|
{ m_maxchans = ncalls; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the DTMF duplicates allowed flag
|
||||||
|
* @param duplicates True to allow DTMF duplicate messages
|
||||||
|
*/
|
||||||
|
inline void dtmfDups(bool duplicates)
|
||||||
|
{ m_dtmfDups = duplicates; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Driver(); // no default constructor please
|
Driver(); // no default constructor please
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue