[asterisk-scf-commits] asterisk-scf/release/sip.git branch "master" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Thu Oct 6 11:16:33 CDT 2011


branch "master" has been updated
       via  9920aea9b6e4647f41f3464e605d282154c9f9b9 (commit)
       via  0ca99918a255c76ca856ce1a1f4090b6d18834c2 (commit)
       via  929a1cff9ce65f6e5b18f3d0dc0cf761b3683f47 (commit)
       via  5e0ba080e24eaa73a77601f50733047fc4b4aff3 (commit)
       via  83d4e0737de244e6c1a64e8dac6dd12c04f8ec96 (commit)
       via  d686a273766e9ee293d9050c9dbfc3748b62eeaf (commit)
       via  b6345950d2a4f1c61c986232ca0b225eb84f4296 (commit)
       via  7cf2d5832e61940212efbd808a54a1135ace49a6 (commit)
       via  d199b12db578f5ac2c51839f838d63f31cc682b7 (commit)
       via  132df0b6a986086f4ec94858e1d31317e90ba0da (commit)
       via  5b568aeb3078b9f94a36a5672f793664414ee3b1 (commit)
       via  626702b93dea964bdb35251fa6b8123c5236cd16 (commit)
       via  780b003c24252625f2a835cb493416a4e515bc42 (commit)
       via  6e3818ecf1213e1918454a129d1b49adcab0fc29 (commit)
       via  87a71b84f090c02df4091b65fb42f65dbf16e6d5 (commit)
       via  627496611f923896f9af9492d63b97c1eeb25b1d (commit)
       via  d7b7717cfd58774cb42c60875538809e6cd4d473 (commit)
       via  0fde963b9043996f95488778f12ff9c868709fbe (commit)
       via  26b319bfb38e0d0787162de8dfb1957b464fe359 (commit)
       via  7654c9134f255423b8e94e4b88accb878796e4a7 (commit)
       via  f5a0c2e9133a8b3df35a3f4ac081409a1d9b81a5 (commit)
       via  ed015861dae9dbf07fa1795d6babb1e1fd0b205f (commit)
       via  57946244283425c9a3c698634d4cb69355ecab50 (commit)
       via  f5e26ad62bc18858e6e12a5c6e1addf1eb709a8a (commit)
       via  a87f0035311d0650068152e5ef476d18c83603b4 (commit)
       via  f0afa67a194945ba8f9054c74efbc91d6502c72e (commit)
       via  560f85b3223a130f3b8602ddcc8c36e87d8f9f50 (commit)
       via  07dde091d16b917b8c85536d8e7bfaaff77c8c31 (commit)
       via  9b2ad86fa457265c641ed3f68f8824fccc49fbdb (commit)
       via  a7318e778be043b164a8d16c4bb7835811543f6a (commit)
       via  185177314c92bf0ff843f150f7634759ec45f138 (commit)
       via  fbea8a4d8f438cb0585814d88f4e664112196809 (commit)
       via  cec71b05eb37b49dbbd295014b34f36ad19272dc (commit)
      from  1094f862471a5cdc8955aecca1bbbeebba31b44c (commit)

Summary of changes:
 config/SipConfigurator.py                          |   57 +++-
 .../SipSessionManager/SipConfigurationIf.ice       |   66 ++++
 src/AuthManager.h                                  |    1 +
 src/CMakeLists.txt                                 |    2 +
 src/Component.cpp                                  |   15 +-
 src/PJSipManager.cpp                               |   11 +-
 src/PJSipManager.h                                 |    5 +
 src/SipClientRegistration.cpp                      |  403 ++++++++++++++++++++
 src/SipClientRegistration.h                        |  268 +++++++++++++
 src/SipConfiguration.cpp                           |  187 +++++++++-
 src/SipEndpoint.cpp                                |  100 +++++-
 src/SipEndpoint.h                                  |   15 +-
 src/SipEndpointFactory.cpp                         |   17 +-
 src/SipEndpointFactory.h                           |   21 +-
 14 files changed, 1142 insertions(+), 26 deletions(-)
 create mode 100644 src/SipClientRegistration.cpp
 create mode 100644 src/SipClientRegistration.h


- Log -----------------------------------------------------------------
commit 9920aea9b6e4647f41f3464e605d282154c9f9b9
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Oct 6 11:16:08 2011 -0500

    Use the proper name for the constant for default registration since it has changed.

diff --git a/config/SipConfigurator.py b/config/SipConfigurator.py
index 01acf32..c7c9f6f 100755
--- a/config/SipConfigurator.py
+++ b/config/SipConfigurator.py
@@ -130,7 +130,7 @@ class SipSectionVisitors(Configurator.SectionVisitors):
         item = AsteriskSCF.Configuration.SipSessionManager.V1.SipClientRegistrationItem()
 
         mapper.map('aor', item, 'aor', 'registration', config.get, None)
-        mapper.map('expiration', item, 'defaultExpiration', 'registration', config.getint, AsteriskSCF.Configuration.SipSessionManager.V1.DefaultExpiration)
+        mapper.map('expiration', item, 'defaultExpiration', 'registration', config.getint, AsteriskSCF.Configuration.SipSessionManager.V1.DefaultRegistrationExpirationSeconds)
         handler = RegistrationContactHandler(config)
         mapper.map('contacts', item, 'contacts', 'registration', handler.get, None)
 

commit 0ca99918a255c76ca856ce1a1f4090b6d18834c2
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Oct 5 17:02:55 2011 -0500

    Clarify documentation and change name of the method used to respond to an authentication challenge.

diff --git a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
index 6b74279..49f0d96 100644
--- a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
+++ b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
@@ -591,7 +591,7 @@ struct ContactInfo
 
 sequence<ContactInfo> ContactInfoSeq;
 
-const int DefaultExpiration = 3600;
+const int DefaultRegistrationExpirationSeconds = 3600;
 
 class SipClientRegistrationItem extends SipConfigurationItem
 {
@@ -606,8 +606,8 @@ class SipClientRegistrationItem extends SipConfigurationItem
     ContactInfoSeq contacts;
     /**
      * The expiration to use for any contacts
-     * with no explicit expiration set. Units
-     * for expiration are seconds.
+     * with no explicit expiration set (i.e. a 0 expiration).
+     * Units for expiration are seconds.
      */
     int defaultExpiration;
 };
diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index ba624f7..a4e03d5 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -373,7 +373,7 @@ void SipRegistrationClient::authenticate(pjsip_rx_data *rdata)
         ClientAuthSeq auths;
         Ice::StringSeq realms = getRealms(rdata);
 
-        HookResult result = (*iter)->getCredentials(mEndpointName, realms, auths);
+        HookResult result = (*iter)->respondToChallenge(mEndpointName, realms, auths);
         if (result.status == Succeeded)
         {
             std::vector<pjsip_cred_info> creds;

commit 929a1cff9ce65f6e5b18f3d0dc0cf761b3683f47
Merge: 5e0ba08 1094f86
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Oct 5 11:10:44 2011 -0500

    Merge branch 'master' into client-registration


commit 5e0ba080e24eaa73a77601f50733047fc4b4aff3
Merge: 83d4e07 030ca07
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 4 18:25:42 2011 -0500

    Merge branch 'master' into client-registration
    
    Conflicts:
    	src/Component.cpp


commit 83d4e0737de244e6c1a64e8dac6dd12c04f8ec96
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 4 17:34:42 2011 -0500

    Set the replica proxy in the endpoint factory after it has actually been initialized.

diff --git a/src/Component.cpp b/src/Component.cpp
index 405ee50..53974e8 100644
--- a/src/Component.cpp
+++ b/src/Component.cpp
@@ -529,8 +529,7 @@ void Component::createPrimaryServices()
                     getBackplaneAdapter(),
                     mPJSipManager,
                     getServiceLocator(),
-                    sipReplicationContext,
-                    getReplicaProxy()));
+                    sipReplicationContext));
         lg(Debug) << "Created SIP endpoint factory";
 
 	    // Locate the Routing Service so that we can do routing. This is done here so it can be
@@ -575,6 +574,10 @@ void Component::createBackplaneServices()
             getBackplaneAdapter()->addWithUUID(mConfigurationService));
         lg(Debug) << "Created SIP Configuration Implementation";
 
+        // We have to wait until this point to add the replica proxy to
+        // the endpoint factory because prior to this point the replica hasn't
+        // been created.
+        mEndpointFactory->setReplicaProxy(getReplicaProxy());
     }
     catch(const Ice::Exception& e)
     {
diff --git a/src/SipConfiguration.cpp b/src/SipConfiguration.cpp
index ab28759..a505fff 100644
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@ -1888,9 +1888,7 @@ void ConfigurationServiceImpl::setConfiguration(const AsteriskSCF::System::Confi
 
         void visitSipRegistrationGroup(const SipRegistrationGroupPtr& group)
         {
-            std::cout << "!!!!!!!!!!!!!! How's it going? !!!!!!!!!!!!" << std::endl;
             genericSet<SipRegistrationGroupPtr>(mImpl->getData(), group);
-            std::cout << "!!!!!!!!!!!!!! FINE? !!!!!!!!!!!!" << std::endl;
         }
         void visitIdentityGroup(const IdentityGroupPtr& group)
         {
diff --git a/src/SipEndpointFactory.cpp b/src/SipEndpointFactory.cpp
index 2be256d..4b8682c 100644
--- a/src/SipEndpointFactory.cpp
+++ b/src/SipEndpointFactory.cpp
@@ -20,6 +20,7 @@
 #include "SipEndpointFactory.h"
 
 using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::System::Component::V1;
 
 namespace
 {
@@ -77,5 +78,10 @@ void SipEndpointFactory::generateRoutingDestinations(AsteriskSCF::Core::Routing:
     }
 }
 
+void SipEndpointFactory::setReplicaProxy(const ReplicaPrx& replica)
+{
+    mReplica = replica;
+}
+
 }; // end SipSessionManager
 }; // end AsteriskSCF
diff --git a/src/SipEndpointFactory.h b/src/SipEndpointFactory.h
index fbefdd2..7d792b5 100644
--- a/src/SipEndpointFactory.h
+++ b/src/SipEndpointFactory.h
@@ -43,14 +43,12 @@ public:
             const Ice::ObjectAdapterPtr& backplaneAdapter,
             const PJSipManagerPtr& manager,
             const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
-            const SipReplicationContextPtr& replicationContext,
-            const AsteriskSCF::System::Component::V1::ReplicaPrx& replica) :
+            const SipReplicationContextPtr& replicationContext) :
         mAdapter(adapter),
         mBackplaneAdapter(backplaneAdapter),
         mManager(manager),
         mServiceLocator(serviceLocator),
