[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
Wed Jun 15 09:30:20 CDT 2011


branch "registrar" has been updated
       via  1a6d54ba8e42b022e2dea6c696ab26ebac0345a2 (commit)
       via  c5ed036baf4b2eea39a2496e8c8267be96766dc2 (commit)
       via  433163526c9c788f53fb52ae4b389e3c77f7dc31 (commit)
       via  fa87159c9237db447843c6523f1daa7da2a67607 (commit)
       via  9ab8adb83f3038c03b8c1619bebcabbffc4e352e (commit)
      from  cb2abe96f218864eb0088c343b3a91ffa6e578e8 (commit)

Summary of changes:
 src/PJSipRegistrarModule.cpp |  193 +++++++++++++++++++++++++++++-------------
 src/PJSipRegistrarModule.h   |   64 +++++++++++---
 2 files changed, 185 insertions(+), 72 deletions(-)


- Log -----------------------------------------------------------------
commit 1a6d54ba8e42b022e2dea6c696ab26ebac0345a2
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jun 15 09:30:41 2011 -0500

    Properly remove bindings from the registrar when they expire.
    
    Tested and it works!

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 3e46caa..9dda376 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -38,6 +38,8 @@ static void registrationExpired(pj_timer_heap_t *, struct pj_timer_entry *entry)
     BindingHolder *holder = static_cast<BindingHolder *>(entry->user_data);
     lg(Debug) << "Detected expiration of binding " << holder->mBinding->contact;
     holder->cancelRegistrationExpiration();
+    BindingHolderSeq& currentBindings = holder->mRegistrar->getAORBindingHolders(holder->mAOR);
+    holder->mRegistrar->removeBinding(currentBindings, holder);
 }
 
 static int expirationId;
@@ -46,8 +48,9 @@ BindingHolder::BindingHolder(
         int expiration,
         const BindingPtr& binding,
         const RegistrarIPtr& registrar,
-        pjsip_endpoint *endpt)
-    : mRegistrar(registrar), mBinding(binding), mEndpoint(endpt)
+        pjsip_endpoint *endpt,
+        const std::string& aor)
+    : mRegistrar(registrar), mBinding(binding), mEndpoint(endpt), mAOR(aor)
 {
     pj_timer_entry_init(&mEntry, expirationId++, this, registrationExpired);
     pj_time_val delay = {expiration, 0};
@@ -145,7 +148,9 @@ BindingSeq RegistrarI::getAORBindings(const std::string &aor, const Ice::Current
     }
 }
 
-BindingHolderSeq RegistrarI::getAORBindingHolders(const std::string &aor)
+static BindingHolderSeq Empty;
+
+BindingHolderSeq& RegistrarI::getAORBindingHolders(const std::string &aor)
 {
     BindingHolderDict::iterator iter = mBindings.find(aor);
     if (iter != mBindings.end())
@@ -154,11 +159,16 @@ BindingHolderSeq RegistrarI::getAORBindingHolders(const std::string &aor)
     }
     else
     {
-        BindingHolderSeq empty;
-        return empty;
+        return Empty;
     }
 }
 
+void RegistrarI::removeBinding(BindingHolderSeq& currentBindings, BindingHolder *holder)
+{
+    lg(Debug) << "Removing binding " << holder->mBinding->contact;
+    currentBindings.erase(std::remove(currentBindings.begin(), currentBindings.end(), holder), currentBindings.end());
+}
+
 void RegistrarI::updateBindings(const std::string &aor, BindingHolderSeq&, BindingHolderSeq& newBindings, BindingHolderSeq& removedBindings)
 {
     //Best way to do this...
@@ -180,8 +190,7 @@ void RegistrarI::updateBindings(const std::string &aor, BindingHolderSeq&, Bindi
         currentBindings.insert(currentBindings.end(), newBindings.begin(), newBindings.end());
         for (BindingHolderSeq::iterator iter = removedBindings.begin(); iter != removedBindings.end(); ++iter)
         {
-            lg(Debug) << "Removing binding " << (*iter)->mBinding->contact;
-            currentBindings.erase(std::remove(currentBindings.begin(), currentBindings.end(), *iter), currentBindings.end());
+            removeBinding(currentBindings, *iter);
         }
     }
 
@@ -339,7 +348,7 @@ int PJSipRegistrarModule::getExpiration(pjsip_contact_hdr *contact, pjsip_rx_dat
     }
 }
 
