|
1 /* |
|
2 * Copyright 2005-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/util/OptParser.h> |
|
22 #include <oasys/util/StringBuffer.h> |
|
23 |
|
24 #include "Connectivity.h" |
|
25 #include "Node.h" |
|
26 #include "SimEvent.h" |
|
27 #include "SimConvergenceLayer.h" |
|
28 #include "Topology.h" |
|
29 |
|
30 #include "contacts/ContactManager.h" |
|
31 #include "contacts/Link.h" |
|
32 #include "naming/EndpointID.h" |
|
33 |
|
34 namespace dtnsim { |
|
35 |
|
36 //---------------------------------------------------------------------- |
|
37 Connectivity* Connectivity::instance_(NULL); |
|
38 std::string Connectivity::type_(""); |
|
39 |
|
40 //---------------------------------------------------------------------- |
|
41 Connectivity::Connectivity() |
|
42 : Logger("Connectivity", "/sim/conn") |
|
43 { |
|
44 } |
|
45 |
|
46 //---------------------------------------------------------------------- |
|
47 Connectivity* |
|
48 Connectivity::create_conn() |
|
49 { |
|
50 ASSERT(type_ != ""); |
|
51 |
|
52 if (type_ == "static") { |
|
53 // just the base class |
|
54 return new Connectivity(); |
|
55 } else { |
|
56 log_crit_p("/connectivity", "invalid connectivity module type %s", |
|
57 type_.c_str()); |
|
58 return NULL; |
|
59 } |
|
60 } |
|
61 |
|
62 //---------------------------------------------------------------------- |
|
63 bool |
|
64 ConnState::parse_time(const char* time_str, double* time) |
|
65 { |
|
66 char* end; |
|
67 *time = strtod(time_str, &end); |
|
68 |
|
69 if (end == time_str) |
|
70 return false; |
|
71 |
|
72 if (!strcmp(end, "us")) { |
|
73 *time = *time / 1000000.0; |
|
74 return true; |
|
75 |
|
76 } else if (!strcmp(end, "ms")) { |
|
77 *time = *time / 1000.0; |
|
78 return true; |
|
79 |
|
80 } else if (!strcmp(end, "s")) { |
|
81 return true; |
|
82 |
|
83 } else if (!strcmp(end, "min")) { |
|
84 *time = *time * 60; |
|
85 return true; |
|
86 |
|
87 } else if (!strcmp(end, "hr")) { |
|
88 *time = *time * 3600; |
|
89 return true; |
|
90 |
|
91 } else { |
|
92 return false; |
|
93 } |
|
94 } |
|
95 |
|
96 //---------------------------------------------------------------------- |
|
97 bool |
|
98 ConnState::parse_options(int argc, const char** argv, const char** invalidp) |
|
99 { |
|
100 oasys::OptParser p; |
|
101 std::string latency_str; |
|
102 |
|
103 p.addopt(new oasys::RateOpt("bw", &bw_)); |
|
104 p.addopt(new oasys::StringOpt("latency", &latency_str)); |
|
105 |
|
106 if (! p.parse(argc, argv, invalidp)) { |
|
107 return false; |
|
108 } |
|
109 |
|
110 if (latency_str != "" && !parse_time(latency_str.c_str(), &latency_)) { |
|
111 *invalidp = strdup(latency_str.c_str()); // leak! |
|
112 return false; |
|
113 } |
|
114 |
|
115 return true; |
|
116 } |
|
117 |
|
118 //---------------------------------------------------------------------- |
|
119 void |
|
120 Connectivity::set_state(const char* n1, const char* n2, const ConnState& s) |
|
121 { |
|
122 log_debug("set state %s,%s: %s bw=%llu latency=%f", |
|
123 n1, n2, s.open_ ? "up" : "down", U64FMT(s.bw_), s.latency_); |
|
124 |
|
125 // handle wildcards |
|
126 if (!strcmp(n1, "*")) { |
|
127 Topology::NodeTable* nodes = Topology::node_table(); |
|
128 |
|
129 for (Topology::NodeTable::iterator iter = nodes->begin(); |
|
130 iter != nodes->end(); ++iter) |
|
131 { |
|
132 if (strcmp(iter->second->name(), n2) != 0) { |
|
133 set_state(iter->second->name(), n2, s); |
|
134 } |
|
135 } |
|
136 return; |
|
137 } |
|
138 |
|
139 if (!strcmp(n2, "*")) { |
|
140 Topology::NodeTable* nodes = Topology::node_table(); |
|
141 |
|
142 for (Topology::NodeTable::iterator iter = nodes->begin(); |
|
143 iter != nodes->end(); ++iter) |
|
144 { |
|
145 if (strcmp(n1, iter->second->name()) != 0) { |
|
146 set_state(n1, iter->second->name(), s); |
|
147 } |
|
148 } |
|
149 return; |
|
150 } |
|
151 |
|
152 oasys::StringBuffer key("%s,%s", n1, n2); |
|
153 StateTable::iterator iter = state_.find(key.c_str()); |
|
154 if (iter != state_.end()) { |
|
155 iter->second = s; |
|
156 } else { |
|
157 state_[key.c_str()] = s; |
|
158 } |
|
159 |
|
160 SimConvergenceLayer::instance()-> |
|
161 update_connectivity(Topology::find_node(n1), |
|
162 Topology::find_node(n2), s); |
|
163 } |
|
164 |
|
165 //---------------------------------------------------------------------- |
|
166 const ConnState* |
|
167 Connectivity::lookup(Node* n1, Node* n2) |
|
168 { |
|
169 oasys::StringBuffer key("%s,%s", n1->name(), n2->name()); |
|
170 StateTable::iterator iter = state_.find(key.c_str()); |
|
171 if (iter == state_.end()) { |
|
172 return NULL; |
|
173 } |
|
174 return &iter->second; |
|
175 } |
|
176 |
|
177 } // namespace dtnsim |