[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 20 07:56:09 CDT 2011


branch "modular-transport-refactor" has been updated
       via  e1bee9143c559f83db106cedee3551aee38ca56b (commit)
       via  df1e8702e76c9c218ced0539f9de00cc53030a7f (commit)
       via  d78e33303454c7dc1eb6b14892b8e6ef445162c3 (commit)
      from  22c77cd865f76c6a2270860cf763301acf70b401 (commit)

Summary of changes:
 local-slice/RtpConfigurationIf.ice                 |  359 ++++++++-----
 src/CMakeLists.txt                                 |   12 +
 src/Configuration.h                                |   10 +
 src/{PJUtil.h => ICEConfiguration.cpp}             |   35 +-
 src/{PJLibConfiguration.h => ICEConfiguration.h}   |   44 +-
 src/ICETransport.cpp                               |  205 +++++++
 src/ICETransport.h                                 |   76 +++
 src/MediaRTPpjmedia.cpp                            |   83 +++-
 src/NATConfig.cpp                                  |  118 ++++
 src/NATConfig.h                                    |   76 +++
 src/NATModule.cpp                                  |   81 +++
 src/{PJMediaEndpoint.h => NATModule.h}             |   33 +-
 src/PJLibConfiguration.cpp                         |   10 +-
 src/PJLibConfiguration.h                           |    3 +-
 src/PJMediaEnvironment.cpp                         |   13 +-
 src/PJMediaEnvironment.h                           |   36 +-
 src/PJMediaTransport.cpp                           |   30 +-
 src/PJMediaTransport.h                             |    8 +-
 src/RTPConfiguration.cpp                           |  559 ++++++++++++++++----
 src/RTPConfiguration.h                             |   39 +-
 src/RTPSession.cpp                                 |  148 ++++--
 ...JLibConfiguration.cpp => SRTPConfiguration.cpp} |   21 +-
 src/{PJLibConfiguration.h => SRTPConfiguration.h}  |   42 +-
 src/{PJMediaEndpoint.cpp => SRTPTransport.cpp}     |   33 +-
 src/{UDPTransport.h => SRTPTransport.h}            |   42 +-
 src/UDPTransport.h                                 |    2 +-
 test/CMakeLists.txt                                |   11 +
 27 files changed, 1645 insertions(+), 484 deletions(-)
 copy src/{PJUtil.h => ICEConfiguration.cpp} (53%)
 copy src/{PJLibConfiguration.h => ICEConfiguration.h} (50%)
 create mode 100644 src/ICETransport.cpp
 create mode 100644 src/ICETransport.h
 create mode 100644 src/NATConfig.cpp
 create mode 100644 src/NATConfig.h
 create mode 100644 src/NATModule.cpp
 copy src/{PJMediaEndpoint.h => NATModule.h} (57%)
 copy src/{PJLibConfiguration.cpp => SRTPConfiguration.cpp} (61%)
 copy src/{PJLibConfiguration.h => SRTPConfiguration.h} (58%)
 copy src/{PJMediaEndpoint.cpp => SRTPTransport.cpp} (51%)
 copy src/{UDPTransport.h => SRTPTransport.h} (59%)


- Log -----------------------------------------------------------------
commit e1bee9143c559f83db106cedee3551aee38ca56b
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Jun 17 19:27:15 2011 -0230

    Incorporating a load of ICE/NAT related changes.

diff --git a/local-slice/RtpConfigurationIf.ice b/local-slice/RtpConfigurationIf.ice
index c380070..68c7c89 100644
--- a/local-slice/RtpConfigurationIf.ice
+++ b/local-slice/RtpConfigurationIf.ice
@@ -16,7 +16,6 @@
 
 #pragma once
 
-#include <Ice/BuiltinSequences.ice>
 #include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice>
 #include <AsteriskSCF/System/Component/ConfigurationIf.ice>
 
@@ -32,145 +31,225 @@ module RTP
 ["suppress"]
 module V1
 {
-   /**
-    * Service locator category for finding the configuration service
-    */
-   const string ConfigurationDiscoveryCategory = "RtpConfiguration";
-
-   /**
-    * Service locator parameters class for discovering the configuration service
-    */
-   unsliceable class RtpConfigurationParams extends AsteriskSCF::Core::Discovery::V1::ServiceLocatorParams
-   {
-       /**
-	* Unique name for the configuration service
-	*/
-       string name;
-   };
-
-   /**
-    * Local visitor class for visiting RTP configuration groups
-    */
-   local class RtpConfigurationGroupVisitor extends AsteriskSCF::System::Configuration::V1::ConfigurationGroupVisitor
-   {
-   };
-
-   /**
-    * Generic RTP configuration group
-    */
-   ["visitor:RtpConfigurationGroupVisitor"] class RtpConfigurationGroup extends AsteriskSCF::System::Configuration::V1::ConfigurationGroup
-   {
-   };
-
-   /**
-    * General RTP configuration group that contains general items related to the RTP component as a whole
-    */
-   class RtpGeneralGroup extends RtpConfigurationGroup
-   {
-   };
-
-   /**
-    * Local visitor class for visiting RTP configuration items
-    */
-   local class RtpConfigurationItemVisitor extends AsteriskSCF::System::Configuration::V1::ConfigurationItemVisitor
-   {
-   };
-
-   /**
-    * Generic RTP configuration item
-    */
-   ["visitor:RtpConfigurationItemVisitor"] class RtpConfigurationItem extends AsteriskSCF::System::Configuration::V1::ConfigurationItem
-   {
-   };
-
-   /**
-    * Name that the port ranges configuration item should be inserted as
-    */
-   const string PortRangesItemName = "ports";
-
-   /**
-    * Port ranges configuration item
-    *
-    * This must be added to the general configuration group using the constant string
-    * in PortRangesItemName
-    *
-    */
-   class PortRangesItem extends RtpConfigurationItem
-   {
-       /**
-	* Start port for RTP and RTCP sockets.
-	*
-	* Default value is 10000.
-	*
-	*/
-       int startPort = 10000;
-
-       /**
-	* End port for RTP and RTCP sockets.
-	*
-	* Default value is 20000.
-	*
-	*/
-       int endPort = 20000;
-   };
-
-   /**
-    * Name that the worker thread count configuration item should be inserted as
-    */
-   const string WorkerThreadCountItemName = "workerThreadCount";
-
-   /**
-    * Worker thread count for incoming media configuration item
-    *
-    * This must be added to the general configuration group using the constant string
-    * in WorkerThreadCountItemName
-    *
-    */
-   class WorkerThreadCountItem extends RtpConfigurationItem
-   {
-       /**
-	* Number of threads that should handle incoming media.
-	*
-	* Default value is 4.
-	*/
-       int count = 4;
-   };
-
-   /**
-    * Name that the IPv4 binding configuration item should be inserted as
-    */
-   const string BindingIPv4AddressItemName = "bindingIPv4";
-
-   /**
-    * Binding address for IPv4 traffic
-    */
-   class BindingIPv4Item extends RtpConfigurationItem
-   {
-       /**
-	* Address that IPv4 sessions should be binded to.
-	*
-	* Default value is all.
-	*/
-       string address;
-   };
-
-   /**
-    * Name that the IPv6 binding configuration item should be inserted as
-    */
-   const string BindingIPv6AddressItemName = "bindingIPv6";
-
-   /**
-    * Binding address for IPv6 traffic
-    */
-   class BindingIPv6Item extends RtpConfigurationItem
-   {
-       /**
-	* Address that IPv6 sessions should be binded to.
-	*
-	* Default value is all.
-	*/
-       string address;
-   };
+    /**
+     * Service locator category for finding the configuration service
+     */
+    const string ConfigurationDiscoveryCategory = "RtpConfiguration";
+
+    /**
+     * Service locator parameters class for discovering the configuration service
+     */
+    unsliceable class RtpConfigurationParams extends AsteriskSCF::Core::Discovery::V1::ServiceLocatorParams
+    {
+        /**
+         * Unique name for the configuration service
+         */
+        string name;
+    };
+
+    /**
+     * Local visitor class for visiting RTP configuration groups
+     */
+    local class RtpConfigurationGroupVisitor extends AsteriskSCF::System::Configuration::V1::ConfigurationGroupVisitor
+    {
+    };
+
+    /**
+     * Generic RTP configuration group
+     */
+    ["visitor:RtpConfigurationGroupVisitor"] class RtpConfigurationGroup extends AsteriskSCF::System::Configuration::V1::ConfigurationGroup
+    {
+    };
+
+    /**
+     * General RTP configuration group that contains general items related to the RTP component as a whole
+     */
+    class RtpGeneralGroup extends RtpConfigurationGroup
+    {
+    };
+
+    /**
+     * Local visitor class for visiting RTP configuration items
+     */
+    local class RtpConfigurationItemVisitor extends AsteriskSCF::System::Configuration::V1::ConfigurationItemVisitor
+    {
+    };
+
+    /**
+     * Generic RTP configuration item
+     */
+    ["visitor:RtpConfigurationItemVisitor"] class RtpConfigurationItem extends AsteriskSCF::System::Configuration::V1::ConfigurationItem
+    {
+    };
+
+    /**
+     * Name that the port ranges configuration item should be inserted as
+     */
+    const string PortRangesItemName = "ports";
+
+    /**
+     * Port ranges configuration item
+     *
+     * This must be added to the general configuration group using the constant string
+     * in PortRangesItemName
+     *
+     */
+    class PortRangesItem extends RtpConfigurationItem
+    {
+        /**
+         * Start port for RTP and RTCP sockets.
+         *
+         * Default value is 10000.
+         *
+         */
+        int startPort = 10000;
+
+        /**
+         * End port for RTP and RTCP sockets.
+         *
+         * Default value is 20000.
+         *
+         */
+        int endPort = 20000;
+    };
+
+    /**
+     * Name that the worker thread count configuration item should be inserted as
+     */
+    const string WorkerThreadCountItemName = "workerThreadCount";
+
+    /**
+     * Worker thread count for incoming media configuration item
+     *
+     * This must be added to the general configuration group using the constant string
+     * in WorkerThreadCountItemName
+     *
+     */
+    class WorkerThreadCountItem extends RtpConfigurationItem
+    {
+        /**
+         * Number of threads that should handle incoming media.
+         *
+         * Default value is 4.
+         */
+        int count = 4;
+    };
+
+    /**
+     * Name that the IPv4 binding configuration item should be inserted as
+     */
+    const string BindingIPv4AddressItemName = "bindingIPv4";
+
+    /**
+     * Binding address for IPv4 traffic
+     */
+    class BindingIPv4Item extends RtpConfigurationItem
+    {
+        /**
+         * Address that IPv4 sessions should be binded to.
+         *
+         * Default value is all.
+         */
+        string address;
+    };
+
+    /**
+     * Name that the IPv6 binding configuration item should be inserted as
+     */
+    const string BindingIPv6AddressItemName = "bindingIPv6";
+
+    /**
+     * Binding address for IPv6 traffic
+     */
+    class BindingIPv6Item extends RtpConfigurationItem
+    {
+        /**
+         * Address that IPv6 sessions should be binded to.
+         *
+         * Default value is all.
+         */
+        string address;
+    };
+       
+    /*
+     * Configuration group for ICE enabled RTP.
+     */
+    class RTPICEConfigurationGroup extends RtpConfigurationGroup
+    {
+    };
+
+    /**
+     * Name that the STUN server configuration item should be inserted as.
+     */
+    const string STUNServerItemName = "stunServer";
+
+    /**
+     * Hostname for the STUN server.
+     */
+    ["visitor:RtpConfigurationItemVisitor"] class STUNServerItem extends RtpConfigurationItem
+    {
+        string address;
+        int port;
+    };
+
+    /**
+     * Name that the TURN server configuration item should be inserted as.
+     */
+    const string TURNServerItemName = "turnServer";
+
+    /**
+     * Hostname for the TURN server.
+     */
+    ["visitor:RtpConfigurationItemVisitor"] class TURNServerItem extends RtpConfigurationItem
+    {
+        string address;
+        int port;
+    };
+
+    /**
+     * Name that the ICE transport configuration flags item should be inserted as.
+     */
+    const string RTPICETransportFlagsItemName = "iceFlags";
+
+    /**
+     * Configuration item with option flags for the ICE transport.
+     */
+    ["visitor:RtpConfigurationItemVisitor"] class RTPICETransportFlagsItem extends RtpConfigurationItem
+    {
+        /**
+         * If the configuration option is present, it's most likely
+         * because we want to enable STUN and ICE
+         */
+        bool enableICE = true;
+        
+        /**
+         * Using a TURN server as a candidate should be a selectable option
+         * since a TURN server isn't always available. Setting this to true
+         * while enableICE is false has no effect.
+         */
+        bool enableTURN = true;
+    };
+
+    /**
+     * Name that ICE option items should be inserted as.
+     */
+    const string RTPICELimitsItemName = "iceLimits";
+
+    /**
+     * Configuration item for configurable limits for the ICE transport.
+     */
+    ["visitor:RtpConfigurationItemVisitor"] class RTPICETransportLimitsItem extends RtpConfigurationItem
+    {
+        /**
+         * The maximum number of candidates to gather and publish.
+         */
+        int maxCandidates;
+
+        /**
+         * The maximum number of ICE negotiated flows to allow.
+         */
+        int maxCalls;
+    };
 
 }; /* module V1 */
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 98e50f6..b8613b7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -43,7 +43,6 @@ asterisk_scf_component_add_file(media_rtp_pjmedia SRTPConfiguration.h)
 asterisk_scf_component_add_file(media_rtp_pjmedia SRTPTransport.cpp)
 asterisk_scf_component_add_file(media_rtp_pjmedia SRTPTransport.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 date_time)
diff --git a/src/Configuration.h b/src/Configuration.h
index 5438f4a..dbe7f25 100755
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -16,6 +16,11 @@
 
 #pragma once
 
+#include "PJLibConfiguration.h"
+#include "NATConfig.h"
+#include "ICEConfiguration.h"
+#include "SRTPConfiguration.h"
+
 #include <Ice/PropertiesF.h>
 #include <string>
 #include <IceUtil/Shared.h>
@@ -34,6 +39,11 @@ class RTPConfiguration : public virtual IceUtil::Shared
 public:
     virtual ~RTPConfiguration() {}
 
+    virtual PJLibConfigurationPtr libConfig() const = 0;
+    virtual NATConfigPtr natConfig() const = 0;
+    virtual ICEConfigurationPtr ICEConfig() const = 0;
+    virtual SRTPConfigurationPtr srtpConfig() const = 0;
+
     virtual int getStartPort() = 0;
     virtual int getEndPort() = 0;
     virtual int getWorkerThreadCount() = 0;
diff --git a/src/ICEConfiguration.cpp b/src/ICEConfiguration.cpp
index d59996c..4ea0aaf 100644
--- a/src/ICEConfiguration.cpp
+++ b/src/ICEConfiguration.cpp
@@ -20,17 +20,9 @@
 using namespace std;
 using namespace AsteriskSCF::PJMediaRTP;
 
-ICEConfigurationPtr AsteriskSCF::PJMediaRTP::ICEConfiguration::create(const Ice::PropertiesPtr& props,
-        const string& propertyPrefix)
+ICEConfigurationPtr AsteriskSCF::PJMediaRTP::ICEConfiguration::create(int maxCand, int maxClls)
 {
-    string prefix(propertyPrefix);
-    if (!prefix.empty() && *(--prefix.end()) != '.')
-    {
-        prefix += '.';
-    }
-    int maxCandidates = props->getPropertyAsIntWithDefault(prefix + "ICE.MaxCandidates", 2);
-    int maxCalls = props->getPropertyAsIntWithDefault(prefix + "ICE.MaxCalls", 2);
-    return ICEConfigurationPtr(new ICEConfiguration(maxCandidates, maxCalls));
+    return ICEConfigurationPtr(new ICEConfiguration(maxCand, maxClls));
 }
 
 ICEConfiguration::ICEConfiguration(int maxCand, int maxClls) :
diff --git a/src/ICEConfiguration.h b/src/ICEConfiguration.h
index 281ace5..450d4df 100644
--- a/src/ICEConfiguration.h
+++ b/src/ICEConfiguration.h
@@ -30,8 +30,7 @@ typedef boost::shared_ptr<ICEConfiguration> ICEConfigurationPtr;
 
 /**
  * ICEConfiguration is fairly minimal at the moment, but may grow in the future. The intent is to reduce code
- * duplication when dealing with pjproject related configuration. This is also an immutable object, so locking is not an
- * issue.
+ * duplication when dealing with pjproject related configuration. 
  **/
 class ICEConfiguration
 {
@@ -46,13 +45,11 @@ public:
     {
         return mMaxCalls;
     }
-    
+
     /**
-     * Create configuration instance from Ice properties.  TODO: This could be extended by adding additional factory
-     * overrides.
+     * Create configuration instance!
      **/
-    static ICEConfigurationPtr create(const Ice::PropertiesPtr& props,
-            const std::string& propertyPrefix);
+    static ICEConfigurationPtr create(int maxCand, int maxClls);
     
 private:
     int mMaxCandidates;
diff --git a/src/ICETransport.cpp b/src/ICETransport.cpp
index 8ba48ef..afd9e1e 100644
--- a/src/ICETransport.cpp
+++ b/src/ICETransport.cpp
@@ -22,11 +22,14 @@
 
 #include <AsteriskSCF/System/ExceptionsIf.h>
 #include <map>
+#include <boost/thread.hpp>
+#include <boost/thread/shared_mutex.hpp>
 
 using namespace AsteriskSCF::PJMediaRTP;
 using namespace AsteriskSCF::System::V1;
 using namespace AsteriskSCF::PJUtil;
 using namespace std;
+using namespace AsteriskSCF::Helpers;
 
 namespace 
 {
@@ -161,26 +164,42 @@ void ICETransport::onSetupComplete(pjmedia_transport* transport, int status)
             pj_memcpy(mLastKnownAddr.get(), &info.sock_info.rtp_addr_name, sizeof(pj_sockaddr));
         }
     }