-BindingHolder *PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, const std::string &callID, int cSeq, int expiration)
+BindingHolder *PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, const std::string &callID, int cSeq, int expiration, const std::string& aor)
 {
     char buf[512];
     pjsip_sip_uri *contactURI = (pjsip_sip_uri *)pjsip_uri_get_uri(contact->uri);
@@ -352,7 +361,7 @@ BindingHolder *PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact
         << ", and Expires: " << expiration;
 
     BindingPtr binding(new Binding(contactURIStr, callID, cSeq, time(NULL) + expiration));
-    BindingHolder *holder(new BindingHolder(expiration, binding, mRegistrar, mEndpoint));
+    BindingHolder *holder(new BindingHolder(expiration, binding, mRegistrar, mEndpoint, aor));
     //We could just return binding, but using holder here makes the compiler
     //not complain about an unused variable.
     return holder;
@@ -384,7 +393,7 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
 
     std::string aor = getAOR(rdata);
     lg(Debug) << "AoR in REGISTER is " << aor;
-    BindingHolderSeq currentBindings = mRegistrar->getAORBindingHolders(aor);
+    BindingHolderSeq& currentBindings = mRegistrar->getAORBindingHolders(aor);
     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));
@@ -426,7 +435,7 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
         }
         else
         {
-            BindingHolder *holder = createNewBinding(*iter, callID, cSeq, expiration);
+            BindingHolder *holder = createNewBinding(*iter, callID, cSeq, expiration, aor);
             lg(Debug) << "Adding " << holder->mBinding->contact << " to our bindings to add";
             newBindings.push_back(holder);
         }
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index 2346244..dbd3cc1 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -36,7 +36,8 @@ public:
             int expiration,
             const AsteriskSCF::SIP::Registration::V1::BindingPtr& binding,
             const RegistrarIPtr& registrar,
-            pjsip_endpoint *endpt);
+            pjsip_endpoint *endpt,
+            const std::string& aor);
 
     ~BindingHolder();
 
@@ -52,6 +53,7 @@ public:
     AsteriskSCF::SIP::Registration::V1::BindingPtr mBinding;
     pjsip_endpoint *mEndpoint;
     pj_timer_entry mEntry;
+    const std::string mAOR;
 };
 
 typedef std::vector<BindingHolder *> BindingHolderSeq;
@@ -66,7 +68,10 @@ public:
     AsteriskSCF::SIP::Registration::V1::BindingDict getAllBindings(const Ice::Current&);
     AsteriskSCF::SIP::Registration::V1::BindingSeq getAORBindings(const std::string &aor, const Ice::Current&);
 
-    BindingHolderSeq getAORBindingHolders(const std::string &aor);
+    BindingHolderSeq& getAORBindingHolders(const std::string &aor);
+
+    void removeBinding(BindingHolderSeq& currentBindings, BindingHolder *holder);
+
     void updateBindings(
             const std::string &aor,
             BindingHolderSeq& existingBindings,
@@ -102,7 +107,7 @@ private:
             BindingHolderSeq& bindings);
     int getExpiration(pjsip_contact_hdr *contact, pjsip_rx_data *rdata);
     BindingHolder *createNewBinding(pjsip_contact_hdr *contact,
-            const std::string& callID, int cSeq, int expiration);
+            const std::string& callID, int cSeq, int expiration, const std::string& aor);
 
     pjsip_endpoint *mEndpoint;
     RegistrarIPtr mRegistrar;

