00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "simulator.h"
00048 #include "node.h"
00049 #include "address.h"
00050 #include "object.h"
00051
00052
00053
00054 static class SimulatorClass : public TclClass {
00055 public:
00056 SimulatorClass() : TclClass("Simulator") {}
00057 TclObject* create(int argc, const char*const* argv) {
00058 return (new Simulator);
00059 }
00060 } simulator_class;
00061
00062 Simulator* Simulator::instance_;
00063
00064 int Simulator::command(int argc, const char*const* argv) {
00065 Tcl& tcl = Tcl::instance();
00066 if ((instance_ == 0) || (instance_ != this))
00067 instance_ = this;
00068 if (argc == 3) {
00069 if (strcmp(argv[1], "populate-flat-classifiers") == 0) {
00070 nn_ = atoi(argv[2]);
00071 populate_flat_classifiers();
00072 return TCL_OK;
00073 }
00074 if (strcmp(argv[1], "populate-hier-classifiers") == 0) {
00075 nn_ = atoi(argv[2]);
00076 populate_hier_classifiers();
00077 return TCL_OK;
00078 }
00079 if (strcmp(argv[1], "get-routelogic") == 0) {
00080 rtobject_ = (RouteLogic *)(TclObject::lookup(argv[2]));
00081 if (rtobject_ == NULL) {
00082 tcl.add_errorf("Wrong rtobject name %s", argv[2]);
00083 return TCL_ERROR;
00084 }
00085 return TCL_OK;
00086 }
00087 if (strcmp(argv[1], "mac-type") == 0) {
00088 if (strlen(argv[2]) >= SMALL_LEN) {
00089 tcl.add_errorf("Length of mac-type name must be < %d", SMALL_LEN);
00090 return TCL_ERROR;
00091 }
00092 strcpy(macType_, argv[2]);
00093 return TCL_OK;
00094 }
00095 }
00096 if (argc == 4) {
00097 if (strcmp(argv[1], "add-node") == 0) {
00098 Node *node = (Node *)(TclObject::lookup(argv[2]));
00099 if (node == NULL) {
00100 tcl.add_errorf("Wrong object name %s",argv[2]);
00101 return TCL_ERROR;
00102 }
00103 int id = atoi(argv[3]);
00104 add_node(node, id);
00105 return TCL_OK;
00106 } else if (strcmp(argv[1], "add-lannode") == 0) {
00107 LanNode *node = (LanNode *)(TclObject::lookup(argv[2]));
00108 if (node == NULL) {
00109 tcl.add_errorf("Wrong object name %s",argv[2]);
00110 return TCL_ERROR;
00111 }
00112 int id = atoi(argv[3]);
00113 add_node(node, id);
00114 return TCL_OK;
00115 } else if (strcmp(argv[1], "add-abslan-node") == 0) {
00116 AbsLanNode *node = (AbsLanNode *)(TclObject::lookup(argv[2]));
00117 if (node == NULL) {
00118 tcl.add_errorf("Wrong object name %s",argv[2]);
00119 return TCL_ERROR;
00120 }
00121 int id = atoi(argv[3]);
00122 add_node(node, id);
00123 return TCL_OK;
00124 } else if (strcmp(argv[1], "add-broadcast-node") == 0) {
00125 BroadcastNode *node = (BroadcastNode *)(TclObject::lookup(argv[2]));
00126 if (node == NULL) {
00127 tcl.add_errorf("Wrong object name %s",argv[2]);
00128 return TCL_ERROR;
00129 }
00130 int id = atoi(argv[3]);
00131 add_node(node, id);
00132 return TCL_OK;
00133 }
00134 }
00135 return (TclObject::command(argc, argv));
00136 }
00137
00138 void Simulator::add_node(ParentNode *node, int id) {
00139 if (nodelist_ == NULL)
00140 nodelist_ = new ParentNode*[SMALL_LEN];
00141 check(id);
00142 nodelist_[id] = node;
00143 }
00144
00145 void Simulator::alloc(int n) {
00146 size_ = n;
00147 nodelist_ = new ParentNode*[n];
00148 for (int i=0; i<n; i++)
00149 nodelist_[i] = NULL;
00150 }
00151
00152
00153 void Simulator::check(int n) {
00154 if (n < size_)
00155 return;
00156 ParentNode **old = nodelist_;
00157 int osize = size_;
00158 int m = osize;
00159 if (m == 0)
00160 m = SMALL_LEN;
00161 while (m <= n)
00162 m <<= 1;
00163 alloc(m);
00164 for (int i=0; i < osize; i++)
00165 nodelist_[i] = old[i];
00166 delete [] old;
00167 }
00168
00169 void Simulator::populate_flat_classifiers() {
00170
00171
00172
00173 char tmp[SMALL_LEN];
00174 if (nodelist_ == NULL)
00175 return;
00176
00177
00178
00179 check(nn_);
00180 for (int i=0; i<nn_; i++) {
00181 if (nodelist_[i] == NULL) {
00182 i++;
00183 continue;
00184 }
00185 nodelist_[i]->set_table_size(nn_);
00186 for (int j=0; j<nn_; j++) {
00187 if (i != j) {
00188 int nh = -1;
00189 nh = rtobject_->lookup_flat(i, j);
00190 if (nh >= 0) {
00191 NsObject *l_head = get_link_head(nodelist_[i], nh);
00192 sprintf(tmp, "%d", j);
00193 nodelist_[i]->add_route(tmp, l_head);
00194 }
00195 }
00196 }
00197 }
00198 }
00199
00200
00201 void Simulator::populate_hier_classifiers() {
00202
00203
00204
00205 int n_addr, levels, nh;
00206 int addr[TINY_LEN];
00207 char a[SMALL_LEN];
00208
00209 check(nn_);
00210 for (int i=0; i<nn_; i++) {
00211 if (nodelist_[i] == NULL) {
00212 i++;
00213 continue;
00214 }
00215 n_addr = nodelist_[i]->address();
00216 char *addr_str = Address::instance().
00217 print_nodeaddr(n_addr);
00218 levels = Address::instance().levels_;
00219 int k;
00220 for (k=1; k <= levels; k++)
00221 addr[k-1] = Address::instance().hier_addr(n_addr, k);
00222 for (k=1; k <= levels; k++) {
00223 int csize = rtobject_->elements_in_level(addr, k);
00224 nodelist_[i]->set_table_size(k, csize);
00225
00226 char *prefix = NULL;
00227 if (k > 1)
00228 prefix = append_addr(k, addr);
00229 for (int m=0; m < csize; m++) {
00230 if (m == addr[k-1])
00231 continue;
00232 nh = -1;
00233 if (k > 1) {
00234 sprintf(a, "%s%d", prefix,m);
00235 } else
00236 sprintf(a, "%d", m);
00237 rtobject_->lookup_hier(addr_str, a, nh);
00238 if (nh == -1)
00239 continue;
00240 int n_id = node_id_by_addr(nh);
00241 if (n_id >= 0) {
00242 NsObject *l_head = get_link_head(nodelist_[i], n_id);
00243 nodelist_[i]->add_route(a, l_head);
00244 }
00245 }
00246 if (prefix)
00247 delete [] prefix;
00248 }
00249 delete [] addr_str;
00250 }
00251 }
00252
00253
00254 int Simulator::node_id_by_addr(int address) {
00255 for (int i=0; i<nn_; i++) {
00256 if(nodelist_[i]->address() == address)
00257 return (nodelist_[i]->nodeid());
00258 }
00259 return -1;
00260 }
00261
00262 char *Simulator::append_addr(int level, int *addr) {
00263 if (level > 1) {
00264 char tmp[TINY_LEN], a[SMALL_LEN];
00265 char *str;
00266 a[0] = '\0';
00267 for (int i=2; i<= level; i++) {
00268 sprintf(tmp, "%d.",addr[i-2]);
00269 strcat(a, tmp);
00270 }
00271
00272
00273
00274
00275 str = new char[strlen(a) + 1];
00276 strcpy(str, a);
00277 return (str);
00278 }
00279 return NULL;
00280 }
00281
00282
00283 NsObject* Simulator::get_link_head(ParentNode *node, int nh) {
00284 Tcl& tcl = Tcl::instance();
00285 tcl.evalf("[Simulator instance] get-link-head %d %d",
00286 node->nodeid(), nh);
00287 NsObject *l_head = (NsObject *)TclObject::lookup(tcl.result());
00288 return l_head;
00289 }
00290