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:
paulc 2008-04-25 13:11:49 +00:00
parent 49ef252006
commit 0f630bd627
10 changed files with 86 additions and 15 deletions

View File

@ -105,3 +105,6 @@ h323chan.yate=yes
; maxchans: int: Maximum number of channels running at once in each driver
;maxchans=0
; dtmfdups: bool: Allow duplicate DTMFs (detected with different methods)
;dtmfdups=disable

View File

@ -282,7 +282,7 @@ Channel::Channel(Driver* driver, const char* id, bool outgoing)
: CallEndpoint(id),
m_driver(driver), m_outgoing(outgoing),
m_timeout(0), m_maxcall(0),
m_sequence(0), m_answered(false)
m_dtmfSeq(0), m_answered(false)
{
init();
}
@ -291,7 +291,7 @@ Channel::Channel(Driver& driver, const char* id, bool outgoing)
: CallEndpoint(id),
m_driver(&driver), m_outgoing(outgoing),
m_timeout(0), m_maxcall(0),
m_sequence(0), m_answered(false)
m_dtmfSeq(0), m_answered(false)
{
init();
}
@ -435,11 +435,6 @@ void Channel::complete(Message& msg, bool minimal) const
msg.setParam("id",id());
if (m_driver)
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)
return;
@ -568,6 +563,14 @@ bool Channel::msgMasquerade(Message& msg)
Debug(this,DebugInfo,"Masquerading ringing operation [%p]",this);
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;
}
@ -684,6 +687,41 @@ void Channel::callRejected(const char* error, const char* reason, const Message*
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)
{
if (null(tone))
@ -1038,7 +1076,7 @@ Driver::Driver(const char* name, const char* type)
m_init(false), m_varchan(true),
m_routing(0), m_routed(0), m_total(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 << "/";
}
@ -1323,6 +1361,7 @@ void Driver::loadLimits()
timeout(Engine::config().getIntValue("telephony","timeout"));
maxRoute(Engine::config().getIntValue("telephony","maxroute"));
maxChans(Engine::config().getIntValue("telephony","maxchans"));
dtmfDups(Engine::config().getBoolValue("telephony","dtmfdups"));
}
unsigned int Driver::nextid()

View File

@ -1370,7 +1370,8 @@ void YateH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned
buf[1] = 0;
m->addParam("text",buf);
m->addParam("duration",String(duration));
Engine::enqueue(m);
m->addParam("detected","h323");
m_chan->dtmfEnqueue(m);
}
void YateH323Connection::OnUserInputString(const PString &value)

View File

@ -1655,7 +1655,8 @@ void AnalogChannel::evDigits(const char* text, bool tone)
m->addParam("text",text);
if (!tone)
m->addParam("pulse",String::boolText(true));
Engine::enqueue(m);
m->addParam("detected","analog");
dtmfEnqueue(m);
}
// Line got off hook. Terminate ringing
@ -2334,6 +2335,7 @@ void AnalogCallRec::evDigits(bool fxsEvent, const char* text, bool tone)
if (!tone)
m->addParam("pulse",String::boolText(true));
m->addParam("sender",callertype(fxsEvent));
m->addParam("detected","analog");
Engine::enqueue(m);
}

View File

@ -386,6 +386,7 @@ void MGCPWrapper::gotDTMF(char tone)
m->addParam("id",m_master);
m->addParam("message","chan.dtmf");
m->addParam("text",buf);
m->addParam("detected","mgcp");
Engine::enqueue(m);
}

View File

@ -884,7 +884,7 @@ void SigChannel::evInfo(SignallingEvent* event)
Message* m = message("chan.dtmf");
m->addParam("text",tmp);
m->addParam("detected",inband ? "inband" : "signal");
Engine::enqueue(m);
dtmfEnqueue(m);
}
}

View File

@ -1563,7 +1563,7 @@ void YIAXConnection::handleEvent(IAXEvent* event)
Message* m = message("chan.dtmf");
m->addParam("text",dtmf);
m->addParam("detected","iax-event");
Engine::enqueue(m);
dtmfEnqueue(m);
}
break;
case IAXEvent::Noise:

View File

@ -1351,7 +1351,8 @@ void YJGConnection::handleEvent(JGEvent* event)
if (event->reason() == "button-up" && event->text()) {
Message* m = message("chan.dtmf");
m->addParam("text",event->text());
Engine::enqueue(m);
m->addParam("detected","jingle");
dtmfEnqueue(m);
}
break;
case JGSession::ActDtmfMethod:

View File

@ -3313,7 +3313,7 @@ void YateSIPConnection::doInfo(SIPTransaction* t)
copySipHeaders(*msg,*t->initialMessage());
msg->addParam("text",tmp);
msg->addParam("detected","sip-info");
Engine::enqueue(msg);
dtmfEnqueue(msg);
}
}

View File

@ -1491,7 +1491,9 @@ private:
bool m_outgoing;
u_int64_t m_timeout;
u_int64_t m_maxcall;
mutable unsigned int m_sequence;
unsigned int m_dtmfSeq;
String m_dtmfText;
String m_dtmfDetected;
protected:
String m_status;
@ -1867,6 +1869,20 @@ protected:
inline void setOutgoing(bool outgoing = true)
{ 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.
* Needs a tone generator module capable to override with "tone/dtmfstr/xyz"
@ -1909,6 +1925,7 @@ private:
int m_timeout;
int m_maxroute;
int m_maxchans;
bool m_dtmfDups;
public:
/**
@ -2121,6 +2138,13 @@ protected:
inline void maxChans(int 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:
Driver(); // no default constructor please
};