commit c5ed036baf4b2eea39a2496e8c8267be96766dc2
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Jun 14 16:55:35 2011 -0500

    Place scheduling and expiration into their own functions.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 89a5c91..3e46caa 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -36,7 +36,8 @@ namespace SipSessionManager
 static void registrationExpired(pj_timer_heap_t *, struct pj_timer_entry *entry)
 {
     BindingHolder *holder = static_cast<BindingHolder *>(entry->user_data);
-    holder->expireRegistration();
+    lg(Debug) << "Detected expiration of binding " << holder->mBinding->contact;
+    holder->cancelRegistrationExpiration();
 }
 
 static int expirationId;
@@ -50,12 +51,13 @@ BindingHolder::BindingHolder(
 {
     pj_timer_entry_init(&mEntry, expirationId++, this, registrationExpired);
     pj_time_val delay = {expiration, 0};
+    lg(Debug) << "Scheduling binding " << mBinding->contact << " for " << expiration << " seconds.";
     pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
 }
 
 BindingHolder::~BindingHolder()
 {
-    pjsip_endpt_cancel_timer(mEndpoint, &mEntry);
+    cancelRegistrationExpiration();
 }
 
 bool BindingHolder::operator==(const BindingHolder& rhs)
@@ -63,9 +65,15 @@ bool BindingHolder::operator==(const BindingHolder& rhs)
     return mBinding->contact == rhs.mBinding->contact;
 }
 
-void BindingHolder::expireRegistration()
+void BindingHolder::cancelRegistrationExpiration()
+{
+    pjsip_endpt_cancel_timer(mEndpoint, &mEntry);
+}
+
+void BindingHolder::scheduleRegistrationExpiration(int expiration)
 {
-    lg(Debug) << "Detected expiration of binding " << mBinding->contact;
+    pj_time_val delay = {expiration, 0};
+    pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
 }
 
 void BindingHolder::updateBinding(const std::string &callID, int cSeq, int expiration)
@@ -73,10 +81,9 @@ void BindingHolder::updateBinding(const std::string &callID, int cSeq, int expir
     mBinding->callid = callID;
     mBinding->cseq = cSeq;
     mBinding->expiration = time(NULL) + expiration;
-    pjsip_endpt_cancel_timer(mEndpoint, &mEntry);
-    pj_time_val delay = {expiration, 0};
-    pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
+    cancelRegistrationExpiration();
     lg(Debug) << "Renewing binding " << mBinding->contact << " for another " << expiration << " seconds.";
+    scheduleRegistrationExpiration(expiration);
 }
 
 RegistrarI::RegistrarI() { }
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index 9e6d0a6..2346244 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -41,6 +41,8 @@ public:
     ~BindingHolder();
 
     void expireRegistration();
+    void scheduleRegistrationExpiration(int expiration);
+    void cancelRegistrationExpiration();
 
     void updateBinding(const std::string &callID, int cSeq, int expiration);
 

commit 433163526c9c788f53fb52ae4b389e3c77f7dc31
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Jun 14 16:40:27 2011 -0500

    Move updateBinding() into the BindingHolder class.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 7d45b8a..89a5c91 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -53,6 +53,11 @@ BindingHolder::BindingHolder(
     pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
 }
 
+BindingHolder::~BindingHolder()
+{
+    pjsip_endpt_cancel_timer(mEndpoint, &mEntry);
+}
+
 bool BindingHolder::operator==(const BindingHolder& rhs)
 {
     return mBinding->contact == rhs.mBinding->contact;
@@ -63,6 +68,17 @@ void BindingHolder::expireRegistration()
     lg(Debug) << "Detected expiration of binding " << mBinding->contact;
 }
 
+void BindingHolder::updateBinding(const std::string &callID, int cSeq, int expiration)
+{
+    mBinding->callid = callID;
+    mBinding->cseq = cSeq;
+    mBinding->expiration = time(NULL) + expiration;
+    pjsip_endpt_cancel_timer(mEndpoint, &mEntry);
+    pj_time_val delay = {expiration, 0};
+    pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
+    lg(Debug) << "Renewing binding " << mBinding->contact << " for another " << expiration << " seconds.";
+}
+
 RegistrarI::RegistrarI() { }
 
 ContactDict RegistrarI::addListener(const RegistrarListenerPrx& listener, const Ice::Current&)
