Fix #122 [NS3] Implement wireless model scenarios with mobility
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Sun, 16 Feb 2014 03:42:18 +0000 (04:42 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Sun, 16 Feb 2014 03:42:18 +0000 (04:42 +0100)
20 files changed:
src/nepi/execution/attribute.py
src/nepi/execution/resource.py
src/nepi/resources/linux/interface.py
src/nepi/resources/ns3/ns3base.py
src/nepi/resources/ns3/ns3channel.py
src/nepi/resources/ns3/ns3errorratemodel.py
src/nepi/resources/ns3/ns3ipv4l3protocol.py
src/nepi/resources/ns3/ns3mobilitymodel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3netdevice.py
src/nepi/resources/ns3/ns3node.py
src/nepi/resources/ns3/ns3propagationdelaymodel.py
src/nepi/resources/ns3/ns3propagationlossmodel.py
src/nepi/resources/ns3/ns3simulation.py
src/nepi/resources/ns3/ns3wifichannel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wifimac.py
src/nepi/resources/ns3/ns3wifinetdevice.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wifiphy.py
src/nepi/resources/ns3/ns3wifiremotestationmanager.py
src/nepi/resources/ns3/resource_manager_generator.py
test/resources/linux/ns3/ns3simulation.py

index 64a3d05..bda72e2 100644 (file)
@@ -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
index e4c4b0c..54af5e3 100644 (file)
@@ -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
 
index 795c4d5..bb352e1 100644 (file)
@@ -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)
index 085412b..b007059 100644 (file)
@@ -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
+
index 85556fe..bdeec57 100644 (file)
@@ -46,3 +46,6 @@ class NS3BaseChannel(NS3Base):
         rms.add(self.simulation)
         return rms
 
+    def _connect_object(self):
+        pass
+
index f1f5666..961b541 100644 (file)
@@ -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
index 526cae7..5dd0827 100644 (file)
@@ -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 (file)
index 0000000..4e1a0e0
--- /dev/null
@@ -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 <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
+
+# 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
index 3e74278..074f075 100644 (file)
@@ -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"):
index 3f1ce33..b0e5dcf 100644 (file)
@@ -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)
+
+
index 1a5b72a..f091ec8 100644 (file)
@@ -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)
 
index 8b4a085..94d0dab 100644 (file)
@@ -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"
index ebf0b22..f98237f 100644 (file)
@@ -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 (file)
index 0000000..3942e8c
--- /dev/null
@@ -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 <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 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
+
index 700f6cb..e8ab8b6 100644 (file)
 #
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
+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 (file)
index 0000000..ea700ea
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+
+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)
+
index 8b6166a..4ea0248 100644 (file)
 #
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 
+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)
 
index 49eb52f..764c097 100644 (file)
@@ -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"
index aa3f51b..9ec844e 100644 (file)
@@ -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
index 8a3a248..f289ca4 100644 (file)
@@ -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)