NodeCommand.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2005 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #include <stdlib.h>
00040 
00041 #include "Node.h"
00042 #include "NodeCommand.h"
00043 #include "SimConvergenceLayer.h"
00044 #include "SimRegistration.h"
00045 #include "Simulator.h"
00046 #include "Topology.h"
00047 #include "TrAgent.h"
00048 #include "bundling/Bundle.h"
00049 #include "contacts/ContactManager.h"
00050 #include "contacts/Link.h"
00051 #include "naming/EndpointID.h"
00052 #include "routing/BundleRouter.h"
00053 #include "routing/RouteTable.h"
00054 #include "reg/RegistrationTable.h"
00055 
00056 using namespace dtn;
00057 
00058 namespace dtnsim {
00059 
00060 NodeCommand::NodeCommand(Node* node)
00061     : TclCommand(node->name()), node_(node)
00062 {
00063     add_to_help("<time> route", "XXX");
00064     add_to_help("<time> add", "XXX");
00065     add_to_help("<time> tragent", "XXX");
00066     add_to_help("<time> link", "XXX");
00067     add_to_help("<time> registration", "XXX");
00068 }
00069 
00070 int
00071 NodeCommand::exec(int argc, const char** argv, Tcl_Interp* interp)
00072 {
00073     (void)interp;
00074     
00075     if (argc < 3) {
00076         wrong_num_args(argc, argv, 2, 4, INT_MAX);
00077         return TCL_ERROR;
00078     }
00079 
00080     // pull out the time and subcommand
00081     char* end;
00082     double time = strtod(argv[1], &end);
00083     if (*end != '\0') {
00084         resultf("time value '%s' invalid", argv[1]);
00085         return TCL_ERROR;
00086     }
00087 
00088     // for all commands and their side-effects, install the node as
00089     // the "singleton" BundleDaemon instance, and store the command
00090     // time in the node so any posted events happen in the future
00091     node_->set_active();
00092 
00093     const char* cmd = argv[2];
00094     const char* subcmd = NULL;
00095     if (argc >= 4) {
00096         subcmd = argv[3];
00097     }
00098 
00099     if (strcmp(cmd, "route") == 0)
00100     {
00101         if (strcmp(subcmd, "local_eid") == 0) {
00102             if (time != 0) {
00103                 resultf("node %s %s must be run at time 0", cmd, subcmd);
00104                 return TCL_ERROR;
00105             }
00106         
00107             if (argc == 4) {
00108                 // <node> 0 route local_eid
00109                 set_result(node_->local_eid().c_str());
00110                 return TCL_OK;
00111                 
00112             } else if (argc == 5) {
00113                 // <node> 0 route local_eid <eid>
00114                 node_->set_local_eid(argv[4]);
00115 
00116                 if (! node_->local_eid().valid()) {
00117                     resultf("invalid eid '%s'", argv[4]);
00118                     return TCL_ERROR;
00119                 }
00120                 return TCL_OK;
00121             } else {
00122                 wrong_num_args(argc, argv, 4, 4, 5);
00123                 return TCL_ERROR;
00124             }
00125         }
00126         else if (strcmp(subcmd, "add") == 0)
00127         {
00128             // <node> X route add <dest> <link/node>
00129             if (argc != 6) {
00130                 wrong_num_args(argc, argv, 2, 6, 6);
00131                 return TCL_ERROR;
00132             }
00133 
00134             const char* dest_str = argv[4];
00135             const char* nexthop = argv[5];
00136 
00137             log_debug("adding route to %s through %s", dest_str, nexthop);
00138             
00139             EndpointIDPattern dest(dest_str);
00140             if (!dest.valid()) {
00141                 resultf("invalid destination eid %s", dest_str);
00142                 return TCL_ERROR;
00143             }
00144 
00145             Simulator::post(new SimAddRouteEvent(time, node_, dest, nexthop));
00146             
00147             return TCL_OK;
00148         }
00149         
00150         resultf("node route: unsupported subcommand %s", subcmd);
00151         return TCL_ERROR;
00152     }
00153     else if (strcmp(cmd, "link") == 0)
00154     {
00155         if (strcmp(subcmd, "add") == 0) {
00156             // <node1> X link add <name> <peer> <type> <args>
00157             if (argc < 6) {
00158                 wrong_num_args(argc, argv, 2, 7, INT_MAX);
00159                 return TCL_ERROR;
00160             }
00161 
00162             const char* name = argv[4];
00163             const char* nexthop_name = argv[5];
00164             const char* type_str = argv[6];
00165             
00166             Node* nexthop = Topology::find_node(nexthop_name);
00167 
00168             if (!nexthop) {
00169                 resultf("invalid next hop node %s", nexthop_name);
00170                 return TCL_ERROR;
00171             }
00172                 
00173             Link::link_type_t type = Link::str_to_link_type(type_str);
00174             if (type == Link::LINK_INVALID) {
00175                 resultf("invalid link type %s", type_str);
00176                 return TCL_ERROR;
00177             }
00178 
00179             SimConvergenceLayer* simcl = SimConvergenceLayer::instance();
00180             Link* link = Link::create_link(name, type, simcl, nexthop->name(),
00181                                            argc - 7, &argv[7]);
00182             if (!link)
00183                 return TCL_ERROR;
00184             
00185             Simulator::post(new SimAddLinkEvent(time, node_, link));
00186 
00187             return TCL_OK;
00188         }
00189 
00190         resultf("node link: unsupported subcommand %s", subcmd);
00191         return TCL_ERROR;
00192     }
00193     else if (strcmp(cmd, "registration") == 0)
00194     {
00195         if (strcmp(subcmd, "add") == 0) {
00196             // <node> X registration add <eid>
00197             const char* eid_str = argv[4];
00198             EndpointIDPattern eid(eid_str);
00199 
00200             if (!eid.valid()) {
00201                 resultf("error in node registration add %s: "
00202                         "invalid demux eid", eid_str);
00203                 return TCL_ERROR;
00204             }
00205 
00206             Registration* r = new SimRegistration(node_, eid);
00207             RegistrationAddedEvent* e =
00208                 new RegistrationAddedEvent(r, EVENTSRC_ADMIN);
00209             Simulator::post(new SimRouterEvent(time, node_, e));
00210             
00211             return TCL_OK;
00212         }        
00213         resultf("node registration: unsupported subcommand %s", subcmd);
00214         return TCL_ERROR;
00215     }
00216 
00217     else if (strcmp(cmd, "tragent") == 0)
00218     {
00219         if (argc < 5) {
00220             wrong_num_args(argc, argv, 3, 5, INT_MAX);
00221             return TCL_ERROR;
00222         }
00223         
00224         const char* src = argv[3];
00225         const char* dst = argv[4];
00226 
00227         // see if src/dest are node names, in which case we use its
00228         // local eid as the source address
00229         EndpointID src_eid;
00230         Node* src_node = Topology::find_node(src);
00231         if (src_node) {
00232             src_eid.assign(src_node->local_eid());
00233         } else {
00234             src_eid.assign(src);
00235             if (!src_eid.valid()) {
00236                 resultf("node tragent: invalid src eid %s", src);
00237                 return TCL_ERROR;
00238             }
00239         }
00240         
00241         EndpointID dst_eid;
00242         Node* dst_node = Topology::find_node(dst);
00243         if (dst_node) {
00244             dst_eid.assign(dst_node->local_eid());
00245         } else {
00246             dst_eid.assign(dst);
00247             if (!dst_eid.valid()) {
00248                 resultf("node tragent: invalid dst eid %s", dst);
00249                 return TCL_ERROR;
00250             }
00251         }
00252         
00253         TrAgent* a = TrAgent::init(node_, time, src_eid, dst_eid,
00254                                    argc - 5, argv + 5);
00255         if (!a) {
00256             resultf("error in tragent config");
00257             return TCL_ERROR;
00258         }
00259         
00260         return TCL_OK;
00261     }
00262 
00263     else
00264     {
00265         resultf("node: unsupported subcommand %s", cmd);
00266         return TCL_ERROR;
00267     }
00268 }
00269 
00270 } // namespace dtnsim

Generated on Fri Dec 22 14:47:59 2006 for DTN Reference Implementation by  doxygen 1.5.1