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:
parent
84129ca775
commit
c850455ea0
|
@ -105,6 +105,15 @@
|
||||||
; This parameter can be overridden from routing
|
; This parameter can be overridden from routing
|
||||||
;redirectcount=0
|
;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]
|
[codecs]
|
||||||
; This section allows to individually enable or disable the codecs
|
; This section allows to individually enable or disable the codecs
|
||||||
|
|
|
@ -306,6 +306,8 @@ private:
|
||||||
bool m_offerRawTransport; // Offer RAW transport on outgoing session
|
bool m_offerRawTransport; // Offer RAW transport on outgoing session
|
||||||
bool m_offerIceTransport; // Offer ICE transport on outgoing session
|
bool m_offerIceTransport; // Offer ICE transport on outgoing session
|
||||||
unsigned int m_redirectCount; // Redirect counter
|
unsigned int m_redirectCount; // Redirect counter
|
||||||
|
int m_dtmfMeth; // Used DMTF method
|
||||||
|
String m_rtpId; // Started RTP id
|
||||||
// Crypto (for contents created by us)
|
// Crypto (for contents created by us)
|
||||||
bool m_secure; // The channel is using crypto
|
bool m_secure; // The channel is using crypto
|
||||||
bool m_secureRequired; // Crypto is mandatory
|
bool m_secureRequired; // Crypto is mandatory
|
||||||
|
@ -381,6 +383,14 @@ private:
|
||||||
class YJGDriver : public Driver
|
class YJGDriver : public Driver
|
||||||
{
|
{
|
||||||
public:
|
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();
|
YJGDriver();
|
||||||
virtual ~YJGDriver();
|
virtual ~YJGDriver();
|
||||||
// Check if a message was sent by us
|
// 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 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 int s_priority = 0; // Resource priority for presence generated by this module
|
||||||
static unsigned int s_redirectCount = 0; // Redirect counter
|
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 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 String s_capsNode = "http://yate.null.ro/yate/jingle/caps"; // node for entity capabilities
|
||||||
static bool s_serverMode = true; // Server/client mode
|
static bool s_serverMode = true; // Server/client mode
|
||||||
|
@ -569,6 +580,15 @@ static TokenDict s_errMap[] = {
|
||||||
{0,0}
|
{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)
|
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_callerPrompt(msg.getValue("callerprompt")),
|
||||||
m_localip(localip),
|
m_localip(localip),
|
||||||
m_offerRawTransport(true), m_offerIceTransport(true),
|
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_secure(s_useCrypto), m_secureRequired(s_cryptoMandatory),
|
||||||
m_hangup(false), m_timeout(0), m_transferring(false), m_recvTransferStanza(0),
|
m_hangup(false), m_timeout(0), m_transferring(false), m_recvTransferStanza(0),
|
||||||
m_dataFlags(0), m_ftStatus(FTNone), m_ftHostDirection(FTHostNone),
|
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);
|
int redir = msg.getIntValue("redirectcount",m_redirectCount);
|
||||||
m_redirectCount = (redir >= 0) ? redir : 0;
|
m_redirectCount = (redir >= 0) ? redir : 0;
|
||||||
|
m_dtmfMeth = msg.getIntValue("dtmfmethod",s_dictDtmfMeth,s_dtmfMeth);
|
||||||
m_secure = msg.getBoolValue("secure",m_secure);
|
m_secure = msg.getBoolValue("secure",m_secure);
|
||||||
m_secureRequired = msg.getBoolValue("secure_required",m_secureRequired);
|
m_secureRequired = msg.getBoolValue("secure_required",m_secureRequired);
|
||||||
overrideJingleVersion(msg,false);
|
overrideJingleVersion(msg,false);
|
||||||
|
@ -814,7 +835,8 @@ YJGConnection::YJGConnection(JGEvent* event)
|
||||||
m_sessVersion(event->session()->version()),
|
m_sessVersion(event->session()->version()),
|
||||||
m_local(event->session()->local()), m_remote(event->session()->remote()),
|
m_local(event->session()->local()), m_remote(event->session()->remote()),
|
||||||
m_audioContent(0),
|
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_secure(s_useCrypto), m_secureRequired(s_cryptoMandatory),
|
||||||
m_hangup(false), m_timeout(0), m_transferring(false), m_recvTransferStanza(0),
|
m_hangup(false), m_timeout(0), m_transferring(false), m_recvTransferStanza(0),
|
||||||
m_dataFlags(0), m_ftStatus(FTNone), m_ftHostDirection(FTHostNone),
|
m_dataFlags(0), m_ftStatus(FTNone), m_ftHostDirection(FTHostNone),
|
||||||
|
@ -1043,8 +1065,11 @@ bool YJGConnection::msgAnswered(Message& msg)
|
||||||
{
|
{
|
||||||
Debug(this,DebugCall,"msgAnswered [%p]",this);
|
Debug(this,DebugCall,"msgAnswered [%p]",this);
|
||||||
if (m_ftStatus == FTNone) {
|
if (m_ftStatus == FTNone) {
|
||||||
if (m_sessVersion != JGSession::Version0)
|
if (m_sessVersion != JGSession::Version0) {
|
||||||
clearEndpoint();
|
clearEndpoint();
|
||||||
|
Lock lock(m_mutex);
|
||||||
|
m_rtpId.clear();
|
||||||
|
}
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
if (m_sessVersion != JGSession::Version0 || !m_rtpStarted)
|
if (m_sessVersion != JGSession::Version0 || !m_rtpStarted)
|
||||||
resetCurrentAudioContent(true,false,true);
|
resetCurrentAudioContent(true,false,true);
|
||||||
|
@ -1213,18 +1238,35 @@ bool YJGConnection::msgTone(Message& msg, const char* tone)
|
||||||
DDebug(this,DebugCall,"msgTone. '%s' [%p]",tone,this);
|
DDebug(this,DebugCall,"msgTone. '%s' [%p]",tone,this);
|
||||||
if (!(tone && *tone))
|
if (!(tone && *tone))
|
||||||
return true;
|
return true;
|
||||||
|
int meth = msg.getIntValue("method",s_dictDtmfMeth,m_dtmfMeth);
|
||||||
Lock lock(m_mutex);
|
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)
|
if (!m_session)
|
||||||
return true;
|
return false;
|
||||||
if (s_singleTone) {
|
if (s_singleTone) {
|
||||||
char s[2] = {0,0};
|
char s[2] = {0,0};
|
||||||
while (*tone) {
|
while (*tone) {
|
||||||
s[0] = *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);
|
m_session->sendDtmf(tone);
|
||||||
|
else
|
||||||
|
s_jingle->sendMessage(m_session,tone);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1991,6 +2033,7 @@ bool YJGConnection::updateCandidate(unsigned int component, JGSessionContent& lo
|
||||||
rtp = 0;
|
rtp = 0;
|
||||||
clearEndpoint();
|
clearEndpoint();
|
||||||
m_rtpStarted = false;
|
m_rtpStarted = false;
|
||||||
|
m_rtpId.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Any other transport type accepted only initially
|
// 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
|
// add a new identical content and remove the old old one from the session
|
||||||
void YJGConnection::removeCurrentAudioContent(bool removeReq)
|
void YJGConnection::removeCurrentAudioContent(bool removeReq)
|
||||||
{
|
{
|
||||||
if (!dataFlags(OnHold))
|
if (!dataFlags(OnHold)) {
|
||||||
clearEndpoint();
|
clearEndpoint();
|
||||||
|
m_rtpId.clear();
|
||||||
|
}
|
||||||
if (!m_audioContent)
|
if (!m_audioContent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2206,6 +2251,7 @@ bool YJGConnection::startRtp()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_rtpId = m.getValue("rtpid");
|
||||||
rtpLocal->m_port = m.getValue("localport");
|
rtpLocal->m_port = m.getValue("localport");
|
||||||
|
|
||||||
Debug(this,DebugAll,
|
Debug(this,DebugAll,
|
||||||
|
@ -2232,7 +2278,7 @@ bool YJGConnection::startRtp()
|
||||||
m_audioContent->m_rtpRemoteCandidates.m_ufrag);
|
m_audioContent->m_rtpRemoteCandidates.m_ufrag);
|
||||||
msg->addParam("remoteip",rtpRemote->m_address.c_str());
|
msg->addParam("remoteip",rtpRemote->m_address.c_str());
|
||||||
msg->addParam("remoteport",rtpRemote->m_port);
|
msg->addParam("remoteport",rtpRemote->m_port);
|
||||||
msg->addParam("userid",m.getValue("rtpid"));
|
msg->addParam("userid",m_rtpId);
|
||||||
Engine::enqueue(msg);
|
Engine::enqueue(msg);
|
||||||
}
|
}
|
||||||
else if (m_audioContent->m_rtpLocalCandidates.m_type == JGRtpCandidates::RtpRawUdp) {
|
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));
|
m->setParam(what->tag(),String::boolText(true));
|
||||||
// Clear endpoint before dispatching the message
|
// Clear endpoint before dispatching the message
|
||||||
// Our data source/consumer may be replaced
|
// Our data source/consumer may be replaced
|
||||||
if (hold)
|
if (hold) {
|
||||||
clearEndpoint();
|
clearEndpoint();
|
||||||
|
m_rtpId.clear();
|
||||||
|
}
|
||||||
Engine::dispatch(*m);
|
Engine::dispatch(*m);
|
||||||
TelEngine::destruct(m);
|
TelEngine::destruct(m);
|
||||||
// Reset data transport when put on hold
|
// 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,"secure_required",String::boolText(m_secureRequired),copy);
|
||||||
jingleAddParam(list,"offerrawudp",String::boolText(m_offerRawTransport),copy);
|
jingleAddParam(list,"offerrawudp",String::boolText(m_offerRawTransport),copy);
|
||||||
jingleAddParam(list,"offericeudp",String::boolText(m_offerIceTransport),copy);
|
jingleAddParam(list,"offericeudp",String::boolText(m_offerIceTransport),copy);
|
||||||
|
jingleAddParam(list,"dtmfmethod",lookup(m_dtmfMeth,s_dictDtmfMeth),copy,false);
|
||||||
// File transfer
|
// File transfer
|
||||||
JGSessionContent* c = firstFTContent();
|
JGSessionContent* c = firstFTContent();
|
||||||
if (!c)
|
if (!c)
|
||||||
|
@ -3300,6 +3349,7 @@ void YJGDriver::initialize()
|
||||||
s_offerIceTransport = sect->getBoolValue("offericeudp",true);
|
s_offerIceTransport = sect->getBoolValue("offericeudp",true);
|
||||||
int redir = sect->getIntValue("redirectcount");
|
int redir = sect->getIntValue("redirectcount");
|
||||||
s_redirectCount = (redir >= 0) ? redir : 0;
|
s_redirectCount = (redir >= 0) ? redir : 0;
|
||||||
|
s_dtmfMeth = sect->getIntValue("dtmfmethod",s_dictDtmfMeth,DtmfJingle);
|
||||||
|
|
||||||
int prio = sect->getIntValue("resource_priority");
|
int prio = sect->getIntValue("resource_priority");
|
||||||
if (prio < -128)
|
if (prio < -128)
|
||||||
|
|
Loading…
Reference in New Issue