From a46d3807241cf45324ef9e46ee2d8eb98ccb4f9d Mon Sep 17 00:00:00 2001 From: Alina Quereilhac Date: Sun, 16 Feb 2014 04:42:18 +0100 Subject: [PATCH] Fix #122 [NS3] Implement wireless model scenarios with mobility --- src/nepi/execution/attribute.py | 12 ++-- src/nepi/execution/resource.py | 10 +++ src/nepi/resources/linux/interface.py | 10 +-- src/nepi/resources/ns3/ns3base.py | 24 ++++++- src/nepi/resources/ns3/ns3channel.py | 3 + src/nepi/resources/ns3/ns3errorratemodel.py | 4 ++ src/nepi/resources/ns3/ns3ipv4l3protocol.py | 4 +- src/nepi/resources/ns3/ns3mobilitymodel.py | 44 +++++++++++++ src/nepi/resources/ns3/ns3netdevice.py | 25 +++++--- src/nepi/resources/ns3/ns3node.py | 26 ++++++++ .../resources/ns3/ns3propagationdelaymodel.py | 6 +- .../resources/ns3/ns3propagationlossmodel.py | 4 +- src/nepi/resources/ns3/ns3simulation.py | 4 +- src/nepi/resources/ns3/ns3wifichannel.py | 51 +++++++++++++++ src/nepi/resources/ns3/ns3wifimac.py | 32 +++++++++- src/nepi/resources/ns3/ns3wifinetdevice.py | 62 +++++++++++++++++++ src/nepi/resources/ns3/ns3wifiphy.py | 41 ++++++++++-- .../ns3/ns3wifiremotestationmanager.py | 4 +- .../ns3/resource_manager_generator.py | 16 +++-- test/resources/linux/ns3/ns3simulation.py | 61 +++++++++--------- 20 files changed, 371 insertions(+), 72 deletions(-) create mode 100644 src/nepi/resources/ns3/ns3mobilitymodel.py create mode 100644 src/nepi/resources/ns3/ns3wifichannel.py create mode 100644 src/nepi/resources/ns3/ns3wifinetdevice.py diff --git a/src/nepi/execution/attribute.py b/src/nepi/execution/attribute.py index 64a3d056..bda72e2c 100644 --- a/src/nepi/execution/attribute.py +++ b/src/nepi/execution/attribute.py @@ -39,8 +39,8 @@ class Flags: # Attribute value can be modified only before deployment Design = 1 << 2 # 4 - # Attribute value will be used only during the deployment face - Construct = 1 << 3 | Design # 8 + 4 + # Attribute value will be used at deployment time for initial configuration + Construct = 1 << 3 # 8 # Attribute provides credentials to access resources Credential = 1 << 4 | Design # 16 + 4 @@ -48,6 +48,10 @@ class Flags: # Attribute is a filter used to discover resources Filter = 1 << 5 | Design # 32 + 4 + # Attribute Flag is reserved for internal RM usage (i.e. should be + # transparent to the user) + Reserved = 1 << 6 # 64 + class Attribute(object): """ @@ -85,7 +89,7 @@ class Attribute(object): attributes. :type range: (int, int) or (float, float) - :param set_hook: Function that will be executed when ever a new + :param set_hook: Function that will be executed whenever a new value is set for the attribute. :type set_hook: function @@ -142,7 +146,7 @@ class Attribute(object): def has_flag(self, flag): """ Returns true if the attribute has the flag 'flag' - :param flag: Flag that need to be ckecked + :param flag: Flag to be checked :type flag: Flags """ return (self._flags & flag) == flag diff --git a/src/nepi/execution/resource.py b/src/nepi/execution/resource.py index e4c4b0c7..54af5e36 100644 --- a/src/nepi/execution/resource.py +++ b/src/nepi/execution/resource.py @@ -554,6 +554,7 @@ class ResourceManager(Logger): """ attr = self._attrs[name] attr.value = value + return value def get(self, name): """ Returns the value of the attribute @@ -576,6 +577,15 @@ class ResourceManager(Logger): attr = self._attrs[name] return attr.has_changed() + def has_flag(self, name, flag): + """ Returns true if the attribute has the flag 'flag' + + :param flag: Flag to be checked + :type flag: Flags + """ + attr = self._attrs[name] + return attr.has_flag(flag) + def enable_trace(self, name): """ Explicitly enable trace generation diff --git a/src/nepi/resources/linux/interface.py b/src/nepi/resources/linux/interface.py index 795c4d5d..bb352e1a 100644 --- a/src/nepi/resources/linux/interface.py +++ b/src/nepi/resources/linux/interface.py @@ -30,8 +30,9 @@ import re import tempfile import time -# TODO: UP, MTU attributes! - +# TODO: +# - check UP, MTU attributes! +# - clean up code and test! @clsinit_copy class LinuxInterface(ResourceManager): @@ -266,6 +267,7 @@ class LinuxInterface(ResourceManager): attr = self._attrs["up"] attr._value = up attr = self._attrs["mtu"] + attr._value = mtu def add_set_hooks(self): attrup = self._attrs["up"] @@ -275,7 +277,7 @@ class LinuxInterface(ResourceManager): attrmtu.set_hook = self.set_hook_mtu def set_hook_up(self, oldval, newval): - if oldval == newval: + if self.state == ResourceState.NEW or oldval == newval: return oldval # configure interface up @@ -294,7 +296,7 @@ class LinuxInterface(ResourceManager): return newval def set_hook_mtu(self, oldval, newval): - if oldval == newval: + if self.state == ResourceState.NEW or oldval == newval: return oldval cmd = "ifconfig %s mtu %d" % (self.get("deviceName"), newval) diff --git a/src/nepi/resources/ns3/ns3base.py b/src/nepi/resources/ns3/ns3base.py index 085412b6..b0070593 100644 --- a/src/nepi/resources/ns3/ns3base.py +++ b/src/nepi/resources/ns3/ns3base.py @@ -83,10 +83,10 @@ class NS3Base(ResourceManager): kwargs = dict() for attr in self._attrs.values(): - if not (attr.has_changed() and attr.has_flag(Flags.Construct)): + if not ( attr.has_flag(Flags.Construct) and attr.has_changed() ): continue - kwargs[attr.name] = attr.value + kwargs[attr.name] = attr._value self._uuid = self.simulation.factory(self.get_rtype(), **kwargs) @@ -148,3 +148,23 @@ class NS3Base(ResourceManager): def state(self): return self._state + def get(self, name): + if self.state in [ResourceState.READY, ResourceState.STARTED] and \ + self.has_flag(name, Flags.Reserved) and \ + not self.has_flag(name, Flags.NoRead): + return self.simulation.ns3_get(self.uuid, name) + else: + value = super(NS3Base, self).get(name) + + return value + + def set(self, name, value): + if self.state in [ResourceState.READY, ResourceState.STARTED] and \ + self.has_flag(name, Flags.Reserved) and \ + not (self.has_flag(Flags.NoWrite) or self.has_flag(name, Flags.Design)): + self.simulation.ns3_set(self.uuid, name, value) + + value = super(NS3Base, self).set(name, value) + + return value + diff --git a/src/nepi/resources/ns3/ns3channel.py b/src/nepi/resources/ns3/ns3channel.py index 85556fe7..bdeec577 100644 --- a/src/nepi/resources/ns3/ns3channel.py +++ b/src/nepi/resources/ns3/ns3channel.py @@ -46,3 +46,6 @@ class NS3BaseChannel(NS3Base): rms.add(self.simulation) return rms + def _connect_object(self): + pass + diff --git a/src/nepi/resources/ns3/ns3errorratemodel.py b/src/nepi/resources/ns3/ns3errorratemodel.py index f1f56668..961b5418 100644 --- a/src/nepi/resources/ns3/ns3errorratemodel.py +++ b/src/nepi/resources/ns3/ns3errorratemodel.py @@ -24,6 +24,10 @@ from nepi.resources.ns3.ns3base import NS3Base class NS3BaseErrorRateModel(NS3Base): _rtype = "abstract::ns3::ErrorRateModel" + @property + def node(self): + return self.phy.node + @property def phy(self): from nepi.resources.ns3.ns3wifiphy import NS3BaseWifiPhy diff --git a/src/nepi/resources/ns3/ns3ipv4l3protocol.py b/src/nepi/resources/ns3/ns3ipv4l3protocol.py index 526cae7d..5dd08276 100644 --- a/src/nepi/resources/ns3/ns3ipv4l3protocol.py +++ b/src/nepi/resources/ns3/ns3ipv4l3protocol.py @@ -39,7 +39,7 @@ class NS3BaseIpv4L3Protocol(NS3Base): @property def _rms_to_wait(self): rms = set() - rms.add(self.node) + rms.add(self.simulation) return rms def _configure_object(self): @@ -51,3 +51,5 @@ class NS3BaseIpv4L3Protocol(NS3Base): uuid_static_routing = simulation.create("Ipv4StaticRouting") simulation.invoke(uuid_list_routing, "AddRoutingProtocol", uuid_static_routing, 1) + def _connect_object(self): + pass diff --git a/src/nepi/resources/ns3/ns3mobilitymodel.py b/src/nepi/resources/ns3/ns3mobilitymodel.py new file mode 100644 index 00000000..4e1a0e01 --- /dev/null +++ b/src/nepi/resources/ns3/ns3mobilitymodel.py @@ -0,0 +1,44 @@ +# +# 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 . +# +# Author: Alina Quereilhac + +from nepi.execution.resource import clsinit_copy +from nepi.resources.ns3.ns3base import NS3Base + +# TODO: +# - mobility.SetPositionAllocator ("ns3::GridPositionAllocator", +# - set hook for Position - SetPosition(Vector) + +@clsinit_copy +class NS3BaseMobilityModel(NS3Base): + _rtype = "abstract::ns3::MobilityModel" + + def _configure_object(self): + # Set initial position + position = self.get("Position") + if position: + self.simulation.ns3_set(self.uuid, "Position", position) + + @property + def _rms_to_wait(self): + rms = set() + rms.add(self.simulation) + return rms + + def _connect_object(self): + pass diff --git a/src/nepi/resources/ns3/ns3netdevice.py b/src/nepi/resources/ns3/ns3netdevice.py index 3e742783..074f0754 100644 --- a/src/nepi/resources/ns3/ns3netdevice.py +++ b/src/nepi/resources/ns3/ns3netdevice.py @@ -113,28 +113,38 @@ class NS3BaseNetDevice(NS3Base): @property def _rms_to_wait(self): - others = set() + rms = set() node = self.node - others.add(node) + rms.add(node) ipv4 = node.ipv4 if node.ipv4: - others.add(ipv4) + rms.add(ipv4) - others.add(self.channel) - return others + rms.add(self.channel) + return rms def _configure_object(self): # Set Mac + self._configure_mac_address() + + # Set IP address + self._configure_ip_address() + + # Enable traces + self._configure_traces() + + def _configure_mac_address(self): mac = self.get("mac") if mac: mac_uuid = self.simulation.create("Mac48Address", mac) else: mac_uuid = self.simulation.invoke("singleton::Mac48Address", "Allocate") + self.simulation.invoke(self.uuid, "SetAddress", mac_uuid) - # Set IP address + def _configure_ip_address(self): ip = self.get("ip") prefix = self.get("prefix") @@ -156,9 +166,6 @@ class NS3BaseNetDevice(NS3Base): # IPv6 # TODO! pass - - # Enable traces - self._configure_traces() def _configure_traces(self): if self.trace_enabled("pcap"): diff --git a/src/nepi/resources/ns3/ns3node.py b/src/nepi/resources/ns3/ns3node.py index 3f1ce33f..b0e5dcf3 100644 --- a/src/nepi/resources/ns3/ns3node.py +++ b/src/nepi/resources/ns3/ns3node.py @@ -43,10 +43,26 @@ class NS3BaseNode(NS3Base): if ipv4s: return ipv4s[0] return None + @property + def mobility(self): + from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel + mobility = self.get_connected(NS3BaseMobilityModel.get_rtype()) + if mobility: return mobility[0] + return None + @property def _rms_to_wait(self): rms = set() rms.add(self.simulation) + + ipv4 = self.ipv4 + if ipv4: + rms.add(ipv4) + + mobility = self.mobility + if mobility: + rms.add(mobility) + return rms def _configure_object(self): @@ -54,3 +70,13 @@ class NS3BaseNode(NS3Base): uuid_packet_socket_factory = self.simulation.create("PacketSocketFactory") self.simulation.invoke(self.uuid, "AggregateObject", uuid_packet_socket_factory) + def _connect_object(self): + ipv4 = self.ipv4 + if ipv4: + self.simulation.invoke(self.uuid, "AggregateObject", ipv4.uuid) + + mobility = self.mobility + if mobility: + self.simulation.invoke(self.uuid, "AggregateObject", mobility.uuid) + + diff --git a/src/nepi/resources/ns3/ns3propagationdelaymodel.py b/src/nepi/resources/ns3/ns3propagationdelaymodel.py index 1a5b72a2..f091ec80 100644 --- a/src/nepi/resources/ns3/ns3propagationdelaymodel.py +++ b/src/nepi/resources/ns3/ns3propagationdelaymodel.py @@ -30,8 +30,8 @@ class NS3BasePropagationDelayModel(NS3Base): @property def channel(self): - from nepi.resources.ns3.ns3channel import NS3BaseChannel - channels = self.get_connected(NS3BaseChannel.get_rtype()) + from nepi.resources.ns3.ns3wifichannel import NS3BaseWifiChannel + channels = self.get_connected(NS3BaseWifiChannel.get_rtype()) if not channels: msg = "PropagationDelayModel not connected to channel" @@ -49,6 +49,6 @@ class NS3BasePropagationDelayModel(NS3Base): def _connect_object(self): channel = self.channel if channel.uuid not in self.connected: - self.simulator.invoke(channel.uuid, "SetPropagationDelayModel", self.uuid) + self.simulation.invoke(channel.uuid, "SetPropagationDelayModel", self.uuid) self._connected.add(channel.uuid) diff --git a/src/nepi/resources/ns3/ns3propagationlossmodel.py b/src/nepi/resources/ns3/ns3propagationlossmodel.py index 8b4a0856..94d0dab6 100644 --- a/src/nepi/resources/ns3/ns3propagationlossmodel.py +++ b/src/nepi/resources/ns3/ns3propagationlossmodel.py @@ -30,8 +30,8 @@ class NS3BasePropagationLossModel(NS3Base): @property def channel(self): - from nepi.resources.ns3.ns3channel import NS3BaseChannel - channels = self.get_connected(NS3BaseChannel.get_rtype()) + from nepi.resources.ns3.ns3wifichannel import NS3BaseWifiChannel + channels = self.get_connected(NS3BaseWifiChannel.get_rtype()) if not channels: msg = "PropagationLossModel not connected to channel" diff --git a/src/nepi/resources/ns3/ns3simulation.py b/src/nepi/resources/ns3/ns3simulation.py index ebf0b22e..f98237f8 100644 --- a/src/nepi/resources/ns3/ns3simulation.py +++ b/src/nepi/resources/ns3/ns3simulation.py @@ -31,10 +31,10 @@ class NS3Simulation(object): def invoke(self, *args, **kwargs): return self.client.invoke(*args, **kwargs) - def set(self, *args, **kwargs): + def ns3_set(self, *args, **kwargs): return self.client.set(*args, **kwargs) - def get(self, *args, **kwargs): + def ns3_get(self, *args, **kwargs): return self.client.get(*args, **kwargs) def flush(self, *args, **kwargs): diff --git a/src/nepi/resources/ns3/ns3wifichannel.py b/src/nepi/resources/ns3/ns3wifichannel.py new file mode 100644 index 00000000..3942e8c7 --- /dev/null +++ b/src/nepi/resources/ns3/ns3wifichannel.py @@ -0,0 +1,51 @@ +# +# 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 . +# +# Author: Alina Quereilhac + +from nepi.execution.resource import clsinit_copy +from nepi.resources.ns3.ns3base import NS3Base + +@clsinit_copy +class NS3BaseWifiChannel(NS3Base): + _rtype = "abstract::ns3::WifiChannel" + + @property + def simulation(self): + return self.phys[0].device.node.simulation + + @property + def phys(self): + from nepi.resources.ns3.ns3wifiphy import NS3BaseWifiPhy + phys = self.get_connected(NS3BaseWifiPhy.get_rtype()) + + if not phys: + msg = "Channel not connected to phy" + self.error(msg) + raise RuntimeError, msg + + return phys + + @property + def _rms_to_wait(self): + rms = set() + rms.add(self.simulation) + return rms + + def _connect_object(self): + pass + diff --git a/src/nepi/resources/ns3/ns3wifimac.py b/src/nepi/resources/ns3/ns3wifimac.py index 700f6cb4..e8ab8b63 100644 --- a/src/nepi/resources/ns3/ns3wifimac.py +++ b/src/nepi/resources/ns3/ns3wifimac.py @@ -17,21 +17,33 @@ # # Author: Alina Quereilhac +from nepi.execution.attribute import Attribute, Flags, Types from nepi.execution.resource import clsinit_copy from nepi.resources.ns3.ns3base import NS3Base +from nepi.resources.ns3.ns3wifinetdevice import WIFI_STANDARDS @clsinit_copy class NS3BaseWifiMac(NS3Base): _rtype = "abstract::ns3::WifiMac" + @classmethod + def _register_attributes(cls): + standard = Attribute("Standard", "Wireless standard", + default = "WIFI_PHY_STANDARD_80211a", + allowed = WIFI_STANDARDS.keys(), + type = Types.Enumerate, + flags = Flags.Design) + + cls._register_attribute(standard) + @property def node(self): return self.device.node @property def device(self): - from nepi.resources.ns3.ns3device import NS3BaseNetDevice - devices = self.get_connected(NS3BaseNetDevice.get_rtype()) + from nepi.resources.ns3.ns3wifinetdevice import NS3BaseWifiNetDevice + devices = self.get_connected(NS3BaseWifiNetDevice.get_rtype()) if not devices: msg = "WifiMac not connected to device" @@ -49,6 +61,20 @@ class NS3BaseWifiMac(NS3Base): def _connect_object(self): device = self.device if device.uuid not in self.connected: - self.simulation.invoke(device.uuid, "SetMac", self.uuid) self._connected.add(device.uuid) + self.simulation.invoke(device.uuid, "SetMac", self.uuid) + + standard = self.get("Standard") + self.simulation.invoke(self.uuid, "ConfigureStandard", WIFI_STANDARDS[standard]) + + # Delayed configuration of MAC address + mac = device.get("mac") + if mac: + mac_uuid = self.simulation.create("Mac48Address", mac) + else: + mac_uuid = self.simulation.invoke("singleton::Mac48Address", "Allocate") + + self.simulation.invoke(self.uuid, "SetAddress", mac_uuid) + + diff --git a/src/nepi/resources/ns3/ns3wifinetdevice.py b/src/nepi/resources/ns3/ns3wifinetdevice.py new file mode 100644 index 00000000..ea700eae --- /dev/null +++ b/src/nepi/resources/ns3/ns3wifinetdevice.py @@ -0,0 +1,62 @@ +# +# 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 . +# +# Author: Alina Quereilhac + +from nepi.execution.resource import clsinit_copy +from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice + +WIFI_STANDARDS = dict({ + "WIFI_PHY_STANDARD_holland": 5, + "WIFI_PHY_STANDARD_80211p_SCH": 7, + "WIFI_PHY_STANDARD_80211_5Mhz": 4, + "WIFI_PHY_UNKNOWN": 8, + "WIFI_PHY_STANDARD_80211_10Mhz": 3, + "WIFI_PHY_STANDARD_80211g": 2, + "WIFI_PHY_STANDARD_80211p_CCH": 6, + "WIFI_PHY_STANDARD_80211a": 0, + "WIFI_PHY_STANDARD_80211b": 1 +}) + +@clsinit_copy +class NS3BaseWifiNetDevice(NS3BaseNetDevice): + _rtype = "abstract::ns3::WifiNetDevice" + + @property + def _rms_to_wait(self): + rms = set() + + node = self.node + rms.add(node) + + ipv4 = node.ipv4 + if node.ipv4: + rms.add(ipv4) + + return rms + + def _configure_mac_address(self): + # The wifimac is the one responsible for + # configuring the MAC address + pass + + def _connect_object(self): + node = self.node + if node and node.uuid not in self.connected: + self.simulation.invoke(node.uuid, "AddDevice", self.uuid) + self._connected.add(node.uuid) + diff --git a/src/nepi/resources/ns3/ns3wifiphy.py b/src/nepi/resources/ns3/ns3wifiphy.py index 8b6166ac..4ea0248b 100644 --- a/src/nepi/resources/ns3/ns3wifiphy.py +++ b/src/nepi/resources/ns3/ns3wifiphy.py @@ -17,21 +17,33 @@ # # Author: Alina Quereilhac +from nepi.execution.attribute import Attribute, Flags, Types from nepi.execution.resource import clsinit_copy from nepi.resources.ns3.ns3base import NS3Base +from nepi.resources.ns3.ns3wifinetdevice import WIFI_STANDARDS @clsinit_copy class NS3BaseWifiPhy(NS3Base): _rtype = "abstract::ns3::WifiPhy" + @classmethod + def _register_attributes(cls): + standard = Attribute("Standard", "Wireless standard", + default = "WIFI_PHY_STANDARD_80211a", + allowed = WIFI_STANDARDS.keys(), + type = Types.Enumerate, + flags = Flags.Design) + + cls._register_attribute(standard) + @property def node(self): return self.device.node @property def device(self): - from nepi.resources.ns3.ns3device import NS3BaseNetDevice - devices = self.get_connected(NS3BaseNetDevice.get_rtype()) + from nepi.resources.ns3.ns3wifinetdevice import NS3BaseWifiNetDevice + devices = self.get_connected(NS3BaseWifiNetDevice.get_rtype()) if not devices: msg = "WifiPhy not connected to device" @@ -40,6 +52,18 @@ class NS3BaseWifiPhy(NS3Base): return devices[0] + @property + def channel(self): + from nepi.resources.ns3.ns3wifichannel import NS3BaseWifiChannel + channels = self.get_connected(NS3BaseWifiChannel.get_rtype()) + + if not channels: + msg = "WifiPhy not connected to channel" + self.error(msg) + raise RuntimeError, msg + + return channels[0] + @property def _rms_to_wait(self): rms = set() @@ -49,9 +73,16 @@ class NS3BaseWifiPhy(NS3Base): def _connect_object(self): device = self.device if device.uuid not in self.connected: - self.simulation.invoke(device.uuid, "SetPhy", self.uuid) - self.simulator.invoke(self.uuid, "SetDevice", device.uuid) self._connected.add(device.uuid) - self.simulator.invoke(self.uuid, "SetMobility", self.node.uuid) + self.simulation.invoke(self.uuid, "SetMobility", self.node.uuid) + + standard = self.get("Standard") + self.simulation.invoke(self.uuid, "ConfigureStandard", WIFI_STANDARDS[standard]) + + self.simulation.invoke(self.uuid, "SetDevice", device.uuid) + + self.simulation.invoke(self.uuid, "SetChannel", self.channel.uuid) + + self.simulation.invoke(device.uuid, "SetPhy", self.uuid) diff --git a/src/nepi/resources/ns3/ns3wifiremotestationmanager.py b/src/nepi/resources/ns3/ns3wifiremotestationmanager.py index 49eb52f0..764c097c 100644 --- a/src/nepi/resources/ns3/ns3wifiremotestationmanager.py +++ b/src/nepi/resources/ns3/ns3wifiremotestationmanager.py @@ -31,8 +31,8 @@ class NS3BaseWifiRemoteStationManager(NS3Base): @property def device(self): - from nepi.resources.ns3.ns3device import NS3BaseNetDevice - devices = self.get_connected(NS3BaseNetDevice.get_rtype()) + from nepi.resources.ns3.ns3wifinetdevice import NS3BaseWifiNetDevice + devices = self.get_connected(NS3BaseWifiNetDevice.get_rtype()) if not devices: msg = "WifiRemoteStationManager not connected to device" diff --git a/src/nepi/resources/ns3/resource_manager_generator.py b/src/nepi/resources/ns3/resource_manager_generator.py index aa3f51b1..9ec844e9 100644 --- a/src/nepi/resources/ns3/resource_manager_generator.py +++ b/src/nepi/resources/ns3/resource_manager_generator.py @@ -32,8 +32,11 @@ base_types = ["ns3::Node", "ns3::ArpL3Protocol", "ns3::Ipv4L3Protocol", "ns3::PropagationLossModel", + "ns3::MobilityModel", "ns3::PropagationDelayModel", "ns3::WifiRemoteStationManager", + "ns3::WifiNetDevice", + "ns3::WifiChannel", "ns3::WifiPhy", "ns3::WifiMac", "ns3::ErrorModel", @@ -146,12 +149,15 @@ def template_attributes(ns3, tid): if not attr_info.accessor.HasGetter(): continue - attr_flags = "None" + attr_flags = "Flags.Reserved" flags = attr_info.flags - if (flags & ns3.TypeId.ATTR_SET) != ns3.TypeId.ATTR_SET: - attr_flags = "Flags.Design" - elif (flags & ns3.TypeId.ATTR_CONSTRUCT) == ns3.TypeId.ATTR_CONSTRUCT: - attr_flags = "Flags.Construct" + if (flags & ns3.TypeId.ATTR_CONSTRUCT) == ns3.TypeId.ATTR_CONSTRUCT: + attr_flags += " | Flags.Construct" + else: + if (flags & ns3.TypeId.ATTR_GET) != ns3.TypeId.ATTR_GET: + attr_flags += " | Flags.NoRead" + elif (flags & ns3.TypeId.ATTR_SET) != ns3.TypeId.ATTR_SET: + attr_flags += " | Flags.NoWrite" attr_name = attr_info.name checker = attr_info.checker diff --git a/test/resources/linux/ns3/ns3simulation.py b/test/resources/linux/ns3/ns3simulation.py index 8a3a2487..f289ca47 100644 --- a/test/resources/linux/ns3/ns3simulation.py +++ b/test/resources/linux/ns3/ns3simulation.py @@ -37,48 +37,48 @@ import time import unittest def add_ns3_node(ec, simu): - ns3_node = ec.register_resource("ns3::Node") - ec.register_connection(ns3_node, simu) + node = ec.register_resource("ns3::Node") + ec.register_connection(node, simu) ipv4 = ec.register_resource("ns3::Ipv4L3Protocol") - ec.register_connection(ns3_node, ipv4) + ec.register_connection(node, ipv4) arp = ec.register_resource("ns3::ArpL3Protocol") - ec.register_connection(ns3_node, arp) + ec.register_connection(node, arp) icmp = ec.register_resource("ns3::Icmpv4L4Protocol") - ec.register_connection(ns3_node, icmp) + ec.register_connection(node, icmp) - return ns3_node + return node -def add_point2point_device(ec, ns3_node, address, prefix): +def add_point2point_device(ec, node, address, prefix): dev = ec.register_resource("ns3::PointToPointNetDevice") ec.set(dev, "ip", address) ec.set(dev, "prefix", prefix) - ec.register_connection(ns3_node, dev) + ec.register_connection(node, dev) queue = ec.register_resource("ns3::DropTailQueue") ec.register_connection(dev, queue) return dev -def add_csma_device(ec, ns3_node, address, prefix): +def add_csma_device(ec, node, address, prefix): dev = ec.register_resource("ns3::CsmaNetDevice") ec.set(dev, "ip", address) ec.set(dev, "prefix", prefix) - ec.register_connection(ns3_node, dev) + ec.register_connection(node, dev) queue = ec.register_resource("ns3::DropTailQueue") ec.register_connection(dev, queue) return dev -def add_wifi_device(ec, ns3_node, address, prefix, +def add_wifi_device(ec, node, address, prefix, access_point = False): dev = ec.register_resource("ns3::WifiNetDevice") ec.set(dev, "ip", address) ec.set(dev, "prefix", prefix) - ec.register_connection(ns3_node, dev) + ec.register_connection(node, dev) phy = ec.register_resource("ns3::YansWifiPhy") ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a") @@ -87,34 +87,35 @@ def add_wifi_device(ec, ns3_node, address, prefix, error = ec.register_resource("ns3::NistErrorRateModel") ec.register_connection(phy, error) - manager = ec.register_resources("ns3::ArfWifiManager") + manager = ec.register_resource("ns3::ArfWifiManager") ec.register_connection(dev, manager) if access_point: - mac = ec.register_resources("ns3::ApWifiMac") + mac = ec.register_resource("ns3::ApWifiMac") else: - mac = ec.register_resources("ns3::StaWifiMac") + mac = ec.register_resource("ns3::StaWifiMac") ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a") ec.register_connection(dev, mac) - return dev + return dev, phy -def add_random_mobility(ec, ns3_node, x, y, z, speed, bounds_width, +def add_random_mobility(ec, node, x, y, z, speed, bounds_width, bounds_height): position = "%d:%d:%d" % (x, y, z) bounds = "0|%d|0|%d" % (bounds_width, bounds_height) - speed = "Constant:%d" % speed + speed = "ns3::UniformRandomVariable[Min=%d|Max=%s]" % (speed, speed) + pause = "ns3::ConstantRandomVariable[Constant=1.0]" mobility = ec.register_resource("ns3::RandomDirection2dMobilityModel") ec.set(mobility, "Position", position) ec.set(mobility, "Bounds", bounds) ec.set(mobility, "Speed", speed) - ec.set(mobility, "Pause", "Constant:1") + ec.set(mobility, "Pause", pause) ec.register_connection(node, mobility) return mobility -def add_constant_mobility(ec, ns3_node, x, y, z): +def add_constant_mobility(ec, node, x, y, z): mobility = ec.register_resource("ns3::ConstantPositionMobilityModel") position = "%d:%d:%d" % (x, y, z) ec.set(mobility, "Position", position) @@ -458,7 +459,7 @@ class LinuxNS3ClientTest(unittest.TestCase): ec.shutdown() - def ztest_simple_wifi_ping(self): + def test_simple_wifi_ping(self): bounds_width = bounds_height = 200 x = y = 100 speed = 1 @@ -473,29 +474,30 @@ class LinuxNS3ClientTest(unittest.TestCase): #ec.set(node, "cleanHome", True) simu = ec.register_resource("LinuxNS3Simulation") + ec.set(simu, "verbose", True) ec.register_connection(simu, node) nsnode1 = add_ns3_node(ec, simu) - dev1 = add_wifi_node(ec, nsnode1, "10.0.0.1", "30", access_point = True) + dev1, phy1 = add_wifi_device(ec, nsnode1, "10.0.0.1", "24", access_point = True) mobility1 = add_constant_mobility(ec, nsnode1, x, y, 0) nsnode2 = add_ns3_node(ec, simu) - dev2 = add_wifi_node(ec, nsnode1, "10.0.0.2", "30", access_point = False) - mobility2 = add_random_mobility(ec, nsnode2, x, y, 0, speed, - bounds_width, bounds_height) + dev2, phy2 = add_wifi_device(ec, nsnode2, "10.0.0.2", "24", access_point = False) + mobility1 = add_constant_mobility(ec, nsnode2, x, y, 0) + #mobility2 = add_random_mobility(ec, nsnode2, x, y, 0, speed, bounds_width, bounds_height) # Create channel chan = add_wifi_channel(ec) - ec.register_connection(chan, dev1) - ec.register_connection(chan, dev2) + ec.register_connection(chan, phy1) + ec.register_connection(chan, phy2) ### create pinger ping = ec.register_resource("ns3::V4Ping") ec.set (ping, "Remote", "10.0.0.1") ec.set (ping, "Interval", "1s") ec.set (ping, "Verbose", True) - ec.set (ping, "StartTime", "0s") - ec.set (ping, "StopTime", "20s") + ec.set (ping, "StartTime", "1s") + ec.set (ping, "StopTime", "21s") ec.register_connection(ping, nsnode2) ec.deploy() @@ -503,7 +505,6 @@ class LinuxNS3ClientTest(unittest.TestCase): ec.wait_finished([ping]) stdout = ec.trace(simu, "stdout") - print stdout expected = "20 packets transmitted, 20 received, 0% packet loss" self.assertTrue(stdout.find(expected) > -1) -- 2.43.0