rtProtoLS.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:10k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * rtProtoLS.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: rtProtoLS.cc,v 1.8 2005/08/25 18:58:06 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. //
  46. // Other copyrights might apply to parts of this software and are so
  47. // noted when applicable.
  48. //
  49. //  Copyright (C) 1998 by Mingzhou Sun. All rights reserved.
  50. //  This software is developed at Rensselaer Polytechnic Institute under 
  51. //  DARPA grant No. F30602-97-C-0274
  52. //  Redistribution and use in source and binary forms are permitted
  53. //  provided that the above copyright notice and this paragraph are
  54. //  duplicated in all such forms and that any documentation, advertising
  55. //  materials, and other materials related to such distribution and use
  56. //  acknowledge that the software was developed by Mingzhou Sun at the
  57. //  Rensselaer  Polytechnic Institute.  The name of the University may not 
  58. //  be used to endorse or promote products derived from this software 
  59. //  without specific prior written permission.
  60. //
  61. // $Header: /cvsroot/nsnam/ns-2/linkstate/rtProtoLS.cc,v 1.8 2005/08/25 18:58:06 johnh Exp $
  62. #include "config.h"
  63. #ifdef HAVE_STL
  64. #include "hdr-ls.h"
  65. #include "rtProtoLS.h"
  66. #include "agent.h"
  67. #include "string.h" // for strtok
  68. // Helper classes
  69. class LsTokenList : public LsList<char *> {
  70. public:
  71. LsTokenList (char * str, const char * delim ) 
  72. : LsList<char*> () { 
  73. for ( char * token = strtok (str, delim);
  74.       token != NULL; token = strtok(NULL, delim) ) {
  75. push_back (token);
  76. }
  77. }
  78. };
  79.    
  80. class LsIntList : public LsList<int> {
  81. public:
  82. LsIntList (const char * str, const char * delim)
  83. : LsList<int> () {
  84. for ( char * token = strtok ((char *)str, delim);
  85.       token != NULL; token = strtok(NULL, delim) ) {
  86. push_back ( atoi(token) );
  87. }
  88. }
  89. };
  90. static class rtProtoLSclass : public TclClass {
  91. public:
  92. rtProtoLSclass() : TclClass("Agent/rtProto/LS") {}
  93. TclObject* create(int, const char*const*) {
  94. return (new rtProtoLS);
  95. }
  96. } class_rtProtoLS;
  97. int rtProtoLS::command(int argc, const char*const* argv)
  98. {
  99.         if (strcmp(argv[1], "send-update") == 0) {
  100.                 ns_addr_t dst;
  101. dst.addr_ = atoi(argv[2]);
  102. dst.port_ = atoi(argv[3]);
  103.                 u_int32_t mtvar = atoi(argv[4]);
  104. u_int32_t size  = atoi(argv[5]);
  105.                 sendpkt(dst, mtvar, size);
  106.                 return TCL_OK;
  107.        }
  108. /* --------------- LS specific --------------- */
  109. if (strcmp(argv[1], "lookup") == 0) {
  110. if (argc == 3) {
  111. int dst = atoi(argv[2]);
  112. lookup (dst);
  113. /* use tcl.resultf () to return the lookup results */
  114. return TCL_OK;
  115. }
  116. }  
  117. if (strcmp(argv[1], "initialize") == 0) {
  118. initialize ();
  119. return TCL_OK;
  120. }
  121. if (strcmp(argv[1], "setDelay" ) == 0 ) {
  122. if ( argc == 4) {
  123. int nbrId = atoi(argv[2]);
  124. double delay = strtod ( argv[3], NULL);
  125. setDelay(nbrId, delay);
  126. return TCL_OK;
  127. }
  128. }
  129. if (strcmp(argv[1], "setNodeNumber" ) == 0 ) {
  130. if ( argc == 3 ) {
  131. int number_of_nodes = atoi(argv[2]);
  132. LsMessageCenter::instance().setNodeNumber(number_of_nodes);
  133. }
  134. return TCL_OK;
  135. }
  136. if (strcmp(argv[1], "computeRoutes") == 0) {
  137. computeRoutes();
  138. return TCL_OK;
  139. }
  140. if (strcmp(argv[1], "intfChanged") == 0) {
  141. intfChanged();
  142. return TCL_OK;
  143. }
  144. if (strcmp (argv[1], "send-buffered-messages") == 0) {
  145. sendBufferedMessages();
  146. return TCL_OK;
  147. }
  148. if (strcmp(argv[1], "sendUpdates") == 0) {
  149. sendUpdates ();
  150. return TCL_OK;
  151. }
  152. return Agent::command(argc, argv);
  153. }
  154. void rtProtoLS::sendpkt(ns_addr_t dst, u_int32_t mtvar, u_int32_t size)
  155. {
  156. dst_ = dst;
  157. size_ = size;
  158.         Packet* p = Agent::allocpkt();
  159. hdr_LS *rh = hdr_LS::access(p);
  160.         rh->metricsVar() = mtvar;
  161.         target_->recv(p);               
  162. }
  163. void rtProtoLS::recv(Packet* p, Handler*)
  164. {   
  165. hdr_LS* rh = hdr_LS::access(p);
  166. hdr_ip* ih = hdr_ip::access(p);
  167. // -- LS stuffs --
  168. if (LS_ready_ || (rh->metricsVar() == LS_BIG_NUMBER))
  169. receiveMessage(findPeerNodeId(ih->src()), rh->msgId());
  170. else
  171. Tcl::instance().evalf("%s recv-update %d %d", name(),
  172.       ih->saddr(), rh->metricsVar());
  173. Packet::free(p);
  174. }
  175. /* LS specific */
  176. // implement tcl cmd's
  177. /* -- findPeerNodeId -- */
  178. int rtProtoLS::findPeerNodeId (ns_addr_t agentAddr) 
  179. {
  180. // because the agentAddr is the value, not the key of the map
  181. for (PeerAddrMap::iterator itr = peerAddrMap_.begin();
  182.      itr != peerAddrMap_.end(); itr++) {
  183. if ((*itr).second.isEqual (agentAddr)) {
  184. return (*itr).first;
  185. }
  186. }
  187. return LS_INVALID_NODE_ID;
  188. }
  189. void rtProtoLS::initialize() // init nodeState_ and routing_
  190. {
  191. Tcl & tcl = Tcl::instance();
  192. // call tcl get-node-id, atoi, set nodeId
  193. tcl.evalf("%s get-node-id", name());
  194. const char * resultString = tcl.result();
  195. nodeId_ = atoi(resultString);
  196.   
  197. // call tcl get-peers, strtok, set peerAddrMap, peerIdList;
  198. tcl.evalf("%s get-peers", name());
  199. resultString = tcl.result();
  200. int nodeId, neighborId;
  201. ns_addr_t peer;
  202. ls_status_t status;
  203. int cost;
  204. // XXX no error checking for now yet. tcl MUST return pairs of numbers
  205. for ( LsIntList intList(resultString, " tn");
  206.       !intList.empty(); ) {
  207. nodeId = intList.front();
  208. intList.pop_front();
  209. // Agent.addr_
  210. peer.addr_ = intList.front();
  211. intList.pop_front();
  212. peer.port_ = intList.front();
  213. intList.pop_front();
  214. peerAddrMap_.insert(nodeId, peer);
  215. peerIdList_.push_back(nodeId);
  216. }
  217. // call tcl get-links-status, strtok, set linkStateList;
  218. tcl.evalf("%s get-links-status", name());
  219. resultString = tcl.result();
  220. // cout << "get-links-status:t" << resultString <<endl; 
  221. // XXX no error checking for now. tcl MUST return triplets of numbers
  222. for ( LsIntList intList2(resultString, " tn");
  223.       !intList2.empty(); ) {
  224. neighborId = intList2.front();
  225. intList2.pop_front();
  226. status = (ls_status_t) intList2.front();
  227. intList2.pop_front();
  228. cost = (int) intList2.front();
  229. intList2.pop_front();
  230. linkStateList_.push_back(LsLinkState(neighborId,status,cost));
  231. }    
  232. // call tcl get-delay-estimates
  233. tcl.evalf ("%s get-delay-estimates", name());
  234. // call routing.init(this); and computeRoutes
  235. routing_.init(this);
  236. routing_.computeRoutes();
  237. // debug
  238. tcl.evalf("%s set LS_ready", name());
  239. const char* token = strtok((char *)tcl.result(), " tn");
  240. if (token == NULL) 
  241. LS_ready_ = 0;
  242. else
  243. LS_ready_ = atoi(token); // buggy
  244. }
  245. void rtProtoLS::intfChanged ()
  246. {
  247. // XXX redudant, to be changed later
  248. Tcl & tcl = Tcl::instance();
  249. // call tcl get-links-status, strtok, set linkStateList;
  250. tcl.evalf("%s get-links-status", name());
  251. const char * resultString = tcl.result();
  252. // destroy the old link states
  253. linkStateList_.eraseAll();
  254. // XXX no error checking for now. tcl MUST return triplets of numbers
  255.   
  256. for (LsIntList intList2(resultString, " tn");
  257.      !intList2.empty(); ) {
  258. int neighborId = intList2.front();
  259. intList2.pop_front();
  260. ls_status_t  status = ( ls_status_t ) intList2.front();
  261. intList2.pop_front();
  262. int cost = (int) intList2.front();
  263. intList2.pop_front();
  264. // LsLinkState ls;
  265. // ls.init(neighborId, status, cost);
  266. linkStateList_.push_back(LsLinkState(neighborId,status,cost));
  267. }    
  268. // call routing_'s LinkStateChanged() 
  269. //   for now, don't compute routes yet (?)
  270. routing_.linkStateChanged();
  271. }
  272. void rtProtoLS::lookup(int destId) 
  273. {
  274. // Call routing_'s lookup
  275. LsEqualPaths* EPptr = routing_.lookup(destId);
  276. // then use tcl.resultf() to return the results
  277. if (EPptr == NULL) {
  278. Tcl::instance().resultf( "%s",  "");
  279. return;
  280. }
  281. char resultBuf[64]; // XXX buggy;
  282. sprintf(resultBuf, "%d" , EPptr->cost);
  283. char tmpBuf[16]; // XXX
  284.  
  285. for (LsNodeIdList::iterator itr = (EPptr->nextHopList).begin();
  286.      itr != (EPptr->nextHopList).end(); itr++) {
  287. sprintf(tmpBuf, " %d", (*itr) );
  288. strcat (resultBuf, tmpBuf); // strcat (dest, src);
  289. }
  290. Tcl::instance().resultf("%s", resultBuf);
  291. }
  292. void rtProtoLS::receiveMessage(int sender, u_int32_t msgId) 
  293. if (routing_.receiveMessage(sender, msgId))
  294. installRoutes();
  295. }
  296. // Implementing LsNode interface
  297. bool rtProtoLS::sendMessage(int destId, u_int32_t messageId, int size) 
  298. {
  299. ns_addr_t* agentAddrPtr = peerAddrMap_.findPtr(destId);
  300. if (agentAddrPtr == NULL) 
  301. return false;
  302. dst_ = *agentAddrPtr;
  303. size_ = size;
  304.   
  305. Packet* p = Agent::allocpkt();
  306. hdr_LS *rh = hdr_LS::access(p);
  307. rh->msgId() = messageId;
  308. rh->metricsVar() = LS_BIG_NUMBER;
  309. target_->recv(p);           
  310. // sendpkt( *agentAddrPtr , messageId, size);
  311. return true;
  312. }
  313. #endif // HAVE_STL