Cleaning up ns-3 multi-host examples
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 16 Feb 2015 03:03:03 +0000 (04:03 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 16 Feb 2015 03:03:03 +0000 (04:03 +0100)
14 files changed:
examples/ns3/multi_host/case_a.py [deleted file]
examples/ns3/multi_host/case_b.py [deleted file]
examples/ns3/multi_host/case_c.py [deleted file]
examples/ns3/multi_host/code/agent.c
examples/ns3/multi_host/code/transmitter.c
examples/ns3/multi_host/distributed.py [new file with mode: 0644]
examples/ns3/multi_host/experiment.py [deleted file]
examples/ns3/multi_host/experiment_interconnected.py [deleted file]
examples/ns3/multi_host/experiment_interconnected_ns3_planetlab.py [deleted file]
examples/ns3/multi_host/experiment_interconnected_ns3ns3.py [deleted file]
examples/ns3/multi_host/hybrid.py [new file with mode: 0644]
examples/ns3/multi_host/parallel.py [new file with mode: 0644]
examples/ns3/multi_host/topology.py [new file with mode: 0644]
src/nepi/resources/linux/ns3/ns3simulation.py

diff --git a/examples/ns3/multi_host/case_a.py b/examples/ns3/multi_host/case_a.py
deleted file mode 100644 (file)
index 9c34226..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python\r
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2013 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-\r
-import os\r
-from experiment imptort Experiment\r
-from nepi.execution.ec import ExperimentController\r
-from nepi.execution.resource import ResourceState, ResourceManager\r
-\r
-# Experiment parameters\r
-experiment_id = "case_a"\r
-agent = "10.0.1.1"\r
-netblock = "10.0.1.0"\r
-prefix = "24"\r
-# number of nodes to test\r
-parameters = [3]\r
-\r
-# list of hosts for running the experiment on                                                     \r
-node_info = [\r
-        {"hostname":"onelab4.warsaw.rd.tp.pl", \r
-        "username":"inria_nepi", \r
-        "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])}]\r
-\r
-# tunning\r
-os.environ["NEPI_NTHREADS"] = "1"\r
-ResourceManager._reschedule_delay = "0s"\r
-\r
-# == Experimentation setup ====================================================\r
-def main():\r
-    # Prepare the ExperimentController\r
-    ec = ExperimentController(exp_id = experiment_id)\r
-\r
-    # run experimentation as long as there is something to do\r
-    while len(parameters) > 0:\r
-        # Collection of application being processed\r
-        jobs = list()\r
-\r
-        # Collection of experiments launched\r
-        xps = list()\r
-\r
-        # Push a job on each node in the cluster\r
-        for node in node_info:\r
-            # Stop if nothing else to do\r
-            if len(parameters) == 0:\r
-                break\r
-\r
-            # Determine what network size to test\r
-            nb_nodes = parameters.pop(0)\r
-\r
-            # Create the simulated network\r
-            xp = Experiment(ec, node, nb_nodes, False)\r
-            xp.build_topology(netblock, prefix, agent)\r
-\r
-            # Remember the experiments just created\r
-            xps.append(xp)\r
-\r
-            # Remember the applications to be executed\r
-            jobs += xp.apps\r
-        \r
-        # Let's run the experiment\r
-        ec.deploy()\r
-        ec.wait_finished(jobs)\r
-\r
-        # Check if everything went well for each experiment\r
-        for xp in xps:\r
-            # and see the output\r
-            stdout = ec.trace(xp.apps[0], "stdout")\r
-            print "[", stdout, "]"\r
-            # check if one transmitter failed (if everything goes well, all trasmitters\r
-            # must have stopped properly) (ignore the agent)\r
-            for app in xp.apps[1:len(xp.apps)]:\r
-                if ec.state(app, hr=False) != ResourceState.STOPPED:\r
-                    raise Exception("Crashed at size %d" % xp.nb_nodes)\r
-    # et voila \r
-    ec.shutdown()\r
-\r
-main()\r
diff --git a/examples/ns3/multi_host/case_b.py b/examples/ns3/multi_host/case_b.py
deleted file mode 100644 (file)
index b44c899..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python\r
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2013 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-\r
-import os\r
-from experiment_interconnected_ns3_ns3 import ExperimentInterconnectedNs3Ns3\r
-from nepi.execution.ec import ExperimentController \r
-from nepi.execution.resource import ResourceManager\r
-\r
-# Experiment parameters\r
-experiment_id = "case_b"\r
-agent = ["10.0.2.1", "10.0.1.1"]\r
-netblock = ["10.0.1.0", "10.0.2.0"]\r
-prefix = ["24", "24"]\r
-nb_nodes = [1, 1]\r
-# list of hosts for running the experiment on\r
-node_info = [\r
-        {"hostname":"onelab4.warsaw.rd.tp.pl", \r
-            "username":"inria_nepi", \r
-            "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])},  \r
-        {"hostname":"planet2.servers.ua.pt", \r
-            "username":"inria_nepi", \r
-            "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])}\r
-    ]\r
-\r
-# tunning\r
-os.environ["NEPI_NTHREADS"] = "1"\r
-ResourceManager._reschedule_delay = "0s"\r
-\r
-# == Experimentation setup ====================================================\r
-def main():\r
-    # Prepare the ExperimentController\r
-    ec = ExperimentController(exp_id = experiment_id)\r
-\r
-    # Create the simulated network\r
-    #\r
-    # On the first machine\r
-    xp1 = ExperimentInterconnectedNs3Ns3(ec, node_info[0], nb_nodes[0])\r
-    xp1.build_topology(netblock = netblock[0], prefix = prefix[0], target = agent[0])\r
-    #\r
-    # On the second machine\r
-    xp2 = ExperimentInterconnectedNs3Ns3(ec, node_info[1], nb_nodes[1])\r
-    xp2.build_topology(netblock = netblock[1], prefix = prefix[1], target = agent[1])\r
-\r
-    # interconnect the two experiments\r
-    xp1.interconnect(xp2)\r
-\r
-    # Let's run the experiment\r
-    ec.deploy()\r
-    ec.wait_finished( xp1.apps[1:len(xp1.apps)] + xp2.apps[1:len(xp2.apps)]  )\r
-\r
-\r
-    # and see the output\r
-    stdout = ec.trace(xp1.apps[0], "stdout")\r
-    print "1[", stdout, "]"\r
-\r
-    stdout = ec.trace(xp2.apps[0], "stdout")\r
-    print "2[", stdout, "]"\r
-\r
-    # et voila\r
-    ec.shutdown()\r
-\r
-main()\r
diff --git a/examples/ns3/multi_host/case_c.py b/examples/ns3/multi_host/case_c.py
deleted file mode 100644 (file)
index bd36cf7..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python\r
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2013 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-\r
-import os\r
-from experiment_interconnected_ns3_planetlab import ExperimentInterconnectedNs3Planetlab\r
-from nepi.execution.ec import ExperimentController \r
-from nepi.execution.resource import ResourceManager\r
-\r
-# Experiment parameters\r
-experiment_id = "case_c"\r
-agent = None\r
-netblock = "192.168.3.0"\r
-prefix = "25"\r
-nb_nodes = 1\r
-\r
-node_info = {\r
-    "hostname":"onelab4.warsaw.rd.tp.pl", \r
-    "username":"inria_nepi", \r
-    "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])\r
-    }\r
-\r
-\r
-# tunning\r
-os.environ["NEPI_NTHREADS"] = "1"\r
-ResourceManager._reschedule_delay = "0s"\r
-\r
-# == Experimentation setup ====================================================\r
-def main():\r
-    # Prepare the ExperimentController\r
-    ec = ExperimentController(exp_id = experiment_id)\r
-\r
-    # Create the simulated network\r
-    xp = ExperimentInterconnectedNs3Planetlab(ec, node_info, nb_nodes)\r
-    xp.build_topology(netblock = netblock, prefix = prefix, target = agent)\r
-\r
-    # Create Planetlab application\r
-    app = xp.add_planetlab_client(xp.ip_ap)\r
-\r
-    # Interconnect Planetlab and ns3\r
-    xp.interconnect("192.168.3.128", "25")\r
-\r
-    # Let's run the experiment\r
-    ec.deploy()\r
-    ec.wait_finished([app])\r
-\r
-    # and see the output\r
-    stdout = ec.trace(xp.apps[0], "stdout")\r
-    print "[", stdout, "]"\r
-\r
-    # et voila\r
-    ec.shutdown()\r
-\r
-main()\r
index 460401c..2a82fe7 100644 (file)
@@ -13,12 +13,6 @@ int main(int argc, char**argv)
   socklen_t len;\r
   char mesg[1000];\r
 \r
-  printf("DEBUT\n");\r
-  if (argc != 2)\r
-  {\r
-    fprintf(stderr, "usage:  %s <port>\n", argv[0]);\r
-    exit(1);\r
-  }\r
 \r
   sockfd = socket(AF_INET,SOCK_DGRAM,0);\r
   if(sockfd < 0){\r
@@ -29,7 +23,7 @@ int main(int argc, char**argv)
   bzero(&servaddr,sizeof(servaddr));\r
   servaddr.sin_family = AF_INET;\r
   servaddr.sin_addr.s_addr=htonl(INADDR_ANY);\r
-  servaddr.sin_port = htons(atoi(argv[1]));\r
+  servaddr.sin_port = htons(45005);\r
   if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0){\r
     perror("bind");\r
     exit(2);\r
@@ -49,5 +43,4 @@ int main(int argc, char**argv)
     mesg[n] = 0;\r
     printf("[%s]\n",mesg);\r
   }\r
-  printf("FIN\n");\r
 }\r
index 52bb3b2..10fe57e 100644 (file)
@@ -16,9 +16,9 @@ int main(int argc, char**argv)
   struct sockaddr_in servaddr,cliaddr;\r
   char * sendline = "coucou";\r
 \r
-  if (argc != 3)\r
+  if (argc != 2)\r
   {\r
-    fprintf(stderr, "usage:  %s <IP address> <port>\n", argv[0]);\r
+    fprintf(stderr, "usage:  %s <IP address>\n", argv[0]);\r
     exit(1);\r
   }\r
 \r
@@ -31,7 +31,7 @@ int main(int argc, char**argv)
   bzero(&servaddr,sizeof(servaddr));\r
   servaddr.sin_family = AF_INET;\r
   servaddr.sin_addr.s_addr=inet_addr(argv[1]);\r
-  servaddr.sin_port=htons(atoi(argv[2]));\r
+  servaddr.sin_port=htons(45005);\r
 \r
   int i;\r
   for(i = 0; i < 10; i++){\r
diff --git a/examples/ns3/multi_host/distributed.py b/examples/ns3/multi_host/distributed.py
new file mode 100644 (file)
index 0000000..c1a5a8b
--- /dev/null
@@ -0,0 +1,82 @@
+#!/usr/bin/env python\r
+#\r
+#    NEPI, a framework to manage network experiments\r
+#    Copyright (C) 2015 INRIA\r
+#\r
+#    This program is free software: you can redistribute it and/or modify\r
+#    it under the terms of the GNU General Public License version 2 as\r
+#    published by the Free Software Foundation;\r
+#\r
+#    This program is distributed in the hope that it will be useful,\r
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+#    GNU General Public License for more details.\r
+#\r
+#    You should have received a copy of the GNU General Public License\r
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
+#\r
+\r
+#\r
+# Note: To run this experiment you need to have a PlanetLab account.\r
+#\r
+# This experiment consists of a simulated wireless sensor network (ns-3)\r
+# with one fixed access point (AP), running an agent application, and several\r
+# mobile stations that run a transmitter application to send messages to\r
+# the AP.\r
+#\r
+# The experiment uses 2 networks like the one described above, running in 2\r
+# independent ns-3 instances in remote hosts, and transparently connected\r
+# through a UDP tunnel.\r
+\r
+#\r
+# command line:\r
+#\r
+# PYTHONPATH=$PYTHONPATH:src python examples/ns3/multi_host/ditributed.py\r
+#\r
+\r
+import os\r
+\r
+from nepi.execution.ec import ExperimentController\r
+from nepi.execution.resource import ResourceState, ResourceManager\r
+\r
+from topology import *\r
+\r
+# tunning\r
+os.environ["NEPI_NTHREADS"] = "1"\r
+ResourceManager._reschedule_delay = "0s"\r
+\r
+# list of hosts for running the experiment on\r
+hostname1 = "onelab4.warsaw.rd.tp.pl"\r
+hostname2 = "planet2.servers.ua.pt"\r
+\r
+(username, pl_user, pl_password, ssh_key, node_count) = get_options()\r
+\r
+ec = ExperimentController(exp_id="distributed")\r
+\r
+host1, simu1 = add_host_simu(ec, hostname1, username, pl_user, pl_password, \r
+        ssh_key)\r
+\r
+ap1, agent1 = build_ns3_topology(ec, simu1, node_count, network="10.1.0.0", \r
+        prefixlen="24", agent_ip="10.1.0.1")\r
+\r
+host2, simu2 = add_host_simu(ec, hostname2, username, pl_user, pl_password, ssh_key)\r
+ap2, agent2 = build_ns3_topology(ec, simu2, node_count, network="10.2.0.0", prefixlen="24", agent_ip="10.1.0.1")\r
+\r
+fddev1 = add_fdnet_device(ec, ap1, "10.0.0.1", "30")\r
+fddev2 = add_fdnet_device(ec, ap2, "10.0.0.2", "30")\r
+\r
+connect_with_udp_tunnel(ec, fddev1, fddev2)\r
+\r
+ec.deploy()\r
+\r
+ec.wait_finished([simu1, simu2])\r
+\r
+stdout = ec.trace(agent1, "stdout")\r
+print " Agent says:"\r
+print stdout\r
+\r
+ec.shutdown()\r
+\r
diff --git a/examples/ns3/multi_host/experiment.py b/examples/ns3/multi_host/experiment.py
deleted file mode 100644 (file)
index 34da12f..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2013 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-\r
-import ipaddr\r
-from random import randint\r
-from nepi.execution.ec import ExperimentController \r
-from nepi.execution.resource import ResourceState, ResourceAction\r
-\r
-# ########################################################\r
-class Experiment(object):\r
-    # ec : ExperimentController\r
-    # node: planetlab::Node\r
-    def __init__(self, ec, node_info, nb_nodes, real_time = True):\r
-        print "Experiement %s %s" % (node_info, nb_nodes)\r
-\r
-        # remember the ExperimentController the experiment is associated to\r
-        self.ec = ec\r
-\r
-        # define the physical machine to run the experiment on\r
-        self.add_node(node_info)\r
-\r
-        # number of simulated nodes moving in the \r
-        self.nb_nodes = nb_nodes\r
-        \r
-        # fix the geographical boundaries of the network\r
-        self.bounds_width = self.bounds_height = 100\r
-        \r
-        # fix the speed at which mobile nodes can move\r
-        self.speed = 1\r
-\r
-        # collection of simulated node (their GID) in the simulator\r
-        #   nsnodes[0] is always the GID of the simulated node containing the\r
-        #   access point\r
-        self.nsnodes = list()\r
-        \r
-        # collection of application (their GID) running in the simulator\r
-        #   apps[0] is always the GID of the agent application running on the\r
-        #   access point\r
-        self.apps = list()\r
-\r
-        # prepare the ns-3 simulator to use for the experiment\r
-        self.add_simulator(real_time)\r
-\r
-        # for sanity check\r
-        self.topology_built = False\r
-\r
-    def add_node(self, node_info):\r
-        """\r
-        Define the physical machine on which run the experiment\r
-        """\r
-        if node_info["hostname"] == "localhost":\r
-            self.node = self.ec.register_resource("linux::Node")\r
-            self.ec.set(self.node, "hostname", "localhost")\r
-        else:\r
-            self.node = self.ec.register_resource("planetlab::Node")\r
-            self.ec.set(self.node, "hostname", node_info["hostname"])\r
-            self.ec.set(self.node, "username", node_info["username"])\r
-            self.ec.set(self.node, "identity", node_info["identity"])\r
-            self.ec.set(self.node, "cleanProcesses", True)\r
-            self.ec.set(self.node, "cleanExperiment", True)\r
-\r
-        return self.node\r
-\r
-    def add_simulator(self, real_time):\r
-        """\r
-        Add a ns-3 simulator on the node used for the experiment\r
-        """\r
-        # creat the ns-3 simulator instance\r
-        self.simu = self.ec.register_resource("linux::ns3::Simulation")\r
-        self.ec.set (self.simu, "StopTime", "200s")\r
-        #\r
-        # run it in realtime mode if asked\r
-        if real_time:\r
-            self.ec.set(self.simu, "simulatorImplementationType", "ns3::RealtimeSimulatorImpl")\r
-        # \r
-        # log additional information\r
-        self.ec.set(self.simu, "checksumEnabled", True)\r
-        self.ec.set(self.simu, "verbose", True)\r
-        self.ec.set(self.simu, "enableDump", True)\r
-        self.ec.register_connection(self.simu, self.node)\r
-\r
-        return self.simu\r
-\r
-    # == ns-3 simulation helper functions =====================================\r
-    def add_nsnode(self):\r
-        """\r
-        Create a ns-3 node and add it to the simulator\r
-        """\r
-        # create a ns-3 node\r
-        nsnode = self.ec.register_resource("ns3::Node")\r
-        # enable its network stack\r
-        self.ec.set(nsnode, "enableStack", True)\r
-        self.ec.register_connection(nsnode, self.simu)\r
-\r
-        return nsnode\r
-\r
-    def add_wifi_channel(self):\r
-        """\r
-        Create the WiFi channel on which all nodes will be connected\r
-        """\r
-        # create a channel\r
-        channel = self.ec.register_resource("ns3::YansWifiChannel")\r
-        \r
-        # specify the delay model\r
-        delay = self.ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")\r
-        self.ec.register_connection(channel, delay)\r
-\r
-        # specify a loss model\r
-        loss  = self.ec.register_resource("ns3::LogDistancePropagationLossModel")\r
-        self.ec.register_connection(channel, loss)\r
-\r
-        return channel\r
-\r
-    def add_wifi_device(self, node, ip, prefix, access_point = False):\r
-        """\r
-        Add and configure the WiFi interface on a simulated node\r
-        """\r
-        \r
-        # create the WiFi network interface\r
-        dev = self.ec.register_resource("ns3::WifiNetDevice")\r
-        \r
-        # specify the network layer parameters\r
-        self.ec.set(dev, "ip", ip)\r
-        self.ec.set(dev, "prefix", prefix)\r
-        self.ec.register_connection(node, dev)\r
-        \r
-        # specify the MAC layer parameters\r
-        #\r
-        # can be in access point mode or not\r
-        if access_point:\r
-            mac = self.ec.register_resource("ns3::ApWifiMac")\r
-        else:\r
-            mac = self.ec.register_resource("ns3::StaWifiMac")\r
-        # the MAC is IEEE 802.11a\r
-        self.ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")\r
-        self.ec.register_connection(dev, mac)\r
-\r
-        # specify the physical layer parameters\r
-        phy = self.ec.register_resource("ns3::YansWifiPhy")\r
-        #\r
-        # it physical layer is IEEE802.11a\r
-        self.ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")\r
-        self.ec.register_connection(dev, phy)\r
-        #\r
-        # specify an error model for transmissions\r
-        error = self.ec.register_resource("ns3::NistErrorRateModel")\r
-        self.ec.register_connection(phy, error)\r
-        \r
-        # specify the Wifi manager to be assocated with the interface\r
-        manager = self.ec.register_resource("ns3::ArfWifiManager")\r
-        self.ec.register_connection(dev, manager)\r
-\r
-        return dev, phy\r
-\r
-    def add_random_mobility(self, node, x, y, z, speed, bounds_width, bounds_height):\r
-        """\r
-        Create a mobility model for node with random movements\r
-        """\r
-        position = "%d:%d:%d" % (x, y, z)\r
-        bounds = "0|%d|0|%d" % (bounds_width, bounds_height) \r
-        speed = "ns3::UniformRandomVariable[Min=%d|Max=%s]" % (speed, speed)\r
-        pause = "ns3::ConstantRandomVariable[Constant=1.0]"\r
-\r
-        mobility = self.ec.register_resource("ns3::RandomDirection2dMobilityModel")\r
-        self.ec.set(mobility, "Position", position)\r
-        self.ec.set(mobility, "Bounds", bounds)\r
-        self.ec.set(mobility, "Speed", speed)\r
-        self.ec.set(mobility, "Pause",  pause)\r
-        self.ec.register_connection(node, mobility)\r
-\r
-        return mobility\r
-\r
-    def add_constant_mobility(self, node, x, y, z):\r
-        """\r
-        Create a mobility model for node with a constant position\r
-        """\r
-        mobility = self.ec.register_resource("ns3::ConstantPositionMobilityModel") \r
-        position = "%d:%d:%d" % (x, y, z)\r
-        self.ec.set(mobility, "Position", position)\r
-        self.ec.register_connection(node, mobility)\r
-\r
-        return mobility\r
-\r
-    def create_simulated_node(self, ip, prefix, channel, access_point, x, y):\r
-        """\r
-        Create a simulated node connected on a WiFi channel\r
-        """\r
-        # Create the ns node that will run the application\r
-        nsnode = self.add_nsnode()\r
-\r
-        # Add a WiFi interface to the node\r
-        dev, phy = self.add_wifi_device(nsnode, ip, prefix, access_point)\r
-        #\r
-        # Connect the access point to the WiFi network\r
-        self.ec.register_connection(channel, phy)\r
-\r
-        # Specify that the node mobility \r
-        #\r
-        # access point is not mobile\r
-        if access_point:\r
-            mobility = self.add_constant_mobility(nsnode, x, y, 0)\r
-        # other nodes have random mobility pattern\r
-        else:\r
-            mobility = self.add_random_mobility(nsnode, x, y, 0, self.speed, self.bounds_width, self.bounds_height)\r
-\r
-        return nsnode\r
-\r
-    def add_route(self, nsnode, netblock, prefix, nexthop):\r
-        """\r
-        add a route on ns-3 node nsnode for netblock/prefix via nexthop\r
-        """\r
-        route = self.ec.register_resource("ns3::Route")\r
-        self.ec.set(route, "network", netblock)\r
-        self.ec.set(route, "prefix", prefix)\r
-        self.ec.set(route, "nexthop", nexthop)\r
-        self.ec.register_connection(route, nsnode)\r
-        print "route %s/%s via %s added on nsnode %s (%s)" % (netblock, prefix, nexthop, nsnode, self)\r
-\r
-        return route\r
-\r
-    def add_vroute(self, dev, netblock, prefix, nexthop):\r
-        """\r
-        Add a route on Planetlab node for netblock/prefix via nexthop\r
-        """\r
-        route = self.ec.register_resource("planetlab::Vroute")\r
-        self.ec.set(route, "network", netblock)\r
-        self.ec.set(route, "prefix", prefix)\r
-        self.ec.set(route, "nexthop", nexthop)\r
-        self.ec.register_connection(route, dev)\r
-        print "Vroute %s/%s via %s added on nsnode %s (%s)" % (netblock, prefix, nexthop, dev, self)\r
-\r
-        return route\r
-\r
-    def add_agent(self, nsnode):\r
-        """\r
-        Add a agent application\r
-        """\r
-        # Create a DCE application running the agent code\r
-        app = self.ec.register_resource("linux::ns3::dce::Application")\r
-        self.ec.set(app, "sources", "code/agent.c")\r
-        self.ec.set(app "build", "gcc -fPIC -pie -rdynamic ${SRC}/agent.c -o ${BIN_DCE}/agent")\r
-        self.ec.set(app, "binary", "agent")\r
-        self.ec.set(app, "arguments", "45005")\r
-        self.ec.set(app, "stackSize", 1<<20)\r
-        self.ec.set(app, "StartTime", "10s")\r
-        self.ec.set(app, "StopTime", "200s")\r
-\r
-        # Associate the application with the simulated node\r
-        self.ec.register_connection(app, nsnode)\r
-        \r
-        # Make the application start only once the simulated node is started\r
-        self.ec.register_condition(app, ResourceAction.START, \r
-                nsnode, ResourceState.STARTED, time="5s")\r
-\r
-        return app\r
-\r
-    def add_transmitter(self, nsnode):\r
-        """\r
-        Add a transmitter application\r
-        """\r
-        # Create a DCE application running the transmitter code\r
-        app = self.ec.register_resource("linux::ns3::dce::Application")\r
-        self.ec.set(app, "sources", "code/transmitter.c")\r
-        self.ec.set(app, "build", "gcc -fPIC -pie -rdynamic ${SRC}/transmitter.c -o ${BIN_DCE}/transmitter")\r
-        self.ec.set(app, "binary", "transmitter")\r
-        self.ec.set(app, "arguments", "%s;45005" % target)\r
-        self.ec.set(app, "stackSize", 1<<20)\r
-        self.ec.set(app, "StartTime", "10s")\r
-        self.ec.set(app, "StopTime", "200s")\r
-\r
-        # Associate the application with the simulated node\r
-        self.ec.register_connection(app, nsnode)\r
-        #\r
-        # Make the application start only once the simulated node and the serer are started\r
-        self.ec.register_condition(app, ResourceAction.START, \r
-                [nsnode, self.apps[0]], ResourceState.STARTED, time="10s")\r
-\r
-        return app\r
-\r
-    def add_planetlab_transmitter(self, target):\r
-        """\r
-        Add a planetlab transmitter application\r
-        """\r
-\r
-        # Create an application running the transmitter code\r
-        app = self.ec.register_resource("linux::Application")\r
-        self.ec.set(app, "sources", "code/transmitter.c")\r
-        self.ec.set(app, "build", "make ${SRC}/transmitter")\r
-        self.ec.set(app, "command", "${SRC}/transmitter %s 45005" % target)\r
-\r
-        # Associate the application with the Planetlab node\r
-        self.ec.register_connection(app, self.node)\r
-        \r
-        # Make the application start only once the simulated agent and the node are started\r
-        self.ec.register_condition(app, ResourceAction.START, \r
-                [self.apps[0], self.node], ResourceState.STARTED, time="10s")\r
-\r
-        return app\r
-\r
-    # == Topology construction ================================================\r
-    def build_topology(self, netblock, prefix, target):\r
-        """\r
-        Builds a topology composed of one fixed access point and nb_nodes\r
-        mobile nodes\r
-        """\r
-\r
-        # Rember network parameters\r
-        self.netblock = netblock\r
-        self.prefix = prefix\r
-\r
-        # Create the WiFi network via which nodes are connected\r
-        chan = self.add_wifi_channel()\r
-\r
-        # == Access point\r
-        # Geographical position of the access point\r
-        x=50\r
-        y=0\r
-\r
-        # the IP address of the access point is the first in the prefix\r
-        self.ip_ap = str(ipaddr.IPv4Address(self.netblock) + 1)\r
-        print "IP AP: %s " % (self.ip_ap)\r
-\r
-        # Create the ns node that will run the access point\r
-        nsnode = self.create_simulated_node(self.ip_ap, self.prefix, chan, True, x, y)\r
-        \r
-        # add the node in the collection of simulated nodes\r
-        self.nsnodes.append(nsnode)\r
-\r
-        # Run a agent application on the access point\r
-        agent = self.add_agent(nsnode)\r
-        \r
-        # add the agent application in the collection of applications\r
-        self.apps.append(agent)\r
-        \r
-        # Add nb_nodes mobile nodes in the WiFi network\r
-        for i in range(1, self.nb_nodes + 1):\r
-            # pic a random initial location\r
-            x = randint(0, self.bounds_width)\r
-            y = randint(0, self.bounds_height)\r
-\r
-            # define the appropriate IP address of the node (sequential IP in what remains after the access point IP)\r
-            ip = str(ipaddr.IPv4Address(self.ip_ap) + i)\r
-\r
-            print "IP mobile: " , ip\r
-\r
-            # Create the ns node that will run the mobile node\r
-            nsnode = self.create_simulated_node(ip, self.prefix, chan, False, x, y)\r
-            # \r
-            # add the node in the collection of simulated nodes\r
-            self.nsnodes.append(nsnode)\r
-\r
-            if target:\r
-                # Run a transmitter application on the mobile node\r
-                transmitter = self.add_transmitter(nsnode)\r
-                \r
-                # add the trasmitter application in the collection of applications\r
-                self.apps.append(transmitter)\r
-\r
-            # Add a default route via the access point\r
-            self.add_route(nsnode, "0.0.0.0", "0", self.ip_ap)\r
-\r
-        # for sanity check\r
-        self.topology_built = True\r
diff --git a/examples/ns3/multi_host/experiment_interconnected.py b/examples/ns3/multi_host/experiment_interconnected.py
deleted file mode 100644 (file)
index f95bd77..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2013 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-\r
-from experiment import Experiment\r
-\r
-class ExperimentInterconnected(Experiment):\r
-    def __init__(self, ec, node, nb_nodes, real_time = True):                                                                                                                      \r
-        super(ExperimentInterconnected, self).__init__(ec, node, nb_nodes, real_time)\r
-        self.interconnected = False\r
-        self.fddev = None\r
-\r
-    def add_fdnetdevice(self, ip, prefix, nsnode = None):\r
-        # Sanity check\r
-        #\r
-        # only one FD device allowed\r
-        if self.fddev:\r
-            raise Exception("A FD device is already setup")\r
-\r
-        # Attach the FD device to the access point by default\r
-        if not nsnode:\r
-            nsnode = self.nsnodes[0]\r
-\r
-        # Create the FD device\r
-        self.fddev = self.ec.register_resource("ns3::FdNetDevice")\r
-        self.ec.set(self.fddev, "ip", ip)\r
-        self.ec.set(self.fddev, "prefix", prefix)\r
-\r
-        # attach it to the simulated node\r
-        self.ec.register_connection(nsnode, self.fddev)\r
-\r
-        return self.fddev\r
diff --git a/examples/ns3/multi_host/experiment_interconnected_ns3_planetlab.py b/examples/ns3/multi_host/experiment_interconnected_ns3_planetlab.py
deleted file mode 100644 (file)
index 01f8bcd..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2013 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-\r
-import ipaddr\r
-from experiment_interconnected import ExperimentInterconnected\r
-\r
-class ExperimentInterconnectedNs3Planetlab(ExperimentInterconnected):\r
-    def add_tap_device(self, node, ip, prefix, pointopoint):\r
-        """\r
-        Add a point-to-point tap device on the planetlab node. This tap device\r
-        is used to exchange traffic with the simulated network\r
-        """\r
-        # Create the tap device\r
-        dev = self.ec.register_resource("planetlab::Tap")\r
-\r
-        # Define the local network associated with the TAP device\r
-        self.ec.set(dev, "ip", ip)\r
-        self.ec.set(dev, "prefix", prefix)\r
-\r
-        # Define the other side of the tap (the simulated network device)\r
-        self.ec.set(dev, "pointopoint", pointopoint)\r
-\r
-        # Associate the TAP device with the Planetlab node\r
-        self.ec.register_connection(node, dev)\r
-\r
-        return dev\r
-\r
-    def connect_with_tuntap(self, tap):\r
-        """\r
-        Connect the simulated network with the Planetlab node via the TAP of\r
-        the Planetlab node and the FD device of the simulated network\r
-        """\r
-        # Create the link\r
-        crosslink = self.ec.register_resource("planetlab::ns3::TunTapFdLink")                                                                                      \r
-\r
-        # Associate it with the Planetlab tap device on one side\r
-        self.ec.register_connection(crosslink, tap)\r
-        # \r
-        # Associate it with the simulated network FD device on the other side\r
-        self.ec.register_connection(crosslink, self.fddev)\r
-\r
-        return crosslink\r
-\r
-    def interconnect(self, netblock_pl, prefix_pl):\r
-        """\r
-        Interconnect a simulated network with a Planetlab network via a tap device\r
-        """\r
-        # sanity checks\r
-        #\r
-        # topology must be setup\r
-        if not self.topology_built:\r
-            raise Exception("Topology not setup on ", self)\r
-        #\r
-        # experiment cannot be interconnected to another experiment\r
-        if self.interconnected:\r
-            raise Exception("Experiment already interconnected on ", self)\r
-       \r
-\r
-        ip_simulated = str(ipaddr.IPv4Address(netblock_pl) + 1)\r
-        ip_pl = str(ipaddr.IPv4Address(ip_simulated) + 1)\r
-\r
-        # Add a TAP interface on the Planetlab machine to connect the real\r
-        # application with the simulated network\r
-        tap = self.add_tap_device(self.node, ip_pl, prefix_pl, ip_simulated)\r
-        \r
-        # Add an FD device on the simulator to connect to the real\r
-        self.add_fdnetdevice(ip_simulated, prefix_pl)\r
-\r
-        # Connect both Planetlab and simulated network via the tap device\r
-        self.connect_with_tuntap(tap)\r
-\r
-        # Route traffic for the Planetlab node to the Planetlab machine\r
-        self.add_route(self.nsnodes[0], netblock_pl, prefix_pl, self.ip_ap)\r
-\r
-        # Route traffic for the simulated node to the simulator\r
-        self.add_vroute(tap, self.netblock, self.prefix, ip_simulated)\r
-\r
-        # Sanity check\r
-        self.interconnected = True\r
-\r
diff --git a/examples/ns3/multi_host/experiment_interconnected_ns3ns3.py b/examples/ns3/multi_host/experiment_interconnected_ns3ns3.py
deleted file mode 100644 (file)
index ab2a8a2..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#\r
-#    NEPI, a framework to manage network experiments\r
-#    Copyright (C) 2013 INRIA\r
-#\r
-#    This program is free software: you can redistribute it and/or modify\r
-#    it under the terms of the GNU General Public License version 2 as\r
-#    published by the Free Software Foundation;\r
-#\r
-#    This program is distributed in the hope that it will be useful,\r
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#    GNU General Public License for more details.\r
-#\r
-#    You should have received a copy of the GNU General Public License\r
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
-#\r
-# Author: Damien Saucez <damien.saucez@inria.fr>\r
-#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
-\r
-from experiment_interconnected import ExperimentInterconnected\r
-\r
-class ExperimentInterconnectedNs3Ns3(ExperimentInterconnected):\r
-    def connect_with_udp_tunnel(self, xp_remote):\r
-        # Connect the two experiments via a UDP tunnel direcly on the FD devices\r
-        tunnel = self.ec.register_resource("planetlab::ns3::FdUdpTunnel")\r
-        self.ec.register_connection(tunnel, self.fddev)\r
-        self.ec.register_connection(tunnel, xp_remote.fddev)\r
-\r
-        return tunnel\r
-\r
-    def interconnect(self, xp_remote):\r
-        """\r
-        Interconnect two ns3 simulations via a UDP tunnel\r
-        """\r
-        # sanity checks\r
-        #\r
-        # topology must be setup\r
-        if not self.topology_built:\r
-            raise Exception("Topology not setup on ", self)\r
-        if not xp_remote.topology_built:\r
-            raise Exception("Topology not setup on ", xp_remote )\r
-        #\r
-        # experiment cannot be interconnected to another experiment\r
-        if self.interconnected:\r
-            raise Exception("Experiment already interconnected on ", self)\r
-        if xp_remote.interconnected:\r
-            raise Exception("Experiment already interconnected on ", xp_remote)\r
-\r
-        # IP for the AP of the two experiments\r
-        # XXX DSA: ugly\r
-        ip = ["10.0.0.1", "10.0.0.2"]\r
-\r
-        # add an FD device on both local and remote experiments\r
-        self.add_fdnetdevice(ip[0], "30")\r
-        xp_remote.add_fdnetdevice(ip[1], "30")\r
-\r
-        # Connect the two experiments via a UDP tunnel direcly on the FD devices\r
-        self.connect_with_udp_tunnel(xp_remote)\r
-\r
-        # Add a route to the remote network on each experiment, via the FD device\r
-        self.add_route(self.nsnodes[0], xp_remote.netblock, xp_remote.prefix, ip[1])\r
-        xp_remote.add_route(xp_remote.nsnodes[0], self.netblock, self.prefix, ip[0])\r
-\r
-        # Sanity check\r
-        self.interconnected = True\r
diff --git a/examples/ns3/multi_host/hybrid.py b/examples/ns3/multi_host/hybrid.py
new file mode 100644 (file)
index 0000000..0b36478
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/env python\r
+#\r
+#    NEPI, a framework to manage network experiments\r
+#    Copyright (C) 2015 INRIA\r
+#\r
+#    This program is free software: you can redistribute it and/or modify\r
+#    it under the terms of the GNU General Public License version 2 as\r
+#    published by the Free Software Foundation;\r
+#\r
+#    This program is distributed in the hope that it will be useful,\r
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+#    GNU General Public License for more details.\r
+#\r
+#    You should have received a copy of the GNU General Public License\r
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
+#\r
+\r
+#\r
+# Note that to run this experiment you need to have a PlanetLab account.\r
+#\r
+# This experiment consists of a simulated wireless sensor network (ns-3)\r
+# with one fixed access point (AP), running an agent application, and several\r
+# mobile stations that run a transmitter application to send messages to\r
+# the AP.\r
+#\r
+# One of the transmitter applications runs outside the simulation, on\r
+# the host, and sends messages to the AP through the FdNetDevice/TAP\r
+# link.\r
+#\r
+\r
+#\r
+# command line:\r
+#\r
+# PYTHONPATH=$PYTHONPATH:src python examples/ns3/multi_host/hybrid.py\r
+#\r
+\r
+import os\r
+\r
+from nepi.execution.ec import ExperimentController\r
+from nepi.execution.resource import ResourceState, ResourceManager\r
+\r
+from topology import *\r
+\r
+# tunning\r
+os.environ["NEPI_NTHREADS"] = "1"\r
+ResourceManager._reschedule_delay = "0s"\r
+\r
+# list of hosts for running the experiment on\r
+hostname1 = "onelab4.warsaw.rd.tp.pl"\r
+hostname2 = "planet2.servers.ua.pt"\r
+\r
+(username, pl_user, pl_password, ssh_key, node_count) = get_options()\r
+\r
+ec = ExperimentController(exp_id="hybrid")\r
+\r
+host, simu = add_host_simu(ec, hostname1, username, pl_user, pl_password, \r
+        ssh_key)\r
+\r
+ap, agent = build_ns3_topology(ec, simu, node_count, network="192.168.3.0", \r
+        prefixlen="25", agent_ip="192.168.3.1")\r
+\r
+fddev = add_fdnet_device(ec, ap, "192.168.3.129", "25")\r
+\r
+tap = ec.register_resource("planetlab::Tap")\r
+ec.set(tap, "ip", "192.168.3.130")\r
+ec.set(tap, "prefix", "25")\r
+ec.set(tap, "pointopoint", "192.168.3.129")\r
+ec.register_connection(host, tap)  \r
+\r
+connect_with_virtual_link(ec, tap, fddev)\r
+\r
+add_ns3_route(ec, ap, network="192.168.3.128", prefixlen="25", nexthop="192.168.3.1")\r
+add_planetlab_route(ec, tap, network="192.168.3.0", prefixlen="25", nexthop="192.168.3.129")\r
+\r
+transmitter = ec.register_resource("linux::Application")\r
+ec.set(transmitter, "sources", "code/transmitter.c")\r
+ec.set(transmitter, "build", "gcc ${SRC}/transmitter.c -o ${BIN}/transmitter")\r
+ec.set(transmitter, "command", "${BIN}/transmitter 192.168.3.1")\r
+ec.register_connection(transmitter, host)\r
+\r
+ec.deploy()\r
+\r
+ec.wait_finished([simu, transmitter])\r
+\r
+stdout = ec.trace(agent, "stdout")\r
+print " Agent says: "\r
+print stdout\r
+\r
+stdout = ec.trace(transmitter, "stdout")\r
+print " Live transmitter output: "\r
+print stdout\r
+\r
+ec.shutdown()\r
+\r
+\r
diff --git a/examples/ns3/multi_host/parallel.py b/examples/ns3/multi_host/parallel.py
new file mode 100644 (file)
index 0000000..a0be0a9
--- /dev/null
@@ -0,0 +1,85 @@
+#!/usr/bin/env python\r
+#\r
+#    NEPI, a framework to manage network experiments\r
+#    Copyright (C) 2015 INRIA\r
+#\r
+#    This program is free software: you can redistribute it and/or modify\r
+#    it under the terms of the GNU General Public License version 2 as\r
+#    published by the Free Software Foundation;\r
+#\r
+#    This program is distributed in the hope that it will be useful,\r
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+#    GNU General Public License for more details.\r
+#\r
+#    You should have received a copy of the GNU General Public License\r
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
+#\r
+\r
+#\r
+# Note: To run this experiment you need to have a PlanetLab account.\r
+#\r
+# This experiment consists of a simulated wireless sensor network (ns-3)\r
+# with one fixed access point (AP), running an agent application, and several\r
+# mobile stations that run a transmitter application to send messages to\r
+# the AP.\r
+#\r
+# The same experiment described above is run in parallel with different\r
+# number of mobile stations in 2 PlanetLab hosts.\r
+#\r
+\r
+#\r
+# command line:\r
+#\r
+# PYTHONPATH=$PYTHONPATH:src python examples/ns3/multi_host/parallel.py\r
+#\r
+\r
+import os\r
+\r
+from topology import *\r
+\r
+from nepi.execution.ec import ExperimentController\r
+from nepi.execution.resource import ResourceState, ResourceManager\r
+\r
+# tunning\r
+os.environ["NEPI_NTHREADS"] = "1"\r
+ResourceManager._reschedule_delay = "0s"\r
+\r
+# list of hosts for running the experiment on\r
+hostname1 = "onelab4.warsaw.rd.tp.pl"\r
+hostname2 = "planet2.servers.ua.pt"\r
+\r
+(username, pl_user, pl_password, ssh_key, node_count) = get_options()\r
+\r
+ec = ExperimentController(exp_id="parallel")\r
+counts = [node_count, 10]\r
+hosts = [hostname1, hostname2]\r
+\r
+simulations = []\r
+agents = []\r
+\r
+for hostname in hosts:\r
+    host, simu = add_host_simu(ec, hostname, username, pl_user, pl_password, \r
+            ssh_key)\r
+    simulations.append(simu)\r
+\r
+    node_count = counts.pop()\r
+    ap, agent = build_ns3_topology(ec, simu, node_count, network="10.1.0.0", \r
+            prefixlen="24", agent_ip="10.1.0.1")\r
+    agents.append(agent)\r
+\r
+ec.deploy()\r
+\r
+ec.wait_finished(simulations)\r
+\r
+for agent in agents:\r
+    stdout = ec.trace(agent, "stdout")\r
+    print " Agent says:"\r
+    print stdout\r
+\r
+ec.shutdown()\r
+\r
+\r
diff --git a/examples/ns3/multi_host/topology.py b/examples/ns3/multi_host/topology.py
new file mode 100644 (file)
index 0000000..70dbbbf
--- /dev/null
@@ -0,0 +1,286 @@
+#!/usr/bin/env python\r
+#\r
+#    NEPI, a framework to manage network experiments\r
+#    Copyright (C) 2015 INRIA\r
+#\r
+#    This program is free software: you can redistribute it and/or modify\r
+#    it under the terms of the GNU General Public License version 2 as\r
+#    published by the Free Software Foundation;\r
+#\r
+#    This program is distributed in the hope that it will be useful,\r
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+#    GNU General Public License for more details.\r
+#\r
+#    You should have received a copy of the GNU General Public License\r
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+#         Alina Quereilhac <alina.quereilhac@inria.fr>\r
+#\r
+\r
+import ipaddr\r
+from optparse import OptionParser\r
+import os\r
+from random import randint\r
+\r
+# list of hosts for running the experiment on\r
+hostname1 = "onelab4.warsaw.rd.tp.pl"\r
+hostname2 = "planet2.servers.ua.pt"\r
+\r
+def get_options():\r
+    # PlanetLab credentials\r
+    pl_slice = os.environ.get("PL_SLICE")\r
+    pl_user = os.environ.get("PL_USER")\r
+    pl_password = os.environ.get("PL_PASS")\r
+    pl_ssh_key = os.environ.get("PL_SSHKEY")\r
+\r
+    usage = ("usage: %prog -s <pl-slice> -u <pl-user> -p <pl-password> "\r
+                "-k <pl-ssh-key> -n <node-count> ")\r
+\r
+    parser = OptionParser(usage = usage)\r
+    parser.add_option("-s", "--pl-slice", dest="pl_slice",\r
+            help="PlanetLab slicename", default=pl_slice, type="str")\r
+    parser.add_option("-u", "--pl-user", dest="pl_user",\r
+            help="PlanetLab web username", default=pl_user, type="str")\r
+    parser.add_option("-p", "--pl-password", dest="pl_password",\r
+            help="PlanetLab web password", default=pl_password, type="str")\r
+    parser.add_option("-k", "--pl-ssh-key", dest="pl_ssh_key",\r
+            help="Path to private SSH key associated with the PL account",\r
+            default=pl_ssh_key, type="str")\r
+    parser.add_option("-n", "--node-count", dest="node_count",\r
+            help="Number of nodes in the wireless network",\r
+            default = 4, type="int")\r
+\r
+    (options, args) = parser.parse_args()\r
+\r
+    return (options.pl_slice, options.pl_user, options.pl_password, \r
+            options.pl_ssh_key, options.node_count)\r
+\r
+# == add host and simu =======================================================\r
+def add_host_simu(ec, hostname, username, pl_user, pl_password, ssh_key):\r
+    host = ec.register_resource("planetlab::Node")\r
+    ec.set(host, "hostname", hostname)\r
+\r
+    if username:\r
+        ec.set(host, "username", username)\r
+\r
+    if pl_user:\r
+        ec.set(host, "pluser", pl_user)\r
+\r
+    if pl_password:\r
+        ec.set(host, "plpassword", pl_password)\r
+\r
+    if ssh_key:\r
+        ec.set(host, "identity", ssh_key)\r
+\r
+    ec.set(host, "cleanProcesses", True)\r
+    ec.set(host, "cleanExperiment", True)\r
+\r
+    simu = ec.register_resource("linux::ns3::Simulation")\r
+    ec.set(simu, "simulatorImplementationType", "ns3::RealtimeSimulatorImpl")\r
+    ec.set(simu, "checksumEnabled", True)\r
+    ec.set(simu, "verbose", True)\r
+    ec.set(simu, "enableDump", True)\r
+    ec.set (simu, "StopTime", "200s")\r
+    ec.register_connection(simu, host)\r
+\r
+    return host, simu\r
+\r
+# == build topology  =========================================================\r
+\r
+def add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode):\r
+    # create the WiFi network interface\r
+    dev = ec.register_resource("ns3::WifiNetDevice")\r
+\r
+    # specify the network layer parameters\r
+    ec.set(dev, "ip", ip)\r
+    ec.set(dev, "prefix", prefixlen)\r
+    ec.register_connection(ns3_node, dev)\r
+\r
+    # specify the MAC layer parameters\r
+    #\r
+    # can be in access point mode or not\r
+    if ap_mode:\r
+        mac = ec.register_resource("ns3::ApWifiMac")\r
+    else:\r
+        mac = ec.register_resource("ns3::StaWifiMac")\r
+\r
+    # the MAC is IEEE 802.11a\r
+    ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")\r
+    ec.register_connection(dev, mac)\r
+\r
+    # specify the physical layer parameters\r
+    phy = ec.register_resource("ns3::YansWifiPhy")\r
+    #\r
+    # it physical layer is IEEE802.11a\r
+    ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")\r
+    ec.register_connection(dev, phy)\r
+    #\r
+    # specify an error model for transmissions\r
+    error = ec.register_resource("ns3::NistErrorRateModel")\r
+    ec.register_connection(phy, error)\r
+\r
+    # specify the Wifi manager to be assocated with the interface\r
+    manager = ec.register_resource("ns3::ArfWifiManager")\r
+    ec.register_connection(dev, manager)\r
+\r
+    return dev, phy\r
+\r
+def add_ns3_wifi_channel(ec):\r
+    channel = ec.register_resource("ns3::YansWifiChannel")\r
+\r
+    delay = ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")\r
+    ec.register_connection(channel, delay)\r
+\r
+    loss  = ec.register_resource("ns3::LogDistancePropagationLossModel")\r
+    ec.register_connection(channel, loss)\r
+\r
+    return channel\r
+\r
+# == Add random mobility\r
+def add_ns3_random_mobility(ec, ns3_node):\r
+    speed =  1\r
+    bounds_width = 100\r
+    bounds_height = 100\r
+    x = randint(0, bounds_width)\r
+    y = randint(0, bounds_height)\r
+    z = 0\r
+\r
+    position = "%d:%d:%d" % (x, y, z)\r
+    bounds = "0|%d|0|%d" % (bounds_width, bounds_height)\r
+    speed = "ns3::UniformRandomVariable[Min=%d|Max=%s]" % (speed, speed)\r
+    pause = "ns3::ConstantRandomVariable[Constant=1.0]"\r
+\r
+    mobility = ec.register_resource("ns3::RandomDirection2dMobilityModel")\r
+    ec.set(mobility, "Position", position)\r
+    ec.set(mobility, "Bounds", bounds)\r
+    ec.set(mobility, "Speed", speed)\r
+    ec.set(mobility, "Pause",  pause)\r
+    ec.register_connection(ns3_node, mobility)\r
+\r
+    return mobility\r
+\r
+# == Add constant mobility\r
+def add_ns3_constant_mobility(ec, ns3_node):\r
+    mobility = ec.register_resource("ns3::ConstantPositionMobilityModel")\r
+    position = "%d:%d:%d" % (0, 50, 0)\r
+    ec.set(mobility, "Position", position)\r
+    ec.register_connection(ns3_node, mobility)\r
+\r
+    return mobility\r
+\r
+# == add ns-3 node\r
+def add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False):\r
+    ns3_node = ec.register_resource("ns3::Node")\r
+    ec.set(ns3_node, "enableStack", True)\r
+    ec.register_connection(ns3_node, simu)\r
+\r
+    dev, phy = add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode)\r
+    ec.register_connection(channel, phy)\r
+\r
+    if not ap_mode:\r
+        add_ns3_random_mobility(ec, ns3_node)\r
+    else:\r
+        add_ns3_constant_mobility(ec, ns3_node)\r
+\r
+    return ns3_node\r
+\r
+# == add DCE agent\r
+def add_dce_agent(ec, ns3_node):\r
+    agent = ec.register_resource("linux::ns3::dce::Application")\r
+    ec.set(agent, "sources", "code/agent.c")\r
+    ec.set(agent, "build", "gcc -fPIC -pie -rdynamic ${SRC}/agent.c -o ${BIN_DCE}/agent")\r
+    ec.set(agent, "binary", "agent")\r
+    ec.set(agent, "stackSize", 1<<20)\r
+    ec.set(agent, "StartTime", "10s")\r
+    ec.set(agent, "StopTime", "200s")\r
+\r
+    ec.register_connection(agent, ns3_node)\r
+\r
+    return agent\r
+\r
+# == add DCE transmitter\r
+def add_dce_transmitter(ec, ns3_node, target):\r
+    transmitter = ec.register_resource("linux::ns3::dce::Application")\r
+    ec.set(transmitter, "sources", "code/transmitter.c")\r
+    ec.set(transmitter, "build", "gcc -fPIC -pie -rdynamic ${SRC}/transmitter.c -o ${BIN_DCE}/transmitter")\r
+    ec.set(transmitter, "binary", "transmitter")\r
+    ec.set(transmitter, "arguments", target)\r
+    ec.set(transmitter, "stackSize", 1<<20)\r
+    ec.set(transmitter, "StartTime", "10s")\r
+    ec.set(transmitter, "StopTime", "200s")\r
+    \r
+    ec.register_connection(transmitter, ns3_node)\r
+\r
+    return transmitter\r
+\r
+# == Add ns-3 route\r
+def add_ns3_route(ec, ns3_node, network, prefixlen, nexthop):\r
+    route = ec.register_resource("ns3::Route")\r
+    ec.set(route, "network", network)\r
+    ec.set(route, "prefix", prefixlen)\r
+    ec.set(route, "nexthop", nexthop)\r
+    ec.register_connection(route, ns3_node)\r
+\r
+    return route\r
+\r
+# = build ns3 topology =======================================================\r
+def build_ns3_topology(ec, simu, node_count, network, prefixlen, agent_ip):\r
+    channel = add_ns3_wifi_channel(ec)\r
+\r
+    net = ipaddr.IPv4Network("%s/%s" % (network, prefixlen)) \r
+    itr = net.iterhosts()\r
+\r
+    ap_ip = itr.next().exploded\r
+    ap = add_ns3_node(ec, simu, ap_ip, prefixlen, channel, ap_mode=True)\r
+\r
+    agent = None\r
+    if ap_ip == agent_ip:\r
+        agent = add_dce_agent(ec, ap)\r
+\r
+    for i in range(0, node_count):\r
+        ip = itr.next().exploded\r
+        sensor = add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False)\r
+        transmitter = add_dce_transmitter(ec, sensor, ap_ip)\r
+        add_ns3_route(ec, sensor, network="0.0.0.0", prefixlen="0", nexthop=ap_ip)\r
+\r
+    return ap, agent\r
+\r
+\r
+# == add FdNetDevice =========================================================\r
+def add_fdnet_device(ec, ap, ip, prefixlen):\r
+    fddev = ec.register_resource("ns3::FdNetDevice")\r
+    ec.set(fddev, "ip", ip)\r
+    ec.set(fddev, "prefix", prefixlen)\r
+    ec.register_connection(ap, fddev)\r
+\r
+    return fddev\r
+\r
+# == connect with UDP tunnel =================================================\r
+def connect_with_udp_tunnel(ec, fddev1, fddev2):                                                             \r
+    tunnel = ec.register_resource("planetlab::ns3::FdUdpTunnel")\r
+    ec.register_connection(tunnel, fddev1)\r
+    ec.register_connection(tunnel, fddev2)\r
+\r
+    return tunnel\r
+\r
+# == connect with virtual link ===============================================\r
+def connect_with_virtual_link(ec, tap, fddev):                                                                   \r
+    link = ec.register_resource("planetlab::ns3::TunTapFdLink")                          \r
+    ec.register_connection(link, tap)\r
+    ec.register_connection(link, fddev)\r
+\r
+    return link\r
+\r
+# == Add planet lab route ====================================================\r
+\r
+def add_planetlab_route(ec, dev, network, prefixlen, nexthop):\r
+    route = ec.register_resource("planetlab::Vroute")\r
+    ec.set(route, "network", network)\r
+    ec.set(route, "prefix", prefixlen)\r
+    ec.set(route, "nexthop", nexthop)\r
+    ec.register_connection(route, dev)\r
+\r
+    return route\r
+\r
index c39c1a3..f6be975 100644 (file)
@@ -335,6 +335,27 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
         
         super(LinuxApplication, self).do_release()
 
+    @property
+    def state(self):
+        super(LinuxApplication, self).state
+        
+        if self._state == ResourceState.STARTED:
+            try:
+                is_finished = self.invoke(SIMULATOR_UUID, "isFinished")
+                
+                if is_finished:
+                    self.set_stopped()
+            except:
+                msg = "Simulator failed. Can not retrieve state"
+                out = ""
+
+                import traceback
+                err = traceback.format_exc()
+                self.error(msg, out, err)
+                self.do_fail()
+
+        return self._state
+
     @property
     def enable_dce(self):
         if self._enable_dce is None: