rtProtoLS.cc

Go to the documentation of this file.
00001 
00002 /*
00003  * rtProtoLS.cc
00004  * Copyright (C) 2000 by the University of Southern California
00005  * $Id: rtProtoLS.cc,v 1.8 2005/08/25 18:58:06 johnh Exp $
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  *
00020  *
00021  * The copyright of this module includes the following
00022  * linking-with-specific-other-licenses addition:
00023  *
00024  * In addition, as a special exception, the copyright holders of
00025  * this module give you permission to combine (via static or
00026  * dynamic linking) this module with free software programs or
00027  * libraries that are released under the GNU LGPL and with code
00028  * included in the standard release of ns-2 under the Apache 2.0
00029  * license or under otherwise-compatible licenses with advertising
00030  * requirements (or modified versions of such code, with unchanged
00031  * license).  You may copy and distribute such a system following the
00032  * terms of the GNU GPL for this module and the licenses of the
00033  * other code concerned, provided that you include the source code of
00034  * that other code when and as the GNU GPL requires distribution of
00035  * source code.
00036  *
00037  * Note that people who make modified versions of this module
00038  * are not obligated to grant this special exception for their
00039  * modified versions; it is their choice whether to do so.  The GNU
00040  * General Public License gives permission to release a modified
00041  * version without this exception; this exception also makes it
00042  * possible to release a modified version which carries forward this
00043  * exception.
00044  *
00045  */
00046 //
00047 // Other copyrights might apply to parts of this software and are so
00048 // noted when applicable.
00049 //
00050 //  Copyright (C) 1998 by Mingzhou Sun. All rights reserved.
00051 //  This software is developed at Rensselaer Polytechnic Institute under 
00052 //  DARPA grant No. F30602-97-C-0274
00053 //  Redistribution and use in source and binary forms are permitted
00054 //  provided that the above copyright notice and this paragraph are
00055 //  duplicated in all such forms and that any documentation, advertising
00056 //  materials, and other materials related to such distribution and use
00057 //  acknowledge that the software was developed by Mingzhou Sun at the
00058 //  Rensselaer  Polytechnic Institute.  The name of the University may not 
00059 //  be used to endorse or promote products derived from this software 
00060 //  without specific prior written permission.
00061 //
00062 // $Header: /nfs/jade/vint/CVSROOT/ns-2/linkstate/rtProtoLS.cc,v 1.8 2005/08/25 18:58:06 johnh Exp $
00063 
00064 #include "config.h"
00065 #ifdef HAVE_STL
00066 
00067 #include "hdr-ls.h"
00068 #include "rtProtoLS.h"
00069 #include "agent.h"
00070 #include "string.h" // for strtok
00071 
00072 // Helper classes
00073 class LsTokenList : public LsList<char *> {
00074 public:
00075     LsTokenList (char * str, const char * delim ) 
00076         : LsList<char*> () { 
00077         for ( char * token = strtok (str, delim);
00078               token != NULL; token = strtok(NULL, delim) ) {
00079             push_back (token);
00080         }
00081     }
00082 };
00083    
00084 class LsIntList : public LsList<int> {
00085 public:
00086     LsIntList (const char * str, const char * delim)
00087         : LsList<int> () {
00088         for ( char * token = strtok ((char *)str, delim);
00089               token != NULL; token = strtok(NULL, delim) ) {
00090             push_back ( atoi(token) );
00091         }
00092     }
00093 };
00094 
00095 static class rtProtoLSclass : public TclClass {
00096 public:
00097     rtProtoLSclass() : TclClass("Agent/rtProto/LS") {}
00098     TclObject* create(int, const char*const*) {
00099         return (new rtProtoLS);
00100     }
00101 } class_rtProtoLS;
00102 
00103 
00104 int rtProtoLS::command(int argc, const char*const* argv)
00105 {
00106         if (strcmp(argv[1], "send-update") == 0) {
00107                 ns_addr_t dst;
00108         dst.addr_ = atoi(argv[2]);
00109         dst.port_ = atoi(argv[3]);
00110                 u_int32_t mtvar = atoi(argv[4]);
00111         u_int32_t size  = atoi(argv[5]);
00112                 sendpkt(dst, mtvar, size);
00113                 return TCL_OK;
00114        }
00115     /* --------------- LS specific --------------- */
00116     if (strcmp(argv[1], "lookup") == 0) {
00117         if (argc == 3) {
00118             int dst = atoi(argv[2]);
00119             lookup (dst);
00120             /* use tcl.resultf () to return the lookup results */
00121             return TCL_OK;
00122         }
00123     }  
00124     if (strcmp(argv[1], "initialize") == 0) {
00125         initialize ();
00126         return TCL_OK;
00127     }
00128     if (strcmp(argv[1], "setDelay" ) == 0 ) {
00129         if ( argc == 4) {
00130             int nbrId = atoi(argv[2]);
00131             double delay = strtod ( argv[3], NULL);
00132             setDelay(nbrId, delay);
00133             return TCL_OK;
00134         }
00135     }
00136     if (strcmp(argv[1], "setNodeNumber" ) == 0 ) {
00137         if ( argc == 3 ) {
00138             int number_of_nodes = atoi(argv[2]);
00139             LsMessageCenter::instance().setNodeNumber(number_of_nodes);
00140         }
00141         return TCL_OK;
00142     }
00143     if (strcmp(argv[1], "computeRoutes") == 0) {
00144         computeRoutes();
00145         return TCL_OK;
00146     }
00147     if (strcmp(argv[1], "intfChanged") == 0) {
00148         intfChanged();
00149         return TCL_OK;
00150     }
00151     if (strcmp (argv[1], "send-buffered-messages") == 0) {
00152         sendBufferedMessages();
00153         return TCL_OK;
00154     }
00155     if (strcmp(argv[1], "sendUpdates") == 0) {
00156         sendUpdates ();
00157         return TCL_OK;
00158     }
00159     return Agent::command(argc, argv);
00160 }
00161 
00162 void rtProtoLS::sendpkt(ns_addr_t dst, u_int32_t mtvar, u_int32_t size)
00163 {
00164     dst_ = dst;
00165     size_ = size;
00166     
00167         Packet* p = Agent::allocpkt();
00168     hdr_LS *rh = hdr_LS::access(p);
00169         rh->metricsVar() = mtvar;
00170 
00171         target_->recv(p);               
00172 }
00173 
00174 void rtProtoLS::recv(Packet* p, Handler*)
00175 {   
00176     hdr_LS* rh = hdr_LS::access(p);
00177     hdr_ip* ih = hdr_ip::access(p);
00178     // -- LS stuffs --
00179     if (LS_ready_ || (rh->metricsVar() == LS_BIG_NUMBER))
00180         receiveMessage(findPeerNodeId(ih->src()), rh->msgId());
00181     else
00182         Tcl::instance().evalf("%s recv-update %d %d", name(),
00183                       ih->saddr(), rh->metricsVar());
00184     Packet::free(p);
00185 }
00186 
00187 /* LS specific */
00188 // implement tcl cmd's
00189 
00190 /* -- findPeerNodeId -- */
00191 int rtProtoLS::findPeerNodeId (ns_addr_t agentAddr) 
00192 {
00193     // because the agentAddr is the value, not the key of the map
00194     for (PeerAddrMap::iterator itr = peerAddrMap_.begin();
00195          itr != peerAddrMap_.end(); itr++) {
00196         if ((*itr).second.isEqual (agentAddr)) {
00197             return (*itr).first;
00198         }
00199     }
00200     return LS_INVALID_NODE_ID;
00201 }
00202 
00203 void rtProtoLS::initialize() // init nodeState_ and routing_
00204 {
00205     Tcl & tcl = Tcl::instance();
00206     // call tcl get-node-id, atoi, set nodeId
00207     tcl.evalf("%s get-node-id", name());
00208     const char * resultString = tcl.result();
00209     nodeId_ = atoi(resultString);
00210   
00211     // call tcl get-peers, strtok, set peerAddrMap, peerIdList;
00212     tcl.evalf("%s get-peers", name());
00213     resultString = tcl.result();
00214 
00215     int nodeId, neighborId;
00216     ns_addr_t peer;
00217     ls_status_t status;
00218     int cost;
00219 
00220     // XXX no error checking for now yet. tcl MUST return pairs of numbers
00221     for ( LsIntList intList(resultString, " \t\n");
00222           !intList.empty(); ) {
00223         nodeId = intList.front();
00224         intList.pop_front();
00225         // Agent.addr_
00226         peer.addr_ = intList.front();
00227         intList.pop_front();
00228         peer.port_ = intList.front();
00229         intList.pop_front();
00230         peerAddrMap_.insert(nodeId, peer);
00231         peerIdList_.push_back(nodeId);
00232     }
00233     
00234     // call tcl get-links-status, strtok, set linkStateList;
00235     tcl.evalf("%s get-links-status", name());
00236     resultString = tcl.result();
00237     // cout << "get-links-status:\t" << resultString <<endl; 
00238     // XXX no error checking for now. tcl MUST return triplets of numbers
00239     for ( LsIntList intList2(resultString, " \t\n");
00240           !intList2.empty(); ) {
00241         neighborId = intList2.front();
00242         intList2.pop_front();
00243         status = (ls_status_t) intList2.front();
00244         intList2.pop_front();
00245         cost = (int) intList2.front();
00246         intList2.pop_front();
00247         linkStateList_.push_back(LsLinkState(neighborId,status,cost));
00248     }    
00249 
00250     // call tcl get-delay-estimates
00251     tcl.evalf ("%s get-delay-estimates", name());
00252 
00253     // call routing.init(this); and computeRoutes
00254     routing_.init(this);
00255     routing_.computeRoutes();
00256     // debug
00257     tcl.evalf("%s set LS_ready", name());
00258     const char* token = strtok((char *)tcl.result(), " \t\n");
00259     if (token == NULL) 
00260         LS_ready_ = 0;
00261     else
00262         LS_ready_ = atoi(token); // buggy
00263 }
00264 
00265 void rtProtoLS::intfChanged ()
00266 {
00267     // XXX redudant, to be changed later
00268     Tcl & tcl = Tcl::instance();
00269     // call tcl get-links-status, strtok, set linkStateList;
00270     tcl.evalf("%s get-links-status", name());
00271     const char * resultString = tcl.result();
00272 
00273     // destroy the old link states
00274     linkStateList_.eraseAll();
00275     // XXX no error checking for now. tcl MUST return triplets of numbers
00276   
00277     for (LsIntList intList2(resultString, " \t\n");
00278          !intList2.empty(); ) {
00279         int neighborId = intList2.front();
00280         intList2.pop_front();
00281         ls_status_t  status = ( ls_status_t ) intList2.front();
00282         intList2.pop_front();
00283         int cost = (int) intList2.front();
00284         intList2.pop_front();
00285         // LsLinkState ls;
00286         // ls.init(neighborId, status, cost);
00287         linkStateList_.push_back(LsLinkState(neighborId,status,cost));
00288     }    
00289     // call routing_'s LinkStateChanged() 
00290     //   for now, don't compute routes yet (?)
00291     routing_.linkStateChanged();
00292 }
00293 
00294 void rtProtoLS::lookup(int destId) 
00295 {
00296     // Call routing_'s lookup
00297     LsEqualPaths* EPptr = routing_.lookup(destId);
00298 
00299     // then use tcl.resultf() to return the results
00300     if (EPptr == NULL) {
00301         Tcl::instance().resultf( "%s",  "");
00302         return;
00303     }
00304     char resultBuf[64]; // XXX buggy;
00305     sprintf(resultBuf, "%d" , EPptr->cost);
00306     char tmpBuf[16]; // XXX
00307  
00308     for (LsNodeIdList::iterator itr = (EPptr->nextHopList).begin();
00309          itr != (EPptr->nextHopList).end(); itr++) {
00310         sprintf(tmpBuf, " %d", (*itr) );
00311         strcat (resultBuf, tmpBuf); // strcat (dest, src);
00312     }
00313 
00314     Tcl::instance().resultf("%s", resultBuf);
00315 }
00316 
00317 void rtProtoLS::receiveMessage(int sender, u_int32_t msgId) 
00318 { 
00319     if (routing_.receiveMessage(sender, msgId))
00320         installRoutes();
00321 }
00322 
00323 // Implementing LsNode interface
00324 bool rtProtoLS::sendMessage(int destId, u_int32_t messageId, int size) 
00325 {
00326     ns_addr_t* agentAddrPtr = peerAddrMap_.findPtr(destId);
00327     if (agentAddrPtr == NULL) 
00328         return false;
00329     dst_ = *agentAddrPtr;
00330     size_ = size;
00331   
00332     Packet* p = Agent::allocpkt();
00333     hdr_LS *rh = hdr_LS::access(p);
00334     rh->msgId() = messageId;
00335     rh->metricsVar() = LS_BIG_NUMBER;
00336     target_->recv(p);           
00337     // sendpkt( *agentAddrPtr , messageId, size);
00338     return true;
00339 }
00340 
00341 #endif // HAVE_STL

Generated on Tue Mar 6 16:47:50 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6