Implemented configurable method to send DTMFs: using the protocol, inband, rfc2833 or chat message.

git-svn-id: http://voip.null.ro/svn/yate@4003 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2010-12-22 08:47:45 +00:00
parent 84129ca775
commit c850455ea0
2 changed files with 68 additions and 9 deletions

View File

@ -105,6 +105,15 @@
; This parameter can be overridden from routing
;redirectcount=0
; dtmfmethod: string: Default value for the method used to send DTMFs
; Allowed values:
; jingle: Use the jingle protocol
; rfc2833: Send RFC 2833 DTMFs
; inband: Generate inband tones
; chat: Send tones as chat messages
; This parameter can be overridden from routing
;dtmfmethod=jingle
[codecs]
; This section allows to individually enable or disable the codecs

View File

@ -306,6 +306,8 @@ private:
bool m_offerRawTransport; // Offer RAW transport on outgoing session
bool m_offerIceTransport; // Offer ICE transport on outgoing session
unsigned int m_redirectCount; // Redirect counter
int m_dtmfMeth; // Used DMTF method
String m_rtpId; // Started RTP id
// Crypto (for contents created by us)
bool m_secure; // The channel is using crypto
bool m_secureRequired; // Crypto is mandatory
@ -381,6 +383,14 @@ private:
class YJGDriver : public Driver
{
public:
// Dtmf type
enum DtmfType {
DtmfUnknown = 0,
DtmfRfc2833, // Send RFC 2833 tones
DtmfInband, // Send inband tones
DtmfJingle, // Use the jingle protocol
DtmfChat // Send chat
};
YJGDriver();
virtual ~YJGDriver();
// Check if a message was sent by us
@ -510,6 +520,7 @@ static bool s_offerRawTransport = true; // Offer RAW UDP transport on
static bool s_offerIceTransport = true; // Offer ICE UDP transport on outgoing sessions
static int s_priority = 0; // Resource priority for presence generated by this module
static unsigned int s_redirectCount = 0; // Redirect counter
static int s_dtmfMeth; // Default DTMF method to use
static JGSession::Version s_sessVersion = JGSession::VersionUnknown; // Default jingle session version for outgoing calls
static String s_capsNode = "http://yate.null.ro/yate/jingle/caps"; // node for entity capabilities
static bool s_serverMode = true; // Server/client mode
@ -569,6 +580,15 @@ static TokenDict s_errMap[] = {
{0,0}
};
// Error mapping
static const TokenDict s_dictDtmfMeth[] = {
{"rfc2833", YJGDriver::DtmfRfc2833},
{"inband", YJGDriver::DtmfInband},
{"jingle", YJGDriver::DtmfJingle},
{"chat", YJGDriver::DtmfChat},
{0,0}
};
static inline void addValidParam(Message& m, const char* param, const char* value)
{
@ -721,7 +741,7 @@ YJGConnection::YJGConnection(Message& msg, const char* caller, const char* calle
m_callerPrompt(msg.getValue("callerprompt")),
m_localip(localip),
m_offerRawTransport(true), m_offerIceTransport(true),
m_redirectCount(s_redirectCount),
m_redirectCount(s_redirectCount), m_dtmfMeth(s_dtmfMeth),
m_secure(s_useCrypto), m_secureRequired(s_cryptoMandatory),
m_hangup(false), m_timeout(0), m_transferring(false), m_recvTransferStanza(0),
m_dataFlags(0), m_ftStatus(FTNone), m_ftHostDirection(FTHostNone),
@ -729,6 +749,7 @@ YJGConnection::YJGConnection(Message& msg, const char* caller, const char* calle
{
int redir = msg.getIntValue("redirectcount",m_redirectCount);
m_redirectCount = (redir >= 0) ? redir : 0;
m_dtmfMeth = msg.getIntValue("dtmfmethod",s_dictDtmfMeth,s_dtmfMeth);
m_secure = msg.getBoolValue("secure",m_secure);
m_secureRequired = msg.getBoolValue("secure_required",m_secureRequired);
overrideJingleVersion(msg,false);
@ -814,7 +835,8 @@ YJGConnection::YJGConnection(JGEvent* event)
m_sessVersion(event->session()->version()),
m_local(event->session()->local()), m_remote(event->session()->remote()),
m_audioContent(0),
m_offerRawTransport(true), m_offerIceTransport(true), m_redirectCount(0),
m_offerRawTransport(true), m_offerIceTransport(true),
m_redirectCount(0), m_dtmfMeth(s_dtmfMeth),
m_secure(s_useCrypto), m_secureRequired(s_cryptoMandatory),
m_hangup(false), m_timeout(0), m_transferring(false), m_recvTransferStanza(0),
m_dataFlags(0), m_ftStatus(FTNone), m_ftHostDirection(FTHostNone),
@ -1043,8 +1065,11 @@ bool YJGConnection::msgAnswered(Message& msg)
{
Debug(this,DebugCall,"msgAnswered [%p]",this);
if (m_ftStatus == FTNone) {
if (m_sessVersion != JGSession::Version0)
if (m_sessVersion != JGSession::Version0) {
clearEndpoint();
Lock lock(m_mutex);
m_rtpId.clear();
}
m_mutex.lock();
if (m_sessVersion != JGSession::Version0 || !m_rtpStarted)
resetCurrentAudioContent(true,false,true);
@ -1213,18 +1238,35 @@ bool YJGConnection::msgTone(Message& msg, const char* tone)
DDebug(this,DebugCall,"msgTone. '%s' [%p]",tone,this);
if (!(tone && *tone))
return true;
int meth = msg.getIntValue("method",s_dictDtmfMeth,m_dtmfMeth);
Lock lock(m_mutex);
// Inband and RFC 2833 require an active local RTP stream
if (meth == YJGDriver::DtmfInband) {
if (m_rtpId && dtmfInband(tone))
return true;
}
else if (meth == YJGDriver::DtmfRfc2833) {
if (m_rtpId) {
msg.setParam("targetid",m_rtpId);
return false;
}
}
if (!m_session)
return true;
return false;
if (s_singleTone) {
char s[2] = {0,0};
while (*tone) {
s[0] = *tone++;
m_session->sendDtmf(s);
if (meth != YJGDriver::DtmfChat)
m_session->sendDtmf(s);
else
s_jingle->sendMessage(m_session,s);
}
}
else
else if (meth != YJGDriver::DtmfChat)
m_session->sendDtmf(tone);
else
s_jingle->sendMessage(m_session,tone);
return true;
}
@ -1991,6 +2033,7 @@ bool YJGConnection::updateCandidate(unsigned int component, JGSessionContent& lo
rtp = 0;
clearEndpoint();
m_rtpStarted = false;
m_rtpId.clear();
}
}
// Any other transport type accepted only initially
@ -2064,8 +2107,10 @@ void YJGConnection::removeContent(JGSessionContent* c)
// add a new identical content and remove the old old one from the session
void YJGConnection::removeCurrentAudioContent(bool removeReq)
{
if (!dataFlags(OnHold))
if (!dataFlags(OnHold)) {
clearEndpoint();
m_rtpId.clear();
}
if (!m_audioContent)
return;
@ -2206,6 +2251,7 @@ bool YJGConnection::startRtp()
return false;
}
m_rtpId = m.getValue("rtpid");
rtpLocal->m_port = m.getValue("localport");
Debug(this,DebugAll,
@ -2232,7 +2278,7 @@ bool YJGConnection::startRtp()
m_audioContent->m_rtpRemoteCandidates.m_ufrag);
msg->addParam("remoteip",rtpRemote->m_address.c_str());
msg->addParam("remoteport",rtpRemote->m_port);
msg->addParam("userid",m.getValue("rtpid"));
msg->addParam("userid",m_rtpId);
Engine::enqueue(msg);
}
else if (m_audioContent->m_rtpLocalCandidates.m_type == JGRtpCandidates::RtpRawUdp) {
@ -2923,8 +2969,10 @@ void YJGConnection::handleAudioInfoEvent(JGEvent* event)
m->setParam(what->tag(),String::boolText(true));
// Clear endpoint before dispatching the message
// Our data source/consumer may be replaced
if (hold)
if (hold) {
clearEndpoint();
m_rtpId.clear();
}
Engine::dispatch(*m);
TelEngine::destruct(m);
// Reset data transport when put on hold
@ -2998,6 +3046,7 @@ void YJGConnection::copySessionParams(NamedList& list, bool redirect)
jingleAddParam(list,"secure_required",String::boolText(m_secureRequired),copy);
jingleAddParam(list,"offerrawudp",String::boolText(m_offerRawTransport),copy);
jingleAddParam(list,"offericeudp",String::boolText(m_offerIceTransport),copy);
jingleAddParam(list,"dtmfmethod",lookup(m_dtmfMeth,s_dictDtmfMeth),copy,false);
// File transfer
JGSessionContent* c = firstFTContent();
if (!c)
@ -3300,6 +3349,7 @@ void YJGDriver::initialize()
s_offerIceTransport = sect->getBoolValue("offericeudp",true);
int redir = sect->getIntValue("redirectcount");
s_redirectCount = (redir >= 0) ? redir : 0;
s_dtmfMeth = sect->getIntValue("dtmfmethod",s_dictDtmfMeth,DtmfJingle);
int prio = sect->getIntValue("resource_priority");
if (prio < -128)