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

rtProtoLS.cc

Go to the documentation of this file.
00001 // Copyright (c) 2000 by the University of Southern California
00002 // All rights reserved.
00003 //
00004 // Permission to use, copy, modify, and distribute this software and its
00005 // documentation in source and binary forms for non-commercial purposes
00006 // and without fee is hereby granted, provided that the above copyright
00007 // notice appear in all copies and that both the copyright notice and
00008 // this permission notice appear in supporting documentation. and that
00009 // any documentation, advertising materials, and other materials related
00010 // to such distribution and use acknowledge that the software was
00011 // developed by the University of Southern California, Information
00012 // Sciences Institute.  The name of the University may not be used to
00013 // endorse or promote products derived from this software without
00014 // specific prior written permission.
00015 //
00016 // THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
00017 // the suitability of this software for any purpose.  THIS SOFTWARE IS
00018 // PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
00019 // INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 //
00022 // Other copyrights might apply to parts of this software and are so
00023 // noted when applicable.
00024 //
00025 //  Copyright (C) 1998 by Mingzhou Sun. All rights reserved.
00026 //  This software is developed at Rensselaer Polytechnic Institute under 
00027 //  DARPA grant No. F30602-97-C-0274
00028 //  Redistribution and use in source and binary forms are permitted
00029 //  provided that the above copyright notice and this paragraph are
00030 //  duplicated in all such forms and that any documentation, advertising
00031 //  materials, and other materials related to such distribution and use
00032 //  acknowledge that the software was developed by Mingzhou Sun at the
00033 //  Rensselaer  Polytechnic Institute.  The name of the University may not 
00034 //  be used to endorse or promote products derived from this software 
00035 //  without specific prior written permission.
00036 //
00037 // $Header: /nfs/jade/vint/CVSROOT/ns-2/linkstate/rtProtoLS.cc,v 1.5 2002/05/30 17:44:04 haldar Exp $
00038 
00039 #include "config.h"
00040 #ifdef HAVE_STL
00041 
00042 #include "hdr-ls.h"
00043 #include "rtProtoLS.h"
00044 #include "agent.h"
00045 #include "string.h" // for strtok
00046 
00047 // Helper classes
00048 class LsTokenList : public LsList<char *> {
00049 public:
00050         LsTokenList (char * str, const char * delim ) 
00051                 : LsList<char*> () { 
00052                 for ( char * token = strtok (str, delim);
00053                       token != NULL; token = strtok(NULL, delim) ) {
00054                         push_back (token);
00055                 }
00056         }
00057 };
00058    
00059 class LsIntList : public LsList<int> {
00060 public:
00061         LsIntList (char * str, const char * delim)
00062                 : LsList<int> () {
00063                 for ( char * token = strtok (str, delim);
00064                       token != NULL; token = strtok(NULL, delim) ) {
00065                         push_back ( atoi(token) );
00066                 }
00067         }
00068 };
00069 
00070 static class rtProtoLSclass : public TclClass {
00071 public:
00072         rtProtoLSclass() : TclClass("Agent/rtProto/LS") {}
00073         TclObject* create(int, const char*const*) {
00074                 return (new rtProtoLS);
00075         }
00076 } class_rtProtoLS;
00077 
00078 
00079 int rtProtoLS::command(int argc, const char*const* argv)
00080 {
00081         if (strcmp(argv[1], "send-update") == 0) {
00082                 ns_addr_t dst;
00083                 dst.addr_ = atoi(argv[2]);
00084                 dst.port_ = atoi(argv[3]);
00085                 u_int32_t mtvar = atoi(argv[4]);
00086                 u_int32_t size  = atoi(argv[5]);
00087                 sendpkt(dst, mtvar, size);
00088                 return TCL_OK;
00089        }
00090         /* --------------- LS specific --------------- */
00091         if (strcmp(argv[1], "lookup") == 0) {
00092                 if (argc == 3) {
00093                         int dst = atoi(argv[2]);
00094                         lookup (dst);
00095                         /* use tcl.resultf () to return the lookup results */
00096                         return TCL_OK;
00097                 }
00098         }  
00099         if (strcmp(argv[1], "initialize") == 0) {
00100                 initialize ();
00101                 return TCL_OK;
00102         }
00103         if (strcmp(argv[1], "setDelay" ) == 0 ) {
00104                 if ( argc == 4) {
00105                         int nbrId = atoi(argv[2]);
00106                         double delay = strtod ( argv[3], NULL);
00107                         setDelay(nbrId, delay);
00108                         return TCL_OK;
00109                 }
00110         }
00111         if (strcmp(argv[1], "setNodeNumber" ) == 0 ) {
00112                 if ( argc == 3 ) {
00113                         int number_of_nodes = atoi(argv[2]);
00114                         LsMessageCenter::instance().setNodeNumber(number_of_nodes);
00115                 }
00116                 return TCL_OK;
00117         }
00118         if (strcmp(argv[1], "computeRoutes") == 0) {
00119                 computeRoutes();
00120                 return TCL_OK;
00121         }
00122         if (strcmp(argv[1], "intfChanged") == 0) {
00123                 intfChanged();
00124                 return TCL_OK;
00125         }
00126         if (strcmp (argv[1], "send-buffered-messages") == 0) {
00127                 sendBufferedMessages();
00128                 return TCL_OK;
00129         }
00130         if (strcmp(argv[1], "sendUpdates") == 0) {
00131                 sendUpdates ();
00132                 return TCL_OK;
00133         }
00134         return Agent::command(argc, argv);
00135 }
00136 
00137 void rtProtoLS::sendpkt(ns_addr_t dst, u_int32_t mtvar, u_int32_t size)
00138 {
00139         dst_ = dst;
00140         size_ = size;
00141         
00142         Packet* p = Agent::allocpkt();
00143         hdr_LS *rh = hdr_LS::access(p);
00144         rh->metricsVar() = mtvar;
00145 
00146         target_->recv(p);               
00147 }
00148 
00149 void rtProtoLS::recv(Packet* p, Handler*)
00150 {   
00151         hdr_LS* rh = hdr_LS::access(p);
00152         hdr_ip* ih = hdr_ip::access(p);
00153         // -- LS stuffs --
00154         if (LS_ready_ || (rh->metricsVar() == LS_BIG_NUMBER))
00155                 receiveMessage(findPeerNodeId(ih->src()), rh->msgId());
00156         else
00157                 Tcl::instance().evalf("%s recv-update %d %d", name(),
00158                                       ih->saddr(), rh->metricsVar());
00159         Packet::free(p);
00160 }
00161 
00162 /* LS specific */
00163 // implement tcl cmd's
00164 
00165 /* -- findPeerNodeId -- */
00166 int rtProtoLS::findPeerNodeId (ns_addr_t agentAddr) 
00167 {
00168         // because the agentAddr is the value, not the key of the map
00169         for (PeerAddrMap::iterator itr = peerAddrMap_.begin();
00170              itr != peerAddrMap_.end(); itr++) {
00171                 if ((*itr).second == agentAddr) {
00172                         return (*itr).first;
00173                 }
00174         }
00175         return LS_INVALID_NODE_ID;
00176 }
00177 
00178 void rtProtoLS::initialize() // init nodeState_ and routing_
00179 {
00180         Tcl & tcl = Tcl::instance();
00181         // call tcl get-node-id, atoi, set nodeId
00182         tcl.evalf("%s get-node-id", name());
00183         char * resultString = tcl.result();
00184         nodeId_ = atoi(resultString);
00185   
00186         // call tcl get-peers, strtok, set peerAddrMap, peerIdList;
00187         tcl.evalf("%s get-peers", name());
00188         resultString = tcl.result();
00189 
00190         int nodeId, neighborId;
00191         ns_addr_t peer;
00192         ls_status_t status;
00193         int cost;
00194 
00195         // XXX no error checking for now yet. tcl MUST return pairs of numbers
00196         for ( LsIntList intList(resultString, " \t\n");
00197               !intList.empty(); ) {
00198                 nodeId = intList.front();
00199                 intList.pop_front();
00200                 // Agent.addr_
00201                 peer.addr_ = intList.front();
00202                 intList.pop_front();
00203                 peer.port_ = intList.front();
00204                 intList.pop_front();
00205                 peerAddrMap_.insert(nodeId, peer);
00206                 peerIdList_.push_back(nodeId);
00207         }
00208         
00209         // call tcl get-links-status, strtok, set linkStateList;
00210         tcl.evalf("%s get-links-status", name());
00211         resultString = tcl.result();
00212         // cout << "get-links-status:\t" << resultString <<endl; 
00213         // XXX no error checking for now. tcl MUST return triplets of numbers
00214         for ( LsIntList intList2(resultString, " \t\n");
00215               !intList2.empty(); ) {
00216                 neighborId = intList2.front();
00217                 intList2.pop_front();
00218                 status = (ls_status_t) intList2.front();
00219                 intList2.pop_front();
00220                 cost = (int) intList2.front();
00221                 intList2.pop_front();
00222                 linkStateList_.push_back(LsLinkState(neighborId,status,cost));
00223         }    
00224 
00225         // call tcl get-delay-estimates
00226         tcl.evalf ("%s get-delay-estimates", name());
00227 
00228         // call routing.init(this); and computeRoutes
00229         routing_.init(this);
00230         routing_.computeRoutes();
00231         // debug
00232         tcl.evalf("%s set LS_ready", name());
00233         char* token = strtok(tcl.result(), " \t\n");
00234         if (token == NULL) 
00235                 LS_ready_ = 0;
00236         else
00237                 LS_ready_ = atoi(token); // buggy
00238 }
00239 
00240 void rtProtoLS::intfChanged ()
00241 {
00242         // XXX redudant, to be changed later
00243         Tcl & tcl = Tcl::instance();
00244         // call tcl get-links-status, strtok, set linkStateList;
00245         tcl.evalf("%s get-links-status", name());
00246         char * resultString = tcl.result();
00247 
00248         // destroy the old link states
00249         linkStateList_.eraseAll();
00250         // XXX no error checking for now. tcl MUST return triplets of numbers
00251   
00252         for (LsIntList intList2(resultString, " \t\n");
00253              !intList2.empty(); ) {
00254                 int neighborId = intList2.front();
00255                 intList2.pop_front();
00256                 ls_status_t  status = ( ls_status_t ) intList2.front();
00257                 intList2.pop_front();
00258                 int cost = (int) intList2.front();
00259                 intList2.pop_front();
00260                 // LsLinkState ls;
00261                 // ls.init(neighborId, status, cost);
00262                 linkStateList_.push_back(LsLinkState(neighborId,status,cost));
00263         }    
00264         // call routing_'s LinkStateChanged() 
00265         //   for now, don't compute routes yet (?)
00266         routing_.linkStateChanged();
00267 }
00268 
00269 void rtProtoLS::lookup(int destId) 
00270 {
00271         // Call routing_'s lookup
00272         LsEqualPaths* EPptr = routing_.lookup(destId);
00273 
00274         // then use tcl.resultf() to return the results
00275         if (EPptr == NULL) {
00276                 Tcl::instance().resultf( "%s",  "");
00277                 return;
00278         }
00279         char resultBuf[64]; // XXX buggy;
00280         sprintf(resultBuf, "%d" , EPptr->cost);
00281         char tmpBuf[16]; // XXX
00282  
00283         for (LsNodeIdList::iterator itr = (EPptr->nextHopList).begin();
00284              itr != (EPptr->nextHopList).end(); itr++) {
00285                 sprintf(tmpBuf, " %d", (*itr) );
00286                 strcat (resultBuf, tmpBuf); // strcat (dest, src);
00287         }
00288 
00289         Tcl::instance().resultf("%s", resultBuf);
00290 }
00291 
00292 void rtProtoLS::receiveMessage(int sender, u_int32_t msgId) 
00293 { 
00294         if (routing_.receiveMessage(sender, msgId))
00295                 installRoutes();
00296 }
00297 
00298 // Implementing LsNode interface
00299 bool rtProtoLS::sendMessage(int destId, u_int32_t messageId, int size) 
00300 {
00301         ns_addr_t* agentAddrPtr = peerAddrMap_.findPtr(destId);
00302         if (agentAddrPtr == NULL) 
00303                 return false;
00304         dst_ = *agentAddrPtr;
00305         size_ = size;
00306   
00307         Packet* p = Agent::allocpkt();
00308         hdr_LS *rh = hdr_LS::access(p);
00309         rh->msgId() = messageId;
00310         rh->metricsVar() = LS_BIG_NUMBER;
00311         target_->recv(p);           
00312         // sendpkt( *agentAddrPtr , messageId, size);
00313         return true;
00314 }
00315 
00316 #endif // HAVE_STL

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