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

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Mon Jun 13 17:59:21 CDT 2011


branch "registrar" has been updated
       via  cb2abe96f218864eb0088c343b3a91ffa6e578e8 (commit)
       via  480dca6e1d5a251dd2ab680f776b46f37a052660 (commit)
       via  871d682ad8f89f934e68326fa6b3d861479321da (commit)
       via  2e6f61b3697981bb4a1af0a4f2738ff786668269 (commit)
       via  f8ba9bd5baffb67df87d1726c8635bb7d5d63ff2 (commit)
       via  49064db0f2c505427f826c7fc9608e39d3a2ffe2 (commit)
      from  72fce78916b051f6d76a4e61de9fb5d26eec10de (commit)

Summary of changes:
 src/PJSipManager.h                       |   22 ++--
 src/PJSipRegistrarModule.cpp             |  193 +++++++++++++++++------------
 src/PJSipRegistrarModule.h               |   20 +++-
 src/PJSipRegistrarModuleConstruction.cpp |    3 +-
 4 files changed, 146 insertions(+), 92 deletions(-)


- Log -----------------------------------------------------------------
commit cb2abe96f218864eb0088c343b3a91ffa6e578e8
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jun 13 17:57:04 2011 -0500

    Add initial support for scheduling expiration of bindings.
    
    Right now when a binding expires, a debug message is printed, but
    nothing else occurs.
    
    The next steps will be firstly to cancel the expiration in the
    event that the endpoint reregisters, then to use a WorkQueue to
    linearize the operations.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 0b348a8..a70dce7 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -259,6 +259,14 @@ void PJSipRegistrarModule::updateBinding(BindingPtr &binding, const std::string
     binding->callid = callID;
     binding->cseq = cSeq;
     binding->expiration = expiration;
+    //XXX We need to cancel the previous scheduled destruction
+    //and schedule a new one here.
+}
+
+static void registrationExpired(pj_timer_heap_t *, struct pj_timer_entry *entry)
+{
+    BindingPtr *binding = (BindingPtr *) entry->user_data;
+    lg(Debug) << "Detected expiration of binding " << (*binding)->contact;
 }
 
 BindingPtr PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, const std::string &callID, int cSeq, int expiration)
@@ -273,7 +281,14 @@ BindingPtr PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, co
         << ", CSeq: " << cSeq
         << ", and Expires: " << expiration;
 
-    return new Binding(contactURIStr, callID, cSeq, expiration);
+    BindingPtr *binding(new BindingPtr(new Binding(contactURIStr, callID, cSeq, expiration)));
+    pj_time_val delay = {expiration, 0};
+    pj_timer_entry *entry = new pj_timer_entry;
+    entry->user_data = binding;
+    entry->id = 0;
+    entry->cb = registrationExpired;
+    pjsip_endpt_schedule_timer(mEndpoint, entry, &delay);
+    return *binding;
 }
 
 pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index 3335b53..ce8a8a2 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -71,6 +71,7 @@ private:
     void updateBinding(AsteriskSCF::SIP::Registration::V1::BindingPtr &binding,
             const std::string &callID, int cSeq, int expiration);
 
+    pjsip_endpoint *mEndpoint;
     RegistrarIPtr mRegistrar;
 };
 
diff --git a/src/PJSipRegistrarModuleConstruction.cpp b/src/PJSipRegistrarModuleConstruction.cpp
index 23eec90..a4aeeeb 100644
--- a/src/PJSipRegistrarModuleConstruction.cpp
+++ b/src/PJSipRegistrarModuleConstruction.cpp
@@ -72,7 +72,7 @@ static void registrarOnTsxState(pjsip_transaction *tsx, pjsip_event *event)
 }
 
 PJSipRegistrarModule::PJSipRegistrarModule(pjsip_endpoint *endpt)
