[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