[asterisk-scf-commits] asterisk-scf/integration/sip.git branch "t38udptl" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Wed Sep 28 08:42:52 CDT 2011


branch "t38udptl" has been updated
       via  c90ef5f7c161fcbd7adaf72f4614aea779b815ef (commit)
       via  9f66448d4439bc3c6a90428fa878f14d2b0332ce (commit)
       via  90925e5939f603e874103fd7731f5957febf7b90 (commit)
       via  8e0f48d19b059e7d26fcbd27ace7a0f34e759ef8 (commit)
       via  ee3a950ea3930a81c156217bf614f5b0512fc0aa (commit)
       via  c18c1c9ca971b3b08c0224f059c45052e71f636a (commit)
       via  ec01c62e89fc764c104d4552891d366db52ad9b9 (commit)
       via  1c329a070da3354941507edd495c84d1cd0535ca (commit)
       via  8e37073a5318103b06dec8e241088244968a77fb (commit)
       via  712a66be46d2e2944440e097f88568182b405f4d (commit)
       via  57aae578b562047e1e8fa949a2ca597d73f36645 (commit)
      from  72bdaebe9ea208563ef48bcbbd98dd0e1b7a6d5f (commit)

Summary of changes:
 config/Sip.config                                  |   31 +
 config/SipConfigurator.py                          |   43 +-
 config/test_sip.conf                               |    4 +-
 .../SipSessionManager/SipConfigurationIf.ice       |   35 +
 src/Component.cpp                                  |   12 +-
 src/PJSipLoggingModule.cpp                         |    2 +-
 src/PJSipManager.cpp                               |    7 +-
 src/PJSipManager.h                                 |    2 +-
 src/PJSipModule.cpp                                |    2 +-
 src/PJSipRegistrarModule.cpp                       |    2 +-
 src/PJSipSessionModule.cpp                         |    6 +-
 src/PJSipSessionModuleConstruction.cpp             |    2 +-
 src/STUNModule.cpp                                 |    7 +-
 src/STUNModule.h                                   |    2 +-
 src/STUNTransport.cpp                              |    2 +-
 src/SipConfiguration.cpp                           |  250 ++++++-
 src/SipEndpoint.cpp                                |  267 +++++--
 src/SipEndpoint.h                                  |   11 +
 src/SipEndpointFactory.cpp                         |    2 +-
 src/SipRegistrarListener.cpp                       |    2 +-
 src/SipSession.cpp                                 |  781 +++++++++++++++++---
 src/SipSession.h                                   |  104 ++-
 src/SipSessionManagerApp.cpp                       |   19 +-
 src/SipSessionManagerEndpointLocator.cpp           |    2 +-
 src/SipSessionManagerEventPublisher.cpp            |    2 +-
 src/SipStateReplicatorApp.cpp                      |   21 +-
 src/SipTransfer.cpp                                |    6 +-
 27 files changed, 1358 insertions(+), 268 deletions(-)


- Log -----------------------------------------------------------------
commit c90ef5f7c161fcbd7adaf72f4614aea779b815ef
Author: Joshua Colp <jcolp at digium.com>
Date:   Wed Sep 28 10:41:41 2011 -0300

    Add configuration for UDPTL ICE/TURN support.

diff --git a/config/Sip.config b/config/Sip.config
index 9502e1a..1272985 100644
--- a/config/Sip.config
+++ b/config/Sip.config
@@ -91,6 +91,18 @@ securetransport=none
 rtpoveripv6=no
 # Whether to use IPv6 for UDPTL transport or not
 udptloveripv6=no
+
+#
+# Configure endpoint to create ICE enabled UDPTL streams. Disabled by default.
+#
+# udptloverice=false
+
+#
+# Configure endpoint to enable TURN support for ICE enabled UDPTL streams. ICE must be enabled
+# for this to have an effect. Disable by default.
+#
+# udptlwithturn=false
+
 # Allowable media formats for the endpoint. Each format is separated using , and follows the format
 # <name>/<sample rate>@<frame size>;<format specific parameters>
 #
diff --git a/config/SipConfigurator.py b/config/SipConfigurator.py
index 7b32309..0a29a51 100755
--- a/config/SipConfigurator.py
+++ b/config/SipConfigurator.py
@@ -205,6 +205,8 @@ class SipSectionVisitors(Configurator.SectionVisitors):
 
         item = AsteriskSCF.Configuration.SipSessionManager.V1.SipUDPTLMediaServiceItem()
         mapper.map('udptloveripv6', item, 'requireIPv6', 'udptlmediaservice', config.getboolean, None)
+        mapper.map('udptloverice', item, 'enableICE', 'udptlmediaservice', config.getboolean, None)
+        mapper.map('udptlwithturn', item, 'enableTURN', 'udptlmediaservice', config.getboolean, None)
 
         item = AsteriskSCF.Configuration.SipSessionManager.V1.SipCryptoCertificateItem()
         mapper.map('certificateauthorityfile', item, 'certificateAuthority', 'cryptocert', config.get, None)
diff --git a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
index bd677b1..d3ebea0 100644
--- a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
+++ b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
@@ -336,6 +336,16 @@ class SipUDPTLMediaServiceItem extends SipConfigurationItem
      * Whether to choose an IPv6 UDPTL media service or not
      */
     bool requireIPv6 = false;
+
+    /**
+     * Boolean for whether ICE is enabled
+     */
+    bool enableICE = false;
+
+    /**
+     * Boolean for whether TURN is enabled
+     */
+    bool enableTURN = false;
 };
 
 /**
diff --git a/src/SipConfiguration.cpp b/src/SipConfiguration.cpp
index d2378cc..ce2672d 100644
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@ -458,6 +458,8 @@ public:
     void updateUDPTLMediaService(const SipUDPTLMediaServiceItemPtr& service)
     {
         mEndpoint->setUDPTLOverIPv6(service->requireIPv6);
+        mEndpoint->enableUDPTLICE(service->enableICE);
+        mEndpoint->enableUDPTLTURN(service->enableTURN);
     }
 
     void updateTransport(const SipEndpointTransportItemPtr& transport)
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index 9757e98..be46892 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -342,6 +342,16 @@ void SipEndpoint::setUDPTLOverIPv6(bool enabled)
     mImplPriv->mConfig.sessionConfig.udptlOverIPv6 = enabled;
 }
 
+void SipEndpoint::enableUDPTLICE(bool enabled)
+{
+    mImplPriv->mConfig.sessionConfig.udptlOverICE = enabled;
+}
+
+void SipEndpoint::enableUDPTLTURN(bool enabled)
+{
+    mImplPriv->mConfig.sessionConfig.udptlWithTURN = enabled;
+}
+
 void SipEndpoint::setMediaNATOptions(bool useICE, bool useTURN)
 {
     mImplPriv->mConfig.sessionConfig.rtpOverICE = useICE;
diff --git a/src/SipEndpoint.h b/src/SipEndpoint.h
index 4dc2db0..7b9f4f6 100644
--- a/src/SipEndpoint.h
+++ b/src/SipEndpoint.h
@@ -161,6 +161,10 @@ public:
     bool rtpOverIPv6;
     // Whether we are using IPv6 for UDPTL transport or not.
     bool udptlOverIPv6;
+    // Whether ICE is enabled for UDPTL.
+    bool udptlOverICE;
+    // Whether TURN is enabled for UDPTL.
+    bool udptlWithTURN;
     // The method by which we will transmit
     // DTMF to an endpoint
     AsteriskSCF::Configuration::SipSessionManager::V1::SipDTMFOption dtmf;
@@ -337,6 +341,8 @@ public:
     void setSecureTransport(enum Direction);
     void setRTPOverIPv6(bool);
     void setUDPTLOverIPv6(bool);
+    void enableUDPTLICE(bool);
+    void enableUDPTLTURN(bool);
     void addFormat(const std::string& name, int sampleRate, int frameSize, const Ice::StringSeq& formatSpecific);
 
     /**

commit 9f66448d4439bc3c6a90428fa878f14d2b0332ce
Merge: 72bdaeb 90925e5
Author: Joshua Colp <jcolp at digium.com>
Date:   Tue Sep 27 14:24:35 2011 -0300

    Merge branch 'master' into t38udptl
    
    Conflicts:
    	src/SipEndpoint.cpp
    	src/SipSession.cpp
    	src/SipSession.h

diff --cc config/Sip.config
index fdbd23e,6843989..9502e1a
--- a/config/Sip.config
+++ b/config/Sip.config
@@@ -79,18 -89,15 +89,27 @@@ direction=bot
  securetransport=none
  # Whether to use IPv6 for media transport or not
  rtpoveripv6=no
 +# Whether to use IPv6 for UDPTL transport or not
 +udptloveripv6=no
  # Allowable media formats for the endpoint. Each format is separated using , and follows the format
  # <name>/<sample rate>@<frame size>;<format specific parameters>
 +#
 +# If you would like to enable T.38 you can specify t38udptl here. This will enable T.38 with no overridden
 +# datagram and no error correction scheme. To override the datagram add maxdatagram with a value in the format
 +# specific parameters section. To enable error correction add errorcorrect with either fec, redundancy, or none
 +# as the value.
 +#
 +# Example of T.38 with an overridden max datagram of 400: t38udptl;maxdatagram=400
 +# Example of T.38 with fec error correction: t38udptl;errorcorrect=fec
 +# Example of T.38 with overridden max datagram and fec error correction: t38udptl;maxdatagram=400&errorcorrect=fec
 +#
  formats=ulaw/8000,alaw/8000
+ #
+ # Simple fields for a single identity record
+ name='robert foo bar'
+ number=123
+ #
+ # Or, a reference to a list of individual identity items
+ ids=bob-bar-office,bob-bar-cell
+ 
+ 
diff --cc src/SipEndpoint.cpp
index 63a5b16,2c5bf9d..9757e98
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@@ -462,34 -481,35 +486,36 @@@ AsteriskSCF::SipSessionManager::SipSess
   * Note: Default session cookies and listeners are part of the replicated state, so none are added
   * here. 
   */