@@ -316,19 +332,6 @@ int PJSipRegistrarModule::getExpiration(pjsip_contact_hdr *contact, pjsip_rx_dat
     }
 }
 
-//XXX
-//This function could possibly be moved into the BindingHolder class...
-void PJSipRegistrarModule::updateBinding(BindingHolder *holder, const std::string &callID, int cSeq, int expiration)
-{
-    holder->mBinding->callid = callID;
-    holder->mBinding->cseq = cSeq;
-    holder->mBinding->expiration = time(NULL) + expiration;
-    pjsip_endpt_cancel_timer(holder->mEndpoint, &holder->mEntry);
-    pj_time_val delay = {expiration, 0};
-    pjsip_endpt_schedule_timer(mEndpoint, &holder->mEntry, &delay);
-    lg(Debug) << "Renewing binding " << holder->mBinding->contact << " for another " << expiration << " seconds.";
-}
-
 BindingHolder *PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, const std::string &callID, int cSeq, int expiration)
 {
     char buf[512];
@@ -409,7 +412,7 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
             }
             else
             {
-                updateBinding(*bindingToUpdate, callID, cSeq, expiration);
+                (*bindingToUpdate)->updateBinding(callID, cSeq, expiration);
                 lg(Debug) << "Maintaining " << (*bindingToUpdate)->mBinding->contact << " in our existing bindings";
                 existingBindings.push_back(*bindingToUpdate);
             }
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index 5bd33df..9e6d0a6 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -38,8 +38,12 @@ public:
             const RegistrarIPtr& registrar,
             pjsip_endpoint *endpt);
 
+    ~BindingHolder();
+
     void expireRegistration();
 
+    void updateBinding(const std::string &callID, int cSeq, int expiration);
+
     bool operator==(const BindingHolder& rhs);
 
     RegistrarIPtr mRegistrar;
@@ -97,8 +101,6 @@ private:
     int getExpiration(pjsip_contact_hdr *contact, pjsip_rx_data *rdata);
     BindingHolder *createNewBinding(pjsip_contact_hdr *contact,
             const std::string& callID, int cSeq, int expiration);
-    void updateBinding(BindingHolder *binding,
-            const std::string &callID, int cSeq, int expiration);
 
     pjsip_endpoint *mEndpoint;
     RegistrarIPtr mRegistrar;

