servlib/cmd/ProphetCommand.cc
changeset 0 2b3e5ec03512
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/cmd/ProphetCommand.cc	Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,260 @@
+/*
+ *    Copyright 2006 Baylor University
+ * 
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ * 
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <dtn-config.h>
+#endif
+
+#include <oasys/util/StringBuffer.h>
+#include <oasys/util/OptParser.h>
+
+#include "bundling/BundleDaemon.h"
+#include "routing/BundleRouter.h"
+#include "prophet/QueuePolicy.h"
+#include "prophet/FwdStrategy.h"
+#include "prophet/Params.h"
+// default settings for ProphetRouter::params_ are set in prophet/Params.h
+#include "routing/ProphetRouter.h"
+
+#include "ProphetCommand.h"
+
+namespace dtn {
+
+ProphetCommand::ProphetCommand()
+    : TclCommand("prophet")
+{
+    bind_var(new oasys::DoubleOpt("encounter",
+                                  &ProphetRouter::params_.encounter_,
+                                  "val",
+                                  "predictability initialization constant "
+                                  "(between 0 and 1)"));
+
+    bind_var(new oasys::DoubleOpt("beta", &ProphetRouter::params_.beta_, 
+                                  "val",
+                                  "weight factor for transitive predictability "
+                                  "(between 0 and 1)"));
+
+    bind_var(new oasys::DoubleOpt("gamma", &ProphetRouter::params_.gamma_, 
+                                  "val",
+                                  "weight factor for predictability aging "
+                                  "(between 0 and 1)"));
+
+    bind_var(new oasys::UIntOpt("kappa", &ProphetRouter::params_.kappa_, 
+                                "val",
+                                "scaling factor for aging equation"));
+
+    bind_var(new oasys::UIntOpt("hello_dead", &ProphetRouter::params_.hello_dead_,
+                                "num",
+                                "number of HELLO intervals before "
+                                "peer considered unreachable"));
+
+    bind_var(new oasys::UIntOpt("max_forward",
+                                &ProphetRouter::params_.max_forward_,
+                                "num",
+                                "max times to forward bundle using GTMX"));
+
+    bind_var(new oasys::UIntOpt("min_forward",
+                                &ProphetRouter::params_.min_forward_,
+                                "num",
+                                "min times to forward bundle using LEPR"));
+
+    bind_var(new oasys::UIntOpt("age_period", &ProphetRouter::params_.age_period_,
+                                "val",
+                                "timer setting for aging algorithm and "
+                                "Prophet ACK expiry"));
+
+    bind_var(new oasys::BoolOpt("relay_node",
+                                &ProphetRouter::params_.relay_node_,
+                                "whether this node forwards bundles "
+                                "to other Prophet nodes"));
+
+    bind_var(new oasys::BoolOpt("internet_gw",
+                                &ProphetRouter::params_.internet_gw_,
+                                "whether this node forwards bundles to "
+                                "Internet domain"));
+
+    // smallest double that can fit into 8 bits:  0.0039 (1/255)
+    bind_var(new oasys::DoubleOpt("epsilon", &ProphetRouter::params_.epsilon_,
+                                  "val",
+                                  "lower limit on predictability before "
+                                  "dropping route"));
+
+    add_to_help("queue_policy=<policy>",
+                "set queue policy to one of the following:\n"
+                "\tfifo\tfirst in first out\n"
+                "\tmofo\tevict most forwarded first\n"
+                "\tmopr\tevict most favorably forwarded first\n"
+                "\tlmopr\tevict most favorably forwarded first (linear increase)\n"
+                "\tshli\tevict shortest lifetime first\n"
+                "\tlepr\tevice least probable first\n");
+
+    add_to_help("fwd_strategy=<strategy>",
+                "set forwarding strategy to one of the following:\n"
+                "\tgrtr\tforward if remote's P is greater\n"
+                "\tgtmx\tforward if \"grtr\" and NF < NF_Max\n"
+                "\tgrtr_plus\tforward if \"grtr\" and P > P_Max\n"
+                "\tgtmx_plus\tforward if \"grtr_plus\" and NF < NF_Max\n"
+                "\tgrtr_sort\tforward if \"grtr\" and sort desc by P_remote - P_local\n"
+                "\tgrtr_max\tforward if \"grtr\" and sort desc by P_remote\n");
+
+    add_to_help("hello_interval=<interval>",
+                "maximum delay between protocol messages, in 100ms units,"
+                " ranging from 1 to 255 (100 ms to 25.5s)");
+
+    add_to_help("max_route=<number>",
+                "maximum number of routes for Prophet to retain"
+                " (set to 0 to disable quota)");
+}
+
+int
+ProphetCommand::exec(int argc, const char** argv, Tcl_Interp* interp)
+{
+    (void)interp;
+    
+    if (argc != 2)
+    {
+        resultf("prophet: wrong number of arguments, got %d looking for 2",
+                argc);
+        return TCL_ERROR;
+    }
+
+    const char* cmd = argv[1];
+
+    // scoot past "prophet foo" to the value
+    argc -= 1;
+    argv += 1;
+
+    oasys::OptParser p;
+    const char* invalid = NULL;
+
+    if (strncmp(cmd,"fwd_strategy",strlen("fwd_strategy")) == 0)
+    {
+        oasys::EnumOpt::Case FwdStrategyCases[] =
+        {
+            {"grtr",      prophet::FwdStrategy::GRTR},
+            {"gtmx",      prophet::FwdStrategy::GTMX},
+            {"grtr_plus", prophet::FwdStrategy::GRTR_PLUS},
+            {"gtmx_plus", prophet::FwdStrategy::GTMX_PLUS},
+            {"grtr_sort", prophet::FwdStrategy::GRTR_SORT},
+            {"grtr_max",  prophet::FwdStrategy::GRTR_MAX},
+            {0, 0}
+        };
+        int fs_pass = ProphetRouter::params_.fs_;
+        p.addopt(new oasys::EnumOpt("fwd_strategy",
+                    FwdStrategyCases, &fs_pass, "",
+                    "forwarding strategies"));
+        if (! p.parse(argc,argv,&invalid))
+        {
+            resultf("bad parameter for fwd_strategy: %s",invalid);
+            return TCL_ERROR;
+        }
+
+        ProphetRouter::params_.fs_ =
+            (prophet::FwdStrategy::fwd_strategy_t)fs_pass;
+
+        resultf("fwd_strategy set to %s",
+                prophet::FwdStrategy::fs_to_str(ProphetRouter::params_.fs_));
+    }
+    else
+    if (strncmp(cmd,"queue_policy",strlen("queue_policy")) == 0)
+    {
+        oasys::EnumOpt::Case QueuePolicyCases[] =
+        {
+            {"fifo",  prophet::QueuePolicy::FIFO},
+            {"mofo",  prophet::QueuePolicy::MOFO},
+            {"mopr",  prophet::QueuePolicy::MOPR},
+            {"lmopr", prophet::QueuePolicy::LINEAR_MOPR},
+            {"shli",  prophet::QueuePolicy::SHLI},
+            {"lepr",  prophet::QueuePolicy::LEPR},
+            {0, 0}
+        };
+        int qp_pass;
+        p.addopt(new oasys::EnumOpt("queue_policy",
+                    QueuePolicyCases, &qp_pass, "",
+                    "queueing policies as put forth by Prophet, March 2006"));
+        if (! p.parse(argc,argv,&invalid))
+        {
+            resultf("bad parameter for queue_policy: %s",invalid);
+            return TCL_ERROR;
+        }
+
+        prophet::QueuePolicy::q_policy_t qp =
+            (prophet::QueuePolicy::q_policy_t)qp_pass;
+
+        ProphetRouter::params_.qp_ = qp;
+        if (ProphetRouter::is_init())
+        {
+            ProphetRouter* r = dynamic_cast<ProphetRouter*>(
+                                    BundleDaemon::instance()->router());
+            if (r != NULL)
+                r->set_queue_policy();
+        }
+        resultf("queue_policy set to %s", prophet::QueuePolicy::qp_to_str(qp));
+    }
+    else
+    if (strncmp(cmd,"hello_interval",strlen("hello_interval")) == 0)
+    {
+        u_int8_t hello_interval;
+        p.addopt(new oasys::UInt8Opt("hello_interval",
+                 &hello_interval,"seconds",
+                 "100s of milliseconds between HELLO beacons (between 1 "
+                 "and 255)"));
+
+        if (! p.parse(argc,argv,&invalid))
+        {
+            resultf("bad parameter for hello_interval: %s",invalid);
+            return TCL_ERROR;
+        }
+
+        ProphetRouter::params_.hello_interval_ = hello_interval;
+        if (ProphetRouter::is_init())
+        {
+            ProphetRouter* r = dynamic_cast<ProphetRouter*>(
+                    BundleDaemon::instance()->router());
+            if (r != NULL)
+                r->set_hello_interval();
+        }
+        resultf("hello_interval set to %d",hello_interval);
+    }
+    else
+    if (strncmp(cmd,"max_route",strlen("max_route")) == 0)
+    {
+        u_int max_route;
+        p.addopt(new oasys::UIntOpt("max_route",
+                 &max_route, "maximum number",
+                 "maximum number of routes for Prophet to retain"));
+
+        if (! p.parse(argc,argv,&invalid))
+        {
+            resultf("bad parameter for hello_interval: %s",invalid);
+            return TCL_ERROR;
+        }
+
+        ProphetRouter::params_.max_table_size_ = max_route;
+        if (ProphetRouter::is_init())
+        {
+            ProphetRouter* r = dynamic_cast<ProphetRouter*>(
+                    BundleDaemon::instance()->router());
+            if (r != NULL)
+                r->set_max_route();
+        }
+        resultf("max_route set to %u",max_route);
+    }
+
+    return TCL_OK;
+}
+
+} // namespace dtn