+    boost::unique_lock<boost::shared_mutex> lock(mLock);
+    mLocalAddress = fromInfo(info);
+}
+
+AddressPtr ICETransport::localAddress() 
+{
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
+    return mLocalAddress;
+}
+
+AddressPtr ICETransport::remoteAddress() 
+{
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
+    return mRemoteAddress;
 }
 
-ICETransportPtr ICETransport::create(const PJMediaEndpointPtr& ep, const RTPConfigurationPtr&)
+ICETransportPtr ICETransport::create(const PJMediaEndpointPtr& ep, const PJMediaEnvironmentPtr& config)
 {
     pjmedia_transport* t;
     PJICECallbackPtr callback(new pjmedia_ice_cb);
     callback->on_ice_complete = &ICECallbackAdapter::onICEComplete;
-    pj_status_t result = pjmedia_ice_create(ep->endpoint(), "ASCF_ICE_MEDIA", 10, 0, callback.get(),
+    NATModulePtr natModule = NATModule::create(config, ep);
+    pj_status_t result = pjmedia_ice_create(ep->endpoint(), "ASCF_ICE_MEDIA", 2, natModule->configuration(), callback.get(),
       &t);
     if (fail(result))
     {
         throw InternalInitializationException("Unable to create new ICE media transport");
     }
-    ICETransportPtr transport(new ICETransport(t, callback));
+    ICETransportPtr transport(new ICETransport(t, callback, natModule));
     ICECallbackAdapter::addEntry(t, transport);
     return transport;
 }
 
-ICETransport::ICETransport(pjmedia_transport* t, const PJICECallbackPtr& cb) :
+ICETransport::ICETransport(pjmedia_transport* t, const PJICECallbackPtr& cb, const NATModulePtr& natModule) :
     PJMediaTransport(t),
-    mCallback(cb)
+    mCallback(cb),
+    mNATModule(natModule)
 { 
 }
diff --git a/src/ICETransport.h b/src/ICETransport.h
index c43f164..301f083 100644
--- a/src/ICETransport.h
+++ b/src/ICETransport.h
@@ -18,9 +18,10 @@
 
 #include "PJMediaTransport.h"
 #include "PJMediaEndpoint.h"
-#include "Configuration.h"
+#include "PJMediaEnvironment.h"
 #include <Ice/PropertiesF.h>
 #include <boost/shared_ptr.hpp>
+#include "NATModule.h"
 
 //
 // Forward declarations.
@@ -46,14 +47,23 @@ public:
     ~ICETransport();
     void onSetupComplete(pjmedia_transport* transport, int status);
 
-    static ICETransportPtr create(const PJMediaEndpointPtr& ep, const RTPConfigurationPtr& configObject);
+    //
+    // Overrides of PJMediaTransport
+    //
+    AsteriskSCF::Helpers::AddressPtr localAddress();
+    AsteriskSCF::Helpers::AddressPtr remoteAddress();
+
+    static ICETransportPtr create(const PJMediaEndpointPtr& ep, const PJMediaEnvironmentPtr& configObject);
 
 private:
     boost::shared_mutex mLock;
+    AsteriskSCF::Helpers::AddressPtr mLocalAddress;
+    AsteriskSCF::Helpers::AddressPtr mRemoteAddress;
     PJICECallbackPtr mCallback;
     PJSockAddrPtr mLastKnownAddr;
+    NATModulePtr mNATModule;
 
-    ICETransport(pjmedia_transport* t, const PJICECallbackPtr& cb);
+    ICETransport(pjmedia_transport* t, const PJICECallbackPtr& cb, const NATModulePtr& natModule);
 
     //
     // Hidden and unimplemented.
diff --git a/src/MediaRTPpjmedia.cpp b/src/MediaRTPpjmedia.cpp
index 2b90345..43b7290 100644
--- a/src/MediaRTPpjmedia.cpp
+++ b/src/MediaRTPpjmedia.cpp
@@ -77,6 +77,7 @@ public:
     {
         return mEnvironment;
     }
+
 private:
     /**
      * A pointer to the object adapter that objects should be added to.
@@ -102,6 +103,10 @@ private:
      * A proxy to the state replicator.
      */
     AsteriskSCF::Discovery::SmartProxy<RtpStateReplicatorPrx> mStateReplicator;
+
+#if CONTROL_POINTS_ENABLED
+    AsteriskSCF::PJMediaRTPTesting mMediaServiceSwitchBoard;
+#endif
 };
 
 /**
@@ -180,6 +185,11 @@ private:
 class RTPMediaServiceCompareServiceImpl : public ServiceLocatorParamsCompare
 {
 public:
+    RTPMediaServiceCompareServiceImpl(const ConfigurationServiceImplPtr& config) :
+        mConfig(config)
+    {
+    }
+
     bool isSupported(const ServiceLocatorParamsPtr& locatorParams, const Ice::Current&)
     {
 	RTPServiceLocatorParamsPtr params;
@@ -200,9 +210,45 @@ public:
 	    result = false;
 #endif
 	}
+        if (!result)
+        {
+            return false;
+        }
+        
+        RTPOverICEServiceLocatorParamsPtr iceParams = RTPOverICEServiceLocatorParamsPtr::dynamicCast(locatorParams);
+        if (iceParams)
+        {
+            if (iceParams->enableRTPOverICE)
+            {
+                NATConfigPtr natConfig = mConfig->natConfig();
+
+                if (natConfig && natConfig->isSTUNEnabled())
+                {
+                    if (iceParams->enableTURN)
+                    {
+                        if (!natConfig->isTURNEnabled())
+                        {
+                            result = false;
+                        }
+                    }
+                }
+                else
+                {
+                    result = false;
+                }
+            }
+            //
+            // We ignore the else case because we can definitely do non-ICE related stuff... its not clear
+            // that negative matches in this case should be exclusionary. Actual ICE usage will be specified
+            // when the RTP session is allocated.
+            //
+        }
 
 	return result;
     };
+
+private:
+    ConfigurationServiceImplPtr mConfig;
 };
 
 /**
@@ -429,8 +475,10 @@ typedef IceUtil::Handle<RtpConfigurationCompare> RtpConfigurationComparePtr;
 RTPMediaServiceImpl::RTPMediaServiceImpl(const Ice::ObjectAdapterPtr& adapter, const ReplicaPrx& replicaService,
     const AsteriskSCF::Discovery::SmartProxy<RtpStateReplicatorPrx>& stateReplicator,
     const ConfigurationServiceImplPtr& configurationService) :
-    mAdapter(adapter), mEnvironment(PJMediaEnvironment::create(adapter->getCommunicator()->getProperties(), "")),
-    mReplicaServicePrx(replicaService), mConfigurationService(configurationService),
+    mAdapter(adapter), 
+    mEnvironment(PJMediaEnvironment::create(adapter->getCommunicator()->getProperties(), configurationService)),
+    mReplicaServicePrx(replicaService), 
+    mConfigurationService(configurationService),
     mStateReplicator(stateReplicator)
 {
 }
@@ -484,10 +532,8 @@ void MediaRTPpjmediaApp::start(const std::string&, const Ice::CommunicatorPtr& c
     mReplicaService = new ReplicaImpl(mLocalAdapter);
     mReplicaServicePrx = ReplicaPrx::uncheckedCast(mLocalAdapter->add(mReplicaService, mCommunicator->stringToIdentity(ReplicaServiceId)));
 
-    mConfigurationService = new ConfigurationServiceImpl();
-    ConfigurationServicePrx mConfigurationServiceProxy = ConfigurationServicePrx::uncheckedCast(
-	mLocalAdapter->addWithUUID(mConfigurationService));
-
+    mConfigurationService = ConfigurationServiceImpl::create();
+    ConfigurationServicePrx mConfigurationServiceProxy = mConfigurationService->activate(mLocalAdapter, IceUtil::generateUUID());
     mLocalAdapter->activate();
 
     mGlobalAdapter = mCommunicator->createObjectAdapter("MediaRTPpjmediaAdapter");
@@ -567,7 +613,7 @@ void MediaRTPpjmediaApp::start(const std::string&, const Ice::CommunicatorPtr& c
 	}
     }
 
-    ServiceLocatorParamsComparePtr rtpmediacomparatorservice = new RTPMediaServiceCompareServiceImpl();
+    ServiceLocatorParamsComparePtr rtpmediacomparatorservice = new RTPMediaServiceCompareServiceImpl(mConfigurationService);
     ServiceLocatorParamsComparePrx RTPMediaComparatorServiceProxy = ServiceLocatorParamsComparePrx::uncheckedCast(
 	mGlobalAdapter->add(rtpmediacomparatorservice, mCommunicator->stringToIdentity(MediaComparatorServiceId)));
     
@@ -581,14 +627,31 @@ void MediaRTPpjmediaApp::start(const std::string&, const Ice::CommunicatorPtr& c
     RTPMediaServicePrx RTPMediaServiceProxy = RTPMediaServicePrx::uncheckedCast(mGlobalAdapter->add(rtpmediaservice,
 	    mCommunicator->stringToIdentity(MediaServiceId)));
 
-    RTPServiceLocatorParamsPtr rtpparams = new RTPServiceLocatorParams();
+    RTPOverICEServiceLocatorParamsPtr rtpparams = new RTPOverICEServiceLocatorParams;
+    rtpparams->category = "rtp";
+    PJMediaEnvironmentPtr mediaEnvironment = rtpmediaservice->getEnvironment();
+
+    //
+    // Service wide configuration is done through properties allowing certain features
+    // to be completely disabled.
+    //
+    NATConfigPtr natConfig = mediaEnvironment->natConfig();
+    if (natConfig && natConfig->isSTUNEnabled())
+    {
+        rtpparams->enableRTPOverICE = true;
+        rtpparams->enableTURN = natConfig->isTURNEnabled();
+    }
+    else
+    {
+        rtpparams->enableRTPOverICE = false;
+        rtpparams->enableTURN = false;
+    }
 
     if (mReplicaService->isActive() == true)
     {
 	mGeneralState->mServiceManagement = ServiceManagementPrx::uncheckedCast(
             mManagement->addService(RTPMediaServiceProxy, "media_rtp_pjmedia"));
 	/* Now we can add some parameters to help find us. */
-	rtpparams->category = "rtp";
 	mGeneralState->mServiceManagement->addLocatorParams(rtpparams, mGeneralState->mComparatorId);
     }
 
@@ -601,7 +664,7 @@ void MediaRTPpjmediaApp::start(const std::string&, const Ice::CommunicatorPtr& c
 
     /* Let's add the component service to the service locator first */
     mComponentServiceManagement =
-        ServiceManagementPrx::uncheckedCast(mManagement->addService(ComponentServiceProxy, "media_rtp_pjmedia"));
+        ServiceManagementPrx::uncheckedCast(mManagement->addService(ComponentServiceProxy, "media_rtp_pjmedia.component"));
     genericparams->category = "Component/media_rtp_pjmedia";
     mComponentServiceManagement->addLocatorParams(genericparams, "");
 
diff --git a/src/NATConfig.cpp b/src/NATConfig.cpp
index cab495d..96aa923 100644
--- a/src/NATConfig.cpp
+++ b/src/NATConfig.cpp
@@ -32,6 +32,8 @@ namespace
 Logger logger = getLoggerFactory().getLogger("AsteriskSCF.MediaRTP");
 }
 
+#if 0
+
 NATConfigPtr AsteriskSCF::PJMediaRTP::NATConfig::create(const Ice::PropertiesPtr& props,
         const string& propertyPrefix)
 {
@@ -96,6 +98,13 @@ NATConfigPtr AsteriskSCF::PJMediaRTP::NATConfig::create(const Ice::PropertiesPtr
     }
     return NATConfigPtr(new NATConfig(stunAddress, turnAddress, hasSTUN, hasTURN));
 }
+#endif
+
+NATConfigPtr NATConfig::create(const AsteriskSCF::Helpers::AddressPtr& stunSrv, bool enableSTUN,
+        const AsteriskSCF::Helpers::AddressPtr& turnSrv, bool enableTURN)
+{
+    return NATConfigPtr(new NATConfig(stunSrv, turnSrv, enableSTUN, enableTURN));
+}
 
 NATConfig::NATConfig(const AddressPtr& stun, const AddressPtr& turn,
         bool enableSTUN, bool enableTURN) :
@@ -104,4 +113,6 @@ NATConfig::NATConfig(const AddressPtr& stun, const AddressPtr& turn,
     mSTUNEnabled(enableSTUN),
     mTURNEnabled(enableTURN)
 {
+    std::cerr << "creating a NATConfig object with " << (mSTUNServer ? mSTUNServer->toString() : "<no stun>") << " and " <<
+        (mTURNServer ? mTURNServer->toString() : "<no turn>") << std::endl;
 }
diff --git a/src/NATConfig.h b/src/NATConfig.h
index df86342..ac87662 100644
--- a/src/NATConfig.h
+++ b/src/NATConfig.h
@@ -53,7 +53,8 @@ public:
         return mTURNEnabled;
     }
     
-    static NATConfigPtr create(const Ice::PropertiesPtr& properties, const std::string& prefix);
+    static NATConfigPtr create(const AsteriskSCF::Helpers::AddressPtr& stunSrv, bool enableSTUN,
+            const AsteriskSCF::Helpers::AddressPtr& turnSrv, bool enableTURN);
 private:
     AsteriskSCF::Helpers::AddressPtr mSTUNServer;
     AsteriskSCF::Helpers::AddressPtr mTURNServer;
diff --git a/src/NATModule.cpp b/src/NATModule.cpp
index 06317b1..d20d83f 100644
--- a/src/NATModule.cpp
+++ b/src/NATModule.cpp
@@ -40,7 +40,15 @@ NATModulePtr AsteriskSCF::PJMediaRTP::NATModule::create(const PJMediaEnvironment
 
     pj_strdup2(env->memoryPool(), &transcfg->stun.server, env->natConfig()->stunServer()->hostname().c_str());
     transcfg->stun.port = static_cast<pj_uint16_t>(env->natConfig()->stunServer()->port());
-    transcfg->stun.max_host_cands = env->ICEConfig()->maxCandidates();
+    ICEConfigurationPtr iceConfig = env->ICEConfig();
+    if (iceConfig)
+    {
+        transcfg->stun.max_host_cands = env->ICEConfig()->maxCandidates();
+    }
+    else
+    {
+        transcfg->stun.max_host_cands = 2; // XX arbitrary.
+    }
     if (env->natConfig()->isTURNEnabled())
     {
         pj_strdup2(env->memoryPool(), &transcfg->turn.server, env->natConfig()->turnServer()->hostname().c_str());
diff --git a/src/NATModule.h b/src/NATModule.h
index f23484c..fa834ef 100644
--- a/src/NATModule.h
+++ b/src/NATModule.h
@@ -37,6 +37,11 @@ class NATModule
 public:
     ~NATModule();
 
+    pj_ice_strans_cfg* configuration()
+    {
+        return mTransactionConfig.get();
+    }
+
     static NATModulePtr create(const PJMediaEnvironmentPtr& environ, const PJMediaEndpointPtr& endpoint);
 
 private:
diff --git a/src/PJLibConfiguration.cpp b/src/PJLibConfiguration.cpp
index ae25b7d..654f3fe 100644
--- a/src/PJLibConfiguration.cpp
+++ b/src/PJLibConfiguration.cpp
@@ -20,15 +20,9 @@
 using namespace std;
 using namespace AsteriskSCF::PJMediaRTP;
 
-PJLibConfigurationPtr AsteriskSCF::PJMediaRTP::PJLibConfiguration::create(const Ice::PropertiesPtr& props,
-        const string& propertyPrefix)
+PJLibConfigurationPtr AsteriskSCF::PJMediaRTP::PJLibConfiguration::create(const Ice::PropertiesPtr& props)
 {
-    string prefix(propertyPrefix);
-    if (!prefix.empty() && *(--prefix.end()) != '.')
-    {
-        prefix  += '.';
-    }
-    int timerHeapSize = props->getPropertyAsIntWithDefault(prefix + "TimerHeap.Size", 1000); 
+    int timerHeapSize = props->getPropertyAsIntWithDefault("PJMedia.TimerHeap.Size", 1000); 
     return PJLibConfigurationPtr(new PJLibConfiguration(timerHeapSize));
 }
 
diff --git a/src/PJLibConfiguration.h b/src/PJLibConfiguration.h
index 85ee8c6..3e09288 100644
--- a/src/PJLibConfiguration.h
+++ b/src/PJLibConfiguration.h
@@ -45,8 +45,7 @@ public:
      * Create configuration instance from Ice properties.  TODO: This could be extended by adding additional factory
      * overrides.
      **/
-    static boost::shared_ptr<PJLibConfiguration> create(const Ice::PropertiesPtr& props,
-            const std::string& propertyPrefix);
+    static boost::shared_ptr<PJLibConfiguration> create(const Ice::PropertiesPtr& props);
 
 private:
     int mTimerHeapSize;
diff --git a/src/PJMediaEnvironment.cpp b/src/PJMediaEnvironment.cpp
index d914662..8de76b8 100644
--- a/src/PJMediaEnvironment.cpp
+++ b/src/PJMediaEnvironment.cpp
@@ -31,23 +31,15 @@ using namespace AsteriskSCF::PJUtil;
 // The main work of creating the various objects is done by the factory, not the PJMediaEnvironment constructor.
 //
 PJMediaEnvironmentPtr AsteriskSCF::PJMediaRTP::PJMediaEnvironment::create(const Ice::PropertiesPtr& props,
-        const string& propertyPrefix)
+        const RTPConfigurationPtr& configObject)
 {
-    return PJMediaEnvironmentPtr(
-         new PJMediaEnvironment(PJLibConfiguration::create(props, propertyPrefix),
-                ICEConfiguration::create(props, propertyPrefix),
-                NATConfig::create(props, propertyPrefix),
-                SRTPConfiguration::create(props, propertyPrefix)));
+    return PJMediaEnvironmentPtr(new PJMediaEnvironment(PJLibConfiguration::create(props), configObject));
 }
         
 PJMediaEnvironment::PJMediaEnvironment(const PJLibConfigurationPtr& libCfg,
-        const ICEConfigurationPtr& iceCfg,
-        const NATConfigPtr& natCfg,
-        const SRTPConfigurationPtr& srtpCfg) :
+        const RTPConfigurationPtr& configObject) :
     mPJLibConfig(libCfg),
