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

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Mar 25 17:15:22 CDT 2011


branch "registrar" has been created
        at  5aa5e56f84e645b9c5238215ef4fdeb0eba28f20 (commit)

- Log -----------------------------------------------------------------
commit 5aa5e56f84e645b9c5238215ef4fdeb0eba28f20
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Mar 25 17:14:43 2011 -0500

    Start writing REGISTER-handling logic.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index c19fba0..ece92d6 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -33,6 +33,52 @@ namespace AsteriskSCF
 namespace SipSessionManager
 {
 
+class RegistrarI : public Registrar
+{
+public:
+    RegistrarI() { }
+
+    ContactDict addListener(const RegistrarListenerPrx& listener)
+    {
+        if (std::find(mListener.begin(), mListener.end(), listener) != mListener.end())
+        {
+            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));
+    }
+
+    BindingDict getAllBindings()
+    {
+        return mBindings;
+    }
+
+    BindingSeq getAORbindings(const std::string &aor)
+    {
+        BindingDict::iterator iter = mBindings.find(aor);
+        if (iter != mBindings.end())
+        {
+            return *iter;
+        }
+        else
+        {
+            //XXX Make this a static class member so that
+            //it can be returned on demand.
+            BindingSeq empty;
+            return empty;
+        }
+    }
+    
+    BindingDict mBindings;
+    ContactDict mContacts;
+    std::vector<RegistrarListenerPrx> mListeners;
+};
+
 pj_status_t PJSipRegistrarModule::load(pjsip_endpoint *endpt)
 {
     return PJ_SUCCESS;
@@ -53,28 +99,113 @@ pj_status_t PJSipRegistrarModule::unload()
     return PJ_SUCCESS;
 }
 
+BindingSeq PJSipRegistrarModule::getExistingBindings(pjsip_rx_data *rdata)
+{
+    pjsip_sip_uri *toURI = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.to->uri);
+    char buf[512];
+    pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, to->uri, buf, sizeof(buf));
+    std::string aor(buf, strlen(buf));
+ 
+    // Now we need to find the list of bindings that we have that are associated with
+    // this AoR. 
+    return mRegistrar->getAORBindings(aor);
+}
+
+Ice::StringSeq PJSipRegistrarModule::extractRegisterContacts(pjsip_rx_data *rdata)
+{
+    Ice::StringSeq registerContacts;
+    pjsip_contact_hdr *contact = NULL;
+    while ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact)))
+    {
+        if (contact->star != 0)
+        {
+
+        }
+        else
+        {
+            char buf[512];
+            pjsip_sip_uri *contactURI = (pjsip_sip_uri *) pjsip_uri_get_uri(contact->uri);
+            pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contactURI, buf, sizeof(buf));
+            //XXX PICK UP HERE NEXT TIME
+        }
+    }
+}
+
 pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
 {
+    // This is where we'll be handling incoming requests. What's the
+    // proper procedure?
+    
+
+    // 1. Make sure this is a REGISTER request. If it's not go ahead
+    // and return PJ_FALSE right away.
+
+    if (rdata->msg_info.msg->line.req.method.id != PJSIP_REGISTER_METHOD)
+    {
+        return PJ_FALSE;
+    }
+
+    // 2. We need to determine if the REGISTER should be authenticated.
+    // This should be nearly exactly the same as the session module's
+    // procedure. For now, leave this commented out since auth work
+    // has not been merged to master.
+
+    // Step 2.5 would be perhaps some sort of determination of who the
+    // REGISTER is from and determining whether they have permission
+    // to be doing this sort of thing. How this is done is still murky
+    // and should perhaps be put in writing on the wiki or in some other
+    // way decided upon before trying to write any code for it.
+
+    // 3. Determine the AoR to which this REGISTER pertains. This means
+    // to check out the To header.
+    
+    BindingSeq existingBindings = getExistingBindings(rdata);
+   
+    // 4. Extract each binding from the REGISTER. This means to grab
+    // all Contact headers.
+
+    Ice::StringSeq registerContacts = extractRegisterContacts(rdata);
+
+    // 5. Find if we already know of each binding. This means to look
+    // up bindings in our local map.
+    //
+    // 6. Unknown contacts results in new bindings being created. This
+    // results in both state replication as well as notifying listeners.
+    //
+    // 7. Known contacts with a non-zero expiration result in an update
+    // in the bindings' expiration times. This only results in state
+    // replication.
+    //
+    // 8. Known contacts with a zero expiration result in the bindings'
+    // erasure. This results in state replication and notifying listeners.
+    //
+    // 9. We're done! Send back a 200 OK!
     return PJ_FALSE;
 }
 
 pj_bool_t PJSipRegistrarModule::on_rx_response(pjsip_rx_data *rdata)
 {
+    // The registrar is purely a UAS and will never get any responses.
     return PJ_FALSE;
 }
 
 pj_status_t PJSipRegistrarModule::on_tx_request(pjsip_tx_data *tdata)
 {
+    // The registrar is purely a UAS and will never send requests.
     return PJ_SUCCESS;
 }
 
 pj_status_t PJSipRegistrarModule::on_tx_response(pjsip_tx_data *tdata)
 {
+    // I can't think of anything in particular we'd want to do prior
+    // to sending a response.
     return PJ_SUCCESS;
 }
 
 void PJSipRegistrarModule::on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
 {
+    // I can't think of anything we'd want to do on a transaction state
+    // change.
 }
 
 };

commit dd490ab030f402537f7edac3d1fcd443bc602e68
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Mar 25 11:27:20 2011 -0500

    Add skeleton code for PJSipRegistrarModule.

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d03df8c..e9b9f9a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,6 +27,9 @@ asterisk_scf_component_add_file(SipSessionManager PJSipSessionModule.h)
 asterisk_scf_component_add_file(SipSessionManager PJSipLoggingModule.cpp)
 asterisk_scf_component_add_file(SipSessionManager PJSipLoggingModuleConstruction.cpp)
 asterisk_scf_component_add_file(SipSessionManager PJSipLoggingModule.h)
+asterisk_scf_component_add_file(SipSessionManager PJSipRegistrarModule.cpp)
+asterisk_scf_component_add_file(SipSessionManager PJSipRegistrarModuleConstruction.cpp)
+asterisk_scf_component_add_file(SipSessionManager PJSipRegistrarModule.h)
 asterisk_scf_component_add_file(SipSessionManager SipStateReplicatorListener.cpp)
 asterisk_scf_component_add_file(SipSessionManager SipStateReplicator.h)
 asterisk_scf_component_add_slice(SipSessionManager ../local-slice/SipIf.ice)
diff --git a/src/PJSipManager.cpp b/src/PJSipManager.cpp
index 22b5955..8897d92 100644
--- a/src/PJSipManager.cpp
+++ b/src/PJSipManager.cpp
@@ -86,6 +86,11 @@ void PJSipManager::registerLoggingModule()
     mLoggingModule = new PJSipLoggingModule(mEndpoint);
 }
 
+void PJSipManager::registerRegistrarModule()
+{
+    mRegistrarModule = new PJSipRegistrarModule(mEndpoint);
+}
+
 PJSipSessionModule *PJSipManager::getSessionModule()
 {
     return mSessionModule;
diff --git a/src/PJSipManager.h b/src/PJSipManager.h
index eaedf0d..33094b0 100644
--- a/src/PJSipManager.h
+++ b/src/PJSipManager.h
@@ -29,6 +29,7 @@
 
 #include "PJSipSessionModule.h"
 #include "PJSipLoggingModule.h"
+#include "PJSipRegistrarModule.h"
 
 namespace AsteriskSCF
 {
@@ -80,11 +81,19 @@ public:
      * for logging incoming and outgoing SIP messages
      */
     void registerLoggingModule();
+
+    /**
+     * Register the PJSIPRegistrar, responsible
+     * for keeping track of bindings of contact URIs to
+     * addresses of record.
+     */
+    void registerRegistrarModule();
 private:
     static PJSipManager *mInstance;
     pjsip_endpoint *mEndpoint;
     PJSipSessionModule *mSessionModule;
     PJSipLoggingModule *mLoggingModule;
+    PJSipRegistrarModule *mRegistrarModule;
     pj_thread_t *mPjThread;
     pj_caching_pool mCachingPool;
     pj_pool_t *mMemoryPool;
diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
new file mode 100644
index 0000000..c19fba0
--- /dev/null
+++ b/src/PJSipRegistrarModule.cpp
@@ -0,0 +1,81 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <AsteriskSCF/SIP/SIPRegistrarIf.h>
+#include <AsteriskSCF/logger.h>
+
+#include "PJSipRegistrarModule.h"
+
+using namespace AsteriskSCF::SIP::Registration::V1;
+using namespace AsteriskSCF::System::Logging;
+
+namespace
+{
+Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
+}
+
+namespace AsteriskSCF
+{
+
+namespace SipSessionManager
+{
+
+pj_status_t PJSipRegistrarModule::load(pjsip_endpoint *endpt)
+{
+    return PJ_SUCCESS;
+}
+
+pj_status_t PJSipRegistrarModule::start()
+{
+    return PJ_SUCCESS;
+}
+
+pj_status_t PJSipRegistrarModule::stop()
+{
+    return PJ_SUCCESS;
+}
+
+pj_status_t PJSipRegistrarModule::unload()
+{
+    return PJ_SUCCESS;
+}
+
+pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
+{
+    return PJ_FALSE;
+}
+
+pj_bool_t PJSipRegistrarModule::on_rx_response(pjsip_rx_data *rdata)
+{
+    return PJ_FALSE;
+}
+
+pj_status_t PJSipRegistrarModule::on_tx_request(pjsip_tx_data *tdata)
+{
+    return PJ_SUCCESS;
+}
+
+pj_status_t PJSipRegistrarModule::on_tx_response(pjsip_tx_data *tdata)
+{
+    return PJ_SUCCESS;
+}
+
+void PJSipRegistrarModule::on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
+{
+}
+
+};
+};
diff --git a/src/PJSipRegistrarModule.h b/src/PJSipRegistrarModule.h
new file mode 100644
index 0000000..4875cd2
--- /dev/null
+++ b/src/PJSipRegistrarModule.h
@@ -0,0 +1,43 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include "PJSipModule.h"
+
+namespace AsteriskSCF
+{
+
+namespace SipSessionManager
+{
+
+class PJSipRegistrarModule : public PJSipModule
+{
+public:
+    PJSipRegistrarModule(pjsip_endpoint *endpt);
+    pj_status_t load(pjsip_endpoint *endpoint);
+    pj_status_t start();
+    pj_status_t stop();
+    pj_status_t unload();
+    pj_bool_t on_rx_request(pjsip_rx_data *rdata);
+    pj_bool_t on_rx_response(pjsip_rx_data *rdata);
+    pj_status_t on_tx_request(pjsip_tx_data *tdata);
+    pj_status_t on_tx_response(pjsip_tx_data *tdata);
+    void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event);
+};
+
+};
+};
diff --git a/src/PJSipRegistrarModuleConstruction.cpp b/src/PJSipRegistrarModuleConstruction.cpp
new file mode 100644
index 0000000..909993d
--- /dev/null
+++ b/src/PJSipRegistrarModuleConstruction.cpp
@@ -0,0 +1,97 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include "PJSipRegistrarModule.h"
+
+namespace AsteriskSCF
+{
+
+namespace SipSessionManager
+{
+
+static char registrarModuleName[] = "PJSipRegistrarModule";
+
+static PJSipRegistrarModule *registrarModule;
+
+static pj_status_t registrarLoad(pjsip_endpoint *endpoint)
+{
+    return registrarModule->load(endpoint);
+}
+
+static pj_status_t registrarStart()
+{
+    return registrarModule->unload();
+}
+
+static pj_status_t registrarStop()
+{
+    return registrarModule->stop();
+}
+
+static pj_status_t registrarUnload()
+{
+    return registrarModule->unload();
+}
+
+static pj_bool_t registrarOnRxRequest(pjsip_rx_data *rdata)
+{
+    return registrarModule->on_rx_request(rdata);
+}
+
+static pj_bool_t registrarOnRxResponse(pjsip_rx_data *rdata)
+{
+    return registrarModule->on_rx_response(rdata);
+}
+
+static pj_bool_t registrarOnTxRequest(pjsip_tx_data *tdata)
+{
+    return registrarModule->on_tx_request(tdata);
+}
+
+static pj_status_t registrarOnTxResponse(pjsip_tx_data *tdata)
+{
+    return registrarModule->on_tx_response(tdata);
+}
+
+static void registrarOnTsxState(pjsip_transaction *tsx, pjsip_event *event)
+{
+    return registrarModule->on_tsx_state(tsx, event);
+}
+
+PJSipRegistrarModule::PJSipRegistrarModule(pjsip_endpoint *endpt)
+{
+    registrarModule = this;
+    mModule.name = pj_str(registrarModuleName);
+    // This is the highest priority module. We do this
+    // so that on outgoing messages, the transport information
+    // will have been filled in by the transport layer. This way
+    // what we log is exactly the same as what goes out over the
+    // wire.
+    mModule.priority = 0;
+    mModule.load = registrarLoad;
+    mModule.start = registrarStart;
+    mModule.stop = registrarStop;
+    mModule.unload = registrarUnload;
+    mModule.on_rx_request = registrarOnRxRequest;
+    mModule.on_rx_response = registrarOnRxResponse;
+    mModule.on_tx_request = registrarOnTxRequest;
+    mModule.on_tx_response = registrarOnTxResponse;
+    mModule.on_tsx_state = registrarOnTsxState;
+    pjsip_endpt_register_module(endpt, &mModule);
+}
+
+};
+};
diff --git a/src/SipSessionManagerApp.cpp b/src/SipSessionManagerApp.cpp
index 2afe7ab..d201251 100644
--- a/src/SipSessionManagerApp.cpp
+++ b/src/SipSessionManagerApp.cpp
@@ -466,6 +466,10 @@ void SipSessionManager::registerPJSipModules()
         {
             mPJSipManager->registerLoggingModule();
         }
+        else if (*i == "Registrar")
+        {
+            mPJSipManager->registerRegistrarModule();
+        }
     }
     lg(Debug) << "Registered PJSIP modules";
 }

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


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list