-        mReplicationContext(replicationContext),
-        mReplica(replica){};
+        mReplicationContext(replicationContext) { }
 
     SipEndpointPtr createEndpoint(std::string);
 
@@ -60,6 +58,8 @@ public:
 
     void generateRoutingDestinations(AsteriskSCF::Core::Routing::V1::RegExSeq&);
 
+    void setReplicaProxy(const AsteriskSCF::System::Component::V1::ReplicaPrx& replica);
+
 private:
     /**
      * A pointer to the object adapter that endpoints will be added to.

commit d686a273766e9ee293d9050c9dbfc3748b62eeaf
Merge: b634595 ee3a950
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 4 10:55:45 2011 -0500

    Merge branch 'master' into client-registration

diff --cc src/SipEndpoint.cpp
index 3371038,2e59ea0..822fbe7
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@@ -327,75 -319,19 +338,86 @@@ void SipEndpoint::setSecureTransport(en
  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());
+     }
  }
  
 +class MatchRegistration
 +{
 +public:
 +    MatchRegistration(const std::string& aor)
 +        : mAOR(aor) { }
 +
 +    bool operator()(const SipClientRegistrationItemPtr& item)
 +    {
 +        return item->aor == mAOR;
 +    }
 +private:
 +    const std::string mAOR;
 +};
 +
 +void SipEndpoint::updateClientRegistrations(SipClientRegistrationItemSeq& items)
 +{
 +    lg(Debug) << "Updating client registrations for endpoint " << mImplPriv->mName;
 +
 +    //First step is to find registrations that exist for this endpoint but
 +    //that no longer appear in configuration. These must be KILLED!!!!!
 +    
 +    for (std::map<std::string, SipRegistrationClientPtr>::iterator iter = mImplPriv->mClientRegistrations.begin(); 
 +            iter != mImplPriv->mClientRegistrations.end(); )
 +    {
 +        SipClientRegistrationItemSeq::iterator toRemove = std::find_if(items.begin(), items.end(), MatchRegistration(iter->first));
 +        if (toRemove != items.end())
 +        {
 +            iter->second->destroy();
 +            mImplPriv->mClientRegistrations.erase(iter++);
 +        }
 +        else
 +        {
 +            ++iter;
 +        }
 +    }
 +
 +    //Next we go through the configured registrations and either update existing
 +    //client registrations or create new ones.
 +    for (SipClientRegistrationItemSeq::iterator item = items.begin();
 +            item != items.end(); ++item)
 +    {
 +        std::map<std::string, SipRegistrationClientPtr>::iterator iter =
 +            mImplPriv->mClientRegistrations.find((*item)->aor);
 +
 +        if (iter != mImplPriv->mClientRegistrations.end())
 +        {
 +            //Updating one that exists
 +            iter->second->updateRegistration(*item, mImplPriv->mManager->getEndpoint(), this);
 +        }
 +        else
 +        {
 +            //New one!
 +            mImplPriv->mClientRegistrations[(*item)->aor] =
 +                new SipRegistrationClient(
 +                        *item,
 +                        mImplPriv->mManager->getEndpoint(),
 +                        this,
 +                        mImplPriv->mManager->getClientRegistrationManager(),
 +                        mImplPriv->mReplicationContext,
 +                        mImplPriv->mBackplaneAdapter,
 +                        mImplPriv->mReplica);
 +
 +            mImplPriv->mClientRegistrations[(*item)->aor]->activate();
 +        }
 +    }
 +}
 +
  void SipEndpoint::setRTPOverIPv6(bool enabled)
  {
      mImplPriv->mConfig.sessionConfig.rtpOverIPv6 = enabled;

commit b6345950d2a4f1c61c986232ca0b225eb84f4296
Merge: 7cf2d58 c18c1c9
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Sep 14 15:24:20 2011 -0500

    Merge branch 'master' into client-registration
    
    Conflicts:
    	config/SipConfigurator.py
    	src/SipConfiguration.cpp
    	src/SipEndpoint.cpp

diff --cc config/SipConfigurator.py
index 623b975,bd9a383..ed353e2
--- a/config/SipConfigurator.py
+++ b/config/SipConfigurator.py
@@@ -19,10 -19,10 +19,10 @@@
  # Sip configurator
  
  # Bring in the common configuration infrastructure
- import Ice, Configurator, sys, os, traceback
+ import ConfigParser, Ice, Configurator, sys, os, traceback
  
  # Load our component specific configuration definitions
- Ice.loadSlice("--underscore -I" + os.environ["ASTSCF_HOME"] + " -I" + Ice.getSliceDir() + " --all ../slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice")
 -Ice.loadSlice("--underscore -I\"" + os.environ["ASTSCF_HOME"] + "\" -I" + Ice.getSliceDir() + " --all ../sip/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice")
++Ice.loadSlice("--underscore -I\"" + os.environ["ASTSCF_HOME"] + "\"" + " -I" + Ice.getSliceDir() + " --all ../slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice")
  import AsteriskSCF.Configuration.SipSessionManager.V1
  
  
@@@ -102,40 -102,21 +102,60 @@@ class SipSectionVisitors(Configurator.S
  
          self.groups.append(group)
  
 +    def visit_registration(self, config, section):
 +
 +        class RegistrationContactHandler:
 +            def __init__(self, config):
 +                self.config = config
 +            def get(self, section, option):
 +                setting = config.get(section, option)
 +                contacts = setting.split(',')
 +                ret = []
 +
 +                for contact in contacts:
 +                    uri, slash, expiration = contact.partition('/')
 +                    info = AsteriskSCF.Configuration.SipSessionManager.V1.ContactInfo()
 +                    info.contactURI = uri
 +                    info.expiration = int(expiration)
 +                    ret.append(info)
 +
 +                return ret
 +
 +        group = AsteriskSCF.Configuration.SipSessionManager.V1.SipRegistrationGroup()
 +        group.name = section
 +        group.configurationItems = {}
 +
 +        mapper = Configurator.OptionMapper()
 +
 +        item = AsteriskSCF.Configuration.SipSessionManager.V1.SipClientRegistrationItem()
 +
 +        mapper.map('aor', item, 'aor', 'registration', config.get, None)
 +        mapper.map('expiration', item, 'defaultExpiration', 'registration', config.getint, AsteriskSCF.Configuration.SipSessionManager.V1.DefaultExpiration)
 +        handler = RegistrationContactHandler(config)
 +        mapper.map('contacts', item, 'contacts', 'registration', handler.get, None)
 +
 +        for option in config.options(section):
 +            mapper.execute(group, section, option)
++
++        mapper.finish(group)
++
++        self.groups.append(group)
++
+     def visit_identity(self, config, section):
+         group = AsteriskSCF.Configuration.SipSessionManager.V1.IdentityGroup()
+         group.name = section
+         group.configurationItems = { }
+ 
+         mapper = Configurator.OptionMapper()
+ 
+         item =  AsteriskSCF.Configuration.SipSessionManager.V1.IdentityItem()
+ 	#      map(option, object, item, item_name, method, default)
+         mapper.map('name', item, 'name', 'id', config.get, None)
+         mapper.map('number', item, 'number', 'id', config.get, None)
+ 
+         for option in config.options(section):
+             mapper.execute(group, section, option)
+ 
          mapper.finish(group)
  
          self.groups.append(group)
@@@ -149,6 -130,22 +169,22 @@@
  
          mapper.map('routing', AsteriskSCF.Configuration.SipSessionManager.V1.SipRoutingItem(), 'routingServiceName', 'routingService', config.get, None)
  
 -	item = AsteriskSCF.Configuration.SipSessionManager.V1.IdentityItem()
 -	mapper.map('name', item, 'name', 'identity', config.get, None)
++        item = AsteriskSCF.Configuration.SipSessionManager.V1.IdentityItem()
++        mapper.map('name', item, 'name', 'identity', config.get, None)
+         mapper.map('number', item, 'number', 'identity', config.get, None)
+ 
+         # Alternate form of setting id is a list of references to IdentityGroup objects.
+ 	try:
+             ids = config.get(section, 'ids')
+             idList = ids.split(',')
+             for id in idList:
+                 item = AsteriskSCF.Configuration.SipSessionManager.V1.IdentityGroupRef()
+                 item.identityGroupName = id
+                 group.configurationItems[id] = item
+ 	except ConfigParser.NoOptionError:
+ 	    # It's legit to omit the ids option from this section.
+ 	    pass
+ 
          item = AsteriskSCF.Configuration.SipSessionManager.V1.SipSourceTransportAddressItem()
          mapper.map('sourcehost', item, 'host', 'sourceaddress', config.get, None)
          mapper.map('sourceport', item, 'port', 'sourceaddress', config.getint, 5060)
@@@ -302,8 -289,8 +338,10 @@@
              self.visit_transport_tls(config, section)
          elif config.get(section, 'type') == 'endpoint':
              self.visit_endpoint(config, section)
 +        elif config.get(section, 'type') == 'registration':
 +            self.visit_registration(config, section)
+         elif config.get(section, 'type') == 'identity':
+             self.visit_identity(config, section)
  
  # In order to do service locator based lookup we need to pass in a params object
  serviceLocatorParams = AsteriskSCF.Core.Discovery.V1.ServiceLocatorParams()
diff --cc src/SipConfiguration.cpp
index b1c1965,5c2bca9..ab28759
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@@ -148,63 -147,92 +149,148 @@@ public
  };
  typedef boost::shared_ptr<ConfigBase> ConfigBasePtr;
  
 +class RegistrationConfig : public ConfigBase, public boost::enable_shared_from_this<RegistrationConfig>
 +{
 +    class Visitor : public SipConfigurationItemVisitor
 +    {
 +    public:
 +        Visitor(const boost::shared_ptr<RegistrationConfig>& config)
 +            : mConfig(config) { }
 +
 +        void visitSipClientRegistrationItem(const SipClientRegistrationItemPtr& item)
 +        {
 +            mConfig->update(item);
 +        }
 +    private:
 +        boost::shared_ptr<RegistrationConfig> mConfig;
 +    };
 +
 +public:
 +
 +    RegistrationConfig(const SipRegistrationGroupPtr& group)
 +        : mGroup(group) { }
 +
 +    SipConfigurationItemVisitorPtr getVisitor()
 +    {
 +        return new Visitor(shared_from_this());
 +    }
 +
 +    void update(const SipClientRegistrationItemPtr& item)
 +    {
 +        boost::unique_lock<boost::shared_mutex> lock(mLock);
 +        mItem = item;
 +    }
 +
 +    SipRegistrationGroupPtr getTypedGroup() const
 +    {
 +        return mGroup;
 +    }
 +
 +    SipClientRegistrationItemPtr getClientRegistrationItem()
 +    {
 +        boost::shared_lock<boost::shared_mutex> lock(mLock);
 +        return mItem;
 +    }
 +
 +private:
 +
 +    boost::shared_mutex mLock;
 +
 +    SipClientRegistrationItemPtr mItem;
 +
 +    mutable SipRegistrationGroupPtr mGroup;
 +};
 +
 +typedef boost::shared_ptr<RegistrationConfig> RegistrationConfigPtr;
 +typedef std::map<std::string, RegistrationConfigPtr> RegistrationConfigMap;
 +
 +RegistrationConfigMap mRegistrationConfigMap;
 +
+ class IdentityConfig;
+ typedef boost::shared_ptr<IdentityConfig> IdentityConfigPtr;
+ typedef std::map<std::string, IdentityConfigPtr> IdentityConfigMap;
+ 
+ /**
+  * Configured Identity groups. This has to be accessible to 
+  * the EndpointConfigHelper. 
+  */
+ IdentityConfigMap mIdentityConfigMap;
+ 
+ /** 
+  * Identity groups allow identity to be defined separately from endpoints, 
+  * and for endpoints to have multiple identities. 
+  */
+ class IdentityConfig : public ConfigBase, public boost::enable_shared_from_this<IdentityConfig>
+ {
+     class Visitor : public SipConfigurationItemVisitor
+     {
+     public:
+         Visitor(const boost::shared_ptr<IdentityConfig>& config) :
+             mConfig(config)
+         {
+         }
+ 
+         void visitIdentityItem(const IdentityItemPtr& identityItem)
+         {
+             mConfig->update(identityItem);
+         }
+ 
+     private:
+ 
+         UpdateCommandList mUpdates;
+ 
+         boost::shared_ptr<IdentityConfig> mConfig;
+     };
+     
+ public:
+     /**
+      * Constructor implementation for this
+      */
+     IdentityConfig(const IdentityGroupPtr& group) :
+         mGroup(group)
+     {
+     };
+ 
+     /**
+      * Destructor implementation that shuts down the transport gracefully if we go away
+      */
+     ~IdentityConfig()
+     {
+     };
 -    
++
+     SipConfigurationItemVisitorPtr getVisitor()
+     {
+         return new Visitor(shared_from_this());
+     }
+ 
+     void update(const IdentityItemPtr& identityItem)
+     {
+          boost::unique_lock<boost::shared_mutex> lock(mLock);
+          mIdentityItem = identityItem;
+     }
+ 
+     IdentityGroupPtr getTypedGroup() const
+     {
+         return mGroup;
+     }
+ 
+     IdentityItemPtr getIdentityItem()
+     {
+         return mIdentityItem;
+     }
+ 
+ private:
+     boost::shared_mutex mLock;
+     
+     IdentityItemPtr mIdentityItem;
+ 
+     /**
+      * Configuration group itself.
+      */
+     mutable IdentityGroupPtr mGroup;
+ 
+ }; // class IdentityConfig
+ 
 -
  /**
   * A helper class and visitor for propogating configuration changes to the SIPEndPoint implementation.
   **/