-    mICEConfig(iceCfg),
-    mNATConfig(natCfg),
-    mSRTPConfig(srtpCfg),
+    mConfiguration(configObject),
     mCachingPool(new pj_caching_pool)
 {
     //
diff --git a/src/PJMediaEnvironment.h b/src/PJMediaEnvironment.h
index 5ec0166..b9be64a 100644
--- a/src/PJMediaEnvironment.h
+++ b/src/PJMediaEnvironment.h
@@ -16,10 +16,7 @@
 
 #pragma once
 
-#include "PJLibConfiguration.h"
-#include "NATConfig.h"
-#include "ICEConfiguration.h"
-#include "SRTPConfiguration.h"
+#include "Configuration.h"
 
 #include <Ice/PropertiesF.h>
 #include <string>
@@ -75,7 +72,7 @@ public:
      */
     NATConfigPtr natConfig() const
     {
-        return mNATConfig;
+        return mConfiguration->natConfig();
     }
 
     /**
@@ -83,15 +80,15 @@ public:
      */
     ICEConfigurationPtr ICEConfig() const
     {
-        return mICEConfig;
+        return mConfiguration->ICEConfig();
     }
-
+            
     /**
      * Get SRTP relatd configuratino object.
      */
     SRTPConfigurationPtr srtpConfig() const
     {
-        return mSRTPConfig;
+        return mConfiguration->srtpConfig();
     }
 
     /**
@@ -115,26 +112,20 @@ public:
 
     /**
      * Create an instance of the object based on the Ice properties.
-     *
-     * XXX: This needs to be extended to work with the configuration service.
      */
-    static PJMediaEnvironmentPtr create(const Ice::PropertiesPtr& props, const std::string& prefix);
+    static PJMediaEnvironmentPtr create(const Ice::PropertiesPtr& props, const RTPConfigurationPtr& configObject);
 
 private:
 
     PJLibConfigurationPtr mPJLibConfig;
-    ICEConfigurationPtr mICEConfig;
-    NATConfigPtr mNATConfig;
-    SRTPConfigurationPtr mSRTPConfig;
+    RTPConfigurationPtr mConfiguration;
     
     pj_pool_factory* mPoolFactory;
     pj_pool_t* mMemoryPool;
     boost::shared_ptr<pj_caching_pool> mCachingPool;
 
     PJMediaEnvironment(const PJLibConfigurationPtr& libConfig,
-            const ICEConfigurationPtr& iceConfig,
-            const NATConfigPtr& natconfig,
-            const SRTPConfigurationPtr& srtpConfig);
+            const RTPConfigurationPtr& configObject);
 };
 
 } /* End of namespace PJMediaRTP */
diff --git a/src/PJMediaTransport.cpp b/src/PJMediaTransport.cpp
index a409acc..f218831 100644
--- a/src/PJMediaTransport.cpp
+++ b/src/PJMediaTransport.cpp
@@ -26,15 +26,6 @@ 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);
@@ -48,20 +39,14 @@ pjmedia_transport* PJMediaTransport::getTransport() const
 PJMediaTransport::PJMediaTransport(pjmedia_transport* t) :
     mTransport(t)
 {
-#ifndef _NDEBUG
-    //
-    // TODO: temporary
-    //
-    cerr << "Creating PJMediaTransport for " << getLocalAddressImpl()->toString() << endl;
-#endif
 }
 
-AddressPtr PJMediaTransport::localAddress() const
+AddressPtr PJMediaTransport::localAddress() 
 {
     return getLocalAddressImpl();
 }
 
-AddressPtr PJMediaTransport::remoteAddress() const
+AddressPtr PJMediaTransport::remoteAddress() 
 {
     pjmedia_transport_info info;
     pjmedia_transport_info_init(&info);
@@ -80,10 +65,19 @@ AddressPtr PJMediaTransport::remoteAddress() const
     return fromInfo(info);
 }
 
-AddressPtr PJMediaTransport::getLocalAddressImpl() const
+AddressPtr PJMediaTransport::getLocalAddressImpl() 
 {
     pjmedia_transport_info info;
     pjmedia_transport_info_init(&info);
     pjmedia_transport_get_info(mTransport, &info);
     return fromInfo(info);
 }
+
+AddressPtr PJMediaTransport::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));
+}
diff --git a/src/PJMediaTransport.h b/src/PJMediaTransport.h
index 2ff1da7..9de8f2f 100644
--- a/src/PJMediaTransport.h
+++ b/src/PJMediaTransport.h
@@ -23,6 +23,7 @@
 // Forward declarations.
 //
 struct pjmedia_transport;
