[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
Wed Jun 15 07:14:47 CDT 2011


branch "modular-transport-refactor" has been updated
       via  9c579d66b9af6d7193445ac2d63a7f1340b98150 (commit)
       via  a17d3cbd759461ebd20de707affd707d39e90dbb (commit)
      from  6ed741b6561e9f085df1f2abbb772fb4d2c6b019 (commit)

Summary of changes:
 src/CMakeLists.txt                               |   10 ++-
 src/{ReplicationAdapter.h => Configuration.h}    |   90 ++++++++-------
 src/MediaRTPpjmedia.cpp                          |    2 +-
 src/PJMediaEndpoint.cpp                          |   45 +++++++
 src/{ReplicationAdapter.h => PJMediaEndpoint.h}  |   41 +++++--
 src/PJMediaTransport.cpp                         |   89 ++++++++++++++
 src/{ReplicationAdapter.h => PJMediaTransport.h} |   40 +++++--
 src/RTPConfiguration.cpp                         |    4 +-
 src/RTPConfiguration.h                           |    8 +-
 src/RTPSession.cpp                               |  137 +++++-----------------
 src/RTPSink.cpp                                  |   62 +++++------
 src/RTPSink.h                                    |   18 +++-
 src/RTPSource.cpp                                |   48 +++++----
 src/RTPSource.h                                  |   10 ++-
 src/RtpStateReplicatorApp.cpp                    |    3 +-
 src/RtpStateReplicatorListener.cpp               |    9 ++-
 src/SessionAdapter.h                             |    5 -
 src/UDPTransport.cpp                             |  106 +++++++++++++++++
 src/UDPTransport.h                               |   63 ++++++++++
 19 files changed, 544 insertions(+), 246 deletions(-)
 copy src/{ReplicationAdapter.h => Configuration.h} (56%)
 mode change 100644 => 100755
 create mode 100644 src/PJMediaEndpoint.cpp
 copy src/{ReplicationAdapter.h => PJMediaEndpoint.h} (55%)
 create mode 100644 src/PJMediaTransport.cpp
 copy src/{ReplicationAdapter.h => PJMediaTransport.h} (50%)
 create mode 100644 src/UDPTransport.cpp
 create mode 100644 src/UDPTransport.h


- Log -----------------------------------------------------------------
commit 9c579d66b9af6d7193445ac2d63a7f1340b98150
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Jun 14 16:38:09 2011 -0230

    Fix up replicant version of transport method to accept the transport port.

diff --git a/src/RTPSession.cpp b/src/RTPSession.cpp
index 98bfdd9..d7a6bf9 100644
--- a/src/RTPSession.cpp
+++ b/src/RTPSession.cpp
@@ -304,7 +304,7 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter,
     mReplicaService(0),
     mStateReplicator(replicatorPrx)
 {
-    mTransport = UDPTransport::create(mEndpoint, configurationService, ipv6);
+    mTransport = UDPTransport::create(mEndpoint, configurationService, port, ipv6);
     mStreamSource = new StreamSourceRTPImpl(mSessionAdapter, mTransport, mId);
     mStreamSink = new StreamSinkRTPImpl(mSessionAdapter, mTransport, mId);
 }
diff --git a/src/UDPTransport.cpp b/src/UDPTransport.cpp
index eadca54..18d9c17 100644
--- a/src/UDPTransport.cpp
+++ b/src/UDPTransport.cpp
@@ -68,6 +68,38 @@ 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 90f53ed..7fdf990 100644
--- a/src/UDPTransport.h
+++ b/src/UDPTransport.h
@@ -47,6 +47,14 @@ public:
     static UDPTransportPtr create(const PJMediaEndpointPtr& ep, const RTPConfigurationPtr& configObject,
         bool expectIPv6); 
 
+    //
+    // Primary version.
+    //
+    static UDPTransportPtr create(const PJMediaEndpointPtr& ep, 
+        const RTPConfigurationPtr& configObject,
+        unsigned port,
+        bool expectIPv6); 
+
 private:
     UDPTransport(pjmedia_transport* t);
 };

commit a17d3cbd759461ebd20de707affd707d39e90dbb
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Jun 14 15:42:03 2011 -0230

    Next step in modular transport refactoring. This step moves the actual pjmedia
    UDP transport out into a separate class and passes it to the source and sink
    servants through a pointer to a base class. The implementation specific items
    of the configuration object are moved into a common interface class so that
    servant doesn't need to be passed around to all of the classes that need it.
    This will become even more useful as the additional transports are added.
    
    This is a much smaller step than the previous one, but closes up some loose
    ends and prepares the entire service to receive the new transports.

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d0fb862..b643389 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,16 +20,24 @@ asterisk_scf_component_add_file(media_rtp_pjmedia PJLibConfiguration.cpp)
 asterisk_scf_component_add_file(media_rtp_pjmedia PJLibConfiguration.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia PJMediaEnvironment.cpp)
 asterisk_scf_component_add_file(media_rtp_pjmedia PJMediaEnvironment.h)
+asterisk_scf_component_add_file(media_rtp_pjmedia PJMediaTransport.cpp)
+asterisk_scf_component_add_file(media_rtp_pjmedia PJMediaTransport.h)
+asterisk_scf_component_add_file(media_rtp_pjmedia PJMediaEndpoint.cpp)
+asterisk_scf_component_add_file(media_rtp_pjmedia PJMediaEndpoint.h)
+asterisk_scf_component_add_file(media_rtp_pjmedia UDPTransport.cpp)
+asterisk_scf_component_add_file(media_rtp_pjmedia UDPTransport.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia PJUtil.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia ReplicationAdapter.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia SessionAdapter.h)
+asterisk_scf_component_add_file(media_rtp_pjmedia Configuration.h)
 
 asterisk_scf_component_add_slice(media_rtp_pjmedia ../local-slice/RtpStateReplicationIf.ice)
 asterisk_scf_component_add_slice(media_rtp_pjmedia ../local-slice/RtpConfigurationIf.ice)
-asterisk_scf_component_add_boost_libraries(media_rtp_pjmedia core thread)
+asterisk_scf_component_add_boost_libraries(media_rtp_pjmedia core thread date_time)
 asterisk_scf_component_build_icebox(media_rtp_pjmedia)
 target_link_libraries(media_rtp_pjmedia logging-client)
 target_link_libraries(media_rtp_pjmedia asterisk-scf-api)
