NodeCommand.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2005-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #include <stdlib.h>
00019 
00020 #include "Node.h"
00021 #include "NodeCommand.h"
00022 #include "SimConvergenceLayer.h"
00023 #include "SimRegistration.h"
00024 #include "Simulator.h"
00025 #include "Topology.h"
00026 #include "TrAgent.h"
00027 #include "bundling/Bundle.h"
00028 #include "contacts/ContactManager.h"
00029 #include "contacts/Link.h"
00030 #include "naming/EndpointID.h"
00031 #include "routing/BundleRouter.h"
00032 #include "routing/RouteTable.h"
00033 #include "reg/RegistrationTable.h"
00034 
00035 using namespace dtn;
00036 
00037 namespace dtnsim {
00038 
00039 NodeCommand::NodeCommand(Node* node)
00040     : TclCommand(node->name()), node_(node)
00041 {
00042     add_to_help("<time> route", "XXX");
00043     add_to_help("<time> add", "XXX");
00044     add_to_help("<time> tragent", "XXX");
00045     add_to_help("<time> link", "XXX");
00046     add_to_help("<time> registration", "XXX");
00047 }
00048 
00049 int
00050 NodeCommand::exec(int argc, const char** argv, Tcl_Interp* interp)
00051 {
00052     (void)interp;
00053     
00054     if (argc < 3) {
00055         wrong_num_args(argc, argv, 2, 4, INT_MAX);
00056         return TCL_ERROR;
00057     }
00058 
00059     // pull out the time and subcommand
00060     char* end;
00061     double time = strtod(argv[1], &end);
00062     if (*end != '\0') {
00063         resultf("time value '%s' invalid", argv[1]);
00064         return TCL_ERROR;
00065     }
00066 
00067     // for all commands and their side-effects, install the node as
00068     // the "singleton" BundleDaemon instance, and store the command
00069     // time in the node so any posted events happen in the future
00070     node_->set_active();
00071 
00072     const char* cmd = argv[2];
00073     const char* subcmd = NULL;
00074     if (argc >= 4) {
00075         subcmd = argv[3];
00076     }
00077 
00078     if (strcmp(cmd, "route") == 0)
00079     {
00080         if (strcmp(subcmd, "local_eid") == 0) {
00081             if (time != 0) {
00082                 resultf("node %s %s must be run at time 0", cmd, subcmd);
00083                 return TCL_ERROR;
00084             }
00085         
00086             if (argc == 4) {
00087                 // <node> 0 route local_eid
00088                 set_result(node_->local_eid().c_str());
00089                 return TCL_OK;
00090                 
00091             } else if (argc == 5) {
00092                 // <node> 0 route local_eid <eid>
00093                 node_->set_local_eid(argv[4]);
00094 
00095                 if (! node_->local_eid().valid()) {
00096                     resultf("invalid eid '%s'", argv[4]);
00097                     return TCL_ERROR;
00098                 }
00099                 return TCL_OK;
00100             } else {
00101                 wrong_num_args(argc, argv, 4, 4, 5);
00102                 return TCL_ERROR;
00103             }
00104         }
00105         else if (strcmp(subcmd, "add") == 0)
00106         {
00107             // <node> X route add <dest> <link/node>
00108             if (argc != 6) {
00109                 wrong_num_args(argc, argv, 2, 6, 6);
00110                 return TCL_ERROR;
00111             }
00112 
00113             const char* dest_str = argv[4];
00114             const char* nexthop = argv[5];
00115 
00116             log_debug("adding route to %s through %s", dest_str, nexthop);
00117             
00118             EndpointIDPattern dest(dest_str);
00119             if (!dest.valid()) {
00120                 resultf("invalid destination eid %s", dest_str);
00121                 return TCL_ERROR;
00122             }
00123 
00124             Simulator::post(new SimAddRouteEvent(time, node_, dest, nexthop));
00125             
00126             return TCL_OK;
00127         }
00128         
00129         resultf("node route: unsupported subcommand %s", subcmd);
00130         return TCL_ERROR;
00131     }
00132         
00133     else if (strcmp(cmd, "link") == 0)
00134     {
00135         if (strcmp(subcmd, "add") == 0) {
00136             // <node1> X link add <name> <peer> <type> <args>
00137             if (argc < 6) {
00138                 wrong_num_args(argc, argv, 2, 7, INT_MAX);
00139                 return TCL_ERROR;
00140             }
00141                         
00142             const char* name = argv[4];
00143             const char* nexthop_name = argv[5];
00144             const char* type_str = argv[6];
00145             
00146             Node* nexthop = Topology::find_node(nexthop_name);
00147             if (!nexthop) {
00148                 resultf("invalid next hop node %s", nexthop_name);
00149                 return TCL_ERROR;
00150             }
00151                         
00152             Link::link_type_t type = Link::str_to_link_type(type_str);
00153             if (type == Link::LINK_INVALID) {
00154                 resultf("invalid link type %s", type_str);
00155                 return TCL_ERROR;
00156             }
00157                         
00158             SimConvergenceLayer* simcl = SimConvergenceLayer::instance();
00159                                                 
00160             Link* link = Link::create_link(name, type, simcl, nexthop->name(), 
00161                                            argc - 7, &argv[7]);                                                                            
00162             if (!link)
00163                 return TCL_ERROR;
00164             
00165             Simulator::post(new SimAddLinkEvent(time, node_, link));
00166             return TCL_OK;
00167         }
00168 
00169         resultf("node link: unsupported subcommand %s", subcmd);
00170         return TCL_ERROR;
00171     }
00172         
00173     else if (strcmp(cmd, "registration") == 0)
00174     {
00175         if (strcmp(subcmd, "add") == 0) {
00176             // <node> X registration add <eid>
00177             const char* eid_str = argv[4];
00178             EndpointIDPattern eid(eid_str);
00179 
00180             if (!eid.valid()) {
00181                 resultf("error in node registration add %s: "
00182                         "invalid demux eid", eid_str);
00183                 return TCL_ERROR;
00184             }
00185 
00186             Registration* r = new SimRegistration(node_, eid);
00187             RegistrationAddedEvent* e =
00188                 new RegistrationAddedEvent(r, EVENTSRC_ADMIN);
00189             
00190             Simulator::post(new SimRouterEvent(time, node_, e));
00191             
00192             return TCL_OK;
00193         }        
00194         resultf("node registration: unsupported subcommand %s", subcmd);
00195         return TCL_ERROR;
00196     }
00197 
00198     else if (strcmp(cmd, "tragent") == 0)
00199     {
00200         // <node> X tragent <src> <dst> <args>
00201         if (argc < 5) {
00202             wrong_num_args(argc, argv, 3, 5, INT_MAX);
00203             return TCL_ERROR;
00204         }
00205         
00206         const char* src = argv[3];
00207         const char* dst = argv[4];
00208 
00209         // see if src/dest are node names, in which case we use its
00210         // local eid as the source address
00211         EndpointID src_eid;
00212         Node* src_node = Topology::find_node(src);
00213         if (src_node) {
00214             src_eid.assign(src_node->local_eid());
00215         } else {
00216             src_eid.assign(src);
00217             if (!src_eid.valid()) {
00218                 resultf("node tragent: invalid src eid %s", src);
00219                 return TCL_ERROR;
00220             }
00221         }
00222         
00223         EndpointID dst_eid;
00224         Node* dst_node = Topology::find_node(dst);
00225         if (dst_node) {
00226             dst_eid.assign(dst_node->local_eid());
00227         } else {
00228             dst_eid.assign(dst);
00229             if (!dst_eid.valid()) {
00230                 resultf("node tragent: invalid dst eid %s", dst);
00231                 return TCL_ERROR;
00232             }
00233         }
00234         
00235         TrAgent* a = TrAgent::init(node_, time, src_eid, dst_eid,
00236                                    argc - 5, argv + 5);
00237         if (!a) {
00238             resultf("error in tragent config");
00239             return TCL_ERROR;
00240         }
00241         
00242         return TCL_OK;
00243     }
00244 
00245     else
00246     {
00247         resultf("node: unsupported subcommand %s", cmd);
00248         return TCL_ERROR;
00249     }
00250 }
00251 
00252 } // namespace dtnsim

Generated on Thu Jun 7 16:56:51 2007 for DTN Reference Implementation by  doxygen 1.5.1