+struct pjmedia_transport_info;
 
 namespace AsteriskSCF
 {
@@ -40,15 +41,16 @@ public:
 
     pjmedia_transport* getTransport() const;
 
-    virtual AsteriskSCF::Helpers::AddressPtr localAddress() const;
-    virtual AsteriskSCF::Helpers::AddressPtr remoteAddress() const;
+    virtual AsteriskSCF::Helpers::AddressPtr localAddress();
+    virtual AsteriskSCF::Helpers::AddressPtr remoteAddress();
 
 protected:
     pjmedia_transport* mTransport;
 
     PJMediaTransport(pjmedia_transport* t);
 
-    AsteriskSCF::Helpers::AddressPtr getLocalAddressImpl() const;
+    AsteriskSCF::Helpers::AddressPtr getLocalAddressImpl();
+    AsteriskSCF::Helpers::AddressPtr fromInfo(pjmedia_transport_info& info);
 
     //
     // Hidden and unimplemented.
diff --git a/src/RTPConfiguration.cpp b/src/RTPConfiguration.cpp
index bb00da4..b95780b 100644
--- a/src/RTPConfiguration.cpp
+++ b/src/RTPConfiguration.cpp
@@ -23,17 +23,114 @@
 #include <boost/thread.hpp>
 #include <boost/thread/shared_mutex.hpp>
 
-
 using namespace AsteriskSCF::System::Configuration::V1;
 using namespace AsteriskSCF::Media::RTP::V1;
+using namespace AsteriskSCF::PJMediaRTP;
+using namespace std;
 
-class ConfigurationServiceImplPriv
+/**
+ * Implementation of the configuration service.
+ */
+class ConfigurationServiceServant : virtual public ConfigurationServiceImpl
 {
 public:
+
+    /**
+     * AsteriskSCF::System::Configuration::V1 interface. Slice to C++ mapping.
+     */
+    AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq
+    getConfiguration(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
+    
+    AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq
+    getConfigurationAll(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
+    
+    AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq
+    getConfigurationGroups(const Ice::Current&);
+
+    void setConfiguration(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
+
+    void removeConfigurationItems(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&,
+            const Ice::Current&);
+    void removeConfigurationGroups(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&,
+            const Ice::Current&);
+
+    /**
+     * AsteriskSCF::PJMediaRTP::RTPConfiguration interface.
+     */
+    int getStartPort();
+    int getEndPort();
+    int getWorkerThreadCount();
+
+    std::string getBindIPv4Address();
+    std::string getBindIPv6Address();
+
+    PJLibConfigurationPtr libConfig() const
+    {
+        return PJLibConfigurationPtr(); // XXX this isn't implemented here at this time.
+    }
+
+    NATConfigPtr natConfig() const
+    {
+        return mNATConfig;
+    }
+
+    ICEConfigurationPtr ICEConfig() const
+    {
+        return mICEConfig;
+    }
+
+    SRTPConfigurationPtr srtpConfig() const
+    {
+        return mSRTPConfig;
+    }
+
+    ConfigurationServicePrx activate(const Ice::ObjectAdapterPtr& objectAdapter, const string& id);
+
+    void replaceConfig(const ICEConfigurationPtr& newConfig)
+    {
+        mICEConfig = newConfig;
+    }
+    
+    void replaceConfig(const NATConfigPtr& newConfig)
+    {
+        mNATConfig = newConfig;
+    }
+    
+    void replaceConfig(const SRTPConfigurationPtr& newConfig)
+    {
+        mSRTPConfig = newConfig;
+    }
+
+    RtpGeneralGroupPtr getGeneralGroup()
+    {
+        return mGeneralGroup;
+    }
+
+    RTPICEConfigurationGroupPtr getICEConfigurationGroup()
+    {
+        return mICEConfiguration;
+    }
+
+    void replaceGroup(const RtpGeneralGroupPtr& group)
+    {
+        mGeneralGroup = group;
+    }
+
+    void replaceGroup(const RTPICEConfigurationGroupPtr& group)
+    {
+        mICEConfiguration = group;
+    }
+
+private:
     /**
      * General RTP configuration
      */
     RtpGeneralGroupPtr mGeneralGroup;
+    RTPICEConfigurationGroupPtr mICEConfiguration;
+
+    ICEConfigurationPtr mICEConfig;
+    NATConfigPtr mNATConfig;
+    SRTPConfigurationPtr mSRTPConfig;
 
     /**
      * Shared mutex lock which protects the configuration
@@ -41,16 +138,20 @@ public:
     boost::shared_mutex mLock;
 };
 
-ConfigurationServiceImpl::ConfigurationServiceImpl() : mImplPriv(new ConfigurationServiceImplPriv())
-{
-}
+typedef IceUtil::Handle<ConfigurationServiceServant> ConfigurationServiceServantPtr;
 
-ConfigurationGroupSeq ConfigurationServiceImpl::getConfiguration(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
+ConfigurationGroupSeq ConfigurationServiceServant::getConfiguration(
+    const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
 {
     class GroupVisitor : public RtpConfigurationGroupVisitor
     {
     public:
-        GroupVisitor(boost::shared_ptr<ConfigurationServiceImplPriv> implPriv, ConfigurationGroupSeq& visitorGroups) : mImplPriv(implPriv), mGroups(visitorGroups) { };
+        GroupVisitor(const ConfigurationServiceServantPtr& impl,
+                ConfigurationGroupSeq& visitorGroups) :
+            mImpl(impl),
+            mGroups(visitorGroups)
+        {
+        }
 
     private:
         /**
@@ -60,8 +161,7 @@ ConfigurationGroupSeq ConfigurationServiceImpl::getConfiguration(const AsteriskS
             const ConfigurationItemDict& localItems,
             ConfigurationItemDict& returnedItems)
         {
-
-            boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+            // boost::shared_lock<boost::shared_mutex> lock(mLock); XXX re-establish locking.
 
             for (ConfigurationItemDict::const_iterator requestedItem = requestedItems.begin();
                  requestedItem != requestedItems.end();
@@ -78,24 +178,40 @@ ConfigurationGroupSeq ConfigurationServiceImpl::getConfiguration(const AsteriskS
 
         void visitRtpGeneralGroup(const ::AsteriskSCF::Media::RTP::V1::RtpGeneralGroupPtr& group)
         {
-            if (!mImplPriv->mGeneralGroup)
+            RtpGeneralGroupPtr currentGroup =  mImpl->getGeneralGroup();
+            if (currentGroup)
             {
                 return;
             }
 
             RtpGeneralGroupPtr returnedGroup = new RtpGeneralGroup();
 
-            insertRequestedConfigurationItems(group->configurationItems, mImplPriv->mGeneralGroup->configurationItems, returnedGroup->configurationItems);
+            insertRequestedConfigurationItems(group->configurationItems,
+                    currentGroup->configurationItems, returnedGroup->configurationItems);
 
             mGroups.push_back(returnedGroup);
         };
 
-        boost::shared_ptr<ConfigurationServiceImplPriv> mImplPriv;
+        void visitRTPICEConfigurationGroup(const RTPICEConfigurationGroupPtr& group)
+        {
+            RTPICEConfigurationGroupPtr currentGroup = mImpl->getICEConfigurationGroup();
+            
+            if (!currentGroup)
+            {
+                return;
+            }
+            RTPICEConfigurationGroupPtr returnedGroup = new RTPICEConfigurationGroup;
+            insertRequestedConfigurationItems(group->configurationItems, currentGroup->configurationItems,
+                    returnedGroup->configurationItems);
+            mGroups.push_back(returnedGroup);
+        }
+        
+        ConfigurationServiceServantPtr mImpl;
         ConfigurationGroupSeq& mGroups;
     };
     
     ConfigurationGroupSeq newGroups;
-    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(mImplPriv, newGroups);
+    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(this, newGroups);
     
     for (ConfigurationGroupSeq::const_iterator group = groups.begin(); group != groups.end(); ++group)
     {
@@ -105,33 +221,44 @@ ConfigurationGroupSeq ConfigurationServiceImpl::getConfiguration(const AsteriskS
     return newGroups;
 }
 
-ConfigurationGroupSeq ConfigurationServiceImpl::getConfigurationAll(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
+ConfigurationGroupSeq ConfigurationServiceServant::getConfigurationAll(
+    const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
 {
     class GroupVisitor : public RtpConfigurationGroupVisitor
     {
     public:
-        GroupVisitor(boost::shared_ptr<ConfigurationServiceImplPriv> implPriv, ConfigurationGroupSeq& visitorGroups) :
-            mImplPriv(implPriv), mGroups(visitorGroups) { };
+        GroupVisitor(const ConfigurationServiceServantPtr& impl, ConfigurationGroupSeq& visitorGroups) :
+            mImpl(impl), mGroups(visitorGroups)
+        {
+        }
  
     private:
-        void visitRtpGeneralGroup(const ::AsteriskSCF::Media::RTP::V1::RtpGeneralGroupPtr&)
+        void visitRtpGeneralGroup(const RtpGeneralGroupPtr&)
         {
-            if (!mImplPriv->mGeneralGroup)
+            RtpGeneralGroupPtr g = mImpl->getGeneralGroup();
+            if (g)
             {
-                return;
+                mGroups.push_back(g);
             }
-     
-            mGroups.push_back(mImplPriv->mGeneralGroup);
         };
+
+        void visitICEConfigurationGroup(const RTPICEConfigurationGroupPtr&)
+        {
+            RTPICEConfigurationGroupPtr g = mImpl->getICEConfigurationGroup();
+            if (g)
+            {
+                mGroups.push_back(g);
+            }
+        }
         
-        boost::shared_ptr<ConfigurationServiceImplPriv> mImplPriv;
+        ConfigurationServiceServantPtr mImpl;
         ConfigurationGroupSeq& mGroups;
     };
     
     ConfigurationGroupSeq newGroups;
-    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(mImplPriv, newGroups);
+    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(this, newGroups);
 
-    boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
     
     for (ConfigurationGroupSeq::const_iterator group = groups.begin(); group != groups.end(); ++group)
     {
@@ -141,34 +268,40 @@ ConfigurationGroupSeq ConfigurationServiceImpl::getConfigurationAll(const Asteri
     return newGroups;
 }
 
-ConfigurationGroupSeq ConfigurationServiceImpl::getConfigurationGroups(const Ice::Current&)
+ConfigurationGroupSeq ConfigurationServiceServant::getConfigurationGroups(const Ice::Current&)
 {
     ConfigurationGroupSeq groups;
- 
-    boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
    
-    if (mImplPriv->mGeneralGroup)
+    if (mGeneralGroup)
+    {
+        groups.push_back(new RtpGeneralGroup);
+    }
+    if (mICEConfiguration)
     {
-        RtpGeneralGroupPtr general = new RtpGeneralGroup();
-        groups.push_back(general);
+        groups.push_back(new RTPICEConfigurationGroup);
     }
     
     return groups;
 }
 
-void ConfigurationServiceImpl::setConfiguration(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
+void ConfigurationServiceServant::setConfiguration(const ConfigurationGroupSeq& groups,
+    const Ice::Current&)
 {
     class GroupVisitor : public RtpConfigurationGroupVisitor
     {
     public:
-        GroupVisitor(boost::shared_ptr<ConfigurationServiceImplPriv> implPriv) : mImplPriv(implPriv) { };
+        GroupVisitor(const ConfigurationServiceServantPtr& impl) : 
+            mImpl(impl)
+        {
+        }
  
     private:
         /**
          * Helper function which performs serial number checking of items
          */
         void performSerialCheck(const ConfigurationItemDict& changedItems, const ConfigurationItemDict& localItems,
-            const AsteriskSCF::System::Configuration::V1::ConfigurationGroupPtr& group)
+            const ConfigurationGroupPtr& group)
         {
             for (ConfigurationItemDict::const_iterator item = changedItems.begin();
                  item != changedItems.end();
@@ -197,45 +330,165 @@ void ConfigurationServiceImpl::setConfiguration(const AsteriskSCF::System::Confi
  
         void visitRtpGeneralGroup(const ::AsteriskSCF::Media::RTP::V1::RtpGeneralGroupPtr& group)
         {
-            if (!mImplPriv->mGeneralGroup)
+            RtpGeneralGroupPtr g = mImpl->getGeneralGroup();
+            if (!g)
             {
-                mImplPriv->mGeneralGroup = new RtpGeneralGroup();
+                g = new RtpGeneralGroup();
             }
             else
             {
-                performSerialCheck(group->configurationItems, mImplPriv->mGeneralGroup->configurationItems, group);
+                performSerialCheck(group->configurationItems, g->configurationItems, group);
             }
      
             for (ConfigurationItemDict::const_iterator item = group->configurationItems.begin();
                  item != group->configurationItems.end();
                  ++item)
             {
-                mImplPriv->mGeneralGroup->configurationItems.erase(item->first);
-                mImplPriv->mGeneralGroup->configurationItems.insert((*item));
+                g->configurationItems.erase(item->first);
+                g->configurationItems.insert((*item));
             }
+            //
+            // Replacing the group may or may not be necessary depending on the
+            // semantics of getGeneralGroup() and whether or not we had to
+            // create a new group.
+            //
+            mImpl->replaceGroup(g);
         }
- 
-        boost::shared_ptr<ConfigurationServiceImplPriv> mImplPriv;
+
+        void visitRTPICEConfigurationGroup(const RTPICEConfigurationGroupPtr& group)
+        {
+            //
+            // The Visitor in this case interprets the configuration data and
+            // sets data members to let it know what needs to be done when the
+            // visiting is completed.
+            //
+            class Visitor : public RtpConfigurationItemVisitor
+            {
+            public:
+                Visitor(const ConfigurationServiceServantPtr& configObject) :
+                    mImpl(configObject),
+                    mCreateRTPICEConfig(false),
+                    mCreateNATConfig(false),
+                    mEnableSTUN(false),
+                    mEnableTURN(false),
+                    mMaxCandidates(0),          // XXX- set some kind of hard code or slice defined default?
+                    mMaxCalls(0)
+                {
+                }
+
+                ~Visitor()
+                {
+                    if (mCreateNATConfig)
+                    {
+                        mImpl->replaceConfig(NATConfig::create(mStunHost, mEnableSTUN, mTurnHost, mEnableTURN));
+                    }
+                    if (mCreateRTPICEConfig)
+                    {
+                        mImpl->replaceConfig(ICEConfiguration::create(mMaxCandidates, mMaxCalls));
+                    }
+                }
+                
+
+                void visitSTUNServerItem(const STUNServerItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mCreateNATConfig = true;
+                        mStunHost = AsteriskSCF::Helpers::AddressPtr(new AsteriskSCF::Helpers::Address(item->address, item->port));
+                    }
+                }
+
+                void visitTURNServerItem(const TURNServerItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mCreateNATConfig = true;
+                        mTurnHost = AsteriskSCF::Helpers::AddressPtr(new AsteriskSCF::Helpers::Address(item->address, item->port));
+                    }
+                }
+
+                void visitRTPICETransportFlagsItem(const RTPICETransportFlagsItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mCreateNATConfig = true;
+                        mEnableTURN = item->enableTURN;
+                        mEnableSTUN = item->enableICE;
+                    }
+                }
+
+                void visitRTPICETransportLimitsItem(const RTPICETransportLimitsItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mCreateRTPICEConfig = true;
+                        mMaxCalls = item->maxCalls;
+                        mMaxCandidates = item->maxCandidates;
+                    }
+                }
+                
+            private:
+
+                ConfigurationServiceServantPtr mImpl;
+                
+                bool mCreateRTPICEConfig;
+                bool mCreateNATConfig;
+
+                AsteriskSCF::Helpers::AddressPtr mStunHost;
+                AsteriskSCF::Helpers::AddressPtr mTurnHost;
+                bool mEnableSTUN;
+                bool mEnableTURN;
+                int mMaxCandidates;
+                int mMaxCalls;
+            }; // end of Visitor class definition.
+
+            RTPICEConfigurationGroupPtr g = mImpl->getICEConfigurationGroup();
+            if (!g)
+            {
+                g = new RTPICEConfigurationGroup;
+            }
+            else
+            {
+                performSerialCheck(group->configurationItems, g->configurationItems, group);
+            }
+
+            RtpConfigurationItemVisitorPtr v(new Visitor(mImpl));
+     
+            for (ConfigurationItemDict::const_iterator item = group->configurationItems.begin();
+                 item != group->configurationItems.end();
+                 ++item)
+            {
+                g->configurationItems.erase(item->first);
+                g->configurationItems.insert((*item));
+                item->second->visit(v);
+            }
+            mImpl->replaceGroup(g);
+        }
+
+        ConfigurationServiceServantPtr mImpl;
     };
     
-    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(mImplPriv);
+    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(this);
 
-    boost::unique_lock<boost::shared_mutex> lock(mImplPriv->mLock);
-    
+    boost::unique_lock<boost::shared_mutex> lock(mLock);
     for (ConfigurationGroupSeq::const_iterator group = groups.begin(); group != groups.end(); ++group)
     {
         (*group)->visit(v);
     }
 }
 
-void ConfigurationServiceImpl::removeConfigurationItems(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
+void ConfigurationServiceServant::removeConfigurationItems(
+    const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
 {
     class GroupVisitor : public RtpConfigurationGroupVisitor
     {
     public:
-        GroupVisitor(boost::shared_ptr<ConfigurationServiceImplPriv> implPriv) : mImplPriv(implPriv) { };
-        
-        void removeItems(RtpConfigurationItemVisitor* visitor, ConfigurationItemDict& itemsToRemove,
+        GroupVisitor(const ConfigurationServiceServantPtr& impl) : 
+            mImpl(impl)
+        {
+        }
+
+        void removeItems(const RtpConfigurationItemVisitorPtr& visitor, ConfigurationItemDict& itemsToRemove,
             ConfigurationItemDict& localItems)
         {
             for (ConfigurationItemDict::const_iterator item = itemsToRemove.begin();
@@ -257,21 +510,127 @@ void ConfigurationServiceImpl::removeConfigurationItems(const AsteriskSCF::Syste
  
         void visitRtpGeneralGroup(const ::AsteriskSCF::Media::RTP::V1::RtpGeneralGroupPtr& group)
         {
-            if (!mImplPriv->mGeneralGroup)
+            RtpGeneralGroupPtr g = mImpl->getGeneralGroup();
+            if (g)
             {
-                return;
+                removeItems(0, group->configurationItems, g->configurationItems);
             }
+        }
+
+        void visitRTPICEConfigurationGroup(const RTPICEConfigurationGroupPtr& group)
+        {
+            //
+            // The Visitor in this case interprets the provided information
+            // to decide what it needs to do. This type of thing might be better moved
+            // into a separate helper class (along with the set operations), but 
+            // we'll leave it here for now to avoid inconsistencies with the
+            // rest of the configuration implementation.
+            //
+            class Visitor : public RtpConfigurationItemVisitor
+            {
+            public:
+                Visitor(const ConfigurationServiceServantPtr& impl) :
+                    mImpl(impl),
+                    mRemoveSTUNServer(false),
+                    mRemoveTURNServer(false),
+                    mDisable(false),
+                    mResetICEConfig(false)
+                {
+                }
+                
+                ~Visitor()
+                {
+                    if (mDisable)
+                    {
+                    }
+
+                    NATConfigPtr natCfg = mImpl->natConfig();
+
+                    if (natCfg)
+                    {
+                        if (!mRemoveSTUNServer)
+                        {
+                            stunServer = natCfg->stunServer();
+                        }
+                        if (!mRemoveTURNServer)
+                        {
+                            turnServer = natCfg->turnServer();
+                        }
+                        NATConfigPtr newConfig;
+                        if (mDisable)
+                        {
+                            newConfig = NATConfig::create(stunServer, false, turnServer, false);
+                        }
+                        else
+                        {
+                            newConfig = NATConfig::create(stunServer, natCfg->isSTUNEnabled(), turnServer,
+                                natCfg->isTURNEnabled());
+                        }
+                        mImpl->replaceConfig(newConfig);
+                    }
+                    if (mResetICEConfig)
+                    {
+                        mImpl->replaceConfig(ICEConfigurationPtr());
+                    }
+                }
+                
+                void visitSTUNServerItem(const STUNServerItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mRemoveSTUNServer = true;
+                    }
+                }
+
+                void visitTURNServerItem(const TURNServerItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mRemoveTURNServer = true;
+                    }
+                }
+
+                void visitRTPICETransportFlagsItem(const RTPICETransportFlagsItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mDisable = true;
+                    }
+                }
+
+                void visitRTPICETransportLimitsItem(const RTPICETransportLimitsItemPtr& item)
+                {
+                    if (item)
+                    {
+                        mResetICEConfig = true;
+                    }
+                }
+                
+            private:
+                ConfigurationServiceServantPtr mImpl;
+                bool mRemoveSTUNServer;
+                bool mRemoveTURNServer;
+                bool mDisable;
+                bool mResetICEConfig;
+                AsteriskSCF::Helpers::AddressPtr stunServer;
+                AsteriskSCF::Helpers::AddressPtr turnServer;
+            };
+
+            RTPICEConfigurationGroupPtr g = mImpl->getICEConfigurationGroup();
             
-            removeItems(0, group->configurationItems, mImplPriv->mGeneralGroup->configurationItems);
-        };
+            if (g)
+            {
+                RtpConfigurationItemVisitorPtr v(new Visitor(mImpl));
+                removeItems(v, group->configurationItems, g->configurationItems);
+            }
+        }
  
     private:
-        boost::shared_ptr<ConfigurationServiceImplPriv> mImplPriv;
+        ConfigurationServiceServantPtr mImpl;
     };
     
-    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(mImplPriv);
-
-    boost::unique_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(this);
+    boost::unique_lock<boost::shared_mutex> lock(mLock);
     
     for (ConfigurationGroupSeq::const_iterator group = groups.begin(); group != groups.end(); ++group)
     {
@@ -279,30 +638,33 @@ void ConfigurationServiceImpl::removeConfigurationItems(const AsteriskSCF::Syste
     }
 }
 
-void ConfigurationServiceImpl::removeConfigurationGroups(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq& groups, const Ice::Current&)
+void ConfigurationServiceServant::removeConfigurationGroups(const ConfigurationGroupSeq& groups, const Ice::Current&)
 {
     class GroupVisitor : public RtpConfigurationGroupVisitor
     {
     public:
-        GroupVisitor(boost::shared_ptr<ConfigurationServiceImplPriv> implPriv) : mImplPriv(implPriv) { };
+        GroupVisitor(const ConfigurationServiceServantPtr& impl) : 
+            mImpl(impl)
+        {
+        }
  
     private:
         void visitRtpGeneralGroup(const ::AsteriskSCF::Media::RTP::V1::RtpGeneralGroupPtr&)
         {
-            if (!mImplPriv->mGeneralGroup)
-            {
-                return;
-            }
-            
-            mImplPriv->mGeneralGroup = 0;
-        };
-        
-        boost::shared_ptr<ConfigurationServiceImplPriv> mImplPriv;
+            mImpl->replaceGroup(RtpGeneralGroupPtr());
+        }
+
+        void visitICEConfigurationGroup(const RTPICEConfigurationGroupPtr&)
+        {
+            mImpl->replaceGroup(RTPICEConfigurationGroupPtr());
+        }
+
+        ConfigurationServiceServantPtr mImpl;
     };
     
-    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(mImplPriv);
+    RtpConfigurationGroupVisitorPtr v = new GroupVisitor(this);
 
-    boost::unique_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::unique_lock<boost::shared_mutex> lock(mLock);
     
     for (ConfigurationGroupSeq::const_iterator group = groups.begin(); group != groups.end(); ++group)
     {
@@ -313,19 +675,19 @@ void ConfigurationServiceImpl::removeConfigurationGroups(const AsteriskSCF::Syst
 /**
  * Internal function which returns configured start port.
  */
-int ConfigurationServiceImpl::getStartPort()
+int ConfigurationServiceServant::getStartPort()
 {
-    boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
     PortRangesItemPtr portsDefault = new PortRangesItem();
 
-    if (!mImplPriv->mGeneralGroup)
+    if (!mGeneralGroup)
     {
         return portsDefault->startPort;
     }
 
-    ConfigurationItemDict::iterator item = mImplPriv->mGeneralGroup->configurationItems.find(PortRangesItemName);
+    ConfigurationItemDict::iterator item = mGeneralGroup->configurationItems.find(PortRangesItemName);
 
-    if (item == mImplPriv->mGeneralGroup->configurationItems.end())
+    if (item == mGeneralGroup->configurationItems.end())
     {
         return portsDefault->startPort;
     }
@@ -343,19 +705,19 @@ int ConfigurationServiceImpl::getStartPort()
 /**
  * Internal function which returns configured end port.
  */
-int ConfigurationServiceImpl::getEndPort()
+int ConfigurationServiceServant::getEndPort()
 {
-    boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
     PortRangesItemPtr portsDefault = new PortRangesItem();
 
-    if (!mImplPriv->mGeneralGroup)
+    if (!mGeneralGroup)
     {
         return portsDefault->endPort;
     }
 
-    ConfigurationItemDict::iterator item = mImplPriv->mGeneralGroup->configurationItems.find(PortRangesItemName);
+    ConfigurationItemDict::iterator item = mGeneralGroup->configurationItems.find(PortRangesItemName);
 
-    if (item == mImplPriv->mGeneralGroup->configurationItems.end())
+    if (item == mGeneralGroup->configurationItems.end())
     {
         return portsDefault->endPort;
     }
@@ -373,19 +735,19 @@ int ConfigurationServiceImpl::getEndPort()
 /**
  * Internal function which returns configured worker thread count.
  */
-int ConfigurationServiceImpl::getWorkerThreadCount()
+int ConfigurationServiceServant::getWorkerThreadCount()
 {
-    boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
     WorkerThreadCountItemPtr workerThreadCountDefault = new WorkerThreadCountItem();
 
-    if (!mImplPriv->mGeneralGroup)
+    if (!mGeneralGroup)
     {
         return workerThreadCountDefault->count;
     }
 
-    ConfigurationItemDict::iterator item = mImplPriv->mGeneralGroup->configurationItems.find(WorkerThreadCountItemName);
+    ConfigurationItemDict::iterator item = mGeneralGroup->configurationItems.find(WorkerThreadCountItemName);
 
-    if (item == mImplPriv->mGeneralGroup->configurationItems.end())
+    if (item == mGeneralGroup->configurationItems.end())
     {
         return workerThreadCountDefault->count;
     }
@@ -403,18 +765,18 @@ int ConfigurationServiceImpl::getWorkerThreadCount()
 /**
  * Internal function which returns the IPv4 address to bind to.
  */
-std::string ConfigurationServiceImpl::getBindIPv4Address()
+std::string ConfigurationServiceServant::getBindIPv4Address()
 {
-    boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
 
-    if (!mImplPriv->mGeneralGroup)
+    if (!mGeneralGroup)
     {
         return "";
     }
 
-    ConfigurationItemDict::iterator item = mImplPriv->mGeneralGroup->configurationItems.find(BindingIPv4AddressItemName);
+    ConfigurationItemDict::iterator item = mGeneralGroup->configurationItems.find(BindingIPv4AddressItemName);
 
-    if (item == mImplPriv->mGeneralGroup->configurationItems.end())
+    if (item == mGeneralGroup->configurationItems.end())
     {
         return "";
     }
@@ -432,18 +794,18 @@ std::string ConfigurationServiceImpl::getBindIPv4Address()
 /**
  * Internal function which returns the IPv6 address to bind to.
  */
-std::string ConfigurationServiceImpl::getBindIPv6Address()
+std::string ConfigurationServiceServant::getBindIPv6Address()
 {
-    boost::shared_lock<boost::shared_mutex> lock(mImplPriv->mLock);
+    boost::shared_lock<boost::shared_mutex> lock(mLock);
 
-    if (!mImplPriv->mGeneralGroup)
+    if (!mGeneralGroup)
     {
         return "";
     }
 
-    ConfigurationItemDict::iterator item = mImplPriv->mGeneralGroup->configurationItems.find(BindingIPv6AddressItemName);
+    ConfigurationItemDict::iterator item = mGeneralGroup->configurationItems.find(BindingIPv6AddressItemName);
 
-    if (item == mImplPriv->mGeneralGroup->configurationItems.end())
+    if (item == mGeneralGroup->configurationItems.end())
     {
         return "";
     }
@@ -457,3 +819,14 @@ std::string ConfigurationServiceImpl::getBindIPv6Address()
 
     return binding->address;
 }
+
+ConfigurationServicePrx ConfigurationServiceServant::activate(const Ice::ObjectAdapterPtr& adapter, const string& id)
+{
+    return ConfigurationServicePrx::uncheckedCast(adapter->add(this,
+                    adapter->getCommunicator()->stringToIdentity(id)));
+}
+
+ConfigurationServiceImplPtr ConfigurationServiceImpl::create()
+{
+    return new ConfigurationServiceServant;
+}
diff --git a/src/RTPConfiguration.h b/src/RTPConfiguration.h
index a4329b0..4ae017c 100644
--- a/src/RTPConfiguration.h
+++ b/src/RTPConfiguration.h
@@ -18,43 +18,26 @@
 
 #include <Ice/Ice.h>
 #include <AsteriskSCF/System/Component/ConfigurationIf.h>
+
 #include <boost/shared_ptr.hpp>
+//
+// TODO: class names are a little messed because the filenames don't map to the class names properly.
+//
 #include "Configuration.h"
 
-/*
- * Private implementation class for ConfigurationServiceImpl.
- */
-class ConfigurationServiceImplPriv;
-
-/**
- * Implementation of the configuration service.
- */
 class ConfigurationServiceImpl : virtual public AsteriskSCF::System::Configuration::V1::ConfigurationService,
-    virtual public AsteriskSCF::PJMediaRTP::RTPConfiguration
+                                 virtual public AsteriskSCF::PJMediaRTP::RTPConfiguration
 {
 public:
-    ConfigurationServiceImpl();
-
-    AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq getConfiguration(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
-    AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq getConfigurationAll(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
-    AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq getConfigurationGroups(const Ice::Current&);
-    void setConfiguration(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
-    void removeConfigurationItems(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
-    void removeConfigurationGroups(const AsteriskSCF::System::Configuration::V1::ConfigurationGroupSeq&, const Ice::Current&);
+    virtual AsteriskSCF::System::Configuration::V1::ConfigurationServicePrx
+    activate(const Ice::ObjectAdapterPtr& objectAdapter, const std::string& id) = 0;
 
-    int getStartPort();
-    int getEndPort();
-    int getWorkerThreadCount();
-
-    std::string getBindIPv4Address();
-    std::string getBindIPv6Address();
-private:
-    /**
-     * Private implementation details.
-     */
-    boost::shared_ptr<ConfigurationServiceImplPriv> mImplPriv;
+    static IceUtil::Handle<ConfigurationServiceImpl> create();
+protected:
+    ConfigurationServiceImpl() {}
 };
 
+
 /**
  * A typedef which creates a smart pointer type for ConfigurationServiceImpl.
  */
diff --git a/src/RTPSession.cpp b/src/RTPSession.cpp
index 7a404fa..af1cb58 100644
--- a/src/RTPSession.cpp
+++ b/src/RTPSession.cpp
@@ -106,13 +106,15 @@ public:
     RTPSessionPrx activate(const Ice::Identity& id, const Ice::Identity& sourceId, const Ice::Identity& sinkId);
 
     void destroy();
-    
+
 private:
 
+    boost::shared_mutex mLock;
+
... 1562 lines suppressed ...


-- 
asterisk-scf/integration/media_rtp_pjmedia.git



More information about the asterisk-scf-commits mailing list