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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
  2.  *
  3.  * Copyright (c) 1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Computer Systems
  17.  * Engineering Group at Lawrence Berkeley Laboratory.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  * $Header: /cvsroot/nsnam/ns-2/common/node.cc,v 1.34 2002/05/30 17:44:03 haldar Exp $
  35.  *
  36.  * CMU-Monarch project's Mobility extensions ported by Padma Haldar, 
  37.  * 10/98.
  38.  */
  39. #include <stdio.h>
  40. #include <stdarg.h>
  41. #include "address.h"
  42. #include "config.h"
  43. #ifdef HAVE_STL
  44. #include "nix/nixnode.h"
  45. #endif //HAVE_STL
  46. #include "node.h"
  47. static class LinkHeadClass : public TclClass {
  48. public:
  49. LinkHeadClass() : TclClass("Connector/LinkHead") {}
  50. TclObject* create(int, const char*const*) {
  51. return (new LinkHead);
  52. }
  53. } class_link_head;
  54. LinkHead::LinkHead() : net_if_(0), node_(0), type_(0) { }
  55. int32_t LinkHead::label() 
  56. {
  57. if (net_if_)
  58. return net_if_->intf_label();
  59. printf("Configuration error:  Network Interface missingn");
  60. exit(1);
  61. // Make msvc happy
  62. return 0;
  63. }
  64. int LinkHead::command(int argc, const char*const* argv)
  65. {
  66.         if (argc == 3) {
  67. if(strcmp(argv[1], "setnetinf") == 0) {
  68. net_if_ =
  69. (NetworkInterface*) TclObject::lookup(argv[2]);
  70. if (net_if_ == 0)
  71. return TCL_ERROR;
  72. return TCL_OK;
  73. } else if(strcmp(argv[1], "setnode") == 0) {
  74. node_ = (Node*) TclObject::lookup(argv[2]); 
  75. if (node_ == 0)
  76. return TCL_ERROR;
  77. return TCL_OK;
  78. }
  79. }
  80. return (Connector::command(argc, argv));
  81. }
  82. static class NodeClass : public TclClass {
  83. public:
  84. NodeClass() : TclClass("Node") {}
  85. TclObject* create(int, const char*const*) {
  86.                 return (new Node);
  87.         }
  88. } class_node;
  89. struct node_head Node::nodehead_ = { 0 }; // replaces LIST_INIT macro
  90. char Node::nwrk_[NODE_NAMLOG_BUFSZ];
  91. /* Additions for NixRouting */
  92. int NixRoutingUsed = -1;
  93. Node::Node() : 
  94. address_(-1), nodeid_ (-1), namChan_(0),
  95. rtnotif_(NULL),
  96. #ifdef HAVE_STL
  97. nixnode_(NULL),
  98. #endif //HAVE_STL
  99. energy_model_(NULL), location_(NULL)
  100. {
  101. LIST_INIT(&ifhead_);
  102. LIST_INIT(&linklisthead_);
  103. insert(&(Node::nodehead_)); // insert self into static list of nodes
  104. #ifdef HAVE_STL
  105. // Mods for Nix-Vector routing
  106. if (NixRoutingUsed < 0) {
  107. // Find out if nix routing is in use
  108. Tcl& tcl = Tcl::instance();
  109. tcl.evalf("Simulator set nix-routing");
  110. tcl.resultAs(&NixRoutingUsed);
  111. }
  112. if (NixRoutingUsed) {
  113. // Create the NixNode pointer
  114. if(0)printf("Nix routing in use, creating NixNoden");
  115. nixnode_ = new NixNode();
  116. }
  117. #endif //HAVE_STL
  118. neighbor_list_ = NULL;
  119. }
  120. Node::~Node()
  121. {
  122. LIST_REMOVE(this, entry);
  123. }
  124. int
  125. Node::command(int argc, const char*const* argv)
  126. {
  127. Tcl& tcl = Tcl::instance();
  128. if (argc == 2) {
  129. #ifdef HAVE_STL
  130. // Mods for Nix-Vector Routing
  131. if(strcmp(argv[1], "populate-objects") == 0) {
  132. if (nixnode_) {
  133. nixnode_->PopulateObjects();
  134. }
  135. return TCL_OK;
  136. }
  137. // End mods for Nix-Vector routing
  138. #endif // HAVE_STL
  139. if(strcmp(argv[1], "address?") == 0) {
  140. tcl.resultf("%d", address_);
  141.   return TCL_OK;
  142. }
  143. } else if (argc == 3) {
  144. #ifdef HAVE_STL
  145. // Mods for Nix-Vector Routing
  146. if (strcmp(argv[1], "get-nix-vector") == 0) {
  147. if (nixnode_) {
  148. nixnode_->GetNixVector(atol(argv[2]));
  149. }
  150. return TCL_OK;
  151. }
  152. #endif //HAVE_STL
  153. if (strcmp(argv[1], "set-neighbor") == 0) {
  154. #ifdef HAVE_STL
  155. if (nixnode_) {
  156. nixnode_->AddAdj(atol(argv[2]));
  157. }
  158. #endif //HAVE_STL
  159. return(TCL_OK);
  160. }
  161. if (strcmp(argv[1], "addr") == 0) {
  162. address_ = Address::instance().str2addr(argv[2]);
  163. #ifdef HAVE_STL
  164. if (nixnode_) {
  165. nixnode_->Id(address_);
  166. }
  167. #endif //HAVE_STL
  168. return TCL_OK;
  169. // End mods for Nix-Vector routing
  170. } else if (strcmp(argv[1], "nodeid") == 0) {
  171. nodeid_ = atoi(argv[2]);
  172. return TCL_OK;
  173. } else if(strcmp(argv[1], "addlinkhead") == 0) {
  174. LinkHead* slhp = (LinkHead*)TclObject::lookup(argv[2]);
  175. if (slhp == 0)
  176. return TCL_ERROR;
  177. slhp->insertlink(&linklisthead_);
  178. return TCL_OK;
  179. } else if (strcmp(argv[1], "addenergymodel") == 0) {
  180. energy_model_=(EnergyModel*)TclObject::lookup(argv[2]);
  181. if(!energy_model_)
  182. return TCL_ERROR;
  183. return TCL_OK;
  184. } else if (strcmp(argv[1], "namattach") == 0) {
  185.                         int mode;
  186.                         namChan_ = Tcl_GetChannel(tcl.interp(), (char*)argv[2],
  187.                                                   &mode);
  188.                         if (namChan_ == 0) {
  189.                                 tcl.resultf("node: can't attach %s", argv[2]);
  190.                                 return (TCL_ERROR);
  191.                         }
  192.                         return (TCL_OK);
  193. } else if (strcmp(argv[1], "add-neighbor") == 0) {
  194. Node * node = (Node *)TclObject::lookup(argv[2]);
  195.   if (node == 0) {
  196.   tcl.resultf("Invalid node %s", argv[2]);
  197.                                  return (TCL_ERROR);
  198. }
  199. addNeighbor(node);
  200. return TCL_OK;
  201. }
  202. }
  203. return ParentNode::command(argc,argv);
  204. }
  205. void Node::route_notify(RoutingModule *rtm) {
  206. if (rtnotif_ == NULL)
  207. rtnotif_ = rtm;
  208. else
  209. rtnotif_->route_notify(rtm);
  210. }
  211. void Node::unreg_route_notify(RoutingModule *rtm) {
  212. if (rtnotif_) {
  213. if (rtnotif_ == rtm) {
  214. //RoutingModule *tmp = rtnotif_;
  215. rtnotif_= rtnotif_->next_rtm_;
  216. //free (tmp);
  217. }
  218. else
  219. rtnotif_->unreg_route_notify(rtm);
  220. }
  221. }
  222. void Node::add_route(char *dst, NsObject *target) {
  223. if (rtnotif_)
  224. rtnotif_->add_route(dst, target);
  225. }
  226. void Node::delete_route(char *dst, NsObject *nullagent) {
  227. if (rtnotif_)
  228. rtnotif_->delete_route(dst, nullagent);
  229. }
  230. void Node::set_table_size(int nn) {
  231. if (rtnotif_)
  232. rtnotif_->set_table_size(nn);
  233. }
  234. void Node::set_table_size(int level, int csize) {
  235. if (rtnotif_)
  236. rtnotif_->set_table_size(level, csize);
  237. }
  238. void Node::addNeighbor(Node * neighbor) {
  239. neighbor_list_node* nlistItem = (neighbor_list_node *)malloc(sizeof(neighbor_list_node));
  240. nlistItem->nodeid = neighbor->nodeid();
  241. nlistItem->next = neighbor_list_;
  242. neighbor_list_=nlistItem; 
  243. }
  244. void Node::namlog(const char* fmt, ...)
  245. {
  246. // Don't do anything if we don't have a log file.
  247. if (namChan_ == 0) 
  248. return;
  249. va_list ap;
  250. va_start(ap, fmt);
  251. vsprintf(nwrk_, fmt, ap);
  252. namdump();
  253. }
  254. void Node::namdump()
  255. {
  256.         int n = 0;
  257.         /* Otherwise nwrk_ isn't initialized */
  258. n = strlen(nwrk_);
  259. if (n >= NODE_NAMLOG_BUFSZ-1) {
  260. fprintf(stderr, 
  261. "Node::namdump() exceeds buffer size. Bail out.n");
  262. abort();
  263. }
  264. if (n > 0) {
  265. /*
  266.  * tack on a newline (temporarily) instead
  267.  * of doing two writes
  268.  */
  269. nwrk_[n] = 'n';
  270. nwrk_[n + 1] = 0;
  271. (void)Tcl_Write(namChan_, nwrk_, n + 1);
  272. nwrk_[n] = 0;
  273. }
  274. }
  275. // Given an interface label for a NetworkInterface on this node, we return 
  276. // the head of that link
  277. NsObject* Node::intf_to_target(int32_t label)
  278. {
  279. LinkHead *lhp = linklisthead_.lh_first;
  280. for (; lhp; lhp = lhp->nextlinkhead()) 
  281. if (label == lhp->label())
  282. return ((NsObject*) lhp);
  283. return NULL;
  284. }
  285. // A class static method. Return the node instance from the static node list
  286. Node* Node::get_node_by_address (nsaddr_t id)
  287. {
  288. Node * tnode = nodehead_.lh_first;
  289. for (; tnode; tnode = tnode->nextnode()) {
  290. if (tnode->address_ == id ) {
  291. return (tnode);
  292. }
  293. }
  294. return NULL;
  295. }