servlib/conv_layers/NORMSessionManager.cc
changeset 0 2b3e5ec03512
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/conv_layers/NORMSessionManager.cc	Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2008 The MITRE Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * The US Government will not be charged any license fee and/or royalties
+ * related to this software. Neither name of The MITRE Corporation; nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ */
+
+/*
+ * This product includes software written and developed 
+ * by Brian Adamson and Joe Macker of the Naval Research 
+ * Laboratory (NRL).
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <dtn-config.h>
+#endif
+
+#if defined(NORM_ENABLED)
+
+#include "NORMSessionManager.h"
+
+namespace dtn {
+
+template<>
+NORMSessionManager* oasys::Singleton<NORMSessionManager, true>::instance_ = NULL;
+
+//----------------------------------------------------------------------
+NORMSessionManager::NORMSessionManager()
+    : Thread("NORMSessionManager", DELETE_ON_EXIT),
+      Logger("NORMSessionManager", "/dtn/cl/norm/NORMSessionManager"),
+      norm_instance_(NORM_INSTANCE_INVALID)
+{
+}
+
+//----------------------------------------------------------------------
+NORMSessionManager::~NORMSessionManager() {
+    receiver_list_t::iterator iter = receivers_.begin();
+    receiver_list_t::iterator end = receivers_.end();
+    for (; iter != end; ++iter) {
+        NormStopReceiver((*iter).session_);
+    }
+    receivers_.clear();
+    destroy_instance();
+}
+
+//----------------------------------------------------------------------
+void
+NORMSessionManager::init() {
+    if (! norm_instance_) {
+        norm_instance_ = NormCreateInstance();
+        if (norm_instance_ == NORM_INSTANCE_INVALID) {
+            PANIC("failed to create NORM protocol engine");
+        }
+        start();
+    }
+}
+
+//----------------------------------------------------------------------
+void
+NORMSessionManager::run() {
+    NormEvent event;
+    while (NormGetNextEvent(norm_instance_, &event))
+    {
+        oasys::ScopeLock l(&lock_, "NORMSessionManger::run");
+
+        receiver_list_t::iterator begin = receivers_.begin();
+        receiver_list_t::iterator end = receivers_.end();
+        receiver_list_t::iterator pos = std::find(begin, end, event.session);
+        if (pos == receivers_.end())
+            continue;
+
+        switch (event.type)
+        {
+#define CASE(event_type) \
+    case event_type: \
+    log_debug(#event_type); \
+    break;
+            CASE(NORM_RX_OBJECT_NEW)
+            CASE(NORM_TX_QUEUE_VACANCY)
+            CASE(NORM_TX_QUEUE_EMPTY)
+            CASE(NORM_TX_FLUSH_COMPLETED)
+            CASE(NORM_TX_WATERMARK_COMPLETED)
+            CASE(NORM_TX_OBJECT_SENT)
+            CASE(NORM_TX_OBJECT_PURGED)
+            CASE(NORM_LOCAL_SENDER_CLOSED)
+            CASE(NORM_CC_ACTIVE)
+            CASE(NORM_CC_INACTIVE)
+            CASE(NORM_REMOTE_SENDER_NEW)
+            CASE(NORM_REMOTE_SENDER_ACTIVE)
+            CASE(NORM_REMOTE_SENDER_INACTIVE)
+            CASE(NORM_REMOTE_SENDER_PURGED)
+            CASE(NORM_RX_OBJECT_INFO)
+            CASE(NORM_RX_OBJECT_UPDATED)
+
+            case NORM_RX_OBJECT_COMPLETED: {
+                 log_debug("NORM_RX_OBJECT_COMPLETED");
+                 NormObjectRetain(event.object);
+                 break;
+            }
+
+            CASE(NORM_TX_CMD_SENT)
+            CASE(NORM_RX_CMD_NEW)
+            CASE(NORM_RX_OBJECT_ABORTED)
+            CASE(NORM_GRTT_UPDATED)
+            CASE(NORM_EVENT_INVALID)
+            default:
+                break;
+#undef CASE
+        }
+
+        (*pos).queue_->push_back(event);
+    }
+}
+
+//----------------------------------------------------------------------
+void
+NORMSessionManager::register_receiver(const NORMReceiver *receiver)
+{
+    ASSERT(norm_instance_);
+    NORMParameters *params = receiver->link_params_;
+    NormSessionHandle session = params->norm_session();
+
+    log_debug("new receiver: session: %p eventq: %p",
+              session, receiver->eventq_);
+
+    // configure the receiver
+    NormSetTOS(session, params->tos());
+    NormSetDefaultRxRobustFactor(session, params->rx_robust_factor());
+    NormSetSilentReceiver(session, params->silent());
+
+    // push the new norm receiver onto the list
+    receivers_.push_back(NORMNode(session, receiver->eventq_));
+    NormStartReceiver(session, params->rx_buf_size());
+}
+
+//----------------------------------------------------------------------
+void
+NORMSessionManager::remove_receiver(const NORMReceiver *receiver)
+{
+    oasys::ScopeLock l(&lock_, "NORMSessionManger::remove_receiver");
+
+    ASSERT(norm_instance_);
+    NORMParameters *params = receiver->link_params_;
+    NormSessionHandle session = params->norm_session();
+
+    receiver_list_t::iterator begin = receivers_.begin();
+    receiver_list_t::iterator end = receivers_.end();
+    receiver_list_t::iterator pos = std::find(begin, end, session);
+
+    ASSERT(pos != receivers_.end())
+    log_debug("remove receiver: session: %p eventq: %p",
+              session, (*pos).queue_);
+
+    NormEvent stop;
+    stop.type = NORM_EVENT_INVALID;
+    stop.session = NORM_SESSION_INVALID;
+    stop.sender = NORM_NODE_INVALID;
+    stop.object = NORM_OBJECT_INVALID;
+    (*pos).queue_->push_back(stop);
+
+    NormStopReceiver(session);
+    receivers_.erase(pos);
+}
+
+//----------------------------------------------------------------------
+void
+NORMSessionManager::destroy_instance(bool stop_first)
+{
+    if (norm_instance_) {
+        if (stop_first) {
+            NormStopInstance(norm_instance_);
+        }
+        NormDestroyInstance(norm_instance_);
+        norm_instance_ = 0;
+    }
+}
+
+} // namespace dtn
+#endif // NORM_ENABLED