-    : mRegistrar(new RegistrarI())
+    : mEndpoint(endpt), mRegistrar(new RegistrarI())
 {
     registrarModule = this;
     mModule.name = pj_str(registrarModuleName);
@@ -91,7 +91,7 @@ PJSipRegistrarModule::PJSipRegistrarModule(pjsip_endpoint *endpt)
     mModule.on_tx_request = registrarOnTxRequest;
     mModule.on_tx_response = registrarOnTxResponse;
     mModule.on_tsx_state = registrarOnTsxState;
-    pjsip_endpt_register_module(endpt, &mModule);
+    pjsip_endpt_register_module(mEndpoint, &mModule);
 }
 
 };

commit 480dca6e1d5a251dd2ab680f776b46f37a052660
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jun 13 16:01:27 2011 -0500

    Add debug messages, and fix broken lookup of existing bindings.
    
    Tested sending REGISTERs to add, refresh, and remove bindings. It's
    all working so far. Next step is to work out the expiration logic
    so that bindings will be removed when they expire.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index a93d64c..0b348a8 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -80,11 +80,13 @@ void RegistrarI::updateBindings(const std::string &aor, BindingSeq&, BindingSeq&
     //Let's add in the new bindings, shall we?
     if (thingy == mBindings.end())
     {
-        mBindings.insert(make_pair(aor,newBindings));
+        lg(Debug) << "Adding new bindings";
+        mBindings.insert(make_pair(aor, newBindings));
     }
     else
     {
         BindingSeq& currentBindings = thingy->second;
+        lg(Debug) << "Adding new bindings";
         currentBindings.insert(currentBindings.end(), newBindings.begin(), newBindings.end());
         for (BindingSeq::iterator iter = removedBindings.begin(); iter != removedBindings.end(); ++iter)
         {
@@ -93,6 +95,7 @@ void RegistrarI::updateBindings(const std::string &aor, BindingSeq&, BindingSeq&
             //in order to determine if there is a match. It's really only necessary to compare
             //the contact. Comparing the other members shouldn't have any negative effect
             //on functionality, but it is suboptimal.
+            lg(Debug) << "Removing binding " << (*iter)->contact;
             currentBindings.erase(std::remove(currentBindings.begin(), currentBindings.end(), *iter), currentBindings.end());
         }
     }
@@ -104,6 +107,7 @@ void RegistrarI::updateBindings(const std::string &aor, BindingSeq&, BindingSeq&
             iter != mListeners.end(); ++iter)
     {
         //Listeners are only concerned with new and removed bindings. There's no need to tell them of existing ones.
+        lg(Debug) << "Alerting listener " << (*iter)->ice_getIdentity().name << " about changes to bindings";
         (*iter)->contactsAdded(newBindingUpdateSeq);
         (*iter)->contactsRemoved(removedBindingUpdateSeq);
     }
@@ -210,13 +214,17 @@ BindingSeq::iterator PJSipRegistrarModule::findMatchingBinding(pjsip_contact_hdr
     pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contactURI, buf, sizeof(buf));
     std::string contactURIStr(buf, strlen(buf));
 
+    lg(Debug) << "Searching for binding " << contactURIStr;
     for (BindingSeq::iterator iter = bindings.begin(); iter != bindings.end(); ++iter)
     {
+        lg(Debug) << "Comparing REGISTER contact " << contactURIStr << " with binding contact " << (*iter)->contact;
         if (contactURIStr == (*iter)->contact)
         {
+            lg(Debug) << "Found matching binding " << (*iter)->contact;
             return iter;
         }
     }
+    lg(Debug) << "No matching binding found for " << contactURIStr;
     return bindings.end();
 }
 
@@ -224,6 +232,7 @@ int PJSipRegistrarModule::getExpiration(pjsip_contact_hdr *contact, pjsip_rx_dat
 {
     if (contact->expires != -1)
     {
+        lg(Debug) << "Contact header has expires parameter of " << contact->expires;
         return contact->expires;
     }
 
@@ -231,6 +240,7 @@ int PJSipRegistrarModule::getExpiration(pjsip_contact_hdr *contact, pjsip_rx_dat
 
     if (expires)
     {
+        lg(Debug) << "REGISTER has Expires header with value " << expires->ivalue;
         return expires->ivalue;
     }
     else
@@ -239,6 +249,7 @@ int PJSipRegistrarModule::getExpiration(pjsip_contact_hdr *contact, pjsip_rx_dat
         // use a locally-configured default expiration if none can be determined from
         // the REGISTER. For now, we're using a hard-coded 3600. This can be made into
         // a file-level constant or this may be configurable later.
+        lg(Warning) << "REGISTER has no expiration specified. Using default expiration of 3600";
         return 3600;
     }
 }
@@ -257,6 +268,11 @@ BindingPtr PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, co
     pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contactURI, buf, sizeof(buf));
     std::string contactURIStr(buf, strlen(buf));
 
+    lg(Debug) << "Creating new binding with Contact: " << contactURIStr
+        << ", Call-Id: " << callID
+        << ", CSeq: " << cSeq
+        << ", and Expires: " << expiration;
+
     return new Binding(contactURIStr, callID, cSeq, expiration);
 }
 
@@ -267,6 +283,8 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
         return PJ_FALSE;
     }
 
