[asterisk-scf-commits] asterisk-scf/integration/media_rtp_pjmedia.git branch "nat-support" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Wed Jul 6 09:27:26 CDT 2011


branch "nat-support" has been updated
       via  3985edfb47c8d88392ed6e39e7f82bc0862e7185 (commit)
       via  0492b17c7c9461d4df682ad6f742680723411186 (commit)
      from  cfbf9175d04aa73f0d379a3342f1c691989bf182 (commit)

Summary of changes:
 src/ICETransport.cpp      |  140 +++++++++++++++++++++++++++++++++++++++++----
 src/PJMediaEnvironment.h  |    6 +-
 src/PJMediaTransport.cpp  |    8 +-
 src/SRTPConfiguration.cpp |    2 +-
 src/SessionAdapter.h      |   13 ++--
 src/UDPTransport.cpp      |   44 ++++----------
 src/UDPTransport.h        |    5 ++
 7 files changed, 161 insertions(+), 57 deletions(-)


- Log -----------------------------------------------------------------
commit 3985edfb47c8d88392ed6e39e7f82bc0862e7185
Author: Brent Eagles <beagles at digium.com>
Date:   Mon Jul 4 14:25:22 2011 -0230

    Incorporated review feedback.

diff --git a/src/PJMediaEnvironment.h b/src/PJMediaEnvironment.h
index b9be64a..dc4d39d 100644
--- a/src/PJMediaEnvironment.h
+++ b/src/PJMediaEnvironment.h
@@ -84,7 +84,7 @@ public:
     }
             
     /**
-     * Get SRTP relatd configuratino object.
+     * Get SRTP related configuration object.
      */
     SRTPConfigurationPtr srtpConfig() const
     {
@@ -93,7 +93,7 @@ public:
 
     /**
      * Get our library instance's main pool factory. As this function does not return a reference counted pointer, its
-     * value should not be cached at all. It's validity is directly related to the lifetime of the PJMediaEnvironment
+     * value should not be cached at all. Its validity is directly related to the lifetime of the PJMediaEnvironment
      * object.
      */
     pj_pool_factory* poolFactory() const
@@ -103,7 +103,7 @@ public:
     
     /**
      * Get the main memory pool. As this function does not return a reference counted pointer, its value should
-     * not be cached at all. It's validity is directly related to the lifetime of the PJMediaEnvironment object.
+     * not be cached at all. Its validity is directly related to the lifetime of the PJMediaEnvironment object.
      */
     pj_pool_t* memoryPool() const
     {
diff --git a/src/PJMediaTransport.cpp b/src/PJMediaTransport.cpp
index f218831..c646175 100644
--- a/src/PJMediaTransport.cpp
+++ b/src/PJMediaTransport.cpp
@@ -52,13 +52,13 @@ AddressPtr PJMediaTransport::remoteAddress()
     pjmedia_transport_info_init(&info);
     pjmedia_transport_get_info(mTransport, &info);
 
-    if (info.src_rtp_name.addr.sa_family != PJ_AF_INET && 
-      info.src_rtp_name.addr.sa_family != PJ_AF_INET6)
+    if (info.src_rtp_name.addr.sa_family != pj_AF_INET() && 
+      info.src_rtp_name.addr.sa_family != pj_AF_INET6())
     {
         //
         // If we don't have the remote address yet (we know because the default
-        // intialization for the above is neither PF_AF_INET or PF_AF_INET6) then
-        // return 0
+        // intialization for the above is neither pj_AF_INET() or
+        // pj_AF_INET6()) then return 0
         //
         return AddressPtr();
     }
diff --git a/src/SRTPConfiguration.cpp b/src/SRTPConfiguration.cpp
index e2acc49..9ae53ae 100644
--- a/src/SRTPConfiguration.cpp
+++ b/src/SRTPConfiguration.cpp
@@ -24,7 +24,7 @@ SRTPConfigurationPtr AsteriskSCF::PJMediaRTP::SRTPConfiguration::create(const Ic
         const string& propertyPrefix)
 {
     string prefix(propertyPrefix);
-    if (!prefix.empty() && *(--prefix.end()) != '.')
+    if (!prefix.empty() && prefix[prefix.length()-1] != '.')
     {
         prefix += '.';
     }
diff --git a/src/SessionAdapter.h b/src/SessionAdapter.h
index 0c550d1..d164bca 100644
--- a/src/SessionAdapter.h
+++ b/src/SessionAdapter.h
@@ -33,12 +33,13 @@ namespace PJMediaRTP
 class SessionAdapter;
 typedef boost::shared_ptr<SessionAdapter> SessionAdapterPtr;
 
-/**
- * By formalizing the interface between the session servant and the source and sink servants, we can
- * remove the physical compile time interdepencies. For the moment, this means that there will be
- * an indirect circular reference between the three entities. This is fine for the moment because
- * they are actually quite tightly coupled implementation-wise. e.g. setRemoteDetails propogates to the
- * source servant.
+/** 
+ * By formalizing the interface between the session servant and the source and
+ * sink servants, we can remove the physical compile time interdepencies. For
+ * the moment, this means that there will be an indirect circular reference
+ * between the three entities. This is fine for the moment because they are
+ * actually quite tightly coupled implementation-wise. e.g. setRemoteDetails
+ * propagates to the source servant.
  **/
 class SessionAdapter
 {
diff --git a/src/UDPTransport.cpp b/src/UDPTransport.cpp
index 18d9c17..4294c29 100644
--- a/src/UDPTransport.cpp
+++ b/src/UDPTransport.cpp
@@ -31,7 +31,19 @@ UDPTransportPtr AsteriskSCF::PJMediaRTP::UDPTransport::create(const PJMediaEndpo
 {
     const Ice::Int minPort = configObject->getStartPort();
     const Ice::Int maxPort = configObject->getEndPort();
+    return createImpl(ep, configObject, minPort, maxPort, expectIPv6);
+}
 
+UDPTransportPtr AsteriskSCF::PJMediaRTP::UDPTransport::create(const PJMediaEndpointPtr& ep, 
+    const RTPConfigurationPtr& configObject, unsigned port, bool expectIPv6)
+{
+    return createImpl(ep, configObject, port, port + 1, expectIPv6);
+}
+
+UDPTransportPtr AsteriskSCF::PJMediaRTP::UDPTransport::createImpl(const PJMediaEndpointPtr& ep,
+    const RTPConfigurationPtr& configObject, unsigned minPort, unsigned maxPort,
+    bool expectIPv6)
+{
     int addressFamily = pj_AF_INET();
     string bindingAddress;
     if (expectIPv6)
@@ -68,38 +80,6 @@ UDPTransportPtr AsteriskSCF::PJMediaRTP::UDPTransport::create(const PJMediaEndpo
     throw InternalInitializationException("Unable to initialize UDP media transport");
 }
 
-UDPTransportPtr AsteriskSCF::PJMediaRTP::UDPTransport::create(const PJMediaEndpointPtr& ep, 
-    const RTPConfigurationPtr& configObject, unsigned port, bool expectIPv6)
-{
-    int addressFamily = pj_AF_INET();
-    string bindingAddress;
-    if (expectIPv6)
-    {
-        addressFamily = pj_AF_INET6();
-        bindingAddress = configObject->getBindIPv6Address();
-    }
-    else
-    {
-        bindingAddress = configObject->getBindIPv4Address();
-    }
-    pj_str_t pjBindAddress;
-    pj_strset(&pjBindAddress, (char*)bindingAddress.c_str(), bindingAddress.size());
-    pj_str_t* bindAddressPtr = 0;
-    if (!bindingAddress.empty())
-    {
-        bindAddressPtr = &pjBindAddress;
-    }
-
-    pjmedia_transport* transport;
-    pj_status_t result = pjmedia_transport_udp_create3(ep->endpoint(), addressFamily, "RTP", bindAddressPtr, 
-        port, 0, &transport);
-    if (success(result))
-    {
-        return UDPTransportPtr(new UDPTransport(transport));
-    }
-    throw InternalInitializationException("Unable to initialize UDP media transport");
-}
-
 UDPTransport::UDPTransport(pjmedia_transport* t) :
     PJMediaTransport(t)
 {
diff --git a/src/UDPTransport.h b/src/UDPTransport.h
index 6e50e93..57283af 100644
--- a/src/UDPTransport.h
+++ b/src/UDPTransport.h
@@ -56,6 +56,11 @@ public:
         bool expectIPv6); 
 
 private:
+
+    static  UDPTransportPtr createImpl(const PJMediaEndpointPtr& ep,
+        const RTPConfigurationPtr& configObject,
+        unsigned minPort, unsigned maxPort, bool expectIPv6);
+
     UDPTransport(pjmedia_transport* t);
 };
 

commit 0492b17c7c9461d4df682ad6f742680723411186
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Jul 5 11:58:00 2011 -0230

    Rework offer processing lost in merge.

diff --git a/src/ICETransport.cpp b/src/ICETransport.cpp
index 07d9ed3..6cbfc00 100644
--- a/src/ICETransport.cpp
+++ b/src/ICETransport.cpp
@@ -57,7 +57,8 @@ public:
         mId(id),
         mShuttingDown(false),
         mNATType(AsteriskSCF::System::NAT::V1::Unknown),
-        mRole(UndefinedRole)
+        mRole(UndefinedRole),
+        mTransport(0)
     {
     }
 
@@ -80,13 +81,131 @@ public:
         return mRole;
     }
 
-    CandidatePtr negotiate(const CandidateSeq&, 
+    CandidatePtr negotiate(const string& hostname, Ice::Int port, const CandidateSeq& candidates,
         const Ice::Current&)
     {
         //
-        // TODO: implement.
+        // So how this works is we create a remote SDP and call pjmedia_transport_start() easy peasy. (Same deal 
         //
-        return 0;
+        pjmedia_sdp_session* remoteSDPSession = 
+            static_cast<pjmedia_sdp_session*>(pj_pool_zalloc(mEnv->memoryPool(), sizeof(pjmedia_sdp_session)));
+
+
+        //
+        // TODO: I think the ICE transport ignores a lot of this stuff, but I'm going to add it for the time
+        // being anyways.
+        //
+
+        //
+        // Missing details, user, id, version, net type?
+        //
+        pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->name, "ASCFMEDIA");
+        pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->origin.user, "");
+        AddressPtr remoteHost(new Address(hostname, port));
+
+        remoteSDPSession->conn = static_cast<pjmedia_sdp_conn*>(pj_pool_zalloc(mEnv->memoryPool(), sizeof(pjmedia_sdp_conn)));
+        pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->conn->net_type, "IN");
+        pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->origin.net_type, "IN");
+
+        //
+        // TODO: Look at whether the members can point to the same memory without issues.
+        //
+        if (remoteHost->isIPV6())
+        {
+            pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->origin.addr_type, "IP6");
+            pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->conn->addr_type, "IP6");
+        }
+        else
+        {
+            pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->origin.addr_type, "IP4");
+            pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->conn->addr_type, "IP4");
+        }
+        pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->origin.addr, remoteHost->address().c_str());
+        pj_strdup2(mEnv->memoryPool(), &remoteSDPSession->conn->addr, remoteHost->address().c_str());
+        remoteSDPSession->attr_count = 0;
+
+        //
+        // Cut n' paste from current SIP session manager... icky. TODO: sift through and see what of this
+        // can be discarded for this purpose.
+        //
+        remoteSDPSession->media_count = 1;
+        pjmedia_sdp_media* media =
+            static_cast<pjmedia_sdp_media*>(pj_pool_zalloc(mEnv->memoryPool(), sizeof(pjmedia_sdp_media)));
+        remoteSDPSession->media[0] = media;
+        pj_strdup2(mEnv->memoryPool(), &media->desc.media, "audio");
+        media->desc.port = (pj_uint16_t) port; // XXX --- this is not going to be correct here.. we don't actually have this!
+        media->desc.port_count = 1;
+        pj_strdup2(mEnv->memoryPool(), &media->desc.transport, "RTP/AVP");
+
+        // Populate the stream with codec details
+        remoteSDPSession->media[0]->desc.fmt_count = 1;
+        remoteSDPSession->media[0]->attr_count = 0;
+
+        // TODO: We should iterate over the formats to produce this instead of hardcoding
+        pjmedia_sdp_rtpmap rtpmap;
+        pjmedia_sdp_attr *attr;
+
+        // This is hardcoded value for ULAW for now
+        pj_strdup2(mEnv->memoryPool(), &media->desc.fmt[0], "0");
+        rtpmap.pt = media->desc.fmt[0];
+        rtpmap.clock_rate = 8000;
+        pj_strdup2(mEnv->memoryPool(), &rtpmap.enc_name, "PCMU");
+        rtpmap.param.slen = 0;
+        pjmedia_sdp_rtpmap_to_attr(mEnv->memoryPool(), &rtpmap, &attr);
+        remoteSDPSession->media[0]->attr[remoteSDPSession->media[0]->attr_count++] = attr;
+
+        // Might as well add sendrecv
+        attr = static_cast<pjmedia_sdp_attr*>(pj_pool_zalloc(mEnv->memoryPool(), sizeof(pjmedia_sdp_attr)));
+        pj_strdup2(mEnv->memoryPool(), &attr->name, "sendrecv");
+        remoteSDPSession->media[0]->attr[remoteSDPSession->media[0]->attr_count++] = attr;
+
+        //
+        // I was concerned about the fact that for a given SIP session, there might be multiple media
+        // streams and multiple candidates. I'm not sure that its actually too much of an issue even 
+        // if multiple media types are muxed on a single ICE negotiated flow, but there will need to be
+        // some redesign to pull in the multiple media streams associated with the session. For the moment
+        // we will operation under the premise that we are dealing with a single media stream.
+        // TODO: the SIP session gateway contains similar code, but from the offer perspective. This stuff
+        // should be refactored into a pjproject utility library.
+        //
+        //
+        pjmedia_sdp_media* currentMedia = remoteSDPSession->media[0];
+        for (CandidateSeq::const_iterator i = candidates.begin(); i != candidates.end(); ++i)
+        {
+            CandidatePtr candidate = *i;
+            ostringstream os;
+            os << "candidate:" << candidate->foundation << ' ' << candidate->componentId <<  " UDP " << 
+                candidate->priority << ' ' << candidate->mappedAddress << ' ' << candidate->mappedPort << " typ ";
+            string hostType;
+            switch (candidate->type)
+            {
+            case Host:
+                hostType = "host";
+                break;
+            case ServerReflexive:
+                hostType = "srflx";
+                break;
+            case PeerReflexive:
+                hostType = "prflx";
+                break;
+            case Relayed:
+                hostType = "relay";
+                break;
+            }
+            os << hostType;
+            if (candidate->type != Host)
+            {
+                os << " raddr " << candidate->baseAddress << " rport " << candidate->basePort;
+            }
+            string t = os.str();
+            pj_str_t candidateStr = pj_str(const_cast<char*>(t.c_str()));
+            pjmedia_sdp_attr* newAttribute = pjmedia_sdp_attr_create(mEnv->memoryPool(), 
+                "candidate", &candidateStr);
+            pjmedia_sdp_attr_add(&currentMedia->attr_count, currentMedia->attr, newAttribute);
+        }
+        pjmedia_sdp_session localSession;
+        pjmedia_transport_encode_sdp(mTransport, mEnv->memoryPool(), &localSession, 0, 0);
+        pjmedia_transport_media_start(mTransport, mEnv->memoryPool(), &localSession, remoteSDPSession, 0);
     }
 
     CandidateSeq getCandidates(const Ice::Current&)