- AsteriskSCF::SipSessionManager::SipSessionPtr SipEndpoint::createSession(const std::string& destination,
-                                                                          const Ice::Identity& sessionid, const Ice::Identity& controllerid,
-                                                                          const Ice::Identity& mediaid,
-                                                                          const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
-                                                                          const AsteriskSCF::Replication::SipSessionManager::V1::UDPTLMediaSessionSeq& udptlMediaSessions,
-                                                                          const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
-                                                                          const AsteriskSCF::Media::V1::StreamSinkSeq& sinks)
- {
-     SipSessionPtr session = new SipSession(
-             mImplPriv->mAdapter,
-             this,
-             destination,
-             sessionid,
-             controllerid,
-             mediaid,
-             mediasessions,
-             udptlMediaSessions,
-             sources,
-             sinks,
-             mImplPriv->mManager,
-             mImplPriv->mServiceLocator,
-             mImplPriv->mReplicationContext,
-             0,
-             false,
-             mImplPriv->mConfig,
-             NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE,
-                 mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
-                 mImplPriv->mConfig.transportConfig.enableNAT));
 -SipSessionPtr SipEndpoint::createSession
 -               (const std::string& destination,
 -                const Ice::Identity& sessionid, 
 -		const Ice::Identity& controllerid,
 -                const Ice::Identity& mediaid,
 -                const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
 -                const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
 -                const AsteriskSCF::Media::V1::StreamSinkSeq& sinks)
++SipSessionPtr SipEndpoint::createSession(const std::string& destination,
++                                         const Ice::Identity& sessionid, 
++                                         const Ice::Identity& controllerid,
++                                         const Ice::Identity& mediaid,
++                                         const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
++                                         const AsteriskSCF::Replication::SipSessionManager::V1::UDPTLMediaSessionSeq& udptlMediaSessions,
++                                         const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
++                                         const AsteriskSCF::Media::V1::StreamSinkSeq& sinks)
+ {
+     SipSessionPtr session = SipSession::create
 -	    (mImplPriv->mAdapter, 
 -	     this, 
 -	     destination, 
 -	     sessionid, 
 -             controllerid, 
 -	     mediaid, 
 -	     mediasessions, 
 -	     sources, 
 -	     sinks, 
 -	     mImplPriv->mManager, 
 -             mImplPriv->mServiceLocator, 
 -	     mImplPriv->mReplicationContext, 
 -	     0,
 -	     false, 
 -	     mImplPriv->mConfig,
 -             NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE, 
 -                                mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
 -                                mImplPriv->mConfig.transportConfig.enableNAT));
++        (mImplPriv->mAdapter, 
++         this, 
++         destination, 
++         sessionid, 
++         controllerid, 
++         mediaid, 
++         mediasessions, 
++         udptlMediaSessions,
++         sources, 
++         sinks, 
++         mImplPriv->mManager, 
++         mImplPriv->mServiceLocator, 
++         mImplPriv->mReplicationContext, 
++         0,
++         false, 
++         mImplPriv->mConfig,
++         NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE, 
++                            mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
++                            mImplPriv->mConfig.transportConfig.enableNAT));
+ 
      mImplPriv->mSessions.push_back(session);
      return session;
  }
diff --cc src/SipSession.cpp
index a9c45b0,98d5716..8041e21
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@@ -35,10 -38,8 +38,11 @@@
  #include <AsteriskSCF/Media/RTP/MediaRTPIf.h>
  #include <AsteriskSCF/Media/SDP/MediaSDPIf.h>
  #include <AsteriskSCF/Media/RTP/MediaRTCPIf.h>
 +#include <AsteriskSCF/Media/UDPTL/MediaUDPTLIf.h>
 +#include <AsteriskSCF/Media/Formats/T38UdptlFormat.h>
 +#include <AsteriskSCF/Media/NetworkIf.h>
  #include <AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.h>
+ #include <AsteriskSCF/Collections/HandleSet.h>
  #include "NATOptions.h"
  
  using namespace AsteriskSCF::System::Logging;
@@@ -48,9 -50,7 +53,10 @@@ using namespace AsteriskSCF::Media::RTP
  using namespace AsteriskSCF::Media::V1;
  using namespace AsteriskSCF::Media;
  using namespace AsteriskSCF::Media::SDP::V1;
 +using namespace AsteriskSCF::Media::UDPTL::V1;
 +using namespace AsteriskSCF::Media::Formats::T38Udptl::V1;
 +using namespace AsteriskSCF::Network::V1;
+ using namespace AsteriskSCF::System::V1;
  using namespace std;
  
  namespace
@@@ -792,6 -1137,96 +1148,98 @@@ void SipSession::setTelephonyEventSourc
  }
  
  /**
+  * Standard factory method used by an active component to create SipSession objects.
+  */
+ SipSessionPtr SipSession::create(const Ice::ObjectAdapterPtr& adapter, 
+         const SipEndpointPtr& endpoint,
+         const std::string& destination, 
+         const vector<SessionListenerPrx>& listeners,
+         const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies,
+         const PJSipManagerPtr& manager, 
+         const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+         const SipReplicationContextPtr& replicationContext, 
+         const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& oneShotHook,
+         bool doIpV6, 
+         bool isUAC, 
+         const SipEndpointConfig &config,
+         const NATEndpointOptions& natOptions)
+ {
+     SipSessionPtr newSession = new SipSession(adapter, 
+        endpoint,
+        destination, 
+        listeners,
+        cookies,
+        manager, 
+        serviceLocator,
+        replicationContext, 
+        doIpV6, 
+        isUAC, 
+        config,
+        natOptions);
+ 
+     AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq hooks = 
+         newSession->mImplPriv->mManager->getSessionModule()->getSessionCreationHooks();
+ 
+     if (oneShotHook)
+     {
+         hooks.push_back(oneShotHook);
+     }
+     newSession->activateIceObjects(hooks);
+ 
+     return newSession;
+ }
+ 
+ /**
+  * Factory used by a standby component to create replicas. 
+  */
+ SipSessionPtr SipSession::create(const Ice::ObjectAdapterPtr& adapter, 
 -                       const SipEndpointPtr& endpoint,
 -                       const std::string& destination, 
 -                       const Ice::Identity& sessionid,
 -                       const Ice::Identity& controllerid,
 -                       const Ice::Identity& mediaid, 
 -                       const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
 -                       const AsteriskSCF::Media::V1::StreamSourceSeq& sources, 
 -                       const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
 -                       const PJSipManagerPtr& manager, 
 -                       const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
 -                       const SipReplicationContextPtr& replicationContext, 
 -                       const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& oneShotHook,
 -                       bool isUAC, 
 -                       const SipEndpointConfig &config,
 -                       const NATEndpointOptions& natOptions)
++                                 const SipEndpointPtr& endpoint,
++                                 const std::string& destination, 
++                                 const Ice::Identity& sessionid,
++                                 const Ice::Identity& controllerid,
++                                 const Ice::Identity& mediaid, 
++                                 const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
++                                 const AsteriskSCF::Replication::SipSessionManager::V1::UDPTLMediaSessionSeq& udptlMediaSessions,
++                                 const AsteriskSCF::Media::V1::StreamSourceSeq& sources, 
++                                 const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
++                                 const PJSipManagerPtr& manager, 
++                                 const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
++                                 const SipReplicationContextPtr& replicationContext, 
++                                 const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& oneShotHook,
++                                 bool isUAC, 
++                                 const SipEndpointConfig &config,
++                                 const NATEndpointOptions& natOptions)
+ {
+     SipSessionPtr newSession = new SipSession(adapter, 
 -                       endpoint,
 -                       destination, 
 -                       sessionid,
 -                       controllerid,
 -                       mediaid, 
 -                       mediasessions,
 -                       sources, 
 -                       sinks,
 -                       manager, 
 -                       serviceLocator,
 -                       replicationContext, 
 -                       isUAC, 
 -                       config,
 -                       natOptions);
++                                              endpoint,
++                                              destination, 
++                                              sessionid,
++                                              controllerid,
++                                              mediaid, 
++                                              mediasessions,
++                                              udptlMediaSessions,
++                                              sources, 
++                                              sinks,
++                                              manager, 
++                                              serviceLocator,
++                                              replicationContext, 
++                                              isUAC, 
++                                              config,
++                                              natOptions);
+ 
+     AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq hooks =
+         newSession->mImplPriv->mManager->getSessionModule()->getSessionCreationHooks();
+ 
+     if (oneShotHook)
+     {
+         hooks.push_back(oneShotHook);
+     }
+     newSession->activateIceObjects(hooks);
+ 
+     return newSession;
+ }
+ 
+ /**
   * Standard constructor for use by an active component.
   */
  SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter, 
@@@ -2068,195 -2610,111 +2638,210 @@@ pjmedia_sdp_session *SipSession::create
          // Update the stream with the actual formats
          stream->second->formats = formats;
  
 -        RTPServiceLocatorParamsPtr params = new RTPServiceLocatorParams();
 -        params->category = "rtp";
 -        params->formats = stream->second->formats;
 -        params->ipv6 = mImplPriv->mEndpoint->getConfig().sessionConfig.rtpOverIPv6;
 +        // Determine what media this stream is carrying
 +        AudioFormatPtr audio;
 +        VideoFormatPtr video;
 +	T38UdptlFormatPtr t38;
  
 -        // Try to find a factory for RTP sessions matching what we need
 -        RTPMediaServicePrx factory = RTPMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
 -
 -        // If none exist we can't provide the stream
 -        if (factory == 0)
 +        // If this stream contains an audio or video format the stream is transported using RTP
 +        if ((audio = AudioFormatPtr::dynamicCast(formats.front())) || (video = VideoFormatPtr::dynamicCast(formats.front())))
          {
 -            continue;
 -        }
 +            RTPServiceLocatorParamsPtr params = new RTPServiceLocatorParams();
 +            params->category = "rtp";
 +            params->formats = stream->second->formats;
 +            params->ipv6 = mImplPriv->mEndpoint->getConfig().sessionConfig.rtpOverIPv6;
 +
 +            // Try to find a factory for RTP sessions matching what we need
 +            RTPMediaServicePrx factory = RTPMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
  
-             // If none exist we can't provide the stream
 -        // Allocate a new RTP session to carry the media formats we have in common
 +            if (factory == 0)
 +            {
 +                continue;
 +            }
 +
 +            // Allocate a new RTP session to carry the media formats we have in common
-             RTPSessionPrx session = factory->allocate(params);
+         
 -        RTPOptionsPtr options(new RTPOptions());
 -        RTPAllocationOutputsPtr outputs;
++            RTPOptionsPtr options(new RTPOptions());
++            RTPAllocationOutputsPtr outputs;
+ 
 -        SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
 -        if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SipSessionManager::V1::RFC4733)
 -        {
 -            options->handleTelephonyEvents = true;
 -        }