@@@ -296,16 -323,20 +381,26 @@@ class EndpointConfigHelper : public boo
          {
              mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateDTMF, mConfig, dtmf));
          };
 +        void visitSipRegistrationGroupRef(const SipRegistrationGroupRefPtr& registration)
 +        {
 +            //Since this refers to a group that may not have been processed yet,
 +            //we defer it until later.
 +            mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateRegistration, mConfig, registration));
 +        }
  
+         void visitIdentityItem(const IdentityItemPtr& identity)
+         {
+             mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateIdentity, mConfig, identity));
+         };
+ 
+         void visitIdentityGroupRef(const IdentityGroupRefPtr& identityGroupRef)
+         {
+             mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateIdentityGroupRef, mConfig, identityGroupRef));
+         };
+ 
      private:
  
-         UpdateCommandList mUpdates;;
+         UpdateCommandList mUpdates;
          //
          // We keep a reference to the parent as the helper itself isn't held by the configuration
          // object or client.
@@@ -464,10 -503,10 +601,14 @@@ public
                  UpdateCommand command = *op;
                  command();
              }
 +            if (!mClientRegistrations.empty())
 +            {
 +                postProcesses.push_back(boost::bind(&EndpointConfigHelper::postUpdateRegistration, shared_from_this(), mClientRegistrations));
 +            }