+    lg(Debug) << "Registrar Module handling a new incoming REGISTER request";
+
     pjsip_transaction *tsx;
     pjsip_tsx_create_uas(&mModule, rdata, &tsx);
     pjsip_tsx_recv_msg(tsx, rdata);
@@ -283,6 +301,7 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
     // way decided upon before trying to write any code for it.
 
     std::string aor = getAOR(rdata);
+    lg(Debug) << "AoR in REGISTER is " << aor;
     Ice::Current current;
     BindingSeq currentBindings = mRegistrar->getAORBindings(aor, current);
     std::vector<pjsip_contact_hdr *> registerContacts = extractRegisterContacts(rdata);
@@ -306,7 +325,7 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
     for (std::vector<pjsip_contact_hdr *>::iterator iter = registerContacts.begin();
             iter != registerContacts.end(); ++iter)
     {
-        BindingSeq::iterator bindingToUpdate = findMatchingBinding(*iter, existingBindings);
+        BindingSeq::iterator bindingToUpdate = findMatchingBinding(*iter, currentBindings);
 
         int expiration = getExpiration(*iter, rdata);
 
@@ -314,23 +333,24 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
         {
             if (expiration == 0)
             {
+                lg(Debug) << "Adding " << (*bindingToUpdate)->contact << " to our bindings to remove";
                 removedBindings.push_back(*bindingToUpdate);
             }
             else
             {
                 updateBinding(*bindingToUpdate, callID, cSeq, time(NULL) + expiration);
+                lg(Debug) << "Adding " << (*bindingToUpdate)->contact << " to our existing bindings";
                 existingBindings.push_back(*bindingToUpdate);
             }
         }
         else
         {
             BindingPtr binding = createNewBinding(*iter, callID, cSeq, time(NULL) + expiration);
+            lg(Debug) << "Adding " << binding->contact << " to our bindings to add";
             newBindings.push_back(binding);
         }
     }
 
-    // Now existingBindings should be an up-to-date list of bindings for
-    // this AoR.
     mRegistrar->updateBindings(aor, existingBindings, newBindings, removedBindings);
 
     pjsip_tx_data *tdata;

commit 871d682ad8f89f934e68326fa6b3d861479321da
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jun 13 11:34:26 2011 -0500

    Get rid of the static mEmpty member for now.
    
    It's really a premature optimization anyway, and since I was not
    initializing it properly anyway, it was causing an error when attempting
    to start the SIP service.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 61eae64..a93d64c 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -64,7 +64,8 @@ BindingSeq RegistrarI::getAORBindings(const std::string &aor, const Ice::Current
     }
     else
     {
-        return mEmpty;
+        BindingSeq empty;
+        return empty;
     }
 }
 
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index c3d7b47..3335b53 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -40,11 +40,6 @@ public:
             AsteriskSCF::SIP::Registration::V1::BindingSeq& removedBindings);
     AsteriskSCF::SIP::Registration::V1::BindingUpdateSeq createBindingUpdateSeq(const std::string& aor, AsteriskSCF::SIP::Registration::V1::BindingSeq& bindings);
 private:
