diff -r 000000000000 -r 2b3e5ec03512 sim/Node.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sim/Node.cc Thu Apr 21 14:57:45 2011 +0100 @@ -0,0 +1,223 @@ +/* + * Copyright 2004-2006 Intel 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. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "SimEvent.h" +#include "SimLog.h" +#include "Node.h" +#include "bundling/BundleDaemon.h" +#include "contacts/ContactManager.h" +#include "contacts/Link.h" +#include "routing/BundleRouter.h" +#include "routing/RouteTable.h" +#include "reg/Registration.h" + +using namespace dtn; + +namespace dtnsim { + +//---------------------------------------------------------------------- +Node::Node(const char* name) + : BundleDaemon(), name_(name), + storage_config_("storage", + "memorydb", + "DTN", "") + +{ + logpathf("/node/%s", name); + log_info("node %s initializing...", name); + + storage_config_.init_ = true; + storage_config_.tidy_ = true; + storage_config_.tidy_wait_ = 0; + storage_config_.leave_clean_file_ = false; + + // XXX/demmer see comment in BundlePayload::init + storage_config_.payload_dir_ = "NO_PAYLOAD_FILES"; +} + +//---------------------------------------------------------------------- +void +Node::do_init() +{ + BundleDaemon::instance_ = this; + + actions_ = new BundleActions(); + eventq_ = new std::queue(); + + // forcibly create a new timer system and storage systems + oasys::Singleton::force_set_instance(NULL); + oasys::TimerSystem::create(); + timersys_ = oasys::TimerSystem::instance(); + + store_ = new oasys::DurableStore("/dtnsim/storage"); + store_->create_store(storage_config_); + + // we only have one GlobalStore because it's useful to have unique + // bundle ids across all nodes in the system, so initialize it the + // first node that gets created + if (! GlobalStore::initialized()) { + if (GlobalStore::init(storage_config_, store_) != 0) { + PANIC("Error initializing GlobalStore"); + } + } + + // the other stores are faux-singletons with an instance per node + BundleStore::force_set_instance(NULL); + ProphetStore::force_set_instance(NULL); + LinkStore::force_set_instance(NULL); + RegistrationStore::force_set_instance(NULL); + + log_info("creating storage tables"); + if ((BundleStore::init(storage_config_, store_) != 0) || + (LinkStore::init(storage_config_, store_) != 0) || + (ProphetStore::init(storage_config_, store_) != 0) || + (RegistrationStore::init(storage_config_, store_) != 0)) + { + PANIC("Error initializing storage tables"); + } + + bundle_store_ = BundleStore::instance(); + prophet_store_ = ProphetStore::instance(); + link_store_ = LinkStore::instance(); + reg_store_ = RegistrationStore::instance(); +} + +//---------------------------------------------------------------------- +void +Node::set_active() +{ + if (instance_ == this) return; + + instance_ = this; + oasys::Singleton::force_set_instance(timersys_); + oasys::Log::instance()->set_prefix(name_.c_str()); + + BundleStore::force_set_instance(bundle_store_); + ProphetStore::force_set_instance(prophet_store_); + LinkStore::force_set_instance(link_store_); + RegistrationStore::force_set_instance(reg_store_); +} + +//---------------------------------------------------------------------- +void +Node::configure() +{ + set_active(); + + router_ = BundleRouter::create_router(BundleRouter::config_.type_.c_str()); + router_->initialize(); +} + +//---------------------------------------------------------------------- +void +Node::post_event(BundleEvent* event, bool at_back) +{ + (void)at_back; + log_debug("posting event (%p) with type %s at %s ", + event, event->type_str(),at_back ? "back" : "head"); + + eventq_->push(event); +} + +//---------------------------------------------------------------------- +bool +Node::process_one_bundle_event() +{ + BundleEvent* event; + if (!eventq_->empty()) { + event = eventq_->front(); + eventq_->pop(); + handle_event(event); + delete event; + log_debug("event (%p) %s processed and deleted",event,event->type_str()); + return true; + } + return false; +} + +//---------------------------------------------------------------------- +void +Node::run_one_event_now(BundleEvent* event) +{ + Node* cur_active = active_node(); + set_active(); + handle_event(event); + log_debug("event (%p) %s processed",event,event->type_str()); + cur_active->set_active(); +} + +//---------------------------------------------------------------------- +void +Node::process(SimEvent* e) +{ + switch (e->type()) { + case SIM_BUNDLE_EVENT: + post_event(((SimBundleEvent*)e)->event_); + break; + + default: + NOTREACHED; + } +} + +//---------------------------------------------------------------------- +void +Node::handle_bundle_delivered(BundleDeliveredEvent* event) +{ + SimLog::instance()->log_arrive(this, event->bundleref_.object()); + BundleDaemon::handle_bundle_delivered(event); +} + +//---------------------------------------------------------------------- +void +Node::handle_bundle_received(BundleReceivedEvent* event) +{ + Bundle* bundle = event->bundleref_.object(); + SimLog::instance()->log_recv(this, bundle); + + // XXX/demmer this needs to look at the history of all duplicates, + // not just the duplicates right now... + + Bundle* duplicate = find_duplicate(bundle); + if (duplicate != NULL) { + SimLog::instance()->log_dup(this, bundle); + } + BundleDaemon::handle_bundle_received(event); +} + +//---------------------------------------------------------------------- +void +Node::handle_bundle_transmitted(BundleTransmittedEvent* event) +{ + SimLog::instance()->log_xmit(this, event->bundleref_.object()); + BundleDaemon::handle_bundle_transmitted(event); +} + + +//---------------------------------------------------------------------- +void +Node::handle_bundle_expired(BundleExpiredEvent* event) +{ + SimLog::instance()->log_expire(this, event->bundleref_.object()); + BundleDaemon::handle_bundle_expired(event); +} + +} // namespace dtnsim