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 Mar 6 16:47:47 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6