|
1 /* |
|
2 * Copyright 2004-2006 Intel Corporation |
|
3 * |
|
4 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 * you may not use this file except in compliance with the License. |
|
6 * You may obtain a copy of the License at |
|
7 * |
|
8 * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 * |
|
10 * Unless required by applicable law or agreed to in writing, software |
|
11 * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 * See the License for the specific language governing permissions and |
|
14 * limitations under the License. |
|
15 */ |
|
16 |
|
17 #ifdef HAVE_CONFIG_H |
|
18 # include <dtn-config.h> |
|
19 #endif |
|
20 |
|
21 #include <oasys/thread/Timer.h> |
|
22 #include "SimEvent.h" |
|
23 #include "SimLog.h" |
|
24 #include "Node.h" |
|
25 #include "bundling/BundleDaemon.h" |
|
26 #include "contacts/ContactManager.h" |
|
27 #include "contacts/Link.h" |
|
28 #include "routing/BundleRouter.h" |
|
29 #include "routing/RouteTable.h" |
|
30 #include "reg/Registration.h" |
|
31 |
|
32 using namespace dtn; |
|
33 |
|
34 namespace dtnsim { |
|
35 |
|
36 //---------------------------------------------------------------------- |
|
37 Node::Node(const char* name) |
|
38 : BundleDaemon(), name_(name), |
|
39 storage_config_("storage", |
|
40 "memorydb", |
|
41 "DTN", "") |
|
42 |
|
43 { |
|
44 logpathf("/node/%s", name); |
|
45 log_info("node %s initializing...", name); |
|
46 |
|
47 storage_config_.init_ = true; |
|
48 storage_config_.tidy_ = true; |
|
49 storage_config_.tidy_wait_ = 0; |
|
50 storage_config_.leave_clean_file_ = false; |
|
51 |
|
52 // XXX/demmer see comment in BundlePayload::init |
|
53 storage_config_.payload_dir_ = "NO_PAYLOAD_FILES"; |
|
54 } |
|
55 |
|
56 //---------------------------------------------------------------------- |
|
57 void |
|
58 Node::do_init() |
|
59 { |
|
60 BundleDaemon::instance_ = this; |
|
61 |
|
62 actions_ = new BundleActions(); |
|
63 eventq_ = new std::queue<BundleEvent*>(); |
|
64 |
|
65 // forcibly create a new timer system and storage systems |
|
66 oasys::Singleton<oasys::TimerSystem>::force_set_instance(NULL); |
|
67 oasys::TimerSystem::create(); |
|
68 timersys_ = oasys::TimerSystem::instance(); |
|
69 |
|
70 store_ = new oasys::DurableStore("/dtnsim/storage"); |
|
71 store_->create_store(storage_config_); |
|
72 |
|
73 // we only have one GlobalStore because it's useful to have unique |
|
74 // bundle ids across all nodes in the system, so initialize it the |
|
75 // first node that gets created |
|
76 if (! GlobalStore::initialized()) { |
|
77 if (GlobalStore::init(storage_config_, store_) != 0) { |
|
78 PANIC("Error initializing GlobalStore"); |
|
79 } |
|
80 } |
|
81 |
|
82 // the other stores are faux-singletons with an instance per node |
|
83 BundleStore::force_set_instance(NULL); |
|
84 ProphetStore::force_set_instance(NULL); |
|
85 LinkStore::force_set_instance(NULL); |
|
86 RegistrationStore::force_set_instance(NULL); |
|
87 |
|
88 log_info("creating storage tables"); |
|
89 if ((BundleStore::init(storage_config_, store_) != 0) || |
|
90 (LinkStore::init(storage_config_, store_) != 0) || |
|
91 (ProphetStore::init(storage_config_, store_) != 0) || |
|
92 (RegistrationStore::init(storage_config_, store_) != 0)) |
|
93 { |
|
94 PANIC("Error initializing storage tables"); |
|
95 } |
|
96 |
|
97 bundle_store_ = BundleStore::instance(); |
|
98 prophet_store_ = ProphetStore::instance(); |
|
99 link_store_ = LinkStore::instance(); |
|
100 reg_store_ = RegistrationStore::instance(); |
|
101 } |
|
102 |
|
103 //---------------------------------------------------------------------- |
|
104 void |
|
105 Node::set_active() |
|
106 { |
|
107 if (instance_ == this) return; |
|
108 |
|
109 instance_ = this; |
|
110 oasys::Singleton<oasys::TimerSystem>::force_set_instance(timersys_); |
|
111 oasys::Log::instance()->set_prefix(name_.c_str()); |
|
112 |
|
113 BundleStore::force_set_instance(bundle_store_); |
|
114 ProphetStore::force_set_instance(prophet_store_); |
|
115 LinkStore::force_set_instance(link_store_); |
|
116 RegistrationStore::force_set_instance(reg_store_); |
|
117 } |
|
118 |
|
119 //---------------------------------------------------------------------- |
|
120 void |
|
121 Node::configure() |
|
122 { |
|
123 set_active(); |
|
124 |
|
125 router_ = BundleRouter::create_router(BundleRouter::config_.type_.c_str()); |
|
126 router_->initialize(); |
|
127 } |
|
128 |
|
129 //---------------------------------------------------------------------- |
|
130 void |
|
131 Node::post_event(BundleEvent* event, bool at_back) |
|
132 { |
|
133 (void)at_back; |
|
134 log_debug("posting event (%p) with type %s at %s ", |
|
135 event, event->type_str(),at_back ? "back" : "head"); |
|
136 |
|
137 eventq_->push(event); |
|
138 } |
|
139 |
|
140 //---------------------------------------------------------------------- |
|
141 bool |
|
142 Node::process_one_bundle_event() |
|
143 { |
|
144 BundleEvent* event; |
|
145 if (!eventq_->empty()) { |
|
146 event = eventq_->front(); |
|
147 eventq_->pop(); |
|
148 handle_event(event); |
|
149 delete event; |
|
150 log_debug("event (%p) %s processed and deleted",event,event->type_str()); |
|
151 return true; |
|
152 } |
|
153 return false; |
|
154 } |
|
155 |
|
156 //---------------------------------------------------------------------- |
|
157 void |
|
158 Node::run_one_event_now(BundleEvent* event) |
|
159 { |
|
160 Node* cur_active = active_node(); |
|
161 set_active(); |
|
162 handle_event(event); |
|
163 log_debug("event (%p) %s processed",event,event->type_str()); |
|
164 cur_active->set_active(); |
|
165 } |
|
166 |
|
167 //---------------------------------------------------------------------- |
|
168 void |
|
169 Node::process(SimEvent* e) |
|
170 { |
|
171 switch (e->type()) { |
|
172 case SIM_BUNDLE_EVENT: |
|
173 post_event(((SimBundleEvent*)e)->event_); |
|
174 break; |
|
175 |
|
176 default: |
|
177 NOTREACHED; |
|
178 } |
|
179 } |
|
180 |
|
181 //---------------------------------------------------------------------- |
|
182 void |
|
183 Node::handle_bundle_delivered(BundleDeliveredEvent* event) |
|
184 { |
|
185 SimLog::instance()->log_arrive(this, event->bundleref_.object()); |
|
186 BundleDaemon::handle_bundle_delivered(event); |
|
187 } |
|
188 |
|
189 //---------------------------------------------------------------------- |
|
190 void |
|
191 Node::handle_bundle_received(BundleReceivedEvent* event) |
|
192 { |
|
193 Bundle* bundle = event->bundleref_.object(); |
|
194 SimLog::instance()->log_recv(this, bundle); |
|
195 |
|
196 // XXX/demmer this needs to look at the history of all duplicates, |
|
197 // not just the duplicates right now... |
|
198 |
|
199 Bundle* duplicate = find_duplicate(bundle); |
|
200 if (duplicate != NULL) { |
|
201 SimLog::instance()->log_dup(this, bundle); |
|
202 } |
|
203 BundleDaemon::handle_bundle_received(event); |
|
204 } |
|
205 |
|
206 //---------------------------------------------------------------------- |
|
207 void |
|
208 Node::handle_bundle_transmitted(BundleTransmittedEvent* event) |
|
209 { |
|
210 SimLog::instance()->log_xmit(this, event->bundleref_.object()); |
|
211 BundleDaemon::handle_bundle_transmitted(event); |
|
212 } |
|
213 |
|
214 |
|
215 //---------------------------------------------------------------------- |
|
216 void |
|
217 Node::handle_bundle_expired(BundleExpiredEvent* event) |
|
218 { |
|
219 SimLog::instance()->log_expire(this, event->bundleref_.object()); |
|
220 BundleDaemon::handle_bundle_expired(event); |
|
221 } |
|
222 |
|
223 } // namespace dtnsim |