++            SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
++            if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SipSessionManager::V1::RFC4733)
++            {
++                options->handleTelephonyEvents = true;
++            }
+ 
 -        RTPSessionPrx session = factory->allocate(params, options, outputs);
++            RTPSessionPrx session = factory->allocate(params, options, outputs);
  
 -        // Double check to make sure they actually gave us a sesson back... they could have had a problem
 -        if (session == 0)
 -        {
 -            continue;
 -        }
 +            // Double check to make sure they actually gave us a sesson back... they could have had a problem
 +            if (session == 0)
 +            {
 +                continue;
 +            }
  
 -        if (outputs)
 -        {
 -            mImplPriv->mExternalEventSources = outputs->eventSources;
 -            mImplPriv->mExternalEventSinks = outputs->eventSinks;
 -        }
++            if (outputs)
++            {
++                mImplPriv->mExternalEventSources = outputs->eventSources;
++                mImplPriv->mExternalEventSinks = outputs->eventSinks;
++            }
+ 
 -        // RTP sessions should only provide a single sink, so grab it and update the connection details with that
 -        // of the remote party
 -        StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
 -        mImplPriv->mSinks.push_back(sink);
 -    stream->second->sinks.push_back(sink);
 +            // RTP sessions should only provide a single sink, so grab it and update the connection details with that
 +            // of the remote party
 +            StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
 +            mImplPriv->mSinks.push_back(sink);
 +            stream->second->sinks.push_back(sink);
  
 -        // Ditto goes for source
 -        StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(session->getSources().front());
 -        mImplPriv->mSources.push_back(source);
 -    stream->second->sources.push_back(source);
 +            // Ditto goes for source
 +            StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(session->getSources().front());
 +            mImplPriv->mSources.push_back(source);
 +            stream->second->sources.push_back(source);
  
 -        // Update the SIP session with some RTP session details
 -        mImplPriv->mRTPSessions.push_back(session);
 +            // Update the SIP session with some RTP session details
 +            mImplPriv->mRTPSessions.push_back(session);
 +         
 +	    // Add the stream to the SDP
 +	    pjmedia_sdp_media *media = allocate_from_pool<pjmedia_sdp_media>(mImplPriv->mDialog->pool);
  
 -        // Add the stream to the SDP
 -        pjmedia_sdp_media *media = allocate_from_pool<pjmedia_sdp_media>(mImplPriv->mDialog->pool);
 +	    // The media count is purposely not incremented here since it is done when the stream is added to the sequence
 +	    // of streams
 +	    mImplPriv->mSDP->media[mImplPriv->mSDP->media_count] = media;
 +	    pj_strdup2(mImplPriv->mDialog->pool, &media->desc.media, mImplPriv->mEndpoint->getDescriptor(
 +                           stream->second->formats.front())->type.c_str());
  
 -        // The media count is purposely not incremented here since it is done when the stream is added to the sequence
 -        // of streams
 -        mImplPriv->mSDP->media[mImplPriv->mSDP->media_count] = media;
 -        pj_strdup2(mImplPriv->mDialog->pool, &media->desc.media, mImplPriv->mEndpoint->getDescriptor(
 -                       stream->second->formats.front())->type.c_str());
 +	    pj_strdup2(mImplPriv->mDialog->pool, &media->desc.transport, "RTP/AVP");
  
 -        // TODO: This should not be hardcoded
 -        pj_strdup2(mImplPriv->mDialog->pool, &media->desc.transport, "RTP/AVP");
 +            // Add connection level details
 +            media->conn = allocate_from_pool<pjmedia_sdp_conn>(mImplPriv->mDialog->pool);
 +            pj_strdup2(mImplPriv->mDialog->pool, &media->conn->net_type, "IN");
  
 -        // Add connection level details
 -        media->conn = allocate_from_pool<pjmedia_sdp_conn>(mImplPriv->mDialog->pool);
 -        pj_strdup2(mImplPriv->mDialog->pool, &media->conn->net_type, "IN");
 +            if (params->ipv6 == true)
 +            {
 +                pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr_type, "IP6");
 +            }
 +            else
 +            {
 +                pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr_type, "IP4");
 +            }
  
 -        if (params->ipv6 == true)
 -        {
 -            pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr_type, "IP6");
 +            pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, source->getLocalAddress().c_str());
 +
 +            // If session level connection information has not yet been set then set it to us
 +            if (!mImplPriv->mSDP->conn)
 +            {
 +                mImplPriv->mSDP->conn = media->conn;
 +            }
 +
 +            media->desc.port = (pj_uint16_t) source->getLocalPort();
 +            media->desc.port_count = 1;
 +
 +            RTCP::V1::RTCPSessionPrx rtcpSession;
 +            if ((rtcpSession = RTCP::V1::RTCPSessionPrx::checkedCast(session, RTCP::V1::SessionFacet)))
 +            {
 +                pjmedia_sdp_attr *attr = allocate_from_pool<pjmedia_sdp_attr>(mImplPriv->mDialog->pool);
 +                pj_strdup2(mImplPriv->mDialog->pool, &attr->name, "rtcp");
 +                pj_strdup2(mImplPriv->mDialog->pool, &attr->value, boost::lexical_cast<std::string>(rtcpSession->getLocalPort()).c_str());
 +                media->attr[media->attr_count++] = attr;
 +            }
 +
 +            PayloadMap payloads;
 +
 +            // Add all of the formats to the SDP
 +            addFormatstoSDP(stream->second->formats, media, payloads);
 +
 +            // Push the payload mapping to the RTP session so it'll correctly map things
 +            session->associatePayloads(payloads);
          }
 -        else
 +        else if ((t38 = T38UdptlFormatPtr::dynamicCast(formats.front())))
          {
 -            pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr_type, "IP4");
 -        }
 +            UDPTLServiceLocatorParamsPtr params = new UDPTLServiceLocatorParams();
 +            params->category = "udptl";
 +            params->ipv6 = mImplPriv->mEndpoint->getConfig().sessionConfig.udptlOverIPv6;
  
 -        pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, source->getLocalAddress().c_str());
 +            UDPTLMediaServicePrx factory = UDPTLMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
 +            if (factory == 0)
 +            {
 +                continue;
 +            }
  
 -        // If session level connection information has not yet been set then set it to us
 -        if (!mImplPriv->mSDP->conn)
 -        {
 -            mImplPriv->mSDP->conn = media->conn;
 -        }
 +            UDPTLSessionPrx session = factory->allocate(params);
 +            if (session == 0)
 +            {
 +                continue;
 +            }
  
 -        media->desc.port = (pj_uint16_t) source->getLocalPort();
 -        media->desc.port_count = 1;
 +            StreamSinkUDPTLPrx sink = StreamSinkUDPTLPrx::uncheckedCast(session->getSinks().front());
 +            mImplPriv->mSinks.push_back(sink);
 +            stream->second->sinks.push_back(sink);
  
 -        RTCP::V1::RTCPSessionPrx rtcpSession;
 -        if ((rtcpSession = RTCP::V1::RTCPSessionPrx::checkedCast(session, RTCP::V1::SessionFacet)))
 -        {
 -            pjmedia_sdp_attr *attr = allocate_from_pool<pjmedia_sdp_attr>(mImplPriv->mDialog->pool);
 -            pj_strdup2(mImplPriv->mDialog->pool, &attr->name, "rtcp");
 -            pj_strdup2(mImplPriv->mDialog->pool, &attr->value, boost::lexical_cast<std::string>(rtcpSession->getLocalPort()).c_str());
 -            media->attr[media->attr_count++] = attr;
 -        }
 +            StreamSourceUDPTLPrx source = StreamSourceUDPTLPrx::uncheckedCast(session->getSources().front());
 +            mImplPriv->mSources.push_back(source);
 +            stream->second->sources.push_back(source);
  
 -        PayloadMap payloads;
 +            mImplPriv->mUDPTLSessions.push_back(session);
  
 -        // Add all of the formats to the SDP
 -        addFormatstoSDP(stream->second->formats, media, payloads);
 +            // Add the stream to the SDP
 +            mImplPriv->mSDP->media_count = 0;
  
 -        // Push the payload mapping to the RTP session so it'll correctly map things
 -        session->associatePayloads(payloads);
 +            // Since we may be replacing an existing stream go ahead and remove it
 +            mImplPriv->mStreams.erase(boost::lexical_cast<std::string>(mImplPriv->mSDP->media_count));
 +
 +            pjmedia_sdp_media *media = allocate_from_pool<pjmedia_sdp_media>(mImplPriv->mDialog->pool);
 +            // The media count is purposely not incremented here since it is done when the stream is added to the sequence
 +            // of streams
 +            mImplPriv->mSDP->media[mImplPriv->mSDP->media_count] = media;
 +
 +            pj_strdup2(mImplPriv->mDialog->pool, &media->desc.media, mImplPriv->mEndpoint->getDescriptor(
 +                           stream->second->formats.front())->type.c_str());
 +
 +            pj_strdup2(mImplPriv->mDialog->pool, &media->desc.transport, "UDPTL");
 +
 +	    pj_strdup2(mImplPriv->mDialog->pool, &media->desc.fmt[media->desc.fmt_count++], "t38");
 +
 +            // Add connection level details
 +            media->conn = allocate_from_pool<pjmedia_sdp_conn>(mImplPriv->mDialog->pool);
 +            pj_strdup2(mImplPriv->mDialog->pool, &media->conn->net_type, "IN");
 +
 +            if (params->ipv6 == true)
 +            {
 +                pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr_type, "IP6");
 +            }
 +            else
 +            {
 +                pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr_type, "IP4");
 +            }
 +
 +            AddressInformation info = source->getLocalDetails();
 +
 +            pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, info.ipAddress.c_str());
 +
 +            // If session level connection information has not yet been set then set it to us
 +            if (!mImplPriv->mSDP->conn)
 +            {
 +                mImplPriv->mSDP->conn = media->conn;
 +            }
 +
 +            media->desc.port = (pj_uint16_t) info.port;
 +            media->desc.port_count = 1;
 +
 +            // Use the configured format to set the error correction
 +            T38UdptlFormatPtr t38Configuration = T38UdptlFormatPtr::dynamicCast(mImplPriv->mEndpoint->getFormat(t38));
 +
 +            t38->errorCorrection = t38Configuration->errorCorrection;
 +
 +            SDPDescriptorPtr ourDescriptor = mImplPriv->mEndpoint->getInterpretedDescriptor(t38);
 +            for (SDPFormatParameterSeq::const_iterator parameter = ourDescriptor->parameters.begin();
 +                 parameter != ourDescriptor->parameters.end();
 +                 ++parameter)
 +            {
 +                pjmedia_sdp_attr *attr = allocate_from_pool<pjmedia_sdp_attr>(mImplPriv->mDialog->pool);
 +                pj_strdup2(mImplPriv->mDialog->pool, &attr->name, (*parameter).c_str());
 +                media->attr[media->attr_count++] = attr;
 +            }
 +        }
 +        else
 +        {
 +            // The media format type is just unknown to us, so we can not create a stream for this
 +            continue;
 +        }
  
          // Make the caller aware of this new stream
          newStreams.insert(make_pair(boost::lexical_cast<std::string>(mImplPriv->mSDP->media_count), stream->second));
