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=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),
|
||||
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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
26
yatephone.h
26
yatephone.h
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue