00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include <oasys/util/OptParser.h>
00022 #include <oasys/util/StringBuffer.h>
00023
00024 #include "Connectivity.h"
00025 #include "Node.h"
00026 #include "SimEvent.h"
00027 #include "SimConvergenceLayer.h"
00028 #include "Topology.h"
00029
00030 #include "contacts/ContactManager.h"
00031 #include "contacts/Link.h"
00032 #include "naming/EndpointID.h"
00033
00034 namespace dtnsim {
00035
00036
00037 Connectivity* Connectivity::instance_(NULL);
00038 std::string Connectivity::type_("");
00039
00040
00041 Connectivity::Connectivity()
00042 : Logger("Connectivity", "/sim/conn")
00043 {
00044 }
00045
00046
00047 Connectivity*
00048 Connectivity::create_conn()
00049 {
00050 ASSERT(type_ != "");
00051
00052 if (type_ == "static") {
00053
00054 return new Connectivity();
00055 } else {
00056 log_crit_p("/connectivity", "invalid connectivity module type %s",
00057 type_.c_str());
00058 return NULL;
00059 }
00060 }
00061
00062
00063 bool
00064 ConnState::parse_time(const char* time_str, double* time)
00065 {
00066 char* end;
00067 *time = strtod(time_str, &end);
00068
00069 if (end == time_str)
00070 return false;
00071
00072 if (!strcmp(end, "us")) {
00073 *time = *time / 1000000.0;
00074 return true;
00075
00076 } else if (!strcmp(end, "ms")) {
00077 *time = *time / 1000.0;
00078 return true;
00079
00080 } else if (!strcmp(end, "s")) {
00081 return true;
00082
00083 } else if (!strcmp(end, "min")) {
00084 *time = *time * 60;
00085 return true;
00086
00087 } else if (!strcmp(end, "hr")) {
00088 *time = *time * 3600;
00089 return true;
00090
00091 } else {
00092 return false;
00093 }
00094 }
00095
00096
00097 bool
00098 ConnState::parse_options(int argc, const char** argv, const char** invalidp)
00099 {
00100 oasys::OptParser p;
00101 std::string latency_str;
00102
00103 p.addopt(new oasys::RateOpt("bw", &bw_));
00104 p.addopt(new oasys::StringOpt("latency", &latency_str));
00105
00106 if (! p.parse(argc, argv, invalidp)) {
00107 return false;
00108 }
00109
00110 if (latency_str != "" && !parse_time(latency_str.c_str(), &latency_)) {
00111 *invalidp = strdup(latency_str.c_str());
00112 return false;
00113 }
00114
00115 return true;
00116 }
00117
00118
00119 void
00120 Connectivity::set_state(const char* n1, const char* n2, const ConnState& s)
00121 {
00122 log_debug("set state %s,%s: %s bw=%llu latency=%f",
00123 n1, n2, s.open_ ? "up" : "down", U64FMT(s.bw_), s.latency_);
00124
00125
00126 if (!strcmp(n1, "*")) {
00127 Topology::NodeTable* nodes = Topology::node_table();
00128
00129 for (Topology::NodeTable::iterator iter = nodes->begin();
00130 iter != nodes->end(); ++iter)
00131 {
00132 if (strcmp(iter->second->name(), n2) != 0) {
00133 set_state(iter->second->name(), n2, s);
00134 }
00135 }
00136 return;
00137 }
00138
00139 if (!strcmp(n2, "*")) {
00140 Topology::NodeTable* nodes = Topology::node_table();
00141
00142 for (Topology::NodeTable::iterator iter = nodes->begin();
00143 iter != nodes->end(); ++iter)
00144 {
00145 if (strcmp(n1, iter->second->name()) != 0) {
00146 set_state(n1, iter->second->name(), s);
00147 }
00148 }
00149 return;
00150 }
00151
00152 oasys::StringBuffer key("%s,%s", n1, n2);
00153 StateTable::iterator iter = state_.find(key.c_str());
00154 if (iter != state_.end()) {
00155 iter->second = s;
00156 } else {
00157 state_[key.c_str()] = s;
00158 }
00159
00160 SimConvergenceLayer::instance()->
00161 update_connectivity(Topology::find_node(n1),
00162 Topology::find_node(n2), s);
00163 }
00164
00165
00166 const ConnState*
00167 Connectivity::lookup(Node* n1, Node* n2)
00168 {
00169 oasys::StringBuffer key("%s,%s", n1->name(), n2->name());
00170 StateTable::iterator iter = state_.find(key.c_str());
00171 if (iter == state_.end()) {
00172 return NULL;
00173 }
00174 return &iter->second;
00175 }
00176
00177 }