Added google raw udp transport support for jingle version 1.

git-svn-id: http://yate.null.ro/svn/yate/trunk@5031 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2012-04-30 09:47:59 +00:00
parent ef715381cb
commit 4d3033bff4
5 changed files with 61 additions and 15 deletions

View File

@ -37,6 +37,7 @@ const TokenDict JGRtpCandidates::s_type[] = {
{"ice-udp", RtpIceUdp},
{"raw-udp", RtpRawUdp},
{"p2p", RtpP2P},
{"google-raw-udp", RtpGoogleRawUdp},
{0,0},
};
@ -589,9 +590,13 @@ void JGRtpCandidate::fromXml(XmlElement* xml, const JGRtpCandidates& container)
// Create a 'candidate' element from this object
XmlElement* JGRtpCandidateP2P::toXml(const JGRtpCandidates& container) const
{
if (container.m_type != JGRtpCandidates::RtpP2P)
if (container.m_type != JGRtpCandidates::RtpP2P &&
container.m_type != JGRtpCandidates::RtpGoogleRawUdp)
return 0;
XmlElement* xml = XMPPUtils::createElement(XmlTag::Candidate);
int ns = XMPPNamespace::Count;
if (container.m_type != JGRtpCandidates::RtpP2P)
ns = XMPPNamespace::JingleTransport;
XmlElement* xml = XMPPUtils::createElement(XmlTag::Candidate,ns);
xml->setAttribute("name","rtp");
xml->setAttributeValid("generation",m_generation);
xml->setAttributeValid("address",m_address);
@ -608,7 +613,8 @@ XmlElement* JGRtpCandidateP2P::toXml(const JGRtpCandidates& container) const
// Fill this object from a candidate element
void JGRtpCandidateP2P::fromXml(XmlElement* xml, const JGRtpCandidates& container)
{
if (!xml || container.m_type != JGRtpCandidates::RtpP2P)
if (!xml || (container.m_type != JGRtpCandidates::RtpP2P &&
container.m_type != JGRtpCandidates::RtpGoogleRawUdp))
return;
m_component = "1";
m_generation = xml->attribute("generation");
@ -635,6 +641,8 @@ XmlElement* JGRtpCandidates::toXml(bool addCandidates, bool addAuth) const
ns = XMPPNamespace::JingleTransportRawUdp;
else if (m_type == RtpP2P)
ns = XMPPNamespace::JingleTransport;
else if (m_type == RtpGoogleRawUdp)
ns = XMPPNamespace::JingleTransportGoogleRawUdp;
else
return 0;
XmlElement* trans = XMPPUtils::createElement(XmlTag::Transport,ns);
@ -659,22 +667,27 @@ void JGRtpCandidates::fromXml(XmlElement* element)
return;
// Set transport data
int ns = XMPPUtils::xmlns(*element);
int candidateNs = ns;
if (ns == XMPPNamespace::JingleTransportIceUdp)
m_type = RtpIceUdp;
else if (ns == XMPPNamespace::JingleTransportRawUdp)
m_type = RtpRawUdp;
else if (ns == XMPPNamespace::JingleTransport)
m_type = RtpP2P;
else if (ns == XMPPNamespace::JingleTransportGoogleRawUdp) {
m_type = RtpGoogleRawUdp;
candidateNs = XMPPNamespace::JingleTransport;
}
else
return;
if (m_type != RtpP2P) {
if (m_type != RtpP2P && m_type != RtpGoogleRawUdp) {
m_password = element->getAttribute("pwd");
m_ufrag = element->getAttribute("ufrag");
}
// Get candidates
XmlElement* c = XMPPUtils::findFirstChild(*element,XmlTag::Candidate,ns);
for (; c; c = XMPPUtils::findNextChild(*element,c,XmlTag::Candidate,ns))
if (m_type != RtpP2P)
XmlElement* c = XMPPUtils::findFirstChild(*element,XmlTag::Candidate,candidateNs);
for (; c; c = XMPPUtils::findNextChild(*element,c,XmlTag::Candidate,candidateNs))
if (candidateNs != XMPPNamespace::JingleTransport)
append(new JGRtpCandidate(c,*this));
else
append(new JGRtpCandidateP2P(c,*this));
@ -745,7 +758,8 @@ XmlElement* JGSessionContent::toXml(bool minimum, bool addDesc,
// Add description and transport
XmlElement* desc = 0;
XmlElement* trans = 0;
if (m_type == RtpIceUdp || m_type == RtpRawUdp || m_type == RtpP2P) {
if (m_type == RtpIceUdp || m_type == RtpRawUdp || m_type == RtpP2P ||
m_type == RtpGoogleRawUdp) {
// Audio content
if (addDesc)
desc = m_rtpMedia.toXml();
@ -868,6 +882,8 @@ JGSessionContent* JGSessionContent::fromXml(XmlElement* xml, XMPPError::Type& er
content->m_type = RtpRawUdp;
else if (content->m_rtpRemoteCandidates.m_type == JGRtpCandidates::RtpP2P)
content->m_type = RtpP2P;
else if (content->m_rtpRemoteCandidates.m_type == JGRtpCandidates::RtpGoogleRawUdp)
content->m_type = RtpGoogleRawUdp;
}
else {
if (offer >= 0) {

View File

@ -106,6 +106,7 @@ const String XMPPNamespace::s_array[Count] = {
"jabber:x:data", // XData
"http://jabber.org/protocol/chatstates", // ChatStates
"http://yate.null.ro/yate/cluster", // YateCluster
"http://www.google.com/transport/raw-udp", // JingleTransportGoogleRawUdp
};
const String XMPPError::s_array[Count] = {

View File

@ -190,6 +190,7 @@ public:
XData, // jabber:x:data
ChatStates, // http://jabber.org/protocol/chatstates
YateCluster, // http://yate.null.ro/yate/cluster
JingleTransportGoogleRawUdp, // http://www.google.com/transport/raw-udp
// This value MUST be the last one: it's used as array bound
Count,
};

View File

@ -508,6 +508,7 @@ public:
RtpIceUdp = 1,
RtpRawUdp,
RtpP2P,
RtpGoogleRawUdp,
};
/**
@ -615,6 +616,7 @@ public:
RtpIceUdp = 1, // Audio: RTP ICE-UDP transport
RtpRawUdp, // Audio: RTP RAW-UDP transport
RtpP2P, //
RtpGoogleRawUdp, //
FileBSBOffer, // File offer: byte stream (SOCKS) transport
FileBSBRequest, // File request: byte stream (SOCKS) transport
};

View File

@ -315,6 +315,7 @@ private:
bool m_offerRawTransport; // Offer RAW transport on outgoing session
bool m_offerIceTransport; // Offer ICE transport on outgoing session
bool m_offerP2PTransport; // Offer P2P transport on outgoing session
bool m_offerGRawTransport; // Offer Google raw transport on outgoing session
unsigned int m_redirectCount; // Redirect counter
int m_dtmfMeth; // Used DMTF method
String m_rtpId; // Started RTP id
@ -529,6 +530,7 @@ static bool s_acceptRelay = false;
static bool s_offerRawTransport = true; // Offer RAW UDP transport on outgoing sessions
static bool s_offerIceTransport = true; // Offer ICE UDP transport on outgoing sessions
static bool s_offerP2PTransport = false; // Offer P2P UDP transport on outgoing sessions
static bool s_offerGRawTransport = false; // Offer Google RAW 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
@ -806,7 +808,8 @@ YJGConnection::YJGConnection(Message& msg, const char* caller, const char* calle
m_audioFormats(JGRtpMediaList::Audio),
m_callerPrompt(msg.getValue("callerprompt")),
m_localip(localip),
m_offerRawTransport(true), m_offerIceTransport(true), m_offerP2PTransport(false),
m_offerRawTransport(true), m_offerIceTransport(true),
m_offerP2PTransport(false), m_offerGRawTransport(false),
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),
@ -826,6 +829,7 @@ YJGConnection::YJGConnection(Message& msg, const char* caller, const char* calle
m_offerRawTransport = msg.getBoolValue("offerrawudp",s_offerRawTransport);
m_offerIceTransport = msg.getBoolValue("offericeudp",s_offerIceTransport);
m_offerP2PTransport = msg.getBoolValue("offerp2p",s_offerP2PTransport);
m_offerGRawTransport = msg.getBoolValue("offergraw",s_offerGRawTransport);
}
else
m_offerRawTransport = false;
@ -910,7 +914,8 @@ YJGConnection::YJGConnection(JGEvent* event)
m_local(event->session()->local()), m_remote(event->session()->remote()),
m_audioContent(0),
m_audioFormats(JGRtpMediaList::Audio),
m_offerRawTransport(true), m_offerIceTransport(true), m_offerP2PTransport(false),
m_offerRawTransport(true), m_offerIceTransport(true),
m_offerP2PTransport(false), m_offerGRawTransport(false),
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),
@ -957,6 +962,7 @@ YJGConnection::YJGConnection(JGEvent* event)
case JGSessionContent::RtpIceUdp:
case JGSessionContent::RtpRawUdp:
case JGSessionContent::RtpP2P:
case JGSessionContent::RtpGoogleRawUdp:
haveAudioSession = haveAudioSession || c->isSession();
addContent(false,c);
break;
@ -1863,6 +1869,8 @@ bool YJGConnection::presenceChanged(bool available, NamedList* params)
addContent(true,buildAudioContent(JGRtpCandidates::RtpIceUdp));
if (m_offerP2PTransport)
addContent(true,buildAudioContent(JGRtpCandidates::RtpP2P));
if (m_offerGRawTransport)
addContent(true,buildAudioContent(JGRtpCandidates::RtpGoogleRawUdp));
m_session = s_jingle->call(m_sessVersion,m_local,m_remote,m_audioContents,transfer,
m_callerPrompt,m_subject,m_line,&m_sessFlags);
// Init now the transport for version 0
@ -2135,7 +2143,8 @@ bool YJGConnection::updateCandidate(unsigned int component, JGSessionContent& lo
#endif
// Version0 or p2p transport: check acceptable transport
if (m_sessVersion == JGSession::Version0 ||
local.type() == JGSessionContent::RtpP2P) {
local.type() == JGSessionContent::RtpP2P ||
local.type() == JGSessionContent::RtpGoogleRawUdp) {
// We only handle UDP based transports for now
if (rtpRecv->m_protocol != "udp")
return false;
@ -2193,9 +2202,18 @@ void YJGConnection::addContent(bool local, JGSessionContent* c)
else
c->m_rtpLocalCandidates.generateOldIceAuth();
}
Debug(this,DebugAll,"Added content='%s' type=%s initiator=%s [%p]",
String tmp;
#ifdef DEBUG
JGRtpCandidate* rtp = local ? c->m_rtpLocalCandidates.findByComponent(1) :
c->m_rtpRemoteCandidates.findByComponent(1);
if (rtp) {
tmp << " candidate: ";
dumpCandidate(tmp,rtp);
}
#endif
Debug(this,DebugAll,"Added content='%s' type=%s initiator=%s%s [%p]",
c->toString().c_str(),c->m_rtpLocalCandidates.typeName(),
String::boolText(c->creator() == JGSessionContent::CreatorInitiator),this);
String::boolText(c->creator() == JGSessionContent::CreatorInitiator),tmp.safe(),this);
}
// Remove a content from list
@ -2469,6 +2487,7 @@ bool YJGConnection::processContentAdd(const JGEvent& event, ObjList& ok, ObjList
case JGSessionContent::RtpIceUdp:
case JGSessionContent::RtpRawUdp:
case JGSessionContent::RtpP2P:
case JGSessionContent::RtpGoogleRawUdp:
break;
case JGSessionContent::FileBSBOffer:
case JGSessionContent::FileBSBRequest:
@ -2623,6 +2642,8 @@ JGSessionContent* YJGConnection::buildAudioContent(JGRtpCandidates::Type type,
t = JGSessionContent::RtpIceUdp;
else if (type == JGRtpCandidates::RtpP2P)
t = JGSessionContent::RtpP2P;
else if (type == JGRtpCandidates::RtpGoogleRawUdp)
t = JGSessionContent::RtpGoogleRawUdp;
JGSessionContent* c = new JGSessionContent(t,id,senders,
isOutgoing() ? JGSessionContent::CreatorInitiator : JGSessionContent::CreatorResponder);
@ -2632,7 +2653,8 @@ JGSessionContent* YJGConnection::buildAudioContent(JGRtpCandidates::Type type,
c->m_rtpMedia.m_cryptoRequired = true;
if (useFormats)
c->m_rtpMedia.setMedia(m_audioFormats);
if (m_sessVersion == JGSession::Version0 || type == JGRtpCandidates::RtpP2P) {
if (m_sessVersion == JGSession::Version0 || type == JGRtpCandidates::RtpP2P ||
type == JGRtpCandidates::RtpGoogleRawUdp){
// Hack: set second telephone event for implementations expecting it
c->m_rtpMedia.m_telEventName2 = "audio/telephone-event";
}
@ -2690,7 +2712,9 @@ bool YJGConnection::initLocalCandidates(JGSessionContent& content, bool sendTran
JGRtpCandidate* rtp = content.m_rtpLocalCandidates.findByComponent(1);
bool incGeneration = (0 != rtp);
if (!rtp) {
rtp = buildCandidate(content.type() != JGSessionContent::RtpP2P);
bool nonP2P = content.type() != JGSessionContent::RtpP2P &&
content.type() != JGSessionContent::RtpGoogleRawUdp;
rtp = buildCandidate(nonP2P);
content.m_rtpLocalCandidates.append(rtp);
}
@ -3244,6 +3268,7 @@ void YJGConnection::copySessionParams(NamedList& list, bool redirect)
jingleAddParam(list,"offerrawudp",String::boolText(m_offerRawTransport),copy);
jingleAddParam(list,"offericeudp",String::boolText(m_offerIceTransport),copy);
jingleAddParam(list,"offerp2p",String::boolText(m_offerP2PTransport),copy);
jingleAddParam(list,"offergraw",String::boolText(m_offerGRawTransport),copy);
jingleAddParam(list,"dtmfmethod",lookup(m_dtmfMeth,s_dictDtmfMeth),copy,false);
// File transfer
JGSessionContent* c = firstFTContent();
@ -3698,6 +3723,7 @@ void YJGDriver::initialize()
s_offerRawTransport = sect->getBoolValue("offerrawudp",true);
s_offerIceTransport = sect->getBoolValue("offericeudp",true);
s_offerP2PTransport = sect->getBoolValue("offerp2p",false);
s_offerGRawTransport = sect->getBoolValue("offergraw",false);
int redir = sect->getIntValue("redirectcount");
s_redirectCount = (redir >= 0) ? redir : 0;
s_dtmfMeth = sect->getIntValue("dtmfmethod",s_dictDtmfMeth,DtmfJingle);