@@@ -2444,29 -2892,8 +3029,29 @@@ pjmedia_sdp_session *SipSession::create
              continue;
          }
  
- 	// Update the stream with the formats
- 	ourStream->formats = formats;
 -    // Update the stream with the formats
 -    ourStream->formats = formats;
++        // Update the stream with the formats
++        ourStream->formats = formats;
 +
 +        // Record the old state so we can relay the state change to the controller if needed
 +        StreamState oldState = ourStream->state;
 +
 +        // Determine the state of the stream and update it
 +        if (pjmedia_sdp_media_find_attr2(offer->media[stream], "sendonly", NULL))
 +        {
 +            ourStream->state = SendOnly;
 +        }
 +        else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "recvonly", NULL))
 +        {
 +            ourStream->state = ReceiveOnly;
 +        }
 +        else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "inactive", NULL))
 +        {
 +            ourStream->state = Inactive;
 +        }
 +        else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "sendrecv", NULL))
 +        {
 +            ourStream->state = SendAndReceive;
 +        }
  
          // Assume that no connection level details exist until proven otherwise
          std::string connection = destination;
@@@ -2476,290 -2903,164 +3061,306 @@@
                                       pj_strlen(&offer->media[stream]->conn->addr));
          }
  
 -        RTPSessionPrx session;
 +        AudioFormatPtr audio;
 +        VideoFormatPtr video;
 +        T38UdptlFormatPtr t38;
  
 -    // If no sink and no source is present then this stream has no RTP session yet so find one
 -    if (ourStream->sinks.empty() && ourStream->sources.empty())
 -    {
 -        RTPServiceLocatorParamsPtr params;
 -        if (mImplPriv->mNatOptions.enableICE)
 -        {
 -        AsteriskSCF::Media::RTP::V1::RTPOverICEServiceLocatorParamsPtr iceParams =
 -            new AsteriskSCF::Media::RTP::V1::RTPOverICEServiceLocatorParams;
 -        params = iceParams;
 -        iceParams->enableRTPOverICE = true;
 -        iceParams->enableTURN = mImplPriv->mNatOptions.enableTURN;
 -        }
 -        else
 +        if ((audio = AudioFormatPtr::dynamicCast(formats.front())) || (video = VideoFormatPtr::dynamicCast(formats.front())))
          {
 -        params = new AsteriskSCF::Media::RTP::V1::RTPServiceLocatorParams;
 -        }
 -
 -            params->category = "rtp";
 -            params->formats = formats;
 -
 -            // See what address family the connection address is in so we can request the right RTP service
 -            if (connection.find(":") != std::string::npos)
 +            // If this is a modified stream make sure the transport is RTP, if not clear things out
 +            if (!ourStream->sinks.empty())
              {
 -                params->ipv6 = true;
 +                StreamSinkRTPPrx rtpSink = StreamSinkRTPPrx::checkedCast(ourStream->sinks.front());
 +                if (!rtpSink)
 +                {
 +                    ourStream->sinks.clear();
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.insert(make_pair(boost::lexical_cast<std::string>(stream), ourStream));
 +                }
              }
 -            else
 +
 +            if (!ourStream->sources.empty())
              {
 -                params->ipv6 = false;
 +                StreamSourceRTPPrx rtpSource = StreamSourceRTPPrx::checkedCast(ourStream->sources.front());
 +                if (!rtpSource)
 +                {
 +                    ourStream->sources.clear();
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.insert(make_pair(boost::lexical_cast<std::string>(stream), ourStream));
 +                }
              }
  
 -            // Try to find a factory for RTP sessions matching what we need
 -            RTPMediaServicePrx factory = RTPMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
 +            RTPSessionPrx session;
  
 -            // If none exist we can't provide accept the stream
 -            if (factory == 0)
 +            // If no sink and no source is present then this stream has no RTP session yet so find one
 +            if (ourStream->sinks.empty() && ourStream->sources.empty())
              {
 -                // The only time this should ever occur is on the initial INVITE so removing the stream from everywhere
 -                // is perfectly acceptable since nothing has seen it
 -                mImplPriv->mStreams.erase(boost::lexical_cast<std::string>(stream));
 -                newStreams.erase(boost::lexical_cast<std::string>(stream));
 -                continue;
 +                RTPServiceLocatorParamsPtr params;
 +                if (mImplPriv->mNatOptions.enableICE)
 +                {
 +                    AsteriskSCF::Media::RTP::V1::RTPOverICEServiceLocatorParamsPtr iceParams =
 +                        new AsteriskSCF::Media::RTP::V1::RTPOverICEServiceLocatorParams;
 +                    params = iceParams;
 +                    iceParams->enableRTPOverICE = true;
 +                    iceParams->enableTURN = mImplPriv->mNatOptions.enableTURN;
 +                }
 +                else
 +                {
 +                    params = new AsteriskSCF::Media::RTP::V1::RTPServiceLocatorParams;
 +                }
 +
 +                params->category = "rtp";
 +                params->formats = formats;
 +
 +                // See what address family the connection address is in so we can request the right RTP service
 +                if (connection.find(":") != std::string::npos)
 +                {
 +                    params->ipv6 = true;
 +                }
 +                else
 +                {
 +                    params->ipv6 = false;
 +                }
 +
 +                // Try to find a factory for RTP sessions matching what we need
 +                RTPMediaServicePrx factory = RTPMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
 +
 +                // If none exist we can't provide accept the stream
 +                if (factory == 0)
 +                {
 +                    // The only time this should ever occur is on the initial INVITE so removing the stream from everywhere
 +                    // is perfectly acceptable since nothing has seen it
 +                    mImplPriv->mStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    continue;
 +                }
 +
 +                // Allocate a new RTP session to carry the media formats we have in common
-                 session = factory->allocate(params);
++
++                RTPOptionsPtr options(new RTPOptions());
++                RTPAllocationOutputsPtr outputs;
++
++                SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
++                if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SipSessionManager::V1::RFC4733)
++                {
++                    options->handleTelephonyEvents = true;
++                }
++
++                session = factory->allocate(params, options, outputs);
 +
 +                // Double check to make sure they actually gave us a sesson back... they could have had a problem
 +                if (session == 0)
 +                {
 +                    // The only time this should ever occur is on the initial INVITE so removing the stream from everywhere
 +                    // is perfectly acceptable since nothing has seen it
 +                    mImplPriv->mStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    continue;
 +                }
 +
++                if (outputs)
++                {
++                    mImplPriv->mExternalEventSources = outputs->eventSources;
++                    mImplPriv->mExternalEventSinks = outputs->eventSinks;
++                }
++
 +                // RTP sessions only provide a single sink and source so that makes this easy
 +                StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
 +                mImplPriv->mSinks.push_back(sink);
 +                ourStream->sinks.push_back(sink);
 +
 +                StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(session->getSources().front());
 +                mImplPriv->mSources.push_back(source);
 +                ourStream->sources.push_back(source);
 +
 +                // Update the SIP session with some RTP session details
 +                mImplPriv->mRTPSessions.push_back(session);
 +
 +                // Just by common sense alone since we just got an RTP session for this stream we obviously
 +                // have not added it to the answer SDP either, so do it
 +                pjmedia_sdp_media *media = allocate_from_pool<pjmedia_sdp_media>(mImplPriv->mDialog->pool);
 +                mImplPriv->mSDP->media[mImplPriv->mSDP->media_count++] = media;
 +
 +                // Since our stream should be like the offering stream we can just use some values from there
 +                media->desc.media = offer->media[stream]->desc.media;
 +                media->desc.transport = offer->media[stream]->desc.transport;
 +		media->desc.fmt[0] = offer->media[stream]->desc.fmt[0];
 +
 +                // Add connection level information so they know our IP address
 +                media->conn = allocate_from_pool<pjmedia_sdp_conn>(mImplPriv->mDialog->pool);
 +                media->conn->net_type = offer->origin.net_type;
 +                media->conn->addr_type = offer->origin.addr_type;
 +                pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, source->getLocalAddress().c_str());
 +
 +                // If session level connection information has not yet been set then set it to us
 +                if (!mImplPriv->mSDP->conn)
 +                {
 +                    mImplPriv->mSDP->conn = media->conn;
 +                }
 +
 +                // Add port information so they can talk to us
 +                media->desc.port = (pj_uint16_t) source->getLocalPort();
 +                media->desc.port_count = 1;
 +
 +                PayloadMap payloads;
 +
 +                addFormatstoSDP(formats, media, payloads);
 +
 +                // Push the payload mapping to the RTP session so it'll correctly map things
 +                session->associatePayloads(payloads);
              }
 -        
 -            RTPOptionsPtr options(new RTPOptions());
 -            RTPAllocationOutputsPtr outputs;
  
 -            SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
 -            if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SipSessionManager::V1::RFC4733)
 +            // If the RTP session supports RTCP determine the connection details for it
 +            RTCP::V1::RTCPSessionPrx rtcpSession;
 +            if ((rtcpSession = RTCP::V1::RTCPSessionPrx::checkedCast(session, RTCP::V1::SessionFacet)))
              {
 -                options->handleTelephonyEvents = true;
 +                // Assume RTCP is destined for the same address and the RTP port + 1 as it probably is
 +                std::string rtcpConnection = connection;
 +                int rtcpPort = offer->media[stream]->desc.port + 1;
 +
 +                pjmedia_sdp_attr *attr;
 +                pjmedia_sdp_rtcp_attr rtcpAttr;
 +
 +                if ((attr = pjmedia_sdp_media_find_attr2(offer->media[stream], "rtcp", NULL)) &&
 +                    (pjmedia_sdp_attr_get_rtcp(attr, &rtcpAttr) == PJ_SUCCESS))
 +                {
 +                    rtcpPort = rtcpAttr.port;
 +
 +                    if (rtcpAttr.addr.slen)
 +                    {
 +                        rtcpConnection = std::string(pj_strbuf(&rtcpAttr.addr), pj_strlen(&rtcpAttr.addr));
 +                    }
 +                }
 +
 +                rtcpSession->setRemoteDetails(rtcpConnection, rtcpPort);
              }
  
 -            // Allocate a new RTP session to carry the media formats we have in common
 -            session = factory->allocate(params, options, outputs);
 +            // Update connection information
 +            StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(ourStream->sinks.front());
  
 -            // Double check to make sure they actually gave us a sesson back... they could have had a problem
 -            if (session == 0)
 +            // If the remote party attempts to use an invalid address bring down the session since obviously
 +            // something is critically wrong and stuff will most likely fall apart quickly
 +            try
              {
 -                // The only time this should ever occur is on the initial INVITE so removing the stream from everywhere
 -                // is perfectly acceptable since nothing has seen it
 -                mImplPriv->mStreams.erase(boost::lexical_cast<std::string>(stream));
 -                newStreams.erase(boost::lexical_cast<std::string>(stream));
 -                continue;
 +                sink->setRemoteDetails(connection, offer->media[stream]->desc.port);
 +            }
 +            catch (const AsteriskSCF::Media::RTP::V1::InvalidAddress&)
 +            {
 +                pjsip_tx_data *packet;
 +                if (pjsip_inv_end_session(mImplPriv->mInviteSession, 488, NULL, &packet) == PJ_SUCCESS)
 +                {
 +                    pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
 +                }
 +                return 0;
              }
 +        }
 +        else if ((t38 = T38UdptlFormatPtr::dynamicCast(formats.front())))
 +        {
 +            // Ensure the offer is valid
 +	    if (t38->faxRateManagement == UNSPECIFIED_TCF)
 +	    {
 +		continue;
 +	    }
  
 -            if (outputs)
 +            // If this is a modified stream make sure the transport is UDPTL, if not clear things out
 +            if (!ourStream->sinks.empty())
              {
 -                mImplPriv->mExternalEventSources = outputs->eventSources;
 -                mImplPriv->mExternalEventSinks = outputs->eventSinks;
 +                StreamSinkUDPTLPrx udptlSink = StreamSinkUDPTLPrx::checkedCast(ourStream->sinks.front());
 +                if (!udptlSink)
 +                {
 +                    ourStream->sinks.clear();
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.insert(make_pair(boost::lexical_cast<std::string>(stream), ourStream));
 +                }
              }
  
 -            // RTP sessions only provide a single sink and source so that makes this easy
 -            StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
 -            mImplPriv->mSinks.push_back(sink);
 -            ourStream->sinks.push_back(sink);
 +            if (!ourStream->sources.empty())
 +            {
 +                StreamSourceUDPTLPrx udptlSource = StreamSourceUDPTLPrx::checkedCast(ourStream->sources.front());
 +                if (!udptlSource)
 +                {
 +                    ourStream->sources.clear();
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.insert(make_pair(boost::lexical_cast<std::string>(stream), ourStream));
 +                }
 +            }
  
 -            StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(session->getSources().front());
 -            mImplPriv->mSources.push_back(source);
 -            ourStream->sources.push_back(source);
 +            if (ourStream->sinks.empty() && ourStream->sources.empty())
 +            {
 +                UDPTLServiceLocatorParamsPtr params = new UDPTLServiceLocatorParams();
 +                params->category = "udptl";
  
 -            // Update the SIP session with some RTP session details
 -            mImplPriv->mRTPSessions.push_back(session);
 +                if (connection.find(":") != std::string::npos)
 +                {
 +                    params->ipv6 = true;
 +                }
 +                else
 +                {
 +                    params->ipv6 = false;
 +                }
  
 -            // Just by common sense alone since we just got an RTP session for this stream we obviously
 -            // have not added it to the answer SDP either, so do it
 -            pjmedia_sdp_media *media = allocate_from_pool<pjmedia_sdp_media>(mImplPriv->mDialog->pool);
 -            mImplPriv->mSDP->media[mImplPriv->mSDP->media_count++] = media;
 +                UDPTLMediaServicePrx factory = UDPTLMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
  
 -            // Since our stream should be like the offering stream we can just use some values from there
 -            media->desc.media = offer->media[stream]->desc.media;
 -            media->desc.transport = offer->media[stream]->desc.transport;
 +                if (factory == 0)
 +                {
 +                    mImplPriv->mStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    continue;
 +                }
  
 -            // Add connection level information so they know our IP address
 -            media->conn = allocate_from_pool<pjmedia_sdp_conn>(mImplPriv->mDialog->pool);
 -            media->conn->net_type = offer->origin.net_type;
 -            media->conn->addr_type = offer->origin.addr_type;
 -            pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, source->getLocalAddress().c_str());
 +                UDPTLSessionPrx session = factory->allocate(params);
  
 -            // If session level connection information has not yet been set then set it to us
 -            if (!mImplPriv->mSDP->conn)
 -            {
 -                mImplPriv->mSDP->conn = media->conn;
 -            }
 +                if (session == 0)
 +                {
 +                    mImplPriv->mStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    newStreams.erase(boost::lexical_cast<std::string>(stream));
 +                    continue;
 +                }
  
 -            // Add port information so they can talk to us
 -            media->desc.port = (pj_uint16_t) source->getLocalPort();
 -            media->desc.port_count = 1;
 +                StreamSinkUDPTLPrx sink = StreamSinkUDPTLPrx::uncheckedCast(session->getSinks().front());
 +                mImplPriv->mSinks.push_back(sink);
 +                ourStream->sinks.push_back(sink);
  
 -            PayloadMap payloads;
 +                StreamSourceUDPTLPrx source = StreamSourceUDPTLPrx::uncheckedCast(session->getSources().front());
 +                mImplPriv->mSources.push_back(source);
 +                ourStream->sources.push_back(source);
  
 -            addFormatstoSDP(formats, media, payloads);
 +                mImplPriv->mUDPTLSessions.push_back(session);
  
 -            // Push the payload mapping to the RTP session so it'll correctly map things
 -            session->associatePayloads(payloads);
 -        }
 +                mImplPriv->mSDP->media_count = 0;
  
 -        // Record the old state so we can relay the state change to the controller if needed
 -        StreamState oldState = ourStream->state;
 -        
 -        // Determine the state of the stream and update it
 -    if (pjmedia_sdp_media_find_attr2(offer->media[stream], "sendonly", NULL))
 -        {
 -            ourStream->state = SendOnly;
 -        }
 -        else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "recvonly", NULL))
 -        {
 -            ourStream->state = ReceiveOnly;
 -        }
 -        else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "inactive", NULL))
 -        {
 -            ourStream->state = Inactive;
 -        }
 -        else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "sendrecv", NULL))
 -        {
 -            ourStream->state = SendAndReceive;
 -        }
 +                pjmedia_sdp_media *media = allocate_from_pool<pjmedia_sdp_media>(mImplPriv->mDialog->pool);
 +                mImplPriv->mSDP->media[mImplPriv->mSDP->media_count++] = media;
  
 -        // If the RTP session supports RTCP determine the connection details for it
 -        RTCP::V1::RTCPSessionPrx rtcpSession;
 -        if ((rtcpSession = RTCP::V1::RTCPSessionPrx::checkedCast(session, RTCP::V1::SessionFacet)))
 -        {
 -            // Assume RTCP is destined for the same address and the RTP port + 1 as it probably is
 -            std::string rtcpConnection = connection;
 -            int rtcpPort = offer->media[stream]->desc.port + 1;
 +                media->desc.media = offer->media[stream]->desc.media;
 +                media->desc.transport = offer->media[stream]->desc.transport;
 +		media->desc.fmt[0] = offer->media[stream]->desc.fmt[0];
 +		media->desc.fmt_count++;
  
 -            pjmedia_sdp_attr *attr;
 -            pjmedia_sdp_rtcp_attr rtcpAttr;
 +                media->conn = allocate_from_pool<pjmedia_sdp_conn>(mImplPriv->mDialog->pool);
 +                media->conn->net_type = offer->origin.net_type;
 +                media->conn->addr_type = offer->origin.addr_type;
  
 -            if ((attr = pjmedia_sdp_media_find_attr2(offer->media[stream], "rtcp", NULL)) &&
 -                (pjmedia_sdp_attr_get_rtcp(attr, &rtcpAttr) == PJ_SUCCESS))
 -            {
 -                rtcpPort = rtcpAttr.port;
 +                AddressInformation info = source->getLocalDetails();
 +
 +                pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, info.ipAddress.c_str());
 +
 +                if (!mImplPriv->mSDP->conn)
 +                {
 +                    mImplPriv->mSDP->conn = media->conn;
 +                }
 +
 +                media->desc.port = (pj_uint16_t) info.port;
 +                media->desc.port_count = 1;
  
 -                if (rtcpAttr.addr.slen)
 +                SDPDescriptorPtr ourDescriptor = mImplPriv->mEndpoint->getInterpretedDescriptor(t38);
 +                for (SDPFormatParameterSeq::const_iterator parameter = ourDescriptor->parameters.begin();
 +                     parameter != ourDescriptor->parameters.end();
 +                     ++parameter)
                  {
 -                    rtcpConnection = std::string(pj_strbuf(&rtcpAttr.addr), pj_strlen(&rtcpAttr.addr));
 +                    pjmedia_sdp_attr *attr = allocate_from_pool<pjmedia_sdp_attr>(mImplPriv->mDialog->pool);
 +                    pj_strdup2(mImplPriv->mDialog->pool, &attr->name, (*parameter).c_str());
 +                    media->attr[media->attr_count++] = attr;
                  }
              }
  