-    /** 
-     * Handy empty sequence to return in cases where
-     * someone requests bindings and we don't have any.
-     */
-    static AsteriskSCF::SIP::Registration::V1::BindingSeq mEmpty;
     AsteriskSCF::SIP::Registration::V1::BindingDict mBindings;
     AsteriskSCF::SIP::Registration::V1::ContactDict mContacts;
     std::vector<AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx> mListeners;

commit 2e6f61b3697981bb4a1af0a4f2738ff786668269
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jun 13 11:22:26 2011 -0500

    Fix up RegistrarI's functions to have Ice::Current parameters as they are supposed to.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index d7a9650..61eae64 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -35,7 +35,7 @@ namespace SipSessionManager
 
 RegistrarI::RegistrarI() { }
 
-ContactDict RegistrarI::addListener(const RegistrarListenerPrx& listener)
+ContactDict RegistrarI::addListener(const RegistrarListenerPrx& listener, const Ice::Current&)
 {
     if (std::find(mListeners.begin(), mListeners.end(), listener) != mListeners.end())
     {
@@ -45,17 +45,17 @@ ContactDict RegistrarI::addListener(const RegistrarListenerPrx& listener)
     return mContacts;
 }
 
-void RegistrarI::RemoveListener(const RegistrarListenerPrx& listener)
+void RegistrarI::removeListener(const RegistrarListenerPrx& listener, const Ice::Current&)
 {
     mListeners.erase(std::remove(mListeners.begin(), mListeners.end(), listener));
 }
 
-BindingDict RegistrarI::getAllBindings()
+BindingDict RegistrarI::getAllBindings(const Ice::Current&)
 {
     return mBindings;
 }
 
-BindingSeq RegistrarI::getAORBindings(const std::string &aor)
+BindingSeq RegistrarI::getAORBindings(const std::string &aor, const Ice::Current&)
 {
     BindingDict::iterator iter = mBindings.find(aor);
     if (iter != mBindings.end())
@@ -282,7 +282,8 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
     // way decided upon before trying to write any code for it.
 
     std::string aor = getAOR(rdata);
-    BindingSeq currentBindings = mRegistrar->getAORBindings(aor);
+    Ice::Current current;
+    BindingSeq currentBindings = mRegistrar->getAORBindings(aor, current);
     std::vector<pjsip_contact_hdr *> registerContacts = extractRegisterContacts(rdata);
 
     std::string callID(pj_strbuf(&rdata->msg_info.cid->id), pj_strlen(&rdata->msg_info.cid->id));
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index 8fc15ca..c3d7b47 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -30,10 +30,10 @@ class RegistrarI : public AsteriskSCF::SIP::Registration::V1::Registrar
 {
 public:
     RegistrarI();
-    AsteriskSCF::SIP::Registration::V1::ContactDict addListener(const AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx& listener);
-    void RemoveListener(const AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx& listener);
-    AsteriskSCF::SIP::Registration::V1::BindingDict getAllBindings();
-    AsteriskSCF::SIP::Registration::V1::BindingSeq getAORBindings(const std::string &aor);
+    AsteriskSCF::SIP::Registration::V1::ContactDict addListener(const AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx& listener, const Ice::Current&);
+    void removeListener(const AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx& listener, const Ice::Current&);
+    AsteriskSCF::SIP::Registration::V1::BindingDict getAllBindings(const Ice::Current&);
+    AsteriskSCF::SIP::Registration::V1::BindingSeq getAORBindings(const std::string &aor, const Ice::Current&);
     void updateBindings(
             const std::string &aor, AsteriskSCF::SIP::Registration::V1::BindingSeq& existingBindings,
             AsteriskSCF::SIP::Registration::V1::BindingSeq& newBindings,
diff --git a/src/PJSipRegistrarModuleConstruction.cpp b/src/PJSipRegistrarModuleConstruction.cpp
index 909993d..23eec90 100644
--- a/src/PJSipRegistrarModuleConstruction.cpp
+++ b/src/PJSipRegistrarModuleConstruction.cpp
@@ -72,6 +72,7 @@ static void registrarOnTsxState(pjsip_transaction *tsx, pjsip_event *event)
 }
 
 PJSipRegistrarModule::PJSipRegistrarModule(pjsip_endpoint *endpt)
+    : mRegistrar(new RegistrarI())
 {
     registrarModule = this;
     mModule.name = pj_str(registrarModuleName);

commit f8ba9bd5baffb67df87d1726c8635bb7d5d63ff2
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jun 13 10:56:36 2011 -0500

    Accidentally put some public functions in a private encapsulation during a merge.
    
    Things compile now. Going to add some logging and then do some quick tests
    to see if what we have works properly.

diff --git a/src/PJSipManager.h b/src/PJSipManager.h
index 56fe148..024da4b 100644
--- a/src/PJSipManager.h
+++ b/src/PJSipManager.h
@@ -90,16 +90,7 @@ public:
      * addresses of record.
      */
     void registerRegistrarModule();
-private:
-    static PJSipManager *mInstance;
-    pjsip_endpoint *mEndpoint;
-    PJSipSessionModulePtr mSessionModule;
-    PJSipLoggingModulePtr mLoggingModule;
-    PJSipRegistrarModulePtr mRegistrarModule;
-    pj_thread_t *mPjThread;
-    pj_caching_pool mCachingPool;
-    pj_pool_t *mMemoryPool;
-    pjsip_transport *mUdpTransport;
+
     /**
      * Create a UDP transport.
      */
@@ -115,6 +106,17 @@ private:
      */
     pjsip_tpfactory *createTLSTransport(std::string, int, pjsip_tls_setting*);
 
+private:
+    static PJSipManager *mInstance;
+    pjsip_endpoint *mEndpoint;
+    PJSipSessionModulePtr mSessionModule;
+    PJSipLoggingModulePtr mLoggingModule;
+    PJSipRegistrarModulePtr mRegistrarModule;
+    pj_thread_t *mPjThread;
+    pj_caching_pool mCachingPool;
+    pj_pool_t *mMemoryPool;
+    pjsip_transport *mUdpTransport;
+
     bool setTransports(pjsip_endpoint *endpoint, const Ice::PropertiesPtr& props);
 };
 

commit 49064db0f2c505427f826c7fc9608e39d3a2ffe2
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jun 13 10:40:51 2011 -0500

    Fix up compilation of Registrar code.
    
    There are compilation errors in other parts that probably indicates
    I messed up an earlier merge conflict or something.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 2993f77..d7a9650 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -33,100 +33,96 @@ namespace AsteriskSCF
 namespace SipSessionManager
 {
 
-class RegistrarI : public Registrar
-{
-public:
-    RegistrarI() { }
+RegistrarI::RegistrarI() { }
 
-    ContactDict addListener(const RegistrarListenerPrx& listener)
+ContactDict RegistrarI::addListener(const RegistrarListenerPrx& listener)
+{
+    if (std::find(mListeners.begin(), mListeners.end(), listener) != mListeners.end())
     {
-        if (std::find(mListeners.begin(), mListeners.end(), listener) != mListeners.end())
-        {
-            mListeners.push_back(listener);
-        }
-        //We should maybe throw an exception if someone tries to insert a duplicate?
-        return mContacts;
+        mListeners.push_back(listener);
     }
+    //We should maybe throw an exception if someone tries to insert a duplicate?
+    return mContacts;
+}
 
-    void RemoveListener(const RegistrarListenerPrx& listener)
-    {
-        mListeners.erase(std::remove(mListeners.begin(), mListeners.end(), listener));
-    }
+void RegistrarI::RemoveListener(const RegistrarListenerPrx& listener)
+{
+    mListeners.erase(std::remove(mListeners.begin(), mListeners.end(), listener));
+}
 
-    BindingDict getAllBindings()
-    {
-        return mBindings;
-    }
+BindingDict RegistrarI::getAllBindings()
+{
+    return mBindings;
+}
 
-    BindingSeq getAORBindings(const std::string &aor)
+BindingSeq RegistrarI::getAORBindings(const std::string &aor)
+{
+    BindingDict::iterator iter = mBindings.find(aor);
+    if (iter != mBindings.end())
     {
-        BindingDict::iterator iter = mBindings.find(aor);
-        if (iter != mBindings.end())
-        {
-            return iter->second;
-        }
-        else
-        {
-            return mEmpty;
-        }
+        return iter->second;
     }
-
-    void updateBindings(const std::string &aor, BindingSeq&, BindingSeq& newBindings, BindingSeq& removedBindings)
+    else
     {
-        //Best way to do this...
-        //First, find the sequence of bindings for this particular AoR that we are going to be
-        //updating.
+        return mEmpty;
+    }
+}
 
-        BindingDict::iterator thingy = mBindings.find(aor);
+void RegistrarI::updateBindings(const std::string &aor, BindingSeq&, BindingSeq& newBindings, BindingSeq& removedBindings)
+{
+    //Best way to do this...
+    //First, find the sequence of bindings for this particular AoR that we are going to be
+    //updating.
 
-        //Let's add in the new bindings, shall we?
-        if (thingy == mBindings.end())
-        {
-            mBindings.insert(make_pair(aor,newBindings));
-        }
-        else
-        {
-            BindingSeq& currentBindings = thingy->second;
-            currentBindings.insert(currentBindings.end(), newBindings.begin(), newBindings.end());
-            currentBindings.erase(std::remove(currentBindings.begin(), currentBindings.end(), removedBindings), currentBindings.end());
-        }
+    BindingDict::iterator thingy = mBindings.find(aor);
 
-        // We have our internal stuff all sorted out. Now we need to notify listeners and replicas.
-        BindingUpdateSeq newBindingUpdateSeq(createBindingUpdateSeq(aor, newBindings));
-        BindingUpdateSeq removedBindingUpdateSeq(createBindingUpdateSeq(aor, removedBindings));
-        for (std::vector<RegistrarListenerPrx>::iterator iter = mListeners.begin();
-                iter != mListeners.end(); ++iter)
+    //Let's add in the new bindings, shall we?
+    if (thingy == mBindings.end())
+    {
+        mBindings.insert(make_pair(aor,newBindings));
+    }
+    else
+    {
+        BindingSeq& currentBindings = thingy->second;
+        currentBindings.insert(currentBindings.end(), newBindings.begin(), newBindings.end());
+        for (BindingSeq::iterator iter = removedBindings.begin(); iter != removedBindings.end(); ++iter)
         {
-            //Listeners are only concerned with new and removed bindings. There's no need to tell them of existing ones.
-            (*iter)->contactsAdded(newBindingUpdateSeq);
-            (*iter)->contactsRemoved(removedBindingUpdateSeq);
+            //XXX
+            //The == operator for a Binding is created by Ice and likely compares all members
+            //in order to determine if there is a match. It's really only necessary to compare
+            //the contact. Comparing the other members shouldn't have any negative effect
+            //on functionality, but it is suboptimal.
+            currentBindings.erase(std::remove(currentBindings.begin(), currentBindings.end(), *iter), currentBindings.end());
         }
-        //XXX This would be where we replicate state. BACKBURNER!
     }
 
-    BindingUpdateSeq createBindingUpdateSeq(const std::string& aor, BindingSeq& bindings)
+    // We have our internal stuff all sorted out. Now we need to notify listeners and replicas.
+    BindingUpdateSeq newBindingUpdateSeq(createBindingUpdateSeq(aor, newBindings));
+    BindingUpdateSeq removedBindingUpdateSeq(createBindingUpdateSeq(aor, removedBindings));
+    for (std::vector<RegistrarListenerPrx>::iterator iter = mListeners.begin();
+            iter != mListeners.end(); ++iter)
     {
-        BindingUpdateSeq returnedSeq;
-        Ice::StringSeq contacts;
-        for (BindingSeq::iterator iter = bindings.begin(); iter != bindings.end(); ++iter)
-        {
-            contacts.push_back((*iter)->contact);
-        }
-        BindingUpdate update;
-        update.aor = aor;
-        update.contacts = contacts;
-        returnedSeq.push_back(update);
-        return returnedSeq;
+        //Listeners are only concerned with new and removed bindings. There's no need to tell them of existing ones.
+        (*iter)->contactsAdded(newBindingUpdateSeq);
+        (*iter)->contactsRemoved(removedBindingUpdateSeq);
     }
+    //XXX This would be where we replicate state. BACKBURNER!
+}
 
-    // Ready-made empty sequence to return when someone tries to grab
-    // bindings associated with an AOR for which we have no bindings.
-    static BindingSeq mEmpty;
-    
-    BindingDict mBindings;
-    ContactDict mContacts;
-    std::vector<RegistrarListenerPrx> mListeners;
-};
+BindingUpdateSeq RegistrarI::createBindingUpdateSeq(const std::string& aor, BindingSeq& bindings)
+{
+    BindingUpdateSeq returnedSeq;
+    Ice::StringSeq contacts;
+    for (BindingSeq::iterator iter = bindings.begin(); iter != bindings.end(); ++iter)
+    {
+        contacts.push_back((*iter)->contact);
+    }
+    BindingUpdate update;
+    update.aor = aor;
+    update.contacts = contacts;
+    returnedSeq.push_back(update);
+    return returnedSeq;
+}
 
 pj_status_t PJSipRegistrarModule::load(pjsip_endpoint *)
 {
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index d5f7acf..8fc15ca 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -26,7 +26,29 @@ namespace AsteriskSCF
 namespace SipSessionManager
 {
 
-class RegistrarI;
+class RegistrarI : public AsteriskSCF::SIP::Registration::V1::Registrar
+{
+public:
+    RegistrarI();
+    AsteriskSCF::SIP::Registration::V1::ContactDict addListener(const AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx& listener);
+    void RemoveListener(const AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx& listener);
+    AsteriskSCF::SIP::Registration::V1::BindingDict getAllBindings();
+    AsteriskSCF::SIP::Registration::V1::BindingSeq getAORBindings(const std::string &aor);
+    void updateBindings(
+            const std::string &aor, AsteriskSCF::SIP::Registration::V1::BindingSeq& existingBindings,
+            AsteriskSCF::SIP::Registration::V1::BindingSeq& newBindings,
+            AsteriskSCF::SIP::Registration::V1::BindingSeq& removedBindings);
+    AsteriskSCF::SIP::Registration::V1::BindingUpdateSeq createBindingUpdateSeq(const std::string& aor, AsteriskSCF::SIP::Registration::V1::BindingSeq& bindings);
+private:
+    /** 
+     * Handy empty sequence to return in cases where
+     * someone requests bindings and we don't have any.
+     */
+    static AsteriskSCF::SIP::Registration::V1::BindingSeq mEmpty;
+    AsteriskSCF::SIP::Registration::V1::BindingDict mBindings;
+    AsteriskSCF::SIP::Registration::V1::ContactDict mContacts;
+    std::vector<AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx> mListeners;
+};
 
 typedef IceUtil::Handle<RegistrarI> RegistrarIPtr;
 

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


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list