@@ -104,6 +223,7 @@ public:
             //
             return;
         }
+        mTransport = transport;
 
         pjmedia_transport_info info;
         pjmedia_transport_info_init(&info);
@@ -141,15 +261,12 @@ public:
             // 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.
             //
-            pjmedia_sdp_session* sdpSession;
-            //
-            // 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)
+            pjmedia_sdp_session sdpSession;
+            pjmedia_transport_encode_sdp(mTransport, mEnv->memoryPool(), &sdpSession, 0, 0);
+            for (size_t i = 0; i < sdpSession.media_count; ++i)
             {
                 const string candidateName("candidate");
-                pjmedia_sdp_media* media = sdpSession->media[i];
+                pjmedia_sdp_media* media = sdpSession.media[i];
                 for (size_t j = 0; j < media->attr_count; ++j)
                 {
                     pjmedia_sdp_attr* attr = media->attr[j];
@@ -329,6 +446,7 @@ private:
     CandidateSeq mCandidates;
     PJMediaEnvironmentPtr mEnv;
     PJMediaEndpointPtr mEndpoint;
+    pjmedia_transport* mTransport;
 
     void stateCheck()
     {

-----------------------------------------------------------------------


-- 
asterisk-scf/integration/media_rtp_pjmedia.git



More information about the asterisk-scf-commits mailing list