+             if (mSessionOwnerId != 0)
+             {
+                 mEndpoint->addDefaultSessionCookie(mSessionOwnerId);
+             }
              if (updateSystem)
              {
                  mFactory->generateRoutingDestinations(destinations);
@@@ -485,7 -524,7 +626,8 @@@ private
      boost::shared_ptr<SipEndpointFactory> mFactory;
      LocatorRegistrySmartPrx mRegistry;
      string mRoutingId;
 +    Ice::StringSeq mClientRegistrations;
+     SessionOwnerIdPtr mSessionOwnerId;
  };
  
  /**
@@@ -912,7 -951,7 +1054,8 @@@ public
          mRoutingId(routingId), 
          mRoutingServiceLocatorRegistry(registry) 
      {
 +        mRegistrationConfigMap.clear();
+         mIdentityConfigMap.clear();
      }
  
      /**
@@@ -1154,16 -1197,26 +1315,36 @@@
          return 0;
      }
  
 +    const SipRegistrationGroupPtr getGroupFor(const SipRegistrationGroupPtr& group)
 +    {
 +        RegistrationConfigMap::const_iterator i;
 +        if (getItem(mRegistrationConfigMap, i, group->name))
 +        {
 +            return i->second->getTypedGroup();
 +        }
 +        return 0;
 +    }
 +
+     const IdentityGroupPtr getGroupFor(const IdentityGroupPtr& group)
+     {
+         IdentityConfigMap::const_iterator i;
+         if (getItem(mIdentityConfigMap, i, group->name))
+         {
+             return i->second->getTypedGroup();
+         }
+         return 0;
+     }
+ 
+     const IdentityGroupPtr getGroupByName(const std::string& groupName)
+     {
+         IdentityConfigMap::const_iterator i;
+         if (getItem(mIdentityConfigMap, i, groupName))
+         {
+             return i->second->getTypedGroup();
+         }
+         return 0;
+     }
+ 
  private:
  
      boost::shared_mutex mLock;
@@@ -1346,23 -1399,22 +1527,39 @@@
          return transport->getVisitor();
      }
  
 +    SipConfigurationItemVisitorPtr updateGroup(const SipRegistrationGroupPtr& group)
 +    {
 +        RegistrationConfigMap::const_iterator i;
 +        RegistrationConfigPtr registrationConfig;
 +        if (!getItem(mRegistrationConfigMap, i, group->name))
 +        {
 +            registrationConfig.reset(new RegistrationConfig(group));
 +            mRegistrationConfigMap.insert(make_pair(group->name, registrationConfig));
 +        }
 +        else
 +        {
 +            registrationConfig = i->second;
 +        }
 +
 +        return registrationConfig->getVisitor();
 +    }
 +
+     SipConfigurationItemVisitorPtr updateGroup(const IdentityGroupPtr& group)
+     {
+         IdentityConfigMap::const_iterator i;
+         IdentityConfigPtr identityConfig;
+         if (!getItem(mIdentityConfigMap, i, group->name))
+         {
+             identityConfig.reset(new IdentityConfig(group));
+             mIdentityConfigMap.insert(make_pair(group->name, identityConfig));
+         }
+         else
+         {
+             identityConfig = i->second;
+         }
+         return identityConfig->getVisitor();
+     }
+ 
      template <class T>
      void copyTemplates(ConfigurationGroupSeq& groups, const T& items)
      {
@@@ -1501,11 -1553,11 +1698,16 @@@ ConfigurationGroupSeq ConfigurationServ
              getGeneric<SipEndpointGroupPtr>(mImpl->getData(), group, mGroups);
  	};
  
 +    void visitSipRegistrationGroup(const SipRegistrationGroupPtr& group)
 +    {
 +        getGeneric<SipRegistrationGroupPtr>(mImpl->getData(), group, mGroups);
 +    }
 +
+         void visitIdentityGroup(const IdentityGroupPtr& group)
+         {
+             getGeneric<IdentityGroupPtr>(mImpl->getData(), group, mGroups);
+         }
+ 
  	ConfigurationServiceImplPtr mImpl;
  	ConfigurationGroupSeq& mGroups;
      };
@@@ -1579,10 -1631,10 +1781,14 @@@ ConfigurationGroupSeq ConfigurationServ
              genericGetAll<SipEndpointGroupPtr>(mImpl->getData(), group, mGroups);
  	};
  
 +    void visitSipRegistrationGroup(const SipRegistrationGroupPtr& group)
 +    {
 +        genericGetAll<SipRegistrationGroupPtr>(mImpl->getData(), group, mGroups);
 +    }
+         void visitIdentityGroup(const IdentityGroupPtr& group)
+         {
+             genericGetAll<IdentityGroupPtr>(mImpl->getData(), group, mGroups);
+         }
  
  	ConfigurationServiceImplPtr mImpl;
  	ConfigurationGroupSeq& mGroups;
@@@ -1680,9 -1722,9 +1886,15 @@@ void ConfigurationServiceImpl::setConfi
              genericSet<SipEndpointGroupPtr>(mImpl->getData(), group);
          };
  
 +        void visitSipRegistrationGroup(const SipRegistrationGroupPtr& group)
 +        {
++            std::cout << "!!!!!!!!!!!!!! How's it going? !!!!!!!!!!!!" << std::endl;
 +            genericSet<SipRegistrationGroupPtr>(mImpl->getData(), group);
++            std::cout << "!!!!!!!!!!!!!! FINE? !!!!!!!!!!!!" << std::endl;
++        }
+         void visitIdentityGroup(const IdentityGroupPtr& group)
+         {
+             genericSet<IdentityGroupPtr>(mImpl->getData(), group);
          }
  	
  	ConfigurationServiceImplPtr mImpl;
@@@ -1745,10 -1784,11 +1957,15 @@@ void ConfigurationServiceImpl::removeCo
              mImpl->getData()->removeFromGroup(group);
          };
  
 +        void visitSipRegistrationGroup(const SipRegistrationGroupPtr& group)
 +        {
 +            mImpl->getData()->removeFromGroup(group);
 +        }
+         void visitIdentityGroup(const IdentityGroupPtr& group)
+         {
+             mImpl->getData()->removeFromGroup(group);
+         }
+ 
      private:
  	ConfigurationServiceImplPtr mImpl;
      };
@@@ -1807,10 -1845,10 +2024,14 @@@ void ConfigurationServiceImpl::removeCo
              mImpl->getData()->remove(group);
          };
  
 +        void visitSipRegistrationGroup(const SipRegistrationGroupPtr& group)
 +        {
 +            mImpl->getData()->remove(group);
 +        }
+         void visitIdentityGroup(const IdentityGroupPtr& group)
+         {
+             mImpl->getData()->remove(group);
+         }
  
  	ConfigurationServiceImplPtr mImpl;
      };
diff --cc src/SipEndpoint.cpp
index 0dc9c83,effd1f4..3371038
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@@ -16,7 -16,7 +16,8 @@@
  #include "PJSipManager.h"
  #include "SipEndpointFactory.h"
  #include "SipSession.h"
 +#include "SipClientRegistration.h"
+ 
  #include <Ice/Ice.h>
  #include <IceUtil/UUID.h>
  
@@@ -180,24 -178,14 +181,24 @@@ public
      /**
       * Constructor for the SipEndpointImplPriv class.
       */
 -    SipEndpointImplPriv(const Ice::ObjectAdapterPtr& adapter, const boost::shared_ptr<SipEndpointFactory>& factory,
 -            const std::string& name, const PJSipManagerPtr& manager,
 +    SipEndpointImplPriv(const Ice::ObjectAdapterPtr& adapter,
 +            const Ice::ObjectAdapterPtr& backplaneAdapter,
 +            const boost::shared_ptr<SipEndpointFactory>& factory,
 +            const std::string& name,
 +            const PJSipManagerPtr& manager,
              const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
 -            const SipReplicationContextPtr& replicationContext) :
 -        mName(name), mAdapter(adapter), mEndpointFactory(factory), mManager(manager), mServiceLocator(serviceLocator),
 +            const SipReplicationContextPtr& replicationContext,
 +            const ReplicaPrx& replica) :
 +        mName(name),
 +        mAdapter(adapter),
 +        mBackplaneAdapter(backplaneAdapter),
 +        mEndpointFactory(factory),
 +        mManager(manager),
 +        mServiceLocator(serviceLocator),
          mReplicationContext(replicationContext),
 +        mReplica(replica),
          mDefaultListeners(new AsteriskSCF::Collections::ProxySet<SessionListenerPrx>(adapter, lg, "Default Session Listeners")),
-         mDefaultSessionCookies(new AsteriskSCF::Collections::HandleSet<SessionCookiePtr>(lg, "Default Cookies"))
+         mDefaultSessionCookies(new AsteriskSCF::Collections::HandleSet<AsteriskSCF::SessionCommunications::V1::SessionCookiePtr>(lg, "Default Cookies"))
      {
      };
      
@@@ -250,11 -237,8 +251,11 @@@
  
      AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx mServiceLocator;
      SipReplicationContextPtr mReplicationContext;
 +    ReplicaPrx mReplica;
      AsteriskSCF::Collections::ProxySet<SessionListenerPrx>::SetPtr mDefaultListeners;
-     AsteriskSCF::Collections::HandleSet<SessionCookiePtr>::SetPtr mDefaultSessionCookies;
 +
 +    std::map<std::string, SipRegistrationClientPtr> mClientRegistrations;