commit fa87159c9237db447843c6523f1daa7da2a67607
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Jun 14 16:11:24 2011 -0500

    Refactor to allow for easy scheduling and canceling of expiration of bindings.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index d847d8d..7d45b8a 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -33,6 +33,36 @@ namespace AsteriskSCF
 namespace SipSessionManager
 {
 
+static void registrationExpired(pj_timer_heap_t *, struct pj_timer_entry *entry)
+{
+    BindingHolder *holder = static_cast<BindingHolder *>(entry->user_data);
+    holder->expireRegistration();
+}
+
+static int expirationId;
+
+BindingHolder::BindingHolder(
+        int expiration,
+        const BindingPtr& binding,
+        const RegistrarIPtr& registrar,
+        pjsip_endpoint *endpt)
+    : mRegistrar(registrar), mBinding(binding), mEndpoint(endpt)
+{
+    pj_timer_entry_init(&mEntry, expirationId++, this, registrationExpired);
+    pj_time_val delay = {expiration, 0};
+    pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
+}
+
+bool BindingHolder::operator==(const BindingHolder& rhs)
+{
+    return mBinding->contact == rhs.mBinding->contact;
+}
+
+void BindingHolder::expireRegistration()
+{
+    lg(Debug) << "Detected expiration of binding " << mBinding->contact;
+}
+
 RegistrarI::RegistrarI() { }
 
 ContactDict RegistrarI::addListener(const RegistrarListenerPrx& listener, const Ice::Current&)
@@ -52,15 +82,38 @@ void RegistrarI::removeListener(const RegistrarListenerPrx& listener, const Ice:
 
 BindingDict RegistrarI::getAllBindings(const Ice::Current&)
 {
-    return mBindings;
+    BindingDict returnedBindings;
+    //XXX
+    //This is suboptimal. What may work better is to maintain 
+    //parallel maps of BindingHolders and Bindings so that
+    //we can quickly return the appropriate information instead of
+    //having to construct a BindingDict on each call.
+    for (BindingHolderDict::iterator iter = mBindings.begin();
+            iter != mBindings.end(); ++iter)
+    {
+        BindingSeq bindings;
+        for (BindingHolderSeq::iterator seqIter = iter->second.begin();
+                seqIter != iter->second.end(); ++seqIter)
+        {
+            bindings.push_back((*seqIter)->mBinding);
+        }
+        returnedBindings.insert(make_pair(iter->first, bindings));
+    }
+    return returnedBindings;
 }
 
 BindingSeq RegistrarI::getAORBindings(const std::string &aor, const Ice::Current&)
 {
-    BindingDict::iterator iter = mBindings.find(aor);
+    BindingHolderDict::iterator iter = mBindings.find(aor);
     if (iter != mBindings.end())
     {
-        return iter->second;
+        BindingSeq bindings;
+        for (BindingHolderSeq::iterator seqIter = iter->second.begin();
+                seqIter != iter->second.end(); ++seqIter)
+        {
+            bindings.push_back((*seqIter)->mBinding);
+        }
+        return bindings;
     }
     else
     {
@@ -69,13 +122,27 @@ BindingSeq RegistrarI::getAORBindings(const std::string &aor, const Ice::Current
     }
 }
 
-void RegistrarI::updateBindings(const std::string &aor, BindingSeq&, BindingSeq& newBindings, BindingSeq& removedBindings)
+BindingHolderSeq RegistrarI::getAORBindingHolders(const std::string &aor)
+{
+    BindingHolderDict::iterator iter = mBindings.find(aor);
+    if (iter != mBindings.end())
+    {
+        return iter->second;
+    }
+    else
+    {
+        BindingHolderSeq empty;
+        return empty;
+    }
+}
+
+void RegistrarI::updateBindings(const std::string &aor, BindingHolderSeq&, BindingHolderSeq& newBindings, BindingHolderSeq& removedBindings)
 {
     //Best way to do this...
     //First, find the sequence of bindings for this particular AoR that we are going to be
     //updating.
 
-    BindingDict::iterator thingy = mBindings.find(aor);
+    BindingHolderDict::iterator thingy = mBindings.find(aor);
 
     //Let's add in the new bindings, shall we?
     if (thingy == mBindings.end())
@@ -85,17 +152,12 @@ void RegistrarI::updateBindings(const std::string &aor, BindingSeq&, BindingSeq&
     }
     else
     {
-        BindingSeq& currentBindings = thingy->second;
+        BindingHolderSeq& 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)
+        for (BindingHolderSeq::iterator iter = removedBindings.begin(); iter != removedBindings.end(); ++iter)
         {
-            //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.
-            lg(Debug) << "Removing binding " << (*iter)->contact;
+            lg(Debug) << "Removing binding " << (*iter)->mBinding->contact;
             currentBindings.erase(std::remove(currentBindings.begin(), currentBindings.end(), *iter), currentBindings.end());
         }
     }
@@ -114,13 +176,13 @@ void RegistrarI::updateBindings(const std::string &aor, BindingSeq&, BindingSeq&
     //XXX This would be where we replicate state. BACKBURNER!
 }
 
-BindingUpdateSeq RegistrarI::createBindingUpdateSeq(const std::string& aor, BindingSeq& bindings)
+BindingUpdateSeq RegistrarI::createBindingUpdateSeq(const std::string& aor, BindingHolderSeq& bindings)
 {
     BindingUpdateSeq returnedSeq;
     Ice::StringSeq contacts;
-    for (BindingSeq::iterator iter = bindings.begin(); iter != bindings.end(); ++iter)
+    for (BindingHolderSeq::iterator iter = bindings.begin(); iter != bindings.end(); ++iter)
     {
-        contacts.push_back((*iter)->contact);
+        contacts.push_back((*iter)->mBinding->contact);
     }
     BindingUpdate update;
     update.aor = aor;
@@ -207,7 +269,7 @@ bool verifyContacts(const std::vector<pjsip_contact_hdr *>& contacts)
     return true;
 }
 
-BindingSeq::iterator PJSipRegistrarModule::findMatchingBinding(pjsip_contact_hdr *contact, BindingSeq& bindings)
+BindingHolderSeq::iterator PJSipRegistrarModule::findMatchingBinding(pjsip_contact_hdr *contact, BindingHolderSeq& bindings)
 {
     char buf[512];
     pjsip_sip_uri *contactURI = (pjsip_sip_uri *)pjsip_uri_get_uri(contact->uri);
@@ -215,12 +277,12 @@ BindingSeq::iterator PJSipRegistrarModule::findMatchingBinding(pjsip_contact_hdr
     std::string contactURIStr(buf, strlen(buf));
 
     lg(Debug) << "Searching for binding " << contactURIStr;
-    for (BindingSeq::iterator iter = bindings.begin(); iter != bindings.end(); ++iter)
+    for (BindingHolderSeq::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) << "Comparing REGISTER contact " << contactURIStr << " with binding contact " << (*iter)->mBinding->contact;
+        if (contactURIStr == (*iter)->mBinding->contact)
         {
-            lg(Debug) << "Found matching binding " << (*iter)->contact;
+            lg(Debug) << "Found matching binding " << (*iter)->mBinding->contact;
             return iter;
         }
     }
@@ -254,49 +316,20 @@ int PJSipRegistrarModule::getExpiration(pjsip_contact_hdr *contact, pjsip_rx_dat
     }
 }
 
-void PJSipRegistrarModule::updateBinding(BindingPtr &binding, const std::string &callID, int cSeq, int expiration)
-{
-    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 *);
-
-class BindingHolder
+//XXX
+//This function could possibly be moved into the BindingHolder class...
+void PJSipRegistrarModule::updateBinding(BindingHolder *holder, const std::string &callID, int cSeq, int expiration)
 {
-public:
-    BindingHolder(int expiration, const BindingPtr& binding, const RegistrarIPtr& registrar, pjsip_endpoint *endpt)
-        : mRegistrar(registrar), mBinding(binding), mEndpoint(endpt)
-    {
-        mEntry.user_data = this;
-        mEntry.id = 0;
-        mEntry.cb = registrationExpired;
-        pj_time_val delay = {expiration, 0};
-        pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
-    }
-
-    void expireRegistration()
-    {
-        lg(Debug) << "Detected expiration of binding " << mBinding->contact;
-    }
-
-    RegistrarIPtr mRegistrar;
-    BindingPtr mBinding;
-    pjsip_endpoint *mEndpoint;
-    pj_timer_entry mEntry;
-};
-
-static void registrationExpired(pj_timer_heap_t *, struct pj_timer_entry *entry)
-{
-    BindingHolder *holder = static_cast<BindingHolder *>(entry->user_data);
-    holder->expireRegistration();
-    delete holder;
+    holder->mBinding->callid = callID;
+    holder->mBinding->cseq = cSeq;
+    holder->mBinding->expiration = time(NULL) + expiration;
+    pjsip_endpt_cancel_timer(holder->mEndpoint, &holder->mEntry);
+    pj_time_val delay = {expiration, 0};
+    pjsip_endpt_schedule_timer(mEndpoint, &holder->mEntry, &delay);
+    lg(Debug) << "Renewing binding " << holder->mBinding->contact << " for another " << expiration << " seconds.";
 }
 
-BindingPtr PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, const std::string &callID, int cSeq, int expiration)
+BindingHolder *PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, const std::string &callID, int cSeq, int expiration)
 {
     char buf[512];
     pjsip_sip_uri *contactURI = (pjsip_sip_uri *)pjsip_uri_get_uri(contact->uri);
@@ -308,11 +341,11 @@ BindingPtr PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, co
         << ", CSeq: " << cSeq
         << ", and Expires: " << expiration;
 
-    BindingPtr binding(new Binding(contactURIStr, callID, cSeq, expiration));
+    BindingPtr binding(new Binding(contactURIStr, callID, cSeq, time(NULL) + expiration));
     BindingHolder *holder(new BindingHolder(expiration, binding, mRegistrar, mEndpoint));
     //We could just return binding, but using holder here makes the compiler
     //not complain about an unused variable.
-    return holder->mBinding;
+    return holder;
 }
 
 pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
@@ -341,8 +374,7 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
 
     std::string aor = getAOR(rdata);
     lg(Debug) << "AoR in REGISTER is " << aor;
-    Ice::Current current;
-    BindingSeq currentBindings = mRegistrar->getAORBindings(aor, current);
+    BindingHolderSeq currentBindings = mRegistrar->getAORBindingHolders(aor);
     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));
