00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
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
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 };
00099
00100 char Node::nwrk_[NODE_NAMLOG_BUFSZ];
00101
00102
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
00111 energy_model_(NULL), location_(NULL)
00112 {
00113 LIST_INIT(&ifhead_);
00114 LIST_INIT(&linklisthead_);
00115 insert(&(Node::nodehead_));
00116 #ifdef HAVE_STL
00117
00118 if (NixRoutingUsed < 0) {
00119
00120 Tcl& tcl = Tcl::instance();
00121 tcl.evalf("Simulator set nix-routing");
00122 tcl.resultAs(&NixRoutingUsed);
00123 }
00124 if (NixRoutingUsed) {
00125
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
00145 if(strcmp(argv[1], "populate-objects") == 0) {
00146 if (nixnode_) {
00147 nixnode_->PopulateObjects();
00148 }
00149 return TCL_OK;
00150 }
00151
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
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
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
00233 rtnotif_= rtnotif_->next_rtm_;
00234
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
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
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
00294
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
00304
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
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 }