+     AsteriskSCF::Collections::HandleSet<AsteriskSCF::SessionCommunications::V1::SessionCookiePtr>::SetPtr mDefaultSessionCookies;
  };
  
  SipEndpoint::SipEndpoint(const Ice::ObjectAdapterPtr& adapter, 

commit 7cf2d5832e61940212efbd808a54a1135ace49a6
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Sep 12 15:07:44 2011 -0500

    Adjust for configuration issue that had not been experienced previously.
    
    If the AOR changes in a registration group, we have to unregister and then
    reregister with the new AOR.
    
    This is pretty much done at this point, but I'm now seeing a NULL handle
    exception in the configurator that I'd like to track down if you please.

diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index 76daac0..ba624f7 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -165,12 +165,28 @@ SipRegistrationClient::SipRegistrationClient(
         const Ice::ObjectAdapterPtr& backplaneAdapter,
         const ReplicaPrx& replica)
     : mEndpointName(sipEndpoint->getName()),
+    mAOR(confItem->aor),
     mManager(manager),
     mTimer(new IceUtil::Timer()),
     mReplicationContext(replicationContext),
     mBackplaneAdapter(backplaneAdapter),
     mReplica(replica)
 {
+    createPJSIPRegistration(confItem, pjEndpoint, sipEndpoint);
+}
+
+void SipRegistrationClient::activate()
+{
+    ReplicaListenerPtr listener(new ClientRegistrationReplicaListener(this));
+    mReplicaListenerProxy = ReplicaListenerPrx::uncheckedCast(mBackplaneAdapter->addWithUUID(listener));
+    mReplica->addListener(mReplicaListenerProxy);
+}
+
+void SipRegistrationClient::createPJSIPRegistration(
+        const SipClientRegistrationItemPtr& confItem,
+        pjsip_endpoint *pjEndpoint,
+        const SipEndpointPtr& sipEndpoint)
+{
     pjsip_regc_create(pjEndpoint, this, regCallback, &mReg);
 
     std::vector<pj_str_t> pjContacts;
@@ -204,17 +220,19 @@ SipRegistrationClient::SipRegistrationClient(
     setContacts(confItem->contacts);
 }
 
-void SipRegistrationClient::activate()
-{
-    ReplicaListenerPtr listener(new ClientRegistrationReplicaListener(this));
-    mReplicaListenerProxy = ReplicaListenerPrx::uncheckedCast(mBackplaneAdapter->addWithUUID(listener));
-    mReplica->addListener(mReplicaListenerProxy);
-}
-
 void SipRegistrationClient::destroy()
 {
     mReplica->removeListener(mReplicaListenerProxy);
     mBackplaneAdapter->remove(mReplicaListenerProxy->ice_getIdentity());
+    destroyPJSIPRegistration();
+}
+
+void SipRegistrationClient::destroyPJSIPRegistration()
+{
+    pjsip_tx_data *tdata;
+    pjsip_regc_unregister(mReg, &tdata);
+    pjsip_regc_send(mReg, tdata);
+
     pjsip_regc_destroy(mReg);
 }
 
@@ -229,6 +247,26 @@ void SipRegistrationClient::setContacts(const ContactInfoSeq& contacts)
     sendRegister();
 }
 
+void SipRegistrationClient::updateRegistration(
+        const SipClientRegistrationItemPtr& confItem,
+        pjsip_endpoint *pjEndpoint,
+        const SipEndpointPtr& sipEndpoint)
+{
+    if (confItem->aor != mAOR)
+    {
+        //If the AOR is new, then we have to kill off the
+        //current registration and create a new one.
+        destroyPJSIPRegistration();
+        createPJSIPRegistration(confItem, pjEndpoint, sipEndpoint);
+    }
+    else
+    {
+        //The AOR hasn't changed, so all we must do is to update
+        //the contacts bound for this registration
+        setContacts(confItem->contacts);
+    }
+}
+
 void SipRegistrationClient::sendRegister()
 {
     //Replicas just hold onto the necessary information. They don't actually
diff --git a/src/SipClientRegistration.h b/src/SipClientRegistration.h
index df09fde..035d95c 100644
--- a/src/SipClientRegistration.h
+++ b/src/SipClientRegistration.h
@@ -123,11 +123,43 @@ public:
     void activate();
 
     /**
+     * Create the PJSIP client registration structure
+     *
+     * This will result in setContacts being called, which thus implies
+     * that a REGISTER will be sent out.
+     */
+    void createPJSIPRegistration(
+            const AsteriskSCF::Configuration::SipSessionManager::V1::SipClientRegistrationItemPtr& confItem,
+            pjsip_endpoint* pjEndpoint,
+            const SipEndpointPtr& sipEndpoint);
+
+    /**
      * Remove servants from object adapter and remove replica listeners.
      */
     void destroy();
 
     /**
+     * Kill the PJSIP registration.
+     * 
+     * This both unregisters all contacts currently bound and targets the PJSIP client
+     * registration structure for destruction.
+     */
+    void destroyPJSIPRegistration();
+
+    void updateRegistration(
+            const AsteriskSCF::Configuration::SipSessionManager::V1::SipClientRegistrationItemPtr& confItem,
+            pjsip_endpoint *pjEndpoint,
+            const SipEndpointPtr& sipEndpoint);
+
+    /**
+     * Callback from PJSIP to handle the response from a REGISTER attempt
+     *
+     * @param param Data pertaining to the REGISTER response.
+     */
+    void handleRegisterResponse(pjsip_regc_cbparam *param);
+private:
+
+    /**
      * Set the contacts to bind to the AOR for this registration.
      *
      * Calling this will result in a REGISTER being sent out. If contacts
@@ -138,13 +170,6 @@ public:
      */
     void setContacts(const AsteriskSCF::Configuration::SipSessionManager::V1::ContactInfoSeq& contacts);
 
-    /**
-     * Callback from PJSIP to handle the response from a REGISTER attempt
-     *
-     * @param param Data pertaining to the REGISTER response.
-     */
-    void handleRegisterResponse(pjsip_regc_cbparam *param);
-private:
 
     /**
      * Send a REGISTER
@@ -177,6 +202,11 @@ private:
     const std::string mEndpointName;
 
     /**
+     * The AOR for which this client registration exists.
+     */
+    const std::string mAOR;
+
+    /**
      * The contact headers to place in REGISTER messages.
      */
     AsteriskSCF::Configuration::SipSessionManager::V1::ContactInfoSeq mContacts;
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index 4569e4f..0dc9c83 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -375,7 +375,7 @@ void SipEndpoint::updateClientRegistrations(SipClientRegistrationItemSeq& items)
         if (iter != mImplPriv->mClientRegistrations.end())
         {
             //Updating one that exists
-            iter->second->setContacts((*item)->contacts);
+            iter->second->updateRegistration(*item, mImplPriv->mManager->getEndpoint(), this);
         }
         else
         {

commit d199b12db578f5ac2c51839f838d63f31cc682b7
Author: Mark Michelson <mmichelson at digium.com>
Date:   Sun Sep 11 14:56:24 2011 -0500

    Remove unused function and add a needed return statement.

diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index 04b95aa..76daac0 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -77,20 +77,6 @@ struct MakeContact
     pjsip_regc *mReg;
 };
 
-/**
- * Add new items to a vector, and remove duplicates.
- * This is formulated so that if duplicates are added,
- * the newer version will replace the old version in
- * the vector
- */
-template <class T>
-void unique_add(std::vector<T>& container, const std::vector<T>& stuffToAdd)
-{
-    container.insert(container.begin(), stuffToAdd.begin(), stuffToAdd.end());
-    std::stable_sort(container.begin(), container.end());
-    container.erase(std::unique(container.begin(), container.end()), container.end());
-}
-
 } // end anonymous namespace
 
 namespace AsteriskSCF
@@ -370,6 +356,7 @@ void SipRegistrationClient::authenticate(pjsip_rx_data *rdata)
                 pjsip_regc_set_credentials(mReg, creds.size(), &creds.front());
                 sendRegister();
             }
+            return;
         }
     }
 }

commit 132df0b6a986086f4ec94858e1d31317e90ba0da
Author: Mark Michelson <mmichelson at digium.com>
Date:   Sun Sep 11 14:45:48 2011 -0500

    Add some documentation.

diff --git a/src/SipClientRegistration.h b/src/SipClientRegistration.h
index 9a17683..df09fde 100644
--- a/src/SipClientRegistration.h
+++ b/src/SipClientRegistration.h
@@ -44,13 +44,30 @@ class SipRegistrationClientManager : public IceUtil::Shared
 public:
     SipRegistrationClientManager();
 
+    /**
+     * Get a list of registered authentication hooks
+     */
     AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookSeq getAuthHooks();
 
+    /**
+     * Add an authentication hook
+     */
     void addAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx& hook);
+
+    /**
+     * Remove an authentication hook
+     */
     void removeAuthHook(const AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookPrx& hook);
+
+    /**
+     * Remove all authentication hooks
+     */
     void clearAuthHooks();
     
 private:
+    /**
+     * The registered auth hooks
+     */
     AsteriskSCF::SIP::ExtensionPoint::V1::AuthHookSeq mAuthHooks;
     boost::shared_mutex mLock;
 };
@@ -68,6 +85,27 @@ class ClientRegistrationReplicaListener;
 class SipRegistrationClient : public IceUtil::Shared
 {
 public:
+    /**
+     * Constructor
+     *
+     * @param confItem The configuration item for the registration in question. This contains data
+     * such as the list of contacts, the AOR, and the default expiration for the registration.
+     *
+     * @param pjEndpoint The pjsip_endpoint from which REGISTERs will originate
+     *
+     * @param sipEndpoint The SIP endpoint for which this registration corresponds
+     *
+     * @param manager The registration client manager, used to get data needed for all registrations, such as
+     * authentication hooks.
+     *
+     * @param replicationContext Replication context. Used to determine whether the registration is operating
+     * in active or standby mode.
+     *
+     * @param backplaneAdapter Object adapter onto which servants are added. We use the backplane adapter because
+     * we create replica listeners, and these need to use the backplane adapter.
+     *
+     * @param replica The replica interface on which to add listeners we create.
+     */
     SipRegistrationClient(
             const AsteriskSCF::Configuration::SipSessionManager::V1::SipClientRegistrationItemPtr& confItem,
             pjsip_endpoint* pjEndpoint,
@@ -79,36 +117,117 @@ public:
 
     ~SipRegistrationClient();
 
+    /**
+     * Add servants to object adapter and create replica listeners.
+     */
     void activate();
 
+    /**
+     * Remove servants from object adapter and remove replica listeners.
+     */
     void destroy();
 
+    /**
+     * Set the contacts to bind to the AOR for this registration.
+     *
+     * Calling this will result in a REGISTER being sent out. If contacts
+     * were previously present but are no longer present in the new list,
+     * then they will automatically be unregistered.
+     *
+     * @param contacts The list of contacts to put in the outbound REGISTER.
+     */
     void setContacts(const AsteriskSCF::Configuration::SipSessionManager::V1::ContactInfoSeq& contacts);
 
+    /**
+     * Callback from PJSIP to handle the response from a REGISTER attempt
+     *
+     * @param param Data pertaining to the REGISTER response.
+     */
     void handleRegisterResponse(pjsip_regc_cbparam *param);
 private:
+
+    /**
+     * Send a REGISTER
+     */
     void sendRegister();
 
+    /**
+     * When authenticating, get the realms from the WWW-Authenticate and Proxy-Authenticate
+     * headers.
+     *
+     * @param rdata The response data from which authentication headers are pulled.
+     */
     Ice::StringSeq getRealms(pjsip_rx_data *rdata);
 
+    /**
+     * Called when a 401/407 response is received as a response to a REGISTER.
+     *
+     * This will call out to authentication hooks in order to determine credentials
+     * to send. If credentials are provided, then we will send another REGISTER with
+     * the provided credentials.
+     *
+     * @param rdata Information pertaining to the REGISTER response.
+     */
     void authenticate(pjsip_rx_data *rdata);
 
+    /**
+     * The name of the SIP endpoint. This is kept mainly for debugging and identification
+     * purposes
+     */
     const std::string mEndpointName;
+
+    /**
+     * The contact headers to place in REGISTER messages.
+     */
     AsteriskSCF::Configuration::SipSessionManager::V1::ContactInfoSeq mContacts;
+    
+    /**
+     * The central point from which to get information such as authentication hooks.
+     */
     SipRegistrationClientManagerPtr mManager;
+
+    /**
+     * The PJSIP client registration structure.
+     */
     pjsip_regc* mReg;
 
+    /**
+     * A timer task used when a REGISTER fails, and the response contains
+     * a Retry-After header. The task simply resends the REGISTER
+     */
     IceUtil::TimerTaskPtr mTimerTask;
+
+    /**
+     * Timer used to schedule mTimerTask
+     */
     IceUtil::TimerPtr mTimer;
 
+    /**
+     * Replication context. Used to determine active or standby status.
+     */
     SipReplicationContextPtr mReplicationContext;
 
+    /**
+     * Adapter onto which replica listener is added
+     */
     Ice::ObjectAdapterPtr mBackplaneAdapter;
 
+    /**
+     * Replica that we add our listener to
+     */
     AsteriskSCF::System::Component::V1::ReplicaPrx mReplica;
 
+    /**
+     * Replica listener. This is used to sense when the component moves
+     * from standby to active mode. When this happens, a REGISTER will be
+     * sent out.
+     */
     AsteriskSCF::System::Component::V1::ReplicaListenerPrx mReplicaListenerProxy;
 
+    /**
+     * These classes are declared friends so they will have access to
+     * sendRegister()
+     */
     friend class RescheduleRegister;
     friend class ClientRegistrationReplicaListener;
 };

commit 5b568aeb3078b9f94a36a5672f793664414ee3b1
Author: Mark Michelson <mmichelson at digium.com>
Date:   Sun Sep 11 13:13:48 2011 -0500

    Fix a couple of logical errors in configuration
    
    * Continue instead of returning in for loop when problems occur.
    * Be sure to call updateClientRegistrations() even if the list is empty.

diff --git a/src/SipConfiguration.cpp b/src/SipConfiguration.cpp
index 440fd9f..b1c1965 100644
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@ -430,7 +430,7 @@ public:
             if (entry == mRegistrationConfigMap.end())
             {
                 //Group doesn't exist.
-                return;
+                continue;
             }
 
             SipClientRegistrationItemPtr item = entry->second->getClientRegistrationItem();
@@ -438,15 +438,12 @@ public:
             if (item == 0)
             {
                 //Group doesn't have a configuration item.
-                return;
+                continue;
             }
 
             regItems.push_back(item);
         }
