[asterisk-scf-commits] asterisk-scf/integration/media_rtp_pjmedia.git branch "modular-transport-refactor" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Mon Jun 27 07:16:12 CDT 2011
branch "modular-transport-refactor" has been updated
via 2bb195970c1281b8fba39f609d5c6b713f42ddbc (commit)
from fe117c790109f77d0325caf620bb4b0898bbc3a6 (commit)
Summary of changes:
src/ICETransport.cpp | 290 ++++++++++++++++++++++++++++++-------------------
1 files changed, 177 insertions(+), 113 deletions(-)
- Log -----------------------------------------------------------------
commit 2bb195970c1281b8fba39f609d5c6b713f42ddbc
Author: Brent Eagles <beagles at digium.com>
Date: Fri Jun 24 13:08:24 2011 -0230
Implemented candidate value creation based on generated sdp through
the pjmedia api.
diff --git a/src/ICETransport.cpp b/src/ICETransport.cpp
index d37517c..4f9a573 100644
--- a/src/ICETransport.cpp
+++ b/src/ICETransport.cpp
@@ -28,91 +28,27 @@
#include <AsteriskSCF/System/NAT/NATTraversalIf.h>
#include <Ice/Ice.h>
+#include <sstream>
+#include <AsteriskSCF/logger.h>
+#include <IceUtil/UUID.h>
using namespace AsteriskSCF::PJMediaRTP;
using namespace AsteriskSCF::System::V1;
using namespace AsteriskSCF::PJUtil;
using namespace std;
using namespace AsteriskSCF::Helpers;
+using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::System::NAT::V1;
-namespace
-{
-
-class CandidateRecord
+namespace
{
-public:
- CandidateRecord(const pj_ice_sess_cand& pjCandidate) :
- mCandidate(new AsteriskSCF::System::NAT::V1::Candidate),
- mTransportId(pjCandidate.transport_id),
- mPreference(pjCandidate.local_pref)
- {
- mCandidate->componentId = pjCandidate.comp_id;
- mCandidate->priority = pjCandidate.prio;
- mCandidate->foundation = string(pj_strbuf(&pjCandidate.foundation), pj_strlen(&pjCandidate.foundation));
- char addrBuffer[PJ_INET6_ADDRSTRLEN];
- pj_sockaddr_print(&pjCandidate.addr, addrBuffer, sizeof(addrBuffer), 0);
- mCandidate->mappedAddress = addrBuffer;
- mCandidate->mappedPort = pj_sockaddr_get_port(&pjCandidate.addr);
- pj_sockaddr_print(&pjCandidate.base_addr, addrBuffer, sizeof(addrBuffer), 0);
- mCandidate->baseAddress = addrBuffer;
- mCandidate->basePort = pj_sockaddr_get_port(&pjCandidate.base_addr);
-
- switch (pjCandidate.type)
- {
- case PJ_ICE_CAND_TYPE_HOST:
- mCandidate->type = AsteriskSCF::System::NAT::V1::Host;
- break;
- case PJ_ICE_CAND_TYPE_SRFLX:
- mCandidate->type = AsteriskSCF::System::NAT::V1::ServerReflexive;
- break;
- case PJ_ICE_CAND_TYPE_PRFLX:
- mCandidate->type = AsteriskSCF::System::NAT::V1::PeerReflexive;
- break;
- case PJ_ICE_CAND_TYPE_RELAYED:
- mCandidate->type = AsteriskSCF::System::NAT::V1::Relayed;
- break;
- default:
- assert("Unknown candidate type" == 0);
- }
- }
-
- AsteriskSCF::System::NAT::V1::CandidatePtr getCandidate()
- {
- return mCandidate;
- }
-
- unsigned transportId()
- {
- return mTransportId;
- }
-
- unsigned localPreferenceRating()
- {
- return mPreference;
- }
-
-private:
-
- AsteriskSCF::System::NAT::V1::CandidatePtr mCandidate;
- pj_uint8_t mTransportId;
- pj_uint16_t mPreference;
-};
-
-typedef boost::shared_ptr<CandidateRecord> CandidateRecordPtr;
-typedef vector<CandidateRecordPtr> CandidateRecordSeq;
+Logger logger = getLoggerFactory().getLogger("AsteriskSCF.MediaRTP");
+}
-AsteriskSCF::System::NAT::V1::CandidateSeq convert(const CandidateRecordSeq& candidateRecords)
+namespace
{
- AsteriskSCF::System::NAT::V1::CandidateSeq result;
- result.reserve(candidateRecords.size());
- for (CandidateRecordSeq::const_iterator i = candidateRecords.begin(); i != candidateRecords.end(); ++i)
- {
- result.push_back((*i)->getCandidate());
- }
- return result;
-}
-class ICEAgentImpl : public AsteriskSCF::System::NAT::V1::InteractiveConnectionAgent
+class ICEAgentImpl : public InteractiveConnectionAgent
{
public:
@@ -120,31 +56,31 @@ public:
mAdapter(adapter),
mId(id),
mShuttingDown(false),
- mNATType(AsteriskSCF::System::NAT::V1::Unknown),
- mRole(AsteriskSCF::System::NAT::V1::UndefinedRole)
+ mNATType(Unknown),
+ mRole(UndefinedRole)
{
}
- AsteriskSCF::System::NAT::V1::AgentType getAgentType(const Ice::Current&)
+ AgentType getAgentType(const Ice::Current&)
{
- return AsteriskSCF::System::NAT::V1::Full;
+ return Full;
}
- AsteriskSCF::System::NAT::V1::DetectedNATType getNATType(const Ice::Current&)
+ DetectedNATType getNATType(const Ice::Current&)
{
boost::shared_lock<boost::shared_mutex> lock(mLock);
stateCheck();
return mNATType;
}
- AsteriskSCF::System::NAT::V1::Role getRole(const Ice::Current&)
+ Role getRole(const Ice::Current&)
{
boost::shared_lock<boost::shared_mutex> lock(mLock);
stateCheck();
return mRole;
}
- AsteriskSCF::System::NAT::V1::CandidatePtr negotiate(const AsteriskSCF::System::NAT::V1::CandidateSeq&,
+ CandidatePtr negotiate(const CandidateSeq&,
const Ice::Current&)
{
//
@@ -153,10 +89,10 @@ public:
return 0;
}
- AsteriskSCF::System::NAT::V1::CandidateSeq getCandidates(const Ice::Current&)
+ CandidateSeq getCandidates(const Ice::Current&)
{
boost::shared_lock<boost::shared_mutex> lock(mLock);
- return convert(mCandidates);
+ return mCandidates;
}
void onSetupComplete(pjmedia_transport* transport, pj_status_t status)
@@ -193,42 +129,168 @@ public:
boost::unique_lock<boost::shared_mutex> lock(mLock);
if (iceInfo->role == PJ_ICE_SESS_ROLE_CONTROLLING)
{
- setRole(AsteriskSCF::System::NAT::V1::Controlling);
+ setRole(Controlling);
}
else
{
- setRole(AsteriskSCF::System::NAT::V1::Controlled);
+ setRole(Controlled);
}
//
- // TODO: We need do different things depending on the actual
- // session state at this moment in time.
- //
-#if 0
+ // Ok, so the pjmedia ice transport won't let use get at the actual
+ // candidate structures, so what we have to do is get the SDP from
+ // the transport and convert what we find there to our Ice structures.
//
- // We have access to a lot of things, unfortunately the actual
- // pjnath ICE transport is not one of them.!!! So I have to abandon this approach.
+ pjmedia_sdp_session* sdpSession;
//
- for (size_t component = 0; component < iceInfo->comp_cnt; ++component)
+ // TODO: We are setting the transport size at 1, but I'm not sure that will always be the case.
+ //
+ pjmedia_endpt_create_sdp(mEndpoint->endpoint(), mEnv->memoryPool(), 1, &info.sock_info, &sdpSession);
+ for (size_t i = 0; i < sdpSession->media_count; ++i)
{
- size_t candidateCount = 0;
- pj_ice_sess_cand candidates[PJ_ICE_ST_MAX_CAND];
- pj_status_t enumStatus = pj_ice_strans_enum_cands(iceInfo->ice_st, component + 1,
- &candidateCount, candidates);
- if (fail(enumStatus))
+ const string candidateName("candidate");
+ pjmedia_sdp_media* media = sdpSession->media[i];
+ for (size_t j = 0; j < media->attr_count; ++j)
{
- //
- // TODO: this is unlikely to happen, but if it did, it's
- // not entirely clear whether its terminal or if it could
- // "clear up"
- //
- }
- for (size_t i = 0; i < candidateCount; ++i)
- {
- mCandidates.push_back(new CandidateRecord(candidates[i]));
+ pjmedia_sdp_attr* attr = media->attr[j];
+ if (string(attr->name.ptr, attr->name.slen) == candidateName)
+ {
+ //
+ // Now we get to parse a candidate string!
+ //
+ string value(attr->value.ptr, attr->value.slen);
+ istringstream is(value);
+ string foundation;
+ if (!(is >> foundation))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (foundation) : " << value;
+ break;
+ }
+
+ int componentId;
+ if (!(is >> componentId))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (component id) : " << value;
+ break;
+ }
+
+ //
+ // We don't care about the transport right now.. we are assuming UDP.
+ //
+ string transportDummy;
+ if (!(is >> transportDummy))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (transport) : " << value;
+ break;
+ }
+
+ int priority;
+ if (!(is >> priority))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (priority) : " << value;
+ break;
+ }
+
+ string connectionAddress;
+ if (!(is >> connectionAddress))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (connection address) : " << value;
+ break;
+ }
+
+ unsigned port;
+ if (!(is >> port))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (connection port) : " << value;
+ break;
+ }
+
+ string candidateTypePrefix;
+ if (!(is >> candidateTypePrefix))
+ {
+ logger(Error) << "Unable to parse ICE candidate constant (typ) : " << value;
+ break;
+ }
+
+ string candidateType;
+ if (!(is >> candidateType))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (candidate type) : " << value;
+ break;
+ }
+
+ CandidatePtr candidateObj = new Candidate;
+ candidateObj->sessionId = IceUtil::generateUUID(); // this should be the object id.
+ candidateObj->componentId = 1; // At least until we implement RTCP.
+ candidateObj->priority = priority;
+ candidateObj->baseAddress = connectionAddress;
+ candidateObj->basePort = port;
+ candidateObj->transport = UDP;
+
+ if (candidateType == "host")
+ {
+ candidateObj->type = Host;
+ }
+ else if (candidateType == "srflx")
+ {
+ candidateObj->type = ServerReflexive;
+ }
+ else if (candidateType == "prflx")
+ {
+ candidateObj->type = PeerReflexive;
+ }
+ else if (candidateType == "relay")
+ {
+ candidateObj->type = Relayed;
+ }
+ else
+ {
+ logger(Error) << "Unable to determine the candidate type, skipping : " << value;
+ }
+
+ if (candidateType != "host")
+ {
+ string dummy;
+ if (!(is >> dummy))
+ {
+ logger(Error) << "Unable to parse ICE candidate constant (raddr) : " << value;
+ break;
+ }
+
+ string baseAddress;
+ if (!(is >> baseAddress))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (rel-addr) : " << value;
+ break;
+ }
+
+ if (!(is >> dummy))
+ {
+ logger(Error) << "Unable to parse ICE candidate constant (rport) : " << value;
+ break;
+ }
+
+ unsigned basePort;
+ if (!(is >> basePort))
+ {
+ logger(Error) << "Unable to parse ICE candidate value (rel-port) : " << value;
+ break;
+ }
+ candidateObj->baseAddress = baseAddress;
+ candidateObj->basePort = basePort;
+ }
+ else
+ {
+ candidateObj->baseAddress = candidateObj->mappedAddress;
+ candidateObj->basePort = candidateObj->mappedPort;
+ }
+ //
+ // And we ignore the rest.
+ //
+ mCandidates.push_back(candidateObj);
+ }
}
}
-#endif
}
}
@@ -245,13 +307,13 @@ public:
mAdapter->removeFacet(mId, "ICEAgent");
}
- void setNATType(AsteriskSCF::System::NAT::V1::DetectedNATType natType)
+ void setNATType(DetectedNATType natType)
{
boost::unique_lock<boost::shared_mutex> lock(mLock);
mNATType = natType;
}
- void setRole(AsteriskSCF::System::NAT::V1::Role role)
+ void setRole(Role role)
{
boost::unique_lock<boost::shared_mutex> lock(mLock);
mRole = role;
@@ -262,9 +324,11 @@ private:
Ice::ObjectAdapterPtr mAdapter;
Ice::Identity mId;
bool mShuttingDown;
- AsteriskSCF::System::NAT::V1::DetectedNATType mNATType;
- AsteriskSCF::System::NAT::V1::Role mRole;
- CandidateRecordSeq mCandidates;
+ DetectedNATType mNATType;
+ Role mRole;
+ CandidateSeq mCandidates;
+ PJMediaEnvironmentPtr mEnv;
+ PJMediaEndpointPtr mEndpoint;
void stateCheck()
{
@@ -490,7 +554,7 @@ void ICETransport::addFacets(const Ice::ObjectAdapterPtr& adapter, const Ice::Id
{
ICEAgentImplPtr agent = new ICEAgentImpl(adapter, id);
ICECallbackAdapter::addAgent(mTransport, agent);
- adapter->addFacet(agent, id, AsteriskSCF::System::NAT::V1::InteractiveConnectionAgentFacetName);
+ adapter->addFacet(agent, id, InteractiveConnectionAgentFacetName);
}
ICETransportPtr ICETransport::create(const PJMediaEndpointPtr& ep, const PJMediaEnvironmentPtr& config)
-----------------------------------------------------------------------
--
asterisk-scf/integration/media_rtp_pjmedia.git
More information about the asterisk-scf-commits
mailing list