@@ -358,35 +390,35 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
         pjsip_tsx_send_msg(tsx, tdata);
     }
 
-    BindingSeq newBindings;
-    BindingSeq removedBindings;
-    BindingSeq existingBindings;
+    BindingHolderSeq newBindings;
+    BindingHolderSeq removedBindings;
+    BindingHolderSeq existingBindings;
     for (std::vector<pjsip_contact_hdr *>::iterator iter = registerContacts.begin();
             iter != registerContacts.end(); ++iter)
     {
-        BindingSeq::iterator bindingToUpdate = findMatchingBinding(*iter, currentBindings);
+        BindingHolderSeq::iterator bindingToUpdate = findMatchingBinding(*iter, currentBindings);
 
         int expiration = getExpiration(*iter, rdata);
 
-        if (bindingToUpdate != existingBindings.end())
+        if (bindingToUpdate != currentBindings.end())
         {
             if (expiration == 0)
             {
-                lg(Debug) << "Adding " << (*bindingToUpdate)->contact << " to our bindings to remove";
+                lg(Debug) << "Adding " << (*bindingToUpdate)->mBinding->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";
+                updateBinding(*bindingToUpdate, callID, cSeq, expiration);
+                lg(Debug) << "Maintaining " << (*bindingToUpdate)->mBinding->contact << " in 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);
+            BindingHolder *holder = createNewBinding(*iter, callID, cSeq, expiration);
+            lg(Debug) << "Adding " << holder->mBinding->contact << " to our bindings to add";
+            newBindings.push_back(holder);
         }
     }
 
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
index ce8a8a2..5bd33df 100644
--- a/src/PJSipRegistrarModule.h
+++ b/src/PJSipRegistrarModule.h
@@ -26,6 +26,31 @@ namespace AsteriskSCF
 namespace SipSessionManager
 {
 
+class RegistrarI;
+typedef IceUtil::Handle<RegistrarI> RegistrarIPtr;
+
+class BindingHolder
+{
+public:
+    BindingHolder(
+            int expiration,
+            const AsteriskSCF::SIP::Registration::V1::BindingPtr& binding,
+            const RegistrarIPtr& registrar,
+            pjsip_endpoint *endpt);
+
+    void expireRegistration();
+
+    bool operator==(const BindingHolder& rhs);
+
+    RegistrarIPtr mRegistrar;
+    AsteriskSCF::SIP::Registration::V1::BindingPtr mBinding;
+    pjsip_endpoint *mEndpoint;
+    pj_timer_entry mEntry;
+};
+
+typedef std::vector<BindingHolder *> BindingHolderSeq;
+typedef std::map<std::string, BindingHolderSeq> BindingHolderDict;
+
 class RegistrarI : public AsteriskSCF::SIP::Registration::V1::Registrar
 {
 public:
@@ -34,19 +59,23 @@ public:
     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&);
+
+    BindingHolderSeq getAORBindingHolders(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);
+            const std::string &aor,
+            BindingHolderSeq& existingBindings,
+            BindingHolderSeq& newBindings,
+            BindingHolderSeq& removedBindings);
+
+    AsteriskSCF::SIP::Registration::V1::BindingUpdateSeq createBindingUpdateSeq(
+            const std::string& aor,
+            BindingHolderSeq& bindings);
 private:
-    AsteriskSCF::SIP::Registration::V1::BindingDict mBindings;
+    BindingHolderDict mBindings;
     AsteriskSCF::SIP::Registration::V1::ContactDict mContacts;
     std::vector<AsteriskSCF::SIP::Registration::V1::RegistrarListenerPrx> mListeners;
 };
 