-        if (!regItems.empty())
-        {
-            mEndpoint->updateClientRegistrations(regItems);
-        }
+        mEndpoint->updateClientRegistrations(regItems);
     }
 
     void updated(const UpdateCommandList& updates)

commit 626702b93dea964bdb35251fa6b8123c5236cd16
Author: Mark Michelson <mmichelson at digium.com>
Date:   Sun Sep 11 12:52:26 2011 -0500

    Allow post processing to run on remove operations.

diff --git a/src/SipConfiguration.cpp b/src/SipConfiguration.cpp
index 047c7f5..440fd9f 100644
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@ -1758,10 +1758,12 @@ void ConfigurationServiceImpl::removeConfigurationItems(
     
     SipConfigurationGroupVisitorPtr v = new GroupsVisitor(this);
     
+    postProcesses.clear();
     for (ConfigurationGroupSeq::const_iterator group = groups.begin(); group != groups.end(); ++group)
     {
 	(*group)->visit(v);
     }
+    runPostProcessing();
 }
 
 void ConfigurationServiceImpl::removeConfigurationGroups(
@@ -1818,10 +1820,12 @@ void ConfigurationServiceImpl::removeConfigurationGroups(
     
     SipConfigurationGroupVisitorPtr v = new Visitor(this);
     
+    postProcesses.clear();
     for (ConfigurationGroupSeq::const_iterator group = groups.begin(); group != groups.end(); ++group)
     {
 	(*group)->visit(v);
     }
+    runPostProcessing();
 }
 };
 };

commit 780b003c24252625f2a835cb493416a4e515bc42
Author: Mark Michelson <mmichelson at digium.com>
Date:   Sun Sep 11 12:48:40 2011 -0500

    Switch from an "add/remove" model for contacts to a "set" method.
    
    This reflects the way PJSIP works more betterly.

diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index c7d7628..04b95aa 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -215,7 +215,7 @@ SipRegistrationClient::SipRegistrationClient(
             confItem->defaultExpiration
             );
 
-    addContacts(confItem->contacts);
+    setContacts(confItem->contacts);
 }
 
 void SipRegistrationClient::activate()
@@ -236,20 +236,9 @@ SipRegistrationClient::~SipRegistrationClient()
 {
 }
 
-void SipRegistrationClient::addContacts(const ContactInfoSeq& contacts)
+void SipRegistrationClient::setContacts(const ContactInfoSeq& contacts)
 {
-    unique_add(mContacts, contacts);
-
-    sendRegister();
-}
-
-void SipRegistrationClient::removeContacts(const Ice::StringSeq& contacts)
-{
-    for (Ice::StringSeq::const_iterator iter = contacts.begin();
-            iter != contacts.end(); ++iter)
-    {
-        mContacts.erase(std::find_if(mContacts.begin(), mContacts.end(), EqualContacts(*iter)));
-    }
+    mContacts = contacts;
 
     sendRegister();
 }
diff --git a/src/SipClientRegistration.h b/src/SipClientRegistration.h
index ca5581a..9a17683 100644
--- a/src/SipClientRegistration.h
+++ b/src/SipClientRegistration.h
@@ -83,9 +83,7 @@ public:
 
     void destroy();
 