diff --cc src/SipSession.h
index 2c93670,788e736..a7f94ab
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@@ -119,27 -127,28 +127,29 @@@ public
          const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
          const SipReplicationContextPtr& replicationContext,
          const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx&,
-         bool ipv6,
-         bool isUAC,
-         const SipEndpointConfig& config,
-         const NATEndpointOptions& natOptions);
+         bool ipv6, 
+ 	bool isUAC, 
+ 	const SipEndpointConfig& config, 
+ 	const NATEndpointOptions& natOptions);
  
-     SipSession(const Ice::ObjectAdapterPtr&,
-         const SipEndpointPtr&,
-         const std::string&,
-         const Ice::Identity&,
-         const Ice::Identity&,
-         const Ice::Identity&,
-         const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq&,
-         const AsteriskSCF::Replication::SipSessionManager::V1::UDPTLMediaSessionSeq&,
-         const AsteriskSCF::Media::V1::StreamSourceSeq&,
-         const AsteriskSCF::Media::V1::StreamSinkSeq&,
-         const PJSipManagerPtr& manager,
-         const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
-         const SipReplicationContextPtr& replicationContext,
-         const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx&,
-         bool isUAC,
-         const SipEndpointConfig& config,
+     /**
+      * Factory used by a standby component to create replicas. 
+      */
+     static SipSessionPtr create(const Ice::ObjectAdapterPtr& adapter, const SipEndpointPtr& endpoint,
+         const std::string& destination, 
+         const Ice::Identity& sessionid,
+         const Ice::Identity& controllerid,
+         const Ice::Identity& mediaid, 
+ 	const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
++        const AsteriskSCF::Replication::SipSessionManager::V1::UDPTLMediaSessionSeq& udptlMediaSessions,
+         const AsteriskSCF::Media::V1::StreamSourceSeq& sources, 
+ 	const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
+         const PJSipManagerPtr& manager, 
+ 	const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+         const SipReplicationContextPtr& replicationContext, 
+         const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& hook,
+ 	bool isUAC, 
+ 	const SipEndpointConfig &config,
          const NATEndpointOptions& natOptions);
  
      bool operator==(const SipSession &other) const;
@@@ -323,7 -334,27 +337,28 @@@
      SipTelephonyEventSourcePtr getSipTelephonyEventSource();
  
      bool isTelephonyEventSink();
+ 
+     static bool isSessionCookieReadOnly(const AsteriskSCF::SessionCommunications::V1::SessionCookiePtr &cookie);
+ 
+     void setSelfAsCaller();
+ 
  private:
+     SipSession(const Ice::ObjectAdapterPtr&, const SipEndpointPtr&, const std::string&,
+         const std::vector<AsteriskSCF::SessionCommunications::V1::SessionListenerPrx>&,         
+         const AsteriskSCF::SessionCommunications::V1::SessionCookies&, 
+         const PJSipManagerPtr& manager,
+         const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+         const SipReplicationContextPtr& replicationContext,
+         bool ipv6, bool isUAC, const SipEndpointConfig& config, const NATEndpointOptions& natOptions);
+ 
+     SipSession(const Ice::ObjectAdapterPtr&, const SipEndpointPtr&, const std::string&, const Ice::Identity&, const Ice::Identity&,
 -        const Ice::Identity&, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq&,
 -        const AsteriskSCF::Media::V1::StreamSourceSeq&, const AsteriskSCF::Media::V1::StreamSinkSeq&,
 -        const PJSipManagerPtr& manager, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
 -        const SipReplicationContextPtr& replicationContext,
 -        bool isUAC, const SipEndpointConfig& config, const NATEndpointOptions& natOptions);
++               const Ice::Identity&, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq&,
++               const AsteriskSCF::Replication::SipSessionManager::V1::UDPTLMediaSessionSeq&,
++               const AsteriskSCF::Media::V1::StreamSourceSeq&, const AsteriskSCF::Media::V1::StreamSinkSeq&,
++               const PJSipManagerPtr& manager, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
++               const SipReplicationContextPtr& replicationContext,
++               bool isUAC, const SipEndpointConfig& config, const NATEndpointOptions& natOptions);
+ 
  
      void initializePJSIPStructs();
  

