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