--- /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