Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

simulator.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- 
00002  *
00003  * Copyright (C) 2000 by USC/ISI
00004  * All rights reserved.                                            
00005  *                                                                
00006  * Redistribution and use in source and binary forms are permitted
00007  * provided that the above copyright notice and this paragraph are
00008  * duplicated in all such forms and that any documentation, advertising
00009  * materials, and other materials related to such distribution and use
00010  * acknowledge that the software was developed by the University of
00011  * Southern California, Information Sciences Institute.  The name of the
00012  * University may not be used to endorse or promote products derived from
00013  * this software without specific prior written permission.
00014  * 
00015  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
00016  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00017  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00018  */
00019 
00020 #include "simulator.h"
00021 #include "node.h"
00022 #include "address.h"
00023 #include "object.h"
00024 
00025 //class ParentNode;
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 // check if enough room in nodelist_
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         // Set up each classifer (aka node) to act as a router.
00133         // Point each classifer table to the link object that
00134         // in turns points to the right node.
00135         char tmp[TINY_LEN];
00136         if (nodelist_ == NULL)
00137                 return;
00138 
00139         // Updating nodelist_ (total no of connected nodes)
00140         // size since size_ maybe smaller than nn_ (total no of nodes)
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         // Set up each classifer (aka node) to act as a router.
00165         // Point each classifer table to the link object that
00166         // in turns points to the right node.
00167         int n_addr, levels, nh;
00168         int addr[TINY_LEN];
00169         char a[SMALL_LEN];
00170         // update the size of nodelist with nn_
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                 // To fix the bug of writing beyond the end of 
00235                 // allocated memory for hierarchical addresses (xuanc, 1/14/02)
00236                 // contributed by Joerg Diederich <dieder@ibr.cs.tu-bs.de>
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 

Generated on Tue Apr 20 12:14:32 2004 for NS2.26SourcesOriginal by doxygen 1.3.3