--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+
+@clsinit_copy
+class NS3BaseApplication(NS3Base):
+ _rtype = "ns3::Application"
+
+ def _connect_object(self):
+ node = self.node
+ if node and node.uuid not in self.connected:
+ self.simulator.invoke(node.uuid, "AddApplication", self.uuid)
+ self._connected.add(node.uuid)
+
from nepi.execution.resource import ResourceManager, clsinit_copy, \
ResourceState, reschedule_delay
+from nepi.execute.attributes import Flags
from nepi.resources.ns3.ns3simulator import NS3Simulator
+from nepi.resources.ns3.ns3node import NS3BaseNode
@clsinit_copy
class NS3Base(ResourceManager):
- _rtype = "NS3Base"
+ _rtype = "ns3::Object"
+
+ def __init__(self):
+ super(NS3Base, self).__init__()
+ self._uuid = None
+ self._connected = set()
+
+ @property
+ def connected(self):
+ return self._connected
+
+ @property
+ def uuid(self):
+ return self._uuid
@property
def simulator(self):
- simulator = self.get_connected(NS3Simulator.get_rtype())
- if simulator: return simulator[0]
+ simulators = self.get_connected(NS3Simulator.get_rtype())
+ if simulators: return simulators[0]
+ # if the object is not directly connected to the simulator,
+ # it should be connected to a node
+ node = self.node
+ if node: return node.simulator
+ return None
+
+ @property
+ def node(self):
+ nodes = self.get_connected(NS3BaseNode.get_rtype())
+ if nodes: return nodes[0]
return None
+ @property
+ def others_to_wait(self):
+ others = set()
+ node = self.node
+ if node: others.add(node)
+ return others
+
+ def _instantiate_object(self):
+ if self.uuid:
+ return
+
+ kwargs = dict()
+ for attr in self._attrs:
+ if not attr.value or attr.has_flag(Flags.ReadOnly):
+ continue
+
+ kwargs[attr.name] = attr.value
+
+ self.uuid = self.simulator.factory(self.get_rtype(), **kwargs)
+
+ def _configure_object(self):
+ pass
+
+ def _connect_object(self):
+ node = self.node
+ if node and node.uuid not in self.connected:
+ self.simulator.invoke(node.uuid, "AggregateObject", self.uuid)
+ self._connected.add(node.uuid)
+
+ def _wait_others(self):
+ """ Returns the collection of ns-3 RMs that this RM needs to
+ wait for before start
+
+ This method should be overriden to wait for other ns-3
+ objects to be deployed before proceeding with the deployment
+
+ """
+ for other in self.others_to_wait:
+ if other and other.state < ResourceState.READY:
+ return True
+ return False
+
+ def do_provision(self):
+ # create run dir for ns3 object
+ # self.simulator.node.mkdir(self.run_home)
+
+ self._instantiate_object()
+ self._configure_object()
+ self._connect_object()
+
+ self.info("Provisioning finished")
+
+ super(NS3Base, self).do_provision()
+
def do_deploy(self):
- if not self.simulator or self.simulator.state < ResourceState.READY:
- self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.simulator.state )
+ if not self.simulator or self.simulator.state < ResourceState.READY or \
+ self._wait_others():
+ self.debug("---- RESCHEDULING DEPLOY ----" )
# ccnd needs to wait until node is deployed and running
self.ec.schedule(reschedule_delay, self.deploy)
def do_start(self):
if self.state == ResourceState.READY:
- ## TODO!!!
- self.info("Starting ...")
-
+ # No need to do anything, simulator.Run() will start every object
+ self.info("Starting")
self.set_started()
else:
msg = " Failed "
def do_stop(self):
if self.state == ResourceState.STARTED:
+ # No need to do anything, simulator.Destroy() will stop every object
self.info("Stopping command '%s'" % command)
- ## TODO!!!
-
self.set_stopped()
@property
def state(self):
- # First check if the ccnd has failed
- # TODO!!!
return self._state
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+from nepi.resources.ns3.ns3device import NS3BaseNetDevice
+
+@clsinit_copy
+class NS3BaseChannel(NS3Base):
+ _rtype = "ns3::Channel"
+
+ @property
+ def devices(self):
+ return self.get_connected(NS3BaseNetDevice.get_rtype())
+
+ @property
+ def simulator(self):
+ devices = self.devices
+ if devices: return device[0].node.simulator
+ return None
+
def create(self, clazzname, *args):
pass
+ def factory(self, type_name, **kwargs):
+ pass
+
def invoke(self, uuid, operation, *args):
pass
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+from nepi.resources.ns3.ns3channel import NS3BaseChannel
+
+@clsinit_copy
+class NS3BasePropagationDelayModel(NS3Base):
+ _rtype = "ns3::PropagationDelayModel"
+
+ @property
+ def simulator(self):
+ channel = self.channel
+ if channel: return channel.simulator
+ return None
+
+ @property
+ def channel(self):
+ channels = self.get_connected(NS3BaseChannel.get_rtype())
+ if channels: return channels[0]
+ return None
+
+ @property
+ def others_to_wait(self):
+ others = set()
+ channel = self.channel
+ if channel: others.add(channel)
+ return others
+
+ def _connect_object(self):
+ channel = self.channel
+ if channel and channel.uuid not in self.connected:
+ self.simulator.invoke(channel.uuid, "SetPropagationDelayModel", self.uuid)
+ self._connected.add(channel.uuid)
+
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+from nepi.resources.ns3.ns3channel import NS3Channel
+
+@clsinit_copy
+class NS3BaseNetDevice(NS3Base):
+ _rtype = "ns3::NetDevice"
+
+ @property
+ def channel(self):
+ channels = self.get_connected(NS3BaseChannel.get_rtype())
+ if channels: return channels[0]
+ return None
+
+ @property
+ def others_to_wait(self):
+ others = set()
+ node = self.node
+ if node: others.add(node)
+
+ channel = self.channel
+ if channel: others.add(channel)
+ return others
+
+ def _connect_object(self):
+ node = self.node
+ if node and node.uuid not in self.connected:
+ self.simulator.invoke(node.uuid, "AddDevice", self.uuid)
+ self._connected.add(node.uuid)
+
+ channel = self.channel
+ if channel and channel.uuid not in self.connected:
+ self.simulator.invoke(self.uuid, "Attach", channel.uuid)
+ self._connected.add(channel.uuid)
+
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+
+@clsinit_copy
+class NS3BaseIpV4Protocol(Ns3Base):
+ _rtype = "ns3::IpV4Protocol"
+
+ def do_provision(self):
+ # create run dir for ns3 object
+ # self.simulator.node.mkdir(self.run_home)
+
+ self._instantiate_object()
+
+ uuid_list_routing = simulator.create("Ipv4ListRouting")
+ simulator.invoke(self.uuid, "SetRoutingProtocol", uuid_list_routing)
+
+ uuid_static_routing = simulator.create("Ipv4StaticRouting")
+ simulator.invoke(self.uuid, "SetRoutingProtocol", uuid_static_routing, 1)
+
+ super(NS3BaseIpV4Protocol, self).do_provision()
+
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+from nepi.resources.ns3.ns3channel import NS3BaseChannel
+
+@clsinit_copy
+class NS3BasePropagationLossModel(NS3Base):
+ _rtype = "ns3::PropagationLossModel"
+
+ @property
+ def simulator(self):
+ channel = self.channel
+ if channel: return channel.simulator
+ return None
+
+ @property
+ def channel(self):
+ channels = self.get_connected(NS3BaseChannel.get_rtype())
+ if channels: return channels[0]
+ return None
+
+ @property
+ def others_to_wait(self):
+ others = set()
+ channel = self.channel
+ if channel: others.add(channel)
+ return others
+
+ def _connect_object(self):
+ channel = self.channel
+ if channel and channel.uuid not in self.connected:
+ self.simulator.invoke(channel.uuid, "SetPropagationLossModel", self.uuid)
+ self._connected.add(channel.uuid)
+
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+from nepi.resources.ns3.ns3device import NS3BaseDevice
+
+@clsinit_copy
+class NS3BaseWifiRemoteStationManager(NS3Base):
+ _rtype = "ns3::WifiRemoteStationManager"
+
+ @property
+ def device(self):
+ devices = self.get_connected(NS3BaseDevice.get_rtype())
+ if devices: return devices[0]
+ return None
+
+ @property
+ def node(self):
+ device = self.device
+ if device: return device.node
+ return None
+
+ @property
+ def others_to_wait(self):
+ others = set()
+ device = self.device
+ if device: others.add(device)
+ return others
+
+ def _connect_object(self):
+ device = self.device
+ if device and device.uuid not in self.connected:
+ self.simulator.invoke(device.uuid, "SetRemoteStationManager", self.uuid)
+ self._connected.add(device.uuid)
+
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+
+@clsinit_copy
+class NS3BaseNode(Ns3Base):
+ _rtype = "ns3::Node"
+
+ @property
+ def others_to_wait(self):
+ return set()
+
+ def _configure_object(self):
+ ### node.AggregateObject(PacketSocketFactory())
+ uuid_packet_socket_factory = self.simulator.create("PacketSocketFactory")
+ self.simulator.invoke(self.uuid, "AggregateObject", uuid_packet_socket_factory)
+
--- /dev/null
+#
+# NEPI, a framework to manage network experiments
+# Copyright (C) 2014 INRIA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+from nepi.execution.resource import clsinit_copy
+from nepi.resources.ns3.ns3base import NS3Base
+from nepi.resources.ns3.ns3device import NS3BaseNetDevice
+
+@clsinit_copy
+class NS3BaseQueue(NS3Base):
+ _rtype = "ns3::Queue"
+
+ @property
+ def device(self):
+ devices = self.get_connected(NS3BaseNetDevice.get_rtype())
+ if devices: return devices[0]
+ return None
+
+ @property
+ def node(self):
+ device = self.device
+ if device: return device.node
+ return None
+
+ @property
+ def others_to_wait(self):
+ others = set()
+ device = self.device
+ if device: others.add(device)
+ return others
+
+ def _connect_object(self):
+ device = self.device
+ if device and device.uuid not in self.connected:
+ self.simulator.invoke(device.uuid, "SetQueue", self.uuid)
+ self._connected.add(device.uuid)
+
class NS3WrapperMessage:
CREATE = "CREATE"
+ FACTORY = "FACTORY"
INVOKE = "INVOKE"
SET = "SET"
GET = "GET"
uuid = ns3_wrapper.create(clazzname, *args)
return uuid
+ if msg == NS3WrapperMessage.FACTORY:
+ type_name = args.pop(0)
+ kwargs = args.pop(0)
+
+ uuid = ns3_wrapper.factory(type_name, **kwargs)
+ return uuid
+
if msg == NS3WrapperMessage.INVOKE:
uuid = args.pop(0)
operation = args.pop(0)
def create(self, clazzname, *args):
return self.client.create(clazzname, *args)
+ def factory(self, type_name, **kwargs):
+ return self.client.factory(type_name, **kwargs)
+
def invoke(self, uuid, operation, *args):
return self.client.invoke(uuid, operation, *args)
def get_object(self, uuid):
return self._objects.get(uuid)
- def factory(self, type_name, *kwargs):
+ def factory(self, type_name, **kwargs):
if type_name not in allowed_types:
msg = "Type %s not supported" % (type_name)
self.logger.error(msg)
import os
import re
+def select_base_class(ns3, tid):
+ rtype = tid.GetName()
+
+ type_id = ns3.TypeId()
+ appbase = type_id.LookupByName("ns3::Application")
+ devicebase = type_id.LookupByName("ns3::NetDevice")
+ channelbase = type_id.LookupByName("ns3::Channel")
+ queuebase = type_id.LookupByName("ns3::Queue")
+ lossbase = type_id.LookupByName("ns3::PropagationLossModel")
+ delaybase = type_id.LookupByName("ns3::PropagationDelayModel")
+ managerbase = type_id.LookupByName("ns3::WifiRemoteStationManager")
+
+ if tid.IsChiledOf(appbase):
+ base_class_import = "from nepi.resources.ns3.ns3application import NS3BaseApplication"
+ base_class = "NS3BaseApplication"
+ elif tid.IsChiledOf(devicebase):
+ base_class_import = "from nepi.resources.ns3.ns3device import NS3BaseNetDevice"
+ base_class = "NS3BaseNetDevice"
+ elif tid.IsChiledOf(channelbase):
+ base_class_import = "from nepi.resources.ns3.ns3channel import NS3BaseChannel"
+ base_class = "NS3BaseChannel"
+ elif tid.IsChiledOf(queuebase):
+ base_class_import = "from nepi.resources.ns3.ns3queue import NS3BaseQueue"
+ base_class = "NS3BaseQueue"
+ elif tid.IsChiledOf(lossbase):
+ base_class_import = "from nepi.resources.ns3.ns3loss import NS3BasePropagationLossModel"
+ base_class = "NS3BasePropagationLossDelay"
+ elif tid.IsChiledOf(delaybase):
+ base_class_import = "from nepi.resources.ns3.ns3delay import NS3BasePropagationDelayModel"
+ base_class = "NS3BasePropagationDelayModel"
+ elif tid.IsChiledOf(managerbase):
+ base_class_import = "from nepi.resources.ns3.ns3manager import NS3BaseWifiRemoteStationManager"
+ base_class = "NS3BaseWifiRemoteStationManager"
+ elif rtype == "ns3::Node":
+ base_class_import = "from nepi.resources.ns3.ns3node import NS3BaseNode"
+ base_class = "NS3BaseNode"
+ elif rtype == "ns3::Ipv4L3Protocol":
+ base_class_import = "from nepi.resources.ns3.ns3ipv4protocol import NS3BaseIpV4Protocol"
+ base_class = "NS3BaseIpV4Protocol"
+ else:
+ base_class_import = "from nepi.resources.ns3.ns3base import NS3Base"
+ base_class = "NS3Base"
+
+ return (base_class_import, base_class)
+
def create_ns3_rms():
ns3 = load_ns3_module()
attributes = "\n" + attributes if attributes else "pass"
traces = "\n" + traces if traces else "pass"
+ (base_class_import, base_class) = select_base_class(ns3, tid)
+
rtype = tid.GetName()
category = tid.GetGroupName()
- base_class_import = "from nepi.resources.ns3.ns3base import NS3Base"
- base_clas = "NS3Base"
-
classname = rtype.replace("ns3::", "NS3").replace("::","")
uncamm_rtype = re.sub('([a-z])([A-Z])', r'\1-\2', rtype).lower()
short_rtype = uncamm_rtype.replace("::","-")