-typedef IceUtil::Handle<RegistrarI> RegistrarIPtr;
-
 class PJSipRegistrarModule : public PJSipModule
 {
 public:
@@ -63,12 +92,12 @@ public:
 private:
     std::string getAOR(pjsip_rx_data *rdata);
     std::vector<pjsip_contact_hdr *> extractRegisterContacts(pjsip_rx_data *rdata);
-    AsteriskSCF::SIP::Registration::V1::BindingSeq::iterator findMatchingBinding(pjsip_contact_hdr *contact,
-            AsteriskSCF::SIP::Registration::V1::BindingSeq& bindings);
+    BindingHolderSeq::iterator findMatchingBinding(pjsip_contact_hdr *contact,
+            BindingHolderSeq& bindings);
     int getExpiration(pjsip_contact_hdr *contact, pjsip_rx_data *rdata);
-    AsteriskSCF::SIP::Registration::V1::BindingPtr createNewBinding(pjsip_contact_hdr *contact,
+    BindingHolder *createNewBinding(pjsip_contact_hdr *contact,
             const std::string& callID, int cSeq, int expiration);
-    void updateBinding(AsteriskSCF::SIP::Registration::V1::BindingPtr &binding,
+    void updateBinding(BindingHolder *binding,
             const std::string &callID, int cSeq, int expiration);
 
     pjsip_endpoint *mEndpoint;

commit 9ab8adb83f3038c03b8c1619bebcabbffc4e352e
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Jun 14 11:14:36 2011 -0500

    Create a container object for holding bindings so it is possible to actually
    expire a registration when the time runs out.
    
    Now to implement the expiration...

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index a70dce7..d847d8d 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -263,10 +263,37 @@ void PJSipRegistrarModule::updateBinding(BindingPtr &binding, const std::string
     //and schedule a new one here.
 }
 
+static void registrationExpired(pj_timer_heap_t *, struct pj_timer_entry *);
+
+class BindingHolder
+{
+public:
+    BindingHolder(int expiration, const BindingPtr& binding, const RegistrarIPtr& registrar, pjsip_endpoint *endpt)
+        : mRegistrar(registrar), mBinding(binding), mEndpoint(endpt)
+    {
+        mEntry.user_data = this;
+        mEntry.id = 0;
+        mEntry.cb = registrationExpired;
+        pj_time_val delay = {expiration, 0};
+        pjsip_endpt_schedule_timer(mEndpoint, &mEntry, &delay);
+    }
+
+    void expireRegistration()
+    {
+        lg(Debug) << "Detected expiration of binding " << mBinding->contact;
+    }
+
+    RegistrarIPtr mRegistrar;
+    BindingPtr mBinding;
+    pjsip_endpoint *mEndpoint;
+    pj_timer_entry mEntry;
+};
+
 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;
+    BindingHolder *holder = static_cast<BindingHolder *>(entry->user_data);
+    holder->expireRegistration();
+    delete holder;
 }
 
 BindingPtr PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, const std::string &callID, int cSeq, int expiration)
@@ -281,14 +308,11 @@ BindingPtr PJSipRegistrarModule::createNewBinding(pjsip_contact_hdr *contact, co
         << ", CSeq: " << cSeq
         << ", and Expires: " << 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;
+    BindingPtr binding(new Binding(contactURIStr, callID, cSeq, expiration));
+    BindingHolder *holder(new BindingHolder(expiration, binding, mRegistrar, mEndpoint));
+    //We could just return binding, but using holder here makes the compiler
+    //not complain about an unused variable.
+    return holder->mBinding;
 }
 
 pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)

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


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list