+target_link_libraries(media_rtp_pjmedia ice-util-cpp)
 pjproject_link(media_rtp_pjmedia pjlib)
 pjproject_link(media_rtp_pjmedia pjlib-util)
 pjproject_link(media_rtp_pjmedia pjmedia)
diff --git a/src/Configuration.h b/src/Configuration.h
new file mode 100755
index 0000000..5438f4a
--- /dev/null
+++ b/src/Configuration.h
@@ -0,0 +1,47 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <Ice/PropertiesF.h>
+#include <string>
+#include <IceUtil/Shared.h>
+
+namespace AsteriskSCF
+{
+namespace PJMediaRTP
+{
+
+/**
+ * Base class for objects providing RTP service specific configuration data.
+ */
+
+class RTPConfiguration : public virtual IceUtil::Shared
+{
+public:
+    virtual ~RTPConfiguration() {}
+
+    virtual int getStartPort() = 0;
+    virtual int getEndPort() = 0;
+    virtual int getWorkerThreadCount() = 0;
+    virtual std::string getBindIPv4Address() = 0;
+    virtual std::string getBindIPv6Address() = 0;
+};
+
+typedef IceUtil::Handle<RTPConfiguration> RTPConfigurationPtr;
+
+} /* End of namespace PJMediaRTP */
+} /* End of namespace AsteriskSCF */
diff --git a/src/MediaRTPpjmedia.cpp b/src/MediaRTPpjmedia.cpp
index 6dd0f2c..2b90345 100644
--- a/src/MediaRTPpjmedia.cpp
+++ b/src/MediaRTPpjmedia.cpp
@@ -505,7 +505,7 @@ void MediaRTPpjmediaApp::start(const std::string&, const Ice::CommunicatorPtr& c
     RtpStateReplicatorParamsPtr replicatorParams = new RtpStateReplicatorParams();
     replicatorParams->category = StateReplicatorDiscoveryCategory;
     replicatorParams->mName =
-        mCommunicator->getProperties()->getPropertyWithDefault("Sip.StateReplicatorName", "default");
+        mCommunicator->getProperties()->getPropertyWithDefault("Rtp.StateReplicatorName", "default");
 
     try
     {  
diff --git a/src/PJMediaEndpoint.cpp b/src/PJMediaEndpoint.cpp
new file mode 100644
index 0000000..96d192c
--- /dev/null
+++ b/src/PJMediaEndpoint.cpp
@@ -0,0 +1,45 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include "PJMediaEndpoint.h"
+#include "PJUtil.h"
+#include <AsteriskSCF/System/ExceptionsIf.h>
+#include <pjmedia.h>
+
+using namespace AsteriskSCF::PJMediaRTP;
+using namespace AsteriskSCF::System::V1;
+using namespace AsteriskSCF::PJUtil;
+
+PJMediaEndpoint::~PJMediaEndpoint()
+{
+    pjmedia_endpt_destroy(mEndpoint);
+}
+
+PJMediaEndpointPtr AsteriskSCF::PJMediaRTP::PJMediaEndpoint::create(const PJMediaEnvironmentPtr& env)
+{
+    pjmedia_endpt* t;
+    pj_status_t result =  pjmedia_endpt_create(env->poolFactory(), 0, 1, &t);
+    if (fail(result))
+    {
+        throw InternalInitializationException("Unable to create media endpoint!");
+    }
+    return PJMediaEndpointPtr(new PJMediaEndpoint(t));
+}
+
+PJMediaEndpoint::PJMediaEndpoint(pjmedia_endpt* endpt) :
+    mEndpoint(endpt)
+{
+}
diff --git a/src/PJMediaEndpoint.h b/src/PJMediaEndpoint.h
new file mode 100644
index 0000000..86ce0e4
--- /dev/null
+++ b/src/PJMediaEndpoint.h
@@ -0,0 +1,60 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include "PJMediaEnvironment.h"
+#include <boost/shared_ptr.hpp>
+
+//
+// forward declarations.
+//
+struct pjmedia_endpt;
+
+namespace AsteriskSCF
+{
+namespace PJMediaRTP
+{
+
+class PJMediaEndpoint;
+typedef boost::shared_ptr<PJMediaEndpoint> PJMediaEndpointPtr;
+
+class PJMediaEndpoint
+{
+public:
+
+    ~PJMediaEndpoint();
+
+    pjmedia_endpt* endpoint() const
+    {
+        return mEndpoint;
+    }
+
+    static PJMediaEndpointPtr create(const PJMediaEnvironmentPtr& environ);
+
+private:
+    pjmedia_endpt* mEndpoint;
+
+    PJMediaEndpoint(pjmedia_endpt* endpoint);
+
+    //
+    // Hidden and unimplemented.
+    //
+    PJMediaEndpoint(const PJMediaEndpoint&);
+    void operator=(const PJMediaEndpoint&);
+};
+} /* End of namespace PJMediaRTP */
+} /* End of namespace AsteriskSCF */
diff --git a/src/PJMediaTransport.cpp b/src/PJMediaTransport.cpp
new file mode 100644
index 0000000..a409acc
--- /dev/null
+++ b/src/PJMediaTransport.cpp
@@ -0,0 +1,89 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include "PJMediaTransport.h"
+#include <pjmedia.h>
+#include <pjlib.h>
+#include <string>
+#ifndef _NDEBUG
+#include <iostream>
+#endif
+
+using namespace std;
+using namespace AsteriskSCF::PJMediaRTP;
+using namespace AsteriskSCF::Helpers;
+
+static AddressPtr fromInfo(pjmedia_transport_info& info)
+{
+    char buff[PJ_INET6_ADDRSTRLEN];
+    pj_sockaddr_print(&info.sock_info.rtp_addr_name, buff, sizeof(buff), 0);
+    int port = pj_sockaddr_get_port(&info.sock_info.rtp_addr_name);
+    string address = buff;
+    return AddressPtr(new Address(address, port));
+}
+
+PJMediaTransport::~PJMediaTransport()
+{
+    pjmedia_transport_close(mTransport);
+}
+
+pjmedia_transport* PJMediaTransport::getTransport() const
+{
+    return mTransport;
+}
+
+PJMediaTransport::PJMediaTransport(pjmedia_transport* t) :
+    mTransport(t)
+{
+#ifndef _NDEBUG
+    //
+    // TODO: temporary
+    //
+    cerr << "Creating PJMediaTransport for " << getLocalAddressImpl()->toString() << endl;
+#endif
+}
+
+AddressPtr PJMediaTransport::localAddress() const
+{
+    return getLocalAddressImpl();
+}
+
+AddressPtr PJMediaTransport::remoteAddress() const
+{
+    pjmedia_transport_info info;
+    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 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
+        //
+        return AddressPtr();
+    }
+    return fromInfo(info);
+}
+
+AddressPtr PJMediaTransport::getLocalAddressImpl() const
+{
+    pjmedia_transport_info info;
+    pjmedia_transport_info_init(&info);
+    pjmedia_transport_get_info(mTransport, &info);
+    return fromInfo(info);
+}
diff --git a/src/PJMediaTransport.h b/src/PJMediaTransport.h
new file mode 100644
index 0000000..2ff1da7
--- /dev/null
+++ b/src/PJMediaTransport.h
@@ -0,0 +1,61 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <AsteriskSCF/Helpers/Network.h>
+#include <boost/shared_ptr.hpp>
+
+//
+// Forward declarations.
+//
+struct pjmedia_transport;
+
+namespace AsteriskSCF
+{
+namespace PJMediaRTP
+{
+
+class PJMediaTransport;
+typedef boost::shared_ptr<PJMediaTransport> PJMediaTransportPtr;
+
+class PJMediaTransport
+{
+public:
+
+    virtual ~PJMediaTransport();
+
+    pjmedia_transport* getTransport() const;
+
+    virtual AsteriskSCF::Helpers::AddressPtr localAddress() const;
+    virtual AsteriskSCF::Helpers::AddressPtr remoteAddress() const;
+
+protected:
+    pjmedia_transport* mTransport;
+
+    PJMediaTransport(pjmedia_transport* t);
+
+    AsteriskSCF::Helpers::AddressPtr getLocalAddressImpl() const;
+
+    //
+    // Hidden and unimplemented.
+    //
+    PJMediaTransport(const PJMediaTransport&);
+    void operator=(const PJMediaTransport&);
+};
+
+} /* End of namespace PJMediaRTP */
+} /* End of namespace AsteriskSCF */
diff --git a/src/RTPConfiguration.cpp b/src/RTPConfiguration.cpp
index aa23f95..bb00da4 100644
--- a/src/RTPConfiguration.cpp
+++ b/src/RTPConfiguration.cpp
@@ -403,7 +403,7 @@ int ConfigurationServiceImpl::getWorkerThreadCount()
 /**
  * Internal function which returns the IPv4 address to bind to.
  */
-std::string ConfigurationServiceImpl::getBindIPv4address()
+std::string ConfigurationServiceImpl::getBindIPv4Address()
 {
     boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
 
@@ -432,7 +432,7 @@ std::string ConfigurationServiceImpl::getBindIPv4address()
 /**
  * Internal function which returns the IPv6 address to bind to.
  */
-std::string ConfigurationServiceImpl::getBindIPv6address()
+std::string ConfigurationServiceImpl::getBindIPv6Address()
 {
     boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
 
diff --git a/src/RTPConfiguration.h b/src/RTPConfiguration.h
index b6fc401..a4329b0 100644
--- a/src/RTPConfiguration.h
+++ b/src/RTPConfiguration.h
@@ -19,6 +19,7 @@
 #include <Ice/Ice.h>
 #include <AsteriskSCF/System/Component/ConfigurationIf.h>
 #include <boost/shared_ptr.hpp>
+#include "Configuration.h"
 
 /*
  * Private implementation class for ConfigurationServiceImpl.
@@ -28,7 +29,8 @@ class ConfigurationServiceImplPriv;
 /**
  * Implementation of the configuration service.
  */
-class ConfigurationServiceImpl : public AsteriskSCF::System::Configuration::V1::ConfigurationService
+class ConfigurationServiceImpl : virtual public AsteriskSCF::System::Configuration::V1::ConfigurationService,
+    virtual public AsteriskSCF::PJMediaRTP::RTPConfiguration
 {
 public:
     ConfigurationServiceImpl();
@@ -44,8 +46,8 @@ public:
     int getEndPort();
     int getWorkerThreadCount();
 
-    std::string getBindIPv4address();
-    std::string getBindIPv6address();
+    std::string getBindIPv4Address();
+    std::string getBindIPv6Address();
 private:
     /**
      * Private implementation details.
diff --git a/src/RTPSession.cpp b/src/RTPSession.cpp
index 64aa92a..98bfdd9 100644
--- a/src/RTPSession.cpp
+++ b/src/RTPSession.cpp
@@ -19,6 +19,9 @@
 #include "RTPSource.h"
 #include "RTPSink.h"
 #include "RTPConfiguration.h"
+#include "PJMediaTransport.h"
+#include "PJMediaEndpoint.h"
+#include "UDPTransport.h"
 
 #include <pjlib.h>
 #include <pjmedia.h>
@@ -77,18 +80,16 @@ public:
     /**
      * Internal methods. 
      */
-    pjmedia_transport* getTransport();
     AsteriskSCF::Media::V1::FormatSeq getFormats();
     void setRemoteDetails(const std::string& address, Ice::Int port);
     AsteriskSCF::Media::V1::FormatPtr getFormat(int payload);
     int getPayload(const AsteriskSCF::Media::V1::FormatPtr& mediaformat);
 
     /**
-     * Accessors for the source and sink servants. The source servant is returned through a pointer to the
-     * implementation type because some implementation specific details need to be exposed.
+     * Accessors for the source and sink servants. 
      */
     StreamSourceRTPImplPtr getSourceServant();
-    AsteriskSCF::Media::RTP::V1::StreamSinkRTPPtr getSinkServant();
+    StreamSinkRTPImplPtr getSinkServant();
 
     void replicateState(const AsteriskSCF::Media::RTP::V1::RtpSessionStateItemPtr&,
             const AsteriskSCF::Media::RTP::V1::RtpStreamSinkStateItemPtr&,
@@ -115,6 +116,11 @@ private:
     PJMediaEnvironmentPtr mEnvironment;
 
     /**
+     * pjmedia endpoint for our media.
+     */
+    PJMediaEndpointPtr mEndpoint;
+
+    /**
      * Id.
      */
     string mId;
@@ -129,15 +135,11 @@ private:
      */
     FormatSeq mFormats;
 
-    /**
-     * pjmedia endpoint for our media.
-     */
-    pjmedia_endpt* mEndpoint;
 
     /**
      * pjmedia transport for transmission/reception of RTP.
      */
-    pjmedia_transport* mTransport;
+    PJMediaTransportPtr mTransport;
 
     /**
      * A stream source for this RTP session.
@@ -239,11 +241,6 @@ public:
         mServant->setRemoteDetails(host, port);
     }
 
-    pjmedia_transport* getTransport()
-    {
-        return mServant->getTransport();
-    }
-
 private:
     RTPSessionImplPtr mServant;
 };
@@ -260,6 +257,7 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter,
         const ConfigurationServiceImplPtr& configurationService) : 
     mSessionAdapter(new SessionAdapterImpl(this)),
     mEnvironment(env),
+    mEndpoint(PJMediaEndpoint::create(env)),
     mId(id),
     mAdapter(adapter),
     mFormats(params->formats),
@@ -267,41 +265,7 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter,
     mReplicaService(replicaService),
     mStateReplicator(stateReplicator)
 {
-    /* Create an endpoint in pjmedia for our media. */
-    pj_status_t status = pjmedia_endpt_create(mEnvironment->poolFactory(), 0, configurationService->getWorkerThreadCount(),
-            &mEndpoint);
-
-    assert(status == PJ_SUCCESS);
-
-    int af;
-    pj_str_t binding;
-
-    if (params->ipv6 == true)
-    {
-	af = pj_AF_INET6();
-	pj_strset(&binding, (char*)(configurationService->getBindIPv6address().c_str()),
-                (configurationService->getBindIPv6address().size()));
-    }
-    else
-    {
-	af = pj_AF_INET();
-        pj_strset(&binding, (char*)(configurationService->getBindIPv4address().c_str()),
-                (configurationService->getBindIPv4address().size()));
-    }
-
-    int minimumPort = configurationService->getStartPort();
-    int maximumPort = configurationService->getEndPort();
-
-    /* Now create some transport we can use to actually send or receive the media. */
-    for (int port = minimumPort; port < maximumPort; port += 2)
-    {
-        if ((status = pjmedia_transport_udp_create3(mEndpoint, af, "RTP", pj_strlen(&binding) ? &binding : NULL, port, 0, &mTransport)) ==
-                PJ_SUCCESS)
-        {
-	    mSessionStateItem->mPort = port;
-            break;
-        }
-    }
+    mTransport = UDPTransport::create(mEndpoint, configurationService, params->ipv6);
 
     // Initialize our session state item enough so that the state items for the source and sink can also be initialized.
     mSessionStateItem->key = mSessionStateItem->mSessionId = IceUtil::generateUUID();
@@ -310,9 +274,9 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter,
     mSessionStateItem->mIPv6 = params->ipv6;
 
     /* First up for our own stuff is... a source! Media needs to come from somewhere, you know. */
-    mStreamSource = new StreamSourceRTPImpl(mSessionAdapter, mSessionStateItem->key);
+    mStreamSource = new StreamSourceRTPImpl(mSessionAdapter, mTransport, mSessionStateItem->key);
     /* And for my next trick a place for us to send media out. */
-    mStreamSink = new StreamSinkRTPImpl(mSessionAdapter, mSessionStateItem->key);
+    mStreamSink = new StreamSinkRTPImpl(mSessionAdapter, mTransport, mSessionStateItem->key);
 
     //
     // All of this new stuff will be replicated on activatation.
@@ -332,6 +296,7 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter,
         const ConfigurationServiceImplPtr& configurationService) :
     mSessionAdapter(new SessionAdapterImpl(this)),
     mEnvironment(env),
+    mEndpoint(PJMediaEndpoint::create(env)),
     mId(sessionIdentity),
     mAdapter(adapter),
     mFormats(formats),
@@ -339,32 +304,9 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter,
     mReplicaService(0),
     mStateReplicator(replicatorPrx)
 {
-    pj_status_t status = pjmedia_endpt_create(mEnvironment->poolFactory(), 0, configurationService->getWorkerThreadCount(), &mEndpoint);
-
-    assert(status == PJ_SUCCESS);
-
-    int af;
-    pj_str_t binding;
-
-    if (ipv6)
-    {
-        af = pj_AF_INET6();
-        pj_strset(&binding, (char*)(configurationService->getBindIPv6address().c_str()), (configurationService->getBindIPv6address().size()));
-    }
-    else
-    {
-        af = pj_AF_INET();
-        pj_strset(&binding, (char*)(configurationService->getBindIPv4address().c_str()), (configurationService->getBindIPv4address().size()));
-    }
-
-    if ((status = pjmedia_transport_udp_create3(mEndpoint, af, "RTP", pj_strlen(&binding) ? &binding : NULL, port, 0, &mTransport))
-            != PJ_SUCCESS)
-    {
-	// TODO: This is also bad, something is using the port
-    }
-
-    mStreamSource = new StreamSourceRTPImpl(mSessionAdapter, mId);
-    mStreamSink = new StreamSinkRTPImpl(mSessionAdapter, mId);
+    mTransport = UDPTransport::create(mEndpoint, configurationService, ipv6);
+    mStreamSource = new StreamSourceRTPImpl(mSessionAdapter, mTransport, mId);
+    mStreamSink = new StreamSinkRTPImpl(mSessionAdapter, mTransport, mId);
 }
 
 /**
@@ -372,11 +314,6 @@ RTPSessionImpl::RTPSessionImpl(const Ice::ObjectAdapterPtr& adapter,
  */
 RTPSessionImpl::~RTPSessionImpl()
 {
-    /* Discontinue the media transport. */
-    pjmedia_transport_close(mTransport);
-
-    /* Discontinue the media endpoint. */
-    pjmedia_endpt_destroy(mEndpoint);
 }
 
 /**
@@ -417,6 +354,9 @@ std::string RTPSessionImpl::getId(const Ice::Current&)
  */
 void RTPSessionImpl::useRTCP(bool, const Ice::Current&)
 {
+    //
+    // TODO.
+    //
 }
 
 /**
@@ -424,6 +364,9 @@ void RTPSessionImpl::useRTCP(bool, const Ice::Current&)
  */
 RTCPSessionPrx RTPSessionImpl::getRTCPSession(const Ice::Current&)
 {
+    //
+    // TODO.
+    //
     RTCPSessionPrx proxy;
     return proxy;
 }
@@ -465,16 +408,6 @@ void RTPSessionImpl::associatePayloads(const AsteriskSCF::Media::RTP::V1::Payloa
 }
 
 /**
- * API call which returns the transport used for this RTP session.
- *
- * @return A pointer to the pjmedia transport.
- */
-pjmedia_transport* RTPSessionImpl::getTransport()
-{
-    return mTransport;
-}
-
-/**
  * API call which returns the formats the RTP session is expected to carry.
  *
  * @return A sequence of media formats.
@@ -531,7 +464,7 @@ StreamSourceRTPImplPtr RTPSessionImpl::getSourceServant()
     return mStreamSource;
 }
 
-StreamSinkRTPPtr RTPSessionImpl::getSinkServant()
+StreamSinkRTPImplPtr RTPSessionImpl::getSinkServant()
 {
     return mStreamSink;
 }
@@ -655,14 +588,7 @@ RTPSessionPrx RTPSessionImpl::activate(const Ice::Identity& id, const Ice::Ident
         mSessionStateItem->mFormats = mFormats;
         mSessionStateItem->mSourceIdentity = sourceId;
         mSessionStateItem->mSinkIdentity = sinkId;
-
-        //
-        // XXX- this will be replaced in following updates.
-        //
-        pjmedia_transport_info transportInfo;
-        pjmedia_transport_info_init(&transportInfo);
-        pjmedia_transport_get_info(mTransport, &transportInfo);
-        mSessionStateItem->mPort = pj_sockaddr_get_port(&transportInfo.sock_info.rtp_addr_name);
+        mSessionStateItem->mPort = mTransport->localAddress()->port();
         replicateState(mSessionStateItem, mStreamSink->getStateItem(), mStreamSource->getStateItem());
     }
 
@@ -681,11 +607,8 @@ public:
 
     void update(const RtpStreamSinkStateItemPtr& item)
     {
-        //
-        // XXX Using the slice defined methods will be changed in subsequent updates.
-        //
-        mImpl->getSinkServant()->setSource(item->mSource, Ice::Current());
-        mImpl->getSinkServant()->setRemoteDetails(item->mRemoteAddress, item->mRemotePort, Ice::Current());
+        mImpl->getSinkServant()->setSourceImpl(item->mSource);
+        mImpl->getSinkServant()->setRemoteDetailsImpl(item->mRemoteAddress, item->mRemotePort);
         mImpl->getSourceServant()->setRemoteDetails(item->mRemoteAddress, item->mRemotePort);
     }
 
@@ -694,7 +617,7 @@ public:
         //
         // XXX Using the slice defined methods will be changed in subsequent updates.
         //
-        mImpl->getSourceServant()->setSink(item->mSink, Ice::Current());
+        mImpl->getSourceServant()->setSinkImpl(item->mSink);
     }
 
     void destroy()
diff --git a/src/RTPSink.cpp b/src/RTPSink.cpp
index f4a2179..3cb981a 100644
--- a/src/RTPSink.cpp
+++ b/src/RTPSink.cpp
@@ -43,7 +43,8 @@ public:
     /**
      * Constructor for our StreamSinkRTPImplPriv class.
      */
-    StreamSinkRTPImplPriv(const SessionAdapterPtr&, const std::string&);
+    StreamSinkRTPImplPriv(const SessionAdapterPtr& sessionAdapter, 
+        const PJMediaTransportPtr& transport, const std::string&);
 
     /**
      * A structure containing outgoing pjmedia session data.
@@ -55,6 +56,8 @@ public:
      */
     SessionAdapterPtr mSessionAdapter;
 
+    PJMediaTransportPtr mTransport;
+
     /**
      * Stream sink state item.
      */
@@ -69,8 +72,11 @@ public:
 /**
  * Constructor for the StreamSinkRTPImplPriv class.
  */
-StreamSinkRTPImplPriv::StreamSinkRTPImplPriv(const SessionAdapterPtr& session, const string& sessionId) :
-    mSessionAdapter(session), mSinkStateItem(new RtpStreamSinkStateItem), mSessionId(sessionId)
+StreamSinkRTPImplPriv::StreamSinkRTPImplPriv(const SessionAdapterPtr& session, 
+    const PJMediaTransportPtr& transport, const string& sessionId) :
+    mSessionAdapter(session), mTransport(transport), 
+    mSinkStateItem(new RtpStreamSinkStateItem), 
+    mSessionId(sessionId)
 {
     pjmedia_rtp_session_init(&mOutgoingSession, 0, pj_rand());
     mSinkStateItem->mSessionId = sessionId;
@@ -81,8 +87,9 @@ StreamSinkRTPImplPriv::StreamSinkRTPImplPriv(const SessionAdapterPtr& session, c
 /**
  * Constructor for the StreamSinkRTPImpl class.
  */
-StreamSinkRTPImpl::StreamSinkRTPImpl(const SessionAdapterPtr& session, const string& sessionId) :
-    mImpl(new StreamSinkRTPImplPriv(session, sessionId))
+StreamSinkRTPImpl::StreamSinkRTPImpl(const SessionAdapterPtr& session, const PJMediaTransportPtr& transport,
+    const string& sessionId) :
+    mImpl(new StreamSinkRTPImplPriv(session, transport, sessionId))
 {
 }
 
@@ -139,7 +146,7 @@ void StreamSinkRTPImpl::write(const AsteriskSCF::Media::V1::FrameSeq& frames, co
         pj_memcpy(packet + header_len, &(*frame)->payload[0], (*frame)->payload.size());
 
         /* All done, transmission can now occur */
-        status = pjmedia_transport_send_rtp(mImpl->mSessionAdapter->getTransport(), packet,
+        status = pjmedia_transport_send_rtp(mImpl->mTransport->getTransport(), packet,
                 (*frame)->payload.size() + header_len);
 
         if (status != PJ_SUCCESS)
@@ -209,22 +216,8 @@ void StreamSinkRTPImpl::setRemoteDetails(const string& address, Ice::Int port, c
  */
 std::string StreamSinkRTPImpl::getRemoteAddress(const Ice::Current&)
 {
-    pjmedia_transport_info transportInfo;
-
-    pjmedia_transport_info_init(&transportInfo);
-    pjmedia_transport_get_info(mImpl->mSessionAdapter->getTransport(), &transportInfo);
-
-    if (transportInfo.src_rtp_name.addr.sa_family != PJ_AF_INET &&
-	transportInfo.src_rtp_name.addr.sa_family != PJ_AF_INET6)
-    {
-	// If we have no remote address yet (we know because the default initialization
-	// for the above is neither PJ_AF_INET or PJ_AF_INET6) then return whatever
-	// remote address we have been told, heck, it could be blank!
-	return mImpl->mSinkStateItem->mRemoteAddress;
-    }
-
-    char tmp_addr[PJ_INET6_ADDRSTRLEN];
-    return pj_sockaddr_print(&transportInfo.src_rtp_name, tmp_addr, sizeof(tmp_addr), 0);
+    string address = mImpl->mTransport->remoteAddress()->hostname();
+    return (address != "0.0.0.0") ? address : mImpl->mSinkStateItem->mRemoteAddress;
 }
 
 /**
@@ -232,18 +225,8 @@ std::string StreamSinkRTPImpl::getRemoteAddress(const Ice::Current&)
  */
 Ice::Int StreamSinkRTPImpl::getRemotePort(const Ice::Current&)
 {
-    pjmedia_transport_info transportInfo;
-
-    pjmedia_transport_info_init(&transportInfo);
-    pjmedia_transport_get_info(mImpl->mSessionAdapter->getTransport(), &transportInfo);
-
-    if (transportInfo.src_rtp_name.addr.sa_family != PJ_AF_INET &&
-        transportInfo.src_rtp_name.addr.sa_family != PJ_AF_INET6)
-    {
-	return mImpl->mSinkStateItem->mRemotePort;
-    }
-
-    return pj_sockaddr_get_port(&transportInfo.src_rtp_name);
+    int port = mImpl->mTransport->remoteAddress()->port();
+    return (port != 0) ? port : mImpl->mSinkStateItem->mRemotePort;
 }
 
 /**
@@ -253,3 +236,14 @@ RtpStreamSinkStateItemPtr StreamSinkRTPImpl::getStateItem()
 {
     return mImpl->mSinkStateItem;
 }
+
+void StreamSinkRTPImpl::setRemoteDetailsImpl(const std::string& host, Ice::Int port)
+{
+    mImpl->mSinkStateItem->mRemoteAddress = host;
+    mImpl->mSinkStateItem->mRemotePort = port;
+}
+
+void StreamSinkRTPImpl::setSourceImpl(const AsteriskSCF::Media::V1::StreamSourcePrx& proxy)
+{
+    mImpl->mSinkStateItem->mSource = proxy;
+}
diff --git a/src/RTPSink.h b/src/RTPSink.h
index d2e7b43..e59a546 100644
--- a/src/RTPSink.h
+++ b/src/RTPSink.h
@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include "PJMediaTransport.h"
 #include "SessionAdapter.h"
 #include <boost/shared_ptr.hpp>
 #include <IceUtil/Handle.h>
@@ -23,7 +24,13 @@ class StreamSinkRTPImplPriv;
 class StreamSinkRTPImpl : public AsteriskSCF::Media::RTP::V1::StreamSinkRTP
 {
 public:
-    StreamSinkRTPImpl(const AsteriskSCF::PJMediaRTP::SessionAdapterPtr&, const std::string&);
+    StreamSinkRTPImpl(const AsteriskSCF::PJMediaRTP::SessionAdapterPtr& sessionAdapter, 
+        const AsteriskSCF::PJMediaRTP::PJMediaTransportPtr& transport, 
+        const std::string& sessionId);
+
+    /**
+     * AsteriskSCF::Media::RTP::V1::StreamSinkRTP implementation.
+     */
     void write(const AsteriskSCF::Media::V1::FrameSeq&, const Ice::Current&);
     void setSource(const AsteriskSCF::Media::V1::StreamSourcePrx&, const Ice::Current&);
     AsteriskSCF::Media::V1::StreamSourcePrx getSource(const Ice::Current&);
@@ -32,7 +39,14 @@ public:
     void setRemoteDetails(const std::string&, Ice::Int, const Ice::Current&);
     std::string getRemoteAddress(const Ice::Current&);
     Ice::Int getRemotePort(const Ice::Current&);
+
+    /**
+     * Internal implementation methods.
+     */
     AsteriskSCF::Media::RTP::V1::RtpStreamSinkStateItemPtr getStateItem();
+    void setRemoteDetailsImpl(const std::string& host, Ice::Int port);
+    void setSourceImpl(const AsteriskSCF::Media::V1::StreamSourcePrx& proxy);
+
 private:
     /**
      * Private implementation data for StreamSinkRTPImpl.
@@ -40,4 +54,4 @@ private:
     boost::shared_ptr<StreamSinkRTPImplPriv> mImpl;
 };
 
-typedef IceUtil::Handle<StreamSinkRTPImpl> StreamSinkRTPImplPtr;
\ No newline at end of file
+typedef IceUtil::Handle<StreamSinkRTPImpl> StreamSinkRTPImplPtr;
diff --git a/src/RTPSource.cpp b/src/RTPSource.cpp
index 9bff723..1d855ac 100644
--- a/src/RTPSource.cpp
+++ b/src/RTPSource.cpp
@@ -48,7 +48,9 @@ public:
     /**
      * Constructor for our StreamSourceRTPImplPriv class.
      */
-    StreamSourceRTPImplPriv(const SessionAdapterPtr&, const string&);
+    StreamSourceRTPImplPriv(const SessionAdapterPtr& sessionAdapter, 
+        const PJMediaTransportPtr& transport,
+        const string& parentSessionId);
 
     /**
      * A structure containing incoming pjmedia session data.
@@ -61,6 +63,11 @@ public:
     SessionAdapterPtr mSessionAdapter;
 
     /**
+     * A reference to the internal transport helper class associated with this source.
+     */
+    PJMediaTransportPtr mTransport;
+
+    /**
      * Stream source state item.
      */
     RtpStreamSourceStateItemPtr mSourceStateItem;
@@ -71,8 +78,12 @@ public:
 /**
  * Constructor for the StreamSourceRTPImplPriv class.
  */
-StreamSourceRTPImplPriv::StreamSourceRTPImplPriv(const SessionAdapterPtr& session, const string& sessionId) :
-    mSessionAdapter(session), mSourceStateItem(new RtpStreamSourceStateItem), mSessionId(sessionId)
+StreamSourceRTPImplPriv::StreamSourceRTPImplPriv(const SessionAdapterPtr& session, 
+    const PJMediaTransportPtr& transport, 
+    const string& sessionId) :
+    mSessionAdapter(session), mTransport(transport), 
+    mSourceStateItem(new RtpStreamSourceStateItem), 
+    mSessionId(sessionId)
 {
     pjmedia_rtp_session_init(&mIncomingSession, 0, 0);
     mSourceStateItem->mSessionId = sessionId;
@@ -82,8 +93,9 @@ StreamSourceRTPImplPriv::StreamSourceRTPImplPriv(const SessionAdapterPtr& sessio
 /**
  * Constructor for the StreamSourceRTPImpl class.
  */
-StreamSourceRTPImpl::StreamSourceRTPImpl(const SessionAdapterPtr& session, const string& sessionId) :
-    mImpl(new StreamSourceRTPImplPriv(session, sessionId))
+StreamSourceRTPImpl::StreamSourceRTPImpl(const SessionAdapterPtr& session,
+        const PJMediaTransportPtr& transport, const string& sessionId) :
+    mImpl(new StreamSourceRTPImplPriv(session, transport, sessionId))
 {
 }
 
@@ -136,13 +148,7 @@ void StreamSourceRTPImpl::requestFormat(const AsteriskSCF::Media::V1::FormatPtr&
  */
 std::string StreamSourceRTPImpl::getLocalAddress(const Ice::Current&)
 {
-    pjmedia_transport_info transportInfo;
-
-    pjmedia_transport_info_init(&transportInfo);
-    pjmedia_transport_get_info(mImpl->mSessionAdapter->getTransport(), &transportInfo);
-
-    char tmp_addr[PJ_INET6_ADDRSTRLEN];
-    return pj_sockaddr_print(&transportInfo.sock_info.rtp_addr_name, tmp_addr, sizeof(tmp_addr), 0);
+    return mImpl->mTransport->localAddress()->hostname();
 }
 
 /**
@@ -150,12 +156,7 @@ std::string StreamSourceRTPImpl::getLocalAddress(const Ice::Current&)
  */
 Ice::Int StreamSourceRTPImpl::getLocalPort(const Ice::Current&)
 {
-    pjmedia_transport_info transportInfo;
-
-    pjmedia_transport_info_init(&transportInfo);
-    pjmedia_transport_get_info(mImpl->mSessionAdapter->getTransport(), &transportInfo);
-
-    return pj_sockaddr_get_port(&transportInfo.sock_info.rtp_addr_name);
+    return mImpl->mTransport->localAddress()->port();
 }
 
 /**
@@ -252,7 +253,7 @@ void StreamSourceRTPImpl::setRemoteDetails(const string& address, Ice::Int port)
     pjmedia_transport_info transportInfo;
 
     pjmedia_transport_info_init(&transportInfo);
-    pjmedia_transport_get_info(mImpl->mSessionAdapter->getTransport(), &transportInfo);
+    pjmedia_transport_get_info(mImpl->mTransport->getTransport(), &transportInfo);
 
     if (transportInfo.sock_info.rtp_addr_name.addr.sa_family != addr.addr.sa_family)
     {
@@ -262,10 +263,10 @@ void StreamSourceRTPImpl::setRemoteDetails(const string& address, Ice::Int port)
     pj_sockaddr_set_port(&addr, static_cast<pj_uint16_t>(port));
 
     /* In case we were already attached go ahead and detach */
-    pjmedia_transport_detach(mImpl->mSessionAdapter->getTransport(), this);
+    pjmedia_transport_detach(mImpl->mTransport->getTransport(), this);
 
     /* All ready... actually do it! */
-    status = pjmedia_transport_attach(mImpl->mSessionAdapter->getTransport(), this, &addr, NULL, pj_sockaddr_get_len(&addr), &receiveRTP, NULL);
+    status = pjmedia_transport_attach(mImpl->mTransport->getTransport(), this, &addr, NULL, pj_sockaddr_get_len(&addr), &receiveRTP, NULL);
 
     if (status != PJ_SUCCESS)
     {
@@ -280,3 +281,8 @@ RtpStreamSourceStateItemPtr StreamSourceRTPImpl::getStateItem()
 {
     return mImpl->mSourceStateItem;
 }
+
+void StreamSourceRTPImpl::setSinkImpl(const AsteriskSCF::Media::V1::StreamSinkPrx& proxy)
+{
+    mImpl->mSourceStateItem->mSink = proxy;
+}
diff --git a/src/RTPSource.h b/src/RTPSource.h
index 6eddc1f..1d9ee23 100644
--- a/src/RTPSource.h
+++ b/src/RTPSource.h
@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include "PJMediaTransport.h"
 #include "SessionAdapter.h"
 #include <boost/shared_ptr.hpp>
 #include <IceUtil/Handle.h>
@@ -23,7 +24,10 @@ class StreamSourceRTPImplPriv;
 class StreamSourceRTPImpl : public AsteriskSCF::Media::RTP::V1::StreamSourceRTP
 {
 public:
-    StreamSourceRTPImpl(const AsteriskSCF::PJMediaRTP::SessionAdapterPtr&, const std::string&);
+    StreamSourceRTPImpl(const AsteriskSCF::PJMediaRTP::SessionAdapterPtr& sessionAdapter, 
+        const AsteriskSCF::PJMediaRTP::PJMediaTransportPtr& transport,
+        const std::string& parentSessionId);
+
     void setSink(const AsteriskSCF::Media::V1::StreamSinkPrx&, const Ice::Current&);
     AsteriskSCF::Media::V1::StreamSinkPrx getSink(const Ice::Current&);
     AsteriskSCF::Media::V1::FormatSeq getFormats(const Ice::Current&);
@@ -34,6 +38,8 @@ public:
     void setRemoteDetails(const std::string& address, Ice::Int port);
     AsteriskSCF::Media::RTP::V1::RtpStreamSourceStateItemPtr getStateItem();
 
+    void setSinkImpl(const AsteriskSCF::Media::V1::StreamSinkPrx& proxy);
+
     /**
      * Private implementation data for StreamSourceRTPImpl.
      * Note: This is public on purpose so that our RTP callback can access it.
@@ -41,4 +47,4 @@ public:
     boost::shared_ptr<StreamSourceRTPImplPriv> mImpl;
 };
 
-typedef IceUtil::Handle<StreamSourceRTPImpl> StreamSourceRTPImplPtr;
\ No newline at end of file
+typedef IceUtil::Handle<StreamSourceRTPImpl> StreamSourceRTPImplPtr;
diff --git a/src/RtpStateReplicatorApp.cpp b/src/RtpStateReplicatorApp.cpp
index 189e809..fb26f16 100644
--- a/src/RtpStateReplicatorApp.cpp
+++ b/src/RtpStateReplicatorApp.cpp
@@ -217,7 +217,7 @@ void RtpStateReplicatorService::registerWithServiceLocator(const Ice::Communicat
         mStateReplicationManagement = ServiceManagementPrx::uncheckedCast(
             mServiceLocatorManagement->addService(stateReplicatorPrx, stateReplicationGuid));
 
-        ServiceLocatorParamsPtr discoveryParams = new ServiceLocatorParams;
+        RtpStateReplicatorParamsPtr discoveryParams = new RtpStateReplicatorParams;
         discoveryParams->category = AsteriskSCF::Media::RTP::V1::StateReplicatorDiscoveryCategory;
 
         string replicatorName = ic->getProperties()->getPropertyWithDefault("RtpStateReplicator.Name", "default");
@@ -231,6 +231,7 @@ void RtpStateReplicatorService::registerWithServiceLocator(const Ice::Communicat
 
 	// Publish the configuration service IceStorm topic so everybody gets configuration
 	mConfigurationManagement = ServiceManagementPrx::uncheckedCast(
+
 	    mServiceLocatorManagement->addService(mConfigurationPublisher, ""));
 
 	// Populate the configuration parameters with details so we can be found
diff --git a/src/RtpStateReplicatorListener.cpp b/src/RtpStateReplicatorListener.cpp
index a71175a..73853c2 100644
--- a/src/RtpStateReplicatorListener.cpp
+++ b/src/RtpStateReplicatorListener.cpp
@@ -114,7 +114,14 @@ public:
 		    localitem = i->second;
 		}
 
-	        localitem->getSession()->update(item);
+                //
+                // TODO: This appears to happen in testing on occasion. Should verify if this should be
+                // expected.
+                //
+                if (localitem)
+                {
+                    localitem->getSession()->update(item);
+                }
 	    }
 		    
 	    void visitRtpStreamSinkStateItem(const RtpStreamSinkStateItemPtr &item)
diff --git a/src/SessionAdapter.h b/src/SessionAdapter.h
index dfd2234..48834e2 100644
--- a/src/SessionAdapter.h
+++ b/src/SessionAdapter.h
@@ -52,11 +52,6 @@ public:
     virtual int getPayload(const AsteriskSCF::Media::V1::FormatPtr& format) = 0;
     virtual AsteriskSCF::Media::V1::FormatSeq getFormats() = 0;
     virtual void setRemoteDetails(const std::string& host, int port) = 0;
-
-    //
-    // XXX this will be removed in following steps.
-    //
-    virtual pjmedia_transport* getTransport() = 0;
 };
 
 } /* End of namespace PJMediaRTP */
diff --git a/src/UDPTransport.cpp b/src/UDPTransport.cpp
new file mode 100644
index 0000000..eadca54
--- /dev/null
+++ b/src/UDPTransport.cpp
@@ -0,0 +1,74 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include "UDPTransport.h"
+#include "PJUtil.h"
+
+#include <pjmedia.h>
+#include <AsteriskSCF/System/ExceptionsIf.h>
+#include <Ice/Properties.h>
+
+using namespace AsteriskSCF::PJMediaRTP;
+using namespace AsteriskSCF::System::V1;
+using namespace AsteriskSCF::PJUtil;
+using namespace std;
+
+UDPTransportPtr AsteriskSCF::PJMediaRTP::UDPTransport::create(const PJMediaEndpointPtr& ep, 
+    const RTPConfigurationPtr& configObject, bool expectIPv6)
+{
+    const Ice::Int minPort = configObject->getStartPort();
+    const Ice::Int maxPort = configObject->getEndPort();
+
+    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;
+    }
+
+    //
+    // Now create some transport we can use to actually send or receive the media. The candidate ports increment by
+    // two to allow "room" for both a control and a data port.
+    //
+    for (Ice::Int port = minPort; port < maxPort && port <= USHRT_MAX ; port +=2)
+    {
+        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
new file mode 100644
index 0000000..90f53ed
--- /dev/null
+++ b/src/UDPTransport.h
@@ -0,0 +1,55 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include "PJMediaTransport.h"
+#include "PJMediaEndpoint.h"
+#include <Ice/PropertiesF.h>
+#include <boost/shared_ptr.hpp>
+#include "Configuration.h"
+
+struct pjmedia_transport;
+
+namespace AsteriskSCF
+{
+namespace PJMediaRTP
+{
+
+class UDPTransport;
+typedef boost::shared_ptr<UDPTransport> UDPTransportPtr;
+
+class UDPTransport : public PJMediaTransport
+{
+    //
+    // Hidden and unimplemented.
+    //
+    UDPTransport(const UDPTransport&);
+    void operator=(const UDPTransport&);
+    
+public:
+    //
+    // Primary version.
+    //
+    static UDPTransportPtr create(const PJMediaEndpointPtr& ep, const RTPConfigurationPtr& configObject,
+        bool expectIPv6); 
+
+private:
+    UDPTransport(pjmedia_transport* t);
+};
+
+} /* End of namespace PJMediaRTP */
+} /* End of namespace AsteriskSCF */

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


-- 
asterisk-scf/integration/media_rtp_pjmedia.git



More information about the asterisk-scf-commits mailing list