-    void addContacts(const AsteriskSCF::Configuration::SipSessionManager::V1::ContactInfoSeq& contacts);
-
-    void removeContacts(const Ice::StringSeq& contacts);
+    void setContacts(const AsteriskSCF::Configuration::SipSessionManager::V1::ContactInfoSeq& contacts);
 
     void handleRegisterResponse(pjsip_regc_cbparam *param);
 private:
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index c995952..4569e4f 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -375,7 +375,7 @@ void SipEndpoint::updateClientRegistrations(SipClientRegistrationItemSeq& items)
         if (iter != mImplPriv->mClientRegistrations.end())
         {
             //Updating one that exists
-            iter->second->addContacts((*item)->contacts);
+            iter->second->setContacts((*item)->contacts);
         }
         else
         {

commit 6e3818ecf1213e1918454a129d1b49adcab0fc29
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Sep 9 16:19:54 2011 -0500

    Get activation and destruction in place.

diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index a7e9e1a..c7d7628 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -26,6 +26,7 @@ Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
 using namespace AsteriskSCF::SipSessionManager;
 using namespace AsteriskSCF::System::Hook::V1;
 using namespace AsteriskSCF::Configuration::SipSessionManager::V1;
+using namespace AsteriskSCF::System::Component::V1;
 
 void regCallback(struct pjsip_regc_cbparam *param)
 {
@@ -114,6 +115,28 @@ private:
 
 typedef IceUtil::Handle<RescheduleRegister> RescheduleRegisterPtr;
 
+class ClientRegistrationReplicaListener : public AsteriskSCF::System::Component::V1::ReplicaListener
+{
+public:
+    ClientRegistrationReplicaListener(const SipRegistrationClientPtr& client)
+        : mClient(client) { }
+
+    void activated(const ReplicaPrx&, const Ice::Current&)
+    {
+        mClient->sendRegister();
+    }
+
+    void onStandby(const ReplicaPrx&, const Ice::Current&)
+    {
+    }
+    void heartbeat(const ReplicaPrx&, bool, const Ice::Current&)
+    {
+    }
+
+private:
+    SipRegistrationClientPtr mClient;
+};
+
 using namespace AsteriskSCF::SIP::ExtensionPoint::V1;
 
 SipRegistrationClientManager::SipRegistrationClientManager()
@@ -154,7 +177,7 @@ SipRegistrationClient::SipRegistrationClient(
         const SipRegistrationClientManagerPtr& manager,
         const SipReplicationContextPtr& replicationContext,
         const Ice::ObjectAdapterPtr& backplaneAdapter,
-        const AsteriskSCF::System::Component::V1::ReplicaPrx& replica)
+        const ReplicaPrx& replica)
     : mEndpointName(sipEndpoint->getName()),
     mManager(manager),
     mTimer(new IceUtil::Timer()),
@@ -195,11 +218,24 @@ SipRegistrationClient::SipRegistrationClient(
     addContacts(confItem->contacts);
 }
 
-SipRegistrationClient::~SipRegistrationClient()
+void SipRegistrationClient::activate()
+{
+    ReplicaListenerPtr listener(new ClientRegistrationReplicaListener(this));
+    mReplicaListenerProxy = ReplicaListenerPrx::uncheckedCast(mBackplaneAdapter->addWithUUID(listener));
+    mReplica->addListener(mReplicaListenerProxy);
+}
+
+void SipRegistrationClient::destroy()
 {
+    mReplica->removeListener(mReplicaListenerProxy);
+    mBackplaneAdapter->remove(mReplicaListenerProxy->ice_getIdentity());
     pjsip_regc_destroy(mReg);
 }
 
+SipRegistrationClient::~SipRegistrationClient()
+{
+}
+
 void SipRegistrationClient::addContacts(const ContactInfoSeq& contacts)
 {
     unique_add(mContacts, contacts);
diff --git a/src/SipClientRegistration.h b/src/SipClientRegistration.h
index ce8745e..ca5581a 100644
--- a/src/SipClientRegistration.h
+++ b/src/SipClientRegistration.h
@@ -58,6 +58,7 @@ private:
 typedef IceUtil::Handle<SipRegistrationClientManager> SipRegistrationClientManagerPtr;
 
 class RescheduleRegister;
+class ClientRegistrationReplicaListener;
 
 /**
  * One of these exists per endpoint.
@@ -78,6 +79,10 @@ public:
 
     ~SipRegistrationClient();
 
+    void activate();
+
+    void destroy();
+
     void addContacts(const AsteriskSCF::Configuration::SipSessionManager::V1::ContactInfoSeq& contacts);
 
     void removeContacts(const Ice::StringSeq& contacts);
@@ -104,7 +109,10 @@ private:
 
     AsteriskSCF::System::Component::V1::ReplicaPrx mReplica;
 
+    AsteriskSCF::System::Component::V1::ReplicaListenerPrx mReplicaListenerProxy;
+
     friend class RescheduleRegister;
+    friend class ClientRegistrationReplicaListener;
 };
 
 typedef IceUtil::Handle<SipRegistrationClient> SipRegistrationClientPtr;
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index bf953aa..c995952 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -328,9 +328,44 @@ void SipEndpoint::setDTMFMethod(AsteriskSCF::Configuration::SipSessionManager::V
     mImplPriv->mConfig.sessionConfig.dtmf = dtmf;
 }
 
+class MatchRegistration
+{
+public:
+    MatchRegistration(const std::string& aor)
+        : mAOR(aor) { }
+
+    bool operator()(const SipClientRegistrationItemPtr& item)
+    {
+        return item->aor == mAOR;
+    }
+private:
+    const std::string mAOR;
+};
+
 void SipEndpoint::updateClientRegistrations(SipClientRegistrationItemSeq& items)
 {
     lg(Debug) << "Updating client registrations for endpoint " << mImplPriv->mName;
+
+    //First step is to find registrations that exist for this endpoint but
+    //that no longer appear in configuration. These must be KILLED!!!!!
+    
+    for (std::map<std::string, SipRegistrationClientPtr>::iterator iter = mImplPriv->mClientRegistrations.begin(); 
+            iter != mImplPriv->mClientRegistrations.end(); )
+    {
+        SipClientRegistrationItemSeq::iterator toRemove = std::find_if(items.begin(), items.end(), MatchRegistration(iter->first));
+        if (toRemove != items.end())
+        {
+            iter->second->destroy();
+            mImplPriv->mClientRegistrations.erase(iter++);
+        }
+        else
+        {
+            ++iter;
+        }
+    }
+
+    //Next we go through the configured registrations and either update existing
+    //client registrations or create new ones.
     for (SipClientRegistrationItemSeq::iterator item = items.begin();
             item != items.end(); ++item)
     {
@@ -354,6 +389,8 @@ void SipEndpoint::updateClientRegistrations(SipClientRegistrationItemSeq& items)
                         mImplPriv->mReplicationContext,
                         mImplPriv->mBackplaneAdapter,
                         mImplPriv->mReplica);
+
+            mImplPriv->mClientRegistrations[(*item)->aor]->activate();
         }
     }
 }

commit 87a71b84f090c02df4091b65fb42f65dbf16e6d5
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Sep 9 12:26:14 2011 -0500

    Get the necessary pieces of stuff to the client registration for replication support.

diff --git a/src/Component.cpp b/src/Component.cpp
index ca64fe9..405ee50 100644
--- a/src/Component.cpp
+++ b/src/Component.cpp
@@ -524,8 +524,13 @@ void Component::createPrimaryServices()
         mEventPublisher.reset(new SipSessionManagerEventPublisher(getServiceAdapter()));
         lg(Debug) << "Created SIP Session Manager event publisher";
 
-        mEndpointFactory.reset(new SipEndpointFactory(getServiceAdapter(), 
-               mPJSipManager, getServiceLocator(), sipReplicationContext));
+        mEndpointFactory.reset(new SipEndpointFactory(
+                    getServiceAdapter(),
+                    getBackplaneAdapter(),
+                    mPJSipManager,
+                    getServiceLocator(),
+                    sipReplicationContext,
+                    getReplicaProxy()));
         lg(Debug) << "Created SIP endpoint factory";
 
 	    // Locate the Routing Service so that we can do routing. This is done here so it can be
diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index e389ff7..a7e9e1a 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -66,7 +66,6 @@ struct MakeContact
 
     pj_str_t operator() (const ContactInfo& info)
     {
-        lg(Debug) << "Making contact from " << info.contactURI << " and " << info.expiration;
         std::stringstream str;
         str << info.contactURI << ";expires=" << info.expiration;
         pj_str_t ret;
@@ -152,8 +151,16 @@ SipRegistrationClient::SipRegistrationClient(
         const SipClientRegistrationItemPtr& confItem,
         pjsip_endpoint* pjEndpoint,
         const SipEndpointPtr& sipEndpoint,
-        const SipRegistrationClientManagerPtr manager)
-    : mEndpointName(sipEndpoint->getName()), mManager(manager), mTimer(new IceUtil::Timer())
+        const SipRegistrationClientManagerPtr& manager,
+        const SipReplicationContextPtr& replicationContext,
+        const Ice::ObjectAdapterPtr& backplaneAdapter,
+        const AsteriskSCF::System::Component::V1::ReplicaPrx& replica)
+    : mEndpointName(sipEndpoint->getName()),
+    mManager(manager),
+    mTimer(new IceUtil::Timer()),
+    mReplicationContext(replicationContext),
+    mBackplaneAdapter(backplaneAdapter),
+    mReplica(replica)
 {
     pjsip_regc_create(pjEndpoint, this, regCallback, &mReg);
 
@@ -213,6 +220,12 @@ void SipRegistrationClient::removeContacts(const Ice::StringSeq& contacts)
 
 void SipRegistrationClient::sendRegister()
 {
+    //Replicas just hold onto the necessary information. They don't actually
+    //send registrations until they become active.
+    if (!mReplicationContext->isActive())
+    {
+        return;
+    }
 
     //There's a decent chance that there's no actual
     //scheduled task, but in case there is, we need
@@ -243,6 +256,7 @@ void SipRegistrationClient::handleRegisterResponse(pjsip_regc_cbparam *param)
         break;
     case 200:
         //This is a success!
+        lg(Debug) << "Endpoint " << mEndpointName << " registered successfully.";
         break;
     case 401:
     case 407:
diff --git a/src/SipClientRegistration.h b/src/SipClientRegistration.h
index 2941b36..ce8745e 100644
--- a/src/SipClientRegistration.h
+++ b/src/SipClientRegistration.h
@@ -71,7 +71,10 @@ public:
             const AsteriskSCF::Configuration::SipSessionManager::V1::SipClientRegistrationItemPtr& confItem,
             pjsip_endpoint* pjEndpoint,
             const SipEndpointPtr& sipEndpoint,
-            const SipRegistrationClientManagerPtr manager);
+            const SipRegistrationClientManagerPtr& manager,
+            const SipReplicationContextPtr& replicationContext,
+            const Ice::ObjectAdapterPtr& backplaneAdapter,
+            const AsteriskSCF::System::Component::V1::ReplicaPrx& replica);
 
     ~SipRegistrationClient();
 
@@ -95,6 +98,12 @@ private:
     IceUtil::TimerTaskPtr mTimerTask;
     IceUtil::TimerPtr mTimer;
 
+    SipReplicationContextPtr mReplicationContext;
+
+    Ice::ObjectAdapterPtr mBackplaneAdapter;
+
+    AsteriskSCF::System::Component::V1::ReplicaPrx mReplica;
+
     friend class RescheduleRegister;
 };
 
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index b39fcc7..bf953aa 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -38,6 +38,7 @@ using namespace AsteriskSCF::SessionCommunications::V1;
 using namespace AsteriskSCF::Replication::SipSessionManager::V1;
 using namespace AsteriskSCF::Discovery;
 using namespace AsteriskSCF::Configuration::SipSessionManager::V1;
+using namespace AsteriskSCF::System::Component::V1;
 
 namespace
 {
@@ -179,12 +180,22 @@ public:
     /**
      * Constructor for the SipEndpointImplPriv class.
      */
-    SipEndpointImplPriv(const Ice::ObjectAdapterPtr& adapter, const boost::shared_ptr<SipEndpointFactory>& factory,
-            const std::string& name, const PJSipManagerPtr& manager,
+    SipEndpointImplPriv(const Ice::ObjectAdapterPtr& adapter,
+            const Ice::ObjectAdapterPtr& backplaneAdapter,
+            const boost::shared_ptr<SipEndpointFactory>& factory,
+            const std::string& name,
+            const PJSipManagerPtr& manager,
             const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
-            const SipReplicationContextPtr& replicationContext) :
-        mName(name), mAdapter(adapter), mEndpointFactory(factory), mManager(manager), mServiceLocator(serviceLocator),
+            const SipReplicationContextPtr& replicationContext,
+            const ReplicaPrx& replica) :
+        mName(name),
+        mAdapter(adapter),
+        mBackplaneAdapter(backplaneAdapter),
+        mEndpointFactory(factory),
+        mManager(manager),
+        mServiceLocator(serviceLocator),
         mReplicationContext(replicationContext),
+        mReplica(replica),
         mDefaultListeners(new AsteriskSCF::Collections::ProxySet<SessionListenerPrx>(adapter, lg, "Default Session Listeners")),
         mDefaultSessionCookies(new AsteriskSCF::Collections::HandleSet<SessionCookiePtr>(lg, "Default Cookies"))
     {
@@ -206,6 +217,7 @@ public:
      */
     Ice::ObjectAdapterPtr mAdapter;
 
+    Ice::ObjectAdapterPtr mBackplaneAdapter;
     /**
      * The endpoint factory that created us.
      */
@@ -238,6 +250,7 @@ public:
 
     AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx mServiceLocator;
     SipReplicationContextPtr mReplicationContext;
+    ReplicaPrx mReplica;
     AsteriskSCF::Collections::ProxySet<SessionListenerPrx>::SetPtr mDefaultListeners;
     AsteriskSCF::Collections::HandleSet<SessionCookiePtr>::SetPtr mDefaultSessionCookies;
 
@@ -245,12 +258,14 @@ public:
 };
 
 SipEndpoint::SipEndpoint(const Ice::ObjectAdapterPtr& adapter, 
+    const Ice::ObjectAdapterPtr& backplaneAdapter,
     const boost::shared_ptr<SipEndpointFactory>& factory,
     std::string name, 
     const PJSipManagerPtr& manager, 
     const ServiceLocatorPrx& serviceLocator,
-    const SipReplicationContextPtr& replicationContext)
-    : mImplPriv(new SipEndpointImplPriv(adapter, factory, name, manager, serviceLocator, replicationContext))
+    const SipReplicationContextPtr& replicationContext,
+    const ReplicaPrx& replica)
+    : mImplPriv(new SipEndpointImplPriv(adapter, backplaneAdapter, factory, name, manager, serviceLocator, replicationContext, replica))
 {
     lg(Debug) << "Constructing SIP endpoint " << name;
 
@@ -331,7 +346,14 @@ void SipEndpoint::updateClientRegistrations(SipClientRegistrationItemSeq& items)
         {
             //New one!
             mImplPriv->mClientRegistrations[(*item)->aor] =
-                new SipRegistrationClient(*item, mImplPriv->mManager->getEndpoint(), this, mImplPriv->mManager->getClientRegistrationManager());
+                new SipRegistrationClient(
+                        *item,
+                        mImplPriv->mManager->getEndpoint(),
+                        this,
+                        mImplPriv->mManager->getClientRegistrationManager(),
+                        mImplPriv->mReplicationContext,
+                        mImplPriv->mBackplaneAdapter,
+                        mImplPriv->mReplica);
         }
     }
 }
diff --git a/src/SipEndpoint.h b/src/SipEndpoint.h
index 9ee243f..776f66c 100644
--- a/src/SipEndpoint.h
+++ b/src/SipEndpoint.h
@@ -34,6 +34,7 @@
 #include <AsteriskSCF/Media/RTP/MediaRTPIf.h>
 #include <AsteriskSCF/Media/SDP/MediaSDPIf.h>
 #include <AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.h>
+#include <AsteriskSCF/System/Component/ReplicaIf.h>
 
 #include "SipSession.h"
 #include "SipReplicationContext.h"
@@ -270,9 +271,15 @@ class SipEndpointImplPriv;
 class SipEndpoint : public AsteriskSCF::SessionCommunications::V1::SessionEndpoint
 {
 public:
-    SipEndpoint(const Ice::ObjectAdapterPtr& adapter, const boost::shared_ptr<SipEndpointFactory>& factory, std::string name, 
-        const PJSipManagerPtr& manager, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator, 
-        const SipReplicationContextPtr& replicationContext);
+    SipEndpoint(
+            const Ice::ObjectAdapterPtr& adapter,
+            const Ice::ObjectAdapterPtr& backplaneAdapter,
+            const boost::shared_ptr<SipEndpointFactory>& factory,
+            std::string name,
+            const PJSipManagerPtr& manager,
+            const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+            const SipReplicationContextPtr& replicationContext,
+            const AsteriskSCF::System::Component::V1::ReplicaPrx& replica);
 
     bool operator==(const std::string &name) const;
 
diff --git a/src/SipEndpointFactory.cpp b/src/SipEndpointFactory.cpp
index ce8de77..2be256d 100644
--- a/src/SipEndpointFactory.cpp
+++ b/src/SipEndpointFactory.cpp
@@ -32,8 +32,15 @@ namespace SipSessionManager
 {
 SipEndpointPtr SipEndpointFactory::createEndpoint(std::string endpointName)
 {
-    SipEndpointPtr endpoint = new SipEndpoint(mAdapter, shared_from_this(), endpointName, mManager, 
-        mServiceLocator, mReplicationContext);
+    SipEndpointPtr endpoint = new SipEndpoint(
+            mAdapter,
+            mBackplaneAdapter,
+            shared_from_this(),
+            endpointName,
+            mManager,
+            mServiceLocator,
+            mReplicationContext,
+            mReplica);
     mEndpoints.push_back(endpoint);
     return endpoint;
 }
diff --git a/src/SipEndpointFactory.h b/src/SipEndpointFactory.h
index 13a63ed..fbefdd2 100644
--- a/src/SipEndpointFactory.h
+++ b/src/SipEndpointFactory.h
@@ -38,10 +38,19 @@ namespace SipSessionManager
 class SipEndpointFactory : public boost::enable_shared_from_this<SipEndpointFactory>
 {
 public:
-    SipEndpointFactory(const Ice::ObjectAdapterPtr& adapter, const PJSipManagerPtr& manager,
-        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
-        const SipReplicationContextPtr& replicationContext) :
-        mAdapter(adapter), mManager(manager), mServiceLocator(serviceLocator), mReplicationContext(replicationContext) {};
+    SipEndpointFactory(
+            const Ice::ObjectAdapterPtr& adapter,
+            const Ice::ObjectAdapterPtr& backplaneAdapter,
+            const PJSipManagerPtr& manager,
+            const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+            const SipReplicationContextPtr& replicationContext,
+            const AsteriskSCF::System::Component::V1::ReplicaPrx& replica) :
+        mAdapter(adapter),
+        mBackplaneAdapter(backplaneAdapter),
+        mManager(manager),
+        mServiceLocator(serviceLocator),
+        mReplicationContext(replicationContext),
+        mReplica(replica){};
 
     SipEndpointPtr createEndpoint(std::string);
 
@@ -57,6 +66,8 @@ private:
      */
     Ice::ObjectAdapterPtr mAdapter;
 
+    Ice::ObjectAdapterPtr mBackplaneAdapter;
+
     /**
      * A vector of endpoints that this factory has created.
      */
@@ -76,6 +87,8 @@ private:
      * A pointer to the replica information.
      */
     SipReplicationContextPtr mReplicationContext;
+
+    AsteriskSCF::System::Component::V1::ReplicaPrx mReplica;
 };
 
 }; // end SipSessionManager

commit 627496611f923896f9af9492d63b97c1eeb25b1d
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Sep 8 19:18:09 2011 -0500

    Cancel a re-register attempt if something else causes us to attempt re-registering early.

diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index e32a7dc..e389ff7 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -213,6 +213,17 @@ void SipRegistrationClient::removeContacts(const Ice::StringSeq& contacts)
 
 void SipRegistrationClient::sendRegister()
 {
+
+    //There's a decent chance that there's no actual
+    //scheduled task, but in case there is, we need
+    //to cancel that dude.
+    //
+    //Note that the Ice manual states that attempting to cancel
+    //a one-time task results in nothing occurring. However,
+    //I ran some independent tests and found that at least in
+    //Ice 3.4.2, you can cancel a one-time task succesfully.
+    mTimer->cancel(mTimerTask);
+
     std::vector<pj_str_t> contacts;
     std::transform(mContacts.begin(), mContacts.end(), std::back_inserter(contacts), MakeContact(mReg));
 
@@ -248,7 +259,11 @@ void SipRegistrationClient::handleRegisterResponse(pjsip_regc_cbparam *param)
         if (retryAfter)
         {
             lg(Notice) << "REGISTER attempt failure for endpoint " << mEndpointName << " contains Retry-After of " << retryAfter->ivalue;
-            mTimer->schedule(new RescheduleRegister(this), IceUtil::Time::seconds(retryAfter->ivalue));
+            if (!mTimerTask)
+            {
+                mTimerTask = new RescheduleRegister(this);
+            }
+            mTimer->schedule(mTimerTask, IceUtil::Time::seconds(retryAfter->ivalue));
         }
         else
         {
diff --git a/src/SipClientRegistration.h b/src/SipClientRegistration.h
index 3b4fa65..2941b36 100644
--- a/src/SipClientRegistration.h
+++ b/src/SipClientRegistration.h
@@ -92,6 +92,7 @@ private:
     SipRegistrationClientManagerPtr mManager;
     pjsip_regc* mReg;
 
+    IceUtil::TimerTaskPtr mTimerTask;
     IceUtil::TimerPtr mTimer;
 
     friend class RescheduleRegister;

commit d7b7717cfd58774cb42c60875538809e6cd4d473
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Sep 8 17:40:22 2011 -0500

    Honor Retry-After headers in registration failures.

diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index 40089da..e32a7dc 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -31,7 +31,6 @@ void regCallback(struct pjsip_regc_cbparam *param)
 {
     //I'd much rather be able to control things within the confines of my
     //class thank you very much.
-
     SipRegistrationClient *client = static_cast<SipRegistrationClient*>(param->token);
     client->handleRegisterResponse(param);
... 2513 lines suppressed ...


-- 
asterisk-scf/release/sip.git



More information about the asterisk-scf-commits mailing list