commit 90925e5939f603e874103fd7731f5957febf7b90
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu Sep 22 13:06:42 2011 -0500

    Each file now uses same logger name as that defined in the component's main Component.cpp file.

diff --git a/src/PJSipLoggingModule.cpp b/src/PJSipLoggingModule.cpp
index 214e7f2..6e6a3fb 100644
--- a/src/PJSipLoggingModule.cpp
+++ b/src/PJSipLoggingModule.cpp
@@ -23,7 +23,7 @@ using namespace AsteriskSCF::System::Logging;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/PJSipManager.cpp b/src/PJSipManager.cpp
index 4f3db1d..e4f1054 100644
--- a/src/PJSipManager.cpp
+++ b/src/PJSipManager.cpp
@@ -37,7 +37,7 @@ using namespace std;
 
 namespace
 {
-Logger logger = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger logger = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 const std::string RegistrarId("SipRegistrar");
 }
 
diff --git a/src/PJSipModule.cpp b/src/PJSipModule.cpp
index 5a85362..73ab3df 100644
--- a/src/PJSipModule.cpp
+++ b/src/PJSipModule.cpp
@@ -23,7 +23,7 @@ using namespace AsteriskSCF::System::Logging;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 9dcbbb9..837c03b 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -30,7 +30,7 @@ using namespace AsteriskSCF::System::WorkQueue::V1;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 40ef11f..500acbe 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -44,7 +44,7 @@ using namespace AsteriskSCF::System::Hook::V1;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 //Constants used for AMI callback class construction when calling
 //SessionListenerPrx methods.
 const std::string RingingCallbackName("ringing");
diff --git a/src/PJSipSessionModuleConstruction.cpp b/src/PJSipSessionModuleConstruction.cpp
index 3d3d5ee..8e66d17 100644
--- a/src/PJSipSessionModuleConstruction.cpp
+++ b/src/PJSipSessionModuleConstruction.cpp
@@ -25,7 +25,7 @@ using namespace AsteriskSCF::System::Logging;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 const std::string SessionCreationExtensionPointId("SipSessionCreationExtensionPoint");
 }
 
