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

node.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) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *      This product includes software developed by the Computer Systems
00017  *      Engineering Group at Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * $Header: /nfs/jade/vint/CVSROOT/ns-2/common/node.cc,v 1.34 2002/05/30 17:44:03 haldar Exp $
00035  *
00036  * CMU-Monarch project's Mobility extensions ported by Padma Haldar, 
00037  * 10/98.
00038  */
00039 
00040 #include <stdio.h>
00041 #include <stdarg.h>
00042 
00043 #include "address.h"
00044 #include "config.h"
00045 #ifdef HAVE_STL
00046 #include "nix/nixnode.h"
00047 #endif //HAVE_STL
00048 #include "node.h"
00049 
00050 static class LinkHeadClass : public TclClass {
00051 public:
00052         LinkHeadClass() : TclClass("Connector/LinkHead") {}
00053         TclObject* create(int, const char*const*) {
00054                 return (new LinkHead);
00055         }
00056 } class_link_head;
00057 
00058 LinkHead::LinkHead() : net_if_(0), node_(0), type_(0) { }
00059 
00060 int32_t LinkHead::label() 
00061 {
00062         if (net_if_)
00063                 return net_if_->intf_label();
00064         printf("Configuration error:  Network Interface missing\n");
00065         exit(1);
00066         // Make msvc happy
00067         return 0;
00068 }
00069 
00070 int LinkHead::command(int argc, const char*const* argv)
00071 {
00072         if (argc == 3) {
00073                 if(strcmp(argv[1], "setnetinf") == 0) {
00074                         net_if_ =
00075                                 (NetworkInterface*) TclObject::lookup(argv[2]);
00076                         if (net_if_ == 0)
00077                                 return TCL_ERROR;
00078                         return TCL_OK;
00079                 } else if(strcmp(argv[1], "setnode") == 0) {
00080                         node_ = (Node*) TclObject::lookup(argv[2]); 
00081                         if (node_ == 0)
00082                                 return TCL_ERROR;
00083                         return TCL_OK;
00084                 }
00085         }
00086         return (Connector::command(argc, argv));
00087 }
00088 
00089 
00090 static class NodeClass : public TclClass {
00091 public:
00092         NodeClass() : TclClass("Node") {}
00093         TclObject* create(int, const char*const*) {
00094                 return (new Node);
00095         }
00096 } class_node;
00097 
00098 struct node_head Node::nodehead_ = { 0 }; // replaces LIST_INIT macro
00099 
00100 char Node::nwrk_[NODE_NAMLOG_BUFSZ];
00101 
00102 /* Additions for NixRouting */
00103 int NixRoutingUsed = -1;
00104 
00105 Node::Node() : 
00106         address_(-1), nodeid_ (-1), namChan_(0),
00107         rtnotif_(NULL),
00108 #ifdef HAVE_STL
00109         nixnode_(NULL),
00110 #endif //HAVE_STL
00111         energy_model_(NULL), location_(NULL)
00112 {
00113         LIST_INIT(&ifhead_);
00114         LIST_INIT(&linklisthead_);
00115         insert(&(Node::nodehead_)); // insert self into static list of nodes
00116 #ifdef HAVE_STL
00117         // Mods for Nix-Vector routing
00118         if (NixRoutingUsed < 0) {
00119                 // Find out if nix routing is in use
00120                 Tcl& tcl = Tcl::instance();
00121                 tcl.evalf("Simulator set nix-routing");
00122                 tcl.resultAs(&NixRoutingUsed);
00123         }
00124         if (NixRoutingUsed) {
00125                 // Create the NixNode pointer
00126                 if(0)printf("Nix routing in use, creating NixNode\n");
00127                 nixnode_ = new NixNode();
00128         }
00129 #endif //HAVE_STL
00130         neighbor_list_ = NULL;
00131 }
00132 
00133 Node::~Node()
00134 {
00135         LIST_REMOVE(this, entry);
00136 }
00137 
00138 int
00139 Node::command(int argc, const char*const* argv)
00140 {
00141         Tcl& tcl = Tcl::instance();
00142         if (argc == 2) {
00143 #ifdef HAVE_STL
00144                 // Mods for Nix-Vector Routing
00145                 if(strcmp(argv[1], "populate-objects") == 0) {
00146                         if (nixnode_) {
00147                                 nixnode_->PopulateObjects();
00148                         }
00149                         return TCL_OK;
00150                 }
00151                 // End mods for Nix-Vector routing
00152 #endif // HAVE_STL
00153                 if(strcmp(argv[1], "address?") == 0) {
00154                         tcl.resultf("%d", address_);
00155                         return TCL_OK;
00156                 }
00157                 
00158                 
00159         } else if (argc == 3) {
00160 #ifdef HAVE_STL
00161                 // Mods for Nix-Vector Routing
00162                 if (strcmp(argv[1], "get-nix-vector") == 0) {
00163                         if (nixnode_) {
00164                                 nixnode_->GetNixVector(atol(argv[2]));
00165                         }
00166                         return TCL_OK;
00167                 }
00168 #endif //HAVE_STL
00169                 if (strcmp(argv[1], "set-neighbor") == 0) {
00170 #ifdef HAVE_STL
00171                         if (nixnode_) {
00172                                 nixnode_->AddAdj(atol(argv[2]));
00173                         }
00174 #endif //HAVE_STL
00175                         return(TCL_OK);
00176                 }
00177                 if (strcmp(argv[1], "addr") == 0) {
00178                         address_ = Address::instance().str2addr(argv[2]);
00179 #ifdef HAVE_STL
00180                         if (nixnode_) {
00181                                 nixnode_->Id(address_);
00182                         }
00183 #endif //HAVE_STL
00184                         return TCL_OK;
00185                 // End mods for Nix-Vector routing
00186                 } else if (strcmp(argv[1], "nodeid") == 0) {
00187                         nodeid_ = atoi(argv[2]);
00188                         return TCL_OK;
00189                 } else if(strcmp(argv[1], "addlinkhead") == 0) {
00190                         LinkHead* slhp = (LinkHead*)TclObject::lookup(argv[2]);
00191                         if (slhp == 0)
00192                                 return TCL_ERROR;
00193                         slhp->insertlink(&linklisthead_);
00194                         return TCL_OK;
00195                 } else if (strcmp(argv[1], "addenergymodel") == 0) {
00196                         energy_model_=(EnergyModel*)TclObject::lookup(argv[2]);
00197                         if(!energy_model_)
00198                                 return TCL_ERROR;
00199                         return TCL_OK;
00200                 } else if (strcmp(argv[1], "namattach") == 0) {
00201                         int mode;
00202                         namChan_ = Tcl_GetChannel(tcl.interp(), (char*)argv[2],
00203                                                   &mode);
00204                         if (namChan_ == 0) {
00205                                 tcl.resultf("node: can't attach %s", argv[2]);
00206                                 return (TCL_ERROR);
00207                         }
00208                         return (TCL_OK);
00209                 } else if (strcmp(argv[1], "add-neighbor") == 0) {
00210                         Node * node = (Node *)TclObject::lookup(argv[2]);
00211                         if (node == 0) {
00212                                 tcl.resultf("Invalid node %s", argv[2]);
00213                                  return (TCL_ERROR);
00214                         }
00215                         addNeighbor(node);
00216                         return TCL_OK;
00217                 }
00218         }
00219         return ParentNode::command(argc,argv);
00220 }
00221 
00222 void Node::route_notify(RoutingModule *rtm) {
00223         if (rtnotif_ == NULL)
00224                 rtnotif_ = rtm;
00225         else
00226                 rtnotif_->route_notify(rtm);
00227 }
00228 
00229 void Node::unreg_route_notify(RoutingModule *rtm) {
00230         if (rtnotif_) {
00231                 if (rtnotif_ == rtm) {
00232                         //RoutingModule *tmp = rtnotif_;
00233                         rtnotif_= rtnotif_->next_rtm_;
00234                         //free (tmp);
00235                 }
00236                 else
00237                         rtnotif_->unreg_route_notify(rtm);
00238         }
00239 }
00240 
00241 void Node::add_route(char *dst, NsObject *target) {
00242         if (rtnotif_)
00243                 rtnotif_->add_route(dst, target);
00244 }
00245 
00246 
00247 void Node::delete_route(char *dst, NsObject *nullagent) {
00248         if (rtnotif_)
00249                 rtnotif_->delete_route(dst, nullagent);
00250 }
00251 
00252 void Node::set_table_size(int nn) {
00253         if (rtnotif_)
00254                 rtnotif_->set_table_size(nn);
00255 }
00256 
00257 void Node::set_table_size(int level, int csize) {
00258         if (rtnotif_)
00259                 rtnotif_->set_table_size(level, csize);
00260 }
00261 
00262 void Node::addNeighbor(Node * neighbor) {
00263 
00264         neighbor_list_node* nlistItem = (neighbor_list_node *)malloc(sizeof(neighbor_list_node));
00265         nlistItem->nodeid = neighbor->nodeid();
00266         nlistItem->next = neighbor_list_;
00267         neighbor_list_=nlistItem; 
00268 }
00269 
00270 void Node::namlog(const char* fmt, ...)
00271 {
00272         // Don't do anything if we don't have a log file.
00273         if (namChan_ == 0) 
00274                 return;
00275         va_list ap;
00276         va_start(ap, fmt);
00277         vsprintf(nwrk_, fmt, ap);
00278         namdump();
00279 }
00280 
00281 void Node::namdump()
00282 {
00283         int n = 0;
00284         /* Otherwise nwrk_ isn't initialized */
00285         n = strlen(nwrk_);
00286         if (n >= NODE_NAMLOG_BUFSZ-1) {
00287                 fprintf(stderr, 
00288                         "Node::namdump() exceeds buffer size. Bail out.\n");
00289                 abort();
00290         }
00291         if (n > 0) {
00292                 /*
00293                  * tack on a newline (temporarily) instead
00294                  * of doing two writes
00295                  */
00296                 nwrk_[n] = '\n';
00297                 nwrk_[n + 1] = 0;
00298                 (void)Tcl_Write(namChan_, nwrk_, n + 1);
00299                 nwrk_[n] = 0;
00300         }
00301 }
00302 
00303 // Given an interface label for a NetworkInterface on this node, we return 
00304 // the head of that link
00305 NsObject* Node::intf_to_target(int32_t label)
00306 {
00307         LinkHead *lhp = linklisthead_.lh_first;
00308         for (; lhp; lhp = lhp->nextlinkhead()) 
00309                 if (label == lhp->label())
00310                         return ((NsObject*) lhp);
00311         return NULL;
00312 }
00313 
00314 // A class static method. Return the node instance from the static node list
00315 Node* Node::get_node_by_address (nsaddr_t id)
00316 {
00317         Node * tnode = nodehead_.lh_first;
00318         for (; tnode; tnode = tnode->nextnode()) {
00319                 if (tnode->address_ == id ) {
00320                         return (tnode);
00321                 }
00322         }
00323         return NULL;
00324 }

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