diff --git a/src/STUNTransport.cpp b/src/STUNTransport.cpp
index 076ee72..4ab831a 100644
--- a/src/STUNTransport.cpp
+++ b/src/STUNTransport.cpp
@@ -37,7 +37,7 @@ using namespace std;
 
 namespace
 {
-Logger logger = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger logger = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index 2e59ea0..2c5bf9d 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -40,7 +40,7 @@ using namespace AsteriskSCF::Discovery;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/SipEndpointFactory.cpp b/src/SipEndpointFactory.cpp
index ce8de77..40d3774 100644
--- a/src/SipEndpointFactory.cpp
+++ b/src/SipEndpointFactory.cpp
@@ -23,7 +23,7 @@ using namespace AsteriskSCF::System::Logging;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/SipRegistrarListener.cpp b/src/SipRegistrarListener.cpp
index 8c323c4..be963a2 100644
--- a/src/SipRegistrarListener.cpp
+++ b/src/SipRegistrarListener.cpp
@@ -21,7 +21,7 @@ using namespace AsteriskSCF::System::Logging;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 4ff8833..98d5716 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -55,7 +55,7 @@ using namespace std;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/SipSessionManagerEndpointLocator.cpp b/src/SipSessionManagerEndpointLocator.cpp
index ff0b388..375847c 100644
--- a/src/SipSessionManagerEndpointLocator.cpp
+++ b/src/SipSessionManagerEndpointLocator.cpp
@@ -30,7 +30,7 @@ namespace SipSessionManager
 using namespace AsteriskSCF::System::Logging;
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 /**
diff --git a/src/SipSessionManagerEventPublisher.cpp b/src/SipSessionManagerEventPublisher.cpp
index a716072..84cc60a 100644
--- a/src/SipSessionManagerEventPublisher.cpp
+++ b/src/SipSessionManagerEventPublisher.cpp
@@ -27,7 +27,7 @@ using namespace AsteriskSCF::System::Logging;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 }
 
 namespace AsteriskSCF
diff --git a/src/SipStateReplicatorApp.cpp b/src/SipStateReplicatorApp.cpp
index 4f9cee7..7a875e9 100644
--- a/src/SipStateReplicatorApp.cpp
+++ b/src/SipStateReplicatorApp.cpp
@@ -45,7 +45,7 @@ using namespace AsteriskSCF::System::Configuration::V1;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGatewayReplicator");
 }
 
 class SipStateReplicatorService : public IceBox::Service
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index d6d2ede..455aef5 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -26,7 +26,7 @@ using namespace AsteriskSCF::System::Logging;
 
 namespace
 {
-Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 
 pjsip_tx_data* createNotify(pjsip_dialog *dlg, pj_int32_t cseq, bool active)
 {

commit 8e0f48d19b059e7d26fcbd27ace7a0f34e759ef8
Author: Brent Eagles <beagles at digium.com>
Date:   Mon Sep 19 20:31:36 2011 -0230

    Modified Ice property processing to comply with recent changes to property
    naming conventions.
    
    Note: In the case of the STUNModule configuration, this resulted in (IMO) a
    less-than-ideal change that would be better served by refactoring in a
    pjproject configuration class (or something to that effect). Generally
    speaking, it is preferable to avoid proliferation of property processing
    throughout the code. In this case, I was a bit more willing to let it slide
    because it is a startup-processing type of thing.

diff --git a/src/Component.cpp b/src/Component.cpp
index 75bacbe..77b835b 100644
--- a/src/Component.cpp
+++ b/src/Component.cpp
@@ -252,13 +252,13 @@ void Component::locateRoutingService()
     ServiceLocatorParamsPtr genericparams = new ServiceLocatorParams();
     genericparams->category = Routing::V1::RoutingServiceLocatorRegistryDiscoveryCategory;
     genericparams->service =
-        getCommunicator()->getProperties()->getPropertyWithDefault("Sip.RoutingService", "default");
+        getCommunicator()->getProperties()->getPropertyWithDefault(getName() + ".Sip.RoutingService", "default");
 
     AsteriskSCF::Discovery::SmartProxy<LocatorRegistryPrx> pw(getServiceLocator(), genericparams, lg);
     mRoutingServiceLocatorRegistry = pw;
 
     // This exists here since it may need to be known before actually contacting the routing service
-    mRoutingId = getCommunicator()->getProperties()->getPropertyWithDefault("Sip.RoutingDestinationId", "pjsip");
+    mRoutingId = getCommunicator()->getProperties()->getPropertyWithDefault(getName() + ".Sip.RoutingDestinationId", "pjsip");
 }
 
 void Component::locateStateReplicator()
@@ -271,7 +271,7 @@ void Component::locateStateReplicator()
     ServiceLocatorParamsPtr replicatorParams = new ServiceLocatorParams();
     replicatorParams->category = StateReplicatorDiscoveryCategory;
     replicatorParams->service =
-        getCommunicator()->getProperties()->getPropertyWithDefault("Sip.StateReplicatorService", "default");
+        getCommunicator()->getProperties()->getPropertyWithDefault(getName() + ".Sip.StateReplicatorService", "default");
 
     try
     {
@@ -360,7 +360,7 @@ void Component::locateSessionRouter()
     ServiceLocatorParamsPtr genericparams = new ServiceLocatorParams();
     genericparams->category = Routing::V1::SessionRouterDiscoveryCategory;
     genericparams->service = getCommunicator()->getProperties()->getPropertyWithDefault(
-            "SessionRouter.Service", "default");
+        getName() + ".SessionRouter.Service", "default");
 
     SmartProxy<SessionRouterPrx> pw(getServiceLocator(), genericparams, lg);
     mSessionRouter = pw;
@@ -372,7 +372,7 @@ void Component::registerPJSipModules()
         boost::static_pointer_cast<SipReplicationContext>(getReplicationContext());
 
     Ice::PropertiesPtr props = getCommunicator()->getProperties();
-    Ice::StringSeq moduleNames = props->getPropertyAsList("Sip.Modules");
+    Ice::StringSeq moduleNames = props->getPropertyAsList(getName() + ".Sip.Modules");
     for (Ice::StringSeq::iterator i = moduleNames.begin();
          i != moduleNames.end();
          ++i)
@@ -415,7 +415,7 @@ void Component::onPreInitialize()
     {
         // Initialize PJSIP
         // NOTE: Should use PJSipManager::create now. 
-        mPJSipManager = PJSipManager::create(getCommunicator()->getProperties());
+        mPJSipManager = PJSipManager::create(getName(), getCommunicator()->getProperties());
         lg(Debug) << "Created PJSIP manager";
 
         //As nice as it is of IceBox to provide us with a communicator,
diff --git a/src/PJSipManager.cpp b/src/PJSipManager.cpp
index 4d60459..4f3db1d 100644
--- a/src/PJSipManager.cpp
+++ b/src/PJSipManager.cpp
@@ -96,10 +96,11 @@ static void *monitorThread(void *endpt)
     return NULL;
 }
 
-PJSipManagerPtr AsteriskSCF::SipSessionManager::PJSipManager::create(const Ice::PropertiesPtr& properties)
+PJSipManagerPtr AsteriskSCF::SipSessionManager::PJSipManager::create(const std::string& managerName,
+        const Ice::PropertiesPtr& properties)
 {
     PJSipManagerPtr result(new PJSipManager);
-    STUNModulePtr stunModule = STUNModule::create(result, properties, logger);
+    STUNModulePtr stunModule = STUNModule::create(result, managerName, properties, logger);
     result->addModule("STUN", stunModule);
     return result;
 }
diff --git a/src/PJSipManager.h b/src/PJSipManager.h
index fe25567..9f70907 100644
--- a/src/PJSipManager.h
+++ b/src/PJSipManager.h
@@ -54,7 +54,7 @@ typedef boost::shared_ptr<PJSipManager> PJSipManagerPtr;
 class PJSipManager : public boost::enable_shared_from_this<PJSipManager>
 {
 public:
-    static PJSipManagerPtr create(const Ice::PropertiesPtr& properties);
+    static PJSipManagerPtr create(const std::string& managerName, const Ice::PropertiesPtr& properties);
 
     virtual ~PJSipManager();
 
diff --git a/src/STUNModule.cpp b/src/STUNModule.cpp
index 3678e5e..a1a0be3 100644
--- a/src/STUNModule.cpp
+++ b/src/STUNModule.cpp
@@ -77,7 +77,7 @@ pj_pool_t* STUNModule::getPool()
 //
 // Static public
 //
-boost::shared_ptr<STUNModule> STUNModule::create(const PJSipManagerPtr& sipManager,
+boost::shared_ptr<STUNModule> STUNModule::create(const PJSipManagerPtr& sipManager, const std::string& managerName,
         const Ice::PropertiesPtr& properties, const Logger& logger)
 {
     logger(Debug) << FUNLOG << " : initializing STUN module";
@@ -99,7 +99,7 @@ boost::shared_ptr<STUNModule> STUNModule::create(const PJSipManagerPtr& sipManag
     pj_stun_config_init(config.get(), &sipManager->getCachingPool()->factory, 0, 0, 0);
 
     status = pj_timer_heap_create(sipManager->getMemoryPool(), 
-            properties->getPropertyAsIntWithDefault("Sip.PJSip.TimerHeap.Size", 1000), 
+            properties->getPropertyAsIntWithDefault(managerName + ".Sip.PJSip.TimerHeap.Size", 1000), 
             &(config->timer_heap));
     
     if (fail(status))
@@ -112,7 +112,8 @@ boost::shared_ptr<STUNModule> STUNModule::create(const PJSipManagerPtr& sipManag
         throw InternalInitializationException(message);
     }
 
-    status = pj_ioqueue_create(sipManager->getMemoryPool(), properties->getPropertyAsIntWithDefault("Sip.PJSip.IOQueue.MaxSize", 16), 
+    status = pj_ioqueue_create(sipManager->getMemoryPool(),
+            properties->getPropertyAsIntWithDefault(managerName + ".Sip.PJSip.IOQueue.MaxSize", 16), 
             &(config->ioqueue));
     if (fail(status))
     {
diff --git a/src/STUNModule.h b/src/STUNModule.h
index 492b213..ab04234 100644
--- a/src/STUNModule.h
+++ b/src/STUNModule.h
@@ -75,7 +75,7 @@ public:
 
     //
     //
-    static boost::shared_ptr<STUNModule> create(const PJSipManagerPtr& sipManager,
+    static boost::shared_ptr<STUNModule> create(const PJSipManagerPtr& sipManager, const std::string& managerName,
             const Ice::PropertiesPtr& properties, const AsteriskSCF::System::Logging::Logger& logger);
 protected:
     STUNModule(const boost::shared_ptr<pj_stun_config>& config);
diff --git a/src/SipSessionManagerApp.cpp b/src/SipSessionManagerApp.cpp
index 39f9b74..f73de75 100644
--- a/src/SipSessionManagerApp.cpp
+++ b/src/SipSessionManagerApp.cpp
@@ -337,7 +337,7 @@ void SipSessionManager::registerWithServiceLocator()
         std::string authServiceGuid("SipAuthExtensionPoint");
         mAuthServiceManagement = ServiceManagementPrx::uncheckedCast(mServiceLocatorManagement->addService(authPrx, authServiceGuid));
         setCategory(mAuthServiceManagement, AsteriskSCF::SIP::V1::AuthExtensionPointCategory);
-        if (mCommunicator->getProperties()->getPropertyWithDefault("Sip.Standalone", "false") == "true")
+        if (mCommunicator->getProperties()->getPropertyWithDefault(getName() + ".Sip.Standalone", "false") == "true")
         {
             // Publish the configuration service IceStorm topic so everybody gets configuration
             mConfigurationManagement = ServiceManagementPrx::uncheckedCast(
@@ -346,7 +346,8 @@ void SipSessionManager::registerWithServiceLocator()
             // Populate the configuration parameters with details so we can be found
             SipConfigurationParamsPtr configurationParams = new SipConfigurationParams();
             configurationParams->category = ConfigurationDiscoveryCategory;
-            configurationParams->name = mCommunicator->getProperties()->getPropertyWithDefault("SipConfiguration.Name", "");
+            configurationParams->name = mCommunicator->getProperties()->getPropertyWithDefault(getName() +
+                    ".SipConfiguration.Name", "");
         
             // Add our custom comparator so we can support multiple simultaneous configuration sinks
             SipConfigurationComparePtr configNameCompare = new SipConfigurationCompare(configurationParams->name);
@@ -408,7 +409,7 @@ void SipSessionManager::locateRoutingService()
     mRoutingServiceLocatorRegistry = pw;
 
     // This exists here since it may need to be known before actually contacting the routing service
-    mRoutingId = mCommunicator->getProperties()->getPropertyWithDefault("Sip.RoutingId", "pjsip");
+    mRoutingId = mCommunicator->getProperties()->getPropertyWithDefault(getName() + ".Sip.RoutingId", "pjsip");
 }
 
 void SipSessionManager::locateStateReplicator()
@@ -421,7 +422,7 @@ void SipSessionManager::locateStateReplicator()
     SipStateReplicatorParamsPtr replicatorParams = new SipStateReplicatorParams();
     replicatorParams->category = StateReplicatorDiscoveryCategory;
     replicatorParams->mName =
-        mCommunicator->getProperties()->getPropertyWithDefault("Sip.StateReplicatorName", "default");
+        mCommunicator->getProperties()->getPropertyWithDefault(getName() + ".Sip.StateReplicatorName", "default");
 
     try
     {
@@ -441,14 +442,15 @@ void SipSessionManager::registerWithStateReplicator()
         return;
     }
 
-    if (mCommunicator->getProperties()->getPropertyWithDefault("Sip.Standalone", "false") == "false")
+    if (mCommunicator->getProperties()->getPropertyWithDefault(getName() + ".Sip.Standalone", "false") == "false")
     {
 	ConfigurationReplicatorPrx configurationReplicator = ConfigurationReplicatorPrx::checkedCast(
 	    mStateReplicator.initialize(), ReplicatorFacet);
 	configurationReplicator->registerConfigurationService(mConfigurationServiceProxy);
     }
 
-    if (mCommunicator->getProperties()->getPropertyWithDefault("Sip.StateReplicatorListener", "no") == "yes")
+    if (mCommunicator->getProperties()->getPropertyWithDefault(getName() + ".Sip.StateReplicatorListener", "no")
+            == "yes")
     {
         mStateReplicator->addListener(mReplicatorListenerProxy);
         mReplicaService->standby();
@@ -497,7 +499,7 @@ void SipSessionManager::deregisterFromServiceLocator()
 void SipSessionManager::registerPJSipModules()
 {
     Ice::PropertiesPtr props = mCommunicator->getProperties();
-    Ice::StringSeq moduleNames = props->getPropertyAsList("Sip.Modules");
+    Ice::StringSeq moduleNames = props->getPropertyAsList(getName() + ".Sip.Modules");
     for (Ice::StringSeq::iterator i = moduleNames.begin();
          i != moduleNames.end();
          ++i)
@@ -669,7 +671,8 @@ void SipSessionManager::start(const string& name, const Ice::CommunicatorPtr& ic
 
     // Register our Endpoint Locator so that we can provide endpoints to the
     // Routing Service for the endpoints we manage.
-    if (mCommunicator->getProperties()->getPropertyWithDefault("Sip.StateReplicatorListener", "no") != "yes")
+    if (mCommunicator->getProperties()->getPropertyWithDefault(getName() + ".Sip.StateReplicatorListener",
+                    "no") != "yes")
     {
         //Only register with the routing service if we're the primary SIP instance.
         registerWithRoutingService();
diff --git a/src/SipStateReplicatorApp.cpp b/src/SipStateReplicatorApp.cpp
index d0b1477..4f9cee7 100644
--- a/src/SipStateReplicatorApp.cpp
+++ b/src/SipStateReplicatorApp.cpp
@@ -149,7 +149,8 @@ void SipStateReplicatorService::registerWithServiceLocator(const Ice::Communicat
 {
     try
     {
-        // Get a proxy to the management interface for the Service Locator, so we can add ourselves into the system discovery mechanisms.
+        // Get a proxy to the management interface for the Service Locator, so we can add ourselves into the system
+        // discovery mechanisms.
         mServiceLocatorManagement = ServiceLocatorManagementPrx::checkedCast(
             ic->propertyToProxy("LocatorServiceManagement.Proxy"));
 
@@ -185,9 +186,9 @@ void SipStateReplicatorService::registerWithServiceLocator(const Ice::Communicat
 
         ServiceLocatorParamsPtr discoveryParams = new ServiceLocatorParams();
         discoveryParams->category = StateReplicatorDiscoveryCategory;
-        discoveryParams->service = ic->getProperties()->getPropertyWithDefault("SipStateReplicator.Service", 
+        discoveryParams->service = ic->getProperties()->getPropertyWithDefault(mAppName + ".ServiceName", 
             "default");
-        discoveryParams->id = ic->getProperties()->getPropertyWithDefault("SipStateReplicator.Name", "default");
+        discoveryParams->id = ic->getProperties()->getPropertyWithDefault(mAppName + ".Name", "default");
         mStateReplicationManagement->addLocatorParams(discoveryParams, "");
 
         // Publish the configuration service IceStorm topic so everybody gets configuration
@@ -197,9 +198,9 @@ void SipStateReplicatorService::registerWithServiceLocator(const Ice::Communicat
         // Populate the configuration parameters with details so we can be found
         ServiceLocatorParamsPtr configurationParams = new ServiceLocatorParams();
         configurationParams->category = ConfigurationDiscoveryCategory;
-        configurationParams->service = ic->getProperties()->getPropertyWithDefault("SipStateReplicator.Service", 
+        configurationParams->service = ic->getProperties()->getPropertyWithDefault(mAppName + ".ServiceName", 
             "default");
-        configurationParams->id = ic->getProperties()->getPropertyWithDefault("SipConfiguration.Name", "");
+        configurationParams->id = ic->getProperties()->getPropertyWithDefault(mAppName + ".Name", "");
         mConfigurationManagement->addLocatorParams(configurationParams, "");
 
         // TBD... We may have other interfaces to publish to the Service Locator.
@@ -231,10 +232,8 @@ void SipStateReplicatorService::deregisterFromServiceLocator()
 
 void SipStateReplicatorService::initialize(const std::string& appName, const Ice::CommunicatorPtr& ic)
 {
-    mIceStorm = new CollocatedIceStorm("SipStateReplicatorIceStorm", ic->getProperties());
-
-    IceStorm::TopicManagerPrx topicManager = IceStorm::TopicManagerPrx::checkedCast(
-        ic->propertyToProxy("SipStateReplicatorTopicManager.Proxy"));
+    mIceStorm = new CollocatedIceStorm(appName, ic->getProperties());
+    IceStorm::TopicManagerPrx topicManager = mIceStorm->createTopicManagerProxy(ic);
 
     IceStorm::TopicPrx topic;
 
@@ -265,7 +264,7 @@ void SipStateReplicatorService::initialize(const std::string& appName, const Ice
         lg(Info) << "IceStorm topic manager proxy not present, unable to perform configuration replication.";
     }
 
-    mAdapter = ic->createObjectAdapter("SipStateReplicator");
+    mAdapter = ic->createObjectAdapter(appName + ".Adapter");
 
     // setup logging client
     mIceLogger = createIceLogger(mAdapter);

commit ee3a950ea3930a81c156217bf614f5b0512fc0aa
Merge: 712a66b c18c1c9
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Sep 14 17:32:50 2011 -0500

    Merge branch 'master' into telephone-events


commit c18c1c9ca971b3b08c0224f059c45052e71f636a
Merge: ec01c62 8e37073
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Sep 13 11:48:43 2011 -0500

    Merge branch 'replacement'


commit 8e37073a5318103b06dec8e241088244968a77fb
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Aug 29 14:16:57 2011 -0500

    Make appropriate changes to accommodate API changes.

diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 117ea79..d6d2ede 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -479,7 +479,7 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
 
             lg(Debug) << "handleRefer() calling router connectBridgedSessions(). ";
 
-            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), d);
+            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), false, d);
             pjsip_dlg_dec_lock(other_dlg);
             return Complete;
         }
@@ -518,7 +518,7 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
             addNotifyBody(tdata, "SIP/2.0 100 Trying");
             pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
 
-            mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, mHook->getProxy(), d);
+            mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, false, mHook->getProxy(), d);
             return Complete;
         }
         catch (const Ice::CommunicatorDestroyedException &)

commit 712a66be46d2e2944440e097f88568182b405f4d
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Aug 5 11:01:38 2011 -0500

    Add the RFC4733 format to configured formats if relevant.
    
    I also added some error messages for failures, since I was having a name
    mismatch issue when looking up the format I wanted.

diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index f8e0cf5..e34f455 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -63,8 +63,17 @@ public:
 	mDescriptorService->begin_getNamedFormat(mName, mSampleRate, mFrameSize, mFormatSpecific, descriptorCB);
     }
 
+    std::string printFormat()
+    {
+        std::stringstream str;
+        //We could add frameSize here later.
+        str << mName << "/" << mSampleRate;
+        return str.str();
+    }
+
     void locateFailureCB(const Ice::Exception&)
     {
+        lg(Error) << "Couldn't locate format " << printFormat();
     }
 
     void getNamedFormatCB(const FormatPtr& format)
@@ -82,6 +91,7 @@ public:
 
     void getNamedFormatFailureCB(const Ice::Exception&)
     {
+        lg(Error) << "getNamedFormat failed for format " << printFormat();
     }
 
     void getDescriptorCB(const SDPDescriptorPtr& descriptor)
@@ -95,6 +105,7 @@ public:
 
     void getDescriptorFailureCB(const Ice::Exception&)
     {
+        lg(Error) << "getDescriptor failed for format " << printFormat();
     }
 
     SDPDescriptorServicePrx getDescriptorService()
@@ -288,6 +299,17 @@ void SipEndpoint::setSecureTransport(enum Direction direction)
 void SipEndpoint::setDTMFMethod(AsteriskSCF::Configuration::SipSessionManager::V1::SipDTMFOption dtmf)
 {
     mImplPriv->mConfig.sessionConfig.dtmf = dtmf;
+    if (mImplPriv->mConfig.sessionConfig.dtmf ==
+            AsteriskSCF::Configuration::SipSessionManager::V1::RFC4733)
+    {
+        //For RFC 4733, we need to include information in the SDP about
+        //the format, so we need to add a new format to the endpoint's
+        //configured formats.
+
+        //XXX For now, we're just adding some hard-coded values. We should probably
+        //be a bit more flexible here in the face of changes or something.
+        addFormat("rfc4733", 8000, 0, Ice::StringSeq());
+    }
 }
 
 void SipEndpoint::setRTPOverIPv6(bool enabled)

commit 57aae578b562047e1e8fa949a2ca597d73f36645
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Aug 2 14:26:10 2011 -0500

    Adjust for media API changes.

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index aa2c3f5..8d94fd0 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -1971,7 +1971,17 @@ pjmedia_sdp_session *SipSession::createSDPOffer(const AsteriskSCF::Media::V1::St
         }
 
         // Allocate a new RTP session to carry the media formats we have in common
-        RTPSessionPrx session = factory->allocate(params);
+        
+        RTPOptionsPtr options(new RTPOptions());
+        RTPAllocationOutputsPtr outputs;
+
+        SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
+        if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SipSessionManager::V1::RFC4733)
+        {
+            options->handleTelephonyEvents = true;
+        }
+
+        RTPSessionPrx session = factory->allocate(params, options, outputs);
 
         // Double check to make sure they actually gave us a sesson back... they could have had a problem
         if (session == 0)
@@ -1979,6 +1989,12 @@ pjmedia_sdp_session *SipSession::createSDPOffer(const AsteriskSCF::Media::V1::St
             continue;
         }
 
+        if (outputs)
+        {
+            mImplPriv->mExternalEventSources = outputs->eventSources;
+            mImplPriv->mExternalEventSinks = outputs->eventSinks;
+        }
+
         // RTP sessions should only provide a single sink, so grab it and update the connection details with that
         // of the remote party
         StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
@@ -2277,9 +2293,18 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
                 newStreams.erase(boost::lexical_cast<std::string>(stream));
                 continue;
             }
+        
+            RTPOptionsPtr options(new RTPOptions());
+            RTPAllocationOutputsPtr outputs;
+
+            SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
+            if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SipSessionManager::V1::RFC4733)
+            {
+                options->handleTelephonyEvents = true;
+            }
 
             // Allocate a new RTP session to carry the media formats we have in common
-            session = factory->allocate(params);
+            session = factory->allocate(params, options, outputs);
 
             // Double check to make sure they actually gave us a sesson back... they could have had a problem
             if (session == 0)
@@ -2291,6 +2316,12 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
                 continue;
             }
 
+            if (outputs)
+            {
+                mImplPriv->mExternalEventSources = outputs->eventSources;
+                mImplPriv->mExternalEventSinks = outputs->eventSinks;
+            }
+
             // RTP sessions only provide a single sink and source so that makes this easy
             StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
             mImplPriv->mSinks.push_back(sink);

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


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list