Merging ns-3 into nepi-3-dev
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 17 Feb 2014 18:53:45 +0000 (19:53 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 17 Feb 2014 18:53:45 +0000 (19:53 +0100)
168 files changed:
setup.py
src/nepi/execution/attribute.py
src/nepi/execution/ec.py
src/nepi/execution/resource.py
src/nepi/resources/all/collector.py
src/nepi/resources/linux/application.py
src/nepi/resources/linux/ccn/ccnapplication.py
src/nepi/resources/linux/ccn/ccncontent.py
src/nepi/resources/linux/ccn/ccnd.py
src/nepi/resources/linux/ccn/ccnping.py
src/nepi/resources/linux/ccn/ccnpingserver.py
src/nepi/resources/linux/ccn/ccnr.py
src/nepi/resources/linux/ccn/fibentry.py
src/nepi/resources/linux/interface.py
src/nepi/resources/linux/mtr.py
src/nepi/resources/linux/node.py
src/nepi/resources/linux/nping.py
src/nepi/resources/linux/ns3/__init__.py [new file with mode: 0644]
src/nepi/resources/linux/ns3/dependencies/pygccxml-1.0.0.tar.gz [new file with mode: 0644]
src/nepi/resources/linux/ns3/ns3client.py [new file with mode: 0644]
src/nepi/resources/linux/ns3/ns3simulation.py [new file with mode: 0644]
src/nepi/resources/linux/ping.py
src/nepi/resources/linux/tcpdump.py
src/nepi/resources/linux/traceroute.py
src/nepi/resources/linux/udptest.py
src/nepi/resources/linux/udptunnel.py
src/nepi/resources/ns3/classes/__init__.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/aarf_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/aarfcd_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/adhoc_wifi_mac.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/aloha_noack_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/amrr_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/ap_wifi_mac.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/arf_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/arp_l3protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/base_station_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/bridge_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/bridge_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/bulk_send_application.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/burst_error_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/cara_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/constant_acceleration_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/constant_position_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/constant_rate_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/constant_speed_propagation_delay_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/constant_velocity_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/cost231propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/csma_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/csma_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/drop_tail_queue.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/emu_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/error_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/error_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/fd_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/fixed_rss_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/friis_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/gauss_markov_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/hierarchical_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/hybrid_buildings_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/icmpv4l4protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/ideal_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/ipv4l3protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/jakes_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/list_error_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/log_distance_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/loopback_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/lte_enb_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/lte_simple_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/matrix_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/mesh_point_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/mesh_wifi_interface_mac.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/minstrel_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/multi_model_spectrum_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/nakagami_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/nist_error_rate_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/node.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/non_communicating_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/oh_buildings_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/on_off_application.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/onoe_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/packet_sink.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/ping6.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/point_to_point_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/point_to_point_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/point_to_point_remote_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/radvd.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/random_direction2d_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/random_propagation_delay_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/random_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/random_walk2d_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/random_waypoint_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/range_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/rate_error_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/receive_list_error_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/red_queue.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/rraa_wifi_manager.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/simple_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/simple_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/single_model_spectrum_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/sta_wifi_mac.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/steady_state_random_waypoint_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/subscriber_station_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/tap_bridge.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/three_log_distance_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/two_ray_ground_propagation_loss_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/uan_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/udp_client.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/udp_echo_client.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/udp_echo_server.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/udp_server.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/udp_trace_client.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/v4ping.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/virtual_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/waypoint_mobility_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/wifi_net_device.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/yans_error_rate_model.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/yans_wifi_channel.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/yans_wifi_phy.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3application.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3arpl3protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3base.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3channel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3client.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3errormodel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3errorratemodel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3icmpv4l4protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3ipv4l3protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3mobilitymodel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3netdevice.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3node.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3propagationdelaymodel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3propagationlossmodel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3queue.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3route.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3server.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3simulation.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wifichannel.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wifimac.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wifinetdevice.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wifiphy.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wifiremotestationmanager.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3wrapper.py
src/nepi/resources/ns3/ns3wrapper_server.py [deleted file]
src/nepi/resources/ns3/resource_manager_generator.py [new file with mode: 0644]
src/nepi/resources/ns3/templates/attribute_template.txt [new file with mode: 0644]
src/nepi/resources/ns3/templates/resource_manager_template.txt [new file with mode: 0644]
src/nepi/resources/ns3/templates/trace_template.txt [new file with mode: 0644]
src/nepi/resources/omf/application.py
src/nepi/resources/planetlab/node.py
src/nepi/resources/planetlab/openvswitch/ovs.py
src/nepi/resources/planetlab/openvswitch/ovsport.py
src/nepi/resources/planetlab/openvswitch/tunnel.py
src/nepi/resources/planetlab/tap.py
src/nepi/util/execfuncs.py
src/nepi/util/sshfuncs.py
test/resources/linux/ccn/ccnping.py
test/resources/linux/ccn/fibentry.py
test/resources/linux/interface.py
test/resources/linux/mtr.py
test/resources/linux/nping.py
test/resources/linux/ns3/ns-3.18-user.tar.gz [new file with mode: 0644]
test/resources/linux/ns3/ns3client.py [new file with mode: 0644]
test/resources/linux/ns3/ns3simulation.py [new file with mode: 0644]
test/resources/linux/ping.py
test/resources/linux/tcpdump.py
test/resources/linux/traceroute.py
test/resources/linux/udptest.py
test/resources/ns3/ns3wrapper.py

index aa9bfc6..01ac52a 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -20,8 +20,10 @@ setup(
             "nepi.resources.all",
             "nepi.resources.linux",
             "nepi.resources.linux.ccn",
+            "nepi.resources.linux.ns3",
             "nepi.resources.netns",
             "nepi.resources.ns3",
+            "nepi.resources.ns3.classes",
             "nepi.resources.omf",
             "nepi.resources.planetlab",
             "nepi.resources.planetlab.openvswitch",
@@ -29,6 +31,7 @@ setup(
         package_dir = {"": "src"},
         package_data = {
             "nepi.resources.planetlab" : [ "scripts/*.py" ],
-            "nepi.resources.linux" : [ "scripts/*.py" ]
+            "nepi.resources.linux" : [ "scripts/*.py" ],
+            "nepi.resources.linux.ns3" : [ "dependencies/*.tar.gz" ]
             }
     )
index e9f4c54..bda72e2 100644 (file)
@@ -30,16 +30,28 @@ class Flags:
     """ Differents flags to characterize an attribute
 
     """
-    # Attribute can be modified by the user 
-    NoFlags         = 0x00
-    # Attribute is not modifiable by the user
-    ReadOnly        = 0x01
-    # Attribute is not modifiable by the user during runtime
-    ExecReadOnly        = 0x02
-    # Attribute is an access credential
-    Credential      = 0x04
+    # Attribute value can not be read (it is hidden to the user) 
+    NoRead    = 1 # 1
+    
+    # Attribute value can not be modified (it is not editable by the user)
+    NoWrite   = 1 << 1 # 2
+    
+    # Attribute value can be modified only before deployment
+    Design  = 1 << 2 # 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
+
     # Attribute is a filter used to discover resources
-    Filter      = 0x08
+    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):
     """
@@ -77,18 +89,18 @@ 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
 
     """
     def __init__(self, name, help, type = Types.String,
-            flags = Flags.NoFlags, default = None, allowed = None,
+            flags = None, default = None, allowed = None,
             range = None, set_hook = None):
         self._name = name
         self._help = help
         self._type = type
-        self._flags = flags
+        self._flags = flags or 0
         self._allowed = allowed
         self._range = range
         self._default = self._value = default
@@ -134,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
@@ -152,6 +164,9 @@ class Attribute(object):
 
         if self.type in [Types.Double, Types.Integer] and self.range:
             (min, max) = self.range
+
+            value = float(value)
+
             valid = (value >= min and value <= max) 
         
         valid = valid and self.is_valid_value(value)
@@ -173,3 +188,6 @@ class Attribute(object):
         adequate validation"""
         return True
 
+    def has_changed(self):
+        """ Returns true if the value has changed from the default """
+        return self.value != self.default
index 47110a4..7d8b990 100644 (file)
@@ -31,7 +31,6 @@ from nepi.execution.trace import TraceAttr
 import functools
 import logging
 import os
-import random
 import sys
 import time
 import threading
@@ -747,7 +746,6 @@ class ExperimentController(object):
                     break
 
             if reschedule:
-
                 callback = functools.partial(wait_all_and_start, group)
                 self.schedule("1s", callback)
             else:
index 49b842b..5ad084d 100644 (file)
@@ -193,7 +193,7 @@ class ResourceManager(Logger):
                 "the experiment. ",
                 type = Types.Bool,
                 default = True,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(critical)
         
@@ -512,7 +512,6 @@ class ResourceManager(Logger):
         with self._release_lock:
             if self._state != ResourceState.RELEASED:
                 self.do_deploy()
-                self.debug("----- READY ---- ")
 
     def release(self):
         """ Perform actions to free resources used by the RM.
@@ -531,8 +530,8 @@ class ResourceManager(Logger):
                 import traceback
                 err = traceback.format_exc()
                 self.error(err)
+
                 self.set_released()
-                self.debug("----- RELEASED ---- ")
 
     def fail(self):
         """ Sets the RM to state FAILED.
@@ -555,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
@@ -566,6 +566,26 @@ class ResourceManager(Logger):
         attr = self._attrs[name]
         return attr.value
 
+    def has_changed(self, name):
+        """ Returns the True is the value of the attribute
+            has been modified by the user.
+
+        :param name: Name of the attribute
+        :type name: str
+        :rtype: str
+        """
+        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
 
@@ -676,6 +696,7 @@ class ResourceManager(Logger):
         connected = []
         rclass = ResourceFactory.get_resource_type(rtype)
         for guid in self.connections:
+
             rm = self.ec.get_resource(guid)
             if not rtype or isinstance(rm, rclass):
                 connected.append(rm)
@@ -946,7 +967,6 @@ class ResourceManager(Logger):
 
     def do_release(self):
         self.set_released()
-        self.debug("----- RELEASED ---- ")
 
     def do_fail(self):
         self.set_failed()
@@ -954,30 +974,37 @@ class ResourceManager(Logger):
     def set_started(self):
         """ Mark ResourceManager as STARTED """
         self.set_state(ResourceState.STARTED, "_start_time")
-        
+        self.debug("----- STARTED ---- ")
+
     def set_stopped(self):
         """ Mark ResourceManager as STOPPED """
         self.set_state(ResourceState.STOPPED, "_stop_time")
+        self.debug("----- STOPPED ---- ")
 
     def set_ready(self):
         """ Mark ResourceManager as READY """
         self.set_state(ResourceState.READY, "_ready_time")
+        self.debug("----- READY ---- ")
 
     def set_released(self):
         """ Mark ResourceManager as REALEASED """
         self.set_state(ResourceState.RELEASED, "_release_time")
+        self.debug("----- RELEASED ---- ")
 
     def set_failed(self):
         """ Mark ResourceManager as FAILED """
         self.set_state(ResourceState.FAILED, "_failed_time")
+        self.debug("----- FAILED ---- ")
 
     def set_discovered(self):
         """ Mark ResourceManager as DISCOVERED """
         self.set_state(ResourceState.DISCOVERED, "_discover_time")
+        self.debug("----- DISCOVERED ---- ")
 
     def set_provisioned(self):
         """ Mark ResourceManager as PROVISIONED """
         self.set_state(ResourceState.PROVISIONED, "_provision_time")
+        self.debug("----- PROVISIONED ---- ")
 
     def set_state(self, state, state_time_attr):
         """ Set the state of the RM while keeping a trace of the time """
@@ -1033,7 +1060,7 @@ def find_types():
     path = os.path.dirname(nepi.resources.__file__)
     search_path.add(path)
 
-    types = []
+    types = set()
 
     for importer, modname, ispkg in pkgutil.walk_packages(search_path, 
             prefix = "nepi.resources."):
@@ -1041,7 +1068,7 @@ def find_types():
         loader = importer.find_module(modname)
         
         try:
-            # Notice: Repeated calls to load_module will act as a reload of teh module
+            # Notice: Repeated calls to load_module will act as a reload of the module
             if modname in sys.modules:
                 module = sys.modules.get(modname)
             else:
@@ -1060,7 +1087,7 @@ def find_types():
                     continue
 
                 if issubclass(attr, ResourceManager):
-                    types.append(attr)
+                    types.add(attr)
 
                     if not modname in sys.modules:
                         sys.modules[modname] = module
@@ -1074,4 +1101,3 @@ def find_types():
 
     return types
 
-
index 0b6ad23..f13a392 100644 (file)
@@ -48,14 +48,14 @@ class Collector(ResourceManager):
     @classmethod
     def _register_attributes(cls):
         trace_name = Attribute("traceName", "Name of the trace to be collected", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         store_dir = Attribute("storeDir", "Path to local directory to store trace results", 
                 default = tempfile.gettempdir(),
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         sub_dir = Attribute("subDir", "Sub directory to collect traces into", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         rename = Attribute("rename", "Name to give to the collected trace file", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(trace_name)
         cls._register_attribute(store_dir)
index 6f6efa9..d391086 100644 (file)
@@ -90,43 +90,43 @@ class LinuxApplication(ResourceManager):
         command = Attribute("command", "Command to execute at application start. "
                 "Note that commands will be executed in the ${RUN_HOME} directory, "
                 "make sure to take this into account when using relative paths. ", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         forward_x11 = Attribute("forwardX11", "Enables X11 forwarding for SSH connections", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         env = Attribute("env", "Environment variables string for command execution",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         sudo = Attribute("sudo", "Run with root privileges", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         depends = Attribute("depends", 
                 "Space-separated list of packages required to run the application",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         sources = Attribute("sources", 
                 "semi-colon separated list of regular files to be uploaded to ${SRC} "
                 "directory prior to building. Archives won't be expanded automatically. "
                 "Sources are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all sources). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         files = Attribute("files", 
                 "Space-separated list of regular miscellaneous files to be uploaded "
                 "to ${SHARE} directory. "
                 "Files are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all files). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         libs = Attribute("libs", 
                 "Space-separated list of libraries (e.g. .so files) to be uploaded "
                 "to ${LIB} directory. "
                 "Libraries are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all files). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         bins = Attribute("bins", 
                 "Space-separated list of binary files to be uploaded "
                 "to ${BIN} directory. "
                 "Binaries are globally available for all experiments unless "
                 "cleanHome is set to True (This will delete all files). ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         code = Attribute("code", 
                 "Plain text source code to be uploaded to the ${APP_HOME} directory. ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         build = Attribute("build", 
                 "Build commands to execute after deploying the sources. "
                 "Sources are uploaded to the ${SRC} directory and code "
@@ -135,16 +135,16 @@ class LinuxApplication(ResourceManager):
                 "./configure && make && make clean.\n"
                 "Make sure to make the build commands return with a nonzero exit "
                 "code on error.",
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
         install = Attribute("install", 
                 "Commands to transfer built files to their final destinations. "
                 "Install commands are executed after build commands. ",
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
         stdin = Attribute("stdin", "Standard input for the 'command'", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         tear_down = Attribute("tearDown", "Command to be executed just before " 
                 "releasing the resource", 
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(command)
         cls._register_attribute(forward_x11)
@@ -227,10 +227,13 @@ class LinuxApplication(ResourceManager):
         """
         return self.get("forwardX11") or self._in_foreground
 
+    def trace_filepath(self, filename):
+        return os.path.join(self.run_home, filename)
+
     def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0):
         self.info("Retrieving '%s' trace %s " % (name, attr))
 
-        path = os.path.join(self.run_home, name)
+        path = self.trace_filepath(name)
         
         command = "(test -f %s && echo 'success') || echo 'error'" % path
         (out, err), proc = self.node.execute(command)
@@ -367,11 +370,14 @@ class LinuxApplication(ResourceManager):
                     stdout = "deploy_stdout", 
                     stderr = "deploy_stderr")
 
-    def upload_sources(self):
+    def upload_sources(self, src_dir = None):
         sources = self.get("sources")
    
         command = ""
 
+        if not src_dir:
+            src_dir = self.node.src_dir
+
         if sources:
             self.info("Uploading sources ")
 
@@ -388,15 +394,16 @@ class LinuxApplication(ResourceManager):
 
                     command.append( " ( " 
                             # Check if the source already exists
-                            " ls ${SRC}/%(basename)s "
+                            " ls %(src_dir)s/%(basename)s "
                             " || ( "
                             # If source doesn't exist, download it and check
                             # that it it downloaded ok
-                            "   wget -c --directory-prefix=${SRC} %(source)s && "
-                            "   ls ${SRC}/%(basename)s "
+                            "   wget -c --directory-prefix=%(src_dir)s %(source)s && "
+                            "   ls %(src_dir)s/%(basename)s "
                             " ) ) " % {
                                 "basename": os.path.basename(source),
-                                "source": source
+                                "source": source,
+                                "src_dir": src_dir
                                 })
 
             command = " && ".join(command)
@@ -406,7 +413,7 @@ class LinuxApplication(ResourceManager):
        
             if sources:
                 sources = ' '.join(sources)
-                self.node.upload(sources, self.node.src_dir, overwrite = False)
+                self.node.upload(sources, src_dir, overwrite = False)
 
         return command
 
@@ -519,10 +526,6 @@ class LinuxApplication(ResourceManager):
         x11 = self.get("forwardX11")
         env = self.get("env")
 
-        # For a command being executed in foreground, if there is stdin,
-        # it is expected to be text string not a file or pipe
-        stdin = self.get("stdin") or None
-
         # Command will be launched in foreground and attached to the
         # terminal using the node 'execute' in non blocking mode.
 
@@ -533,7 +536,6 @@ class LinuxApplication(ResourceManager):
         (out, err), self._proc = self.execute_command(command, 
                 env = env,
                 sudo = sudo,
-                stdin = stdin,
                 forward_x11 = x11,
                 blocking = False)
 
@@ -610,7 +612,7 @@ class LinuxApplication(ResourceManager):
                             sudo = self._sudo_kill)
 
                     # TODO: check if execution errors occurred
-                    if proc.poll() or err:
+                    if (proc and proc.poll()) or err:
                         msg = " Failed to STOP command '%s' " % self.get("command")
                         self.error(msg, out, err)
         
@@ -681,7 +683,6 @@ class LinuxApplication(ResourceManager):
     def execute_command(self, command, 
             env = None,
             sudo = False,
-            stdin = None,
             forward_x11 = False,
             blocking = False):
 
@@ -693,7 +694,6 @@ class LinuxApplication(ResourceManager):
 
         return self.node.execute(command,
                 sudo = sudo,
-                stdin = stdin,
                 forward_x11 = forward_x11,
                 blocking = blocking)
 
index 89c949c..f79c7cf 100644 (file)
@@ -59,7 +59,6 @@ class LinuxCCNApplication(LinuxApplication):
             self.do_discover()
             self.do_provision()
 
-            self.debug("----- READY ---- ")
             self.set_ready()
 
     @property
index 84f6185..c7ce3bf 100644 (file)
@@ -34,11 +34,11 @@ class LinuxCCNContent(LinuxApplication):
     def _register_attributes(cls):
         content_name = Attribute("contentName",
                 "The name of the content to publish (e.g. ccn:/VIDEO) ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         content = Attribute("content",
                 "The content to publish. It can be a path to a file or plain text ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         scope = Attribute("scope",
                 "Use the given scope on the start-write request (if -r specified). "
@@ -46,7 +46,7 @@ class LinuxCCNContent(LinuxApplication):
                 "Note that a scope of 3 is encoded as the absence of any scope in the interest. ",
                 type = Types.Integer,
                 default = 1,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(content_name)
         cls._register_attribute(content)
@@ -96,7 +96,6 @@ class LinuxCCNContent(LinuxApplication):
             self.do_discover()
             self.do_provision()
 
-            self.debug("----- READY ---- ")
             self.set_ready()
 
     def upload_start_command(self):
index e4bc39a..95ac92f 100644 (file)
@@ -50,56 +50,56 @@ class LinuxCCND(LinuxApplication):
             "  -1 - max logging \n"
             "  Or apply bitwise OR to these values to get combinations of them",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         port = Attribute("port", "Sets the CCN_LOCAL_PORT environmental variable. "
             "Defaults to 9695 ", 
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
  
         sockname = Attribute("sockname",
             "Sets the CCN_LOCAL_SCOKNAME environmental variable. "
             "Defaults to /tmp/.ccnd.sock", 
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         capacity = Attribute("capacity",
             "Sets the CCND_CAP environmental variable. "
             "Capacity limit in terms of ContentObjects",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         mtu = Attribute("mtu", "Sets the CCND_MTU environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
   
         data_pause = Attribute("dataPauseMicrosec",
             "Sets the CCND_DATA_PAUSE_MICROSEC environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         default_stale = Attribute("defaultTimeToStale",
              "Sets the CCND_DEFAULT_TIME_TO_STALE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_stale = Attribute("maxTimeToStale",
             "Sets the CCND_MAX_TIME_TO_STALE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_rte = Attribute("maxRteMicrosec",
             "Sets the CCND_MAX_RTE_MICROSEC environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         keystore = Attribute("keyStoreDirectory",
             "Sets the CCND_KEYSTORE_DIRECTORY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         listen_on = Attribute("listenOn",
             "Sets the CCND_LISTEN_ON environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         autoreg = Attribute("autoreg",
             "Sets the CCND_AUTOREG environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         prefix = Attribute("prefix",
             "Sets the CCND_PREFIX environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(debug)
         cls._register_attribute(port)
@@ -176,7 +176,6 @@ class LinuxCCND(LinuxApplication):
             self.do_discover()
             self.do_provision()
 
-            self.debug("----- READY ---- ")
             self.set_ready()
 
     def upload_start_command(self):
index f654a2a..cbe599e 100644 (file)
@@ -34,21 +34,21 @@ class LinuxCCNPing(LinuxCCNPingServer):
         interval = Attribute("i",
             "Set ping interval in seconds (minimum 0.10 second) ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         count = Attribute("c",
             "Total number of pings",
             type = Types.Double,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         number = Attribute("n",
             "Set the starting number, the number is incremented by 1 after each Interest ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
  
         prefix = Attribute("prefix",
             "Prefix to serve content (e.g. ccnx:/name/prefix)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(interval)
         cls._register_attribute(count)
index 2dee4db..865b104 100644 (file)
@@ -35,16 +35,16 @@ class LinuxCCNPingServer(LinuxCCNApplication):
             "Run ccnping server as a daemon in background",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         freshness = Attribute("x",
             "Set FreshnessSeconds",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         prefix = Attribute("prefix",
             "Prefix to serve content (e.g. ccnx:/name/prefix)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(daemon)
         cls._register_attribute(freshness)
index e65779a..69a8437 100644 (file)
@@ -35,23 +35,23 @@ class LinuxCCNR(LinuxApplication):
     def _register_attributes(cls):
         max_fanout = Attribute("maxFanout",
             "Sets the CCNR_BTREE_MAX_FANOUT environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_leaf_entries = Attribute("maxLeafEntries",
             "Sets the CCNR_BTREE_MAX_LEAF_ENTRIES environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_node_bytes = Attribute("maxNodeBytes",
             "Sets the CCNR_BTREE_MAX_NODE_BYTES environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         max_node_pool = Attribute("maxNodePool",
             "Sets the CCNR_BTREE_MAX_NODE_POOL environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         content_cache = Attribute("contentCache",
             "Sets the CCNR_CONTENT_CACHE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         debug = Attribute("debug",
             "Sets the CCNR_DEBUG environmental variable. "
@@ -64,92 +64,92 @@ class LinuxCCNR(LinuxApplication):
                     "WARNING",
                     "INFO",
                     "FINE, FINER, FINEST"],
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         directory = Attribute("directory",
             "Sets the CCNR_DIRECTORY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         global_prefix = Attribute("globalPrefix",
             "Sets the CCNR_GLOBAL_PREFIX environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         listen_on = Attribute("listenOn",
             "Sets the CCNR_LISTEN_ON environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         min_send_bufsize = Attribute("minSendBufsize",
             "Sets the CCNR_MIN_SEND_BUFSIZE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         proto = Attribute("proto",
             "Sets the CCNR_PROTO environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         status_port = Attribute("statusPort",
             "Sets the CCNR_STATUS_PORT environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         start_write_scope_limit = Attribute("startWriteScopeLimit",
             "Sets the CCNR_START_WRITE_SCOPE_LIMIT environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_debug = Attribute("ccnsDebug",
             "Sets the CCNS_DEBUG environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_enable = Attribute("ccnsEnable",
             "Sets the CCNS_ENABLE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_faux_error = Attribute("ccnsFauxError",
             "Sets the CCNS_FAUX_ERROR environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_heartbeat_micros = Attribute("ccnsHeartBeatMicros",
             "Sets the CCNS_HEART_BEAT_MICROS environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_max_compares_busy = Attribute("ccnsMaxComparesBusy",
             "Sets the CCNS_MAX_COMPARES_BUSY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_max_fetch_busy = Attribute("ccnsMaxFetchBusy",
             "Sets the CCNS_MAX_FETCH_BUSY environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_node_fetch_lifetime = Attribute("ccnsNodeFetchLifetime",
             "Sets the CCNS_NODE_FETCH_LIFETIME environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_note_err = Attribute("ccnsNoteErr",
             "Sets the CCNS_NOTE_ERR environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_repo_store = Attribute("ccnsRepoStore",
             "Sets the CCNS_REPO_STORE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_root_advise_fresh = Attribute("ccnsRootAdviseFresh",
             "Sets the CCNS_ROOT_ADVISE_FRESH environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_root_advise_lifetime = Attribute("ccnsRootAdviseLifetime",
             "Sets the CCNS_ROOT_ADVISE_LIFETIME environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_stable_enabled = Attribute("ccnsStableEnabled",
             "Sets the CCNS_STABLE_ENABLED environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ccns_sync_scope = Attribute("ccnsSyncScope",
             "Sets the CCNS_SYNC_SCOPE environmental variable. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         repo_file = Attribute("repoFile1",
             "The Repository uses $CCNR_DIRECTORY/repoFile1 for "
             "persistent storage of CCN Content Objects",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(max_fanout)
         cls._register_attribute(max_leaf_entries)
@@ -220,7 +220,6 @@ class LinuxCCNR(LinuxApplication):
             self.do_discover()
             self.do_provision()
 
-            self.debug("----- READY ---- ")
             self.set_ready()
 
     def upload_start_command(self):
index cebc105..dca91c2 100644 (file)
@@ -42,7 +42,7 @@ class LinuxFIBEntry(LinuxApplication):
         uri = Attribute("uri",
                 "URI prefix to match and route for this FIB entry",
                 default = "ccnx:/",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         protocol = Attribute("protocol",
                 "Transport protocol used in network connection to peer "
@@ -50,20 +50,20 @@ class LinuxFIBEntry(LinuxApplication):
                 type = Types.Enumerate, 
                 default = "udp",
                 allowed = ["udp", "tcp"],
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         host = Attribute("host",
                 "Peer hostname used in network connection for this FIB entry. ",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         port = Attribute("port",
                 "Peer port address used in network connection to peer "
                 "for this FIB entry.",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         ip = Attribute("ip",
                 "Peer host public IP used in network connection for this FIB entry. ",
-                flags = Flags.ReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(uri)
         cls._register_attribute(protocol)
@@ -134,7 +134,6 @@ class LinuxFIBEntry(LinuxApplication):
             self.do_provision()
             self.configure()
 
-            self.debug("----- READY ---- ")
             self.set_ready()
 
     def upload_start_command(self):
index 7b8eadc..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):
@@ -42,33 +43,33 @@ class LinuxInterface(ResourceManager):
     @classmethod
     def _register_attributes(cls):
         ip4 = Attribute("ip4", "IPv4 Address",
-              flags = Flags.ExecReadOnly)
+              flags = Flags.Design)
 
         ip6 = Attribute("ip6", "IPv6 Address",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mac = Attribute("mac", "MAC Address",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mask4 = Attribute("mask4", "IPv4 network mask",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mask6 = Attribute("mask6", "IPv6 network mask",
                 type = Types.Integer,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mtu = Attribute("mtu", "Maximum transmition unit for device",
                 type = Types.Integer)
 
         devname = Attribute("deviceName", 
                 "Name of the network interface (e.g. eth0, wlan0, etc)",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         up = Attribute("up", "Link up", type = Types.Bool)
 
         tear_down = Attribute("tearDown", "Bash script to be executed before " + \
                 "releasing the resource",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(ip4)
         cls._register_attribute(ip6)
@@ -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 1edc6b5..b694443 100644 (file)
@@ -34,41 +34,41 @@ class LinuxMtr(LinuxApplication):
             "sets mtr --report-cycles (-c) option. Determines the number of "
             "pings sent to determine both machines in the networks. Each "
             "cycle lasts one sencond.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         no_dns = Attribute("noDns",
             "sets mtr --no-dns (-n) option. Forces mtr to display IPs intead of "
             "trying to resolve to host names ",
             type = Types.Bool,
             default = True,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         address = Attribute("address",
             "sets mtr --address (-a) option. Binds the socket to send outgoing "
             "packets to the interface of the specified address, so that any "
             "any packets are sent through this interface. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         interval = Attribute("interval",
             "sets mtr --interval (-i) option. Specifies the number of seconds "
             "between ICMP ECHO requests. Default value is one second ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         countinuous = Attribute("continuous",
             "Run mtr in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running mtr",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "mtr target host (host that will be pinged)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(report_cycles)
         cls._register_attribute(no_dns)
index 029ee8a..f9ae091 100644 (file)
@@ -149,50 +149,50 @@ class LinuxNode(ResourceManager):
     @classmethod
     def _register_attributes(cls):
         hostname = Attribute("hostname", "Hostname of the machine",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         username = Attribute("username", "Local account username", 
                 flags = Flags.Credential)
 
-        port = Attribute("port", "SSH port", flags = Flags.ExecReadOnly)
+        port = Attribute("port", "SSH port", flags = Flags.Design)
         
         home = Attribute("home",
                 "Experiment home directory to store all experiment related files",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         identity = Attribute("identity", "SSH identity file",
                 flags = Flags.Credential)
         
         server_key = Attribute("serverKey", "Server public key", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         clean_home = Attribute("cleanHome", "Remove all nepi files and directories "
                 " from node home folder before starting experiment", 
                 type = Types.Bool,
                 default = False,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         clean_experiment = Attribute("cleanExperiment", "Remove all files and directories " 
                 " from a previous same experiment, before the new experiment starts", 
                 type = Types.Bool,
                 default = False,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         clean_processes = Attribute("cleanProcesses", 
                 "Kill all running processes before starting experiment",
                 type = Types.Bool,
                 default = False,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         tear_down = Attribute("tearDown", "Bash script to be executed before " + \
                 "releasing the resource",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         gateway_user = Attribute("gatewayUser", "Gateway account username",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         gateway = Attribute("gateway", "Hostname of the gateway machine",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(hostname)
         cls._register_attribute(username)
@@ -452,13 +452,10 @@ class LinuxNode(ResourceManager):
 
     def execute(self, command,
             sudo = False,
-            stdin = None, 
             env = None,
             tty = False,
             forward_x11 = False,
-            timeout = None,
             retry = 3,
-            err_on_timeout = True,
             connect_timeout = 30,
             strict_host_checking = False,
             persistent = True,
@@ -473,10 +470,13 @@ class LinuxNode(ResourceManager):
             (out, err), proc = execfuncs.lexec(command, 
                     user = self.get("username"), # still problem with localhost
                     sudo = sudo,
-                    stdin = stdin,
                     env = env)
         else:
             if with_lock:
+                # If the execute command is blocking, we don't want to keep
+                # the node lock. This lock is used to avoid race conditions
+                # when creating the ControlMaster sockets. A more elegant
+                # solution is needed.
                 with self._node_lock:
                     (out, err), proc = sshfuncs.rexec(
                         command, 
@@ -487,15 +487,12 @@ class LinuxNode(ResourceManager):
                         gw = self.get("gateway"),
                         agent = True,
                         sudo = sudo,
-                        stdin = stdin,
                         identity = self.get("identity"),
                         server_key = self.get("serverKey"),
                         env = env,
                         tty = tty,
                         forward_x11 = forward_x11,
-                        timeout = timeout,
                         retry = retry,
-                        err_on_timeout = err_on_timeout,
                         connect_timeout = connect_timeout,
                         persistent = persistent,
                         blocking = blocking, 
@@ -511,15 +508,12 @@ class LinuxNode(ResourceManager):
                     gw = self.get("gateway"),
                     agent = True,
                     sudo = sudo,
-                    stdin = stdin,
                     identity = self.get("identity"),
                     server_key = self.get("serverKey"),
                     env = env,
                     tty = tty,
                     forward_x11 = forward_x11,
-                    timeout = timeout,
                     retry = retry,
-                    err_on_timeout = err_on_timeout,
                     connect_timeout = connect_timeout,
                     persistent = persistent,
                     blocking = blocking, 
index 62bacd8..544b4d9 100644 (file)
@@ -34,84 +34,84 @@ class LinuxNPing(LinuxApplication):
             "Sets nping -c option. "
             "Stop after a given number of rounds. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         e = Attribute("e",
             "Sets nping -e option. "
             "Set the network interface to be used.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         delay = Attribute("delay",
             "Sets nping --delay option. "
             "Delay between probes ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         rate = Attribute("rate",
             "Sets nping --rate option. "
             "Send probes at a given rate ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttl = Attribute("ttl",
             "Sets nping --ttl option. "
             "Time To Live. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         p = Attribute("p",
             "Sets nping -p option. "
             "Target ports. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tcp = Attribute("tcp",
             "Sets nping --tcp option. "
             "TCP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         udp = Attribute("udp",
             "Sets nping --udp option. "
             "UDP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         icmp = Attribute("icmp",
             "Sets nping --icmp option. "
             "ICMP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         arp = Attribute("arp",
             "Sets nping --arp option. "
             "ARP mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         traceroute = Attribute("traceroute",
             "Sets nping --traceroute option. "
             "Traceroute mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         countinuous = Attribute("continuous",
             "Run nping in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running nping",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "nping target host (host that will be pinged)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(c)
         cls._register_attribute(e)
diff --git a/src/nepi/resources/linux/ns3/__init__.py b/src/nepi/resources/linux/ns3/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/nepi/resources/linux/ns3/dependencies/pygccxml-1.0.0.tar.gz b/src/nepi/resources/linux/ns3/dependencies/pygccxml-1.0.0.tar.gz
new file mode 100644 (file)
index 0000000..5e71694
Binary files /dev/null and b/src/nepi/resources/linux/ns3/dependencies/pygccxml-1.0.0.tar.gz differ
diff --git a/src/nepi/resources/linux/ns3/ns3client.py b/src/nepi/resources/linux/ns3/ns3client.py
new file mode 100644 (file)
index 0000000..882c1f3
--- /dev/null
@@ -0,0 +1,116 @@
+#
+#    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>
+
+import base64
+import cPickle
+import errno
+import os
+import socket
+import time
+import weakref
+
+from optparse import OptionParser, SUPPRESS_HELP
+
+from nepi.resources.ns3.ns3client import NS3Client
+from nepi.resources.ns3.ns3server import NS3WrapperMessage
+
+class LinuxNS3Client(NS3Client):
+    def __init__(self, simulation):
+        super(LinuxNS3Client, self).__init__()
+        self._simulation = weakref.ref(simulation)
+
+        self._socat_proc = None
+
+    @property
+    def simulation(self):
+        return self._simulation()
+
+    def send_msg(self, msg_type, *args, **kwargs):
+        msg = [msg_type, args, kwargs]
+
+        def encode(item):
+            item = cPickle.dumps(item)
+            return base64.b64encode(item)
+
+        encoded = "|".join(map(encode, msg))
+
+        if self.simulation.node.get("hostname") in ['localhost', '127.0.0.1']:
+            sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            sock.connect(self.simulation.remote_socket)
+            sock.send("%s\n" % encoded)
+            reply = sock.recv(1024)
+            sock.close()
+
+        else:
+            command = ( "python -c 'import socket;"
+                "sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM);"
+                "sock.connect(\"%(socket_addr)s\");"
+                "msg = \"%(encoded_message)s\\n\";"
+                "sock.send(msg);"
+                "reply = sock.recv(1024);"
+                "sock.close();"
+                "print reply'") % {
+                    "encoded_message": encoded,
+                    "socket_addr": self.simulation.remote_socket,
+                    }
+
+            (reply, err), proc = self.simulation.node.execute(command)
+
+            if (err and proc.poll()) or reply.strip() == "":
+                msg = " Couldn't connect to remote socket %s" % (
+                        self.simulation.remote_socket)
+                self.simulation.error(msg, reply, err)
+                raise RuntimeError(msg)
+                   
+        reply = cPickle.loads(base64.b64decode(reply))
+
+        return reply
+
+    def create(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.CREATE, *args, **kwargs)
+
+    def factory(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.FACTORY, *args, **kwargs)
+
+    def invoke(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.INVOKE, *args, **kwargs)
+
+    def set(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.SET, *args, **kwargs)
+
+    def get(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.GET, *args, **kwargs)
+
+    def flush(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.FLUSH, *args, **kwargs)
+
+    def start(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.START, *args, **kwargs)
+
+    def stop(self, *args, **kwargs):
+        return self.send_msg(NS3WrapperMessage.STOP, *args, **kwargs)
+
+    def shutdown(self, *args, **kwargs):
+        try:
+            return self.send_msg(NS3WrapperMessage.SHUTDOWN, *args, **kwargs)
+        except:
+            pass
+
+        return None
+
diff --git a/src/nepi/resources/linux/ns3/ns3simulation.py b/src/nepi/resources/linux/ns3/ns3simulation.py
new file mode 100644 (file)
index 0000000..a7780b0
--- /dev/null
@@ -0,0 +1,454 @@
+#
+#    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.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.linux.application import LinuxApplication
+from nepi.util.timefuncs import tnow, tdiffsec
+from nepi.resources.ns3.ns3simulation import NS3Simulation
+from nepi.resources.ns3.ns3wrapper import SIMULATOR_UUID, GLOBAL_VALUE_UUID, \
+        IPV4_GLOBAL_ROUTING_HELPER_UUID
+from nepi.resources.linux.ns3.ns3client import LinuxNS3Client
+
+import os
+import time
+
+@clsinit_copy
+class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
+    _rtype = "LinuxNS3Simulation"
+
+    @classmethod
+    def _register_attributes(cls):
+        impl_type = Attribute("simulatorImplementationType",
+                "The object class to use as the simulator implementation",
+            allowed = ["ns3::DefaultSimulatorImpl", "ns3::RealtimeSimulatorImpl"],
+            default = "ns3::DefaultSimulatorImpl",
+            type = Types.Enumerate,
+            flags = Flags.Design)
+
+        sched_type = Attribute("schedulerType",
+                "The object class to use as the scheduler implementation",
+                allowed = ["ns3::MapScheduler",
+                            "ns3::ListScheduler",
+                            "ns3::HeapScheduler",
+                            "ns3::MapScheduler",
+                            "ns3::CalendarScheduler"
+                    ],
+            default = "ns3::MapScheduler",
+            type = Types.Enumerate,
+            flags = Flags.Design)
+
+        check_sum = Attribute("checksumEnabled",
+                "A global switch to enable all checksums for all protocols",
+            default = False,
+            type = Types.Bool,
+            flags = Flags.Design)
+
+        ns_log = Attribute("nsLog",
+            "NS_LOG environment variable. " \
+                    " Will only generate output if ns-3 is compiled in DEBUG mode. ",
+            flags = Flags.Design)
+
+        verbose = Attribute("verbose",
+            "True to output debugging info from the ns3 client-server communication",
+            type = Types.Bool,
+            flags = Flags.Design)
+
+        build_mode = Attribute("buildMode",
+            "Mode used to build ns-3 with waf. One if: debug, release, oprimized ",
+            default = "release", 
+            allowed = ["debug", "release", "optimized"],
+            type = Types.Enumerate,
+            flags = Flags.Design)
+
+        ns3_version = Attribute("ns3Version",
+            "Version of ns-3 to install from nsam repo",
+            default = "ns-3.19", 
+            flags = Flags.Design)
+
+        pybindgen_version = Attribute("pybindgenVersion",
+            "Version of pybindgen to install from bazar repo",
+            default = "834", 
+            flags = Flags.Design)
+
+        populate_routing_tables = Attribute("populateRoutingTables",
+            "Invokes  Ipv4GlobalRoutingHelper.PopulateRoutingTables() ",
+            default = False,
+            type = Types.Bool,
+            flags = Flags.Design)
+
+        cls._register_attribute(impl_type)
+        cls._register_attribute(sched_type)
+        cls._register_attribute(check_sum)
+        cls._register_attribute(ns_log)
+        cls._register_attribute(verbose)
+        cls._register_attribute(build_mode)
+        cls._register_attribute(ns3_version)
+        cls._register_attribute(pybindgen_version)
+        cls._register_attribute(populate_routing_tables)
+
+    def __init__(self, ec, guid):
+        LinuxApplication.__init__(self, ec, guid)
+        NS3Simulation.__init__(self)
+
+        self._client = None
+        self._home = "ns3-simu-%s" % self.guid
+        self._socket_name = "ns3simu-%s" % os.urandom(8).encode('hex')
+
+    @property
+    def socket_name(self):
+        return self._socket_name
+
+    @property
+    def remote_socket(self):
+        return os.path.join(self.run_home, self.socket_name)
+
+    def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0):
+        self._client.flush() 
+        return LinuxApplication.trace(self, name, attr, block, offset)
+
+    def upload_sources(self):
+        self.node.mkdir(os.path.join(self.node.src_dir, "ns3wrapper"))
+
+        # upload ns3 wrapper python script
+        ns3_wrapper = os.path.join(os.path.dirname(__file__), "..", "..", "ns3", 
+                "ns3wrapper.py")
+
+        self.node.upload(ns3_wrapper,
+                os.path.join(self.node.src_dir, "ns3wrapper", "ns3wrapper.py"),
+                overwrite = False)
+
+        # upload ns3_server python script
+        ns3_server = os.path.join(os.path.dirname(__file__), "..", "..", "ns3",
+                "ns3server.py")
+
+        self.node.upload(ns3_server,
+                os.path.join(self.node.src_dir, "ns3wrapper", "ns3server.py"),
+                overwrite = False)
+
+        if self.node.use_rpm:
+            # upload pygccxml sources
+            pygccxml_tar = os.path.join(os.path.dirname(__file__), "dependencies",
+                    "%s.tar.gz" % self.pygccxml_version)
+
+            self.node.upload(pygccxml_tar,
+                    os.path.join(self.node.src_dir, "%s.tar.gz" % self.pygccxml_version),
+                    overwrite = False)
+
+        # Upload user defined ns-3 sources
+        self.node.mkdir(os.path.join(self.node.src_dir, "ns-3"))
+        src_dir = os.path.join(self.node.src_dir, "ns-3")
+
+        super(LinuxNS3Simulation, self).upload_sources(src_dir = src_dir)
+
+    def upload_start_command(self):
+        command = self.get("command")
+        env = self.get("env")
+
+        # We want to make sure the ccnd is running
+        # before the experiment starts.
+        # Run the command as a bash script in background,
+        # in the host ( but wait until the command has
+        # finished to continue )
+        env = self.replace_paths(env)
+        command = self.replace_paths(command)
+
+        shfile = os.path.join(self.app_home, "start.sh")
+        self.node.upload_command(command, 
+                    shfile = shfile,
+                    env = env,
+                    overwrite = True)
+
+        # Run the ns3wrapper 
+        self._run_in_background()
+
+    def configure(self):
+        if self.has_changed("simulatorImplementationType"):
+            simu_type = self.get("simulatorImplementationType")
+            stype = self.create("StringValue", simu_type)
+            self.invoke(GLOBAL_VALUE_UUID, "Bind", "SimulatorImplementationType", stype)
+
+        if self.has_changed("checksumEnabled"):
+            check_sum = self.get("checksumEnabled")
+            btrue = self.create("BooleanValue", check_sum)    
+            self.invoke(GLOBAL_VALUE_UUID, "Bind", "ChecksumEnabled", btrue)
+        
+        if self.has_changed("schedulerType"):
+            sched_type = self.get("schedulerType")
+            stype = self.create("StringValue", sched_type)
+            self.invoke(GLOBAL_VALUE_UUID, "Bind", "SchedulerType", btrue)
+       
+    def do_deploy(self):
+        if not self.node or self.node.state < ResourceState.READY:
+            self.debug("---- RESCHEDULING DEPLOY ---- node state %s " % self.node.state )
+            
+            # ccnd needs to wait until node is deployed and running
+            self.ec.schedule(reschedule_delay, self.deploy)
+        else:
+            if not self.get("command"):
+                self.set("command", self._start_command)
+            
+            if not self.get("depends"):
+                self.set("depends", self._dependencies)
+
+            if self.get("sources"):
+                sources = self.get("sources")
+                source = sources.split(" ")[0]
+                basename = os.path.basename(source)
+                version = ( basename.strip().replace(".tar.gz", "")
+                    .replace(".tar","")
+                    .replace(".gz","")
+                    .replace(".zip","") )
+
+                self.set("ns3Version", version)
+                self.set("sources", source)
+
+            if not self.get("build"):
+                self.set("build", self._build)
+
+            if not self.get("install"):
+                self.set("install", self._install)
+
+            if not self.get("env"):
+                self.set("env", self._environment)
+
+            self.do_discover()
+            self.do_provision()
+
+            # Create client
+            self._client = LinuxNS3Client(self)
+
+            self.configure()
+            
+            self.set_ready()
+
+    def do_start(self):
+        """ Starts simulation execution
+
+        """
+        self.info("Starting")
+
+        if self.state == ResourceState.READY:
+            if self.get("populateRoutingTables") == True:
+                self.invoke(IPV4_GLOBAL_ROUTING_HELPER_UUID, "PopulateRoutingTables")
+
+            self._client.start() 
+
+            self.set_started()
+        else:
+            msg = " Failed to execute command '%s'" % command
+            self.error(msg, out, err)
+            raise RuntimeError, msg
+
+    def do_stop(self):
+        """ Stops simulation execution
+
+        """
+        if self.state == ResourceState.STARTED:
+            self._client.stop() 
+            self.set_stopped()
+
+    def do_release(self):
+        self.info("Releasing resource")
+
+        tear_down = self.get("tearDown")
+        if tear_down:
+            self.node.execute(tear_down)
+
+        self.do_stop()
+        self._client.shutdown()
+        LinuxApplication.do_stop(self)
+        
+        super(LinuxApplication, self).do_release()
+
+    @property
+    def _start_command(self):
+        command = [] 
+        command.append("PYTHONPATH=$PYTHONPATH:${SRC}/ns3wrapper/")
+
+        command.append("python ${SRC}/ns3wrapper/ns3server.py -S %s" % self.remote_socket )
+
+        ns_log = self.get("nsLog")
+        if ns_log:
+            command.append("-L %s" % ns_log)
+
+        if self.get("verbose"):
+            command.append("-v")
+
+        command = " ".join(command)
+        return command
+
+    @property
+    def _dependencies(self):
+        if self.node.use_rpm:
+            return ( " gcc gcc-c++ python python-devel mercurial bzr tcpdump socat gccxml unzip")
+        elif self.node.use_deb:
+            return ( " gcc g++ python python-dev mercurial bzr tcpdump socat gccxml python-pygccxml unzip")
+        return ""
+
+    @property
+    def ns3_repo(self):
+        return "http://code.nsnam.org"
+
+    @property
+    def pygccxml_version(self):
+        return "pygccxml-1.0.0"
+
+    @property
+    def _build(self):
+        # If the user defined local sources for ns-3, we uncompress the sources
+        # on the remote sources directory. Else we clone ns-3 from the official repo.
+        source = self.get("sources")
+        if not source:
+            copy_ns3_cmd = "hg clone %(ns3_repo)s/%(ns3_version)s ${SRC}/ns-3/%(ns3_version)s" \
+                    % ({
+                        'ns3_version': self.get("ns3Version"),
+                        'ns3_repo':  self.ns3_repo,       
+                       })
+        else:
+            if source.find(".tar.gz") > -1:
+                copy_ns3_cmd = ( 
+                            "tar xzf ${SRC}/ns-3/%(basename)s " 
+                            " --strip-components=1 -C ${SRC}/ns-3/%(ns3_version)s "
+                            ) % ({
+                                'basename': os.path.basename(source),
+                                'ns3_version': self.get("ns3Version"),
+                                })
+            elif source.find(".tar") > -1:
+                copy_ns3_cmd = ( 
+                            "tar xf ${SRC}/ns-3/%(basename)s " 
+                            " --strip-components=1 -C ${SRC}/ns-3/%(ns3_version)s "
+                            ) % ({
+                                'basename': os.path.basename(source),
+                                'ns3_version': self.get("ns3Version"),
+                                })
+            elif source.find(".zip") > -1:
+                basename = os.path.basename(source)
+                bare_basename = basename.replace(".zip", "") \
+                        .replace(".tar", "") \
+                        .replace(".tar.gz", "")
+
+                copy_ns3_cmd = ( 
+                            "unzip ${SRC}/ns-3/%(basename)s && "
+                            "mv ${SRC}/ns-3/%(bare_basename)s ${SRC}/ns-3/%(ns3_version)s "
+                            ) % ({
+                                'bare_basename': basename_name,
+                                'basename': basename,
+                                'ns3_version': self.get("ns3Version"),
+                                })
+
+        return (
+                # Test if ns-3 is alredy installed
+                " ( "
+                " (( "
+                "    ( test -d ${SRC}/ns-3/%(ns3_version)s ) || "
+                "    ( test -d ${NS3BINDINGS:='None'} && test -d ${NS3LIBRARIES:='None'}) "
+                "  ) && echo 'binaries found, nothing to do' )"
+                " ) "
+                "  || " 
+                # If not, install ns-3 and its dependencies
+                " (   "
+                # Install pygccxml
+                "   (   "
+                "     ( "
+                "       python -c 'import pygccxml' && "
+                "       echo 'pygccxml not found' "
+                "     ) "
+                "      || "
+                "     ( "
+                "       tar xf ${SRC}/%(pygccxml_version)s.tar.gz -C ${SRC} && "
+                "       cd ${SRC}/%(pygccxml_version)s && "
+                "       sudo -S python setup.py install "
+                "     ) "
+                "   ) " 
+                # Install pybindgen
+                "  && "
+                "   (   "
+                "     ( "
+                "       test -d ${SRC}/pybindgen/%(pybindgen_version)s && "
+                "       echo 'binaries found, nothing to do' "
+                "     ) "
+                "      || "
+                # If not, clone and build
+                "      ( cd ${SRC} && "
+                "        mkdir -p ${SRC}/pybindgen && "
+                "        bzr checkout lp:pybindgen -r %(pybindgen_version)s ${SRC}/pybindgen/%(pybindgen_version)s && "
+                "        cd ${SRC}/pybindgen/%(pybindgen_version)s && "
+                "        ./waf configure && "
+                "        ./waf "
+                "      ) "
+                "   ) " 
+                " && "
+                # Get ns-3 source code
+                "  ( "
+                "     mkdir -p ${SRC}/ns-3/%(ns3_version)s && "
+                "     %(copy_ns3_cmd)s "
+                "  ) "
+                " ) "
+             ) % ({ 
+                    'ns3_version': self.get("ns3Version"),
+                    'pybindgen_version': self.get("pybindgenVersion"),
+                    'pygccxml_version': self.pygccxml_version,
+                    'copy_ns3_cmd': copy_ns3_cmd,
+                 })
+
+    @property
+    def _install(self):
+        return (
+                 # Test if ns-3 is alredy cloned
+                " ( "
+                "  ( ( (test -d ${BIN}/ns-3/%(ns3_version)s/%(build_mode)s/build ) || "
+                "    (test -d ${NS3BINDINGS:='None'} && test -d ${NS3LIBRARIES:='None'}) ) && "
+                "    echo 'binaries found, nothing to do' )"
+                " ) "
+                " ||" 
+                " (   "
+                 # If not, copy ns-3 build to bin
+                "  cd ${SRC}/ns-3/%(ns3_version)s && "
+                "  ./waf configure -d %(build_mode)s --with-pybindgen=${SRC}/pybindgen/%(pybindgen_version)s && "
+                "  ./waf && "
+                "  mkdir -p ${BIN}/ns-3/%(ns3_version)s/%(build_mode)s && "
+                "  mv ${SRC}/ns-3/%(ns3_version)s/build ${BIN}/ns-3/%(ns3_version)s/%(build_mode)s/build "
+                " )"
+             ) % ({ 
+                    'ns3_version': self.get("ns3Version"),
+                    'pybindgen_version': self.get("pybindgenVersion"),
+                    'build_mode': self.get("buildMode"),
+                 })
+
+    @property
+    def _environment(self):
+        env = []
+        env.append("NS3BINDINGS=${NS3BINDINGS:=${BIN}/ns-3/%(ns3_version)s/%(build_mode)s/build/bindings/python/}" % ({ 
+                    'ns3_version': self.get("ns3Version"),
+                    'build_mode': self.get("buildMode")
+                 }))
+        env.append("NS3LIBRARIES=${NS3LIBRARIES:=${BIN}/ns-3/%(ns3_version)s/%(build_mode)s/build/}" % ({ 
+                    'ns3_version': self.get("ns3Version"),
+                    'build_mode': self.get("buildMode")
+                 }))
+
+        return " ".join(env) 
+
+    def valid_connection(self, guid):
+        # TODO: Validate!
+        return True
+
index 6db0a8d..a3df579 100644 (file)
@@ -34,56 +34,56 @@ class LinuxPing(LinuxApplication):
             "Sets ping -c option. Determines the number of ECHO_REQUEST "
             "packates to send before stopping.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         mark = Attribute("mark",
             "Sets ping -m option. Uses 'mark' to tag outgoing packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         interval = Attribute("interval",
             "Sets ping -i option. Leaves interval seconds between "
             "successive ECHO_REUQEST packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         address = Attribute("address",
             "Sets ping -I option. Sets ECHO_REQUEST packets souce address "
             "to the specified interface address ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         preload = Attribute("preload",
             "Sets ping -l option. Sends preload amount of packets "
             "without waiting for a reply ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         numeric = Attribute("numeric",
             "Sets ping -n option. Disables resolution of host addresses into "
             "symbolic names. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         pattern = Attribute("pattern",
             "Sets ping -p option. Species a up to 16 ''pad'' bytes to fill "
             "out sent packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         printtmp = Attribute("printTimestamp",
             "Sets ping -D option. Prints timestamp befor each line as: "
             "unix time + microseconds as in gettimeofday ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tos = Attribute("tos",
             "Sets ping -Q option. Sets Quality of Service related bits in ICMP "
             "datagrams. tos can be either a decimal or hexadecime number ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         quiet = Attribute("quiet",
             "Sets ping -q option. Disables ping standard output ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         rec_route = Attribute("recordRoute",
             "Sets ping -R option. Includes the RECORD_ROUTE option in the "
@@ -91,37 +91,37 @@ class LinuxPing(LinuxApplication):
             "ping standard output.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         route_bypass = Attribute("routeBypass",
             "Sets ping -r option. Bypasses normal routing tables and sends "
             "ECHO REQUEST packets directly yo a host on an attached interface. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         packetsize = Attribute("packetSize",
             "Sets ping -s option. Specifies the number of data bytes to be "
             "sent. Defaults to 56. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         sendbuff = Attribute("sendBuff",
             "Sets ping -S option. Specifies the number of packets to buffer. "
             "Defaults to one. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttl = Attribute("ttl",
             "Sets ping -t option. Specifies the IP Time to Live for the "
             "packets. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         timestamp = Attribute("timestamp",
             "Sets ping -T option. Sets special IP timestamp options. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         hint = Attribute("hint",
             "Sets ping -M option. Selects Path MTU Discovery strategy. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         full_latency = Attribute("fullLatency",
             "Sets ping -U option. Calculates round trip time taking into "
@@ -129,32 +129,32 @@ class LinuxPing(LinuxApplication):
             "network round trip time. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         verbose = Attribute("verbose",
             "Sets ping -v option. Verbose output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         flood = Attribute("flood",
             "Sets ping -f option. Flood ping. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         deadline = Attribute("deadline",
             "Sets ping -w option. Specify a timeout, in seconds, before ping "
             "exits regardless of how many packets have been sent or received.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         timeout = Attribute("timeout",
             "Sets ping -W option. Time to wait for a respone in seconds .",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "The host to ping .",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(count)
         cls._register_attribute(mark)
index 12d11a2..761c03e 100644 (file)
@@ -35,25 +35,25 @@ class LinuxTcpdump(LinuxApplication):
             "Prints each packet (minus its link level header) in ASCII.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         b = Attribute("b",
             "Sets tcpdump -b option. "
             "Prints the AS number in BGP packets in ASDOT notation. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         B = Attribute("B",
             "Sets tcpdump -B option. "
             "Sets the operaing system capture buffer size in untils of "
             "KiB (1024 bytes).",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         c = Attribute("c",
             "Sets tcpdump -c option. "
             "Exists after receiving count packets.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         C = Attribute("C",
             "Sets tcpdump -C option. "
@@ -63,7 +63,7 @@ class LinuxTcpdump(LinuxApplication):
             "Savefiles after the first savefile will have the name specified "
             "with the -w with a number after it, starting at 1 and continuing "
             "upward. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         d = Attribute("d",
             "Sets tcpdump -d option. "
@@ -71,14 +71,14 @@ class LinuxTcpdump(LinuxApplication):
             "to standard output and stop.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         dd = Attribute("dd",
             "Sets tcpdump -dd option. "
             "Dump packet-matching code as a C program fragment. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ddd = Attribute("ddd",
             "Sets tcpdump -ddd option. "
@@ -86,7 +86,7 @@ class LinuxTcpdump(LinuxApplication):
             "(preceded with a count).",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         D = Attribute("D",
             "Sets tcpdump -D option. "
@@ -94,19 +94,19 @@ class LinuxTcpdump(LinuxApplication):
             "and on which tcpdump can capture packets. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         e = Attribute("e",
             "Sets tcpdump -e option. "
             "Print the link-level header on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         F =  Attribute("F",
             "Sets tcpdump -F option. "
             "Use file as input for the filter expression.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         G =  Attribute("G",
             "Sets tcpdump -G option. "
@@ -114,14 +114,14 @@ class LinuxTcpdump(LinuxApplication):
             "option every rotate_seconds seconds. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         i =  Attribute("i",
             "Sets tcpdump -i option. "
             "Listen on interface.  If unspecified, tcpdump searches the "
             "system interface list for the lowest  numbered, configured "
             "up interface (excluding loopback). ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         I =  Attribute("I",
             "Sets tcpdump -I option. "
@@ -130,7 +130,7 @@ class LinuxTcpdump(LinuxApplication):
             "operating systems. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         j = Attribute("j",
             "Sets tcpdump -j option. "
@@ -138,21 +138,21 @@ class LinuxTcpdump(LinuxApplication):
             "The names to use for the time stamp types are given in "
             "pcap-tstamp-type(7); not all the types listed there will "
             "necessarily be valid for any given interface.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         K = Attribute("K",
             "Sets tcpdump -K option. "
             "Don't attempt to verify IP, TCP, or UDP checksums. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         l = Attribute("l",
             "Sets tcpdump -l option. "
             "Make stdout line buffered. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         U = Attribute("U",
             "Sets tcpdump -U option. "
@@ -161,7 +161,7 @@ class LinuxTcpdump(LinuxApplication):
             "at the end of each packet. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         n = Attribute("n",
             "Sets tcpdump -n option. "
@@ -169,7 +169,7 @@ class LinuxTcpdump(LinuxApplication):
             "etc.) to names.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         N = Attribute("N",
             "Sets tcpdump -N option. "
@@ -178,20 +178,20 @@ class LinuxTcpdump(LinuxApplication):
             "instead of ``nic.ddn.mil''.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         S = Attribute("S",
             "Sets tcpdump -S option. "
             "Print absolute, rather than relative, TCP sequence numbers.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         s = Attribute("s",
             "Sets tcpdump -s option. "
             "Snarf  snaplen bytes of data from each packet rather than "
             "the default of 65535 bytes. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         T = Attribute("T",
             "Sets tcpdump -T option. "
@@ -203,21 +203,21 @@ class LinuxTcpdump(LinuxApplication):
              "protocol), snmp (Simple Network Management Protocol), tftp "
              "(Trivial  File Transfer Protocol), vat (Visual Audio Tool), "
              "and wb (distributed White Board).",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         t = Attribute("t",
             "Sets tcpdump -t option. "
             "Don't print a timestamp on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tt = Attribute("tt",
             "Sets tcpdump -tt option. "
             "Print an unformatted timestamp on each dump line. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttt = Attribute("ttt",
             "Sets tcpdump -ttt option. "
@@ -225,7 +225,7 @@ class LinuxTcpdump(LinuxApplication):
             "and previous line on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         tttt = Attribute("tttt",
             "Sets tcpdump -tttt option. "
@@ -233,7 +233,7 @@ class LinuxTcpdump(LinuxApplication):
             "each dump line. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         ttttt = Attribute("ttttt",
             "Sets tcpdump -ttttt option. "
@@ -241,7 +241,7 @@ class LinuxTcpdump(LinuxApplication):
             "first line on each dump line.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         v = Attribute("v",
             "Sets tcpdump -v option. "
@@ -249,21 +249,21 @@ class LinuxTcpdump(LinuxApplication):
             "verbose output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         vv = Attribute("vv",
             "Sets tcpdump -vv option. "
             "Even  more  verbose  output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         vvv = Attribute("vvv",
             "Sets tcpdump -vv option. "
             "Even  more  verbose  output. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         w = Attribute("w",
             "Sets tcpdump -w option. "
@@ -271,11 +271,11 @@ class LinuxTcpdump(LinuxApplication):
             "and printing them out.",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         expression = Attribute("expression",
             "selects  which packets will be dumped.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(A)
         cls._register_attribute(b)
index 99eea6b..5e592a8 100644 (file)
@@ -35,13 +35,13 @@ class LinuxTraceroute(LinuxApplication):
             "Run traceroute in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running traceroute",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         use_ip = Attribute("useIP",
             "Use the IP address instead of the host domain name. "
@@ -49,11 +49,11 @@ class LinuxTraceroute(LinuxApplication):
             "frequently",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "Traceroute target host (host that will be pinged)",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(countinuous)
         cls._register_attribute(print_timestamp)
index 76c5914..46accbc 100644 (file)
@@ -40,103 +40,103 @@ class LinuxUdpTest(LinuxApplication):
             "Runs in server mode. ",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         p = Attribute("p",
             "Port to listen to in server mode, or to connect to in client mode. "
             "Defaults to 5678. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         a = Attribute("a",
             "Client option. Perform UDP Round Trip Time (latency) ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         A = Attribute("A",
             "Client option. "
             "Message size for UDP RTT test. "
             "UDP RTT (latency) test with specified message size.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         b = Attribute("b",
             "Client option. "
             "Client UDP buffer size in bytes. Using system default "
             "value if not defined.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         B = Attribute("B",
             "Client option. "
             "Server UDP buffer size in bytes. The same as cleint's by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         c = Attribute("c",
             "Client option. "
             "CPU log option. Tracing system info during the test. "
             "Only available when output is defined. ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         d = Attribute("d",
             "Client option. "
             "Data size of each read/write in bytes. The same as packet size "
             "by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         e = Attribute("e",
             "Client option. "
             "Exponential test (data size of each sending increasing from 1 "
             "byte to packet size). ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         g = Attribute("g",
             "Client option. "
             "UDP traffic generator (Keep sending data to a host). "
             "Work without server's support.",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         target = Attribute("target",
             "Client option. "
             "Hostname or IP address of UDP server. Must be specified.",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         i = Attribute("i",
             "Client option. "
             "Bidirectional UDP throuhgput test. Default is unidirection "
             "stream test. ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         l = Attribute("l",
             "Client option. "
             "UDP datagram (packet) size in bytes ( < udp-buffer-szie ). "
             "1460 by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         m = Attribute("m",
             "Client option. "
             "Total message size in bytes. 1048576 by default.",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         o = Attribute("o",
             "Client option. "
             "Output file name. ",
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         P = Attribute("P",
             "Client option. "
             "Write the plot file for gnuplot. Only enable when the output "
             "is specified. ",
             type = Types.Bool,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         q = Attribute("q",
             "Client option. "
@@ -152,38 +152,38 @@ class LinuxUdpTest(LinuxApplication):
             "is specified. ",
             type = Types.Enumerate,
             allowed = ["1", "2", "3", "4", "5", "6"],
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         r = Attribute("r",
             "Client option. "
             "Repetition of tests. 10 by default. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         t = Attribute("t",
             "Client option. "
             "Test time constraint in seconds. 5 by default. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         T = Attribute("T",
             "Client option. "
             "Throughput constraint for UDP generator or throughput "
             "test. Unlimited by default. ",
             type = Types.Integer,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         continuous = Attribute("continuous",
             "Run nping in a while loop",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         print_timestamp = Attribute("printTimestamp",
             "Print timestamp before running nping",
             type = Types.Bool,
             default = False,
-            flags = Flags.ExecReadOnly)
+            flags = Flags.Design)
 
         cls._register_attribute(s)
         cls._register_attribute(p)
index 6372729..ba96788 100644 (file)
@@ -43,25 +43,25 @@ class UdpTunnel(LinuxApplication):
                 default = None,
                 allowed = ["PLAIN", "AES", "Blowfish", "DES", "DES3"],
                 type = Types.Enumerate, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cipher_key = Attribute("cipherKey",
                 "Specify a symmetric encryption key with which to protect "
                 "packets across the tunnel. python-crypto must be installed "
                 "on the system." ,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         txqueuelen = Attribute("txQueueLen",
                 "Specifies the interface's transmission queue length. "
                 "Defaults to 1000. ", 
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         bwlimit = Attribute("bwLimit",
                 "Specifies the interface's emulated bandwidth in bytes "
                 "per second.",
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(cipher)
         cls._register_attribute(cipher_key)
@@ -198,7 +198,6 @@ class UdpTunnel(LinuxApplication):
             self.do_discover()
             self.do_provision()
  
-            self.debug("----- READY ---- ")
             self.set_ready()
 
     def do_start(self):
diff --git a/src/nepi/resources/ns3/classes/__init__.py b/src/nepi/resources/ns3/classes/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/nepi/resources/ns3/classes/aarf_wifi_manager.py b/src/nepi/resources/ns3/classes/aarf_wifi_manager.py
new file mode 100644 (file)
index 0000000..d737f3a
--- /dev/null
@@ -0,0 +1,177 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3AarfWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::AarfWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_successk = Attribute("SuccessK",
+            "Multiplication factor for the success threshold in the AARF algorithm.",
+            type = Types.Double,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_successk)
+
+        attr_timerk = Attribute("TimerK",
+            "Multiplication factor for the timer threshold in the AARF algorithm.",
+            type = Types.Double,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_timerk)
+
+        attr_maxsuccessthreshold = Attribute("MaxSuccessThreshold",
+            "Maximum value of the success threshold in the AARF algorithm.",
+            type = Types.Integer,
+            default = "60",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxsuccessthreshold)
+
+        attr_mintimerthreshold = Attribute("MinTimerThreshold",
+            "The minimum value for the \'timer\' threshold in the AARF algorithm.",
+            type = Types.Integer,
+            default = "15",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mintimerthreshold)
+
+        attr_minsuccessthreshold = Attribute("MinSuccessThreshold",
+            "The minimum value for the success threshold in the AARF algorithm.",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minsuccessthreshold)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3AarfWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-aarf-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/aarfcd_wifi_manager.py b/src/nepi/resources/ns3/classes/aarfcd_wifi_manager.py
new file mode 100644 (file)
index 0000000..625662f
--- /dev/null
@@ -0,0 +1,217 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3AarfcdWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::AarfcdWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_successk = Attribute("SuccessK",
+            "Multiplication factor for the success threshold in the AARF algorithm.",
+            type = Types.Double,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_successk)
+
+        attr_timerk = Attribute("TimerK",
+            "Multiplication factor for the timer threshold in the AARF algorithm.",
+            type = Types.Double,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_timerk)
+
+        attr_maxsuccessthreshold = Attribute("MaxSuccessThreshold",
+            "Maximum value of the success threshold in the AARF algorithm.",
+            type = Types.Integer,
+            default = "60",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxsuccessthreshold)
+
+        attr_mintimerthreshold = Attribute("MinTimerThreshold",
+            "The minimum value for the \'timer\' threshold in the AARF algorithm.",
+            type = Types.Integer,
+            default = "15",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mintimerthreshold)
+
+        attr_minsuccessthreshold = Attribute("MinSuccessThreshold",
+            "The minimum value for the success threshold in the AARF algorithm.",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minsuccessthreshold)
+
+        attr_minrtswnd = Attribute("MinRtsWnd",
+            "Minimum value for Rts window of Aarf-CD",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minrtswnd)
+
+        attr_maxrtswnd = Attribute("MaxRtsWnd",
+            "Maximum value for Rts window of Aarf-CD",
+            type = Types.Integer,
+            default = "40",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxrtswnd)
+
+        attr_turnoffrtsafterratedecrease = Attribute("TurnOffRtsAfterRateDecrease",
+            "If true the RTS mechanism will be turned off when the rate will be decreased",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_turnoffrtsafterratedecrease)
+
+        attr_turnonrtsafterrateincrease = Attribute("TurnOnRtsAfterRateIncrease",
+            "If true the RTS mechanism will be turned on when the rate will be increased",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_turnonrtsafterrateincrease)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3AarfcdWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-aarfcd-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/adhoc_wifi_mac.py b/src/nepi/resources/ns3/classes/adhoc_wifi_mac.py
new file mode 100644 (file)
index 0000000..a53df07
--- /dev/null
@@ -0,0 +1,209 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifimac import NS3BaseWifiMac 
+
+@clsinit_copy
+class NS3AdhocWifiMac(NS3BaseWifiMac):
+    _rtype = "ns3::AdhocWifiMac"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_qossupported = Attribute("QosSupported",
+            "This Boolean attribute is set to enable 802.11e/WMM-style QoS support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_qossupported)
+
+        attr_htsupported = Attribute("HtSupported",
+            "This Boolean attribute is set to enable 802.11n support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_htsupported)
+
+        attr_ctstoselfsupported = Attribute("CtsToSelfSupported",
+            "Use CTS to Self when using a rate that is not in the basic set rate",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstoselfsupported)
+
+        attr_ctstimeout = Attribute("CtsTimeout",
+            "When this timeout expires, the RTS/CTS handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstimeout)
+
+        attr_acktimeout = Attribute("AckTimeout",
+            "When this timeout expires, the DATA/ACK handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_acktimeout)
+
+        attr_basicblockacktimeout = Attribute("BasicBlockAckTimeout",
+            "When this timeout expires, the BASIC_BLOCK_ACK_REQ/BASIC_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+281000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_basicblockacktimeout)
+
+        attr_compressedblockacktimeout = Attribute("CompressedBlockAckTimeout",
+            "When this timeout expires, the COMPRESSED_BLOCK_ACK_REQ/COMPRESSED_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+107000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_compressedblockacktimeout)
+
+        attr_sifs = Attribute("Sifs",
+            "The value of the SIFS constant.",
+            type = Types.String,
+            default = "+16000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sifs)
+
+        attr_eifsnodifs = Attribute("EifsNoDifs",
+            "The value of EIFS-DIFS",
+            type = Types.String,
+            default = "+60000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_eifsnodifs)
+
+        attr_slot = Attribute("Slot",
+            "The duration of a Slot.",
+            type = Types.String,
+            default = "+9000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_slot)
+
+        attr_pifs = Attribute("Pifs",
+            "The value of the PIFS constant.",
+            type = Types.String,
+            default = "+25000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pifs)
+
+        attr_rifs = Attribute("Rifs",
+            "The value of the RIFS constant.",
+            type = Types.String,
+            default = "+2000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rifs)
+
+        attr_maxpropagationdelay = Attribute("MaxPropagationDelay",
+            "The maximum propagation delay. Unused for now.",
+            type = Types.String,
+            default = "+3333.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpropagationdelay)
+
+        attr_ssid = Attribute("Ssid",
+            "The ssid we want to belong to.",
+            type = Types.String,
+            default = "default",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ssid)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        txokheader = Trace("TxOkHeader", "The header of successfully transmitted packet")
+
+        cls._register_trace(txokheader)
+
+        txerrheader = Trace("TxErrHeader", "The header of unsuccessfully transmitted packet")
+
+        cls._register_trace(txerrheader)
+
+        mactx = Trace("MacTx", "A packet has been received from higher layers and is being processed in preparation for queueing for transmission.")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "A packet has been dropped in the MAC layer before being queued for transmission.")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        macrxdrop = Trace("MacRxDrop", "A packet has been dropped in the MAC layer after it has been passed up from the physical layer.")
+
+        cls._register_trace(macrxdrop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3AdhocWifiMac, self).__init__(ec, guid)
+        self._home = "ns3-adhoc-wifi-mac-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/aloha_noack_net_device.py b/src/nepi/resources/ns3/classes/aloha_noack_net_device.py
new file mode 100644 (file)
index 0000000..b45b431
--- /dev/null
@@ -0,0 +1,77 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3AlohaNoackNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::AlohaNoackNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_address = Attribute("Address",
+            "The MAC address of this device.",
+            type = Types.String,
+            default = "12:34:56:78:90:12",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_address)
+
+        attr_mtu = Attribute("Mtu",
+            "The Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "1500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactx = Trace("MacTx", "Trace source indicating a packet has arrived for transmission by this device")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "Trace source indicating a packet has been dropped by the device before transmission")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3AlohaNoackNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-aloha-noack-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/amrr_wifi_manager.py b/src/nepi/resources/ns3/classes/amrr_wifi_manager.py
new file mode 100644 (file)
index 0000000..dfb13f4
--- /dev/null
@@ -0,0 +1,177 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3AmrrWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::AmrrWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_updateperiod = Attribute("UpdatePeriod",
+            "The interval between decisions about rate control changes",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_updateperiod)
+
+        attr_failureratio = Attribute("FailureRatio",
+            "Ratio of minimum erroneous transmissions needed to switch to a lower rate",
+            type = Types.Double,
+            default = "0.333333",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_failureratio)
+
+        attr_successratio = Attribute("SuccessRatio",
+            "Ratio of maximum erroneous transmissions needed to switch to a higher rate",
+            type = Types.Double,
+            default = "0.1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_successratio)
+
+        attr_maxsuccessthreshold = Attribute("MaxSuccessThreshold",
+            "Maximum number of consecutive success periods needed to switch to a higher rate",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxsuccessthreshold)
+
+        attr_minsuccessthreshold = Attribute("MinSuccessThreshold",
+            "Minimum number of consecutive success periods needed to switch to a higher rate",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minsuccessthreshold)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3AmrrWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-amrr-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/ap_wifi_mac.py b/src/nepi/resources/ns3/classes/ap_wifi_mac.py
new file mode 100644 (file)
index 0000000..8802aa7
--- /dev/null
@@ -0,0 +1,249 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifimac import NS3BaseWifiMac 
+
+@clsinit_copy
+class NS3ApWifiMac(NS3BaseWifiMac):
+    _rtype = "ns3::ApWifiMac"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_beaconinterval = Attribute("BeaconInterval",
+            "Delay between two beacons",
+            type = Types.String,
+            default = "+102400000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_beaconinterval)
+
+        attr_beaconjitter = Attribute("BeaconJitter",
+            "A uniform random variable to cause the initial beacon starting time (after simulation time 0) to be distributed between 0 and the BeaconInterval.",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_beaconjitter)
+
+        attr_enablebeaconjitter = Attribute("EnableBeaconJitter",
+            "If beacons are enabled, whether to jitter the initial send event.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_enablebeaconjitter)
+
+        attr_beacongeneration = Attribute("BeaconGeneration",
+            "Whether or not beacons are generated.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_beacongeneration)
+
+        attr_qossupported = Attribute("QosSupported",
+            "This Boolean attribute is set to enable 802.11e/WMM-style QoS support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_qossupported)
+
+        attr_htsupported = Attribute("HtSupported",
+            "This Boolean attribute is set to enable 802.11n support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_htsupported)
+
+        attr_ctstoselfsupported = Attribute("CtsToSelfSupported",
+            "Use CTS to Self when using a rate that is not in the basic set rate",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstoselfsupported)
+
+        attr_ctstimeout = Attribute("CtsTimeout",
+            "When this timeout expires, the RTS/CTS handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstimeout)
+
+        attr_acktimeout = Attribute("AckTimeout",
+            "When this timeout expires, the DATA/ACK handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_acktimeout)
+
+        attr_basicblockacktimeout = Attribute("BasicBlockAckTimeout",
+            "When this timeout expires, the BASIC_BLOCK_ACK_REQ/BASIC_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+281000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_basicblockacktimeout)
+
+        attr_compressedblockacktimeout = Attribute("CompressedBlockAckTimeout",
+            "When this timeout expires, the COMPRESSED_BLOCK_ACK_REQ/COMPRESSED_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+107000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_compressedblockacktimeout)
+
+        attr_sifs = Attribute("Sifs",
+            "The value of the SIFS constant.",
+            type = Types.String,
+            default = "+16000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sifs)
+
+        attr_eifsnodifs = Attribute("EifsNoDifs",
+            "The value of EIFS-DIFS",
+            type = Types.String,
+            default = "+60000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_eifsnodifs)
+
+        attr_slot = Attribute("Slot",
+            "The duration of a Slot.",
+            type = Types.String,
+            default = "+9000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_slot)
+
+        attr_pifs = Attribute("Pifs",
+            "The value of the PIFS constant.",
+            type = Types.String,
+            default = "+25000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pifs)
+
+        attr_rifs = Attribute("Rifs",
+            "The value of the RIFS constant.",
+            type = Types.String,
+            default = "+2000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rifs)
+
+        attr_maxpropagationdelay = Attribute("MaxPropagationDelay",
+            "The maximum propagation delay. Unused for now.",
+            type = Types.String,
+            default = "+3333.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpropagationdelay)
+
+        attr_ssid = Attribute("Ssid",
+            "The ssid we want to belong to.",
+            type = Types.String,
+            default = "default",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ssid)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        txokheader = Trace("TxOkHeader", "The header of successfully transmitted packet")
+
+        cls._register_trace(txokheader)
+
+        txerrheader = Trace("TxErrHeader", "The header of unsuccessfully transmitted packet")
+
+        cls._register_trace(txerrheader)
+
+        mactx = Trace("MacTx", "A packet has been received from higher layers and is being processed in preparation for queueing for transmission.")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "A packet has been dropped in the MAC layer before being queued for transmission.")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        macrxdrop = Trace("MacRxDrop", "A packet has been dropped in the MAC layer after it has been passed up from the physical layer.")
+
+        cls._register_trace(macrxdrop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ApWifiMac, self).__init__(ec, guid)
+        self._home = "ns3-ap-wifi-mac-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/arf_wifi_manager.py b/src/nepi/resources/ns3/classes/arf_wifi_manager.py
new file mode 100644 (file)
index 0000000..9714846
--- /dev/null
@@ -0,0 +1,147 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3ArfWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::ArfWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_timerthreshold = Attribute("TimerThreshold",
+            "The \'timer\' threshold in the ARF algorithm.",
+            type = Types.Integer,
+            default = "15",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_timerthreshold)
+
+        attr_successthreshold = Attribute("SuccessThreshold",
+            "The minimum number of sucessfull transmissions to try a new rate.",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_successthreshold)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ArfWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-arf-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/arp_l3protocol.py b/src/nepi/resources/ns3/classes/arp_l3protocol.py
new file mode 100644 (file)
index 0000000..d027d52
--- /dev/null
@@ -0,0 +1,55 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3arpl3protocol import NS3BaseArpL3Protocol 
+
+@clsinit_copy
+class NS3ArpL3Protocol(NS3BaseArpL3Protocol):
+    _rtype = "ns3::ArpL3Protocol"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_requestjitter = Attribute("RequestJitter",
+            "The jitter in ms a node is allowed to wait before sending an ARP request. Some jitter aims to prevent collisions. By default, the model will wait for a duration in ms defined by a uniform random-variable between 0 and RequestJitter",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=0.0|Max=10.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_requestjitter)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        drop = Trace("Drop", "Packet dropped because not enough room in pending queue for a specific cache entry.")
+
+        cls._register_trace(drop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ArpL3Protocol, self).__init__(ec, guid)
+        self._home = "ns3-arp-l3protocol-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/base_station_net_device.py b/src/nepi/resources/ns3/classes/base_station_net_device.py
new file mode 100644 (file)
index 0000000..c0130be
--- /dev/null
@@ -0,0 +1,169 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3BaseStationNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::BaseStationNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_initialranginterval = Attribute("InitialRangInterval",
+            "Time between Initial Ranging regions assigned by the BS. Maximum is 2s",
+            type = Types.String,
+            default = "+50000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_initialranginterval)
+
+        attr_dcdinterval = Attribute("DcdInterval",
+            "Time between transmission of DCD messages. Maximum value is 10s.",
+            type = Types.String,
+            default = "+3000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_dcdinterval)
+
+        attr_ucdinterval = Attribute("UcdInterval",
+            "Time between transmission of UCD messages. Maximum value is 10s.",
+            type = Types.String,
+            default = "+3000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ucdinterval)
+
+        attr_intervalt8 = Attribute("IntervalT8",
+            "Wait for DSA/DSC Acknowledge timeout. Maximum 300ms.",
+            type = Types.String,
+            default = "+50000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt8)
+
+        attr_rangreqoppsize = Attribute("RangReqOppSize",
+            "The ranging opportunity size in symbols",
+            type = Types.Integer,
+            default = "8",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rangreqoppsize)
+
+        attr_bwreqoppsize = Attribute("BwReqOppSize",
+            "The bandwidth request opportunity size in symbols",
+            type = Types.Integer,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_bwreqoppsize)
+
+        attr_maxrangcorrectionretries = Attribute("MaxRangCorrectionRetries",
+            "Number of retries on contention Ranging Requests",
+            type = Types.Integer,
+            default = "16",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxrangcorrectionretries)
+
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "1400",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+        attr_rtg = Attribute("RTG",
+            "receive/transmit transition gap.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtg)
+
+        attr_ttg = Attribute("TTG",
+            "transmit/receive transition gap.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ttg)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        bstx = Trace("BSTx", "A packet has been received from higher layers and is being processed in preparation for queueing for transmission.")
+
+        cls._register_trace(bstx)
+
+        bstxdrop = Trace("BSTxDrop", "A packet has been dropped in the MAC layer before being queued for transmission.")
+
+        cls._register_trace(bstxdrop)
+
+        bspromiscrx = Trace("BSPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(bspromiscrx)
+
+        bsrx = Trace("BSRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(bsrx)
+
+        bsrxdrop = Trace("BSRxDrop", "A packet has been dropped in the MAC layer after it has been passed up from the physical layer.")
+
+        cls._register_trace(bsrxdrop)
+
+        rx = Trace("Rx", "Receive trace")
+
+        cls._register_trace(rx)
+
+        tx = Trace("Tx", "Transmit trace")
+
+        cls._register_trace(tx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3BaseStationNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-base-station-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/bridge_channel.py b/src/nepi/resources/ns3/classes/bridge_channel.py
new file mode 100644 (file)
index 0000000..4075f54
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3BridgeChannel(NS3BaseChannel):
+    _rtype = "ns3::BridgeChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3BridgeChannel, self).__init__(ec, guid)
+        self._home = "ns3-bridge-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/bridge_net_device.py b/src/nepi/resources/ns3/classes/bridge_net_device.py
new file mode 100644 (file)
index 0000000..d1313c4
--- /dev/null
@@ -0,0 +1,70 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3BridgeNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::BridgeNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "1500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+        attr_enablelearning = Attribute("EnableLearning",
+            "Enable the learning mode of the Learning Bridge",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_enablelearning)
+
+        attr_expirationtime = Attribute("ExpirationTime",
+            "Time it takes for learned MAC state entry to expire.",
+            type = Types.String,
+            default = "+300000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_expirationtime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3BridgeNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-bridge-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/bulk_send_application.py b/src/nepi/resources/ns3/classes/bulk_send_application.py
new file mode 100644 (file)
index 0000000..f7db2e9
--- /dev/null
@@ -0,0 +1,105 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3BulkSendApplication(NS3BaseApplication):
+    _rtype = "ns3::BulkSendApplication"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_sendsize = Attribute("SendSize",
+            "The amount of data to send each time.",
+            type = Types.Integer,
+            default = "512",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sendsize)
+
+        attr_remote = Attribute("Remote",
+            "The address of the destination",
+            type = Types.String,
+            default = "00-00-00",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remote)
+
+        attr_maxbytes = Attribute("MaxBytes",
+            "The total number of bytes to send. Once these bytes are sent, no data  is sent again. The value zero means that there is no limit.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxbytes)
+
+        attr_protocol = Attribute("Protocol",
+            "The type of protocol to use.",
+            type = Types.String,
+            default = "ns3::TcpSocketFactory",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_protocol)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        tx = Trace("Tx", "A new packet is created and is sent")
+
+        cls._register_trace(tx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3BulkSendApplication, self).__init__(ec, guid)
+        self._home = "ns3-bulk-send-application-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/burst_error_model.py b/src/nepi/resources/ns3/classes/burst_error_model.py
new file mode 100644 (file)
index 0000000..bac2cb0
--- /dev/null
@@ -0,0 +1,80 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3errormodel import NS3BaseErrorModel 
+
+@clsinit_copy
+class NS3BurstErrorModel(NS3BaseErrorModel):
+    _rtype = "ns3::BurstErrorModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_errorrate = Attribute("ErrorRate",
+            "The burst error event.",
+            type = Types.Double,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_errorrate)
+
+        attr_burststart = Attribute("BurstStart",
+            "The decision variable attached to this error model.",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=0.0|Max=1.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_burststart)
+
+        attr_burstsize = Attribute("BurstSize",
+            "The number of packets being corrupted at one drop.",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=1|Max=4]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_burstsize)
+
+        attr_isenabled = Attribute("IsEnabled",
+            "Whether this ErrorModel is enabled or not.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_isenabled)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3BurstErrorModel, self).__init__(ec, guid)
+        self._home = "ns3-burst-error-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/cara_wifi_manager.py b/src/nepi/resources/ns3/classes/cara_wifi_manager.py
new file mode 100644 (file)
index 0000000..8f336f1
--- /dev/null
@@ -0,0 +1,167 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3CaraWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::CaraWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_probethreshold = Attribute("ProbeThreshold",
+            "The number of consecutive transmissions failure to activate the RTS probe.",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_probethreshold)
+
+        attr_failurethreshold = Attribute("FailureThreshold",
+            "The number of consecutive transmissions failure to decrease the rate.",
+            type = Types.Integer,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_failurethreshold)
+
+        attr_successthreshold = Attribute("SuccessThreshold",
+            "The minimum number of sucessfull transmissions to try a new rate.",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_successthreshold)
+
+        attr_timeout = Attribute("Timeout",
+            "The \'timer\' in the CARA algorithm",
+            type = Types.Integer,
+            default = "15",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_timeout)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3CaraWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-cara-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/constant_acceleration_mobility_model.py b/src/nepi/resources/ns3/classes/constant_acceleration_mobility_model.py
new file mode 100644 (file)
index 0000000..662f9e7
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3ConstantAccelerationMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::ConstantAccelerationMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ConstantAccelerationMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-constant-acceleration-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/constant_position_mobility_model.py b/src/nepi/resources/ns3/classes/constant_position_mobility_model.py
new file mode 100644 (file)
index 0000000..03ec389
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3ConstantPositionMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::ConstantPositionMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ConstantPositionMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-constant-position-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/constant_rate_wifi_manager.py b/src/nepi/resources/ns3/classes/constant_rate_wifi_manager.py
new file mode 100644 (file)
index 0000000..decba32
--- /dev/null
@@ -0,0 +1,147 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3ConstantRateWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::ConstantRateWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_datamode = Attribute("DataMode",
+            "The transmission mode to use for every data packet transmission",
+            type = Types.String,
+            default = "OfdmRate6Mbps",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_datamode)
+
+        attr_controlmode = Attribute("ControlMode",
+            "The transmission mode to use for every control packet transmission.",
+            type = Types.String,
+            default = "OfdmRate6Mbps",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_controlmode)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ConstantRateWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-constant-rate-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/constant_speed_propagation_delay_model.py b/src/nepi/resources/ns3/classes/constant_speed_propagation_delay_model.py
new file mode 100644 (file)
index 0000000..9722bd4
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationdelaymodel import NS3BasePropagationDelayModel 
+
+@clsinit_copy
+class NS3ConstantSpeedPropagationDelayModel(NS3BasePropagationDelayModel):
+    _rtype = "ns3::ConstantSpeedPropagationDelayModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_speed = Attribute("Speed",
+            "The speed (m/s)",
+            type = Types.Double,
+            default = "3e+08",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_speed)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3ConstantSpeedPropagationDelayModel, self).__init__(ec, guid)
+        self._home = "ns3-constant-speed-propagation-delay-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/constant_velocity_mobility_model.py b/src/nepi/resources/ns3/classes/constant_velocity_mobility_model.py
new file mode 100644 (file)
index 0000000..e0dfd0f
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3ConstantVelocityMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::ConstantVelocityMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ConstantVelocityMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-constant-velocity-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/cost231propagation_loss_model.py b/src/nepi/resources/ns3/classes/cost231propagation_loss_model.py
new file mode 100644 (file)
index 0000000..2bbbe3d
--- /dev/null
@@ -0,0 +1,90 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3Cost231PropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::Cost231PropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_lambda = Attribute("Lambda",
+            "The wavelength  (default is 2.3 GHz at 300 000 km/s).",
+            type = Types.Double,
+            default = "0.130435",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_lambda)
+
+        attr_frequency = Attribute("Frequency",
+            "The Frequency  (default is 2.3 GHz).",
+            type = Types.Double,
+            default = "2.3e+09",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_frequency)
+
+        attr_bsantennaheight = Attribute("BSAntennaHeight",
+            " BS Antenna Height (default is 50m).",
+            type = Types.Double,
+            default = "50",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_bsantennaheight)
+
+        attr_ssantennaheight = Attribute("SSAntennaHeight",
+            " SS Antenna Height (default is 3m).",
+            type = Types.Double,
+            default = "3",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ssantennaheight)
+
+        attr_mindistance = Attribute("MinDistance",
+            "The distance under which the propagation model refuses to give results (m) ",
+            type = Types.Double,
+            default = "0.5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mindistance)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3Cost231PropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-cost231propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/csma_channel.py b/src/nepi/resources/ns3/classes/csma_channel.py
new file mode 100644 (file)
index 0000000..d839f32
--- /dev/null
@@ -0,0 +1,70 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3CsmaChannel(NS3BaseChannel):
+    _rtype = "ns3::CsmaChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_datarate = Attribute("DataRate",
+            "The transmission data rate to be provided to devices connected to the channel",
+            type = Types.String,
+            default = "4294967295bps",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_datarate)
+
+        attr_delay = Attribute("Delay",
+            "Transmission delay through the channel",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_delay)
+
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3CsmaChannel, self).__init__(ec, guid)
+        self._home = "ns3-csma-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/csma_net_device.py b/src/nepi/resources/ns3/classes/csma_net_device.py
new file mode 100644 (file)
index 0000000..b368b27
--- /dev/null
@@ -0,0 +1,129 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3CsmaNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::CsmaNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_address = Attribute("Address",
+            "The MAC address of this device.",
+            type = Types.String,
+            default = "ff:ff:ff:ff:ff:ff",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_address)
+
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "1500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+        attr_sendenable = Attribute("SendEnable",
+            "Enable or disable the transmitter section of the device.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sendenable)
+
+        attr_receiveenable = Attribute("ReceiveEnable",
+            "Enable or disable the receiver section of the device.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_receiveenable)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactx = Trace("MacTx", "Trace source indicating a packet has arrived for transmission by this device")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "Trace source indicating a packet has been dropped by the device before transmission")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        mactxbackoff = Trace("MacTxBackoff", "Trace source indicating a packet has been delayed by the CSMA backoff process")
+
+        cls._register_trace(mactxbackoff)
+
+        phytxbegin = Trace("PhyTxBegin", "Trace source indicating a packet has begun transmitting over the channel")
+
+        cls._register_trace(phytxbegin)
+
+        phytxend = Trace("PhyTxEnd", "Trace source indicating a packet has been completely transmitted over the channel")
+
+        cls._register_trace(phytxend)
+
+        phytxdrop = Trace("PhyTxDrop", "Trace source indicating a packet has been dropped by the device during transmission")
+
+        cls._register_trace(phytxdrop)
+
+        phyrxend = Trace("PhyRxEnd", "Trace source indicating a packet has been completely received by the device")
+
+        cls._register_trace(phyrxend)
+
+        phyrxdrop = Trace("PhyRxDrop", "Trace source indicating a packet has been dropped by the device during reception")
+
+        cls._register_trace(phyrxdrop)
+
+        sniffer = Trace("Sniffer", "Trace source simulating a non-promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(sniffer)
+
+        promiscsniffer = Trace("PromiscSniffer", "Trace source simulating a promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(promiscsniffer)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3CsmaNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-csma-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/drop_tail_queue.py b/src/nepi/resources/ns3/classes/drop_tail_queue.py
new file mode 100644 (file)
index 0000000..550d925
--- /dev/null
@@ -0,0 +1,73 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3queue import NS3BaseQueue 
+
+@clsinit_copy
+class NS3DropTailQueue(NS3BaseQueue):
+    _rtype = "ns3::DropTailQueue"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxpackets = Attribute("MaxPackets",
+            "The maximum number of packets accepted by this DropTailQueue.",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpackets)
+
+        attr_maxbytes = Attribute("MaxBytes",
+            "The maximum number of bytes accepted by this DropTailQueue.",
+            type = Types.Integer,
+            default = "6553500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxbytes)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        enqueue = Trace("Enqueue", "Enqueue a packet in the queue.")
+
+        cls._register_trace(enqueue)
+
+        dequeue = Trace("Dequeue", "Dequeue a packet from the queue.")
+
+        cls._register_trace(dequeue)
+
+        drop = Trace("Drop", "Drop a packet stored in the queue.")
+
+        cls._register_trace(drop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3DropTailQueue, self).__init__(ec, guid)
+        self._home = "ns3-drop-tail-queue-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/emu_net_device.py b/src/nepi/resources/ns3/classes/emu_net_device.py
new file mode 100644 (file)
index 0000000..09a81c5
--- /dev/null
@@ -0,0 +1,125 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3EmuNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::EmuNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+        attr_address = Attribute("Address",
+            "The ns-3 MAC address of this (virtual) device.",
+            type = Types.String,
+            default = "ff:ff:ff:ff:ff:ff",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_address)
+
+        attr_devicename = Attribute("DeviceName",
+            "The name of the underlying real device (e.g. eth1).",
+            type = Types.String,
+            default = "eth1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_devicename)
+
+        attr_start = Attribute("Start",
+            "The simulation time at which to spin up the device thread.",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_start)
+
+        attr_stop = Attribute("Stop",
+            "The simulation time at which to tear down the device thread.",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stop)
+
+        attr_rxqueuesize = Attribute("RxQueueSize",
+            "Maximum size of the read queue.  This value limits number of packets that have been read from the network into a memory buffer but have not yet been processed by the simulator.",
+            type = Types.Integer,
+            default = "1000",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rxqueuesize)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactx = Trace("MacTx", "Trace source indicating a packet has arrived for transmission by this device")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "Trace source indicating a packet has been dropped by the device before transmission")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        sniffer = Trace("Sniffer", "Trace source simulating a non-promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(sniffer)
+
+        promiscsniffer = Trace("PromiscSniffer", "Trace source simulating a promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(promiscsniffer)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3EmuNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-emu-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/error_channel.py b/src/nepi/resources/ns3/classes/error_channel.py
new file mode 100644 (file)
index 0000000..1a9e2ad
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3ErrorChannel(NS3BaseChannel):
+    _rtype = "ns3::ErrorChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3ErrorChannel, self).__init__(ec, guid)
+        self._home = "ns3-error-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/error_net_device.py b/src/nepi/resources/ns3/classes/error_net_device.py
new file mode 100644 (file)
index 0000000..7b59ba8
--- /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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3ErrorNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::ErrorNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        
+        phyrxdrop = Trace("PhyRxDrop", "Trace source indicating a packet has been dropped by the device during reception")
+
+        cls._register_trace(phyrxdrop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3ErrorNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-error-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/fd_net_device.py b/src/nepi/resources/ns3/classes/fd_net_device.py
new file mode 100644 (file)
index 0000000..62fc602
--- /dev/null
@@ -0,0 +1,115 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3FdNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::FdNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_address = Attribute("Address",
+            "The MAC address of this device.",
+            type = Types.String,
+            default = "ff:ff:ff:ff:ff:ff",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_address)
+
+        attr_start = Attribute("Start",
+            "The simulation time at which to spin up the device thread.",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_start)
+
+        attr_stop = Attribute("Stop",
+            "The simulation time at which to tear down the device thread.",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stop)
+
+        attr_encapsulationmode = Attribute("EncapsulationMode",
+            "The link-layer encapsulation type to use.",
+            type = Types.Enumerate,
+            default = "Dix",  
+            allowed = ["Dix","Llc","DixPi"],
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_encapsulationmode)
+
+        attr_rxqueuesize = Attribute("RxQueueSize",
+            "Maximum size of the read queue.  This value limits number of packets that have been read from the network into a memory buffer but have not yet been processed by the simulator.",
+            type = Types.Integer,
+            default = "1000",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rxqueuesize)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactx = Trace("MacTx", "Trace source indicating a packet has arrived for transmission by this device")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "Trace source indicating a packet has been dropped by the device before transmission")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        sniffer = Trace("Sniffer", "Trace source simulating a non-promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(sniffer)
+
+        promiscsniffer = Trace("PromiscSniffer", "Trace source simulating a promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(promiscsniffer)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3FdNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-fd-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/fixed_rss_loss_model.py b/src/nepi/resources/ns3/classes/fixed_rss_loss_model.py
new file mode 100644 (file)
index 0000000..518b4c5
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3FixedRssLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::FixedRssLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_rss = Attribute("Rss",
+            "The fixed receiver Rss.",
+            type = Types.Double,
+            default = "-150",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rss)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3FixedRssLossModel, self).__init__(ec, guid)
+        self._home = "ns3-fixed-rss-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/friis_propagation_loss_model.py b/src/nepi/resources/ns3/classes/friis_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..54d2d4f
--- /dev/null
@@ -0,0 +1,70 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3FriisPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::FriisPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_frequency = Attribute("Frequency",
+            "The carrier frequency (in Hz) at which propagation occurs  (default is 5.15 GHz).",
+            type = Types.Double,
+            default = "5.15e+09",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_frequency)
+
+        attr_systemloss = Attribute("SystemLoss",
+            "The system loss",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_systemloss)
+
+        attr_mindistance = Attribute("MinDistance",
+            "The distance under which the propagation model refuses to give results (m)",
+            type = Types.Double,
+            default = "0.5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mindistance)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3FriisPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-friis-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/gauss_markov_mobility_model.py b/src/nepi/resources/ns3/classes/gauss_markov_mobility_model.py
new file mode 100644 (file)
index 0000000..1d380a7
--- /dev/null
@@ -0,0 +1,155 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3GaussMarkovMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::GaussMarkovMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_bounds = Attribute("Bounds",
+            "Bounds of the area to cruise.",
+            type = Types.String,
+            default = "-100|100|-100|100|0|100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_bounds)
+
+        attr_timestep = Attribute("TimeStep",
+            "Change current direction and speed after moving for this time.",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_timestep)
+
+        attr_alpha = Attribute("Alpha",
+            "A constant representing the tunable parameter in the Gauss-Markov model.",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_alpha)
+
+        attr_meanvelocity = Attribute("MeanVelocity",
+            "A random variable used to assign the average velocity.",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=0.0|Max=1.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_meanvelocity)
+
+        attr_meandirection = Attribute("MeanDirection",
+            "A random variable used to assign the average direction.",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=0.0|Max=6.283185307]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_meandirection)
+
+        attr_meanpitch = Attribute("MeanPitch",
+            "A random variable used to assign the average pitch.",
+            type = Types.String,
+            default = "ns3::ConstantRandomVariable[Constant=0.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_meanpitch)
+
+        attr_normalvelocity = Attribute("NormalVelocity",
+            "A gaussian random variable used to calculate the next velocity value.",
+            type = Types.String,
+            default = "ns3::NormalRandomVariable[Mean=0.0|Variance=1.0|Bound=10.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_normalvelocity)
+
+        attr_normaldirection = Attribute("NormalDirection",
+            "A gaussian random variable used to calculate the next direction value.",
+            type = Types.String,
+            default = "ns3::NormalRandomVariable[Mean=0.0|Variance=1.0|Bound=10.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_normaldirection)
+
+        attr_normalpitch = Attribute("NormalPitch",
+            "A gaussian random variable used to calculate the next pitch value.",
+            type = Types.String,
+            default = "ns3::NormalRandomVariable[Mean=0.0|Variance=1.0|Bound=10.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_normalpitch)
+
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3GaussMarkovMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-gauss-markov-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/hierarchical_mobility_model.py b/src/nepi/resources/ns3/classes/hierarchical_mobility_model.py
new file mode 100644 (file)
index 0000000..97ce062
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3HierarchicalMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::HierarchicalMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3HierarchicalMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-hierarchical-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/hybrid_buildings_propagation_loss_model.py b/src/nepi/resources/ns3/classes/hybrid_buildings_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..26c12a9
--- /dev/null
@@ -0,0 +1,90 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3HybridBuildingsPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::HybridBuildingsPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_los2nlosthr = Attribute("Los2NlosThr",
+            " Threshold from LoS to NLoS in ITU 1411 [m].",
+            type = Types.Double,
+            default = "200",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_los2nlosthr)
+
+        attr_shadowsigmaoutdoor = Attribute("ShadowSigmaOutdoor",
+            "Standard deviation of the normal distribution used for calculate the shadowing for outdoor nodes",
+            type = Types.Double,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_shadowsigmaoutdoor)
+
+        attr_shadowsigmaindoor = Attribute("ShadowSigmaIndoor",
+            "Standard deviation of the normal distribution used for calculate the shadowing for indoor nodes ",
+            type = Types.Double,
+            default = "8",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_shadowsigmaindoor)
+
+        attr_shadowsigmaextwalls = Attribute("ShadowSigmaExtWalls",
+            "Standard deviation of the normal distribution used for calculate the shadowing due to ext walls ",
+            type = Types.Double,
+            default = "5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_shadowsigmaextwalls)
+
+        attr_internalwallloss = Attribute("InternalWallLoss",
+            "Additional loss for each internal wall [dB]",
+            type = Types.Double,
+            default = "5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_internalwallloss)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3HybridBuildingsPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-hybrid-buildings-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/icmpv4l4protocol.py b/src/nepi/resources/ns3/classes/icmpv4l4protocol.py
new file mode 100644 (file)
index 0000000..202137f
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3icmpv4l4protocol import NS3BaseIcmpv4L4Protocol 
+
+@clsinit_copy
+class NS3Icmpv4L4Protocol(NS3BaseIcmpv4L4Protocol):
+    _rtype = "ns3::Icmpv4L4Protocol"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_protocolnumber = Attribute("ProtocolNumber",
+            "The Ip protocol number.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_protocolnumber)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3Icmpv4L4Protocol, self).__init__(ec, guid)
+        self._home = "ns3-icmpv4l4protocol-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/ideal_wifi_manager.py b/src/nepi/resources/ns3/classes/ideal_wifi_manager.py
new file mode 100644 (file)
index 0000000..e384184
--- /dev/null
@@ -0,0 +1,137 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3IdealWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::IdealWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_berthreshold = Attribute("BerThreshold",
+            "The maximum Bit Error Rate acceptable at any transmission mode",
+            type = Types.Double,
+            default = "1e-05",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_berthreshold)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3IdealWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-ideal-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/ipv4l3protocol.py b/src/nepi/resources/ns3/classes/ipv4l3protocol.py
new file mode 100644 (file)
index 0000000..8c7228d
--- /dev/null
@@ -0,0 +1,115 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3ipv4l3protocol import NS3BaseIpv4L3Protocol 
+
+@clsinit_copy
+class NS3Ipv4L3Protocol(NS3BaseIpv4L3Protocol):
+    _rtype = "ns3::Ipv4L3Protocol"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_defaulttos = Attribute("DefaultTos",
+            "The TOS value set by default on all outgoing packets generated on this node.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttos)
+
+        attr_defaultttl = Attribute("DefaultTtl",
+            "The TTL value set by default on all outgoing packets generated on this node.",
+            type = Types.Integer,
+            default = "64",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaultttl)
+
+        attr_fragmentexpirationtimeout = Attribute("FragmentExpirationTimeout",
+            "When this timeout expires, the fragments will be cleared from the buffer.",
+            type = Types.String,
+            default = "+30000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentexpirationtimeout)
+
+        attr_ipforward = Attribute("IpForward",
+            "Globally enable or disable IP forwarding for all current and future Ipv4 devices.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ipforward)
+
+        attr_weakesmodel = Attribute("WeakEsModel",
+            "RFC1122 term for whether host accepts datagram with a dest. address on another interface",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_weakesmodel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        tx = Trace("Tx", "Send ipv4 packet to outgoing interface.")
+
+        cls._register_trace(tx)
+
+        rx = Trace("Rx", "Receive ipv4 packet from incoming interface.")
+
+        cls._register_trace(rx)
+
+        drop = Trace("Drop", "Drop ipv4 packet")
+
+        cls._register_trace(drop)
+
+        sendoutgoing = Trace("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission")
+
+        cls._register_trace(sendoutgoing)
+
+        unicastforward = Trace("UnicastForward", "A unicast IPv4 packet was received by this node and is being forwarded to another node")
+
+        cls._register_trace(unicastforward)
+
+        localdeliver = Trace("LocalDeliver", "An IPv4 packet was received by/for this node, and it is being forward up the stack")
+
+        cls._register_trace(localdeliver)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3Ipv4L3Protocol, self).__init__(ec, guid)
+        self._home = "ns3-ipv4l3protocol-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/jakes_propagation_loss_model.py b/src/nepi/resources/ns3/classes/jakes_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..af4729c
--- /dev/null
@@ -0,0 +1,39 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3JakesPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::JakesPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3JakesPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-jakes-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/list_error_model.py b/src/nepi/resources/ns3/classes/list_error_model.py
new file mode 100644 (file)
index 0000000..a607117
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3errormodel import NS3BaseErrorModel 
+
+@clsinit_copy
+class NS3ListErrorModel(NS3BaseErrorModel):
+    _rtype = "ns3::ListErrorModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_isenabled = Attribute("IsEnabled",
+            "Whether this ErrorModel is enabled or not.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_isenabled)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3ListErrorModel, self).__init__(ec, guid)
+        self._home = "ns3-list-error-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/log_distance_propagation_loss_model.py b/src/nepi/resources/ns3/classes/log_distance_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..5f3c5fd
--- /dev/null
@@ -0,0 +1,70 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3LogDistancePropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::LogDistancePropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_exponent = Attribute("Exponent",
+            "The exponent of the Path Loss propagation model",
+            type = Types.Double,
+            default = "3",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_exponent)
+
+        attr_referencedistance = Attribute("ReferenceDistance",
+            "The distance at which the reference loss is calculated (m)",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_referencedistance)
+
+        attr_referenceloss = Attribute("ReferenceLoss",
+            "The reference loss at reference distance (dB). (Default is Friis at 1m with 5.15 GHz)",
+            type = Types.Double,
+            default = "46.6777",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_referenceloss)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3LogDistancePropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-log-distance-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/loopback_net_device.py b/src/nepi/resources/ns3/classes/loopback_net_device.py
new file mode 100644 (file)
index 0000000..a9e6162
--- /dev/null
@@ -0,0 +1,39 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3LoopbackNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::LoopbackNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3LoopbackNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-loopback-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/lte_enb_net_device.py b/src/nepi/resources/ns3/classes/lte_enb_net_device.py
new file mode 100644 (file)
index 0000000..f1ac832
--- /dev/null
@@ -0,0 +1,100 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3LteEnbNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::LteEnbNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_ulbandwidth = Attribute("UlBandwidth",
+            "Uplink Transmission Bandwidth Configuration in number of Resource Blocks",
+            type = Types.Integer,
+            default = "25",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ulbandwidth)
+
+        attr_dlbandwidth = Attribute("DlBandwidth",
+            "Downlink Transmission Bandwidth Configuration in number of Resource Blocks",
+            type = Types.Integer,
+            default = "25",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_dlbandwidth)
+
+        attr_cellid = Attribute("CellId",
+            "Cell Identifier",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_cellid)
+
+        attr_dlearfcn = Attribute("DlEarfcn",
+            "Downlink E-UTRA Absolute Radio Frequency Channel Number (EARFCN) as per 3GPP 36.101 Section 5.7.3. ",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_dlearfcn)
+
+        attr_ulearfcn = Attribute("UlEarfcn",
+            "Uplink E-UTRA Absolute Radio Frequency Channel Number (EARFCN) as per 3GPP 36.101 Section 5.7.3. ",
+            type = Types.Integer,
+            default = "18100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ulearfcn)
+
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "30000",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3LteEnbNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-lte-enb-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/lte_simple_net_device.py b/src/nepi/resources/ns3/classes/lte_simple_net_device.py
new file mode 100644 (file)
index 0000000..b38a7e9
--- /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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3LteSimpleNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::LteSimpleNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        
+        phyrxdrop = Trace("PhyRxDrop", "Trace source indicating a packet has been dropped by the device during reception")
+
+        cls._register_trace(phyrxdrop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3LteSimpleNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-lte-simple-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/matrix_propagation_loss_model.py b/src/nepi/resources/ns3/classes/matrix_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..4d14e14
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3MatrixPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::MatrixPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_defaultloss = Attribute("DefaultLoss",
+            "The default value for propagation loss, dB.",
+            type = Types.Double,
+            default = "1.79769e+308",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaultloss)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3MatrixPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-matrix-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/mesh_point_device.py b/src/nepi/resources/ns3/classes/mesh_point_device.py
new file mode 100644 (file)
index 0000000..945952a
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3MeshPointDevice(NS3BaseNetDevice):
+    _rtype = "ns3::MeshPointDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "65535",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3MeshPointDevice, self).__init__(ec, guid)
+        self._home = "ns3-mesh-point-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/mesh_wifi_interface_mac.py b/src/nepi/resources/ns3/classes/mesh_wifi_interface_mac.py
new file mode 100644 (file)
index 0000000..b736081
--- /dev/null
@@ -0,0 +1,239 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifimac import NS3BaseWifiMac 
+
+@clsinit_copy
+class NS3MeshWifiInterfaceMac(NS3BaseWifiMac):
+    _rtype = "ns3::MeshWifiInterfaceMac"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_beaconinterval = Attribute("BeaconInterval",
+            "Beacon Interval",
+            type = Types.String,
+            default = "+500000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_beaconinterval)
+
+        attr_randomstart = Attribute("RandomStart",
+            "Window when beacon generating starts (uniform random) in seconds",
+            type = Types.String,
+            default = "+500000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_randomstart)
+
+        attr_beacongeneration = Attribute("BeaconGeneration",
+            "Enable/Disable Beaconing.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_beacongeneration)
+
+        attr_qossupported = Attribute("QosSupported",
+            "This Boolean attribute is set to enable 802.11e/WMM-style QoS support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_qossupported)
+
+        attr_htsupported = Attribute("HtSupported",
+            "This Boolean attribute is set to enable 802.11n support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_htsupported)
+
+        attr_ctstoselfsupported = Attribute("CtsToSelfSupported",
+            "Use CTS to Self when using a rate that is not in the basic set rate",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstoselfsupported)
+
+        attr_ctstimeout = Attribute("CtsTimeout",
+            "When this timeout expires, the RTS/CTS handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstimeout)
+
+        attr_acktimeout = Attribute("AckTimeout",
+            "When this timeout expires, the DATA/ACK handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_acktimeout)
+
+        attr_basicblockacktimeout = Attribute("BasicBlockAckTimeout",
+            "When this timeout expires, the BASIC_BLOCK_ACK_REQ/BASIC_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+281000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_basicblockacktimeout)
+
+        attr_compressedblockacktimeout = Attribute("CompressedBlockAckTimeout",
+            "When this timeout expires, the COMPRESSED_BLOCK_ACK_REQ/COMPRESSED_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+107000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_compressedblockacktimeout)
+
+        attr_sifs = Attribute("Sifs",
+            "The value of the SIFS constant.",
+            type = Types.String,
+            default = "+16000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sifs)
+
+        attr_eifsnodifs = Attribute("EifsNoDifs",
+            "The value of EIFS-DIFS",
+            type = Types.String,
+            default = "+60000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_eifsnodifs)
+
+        attr_slot = Attribute("Slot",
+            "The duration of a Slot.",
+            type = Types.String,
+            default = "+9000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_slot)
+
+        attr_pifs = Attribute("Pifs",
+            "The value of the PIFS constant.",
+            type = Types.String,
+            default = "+25000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pifs)
+
+        attr_rifs = Attribute("Rifs",
+            "The value of the RIFS constant.",
+            type = Types.String,
+            default = "+2000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rifs)
+
+        attr_maxpropagationdelay = Attribute("MaxPropagationDelay",
+            "The maximum propagation delay. Unused for now.",
+            type = Types.String,
+            default = "+3333.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpropagationdelay)
+
+        attr_ssid = Attribute("Ssid",
+            "The ssid we want to belong to.",
+            type = Types.String,
+            default = "default",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ssid)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        txokheader = Trace("TxOkHeader", "The header of successfully transmitted packet")
+
+        cls._register_trace(txokheader)
+
+        txerrheader = Trace("TxErrHeader", "The header of unsuccessfully transmitted packet")
+
+        cls._register_trace(txerrheader)
+
+        mactx = Trace("MacTx", "A packet has been received from higher layers and is being processed in preparation for queueing for transmission.")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "A packet has been dropped in the MAC layer before being queued for transmission.")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        macrxdrop = Trace("MacRxDrop", "A packet has been dropped in the MAC layer after it has been passed up from the physical layer.")
+
+        cls._register_trace(macrxdrop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3MeshWifiInterfaceMac, self).__init__(ec, guid)
+        self._home = "ns3-mesh-wifi-interface-mac-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/minstrel_wifi_manager.py b/src/nepi/resources/ns3/classes/minstrel_wifi_manager.py
new file mode 100644 (file)
index 0000000..3818645
--- /dev/null
@@ -0,0 +1,177 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3MinstrelWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::MinstrelWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_updatestatistics = Attribute("UpdateStatistics",
+            "The interval between updating statistics table ",
+            type = Types.String,
+            default = "+100000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_updatestatistics)
+
+        attr_lookaroundrate = Attribute("LookAroundRate",
+            "the percentage to try other rates",
+            type = Types.Double,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_lookaroundrate)
+
+        attr_ewma = Attribute("EWMA",
+            "EWMA level",
+            type = Types.Double,
+            default = "75",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewma)
+
+        attr_samplecolumn = Attribute("SampleColumn",
+            "The number of columns used for sampling",
+            type = Types.Double,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_samplecolumn)
+
+        attr_packetlength = Attribute("PacketLength",
+            "The packet length used for calculating mode TxTime",
+            type = Types.Double,
+            default = "1200",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_packetlength)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3MinstrelWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-minstrel-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/multi_model_spectrum_channel.py b/src/nepi/resources/ns3/classes/multi_model_spectrum_channel.py
new file mode 100644 (file)
index 0000000..c8d6e64
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3MultiModelSpectrumChannel(NS3BaseChannel):
+    _rtype = "ns3::MultiModelSpectrumChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxlossdb = Attribute("MaxLossDb",
+            "If a single-frequency PropagationLossModel is used, this value represents the maximum loss in dB for which transmissions will be passed to the receiving PHY. Signals for which the PropagationLossModel returns a loss bigger than this value will not be propagated to the receiver. This parameter is to be used to reduce the computational load by not propagating signals that are far beyond the interference range. Note that the default value corresponds to considering all signals for reception. Tune this value with care. ",
+            type = Types.Double,
+            default = "1e+09",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxlossdb)
+
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        pathloss = Trace("PathLoss", "This trace is fired whenever a new path loss value is calculated. The first and second parameters to the trace are pointers respectively to the TX and RX SpectrumPhy instances, whereas the third parameters is the loss value in dB. Note that the loss value reported by this trace is the single-frequency loss value obtained by evaluating only the TX and RX AntennaModels and the PropagationLossModel. In particular, note that SpectrumPropagationLossModel (even if present) is never used to evaluate the loss value reported in this trace. ")
+
+        cls._register_trace(pathloss)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3MultiModelSpectrumChannel, self).__init__(ec, guid)
+        self._home = "ns3-multi-model-spectrum-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/nakagami_propagation_loss_model.py b/src/nepi/resources/ns3/classes/nakagami_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..371a895
--- /dev/null
@@ -0,0 +1,110 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3NakagamiPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::NakagamiPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_distance1 = Attribute("Distance1",
+            "Beginning of the second distance field. Default is 80m.",
+            type = Types.Double,
+            default = "80",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_distance1)
+
+        attr_distance2 = Attribute("Distance2",
+            "Beginning of the third distance field. Default is 200m.",
+            type = Types.Double,
+            default = "200",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_distance2)
+
+        attr_m0 = Attribute("m0",
+            "m0 for distances smaller than Distance1. Default is 1.5.",
+            type = Types.Double,
+            default = "1.5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_m0)
+
+        attr_m1 = Attribute("m1",
+            "m1 for distances smaller than Distance2. Default is 0.75.",
+            type = Types.Double,
+            default = "0.75",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_m1)
+
+        attr_m2 = Attribute("m2",
+            "m2 for distances greater than Distance2. Default is 0.75.",
+            type = Types.Double,
+            default = "0.75",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_m2)
+
+        attr_erlangrv = Attribute("ErlangRv",
+            "Access to the underlying ErlangRandomVariable",
+            type = Types.String,
+            default = "ns3::ErlangRandomVariable",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_erlangrv)
+
+        attr_gammarv = Attribute("GammaRv",
+            "Access to the underlying GammaRandomVariable",
+            type = Types.String,
+            default = "ns3::GammaRandomVariable",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_gammarv)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3NakagamiPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-nakagami-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/nist_error_rate_model.py b/src/nepi/resources/ns3/classes/nist_error_rate_model.py
new file mode 100644 (file)
index 0000000..5a433b4
--- /dev/null
@@ -0,0 +1,39 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3errorratemodel import NS3BaseErrorRateModel 
+
+@clsinit_copy
+class NS3NistErrorRateModel(NS3BaseErrorRateModel):
+    _rtype = "ns3::NistErrorRateModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3NistErrorRateModel, self).__init__(ec, guid)
+        self._home = "ns3-nist-error-rate-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/node.py b/src/nepi/resources/ns3/classes/node.py
new file mode 100644 (file)
index 0000000..f758192
--- /dev/null
@@ -0,0 +1,60 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3node import NS3BaseNode 
+
+@clsinit_copy
+class NS3Node(NS3BaseNode):
+    _rtype = "ns3::Node"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Node.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+        attr_systemid = Attribute("SystemId",
+            "The systemId of this node: a unique integer used for parallel simulations.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_systemid)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3Node, self).__init__(ec, guid)
+        self._home = "ns3-node-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/non_communicating_net_device.py b/src/nepi/resources/ns3/classes/non_communicating_net_device.py
new file mode 100644 (file)
index 0000000..4fb08e7
--- /dev/null
@@ -0,0 +1,39 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3NonCommunicatingNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::NonCommunicatingNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3NonCommunicatingNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-non-communicating-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/oh_buildings_propagation_loss_model.py b/src/nepi/resources/ns3/classes/oh_buildings_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..530d9ae
--- /dev/null
@@ -0,0 +1,80 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3OhBuildingsPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::OhBuildingsPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_shadowsigmaoutdoor = Attribute("ShadowSigmaOutdoor",
+            "Standard deviation of the normal distribution used for calculate the shadowing for outdoor nodes",
+            type = Types.Double,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_shadowsigmaoutdoor)
+
+        attr_shadowsigmaindoor = Attribute("ShadowSigmaIndoor",
+            "Standard deviation of the normal distribution used for calculate the shadowing for indoor nodes ",
+            type = Types.Double,
+            default = "8",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_shadowsigmaindoor)
+
+        attr_shadowsigmaextwalls = Attribute("ShadowSigmaExtWalls",
+            "Standard deviation of the normal distribution used for calculate the shadowing due to ext walls ",
+            type = Types.Double,
+            default = "5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_shadowsigmaextwalls)
+
+        attr_internalwallloss = Attribute("InternalWallLoss",
+            "Additional loss for each internal wall [dB]",
+            type = Types.Double,
+            default = "5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_internalwallloss)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3OhBuildingsPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-oh-buildings-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/on_off_application.py b/src/nepi/resources/ns3/classes/on_off_application.py
new file mode 100644 (file)
index 0000000..ffae8e9
--- /dev/null
@@ -0,0 +1,135 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3OnOffApplication(NS3BaseApplication):
+    _rtype = "ns3::OnOffApplication"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_datarate = Attribute("DataRate",
+            "The data rate in on state.",
+            type = Types.String,
+            default = "500000bps",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_datarate)
+
+        attr_packetsize = Attribute("PacketSize",
+            "The size of packets sent in on state",
+            type = Types.Integer,
+            default = "512",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_packetsize)
+
+        attr_remote = Attribute("Remote",
+            "The address of the destination",
+            type = Types.String,
+            default = "00-00-00",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remote)
+
+        attr_ontime = Attribute("OnTime",
+            "A RandomVariableStream used to pick the duration of the \'On\' state.",
+            type = Types.String,
+            default = "ns3::ConstantRandomVariable[Constant=1.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ontime)
+
+        attr_offtime = Attribute("OffTime",
+            "A RandomVariableStream used to pick the duration of the \'Off\' state.",
+            type = Types.String,
+            default = "ns3::ConstantRandomVariable[Constant=1.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_offtime)
+
+        attr_maxbytes = Attribute("MaxBytes",
+            "The total number of bytes to send. Once these bytes are sent, no packet is sent again, even in on state. The value zero means that there is no limit.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxbytes)
+
+        attr_protocol = Attribute("Protocol",
+            "The type of protocol to use.",
+            type = Types.String,
+            default = "ns3::UdpSocketFactory",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_protocol)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        tx = Trace("Tx", "A new packet is created and is sent")
+
+        cls._register_trace(tx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3OnOffApplication, self).__init__(ec, guid)
+        self._home = "ns3-on-off-application-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/onoe_wifi_manager.py b/src/nepi/resources/ns3/classes/onoe_wifi_manager.py
new file mode 100644 (file)
index 0000000..606b3e8
--- /dev/null
@@ -0,0 +1,157 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3OnoeWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::OnoeWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_updateperiod = Attribute("UpdatePeriod",
+            "The interval between decisions about rate control changes",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_updateperiod)
+
+        attr_raisethreshold = Attribute("RaiseThreshold",
+            "Attempt to raise the rate if we hit that threshold",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_raisethreshold)
+
+        attr_addcreditthreshold = Attribute("AddCreditThreshold",
+            "Add credit threshold",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_addcreditthreshold)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3OnoeWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-onoe-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/packet_sink.py b/src/nepi/resources/ns3/classes/packet_sink.py
new file mode 100644 (file)
index 0000000..701c8d0
--- /dev/null
@@ -0,0 +1,85 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3PacketSink(NS3BaseApplication):
+    _rtype = "ns3::PacketSink"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_local = Attribute("Local",
+            "The Address on which to Bind the rx socket.",
+            type = Types.String,
+            default = "00-00-00",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_local)
+
+        attr_protocol = Attribute("Protocol",
+            "The type id of the protocol to use for the rx socket.",
+            type = Types.String,
+            default = "ns3::UdpSocketFactory",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_protocol)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        rx = Trace("Rx", "A packet has been received")
+
+        cls._register_trace(rx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3PacketSink, self).__init__(ec, guid)
+        self._home = "ns3-packet-sink-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/ping6.py b/src/nepi/resources/ns3/classes/ping6.py
new file mode 100644 (file)
index 0000000..7986532
--- /dev/null
@@ -0,0 +1,110 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3Ping6(NS3BaseApplication):
+    _rtype = "ns3::Ping6"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxpackets = Attribute("MaxPackets",
+            "The maximum number of packets the application will send",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpackets)
+
+        attr_interval = Attribute("Interval",
+            "The time to wait between packets",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_interval)
+
+        attr_remoteipv6 = Attribute("RemoteIpv6",
+            "The Ipv6Address of the outbound packets",
+            type = Types.String,
+            default = "0000:0000:0000:0000:0000:0000:0000:0000",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remoteipv6)
+
+        attr_localipv6 = Attribute("LocalIpv6",
+            "Local Ipv6Address of the sender",
+            type = Types.String,
+            default = "0000:0000:0000:0000:0000:0000:0000:0000",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_localipv6)
+
+        attr_packetsize = Attribute("PacketSize",
+            "Size of packets generated",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_packetsize)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3Ping6, self).__init__(ec, guid)
+        self._home = "ns3-ping6-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/point_to_point_channel.py b/src/nepi/resources/ns3/classes/point_to_point_channel.py
new file mode 100644 (file)
index 0000000..e943fc7
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3PointToPointChannel(NS3BaseChannel):
+    _rtype = "ns3::PointToPointChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_delay = Attribute("Delay",
+            "Transmission delay through the channel",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_delay)
+
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        txrxpointtopoint = Trace("TxRxPointToPoint", "Trace source indicating transmission of packet from the PointToPointChannel, used by the Animation interface.")
+
+        cls._register_trace(txrxpointtopoint)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3PointToPointChannel, self).__init__(ec, guid)
+        self._home = "ns3-point-to-point-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/point_to_point_net_device.py b/src/nepi/resources/ns3/classes/point_to_point_net_device.py
new file mode 100644 (file)
index 0000000..699a785
--- /dev/null
@@ -0,0 +1,125 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3PointToPointNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::PointToPointNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "1500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+        attr_address = Attribute("Address",
+            "The MAC address of this device.",
+            type = Types.String,
+            default = "ff:ff:ff:ff:ff:ff",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_address)
+
+        attr_datarate = Attribute("DataRate",
+            "The default data rate for point to point links",
+            type = Types.String,
+            default = "32768bps",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_datarate)
+
+        attr_interframegap = Attribute("InterframeGap",
+            "The time to wait between packet (frame) transmissions",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_interframegap)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactx = Trace("MacTx", "Trace source indicating a packet has arrived for transmission by this device")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "Trace source indicating a packet has been dropped by the device before transmission")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        phytxbegin = Trace("PhyTxBegin", "Trace source indicating a packet has begun transmitting over the channel")
+
+        cls._register_trace(phytxbegin)
+
+        phytxend = Trace("PhyTxEnd", "Trace source indicating a packet has been completely transmitted over the channel")
+
+        cls._register_trace(phytxend)
+
+        phytxdrop = Trace("PhyTxDrop", "Trace source indicating a packet has been dropped by the device during transmission")
+
+        cls._register_trace(phytxdrop)
+
+        phyrxend = Trace("PhyRxEnd", "Trace source indicating a packet has been completely received by the device")
+
+        cls._register_trace(phyrxend)
+
+        phyrxdrop = Trace("PhyRxDrop", "Trace source indicating a packet has been dropped by the device during reception")
+
+        cls._register_trace(phyrxdrop)
+
+        sniffer = Trace("Sniffer", "Trace source simulating a non-promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(sniffer)
+
+        promiscsniffer = Trace("PromiscSniffer", "Trace source simulating a promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(promiscsniffer)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3PointToPointNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-point-to-point-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/point_to_point_remote_channel.py b/src/nepi/resources/ns3/classes/point_to_point_remote_channel.py
new file mode 100644 (file)
index 0000000..2c3ccf1
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3PointToPointRemoteChannel(NS3BaseChannel):
+    _rtype = "ns3::PointToPointRemoteChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_delay = Attribute("Delay",
+            "Transmission delay through the channel",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_delay)
+
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        txrxpointtopoint = Trace("TxRxPointToPoint", "Trace source indicating transmission of packet from the PointToPointChannel, used by the Animation interface.")
+
+        cls._register_trace(txrxpointtopoint)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3PointToPointRemoteChannel, self).__init__(ec, guid)
+        self._home = "ns3-point-to-point-remote-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/radvd.py b/src/nepi/resources/ns3/classes/radvd.py
new file mode 100644 (file)
index 0000000..d9ac187
--- /dev/null
@@ -0,0 +1,70 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3Radvd(NS3BaseApplication):
+    _rtype = "ns3::Radvd"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_advertisementjitter = Attribute("AdvertisementJitter",
+            "Uniform variable to provide jitter between min and max values of AdvInterval",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_advertisementjitter)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3Radvd, self).__init__(ec, guid)
+        self._home = "ns3-radvd-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/random_direction2d_mobility_model.py b/src/nepi/resources/ns3/classes/random_direction2d_mobility_model.py
new file mode 100644 (file)
index 0000000..6d2e75d
--- /dev/null
@@ -0,0 +1,95 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3RandomDirection2dMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::RandomDirection2dMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_bounds = Attribute("Bounds",
+            "The 2d bounding area",
+            type = Types.String,
+            default = "-100|100|-100|100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_bounds)
+
+        attr_speed = Attribute("Speed",
+            "A random variable to control the speed (m/s).",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=1.0|Max=2.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_speed)
+
+        attr_pause = Attribute("Pause",
+            "A random variable to control the pause (s).",
+            type = Types.String,
+            default = "ns3::ConstantRandomVariable[Constant=2.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pause)
+
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3RandomDirection2dMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-random-direction2d-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/random_propagation_delay_model.py b/src/nepi/resources/ns3/classes/random_propagation_delay_model.py
new file mode 100644 (file)
index 0000000..30a5f29
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationdelaymodel import NS3BasePropagationDelayModel 
+
+@clsinit_copy
+class NS3RandomPropagationDelayModel(NS3BasePropagationDelayModel):
+    _rtype = "ns3::RandomPropagationDelayModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_variable = Attribute("Variable",
+            "The random variable which generates random delays (s).",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_variable)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3RandomPropagationDelayModel, self).__init__(ec, guid)
+        self._home = "ns3-random-propagation-delay-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/random_propagation_loss_model.py b/src/nepi/resources/ns3/classes/random_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..05f0228
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3RandomPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::RandomPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_variable = Attribute("Variable",
+            "The random variable used to pick a loss everytime CalcRxPower is invoked.",
+            type = Types.String,
+            default = "ns3::ConstantRandomVariable[Constant=1.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_variable)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3RandomPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-random-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/random_walk2d_mobility_model.py b/src/nepi/resources/ns3/classes/random_walk2d_mobility_model.py
new file mode 100644 (file)
index 0000000..ee4095a
--- /dev/null
@@ -0,0 +1,125 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3RandomWalk2dMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::RandomWalk2dMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_bounds = Attribute("Bounds",
+            "Bounds of the area to cruise.",
+            type = Types.String,
+            default = "0|0|100|100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_bounds)
+
+        attr_time = Attribute("Time",
+            "Change current direction and speed after moving for this delay.",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_time)
+
+        attr_distance = Attribute("Distance",
+            "Change current direction and speed after moving for this distance.",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_distance)
+
+        attr_mode = Attribute("Mode",
+            "The mode indicates the condition used to change the current speed and direction",
+            type = Types.Enumerate,
+            default = "Distance",  
+            allowed = ["Distance","Time"],
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mode)
+
+        attr_direction = Attribute("Direction",
+            "A random variable used to pick the direction (gradients).",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=0.0|Max=6.283184]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_direction)
+
+        attr_speed = Attribute("Speed",
+            "A random variable used to pick the speed (m/s).",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=2.0|Max=4.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_speed)
+
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3RandomWalk2dMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-random-walk2d-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/random_waypoint_mobility_model.py b/src/nepi/resources/ns3/classes/random_waypoint_mobility_model.py
new file mode 100644 (file)
index 0000000..6ca4a27
--- /dev/null
@@ -0,0 +1,85 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3RandomWaypointMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::RandomWaypointMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_speed = Attribute("Speed",
+            "A random variable used to pick the speed of a random waypoint model.",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=0.3|Max=0.7]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_speed)
+
+        attr_pause = Attribute("Pause",
+            "A random variable used to pick the pause of a random waypoint model.",
+            type = Types.String,
+            default = "ns3::ConstantRandomVariable[Constant=2.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pause)
+
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3RandomWaypointMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-random-waypoint-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/range_propagation_loss_model.py b/src/nepi/resources/ns3/classes/range_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..529e520
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3RangePropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::RangePropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxrange = Attribute("MaxRange",
+            "Maximum Transmission Range (meters)",
+            type = Types.Double,
+            default = "250",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxrange)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3RangePropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-range-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/rate_error_model.py b/src/nepi/resources/ns3/classes/rate_error_model.py
new file mode 100644 (file)
index 0000000..2d56a34
--- /dev/null
@@ -0,0 +1,80 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3errormodel import NS3BaseErrorModel 
+
+@clsinit_copy
+class NS3RateErrorModel(NS3BaseErrorModel):
+    _rtype = "ns3::RateErrorModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_errorunit = Attribute("ErrorUnit",
+            "The error unit",
+            type = Types.Enumerate,
+            default = "ERROR_UNIT_BYTE",  
+            allowed = ["ERROR_UNIT_BIT","ERROR_UNIT_BYTE","ERROR_UNIT_PACKET"],
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_errorunit)
+
+        attr_errorrate = Attribute("ErrorRate",
+            "The error rate.",
+            type = Types.Double,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_errorrate)
+
+        attr_ranvar = Attribute("RanVar",
+            "The decision variable attached to this error model.",
+            type = Types.String,
+            default = "ns3::UniformRandomVariable[Min=0.0|Max=1.0]",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ranvar)
+
+        attr_isenabled = Attribute("IsEnabled",
+            "Whether this ErrorModel is enabled or not.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_isenabled)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3RateErrorModel, self).__init__(ec, guid)
+        self._home = "ns3-rate-error-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/receive_list_error_model.py b/src/nepi/resources/ns3/classes/receive_list_error_model.py
new file mode 100644 (file)
index 0000000..2f1652c
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3errormodel import NS3BaseErrorModel 
+
+@clsinit_copy
+class NS3ReceiveListErrorModel(NS3BaseErrorModel):
+    _rtype = "ns3::ReceiveListErrorModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_isenabled = Attribute("IsEnabled",
+            "Whether this ErrorModel is enabled or not.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_isenabled)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3ReceiveListErrorModel, self).__init__(ec, guid)
+        self._home = "ns3-receive-list-error-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/red_queue.py b/src/nepi/resources/ns3/classes/red_queue.py
new file mode 100644 (file)
index 0000000..d68166e
--- /dev/null
@@ -0,0 +1,173 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3queue import NS3BaseQueue 
+
+@clsinit_copy
+class NS3RedQueue(NS3BaseQueue):
+    _rtype = "ns3::RedQueue"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_meanpktsize = Attribute("MeanPktSize",
+            "Average of packet size",
+            type = Types.Integer,
+            default = "500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_meanpktsize)
+
+        attr_idlepktsize = Attribute("IdlePktSize",
+            "Average packet size used during idle times. Used when m_cautions = 3",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_idlepktsize)
+
+        attr_wait = Attribute("Wait",
+            "True for waiting between dropped packets",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_wait)
+
+        attr_gentle = Attribute("Gentle",
+            "True to increases dropping probability slowly when average queue exceeds maxthresh",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_gentle)
+
+        attr_minth = Attribute("MinTh",
+            "Minimum average length threshold in packets/bytes",
+            type = Types.Double,
+            default = "5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minth)
+
+        attr_maxth = Attribute("MaxTh",
+            "Maximum average length threshold in packets/bytes",
+            type = Types.Double,
+            default = "15",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxth)
+
+        attr_queuelimit = Attribute("QueueLimit",
+            "Queue limit in bytes/packets",
+            type = Types.Integer,
+            default = "25",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_queuelimit)
+
+        attr_qw = Attribute("QW",
+            "Queue weight related to the exponential weighted moving average (EWMA)",
+            type = Types.Double,
+            default = "0.002",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_qw)
+
+        attr_linterm = Attribute("LInterm",
+            "The maximum probability of dropping a packet",
+            type = Types.Double,
+            default = "50",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_linterm)
+
+        attr_ns1compat = Attribute("Ns1Compat",
+            "NS-1 compatibility",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ns1compat)
+
+        attr_linkbandwidth = Attribute("LinkBandwidth",
+            "The RED link bandwidth",
+            type = Types.String,
+            default = "1500000bps",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_linkbandwidth)
+
+        attr_linkdelay = Attribute("LinkDelay",
+            "The RED link delay",
+            type = Types.String,
+            default = "+20000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_linkdelay)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        enqueue = Trace("Enqueue", "Enqueue a packet in the queue.")
+
+        cls._register_trace(enqueue)
+
+        dequeue = Trace("Dequeue", "Dequeue a packet from the queue.")
+
+        cls._register_trace(dequeue)
+
+        drop = Trace("Drop", "Drop a packet stored in the queue.")
+
+        cls._register_trace(drop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3RedQueue, self).__init__(ec, guid)
+        self._home = "ns3-red-queue-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/rraa_wifi_manager.py b/src/nepi/resources/ns3/classes/rraa_wifi_manager.py
new file mode 100644 (file)
index 0000000..1553b8a
--- /dev/null
@@ -0,0 +1,367 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiremotestationmanager import NS3BaseWifiRemoteStationManager 
+
+@clsinit_copy
+class NS3RraaWifiManager(NS3BaseWifiRemoteStationManager):
+    _rtype = "ns3::RraaWifiManager"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_basic = Attribute("Basic",
+            "If true the RRAA-BASIC algorithm will be used, otherwise the RRAA wil be used",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_basic)
+
+        attr_timeout = Attribute("Timeout",
+            "Timeout for the RRAA BASIC loss estimaton block (s)",
+            type = Types.String,
+            default = "+50000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_timeout)
+
+        attr_ewndfor54mbps = Attribute("ewndFor54mbps",
+            "ewnd parameter for 54 Mbs data mode",
+            type = Types.Integer,
+            default = "40",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor54mbps)
+
+        attr_ewndfor48mbps = Attribute("ewndFor48mbps",
+            "ewnd parameter for 48 Mbs data mode",
+            type = Types.Integer,
+            default = "40",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor48mbps)
+
+        attr_ewndfor36mbps = Attribute("ewndFor36mbps",
+            "ewnd parameter for 36 Mbs data mode",
+            type = Types.Integer,
+            default = "40",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor36mbps)
+
+        attr_ewndfor24mbps = Attribute("ewndFor24mbps",
+            "ewnd parameter for 24 Mbs data mode",
+            type = Types.Integer,
+            default = "40",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor24mbps)
+
+        attr_ewndfor18mbps = Attribute("ewndFor18mbps",
+            "ewnd parameter for 18 Mbs data mode",
+            type = Types.Integer,
+            default = "20",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor18mbps)
+
+        attr_ewndfor12mbps = Attribute("ewndFor12mbps",
+            "ewnd parameter for 12 Mbs data mode",
+            type = Types.Integer,
+            default = "20",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor12mbps)
+
+        attr_ewndfor9mbps = Attribute("ewndFor9mbps",
+            "ewnd parameter for 9 Mbs data mode",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor9mbps)
+
+        attr_ewndfor6mbps = Attribute("ewndFor6mbps",
+            "ewnd parameter for 6 Mbs data mode",
+            type = Types.Integer,
+            default = "6",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ewndfor6mbps)
+
+        attr_porifor48mbps = Attribute("poriFor48mbps",
+            "Pori parameter for 48 Mbs data mode",
+            type = Types.Double,
+            default = "0.047",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_porifor48mbps)
+
+        attr_porifor36mbps = Attribute("poriFor36mbps",
+            "Pori parameter for 36 Mbs data mode",
+            type = Types.Double,
+            default = "0.115",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_porifor36mbps)
+
+        attr_porifor24mbps = Attribute("poriFor24mbps",
+            "Pori parameter for 24 Mbs data mode",
+            type = Types.Double,
+            default = "0.1681",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_porifor24mbps)
+
+        attr_porifor18mbps = Attribute("poriFor18mbps",
+            "Pori parameter for 18 Mbs data mode",
+            type = Types.Double,
+            default = "0.1325",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_porifor18mbps)
+
+        attr_porifor12mbps = Attribute("poriFor12mbps",
+            "Pori parameter for 12 Mbs data mode",
+            type = Types.Double,
+            default = "0.1861",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_porifor12mbps)
+
+        attr_porifor9mbps = Attribute("poriFor9mbps",
+            "Pori parameter for 9 Mbs data mode",
+            type = Types.Double,
+            default = "0.1434",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_porifor9mbps)
+
+        attr_porifor6mbps = Attribute("poriFor6mbps",
+            "Pori parameter for 6 Mbs data mode",
+            type = Types.Double,
+            default = "0.5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_porifor6mbps)
+
+        attr_pmtlfor54mbps = Attribute("pmtlFor54mbps",
+            "Pmtl parameter for 54 Mbs data mode",
+            type = Types.Double,
+            default = "0.094",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pmtlfor54mbps)
+
+        attr_pmtlfor48mbps = Attribute("pmtlFor48mbps",
+            "Pmtl parameter for 48 Mbs data mode",
+            type = Types.Double,
+            default = "0.23",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pmtlfor48mbps)
+
+        attr_pmtlfor36mbps = Attribute("pmtlFor36mbps",
+            "Pmtl parameter for 36 Mbs data mode",
+            type = Types.Double,
+            default = "0.3363",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pmtlfor36mbps)
+
+        attr_pmtlfor24mbps = Attribute("pmtlFor24mbps",
+            "Pmtl parameter for 24 Mbs data mode",
+            type = Types.Double,
+            default = "0.265",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pmtlfor24mbps)
+
+        attr_pmtlfor18mbps = Attribute("pmtlFor18mbps",
+            "Pmtl parameter for 18 Mbs data mode",
+            type = Types.Double,
+            default = "0.3722",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pmtlfor18mbps)
+
+        attr_pmtlfor12mbps = Attribute("pmtlFor12mbps",
+            "Pmtl parameter for 12 Mbs data mode",
+            type = Types.Double,
+            default = "0.2868",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pmtlfor12mbps)
+
+        attr_pmtlfor9mbps = Attribute("pmtlFor9mbps",
+            "Pmtl parameter for 9 Mbs data mode",
+            type = Types.Double,
+            default = "0.3932",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pmtlfor9mbps)
+
+        attr_islowlatency = Attribute("IsLowLatency",
+            "If true, we attempt to modelize a so-called low-latency device: a device where decisions about tx parameters can be made on a per-packet basis and feedback about the transmission of each packet is obtained before sending the next. Otherwise, we modelize a  high-latency device, that is a device where we cannot update our decision about tx parameters after every packet transmission.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_islowlatency)
+
+        attr_maxssrc = Attribute("MaxSsrc",
+            "The maximum number of retransmission attempts for an RTS. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxssrc)
+
+        attr_maxslrc = Attribute("MaxSlrc",
+            "The maximum number of retransmission attempts for a DATA packet. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxslrc)
+
+        attr_rtsctsthreshold = Attribute("RtsCtsThreshold",
+            "If  the size of the data packet + LLC header + MAC header + FCS trailer is bigger than this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtsctsthreshold)
+
+        attr_fragmentationthreshold = Attribute("FragmentationThreshold",
+            "If the size of the data packet + LLC header + MAC header + FCS trailer is biggerthan this value, we fragment it such that the size of the fragments are equal or smaller than this value, as per IEEE Std. 802.11-2007, Section 9.4. This value will not have any effect on some rate control algorithms.",
+            type = Types.Integer,
+            default = "2346",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_fragmentationthreshold)
+
+        attr_nonunicastmode = Attribute("NonUnicastMode",
+            "Wifi mode used for non-unicast transmissions.",
+            type = Types.String,
+            default = "Invalid-WifiMode",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonunicastmode)
+
+        attr_defaulttxpowerlevel = Attribute("DefaultTxPowerLevel",
+            "Default power level to be used for transmissions. This is the power level that is used by all those WifiManagers that do notimplement TX power control.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_defaulttxpowerlevel)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactxrtsfailed = Trace("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed")
+
+        cls._register_trace(mactxrtsfailed)
+
+        mactxdatafailed = Trace("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed")
+
+        cls._register_trace(mactxdatafailed)
+
+        mactxfinalrtsfailed = Trace("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinalrtsfailed)
+
+        mactxfinaldatafailed = Trace("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts")
+
+        cls._register_trace(mactxfinaldatafailed)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3RraaWifiManager, self).__init__(ec, guid)
+        self._home = "ns3-rraa-wifi-manager-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/simple_channel.py b/src/nepi/resources/ns3/classes/simple_channel.py
new file mode 100644 (file)
index 0000000..37a9c42
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3SimpleChannel(NS3BaseChannel):
+    _rtype = "ns3::SimpleChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3SimpleChannel, self).__init__(ec, guid)
+        self._home = "ns3-simple-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/simple_net_device.py b/src/nepi/resources/ns3/classes/simple_net_device.py
new file mode 100644 (file)
index 0000000..293394a
--- /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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3SimpleNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::SimpleNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        
+        phyrxdrop = Trace("PhyRxDrop", "Trace source indicating a packet has been dropped by the device during reception")
+
+        cls._register_trace(phyrxdrop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3SimpleNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-simple-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/single_model_spectrum_channel.py b/src/nepi/resources/ns3/classes/single_model_spectrum_channel.py
new file mode 100644 (file)
index 0000000..3328562
--- /dev/null
@@ -0,0 +1,65 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3SingleModelSpectrumChannel(NS3BaseChannel):
+    _rtype = "ns3::SingleModelSpectrumChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxlossdb = Attribute("MaxLossDb",
+            "If a single-frequency PropagationLossModel is used, this value represents the maximum loss in dB for which transmissions will be passed to the receiving PHY. Signals for which the PropagationLossModel returns a loss bigger than this value will not be propagated to the receiver. This parameter is to be used to reduce the computational load by not propagating signals that are far beyond the interference range. Note that the default value corresponds to considering all signals for reception. Tune this value with care. ",
+            type = Types.Double,
+            default = "1e+09",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxlossdb)
+
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        pathloss = Trace("PathLoss", "This trace is fired whenever a new path loss value is calculated. The first and second parameters to the trace are pointers respectively to the TX and RX SpectrumPhy instances, whereas the third parameters is the loss value in dB. Note that the loss value reported by this trace is the single-frequency loss value obtained by evaluating only the TX and RX AntennaModels and the PropagationLossModel. In particular, note that SpectrumPropagationLossModel (even if present) is never used to evaluate the loss value reported in this trace. ")
+
+        cls._register_trace(pathloss)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3SingleModelSpectrumChannel, self).__init__(ec, guid)
+        self._home = "ns3-single-model-spectrum-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/sta_wifi_mac.py b/src/nepi/resources/ns3/classes/sta_wifi_mac.py
new file mode 100644 (file)
index 0000000..3b2288f
--- /dev/null
@@ -0,0 +1,247 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifimac import NS3BaseWifiMac 
+
+@clsinit_copy
+class NS3StaWifiMac(NS3BaseWifiMac):
+    _rtype = "ns3::StaWifiMac"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_proberequesttimeout = Attribute("ProbeRequestTimeout",
+            "The interval between two consecutive probe request attempts.",
+            type = Types.String,
+            default = "+50000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_proberequesttimeout)
+
+        attr_assocrequesttimeout = Attribute("AssocRequestTimeout",
+            "The interval between two consecutive assoc request attempts.",
+            type = Types.String,
+            default = "+500000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_assocrequesttimeout)
+
+        attr_maxmissedbeacons = Attribute("MaxMissedBeacons",
+            "Number of beacons which much be consecutively missed before we attempt to restart association.",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxmissedbeacons)
+
+        attr_qossupported = Attribute("QosSupported",
+            "This Boolean attribute is set to enable 802.11e/WMM-style QoS support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_qossupported)
+
+        attr_htsupported = Attribute("HtSupported",
+            "This Boolean attribute is set to enable 802.11n support at this STA",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_htsupported)
+
+        attr_ctstoselfsupported = Attribute("CtsToSelfSupported",
+            "Use CTS to Self when using a rate that is not in the basic set rate",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstoselfsupported)
+
+        attr_ctstimeout = Attribute("CtsTimeout",
+            "When this timeout expires, the RTS/CTS handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ctstimeout)
+
+        attr_acktimeout = Attribute("AckTimeout",
+            "When this timeout expires, the DATA/ACK handshake has failed.",
+            type = Types.String,
+            default = "+75000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_acktimeout)
+
+        attr_basicblockacktimeout = Attribute("BasicBlockAckTimeout",
+            "When this timeout expires, the BASIC_BLOCK_ACK_REQ/BASIC_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+281000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_basicblockacktimeout)
+
+        attr_compressedblockacktimeout = Attribute("CompressedBlockAckTimeout",
+            "When this timeout expires, the COMPRESSED_BLOCK_ACK_REQ/COMPRESSED_BLOCK_ACK handshake has failed.",
+            type = Types.String,
+            default = "+107000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_compressedblockacktimeout)
+
+        attr_sifs = Attribute("Sifs",
+            "The value of the SIFS constant.",
+            type = Types.String,
+            default = "+16000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sifs)
+
+        attr_eifsnodifs = Attribute("EifsNoDifs",
+            "The value of EIFS-DIFS",
+            type = Types.String,
+            default = "+60000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_eifsnodifs)
+
+        attr_slot = Attribute("Slot",
+            "The duration of a Slot.",
+            type = Types.String,
+            default = "+9000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_slot)
+
+        attr_pifs = Attribute("Pifs",
+            "The value of the PIFS constant.",
+            type = Types.String,
+            default = "+25000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_pifs)
+
+        attr_rifs = Attribute("Rifs",
+            "The value of the RIFS constant.",
+            type = Types.String,
+            default = "+2000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rifs)
+
+        attr_maxpropagationdelay = Attribute("MaxPropagationDelay",
+            "The maximum propagation delay. Unused for now.",
+            type = Types.String,
+            default = "+3333.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpropagationdelay)
+
+        attr_ssid = Attribute("Ssid",
+            "The ssid we want to belong to.",
+            type = Types.String,
+            default = "default",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ssid)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        assoc = Trace("Assoc", "Associated with an access point.")
+
+        cls._register_trace(assoc)
+
+        deassoc = Trace("DeAssoc", "Association with an access point lost.")
+
+        cls._register_trace(deassoc)
+
+        txokheader = Trace("TxOkHeader", "The header of successfully transmitted packet")
+
+        cls._register_trace(txokheader)
+
+        txerrheader = Trace("TxErrHeader", "The header of unsuccessfully transmitted packet")
+
+        cls._register_trace(txerrheader)
+
+        mactx = Trace("MacTx", "A packet has been received from higher layers and is being processed in preparation for queueing for transmission.")
+
+        cls._register_trace(mactx)
+
+        mactxdrop = Trace("MacTxDrop", "A packet has been dropped in the MAC layer before being queued for transmission.")
+
+        cls._register_trace(mactxdrop)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        macrxdrop = Trace("MacRxDrop", "A packet has been dropped in the MAC layer after it has been passed up from the physical layer.")
+
+        cls._register_trace(macrxdrop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3StaWifiMac, self).__init__(ec, guid)
+        self._home = "ns3-sta-wifi-mac-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/steady_state_random_waypoint_mobility_model.py b/src/nepi/resources/ns3/classes/steady_state_random_waypoint_mobility_model.py
new file mode 100644 (file)
index 0000000..65b99b6
--- /dev/null
@@ -0,0 +1,155 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3SteadyStateRandomWaypointMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::SteadyStateRandomWaypointMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_minspeed = Attribute("MinSpeed",
+            "Minimum speed value, [m/s]",
+            type = Types.Double,
+            default = "0.3",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minspeed)
+
+        attr_maxspeed = Attribute("MaxSpeed",
+            "Maximum speed value, [m/s]",
+            type = Types.Double,
+            default = "0.7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxspeed)
+
+        attr_minpause = Attribute("MinPause",
+            "Minimum pause value, [s]",
+            type = Types.Double,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minpause)
+
+        attr_maxpause = Attribute("MaxPause",
+            "Maximum pause value, [s]",
+            type = Types.Double,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpause)
+
+        attr_minx = Attribute("MinX",
+            "Minimum X value of traveling region, [m]",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minx)
+
+        attr_maxx = Attribute("MaxX",
+            "Maximum X value of traveling region, [m]",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxx)
+
+        attr_miny = Attribute("MinY",
+            "Minimum Y value of traveling region, [m]",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_miny)
+
+        attr_maxy = Attribute("MaxY",
+            "Maximum Y value of traveling region, [m]",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxy)
+
+        attr_z = Attribute("Z",
+            "Z value of traveling region (fixed), [m]",
+            type = Types.Double,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_z)
+
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3SteadyStateRandomWaypointMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-steady-state-random-waypoint-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/subscriber_station_net_device.py b/src/nepi/resources/ns3/classes/subscriber_station_net_device.py
new file mode 100644 (file)
index 0000000..18441c2
--- /dev/null
@@ -0,0 +1,215 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3SubscriberStationNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::SubscriberStationNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_lostdlmapinterval = Attribute("LostDlMapInterval",
+            "Time since last received DL-MAP message before downlink synchronization is considered lost. Maximum is 600ms",
+            type = Types.String,
+            default = "+500000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_lostdlmapinterval)
+
+        attr_lostulmapinterval = Attribute("LostUlMapInterval",
+            "Time since last received UL-MAP before uplink synchronization is considered lost, maximum is 600.",
+            type = Types.String,
+            default = "+500000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_lostulmapinterval)
+
+        attr_maxdcdinterval = Attribute("MaxDcdInterval",
+            "Maximum time between transmission of DCD messages. Maximum is 10s",
+            type = Types.String,
+            default = "+10000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxdcdinterval)
+
+        attr_maxucdinterval = Attribute("MaxUcdInterval",
+            "Maximum time between transmission of UCD messages. Maximum is 10s",
+            type = Types.String,
+            default = "+10000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxucdinterval)
+
+        attr_intervalt1 = Attribute("IntervalT1",
+            "Wait for DCD timeout. Maximum is 5*maxDcdInterval",
+            type = Types.String,
+            default = "+50000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt1)
+
+        attr_intervalt2 = Attribute("IntervalT2",
+            "Wait for broadcast ranging timeout, i.e., wait for initial ranging opportunity. Maximum is 5*Ranging interval",
+            type = Types.String,
+            default = "+10000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt2)
+
+        attr_intervalt3 = Attribute("IntervalT3",
+            "ranging Response reception timeout following the transmission of a ranging request. Maximum is 200ms",
+            type = Types.String,
+            default = "+200000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt3)
+
+        attr_intervalt7 = Attribute("IntervalT7",
+            "wait for DSA/DSC/DSD Response timeout. Maximum is 1s",
+            type = Types.String,
+            default = "+100000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt7)
+
+        attr_intervalt12 = Attribute("IntervalT12",
+            "Wait for UCD descriptor.Maximum is 5*MaxUcdInterval",
+            type = Types.String,
+            default = "+10000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt12)
+
+        attr_intervalt20 = Attribute("IntervalT20",
+            "Time the SS searches for preambles on a given channel. Minimum is 2 MAC frames",
+            type = Types.String,
+            default = "+500000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt20)
+
+        attr_intervalt21 = Attribute("IntervalT21",
+            "time the SS searches for (decodable) DL-MAP on a given channel",
+            type = Types.String,
+            default = "+10000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_intervalt21)
+
+        attr_maxcontentionrangingretries = Attribute("MaxContentionRangingRetries",
+            "Number of retries on contention Ranging Requests",
+            type = Types.Integer,
+            default = "16",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxcontentionrangingretries)
+
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "1400",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+        attr_rtg = Attribute("RTG",
+            "receive/transmit transition gap.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rtg)
+
+        attr_ttg = Attribute("TTG",
+            "transmit/receive transition gap.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ttg)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        sstxdrop = Trace("SSTxDrop", "A packet has been dropped in the MAC layer before being queued for transmission.")
+
+        cls._register_trace(sstxdrop)
+
+        sspromiscrx = Trace("SSPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(sspromiscrx)
+
+        ssrx = Trace("SSRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(ssrx)
+
+        ssrxdrop = Trace("SSRxDrop", "A packet has been dropped in the MAC layer after it has been passed up from the physical layer.")
+
+        cls._register_trace(ssrxdrop)
+
+        rx = Trace("Rx", "Receive trace")
+
+        cls._register_trace(rx)
+
+        tx = Trace("Tx", "Transmit trace")
+
+        cls._register_trace(tx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3SubscriberStationNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-subscriber-station-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/tap_bridge.py b/src/nepi/resources/ns3/classes/tap_bridge.py
new file mode 100644 (file)
index 0000000..8438d28
--- /dev/null
@@ -0,0 +1,120 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3TapBridge(NS3BaseNetDevice):
+    _rtype = "ns3::TapBridge"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+        attr_devicename = Attribute("DeviceName",
+            "The name of the tap device to create.",
+            type = Types.String,
+            default = "",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_devicename)
+
+        attr_gateway = Attribute("Gateway",
+            "The IP address of the default gateway to assign to the host machine, when in ConfigureLocal mode.",
+            type = Types.String,
+            default = "255.255.255.255",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_gateway)
+
+        attr_ipaddress = Attribute("IpAddress",
+            "The IP address to assign to the tap device, when in ConfigureLocal mode.  This address will override the discovered IP address of the simulated device.",
+            type = Types.String,
+            default = "255.255.255.255",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ipaddress)
+
+        attr_macaddress = Attribute("MacAddress",
+            "The MAC address to assign to the tap device, when in ConfigureLocal mode.  This address will override the discovered MAC address of the simulated device.",
+            type = Types.String,
+            default = "ff:ff:ff:ff:ff:ff",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_macaddress)
+
+        attr_netmask = Attribute("Netmask",
+            "The network mask to assign to the tap device, when in ConfigureLocal mode.  This address will override the discovered MAC address of the simulated device.",
+            type = Types.String,
+            default = "255.255.255.255",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_netmask)
+
+        attr_start = Attribute("Start",
+            "The simulation time at which to spin up the tap device read thread.",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_start)
+
+        attr_stop = Attribute("Stop",
+            "The simulation time at which to tear down the tap device read thread.",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stop)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3TapBridge, self).__init__(ec, guid)
+        self._home = "ns3-tap-bridge-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/three_log_distance_propagation_loss_model.py b/src/nepi/resources/ns3/classes/three_log_distance_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..620d904
--- /dev/null
@@ -0,0 +1,110 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3ThreeLogDistancePropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::ThreeLogDistancePropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_distance0 = Attribute("Distance0",
+            "Beginning of the first (near) distance field",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_distance0)
+
+        attr_distance1 = Attribute("Distance1",
+            "Beginning of the second (middle) distance field.",
+            type = Types.Double,
+            default = "200",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_distance1)
+
+        attr_distance2 = Attribute("Distance2",
+            "Beginning of the third (far) distance field.",
+            type = Types.Double,
+            default = "500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_distance2)
+
+        attr_exponent0 = Attribute("Exponent0",
+            "The exponent for the first field.",
+            type = Types.Double,
+            default = "1.9",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_exponent0)
+
+        attr_exponent1 = Attribute("Exponent1",
+            "The exponent for the second field.",
+            type = Types.Double,
+            default = "3.8",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_exponent1)
+
+        attr_exponent2 = Attribute("Exponent2",
+            "The exponent for the third field.",
+            type = Types.Double,
+            default = "3.8",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_exponent2)
+
+        attr_referenceloss = Attribute("ReferenceLoss",
+            "The reference loss at distance d0 (dB). (Default is Friis at 1m with 5.15 GHz)",
+            type = Types.Double,
+            default = "46.6777",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_referenceloss)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3ThreeLogDistancePropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-three-log-distance-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/two_ray_ground_propagation_loss_model.py b/src/nepi/resources/ns3/classes/two_ray_ground_propagation_loss_model.py
new file mode 100644 (file)
index 0000000..0dfadb8
--- /dev/null
@@ -0,0 +1,80 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3propagationlossmodel import NS3BasePropagationLossModel 
+
+@clsinit_copy
+class NS3TwoRayGroundPropagationLossModel(NS3BasePropagationLossModel):
+    _rtype = "ns3::TwoRayGroundPropagationLossModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_frequency = Attribute("Frequency",
+            "The carrier frequency (in Hz) at which propagation occurs  (default is 5.15 GHz).",
+            type = Types.Double,
+            default = "5.15e+09",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_frequency)
+
+        attr_systemloss = Attribute("SystemLoss",
+            "The system loss",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_systemloss)
+
+        attr_mindistance = Attribute("MinDistance",
+            "The distance under which the propagation model refuses to give results (m)",
+            type = Types.Double,
+            default = "0.5",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mindistance)
+
+        attr_heightabovez = Attribute("HeightAboveZ",
+            "The height of the antenna (m) above the node\'s Z coordinate",
+            type = Types.Double,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_heightabovez)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3TwoRayGroundPropagationLossModel, self).__init__(ec, guid)
+        self._home = "ns3-two-ray-ground-propagation-loss-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/uan_channel.py b/src/nepi/resources/ns3/classes/uan_channel.py
new file mode 100644 (file)
index 0000000..4683b78
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
+
+@clsinit_copy
+class NS3UanChannel(NS3BaseChannel):
+    _rtype = "ns3::UanChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3UanChannel, self).__init__(ec, guid)
+        self._home = "ns3-uan-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/udp_client.py b/src/nepi/resources/ns3/classes/udp_client.py
new file mode 100644 (file)
index 0000000..e242eb6
--- /dev/null
@@ -0,0 +1,110 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3UdpClient(NS3BaseApplication):
+    _rtype = "ns3::UdpClient"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxpackets = Attribute("MaxPackets",
+            "The maximum number of packets the application will send",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpackets)
+
+        attr_interval = Attribute("Interval",
+            "The time to wait between packets",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_interval)
+
+        attr_remoteaddress = Attribute("RemoteAddress",
+            "The destination Address of the outbound packets",
+            type = Types.String,
+            default = "00-00-00",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remoteaddress)
+
+        attr_remoteport = Attribute("RemotePort",
+            "The destination port of the outbound packets",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remoteport)
+
+        attr_packetsize = Attribute("PacketSize",
+            "Size of packets generated. The minimum packet size is 12 bytes which is the size of the header carrying the sequence number and the time stamp.",
+            type = Types.Integer,
+            default = "1024",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_packetsize)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3UdpClient, self).__init__(ec, guid)
+        self._home = "ns3-udp-client-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/udp_echo_client.py b/src/nepi/resources/ns3/classes/udp_echo_client.py
new file mode 100644 (file)
index 0000000..9293b07
--- /dev/null
@@ -0,0 +1,115 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3UdpEchoClient(NS3BaseApplication):
+    _rtype = "ns3::UdpEchoClient"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxpackets = Attribute("MaxPackets",
+            "The maximum number of packets the application will send",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpackets)
+
+        attr_interval = Attribute("Interval",
+            "The time to wait between packets",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_interval)
+
+        attr_remoteaddress = Attribute("RemoteAddress",
+            "The destination Address of the outbound packets",
+            type = Types.String,
+            default = "00-00-00",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remoteaddress)
+
+        attr_remoteport = Attribute("RemotePort",
+            "The destination port of the outbound packets",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remoteport)
+
+        attr_packetsize = Attribute("PacketSize",
+            "Size of echo data in outbound packets",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_packetsize)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        tx = Trace("Tx", "A new packet is created and is sent")
+
+        cls._register_trace(tx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3UdpEchoClient, self).__init__(ec, guid)
+        self._home = "ns3-udp-echo-client-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/udp_echo_server.py b/src/nepi/resources/ns3/classes/udp_echo_server.py
new file mode 100644 (file)
index 0000000..cd73643
--- /dev/null
@@ -0,0 +1,70 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3UdpEchoServer(NS3BaseApplication):
+    _rtype = "ns3::UdpEchoServer"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_port = Attribute("Port",
+            "Port on which we listen for incoming packets.",
+            type = Types.Integer,
+            default = "9",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_port)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3UdpEchoServer, self).__init__(ec, guid)
+        self._home = "ns3-udp-echo-server-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/udp_server.py b/src/nepi/resources/ns3/classes/udp_server.py
new file mode 100644 (file)
index 0000000..86b109b
--- /dev/null
@@ -0,0 +1,80 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3UdpServer(NS3BaseApplication):
+    _rtype = "ns3::UdpServer"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_port = Attribute("Port",
+            "Port on which we listen for incoming packets.",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_port)
+
+        attr_packetwindowsize = Attribute("PacketWindowSize",
+            "The size of the window used to compute the packet loss. This value should be a multiple of 8.",
+            type = Types.Integer,
+            default = "32",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_packetwindowsize)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3UdpServer, self).__init__(ec, guid)
+        self._home = "ns3-udp-server-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/udp_trace_client.py b/src/nepi/resources/ns3/classes/udp_trace_client.py
new file mode 100644 (file)
index 0000000..6263666
--- /dev/null
@@ -0,0 +1,90 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3UdpTraceClient(NS3BaseApplication):
+    _rtype = "ns3::UdpTraceClient"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_remoteaddress = Attribute("RemoteAddress",
+            "The destination Address of the outbound packets",
+            type = Types.String,
+            default = "00-00-00",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remoteaddress)
+
+        attr_remoteport = Attribute("RemotePort",
+            "The destination port of the outbound packets",
+            type = Types.Integer,
+            default = "100",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remoteport)
+
+        attr_maxpacketsize = Attribute("MaxPacketSize",
+            "The maximum size of a packet.",
+            type = Types.Integer,
+            default = "1024",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxpacketsize)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3UdpTraceClient, self).__init__(ec, guid)
+        self._home = "ns3-udp-trace-client-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/v4ping.py b/src/nepi/resources/ns3/classes/v4ping.py
new file mode 100644 (file)
index 0000000..c9a0958
--- /dev/null
@@ -0,0 +1,105 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication 
+
+@clsinit_copy
+class NS3V4Ping(NS3BaseApplication):
+    _rtype = "ns3::V4Ping"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_remote = Attribute("Remote",
+            "The address of the machine we want to ping.",
+            type = Types.String,
+            default = "102.102.102.102",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_remote)
+
+        attr_verbose = Attribute("Verbose",
+            "Produce usual output.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_verbose)
+
+        attr_interval = Attribute("Interval",
+            "Wait  interval  seconds between sending each packet.",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_interval)
+
+        attr_size = Attribute("Size",
+            "The number of data bytes to be sent, real packet will be 8 (ICMP) + 20 (IP) bytes longer.",
+            type = Types.Integer,
+            default = "56",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_size)
+
+        attr_starttime = Attribute("StartTime",
+            "Time at which the application will start",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_starttime)
+
+        attr_stoptime = Attribute("StopTime",
+            "Time at which the application will stop",
+            type = Types.String,
+            default = "+0.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stoptime)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        rtt = Trace("Rtt", "The rtt calculated by the ping.")
+
+        cls._register_trace(rtt)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3V4Ping, self).__init__(ec, guid)
+        self._home = "ns3-v4ping-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/virtual_net_device.py b/src/nepi/resources/ns3/classes/virtual_net_device.py
new file mode 100644 (file)
index 0000000..a57f363
--- /dev/null
@@ -0,0 +1,71 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
+
+@clsinit_copy
+class NS3VirtualNetDevice(NS3BaseNetDevice):
+    _rtype = "ns3::VirtualNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "1500",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        mactx = Trace("MacTx", "Trace source indicating a packet has arrived for transmission by this device")
+
+        cls._register_trace(mactx)
+
+        macpromiscrx = Trace("MacPromiscRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a promiscuous trace,")
+
+        cls._register_trace(macpromiscrx)
+
+        macrx = Trace("MacRx", "A packet has been received by this device, has been passed up from the physical layer and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,")
+
+        cls._register_trace(macrx)
+
+        sniffer = Trace("Sniffer", "Trace source simulating a non-promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(sniffer)
+
+        promiscsniffer = Trace("PromiscSniffer", "Trace source simulating a promiscuous packet sniffer attached to the device")
+
+        cls._register_trace(promiscsniffer)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3VirtualNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-virtual-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/waypoint_mobility_model.py b/src/nepi/resources/ns3/classes/waypoint_mobility_model.py
new file mode 100644 (file)
index 0000000..116ab45
--- /dev/null
@@ -0,0 +1,95 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3mobilitymodel import NS3BaseMobilityModel 
+
+@clsinit_copy
+class NS3WaypointMobilityModel(NS3BaseMobilityModel):
+    _rtype = "ns3::WaypointMobilityModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_waypointsleft = Attribute("WaypointsLeft",
+            "The number of waypoints remaining.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_waypointsleft)
+
+        attr_lazynotify = Attribute("LazyNotify",
+            "Only call NotifyCourseChange when position is calculated.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_lazynotify)
+
+        attr_initialpositioniswaypoint = Attribute("InitialPositionIsWaypoint",
+            "Calling SetPosition with no waypoints creates a waypoint.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_initialpositioniswaypoint)
+
+        attr_position = Attribute("Position",
+            "The current position of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved)
+
+        cls._register_attribute(attr_position)
+
+        attr_velocity = Attribute("Velocity",
+            "The current velocity of the mobility model.",
+            type = Types.String,
+            default = "0:0:0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_velocity)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        coursechange = Trace("CourseChange", "The value of the position and/or velocity vector changed")
+
+        cls._register_trace(coursechange)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3WaypointMobilityModel, self).__init__(ec, guid)
+        self._home = "ns3-waypoint-mobility-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/wifi_net_device.py b/src/nepi/resources/ns3/classes/wifi_net_device.py
new file mode 100644 (file)
index 0000000..92dd859
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifinetdevice import NS3BaseWifiNetDevice 
+
+@clsinit_copy
+class NS3WifiNetDevice(NS3BaseWifiNetDevice):
+    _rtype = "ns3::WifiNetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_mtu = Attribute("Mtu",
+            "The MAC-level Maximum Transmission Unit",
+            type = Types.Integer,
+            default = "2296",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_mtu)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3WifiNetDevice, self).__init__(ec, guid)
+        self._home = "ns3-wifi-net-device-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/yans_error_rate_model.py b/src/nepi/resources/ns3/classes/yans_error_rate_model.py
new file mode 100644 (file)
index 0000000..0e119dd
--- /dev/null
@@ -0,0 +1,39 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3errorratemodel import NS3BaseErrorRateModel 
+
+@clsinit_copy
+class NS3YansErrorRateModel(NS3BaseErrorRateModel):
+    _rtype = "ns3::YansErrorRateModel"
+
+    @classmethod
+    def _register_attributes(cls):
+        pass
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3YansErrorRateModel, self).__init__(ec, guid)
+        self._home = "ns3-yans-error-rate-model-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/yans_wifi_channel.py b/src/nepi/resources/ns3/classes/yans_wifi_channel.py
new file mode 100644 (file)
index 0000000..314d391
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifichannel import NS3BaseWifiChannel 
+
+@clsinit_copy
+class NS3YansWifiChannel(NS3BaseWifiChannel):
+    _rtype = "ns3::YansWifiChannel"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_id = Attribute("Id",
+            "The id (unique integer) of this Channel.",
+            type = Types.Integer,
+            default = "0",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.NoWrite)
+
+        cls._register_attribute(attr_id)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        pass
+
+    def __init__(self, ec, guid):
+        super(NS3YansWifiChannel, self).__init__(ec, guid)
+        self._home = "ns3-yans-wifi-channel-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/yans_wifi_phy.py b/src/nepi/resources/ns3/classes/yans_wifi_phy.py
new file mode 100644 (file)
index 0000000..2c6ad1c
--- /dev/null
@@ -0,0 +1,253 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3wifiphy import NS3BaseWifiPhy 
+
+@clsinit_copy
+class NS3YansWifiPhy(NS3BaseWifiPhy):
+    _rtype = "ns3::YansWifiPhy"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_energydetectionthreshold = Attribute("EnergyDetectionThreshold",
+            "The energy of a received signal should be higher than this threshold (dbm) to allow the PHY layer to detect the signal.",
+            type = Types.Double,
+            default = "-96",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_energydetectionthreshold)
+
+        attr_ccamode1threshold = Attribute("CcaMode1Threshold",
+            "The energy of a received signal should be higher than this threshold (dbm) to allow the PHY layer to declare CCA BUSY state",
+            type = Types.Double,
+            default = "-99",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ccamode1threshold)
+
+        attr_txgain = Attribute("TxGain",
+            "Transmission gain (dB).",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_txgain)
+
+        attr_rxgain = Attribute("RxGain",
+            "Reception gain (dB).",
+            type = Types.Double,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rxgain)
+
+        attr_txpowerlevels = Attribute("TxPowerLevels",
+            "Number of transmission power levels available between TxPowerStart and TxPowerEnd included.",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_txpowerlevels)
+
+        attr_txpowerend = Attribute("TxPowerEnd",
+            "Maximum available transmission level (dbm).",
+            type = Types.Double,
+            default = "16.0206",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_txpowerend)
+
+        attr_txpowerstart = Attribute("TxPowerStart",
+            "Minimum available transmission level (dbm).",
+            type = Types.Double,
+            default = "16.0206",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_txpowerstart)
+
+        attr_rxnoisefigure = Attribute("RxNoiseFigure",
+            "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver. According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is \"the difference in decibels (dB) between the noise output of the actual receiver to the noise output of an  ideal receiver with the same overall gain and bandwidth when the receivers  are connected to sources at the standard noise temperature T0 (usually 290 K)\". For",
+            type = Types.Double,
+            default = "7",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rxnoisefigure)
+
+        attr_channelswitchdelay = Attribute("ChannelSwitchDelay",
+            "Delay between two short frames transmitted on different frequencies.",
+            type = Types.String,
+            default = "+250000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_channelswitchdelay)
+
+        attr_channelnumber = Attribute("ChannelNumber",
+            "Channel center frequency = Channel starting frequency + 5 MHz * nch",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_channelnumber)
+
+        attr_frequency = Attribute("Frequency",
+            "The operating frequency.",
+            type = Types.Integer,
+            default = "2407",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_frequency)
+
+        attr_transmitters = Attribute("Transmitters",
+            "The number of transmitters.",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_transmitters)
+
+        attr_recievers = Attribute("Recievers",
+            "The number of recievers.",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_recievers)
+
+        attr_shortguardenabled = Attribute("ShortGuardEnabled",
+            "Whether or not short guard interval is enabled.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_shortguardenabled)
+
+        attr_ldpcenabled = Attribute("LdpcEnabled",
+            "Whether or not LDPC is enabled.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_ldpcenabled)
+
+        attr_stbcenabled = Attribute("STBCEnabled",
+            "Whether or not STBC is enabled.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stbcenabled)
+
+        attr_greenfieldenabled = Attribute("GreenfieldEnabled",
+            "Whether or not STBC is enabled.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_greenfieldenabled)
+
+        attr_channelbonding = Attribute("ChannelBonding",
+            "Whether 20MHz or 40MHz.",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_channelbonding)
+
+
+
+    @classmethod
+    def _register_traces(cls):
+        
+        phytxbegin = Trace("PhyTxBegin", "Trace source indicating a packet has begun transmitting over the channel medium")
+
+        cls._register_trace(phytxbegin)
+
+        phytxend = Trace("PhyTxEnd", "Trace source indicating a packet has been completely transmitted over the channel. NOTE: the only official WifiPhy implementation available to this date (YansWifiPhy) never fires this trace source.")
+
+        cls._register_trace(phytxend)
+
+        phytxdrop = Trace("PhyTxDrop", "Trace source indicating a packet has been dropped by the device during transmission")
+
+        cls._register_trace(phytxdrop)
+
+        phyrxbegin = Trace("PhyRxBegin", "Trace source indicating a packet has begun being received from the channel medium by the device")
+
+        cls._register_trace(phyrxbegin)
+
+        phyrxend = Trace("PhyRxEnd", "Trace source indicating a packet has been completely received from the channel medium by the device")
+
+        cls._register_trace(phyrxend)
+
+        phyrxdrop = Trace("PhyRxDrop", "Trace source indicating a packet has been dropped by the device during reception")
+
+        cls._register_trace(phyrxdrop)
+
+        monitorsnifferrx = Trace("MonitorSnifferRx", "Trace source simulating a wifi device in monitor mode sniffing all received frames")
+
+        cls._register_trace(monitorsnifferrx)
+
+        monitorsniffertx = Trace("MonitorSnifferTx", "Trace source simulating the capability of a wifi device in monitor mode to sniff all frames being transmitted")
+
+        cls._register_trace(monitorsniffertx)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3YansWifiPhy, self).__init__(ec, guid)
+        self._home = "ns3-yans-wifi-phy-%s" % self.guid
diff --git a/src/nepi/resources/ns3/ns3application.py b/src/nepi/resources/ns3/ns3application.py
new file mode 100644 (file)
index 0000000..db6096b
--- /dev/null
@@ -0,0 +1,75 @@
+#
+#    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, ResourceState, \
+        reschedule_delay
+from nepi.resources.ns3.ns3base import NS3Base
+
+@clsinit_copy
+class NS3BaseApplication(NS3Base):
+    _rtype = "abstract::ns3::Application"
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+
+        if not nodes: 
+            msg = "Application not connected to node"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return nodes[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.node)
+        return rms
+
+    def _connect_object(self):
+        node = self.node
+        if node.uuid not in self.connected:
+            self.simulation.invoke(node.uuid, "AddApplication", self.uuid)
+            self._connected.add(node.uuid)
+
+    def do_stop(self):
+        if self.state == ResourceState.STARTED:
+            # No need to do anything, simulation.Destroy() will stop every object
+            self.info("Stopping command '%s'" % command)
+            self.simulation.invoke(self.uuid, "Stop")
+            self.set_stopped()
+
+    def do_start(self):
+        if self.simulation.state < ResourceState.STARTED:
+            self.debug("---- RESCHEDULING START ----" )
+            self.ec.schedule(reschedule_delay, self.start)
+        else:
+            super(NS3BaseApplication, self).do_start()
+
+    @property
+    def state(self):
+        if self._state == ResourceState.STARTED:
+            is_running = self.simulation.invoke(self.uuid, "isAppRunning")
+            
+            if not is_running:
+                self.set_stopped()
+
+        return self._state
+
diff --git a/src/nepi/resources/ns3/ns3arpl3protocol.py b/src/nepi/resources/ns3/ns3arpl3protocol.py
new file mode 100644 (file)
index 0000000..b40c581
--- /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
+
+@clsinit_copy
+class NS3BaseArpL3Protocol(NS3Base):
+    _rtype = "abstract::ns3::ArpL3Protocol"
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+
+        if not nodes: 
+            msg = "ArpL3Protocol not connected to node"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return nodes[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.node)
+        return rms
+
diff --git a/src/nepi/resources/ns3/ns3base.py b/src/nepi/resources/ns3/ns3base.py
new file mode 100644 (file)
index 0000000..f38915f
--- /dev/null
@@ -0,0 +1,167 @@
+#
+#    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 ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+from nepi.execution.attribute import Flags
+from nepi.execution.trace import TraceAttr
+
+@clsinit_copy
+class NS3Base(ResourceManager):
+    _rtype = "abstract::ns3::Object"
+    _backend_type = "ns3"
+
+    def __init__(self, ec, guid):
+        super(NS3Base, self).__init__(ec, guid)
+        self._uuid = None
+        self._connected = set()
+        self._trace_filename = dict()
+
+    @property
+    def connected(self):
+        return self._connected
+
+    @property
+    def uuid(self):
+        return self._uuid
+
+    @property
+    def simulation(self):
+        return self.node.simulation
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+        if nodes: return nodes[0]
+        return None
+
+    def trace(self, name, attr = TraceAttr.ALL, block = 512, offset = 0):
+        filename = self._trace_filename.get(name)
+        if not filename:
+            self.error("Can resolve trace %s. Did you enabled it?" % name)
+            return ""
+
+        return self.simulation.trace(filename, attr, block, offset)
+
+    @property
+    def _rms_to_wait(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
+
+        """
+        rms = set()
+        node = self.node
+        if node: rms.add(node)
+        return rms
+
+    def _instantiate_object(self):
+        if self.uuid:
+            return 
+
+        kwargs = dict()
+        for attr in self._attrs.values():
+            if not ( attr.has_flag(Flags.Construct) and attr.has_changed() ):
+                continue
+
+            kwargs[attr.name] = attr._value
+
+        self._uuid = self.simulation.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.simulation.invoke(node.uuid, "AggregateObject", self.uuid)
+            self._connected.add(node.uuid)
+
+    def _wait_rms(self):
+        """ Returns True if dependent RMs are not yer READY, False otherwise"""
+        for rm in self._rms_to_wait:
+            if rm and rm.state < ResourceState.READY:
+                return True
+        return False
+
+    def do_provision(self):
+        # TODO: create run dir for ns3 object !!!!
+        # self.simulation.node.mkdir(self.run_home)
+
+        self._instantiate_object()
+        self._connect_object()
+        self._configure_object()
+      
+        self.info("Provisioning finished")
+
+        super(NS3Base, self).do_provision()
+
+    def do_deploy(self):
+        if self._wait_rms():
+            self.debug("---- RESCHEDULING DEPLOY ----" )
+            self.ec.schedule(reschedule_delay, self.deploy)
+        else:
+            self.do_discover()
+            self.do_provision()
+
+            self.set_ready()
+
+    def do_start(self):
+        if self.state == ResourceState.READY:
+            # No need to do anything, simulation.Run() will start every object
+            self.info("Starting")
+            self.set_started()
+        else:
+            msg = " Failed "
+            self.error(msg, out, err)
+            raise RuntimeError, msg
+
+    def do_stop(self):
+        if self.state == ResourceState.STARTED:
+            # No need to do anything, simulation.Destroy() will stop every object
+            self.info("Stopping command '%s'" % command)
+            self.set_stopped()
+    
+    @property
+    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
new file mode 100644 (file)
index 0000000..bdeec57
--- /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 NS3BaseChannel(NS3Base):
+    _rtype = "abstract::ns3::Channel"
+
+    @property
+    def simulation(self):
+        return self.devices[0].node.simulation
+
+    @property
+    def devices(self):
+        from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice
+        devices = self.get_connected(NS3BaseNetDevice.get_rtype())
+
+        if not devices: 
+            msg = "Channel not connected to devices"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return devices
+
+    @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/ns3client.py b/src/nepi/resources/ns3/ns3client.py
new file mode 100644 (file)
index 0000000..4a9b48d
--- /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>
+
+class NS3Client(object):
+    """ Common Interface for NS3 client classes """
+    def __init__(self):
+        super(NS3Client, self).__init__()
+
+    def create(self, *args, **kwargs):
+        pass
+
+    def factory(self, *args, **kwargs):
+        pass
+
+    def invoke(self, *args, **kwargs):
+        pass
+
+    def set(self, *args, **kwargs):
+        pass
+
+    def get(self, *args, **kwargs):
+        pass
+
+    def flush(self, *args, **kwargs):
+        pass
+
+    def start(self, *args, **kwargs):
+        pass
+
+    def stop(self, *args, **kwargs):
+        pass
+
+    def shutdown(self, *args, **kwargs):
+        pass
+
diff --git a/src/nepi/resources/ns3/ns3errormodel.py b/src/nepi/resources/ns3/ns3errormodel.py
new file mode 100644 (file)
index 0000000..d46293f
--- /dev/null
@@ -0,0 +1,50 @@
+#
+#    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 NS3BaseErrorModel(NS3Base):
+    _rtype = "abstract::ns3::ErrorModel"
+
+    @property
+    def device(self):
+        from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice
+        devices = self.get_connected(NS3BaseNetDevice.get_rtype())
+
+        if not devices: 
+            msg = "ErrorModel not connected to device"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return devices[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.device)
+        return rms
+
+    def _connect_object(self):
+        device = self.device
+        if device.uuid not in self.connected:
+            self.simulation.invoke(device.uuid, "SetReceiveErrorModel", self.uuid)
+            self._connected.add(device.uuid)
+
diff --git a/src/nepi/resources/ns3/ns3errorratemodel.py b/src/nepi/resources/ns3/ns3errorratemodel.py
new file mode 100644 (file)
index 0000000..961b541
--- /dev/null
@@ -0,0 +1,54 @@
+#
+#    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 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
+        phys = self.get_connected(NS3BaseWifiPhy.get_rtype())
+
+        if not phys: 
+            msg = "ErrorRateModel not connected to phy"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return phys[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.phy)
+        return rms
+
+    def _connect_object(self):
+        phy = self.phy
+        if phy.uuid not in self.connected:
+            self.simulation.invoke(phy.uuid, "SetErrorRateModel", self.uuid)
+            self._connected.add(phy.uuid)
+
diff --git a/src/nepi/resources/ns3/ns3icmpv4l4protocol.py b/src/nepi/resources/ns3/ns3icmpv4l4protocol.py
new file mode 100644 (file)
index 0000000..94f8128
--- /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
+
+@clsinit_copy
+class NS3BaseIcmpv4L4Protocol(NS3Base):
+    _rtype = "abstract::ns3::Icmpv4L4Protocol"
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+
+        if not nodes: 
+            msg = "Icmp4L4Protocol not connected to node"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return nodes[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.node)
+        return rms
+
diff --git a/src/nepi/resources/ns3/ns3ipv4l3protocol.py b/src/nepi/resources/ns3/ns3ipv4l3protocol.py
new file mode 100644 (file)
index 0000000..5d53943
--- /dev/null
@@ -0,0 +1,66 @@
+#
+#    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 NS3BaseIpv4L3Protocol(NS3Base):
+    _rtype = "abstract::ns3::Ipv4L3Protocol"
+
+    def __init__(self, ec, guid):
+        super(NS3BaseIpv4L3Protocol, self).__init__(ec, guid)
+        self.list_routing_uuid = None
+        self.static_routing_uuid = None
+        self.global_routing_uuid = None
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+
+        if not nodes: 
+            msg = "Ipv4L3Protocol not connected to node"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return nodes[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.simulation)
+        return rms
+
+    def _configure_object(self):
+        simulation = self.simulation
+
+        self.list_routing_uuid = simulation.create("Ipv4ListRouting")
+        simulation.invoke(self.uuid, "SetRoutingProtocol", self.list_routing_uuid)
+
+        self.static_routing_uuid = simulation.create("Ipv4StaticRouting")
+        simulation.invoke(self.list_routing_uuid, "AddRoutingProtocol", 
+                self.static_routing_uuid, 0)
+
+        self.global_routing_uuid = simulation.create("Ipv4GlobalRouting")
+        simulation.invoke(self.list_routing_uuid, "AddRoutingProtocol", 
+                self.global_routing_uuid, -10)
+
+    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
diff --git a/src/nepi/resources/ns3/ns3netdevice.py b/src/nepi/resources/ns3/ns3netdevice.py
new file mode 100644 (file)
index 0000000..f136dd8
--- /dev/null
@@ -0,0 +1,231 @@
+#
+#    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.attribute import Attribute, Flags
+from nepi.execution.resource import clsinit_copy
+from nepi.execution.trace import Trace
+from nepi.resources.ns3.ns3base import NS3Base
+
+import ipaddr
+
+@clsinit_copy
+class NS3BaseNetDevice(NS3Base):
+    _rtype = "abstract::ns3::NetDevice"
+
+    @classmethod
+    def _register_attributes(cls):
+        mac = Attribute("mac", "MAC address for device",
+                flags = Flags.Design)
+
+        ip = Attribute("ip", "IP address for device",
+                flags = Flags.Design)
+
+        prefix = Attribute("prefix", "Network prefix for device",
+                flags = Flags.Design)
+
+        cls._register_attribute(mac)
+        cls._register_attribute(ip)
+        cls._register_attribute(prefix)
+
+    @classmethod
+    def _register_traces(cls):
+        pcap = Trace("pcap", "Dump traffic sniffed on the network device in Pcap format")
+        promisc_pcap = Trace("promiscPcap", "Dump traffic sniffed in promiscuous mode on the network device in Pcap format")
+        ascii = Trace("ascii", "Dump traffic sniffed on the network device in Ascii format")
+
+        cls._register_trace(pcap)
+        cls._register_trace(promisc_pcap)
+        cls._register_trace(ascii)
+
+    def __init__(self, ec, guid):
+        super(NS3BaseNetDevice, self).__init__(ec, guid)
+        self._ascii_helper_uuid = None
+        self._device_helper_uuid = None
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+
+        if not nodes: 
+            msg = "Device not connected to node"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return nodes[0]
+
+    @property
+    def channel(self):
+        from nepi.resources.ns3.ns3channel import NS3BaseChannel
+        channels = self.get_connected(NS3BaseChannel.get_rtype())
+
+        if not channels: 
+            msg = "Device not connected to channel"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return channels[0]
+
+    @property
+    def queue(self):
+        from nepi.resources.ns3.ns3queue import NS3BaseQueue
+        queue = self.get_connected(NS3BaseQueue.get_rtype())
+
+        if not queue: 
+            msg = "Device not connected to queue"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return queue[0]
+
+    @property
+    def ascii_helper_uuid(self):
+        if not self._ascii_helper_uuid:
+            self._ascii_helper_uuid = self.simulation.create("AsciiTraceHelper")
+        return self._ascii_helper_uuid
+
+    @property
+    def device_helper_uuid(self):
+        if not self._device_helper_uuid:
+            rtype = self.get_rtype()
+            if rtype == "ns3::PointToPointNetDevice":
+                classname = "PointToPointHelper"
+            elif rtype == "ns3::CsmaNetDevice":
+                classname = "CsmaHelper"
+            elif rtype == "ns3::EmuNetDevice":
+                classname = "EmuHelper"
+            elif rtype == "ns3::FdNetDevice":
+                classname = "FdNetDeviceHelper"
+            elif rtype in [ "ns3::BaseStationNetDevice", "SubscriberStationNetDevice" ]:
+                classname = "WimaxHelper"
+            elif rtype == "ns3::WifiNetDevice":
+                classname = "YansWifiPhyHelper"
+
+            self._device_helper_uuid = self.simulation.create(classname)
+
+        return self._device_helper_uuid
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        
+        node = self.node
+        rms.add(node)
+
+        ipv4 = node.ipv4
+        if node.ipv4:
+            rms.add(ipv4)
+
+        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)
+
+    def _configure_ip_address(self):
+        ip = self.get("ip")
+        prefix = self.get("prefix")
+
+        i = ipaddr.IPAddress(ip)
+        if i.version == 4:
+            # IPv4
+            ipv4 = self.node.ipv4
+            ifindex_uuid = self.simulation.invoke(ipv4.uuid, "AddInterface", 
+                    self.uuid)
+            ipv4_addr_uuid = self.simulation.create("Ipv4Address", ip)
+            ipv4_mask_uuid = self.simulation.create("Ipv4Mask", "/%s" % str(prefix))
+            inaddr_uuid = self.simulation.create("Ipv4InterfaceAddress", 
+                    ipv4_addr_uuid, ipv4_mask_uuid)
+            self.simulation.invoke(ipv4.uuid, "AddAddress", ifindex_uuid, 
+                    inaddr_uuid)
+            self.simulation.invoke(ipv4.uuid, "SetMetric", ifindex_uuid, 1)
+            self.simulation.invoke(ipv4.uuid, "SetUp", ifindex_uuid)
+        else:
+            # IPv6
+            # TODO!
+            pass
+
+    def _configure_traces(self):
+        if self.trace_enabled("pcap"):
+            helper_uuid = self.device_helper_uuid
+
+            filename = "trace-pcap-netdev-%d.pcap" % self.guid
+            self._trace_filename["pcap"] = filename
+
+            filepath = self.simulation.trace_filepath(filename)
+
+            self.simulation.invoke(helper_uuid, "EnablePcap", filepath, 
+                    self.uuid, promiscuous = False, explicitFilename = True)
+
+        if self.trace_enabled("promiscPcap"):
+            helper_uuid = self.device_helper_uuid
+
+            filename = "trace-promisc-pcap-netdev-%d.pcap" % self.guid
+            self._trace_filename["promiscPcap"] = filename
+
+            filepath = self.simulation.trace_filepath(filename)
+
+            self.simulation.invoke(helper_uuid, "EnablePcap", filepath, 
+                    self.uuid, promiscuous = True, explicitFilename = True)
+
+        if self.trace_enabled("ascii"):
+            helper_uuid = self.device_helper_uuid
+            ascii_helper_uuid = self.ascii_helper_uuid
+
+            filename = "trace-ascii-netdev-%d.tr" % self.guid
+            self._trace_filename["ascii"] = filename
+
+            filepath = self.simulation.trace_filepath(filename)
+            stream_uuid = self.simulation.invoke(ascii_helper_uuid, 
+                    "CreateFileStream", filepath) 
+            self.simulation.invoke(helper_uuid, "EnableAscii", stream_uuid,
+                    self.uuid)
+
+    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)
+
+        channel = self.channel
+        if channel and channel.uuid not in self.connected:
+            self.simulation.invoke(self.uuid, "Attach", channel.uuid)
+            self._connected.add(channel.uuid)
+        
+        queue = self.queue
+        # Verify that the device has a queue. If no queue is added a segfault 
+        # error occurs
+        if queue and queue.uuid not in self.connected:
+            self._connected.add(queue.uuid)
diff --git a/src/nepi/resources/ns3/ns3node.py b/src/nepi/resources/ns3/ns3node.py
new file mode 100644 (file)
index 0000000..0d6f691
--- /dev/null
@@ -0,0 +1,94 @@
+#
+#    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 = "abstract::ns3::Node"
+
+    @property
+    def simulation(self):
+        from nepi.resources.ns3.ns3simulation import NS3Simulation
+        for guid in self.connections:
+            rm = self.ec.get_resource(guid)
+            if isinstance(rm, NS3Simulation):
+                return rm
+
+        msg = "Node not connected to simulation"
+        self.error(msg)
+        raise RuntimeError, msg
+    @property
+    def ipv4(self):
+        from nepi.resources.ns3.ns3ipv4l3protocol import NS3BaseIpv4L3Protocol
+        ipv4s = self.get_connected(NS3BaseIpv4L3Protocol.get_rtype())
+        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 devices(self):
+        from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice
+        devices = self.get_connected(NS3BaseNetDevice.get_rtype())
+
+        if not devices: 
+            msg = "Node not connected to devices"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return devices
+
+    @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):
+        ### node.AggregateObject(PacketSocketFactory())
+        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
new file mode 100644 (file)
index 0000000..f091ec8
--- /dev/null
@@ -0,0 +1,54 @@
+#
+#    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 NS3BasePropagationDelayModel(NS3Base):
+    _rtype = "abstract::ns3::PropagationDelayModel"
+
+    @property
+    def simulation(self):
+        return self.channel.simulation
+
+    @property
+    def channel(self):
+        from nepi.resources.ns3.ns3wifichannel import NS3BaseWifiChannel
+        channels = self.get_connected(NS3BaseWifiChannel.get_rtype())
+
+        if not channels: 
+            msg = "PropagationDelayModel not connected to channel"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return channels[0]
+
+    @property
+    def _rms_to_wait(self):
+        others = set()
+        others.add(self.channel)
+        return others
+
+    def _connect_object(self):
+        channel = self.channel
+        if channel.uuid not in self.connected:
+            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
new file mode 100644 (file)
index 0000000..94d0dab
--- /dev/null
@@ -0,0 +1,54 @@
+#
+#    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 NS3BasePropagationLossModel(NS3Base):
+    _rtype = "ns3::PropagationLossModel"
+
+    @property
+    def simulation(self):
+        return self.channel.simulation
+
+    @property
+    def channel(self):
+        from nepi.resources.ns3.ns3wifichannel import NS3BaseWifiChannel
+        channels = self.get_connected(NS3BaseWifiChannel.get_rtype())
+
+        if not channels: 
+            msg = "PropagationLossModel not connected to channel"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return channels[0]
+
+    @property
+    def _rms_to_wait(self):
+        others = set()
+        others.add(self.channel)
+        return others
+
+    def _connect_object(self):
+        channel = self.channel
+        if channel.uuid not in self.connected:
+            self.simulation.invoke(channel.uuid, "SetPropagationLossModel", self.uuid)
+            self._connected.add(channel.uuid)
+
diff --git a/src/nepi/resources/ns3/ns3queue.py b/src/nepi/resources/ns3/ns3queue.py
new file mode 100644 (file)
index 0000000..d7ec2b7
--- /dev/null
@@ -0,0 +1,54 @@
+#
+#    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 NS3BaseQueue(NS3Base):
+    _rtype = "abstract::ns3::Queue"
+
+    @property
+    def device(self):
+        from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice
+        devices = self.get_connected(NS3BaseNetDevice.get_rtype())
+
+        if not devices: 
+            msg = "Queue not connected to device"
+            self.error(msg, out, err)
+            raise RuntimeError, msg
+
+        return devices[0]
+
+    @property
+    def node(self):
+        return self.device.node
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.device)
+        return rms
+
+    def _connect_object(self):
+        device = self.device
+        if device.uuid not in self.connected:
+            self.simulation.invoke(device.uuid, "SetQueue", self.uuid)
+            self._connected.add(device.uuid)
+
diff --git a/src/nepi/resources/ns3/ns3route.py b/src/nepi/resources/ns3/ns3route.py
new file mode 100644 (file)
index 0000000..bb61368
--- /dev/null
@@ -0,0 +1,93 @@
+#
+#    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.attribute import Attribute, Flags
+from nepi.execution.resource import clsinit_copy
+from nepi.execution.trace import Trace
+from nepi.resources.ns3.ns3base import NS3Base
+
+import ipaddr
+
+@clsinit_copy
+class NS3Route(NS3Base):
+    _rtype = "ns3::Route"
+
+    @classmethod
+    def _register_attributes(cls):
+        network = Attribute("network", "Destination network address",
+                flags = Flags.Design)
+
+        prefix = Attribute("prefix", "Network prefix for the network",
+                flags = Flags.Design)
+
+        nexthop = Attribute("nexthop", "Address of next hop in the route",
+                flags = Flags.Design)
+
+        cls._register_attribute(network)
+        cls._register_attribute(prefix)
+        cls._register_attribute(nexthop)
+
+    def __init__(self, ec, guid):
+        super(NS3Route, self).__init__(ec, guid)
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+
+        if not nodes: 
+            msg = "Device not connected to node"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return nodes[0]
+
+    @property
+    def _rms_to_wait(self):
+        # Wait for all network devices connected to the node to be ready
+        # before configuring the routes, else the route might refer to a
+        # non yet existing interface
+
+        rms = set()
+        rms.update(self.node.devices)
+        return rms
+
+    def _instantiate_object(self):
+        pass
+
+    def _configure_object(self):
+        network = self.get("network")
+        prefix = self.get("prefix")
+        nexthop = self.get("nexthop")
+        ipv4_uuid = self.node.ipv4.uuid
+
+        ret = self.simulation.invoke(ipv4_uuid, "addStaticRoute", network, 
+            prefix, nexthop)
+
+        if not ret: 
+            msg = "Could not configure route %s/%s hop: %s" % (network, prefix, 
+                    nexthop)
+            self.error(msg)
+            raise RuntimeError, msg
+
+    def _connect_object(self):
+        node = self.node
+        if node and node.uuid not in self.connected:
+            self._connected.add(node.uuid)
+
diff --git a/src/nepi/resources/ns3/ns3server.py b/src/nepi/resources/ns3/ns3server.py
new file mode 100644 (file)
index 0000000..f761b86
--- /dev/null
@@ -0,0 +1,254 @@
+#
+#    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>
+
+import base64
+import cPickle
+import errno
+import logging
+import os
+import socket
+import sys
+
+from optparse import OptionParser, SUPPRESS_HELP
+
+from ns3wrapper import NS3Wrapper
+
+class NS3WrapperMessage:
+    CREATE = "CREATE"
+    FACTORY = "FACTORY"
+    INVOKE = "INVOKE"
+    SET = "SET"
+    GET = "GET"
+    FLUSH = "FLUSH"
+    START = "START"
+    STOP = "STOP"
+    SHUTDOWN = "SHUTDOWN"
+
+def handle_message(ns3_wrapper, msg_type, args, kwargs):
+    if msg_type == NS3WrapperMessage.SHUTDOWN:
+        ns3_wrapper.shutdown()
+        
+        ns3_wrapper.logger.debug("SHUTDOWN")
+        
+        return "BYEBYE"
+    
+    if msg_type == NS3WrapperMessage.STOP:
+        time = kwargs.get("time")
+
+        ns3_wrapper.logger.debug("STOP time=%s" % str(time))
+
+        ns3_wrapper.stop(time=time)
+        return "STOPPED"
+
+    if msg_type == NS3WrapperMessage.START:
+        ns3_wrapper.logger.debug("START") 
+
+        ns3_wrapper.start()
+        return "STARTED"
+
+    if msg_type == NS3WrapperMessage.CREATE:
+        clazzname = args.pop(0)
+        
+        ns3_wrapper.logger.debug("CREATE %s %s" % (clazzname, str(args)))
+
+        uuid = ns3_wrapper.create(clazzname, *args)
+        return uuid
+
+    if msg_type == NS3WrapperMessage.FACTORY:
+        type_name = args.pop(0)
+
+        ns3_wrapper.logger.debug("FACTORY %s %s" % (type_name, str(kwargs)))
+
+        uuid = ns3_wrapper.factory(type_name, **kwargs)
+        return uuid
+
+    if msg_type == NS3WrapperMessage.INVOKE:
+        uuid = args.pop(0)
+        operation = args.pop(0)
+        
+        ns3_wrapper.logger.debug("INVOKE %s %s %s %s " % (uuid, operation, 
+            str(args), str(kwargs)))
+    
+        uuid = ns3_wrapper.invoke(uuid, operation, *args, **kwargs)
+        return uuid
+
+    if msg_type == NS3WrapperMessage.GET:
+        uuid = args.pop(0)
+        name = args.pop(0)
+
+        ns3_wrapper.logger.debug("GET %s %s" % (uuid, name))
+
+        value = ns3_wrapper.get(uuid, name)
+        return value
+
+    if msg_type == NS3WrapperMessage.SET:
+        uuid = args.pop(0)
+        name = args.pop(0)
+        value = args.pop(0)
+
+        ns3_wrapper.logger.debug("SET %s %s %s" % (uuid, name, str(value)))
+
+        value = ns3_wrapper.set(uuid, name, value)
+        return value
+    if msg_type == NS3WrapperMessage.FLUSH:
+        # Forces flushing output and error streams.
+        # NS-3 output will stay unflushed until the program exits or 
+        # explicit invocation flush is done
+        sys.stdout.flush()
+        sys.stderr.flush()
+
+        ns3_wrapper.logger.debug("FLUSHED") 
+        
+        return "FLUSHED"
+
+def create_socket(socket_name):
+    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+    sock.bind(socket_name)
+    return sock
+
+def recv_msg(conn):
+    msg = []
+    chunk = ''
+
+    while '\n' not in chunk:
+        try:
+            chunk = conn.recv(1024)
+        except (OSError, socket.error), e:
+            if e[0] != errno.EINTR:
+                raise
+            # Ignore eintr errors
+            continue
+
+        if chunk:
+            msg.append(chunk)
+        else:
+            # empty chunk = EOF
+            break
+    msg = ''.join(msg).strip()
+
+    # The message is formatted as follows:
+    #   MESSAGE_TYPE|args|kwargs
+    #
+    #   where MESSAGE_TYPE, args and kwargs are pickld and enoded in base64
+
+    def decode(item):
+        item = base64.b64decode(item).rstrip()
+        return cPickle.loads(item)
+
+    decoded = map(decode, msg.split("|"))
+
+    # decoded message
+    dmsg_type = decoded.pop(0)
+    dargs = list(decoded.pop(0)) # transforming touple into list
+    dkwargs = decoded.pop(0)
+
+    return (dmsg_type, dargs, dkwargs)
+
+def send_reply(conn, reply):
+    encoded = base64.b64encode(cPickle.dumps(reply))
+    conn.send("%s\n" % encoded)
+
+def get_options():
+    usage = ("usage: %prog -S <socket-name> -L <NS_LOG> -v ")
+    
+    parser = OptionParser(usage = usage)
+
+    parser.add_option("-S", "--socket-name", dest="socket_name",
+        help = "Name for the unix socket used to interact with this process", 
+        default = "tap.sock", type="str")
+
+    parser.add_option("-L", "--ns-log", dest="ns_log",
+        help = "NS_LOG environmental variable to be set", 
+        default = "", type="str")
+
+    parser.add_option("-v", "--verbose",
+        help="Print debug output",
+        action="store_true", 
+        dest="verbose", default=False)
+
+    (options, args) = parser.parse_args()
+    
+    return (options.socket_name, options.verbose, options.ns_log)
+
+def run_server(socket_name, level = logging.INFO, ns_log = None):
+
+    # Sets NS_LOG environmental variable for NS debugging
+    if ns_log:
+        os.environ["NS_LOG"] = ns_log
+
+    ###### ns-3 wrapper instantiation
+
+    ns3_wrapper = NS3Wrapper(loglevel=level)
+    
+    ns3_wrapper.logger.info("STARTING...")
+
+    # create unix socket to receive instructions
+    sock = create_socket(socket_name)
+    sock.listen(0)
+
+    # wait for messages to arrive and process them
+    stop = False
+
+    while not stop:
+        conn, addr = sock.accept()
+        conn.settimeout(5)
+
+        try:
+            (msg_type, args, kwargs) = recv_msg(conn)
+        except socket.timeout, e:
+            # Ingore time-out
+            continue
+
+        if not msg_type:
+            # Ignore - connection lost
+            break
+
+        if msg_type == NS3WrapperMessage.SHUTDOWN:
+           stop = True
+  
+        try:
+            reply = handle_message(ns3_wrapper, msg_type, args, kwargs)  
+        except:
+            import traceback
+            err = traceback.format_exc()
+            ns3_wrapper.logger.error(err) 
+            raise
+
+        try:
+            send_reply(conn, reply)
+        except socket.error:
+            break
+        
+    ns3_wrapper.logger.info("EXITING...")
+
+if __name__ == '__main__':
+            
+    (socket_name, verbose, ns_log) = get_options()
+
+    ## configure logging
+    FORMAT = "%(asctime)s %(name)s %(levelname)-4s %(message)s"
+    level = logging.DEBUG if verbose else logging.INFO
+
+    logging.basicConfig(format = FORMAT, level = level)
+
+    ## Run the server
+    run_server(socket_name, level, ns_log)
+
diff --git a/src/nepi/resources/ns3/ns3simulation.py b/src/nepi/resources/ns3/ns3simulation.py
new file mode 100644 (file)
index 0000000..f98237f
--- /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>
+
+class NS3Simulation(object):
+    @property
+    def client(self):
+        return self._client
+
+    def create(self, *args, **kwargs):
+        return self.client.create(*args, **kwargs)
+
+    def factory(self, *args, **kwargs):
+        return self.client.factory(*args, **kwargs)
+
+    def invoke(self, *args, **kwargs):
+        return self.client.invoke(*args, **kwargs)
+
+    def ns3_set(self, *args, **kwargs):
+        return self.client.set(*args, **kwargs)
+
+    def ns3_get(self, *args, **kwargs):
+        return self.client.get(*args, **kwargs)
+
+    def flush(self, *args, **kwargs):
+        return self.client.flush(*args, **kwargs)
+
+    def start(self, *args, **kwargs):
+        return self.client.start(*args, **kwargs)
+
+    def stop(self, *args, **kwargs):
+        return self.client.stop(*args, **kwargs)
+
+    def shutdown(self, *args, **kwargs):
+        return self.client.shutdown(*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
+
diff --git a/src/nepi/resources/ns3/ns3wifimac.py b/src/nepi/resources/ns3/ns3wifimac.py
new file mode 100644 (file)
index 0000000..e8ab8b6
--- /dev/null
@@ -0,0 +1,80 @@
+#
+#    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.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.ns3wifinetdevice import NS3BaseWifiNetDevice
+        devices = self.get_connected(NS3BaseWifiNetDevice.get_rtype())
+
+        if not devices: 
+            msg = "WifiMac not connected to device"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return devices[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.device)
+        return rms
+
+    def _connect_object(self):
+        device = self.device
+        if device.uuid not in self.connected:
+            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)
+
diff --git a/src/nepi/resources/ns3/ns3wifiphy.py b/src/nepi/resources/ns3/ns3wifiphy.py
new file mode 100644 (file)
index 0000000..4ea0248
--- /dev/null
@@ -0,0 +1,88 @@
+#
+#    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.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.ns3wifinetdevice import NS3BaseWifiNetDevice
+        devices = self.get_connected(NS3BaseWifiNetDevice.get_rtype())
+
+        if not devices: 
+            msg = "WifiPhy not connected to device"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        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()
+        rms.add(self.device)
+        return rms
+
+    def _connect_object(self):
+        device = self.device
+        if device.uuid not in self.connected:
+            self._connected.add(device.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
new file mode 100644 (file)
index 0000000..764c097
--- /dev/null
@@ -0,0 +1,55 @@
+#
+#    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.ns3netdevice import NS3BaseNetDevice
+
+@clsinit_copy
+class NS3BaseWifiRemoteStationManager(NS3Base):
+    _rtype = "abstract::ns3::WifiRemoteStationManager"
+
+    @property
+    def node(self):
+        return self.device.node
+
+    @property
+    def device(self):
+        from nepi.resources.ns3.ns3wifinetdevice import NS3BaseWifiNetDevice
+        devices = self.get_connected(NS3BaseWifiNetDevice.get_rtype())
+
+        if not devices: 
+            msg = "WifiRemoteStationManager not connected to device"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        return devices[0]
+
+    @property
+    def _rms_to_wait(self):
+        rms = set()
+        rms.add(self.device)
+        return rms
+
+    def _connect_object(self):
+        device = self.device
+        if device.uuid not in self.connected:
+            self.simulation.invoke(device.uuid, "SetRemoteStationManager", self.uuid)
+            self._connected.add(device.uuid)
+
index 388fcb7..b7ed192 100644 (file)
@@ -21,143 +21,273 @@ import logging
 import os
 import sys
 import threading
+import time
 import uuid
 
+SINGLETON = "singleton::"
+SIMULATOR_UUID = "singleton::Simulator"
+CONFIG_UUID = "singleton::Config"
+GLOBAL_VALUE_UUID = "singleton::GlobalValue"
+IPV4_GLOBAL_ROUTING_HELPER_UUID = "singleton::Ipv4GlobalRoutingHelper"
+
+def load_ns3_module():
+    import ctypes
+    import re
+
+    bindings = os.environ.get("NS3BINDINGS")
+    libdir = os.environ.get("NS3LIBRARIES")
+
+    # Load the ns-3 modules shared libraries
+    if libdir:
+        files = os.listdir(libdir)
+        regex = re.compile("(.*\.so)$")
+        libs = [m.group(1) for filename in files for m in [regex.search(filename)] if m]
+
+        initial_size = len(libs)
+        # Try to load the libraries in the right order by trial and error.
+        # Loop until all libraries are loaded.
+        while len(libs) > 0:
+            for lib in libs:
+                libfile = os.path.join(libdir, lib)
+                try:
+                    ctypes.CDLL(libfile, ctypes.RTLD_GLOBAL)
+                    libs.remove(lib)
+                except:
+                    #import traceback
+                    #err = traceback.format_exc()
+                    #print err
+                    pass
+
+            # if did not load any libraries in the last iteration break
+            # to prevent infinit loop
+            if initial_size == len(libs):
+                raise RuntimeError("Imposible to load shared libraries %s" % str(libs))
+            initial_size = list(libs)
+
+    # import the python bindings for the ns-3 modules
+    if bindings:
+        sys.path.append(bindings)
+
+    import pkgutil
+    import imp
+    import ns
+
+    # create a Python module to add all ns3 classes
+    ns3mod = imp.new_module("ns3")
+    sys.modules["ns3"] = ns3mod
+
+    for importer, modname, ispkg in pkgutil.iter_modules(ns.__path__):
+        if modname in [ "visualizer" ]:
+            continue
+
+        fullmodname = "ns.%s" % modname
+        module = __import__(fullmodname, globals(), locals(), ['*'])
+
+        for sattr in dir(module):
+            if sattr.startswith("_"):
+                continue
+
+            attr = getattr(module, sattr)
+
+            # netanim.Config and lte.Config singleton overrides ns3::Config
+            if sattr == "Config" and modname in ['netanim', 'lte']:
+                sattr = "%s.%s" % (modname, sattr)
+
+            setattr(ns3mod, sattr, attr)
+
+    return ns3mod
+
 class NS3Wrapper(object):
-    def __init__(self, homedir = None):
+    def __init__(self, loglevel = logging.INFO):
         super(NS3Wrapper, self).__init__()
-        self._ns3 = None
-        self._uuid = self.make_uuid()
-        self._homedir = homedir or os.path.join("/tmp", self._uuid)
+        # Thread used to run the simulation
         self._simulation_thread = None
         self._condition = None
 
+        # True if Simulator::Run was invoked
         self._started = False
-        self._stopped = False
-
-        # holds reference to all ns-3 objects in the simulation
-        self._resources = dict()
 
-        # create home dir (where all simulation related files will end up)
-        home = os.path.normpath(self.homedir)
-        if not os.path.exists(home):
-            os.makedirs(home, 0755)
+        # holds reference to all C++ objects and variables in the simulation
+        self._objects = dict()
 
         # Logging
-        loglevel = os.environ.get("NS3LOGLEVEL", "debug")
-        self._logger = logging.getLogger("ns3wrapper.%s" % self.uuid)
-        self._logger.setLevel(getattr(logging, loglevel.upper()))
-        hdlr = logging.FileHandler(os.path.join(self.homedir, "ns3wrapper.log"))
-        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
-        hdlr.setFormatter(formatter)
-        self._logger.addHandler(hdlr) 
-
-        # Load ns-3 shared libraries and import modules
-        self._load_ns3_module()
-        
+        self._logger = logging.getLogger("ns3wrapper")
+        self._logger.setLevel(loglevel)
+
+        ## NOTE that the reason to create a handler to the ns3 module,
+        # that is re-loaded each time a ns-3 wrapper is instantiated,
+        # is that else each unit test for the ns3wrapper class would need
+        # a separate file. Several ns3wrappers would be created in the 
+        # same unit test (single process), leading to inchorences in the 
+        # state of ns-3 global objects
+        #
+        # Handler to ns3 classes
+        self._ns3 = None
+
+        # Collection of allowed ns3 classes
+        self._allowed_types = None
+
     @property
     def ns3(self):
-        return self._ns3
+        if not self._ns3:
+            # load ns-3 libraries and bindings
+            self._ns3 = load_ns3_module()
 
-    @property
-    def homedir(self):
-        return self._homedir
+        return self._ns3
 
     @property
-    def uuid(self):
-        return self._uuid
+    def allowed_types(self):
+        if not self._allowed_types:
+            self._allowed_types = set()
+            type_id = self.ns3.TypeId()
+            
+            tid_count = type_id.GetRegisteredN()
+            base = type_id.LookupByName("ns3::Object")
+
+            for i in xrange(tid_count):
+                tid = type_id.GetRegistered(i)
+                
+                if tid.MustHideFromDocumentation() or \
+                        not tid.HasConstructor() or \
+                        not tid.IsChildOf(base): 
+                    continue
+
+                type_name = tid.GetName()
+                self._allowed_types.add(type_name)
+        
+        return self._allowed_types
 
     @property
     def logger(self):
         return self._logger
 
+    @property
+    def is_running(self):
+        return self._started and self.ns3.Simulator.IsFinished()
+
     def make_uuid(self):
         return "uuid%s" % uuid.uuid4()
 
-    def singleton(self, clazzname):
-        uuid = "uuid%s"%clazzname
-
-        if not uuid in self._resources:
-            if not hasattr(self.ns3, clazzname):
-                msg = "Type %s not supported" % (typeid) 
-                self.logger.error(msg)
+    def get_object(self, uuid):
+        return self._objects.get(uuid)
 
-            clazz = getattr(self.ns3, clazzname)
-            typeid = "ns3::%s" % clazzname
-            self._resources[uuid] = (clazz, typeid)
+    def factory(self, type_name, **kwargs):
+        if type_name not in self.allowed_types:
+            msg = "Type %s not supported" % (type_name) 
+            self.logger.error(msg)
+        factory = self.ns3.ObjectFactory()
+        factory.SetTypeId(type_name)
 
-        return uuid
+        for name, value in kwargs.iteritems():
+            ns3_value = self._attr_from_string_to_ns3_value(type_name, name, value)
+            factory.Set(name, ns3_value)
 
-    def get_trace(self, trace, offset = None, nbytes = None ):
-        pass
+        obj = factory.Create()
 
-    def is_running(self):
-        return self._started and not self._stopped
+        uuid = self.make_uuid()
+        self._objects[uuid] = obj
 
-    def get_resource(self, uuid):
-        (resource, typeid) =  self._resources.get(uuid)
-        return resource
-    
-    def get_typeid(self, uuid):
-        (resource, typeid) =  self._resources.get(uuid)
-        return typeid
+        return uuid
 
     def create(self, clazzname, *args):
         if not hasattr(self.ns3, clazzname):
             msg = "Type %s not supported" % (clazzname) 
             self.logger.error(msg)
-
+     
         clazz = getattr(self.ns3, clazzname)
-        #typeid = clazz.GetInstanceTypeId().GetName()
-        typeid = "ns3::%s" % clazzname
-
-        realargs = [self.get_resource(arg) if \
-                str(arg).startswith("uuid") else arg for arg in args]
-      
-        resource = clazz(*realargs)
+        # arguments starting with 'uuid' identify ns-3 C++
+        # objects and must be replaced by the actual object
+        realargs = self.replace_args(args)
+       
+        obj = clazz(*realargs)
         
         uuid = self.make_uuid()
-        self._resources[uuid] = (resource, typeid)
+        self._objects[uuid] = obj
+
         return uuid
 
-    def set(self, uuid, name, value):
-        resource = self.get_resource(uuid)
+    def invoke(self, uuid, operation, *args, **kwargs):
+        if operation == "isAppRunning":
+            return self._is_app_running(uuid)
+        if operation == "addStaticRoute":
+            return self._add_static_route(uuid, *args)
 
-        if hasattr(resource, name):
-            setattr(resource, name, value)
+        if uuid.startswith(SINGLETON):
+            obj = self._singleton(uuid)
         else:
-            self._set_ns3_attr(uuid, name, value)
+            obj = self.get_object(uuid)
+        
+        method = getattr(obj, operation)
 
-    def get(self, name, uuid = None):
-        resource = self.get_resource(uuid)
+        # arguments starting with 'uuid' identify ns-3 C++
+        # objects and must be replaced by the actual object
+        realargs = self.replace_args(args)
+        realkwargs = self.replace_kwargs(kwargs)
 
-        value = None
-        if hasattr(resource, name):
-            value = getattr(resource, name)
-        else:
-            value = self._get_ns3_attr(uuid, name)
+        result = method(*realargs, **realkwargs)
+
+        if result is None or \
+                isinstance(result, bool):
+            return result
+      
+        newuuid = self.make_uuid()
+        self._objects[newuuid] = result
+
+        return newuuid
+
+    def _set_attr(self, obj, name, ns3_value):
+        obj.SetAttribute(name, ns3_value)
+
+    def set(self, uuid, name, value):
+        obj = self.get_object(uuid)
+        type_name = obj.GetInstanceTypeId().GetName()
+        ns3_value = self._attr_from_string_to_ns3_value(type_name, name, value)
+
+        # If the Simulation thread is not running,
+        # then there will be no thread-safety problems
+        # in changing the value of an attribute directly.
+        # However, if the simulation is running we need
+        # to set the value by scheduling an event, else
+        # we risk to corrupt the state of the
+        # simulation.
+        
+        event_executed = [False]
+
+        if self.is_running:
+            # schedule the event in the Simulator
+            self._schedule_event(self._condition, event_executed, 
+                    self._set_attr, obj, name, ns3_value)
+
+        if not event_executed[0]:
+            self._set_attr(obj, name, ns3_value)
 
         return value
 
-    def invoke(self, uuid, operation, *args):
-        resource = self.get_resource(uuid)
-        typeid = self.get_typeid(uuid)
-        method = getattr(resource, operation)
+    def _get_attr(self, obj, name, ns3_value):
+        obj.GetAttribute(name, ns3_value)
 
-        realargs = [self.get_resource(arg) if \
-                str(arg).startswith("uuid") else arg for arg in args]
+    def get(self, uuid, name):
+        obj = self.get_object(uuid)
+        type_name = obj.GetInstanceTypeId().GetName()
+        ns3_value = self._create_attr_ns3_value(type_name, name)
 
-        result = method(*realargs)
+        event_executed = [False]
 
-        if not result:
-            return None
-        
-        uuid = self.make_uuid()
-        self._resources[uuid] = (result, typeid)
+        if self.is_running:
+            # schedule the event in the Simulator
+            self._schedule_event(self._condition, event_executed,
+                    self._get_attr, obj, name, ns3_value)
 
-        return uuid
+        if not event_executed[0]:
+            self._get_attr(obj, name, ns3_value)
+
+        return self._attr_from_ns3_value_to_string(type_name, name, ns3_value)
 
     def start(self):
+        # Launch the simulator thread and Start the
+        # simulator in that thread
         self._condition = threading.Condition()
         self._simulator_thread = threading.Thread(
                 target = self._simulator_run,
@@ -167,51 +297,46 @@ class NS3Wrapper(object):
         self._started = True
 
     def stop(self, time = None):
-        if not self.ns3:
-            return
-
         if time is None:
             self.ns3.Simulator.Stop()
         else:
             self.ns3.Simulator.Stop(self.ns3.Time(time))
-        self._stopped = True
 
     def shutdown(self):
-        if self.ns3:
-            if not self.ns3.Simulator.IsFinished():
-                self.stop()
-            
-            # TODO!!!! SHOULD WAIT UNTIL THE THREAD FINISHES
-            if self._simulator_thread:
-                self._simulator_thread.join()
-            
-            self.ns3.Simulator.Destroy()
+        while not self.ns3.Simulator.IsFinished():
+            #self.logger.debug("Waiting for simulation to finish")
+            time.sleep(0.5)
         
-        self._resources.clear()
+        if self._simulator_thread:
+            self._simulator_thread.join()
+       
+        self.ns3.Simulator.Destroy()
+        
+        # Remove all references to ns-3 objects
+        self._objects.clear()
         
-        self._ns3 = None
         sys.stdout.flush()
         sys.stderr.flush()
 
     def _simulator_run(self, condition):
         # Run simulation
         self.ns3.Simulator.Run()
-        # Signal condition on simulation end to notify waiting threads
+        # Signal condition to indicate simulation ended and
+        # notify waiting threads
         condition.acquire()
         condition.notifyAll()
         condition.release()
 
-    def _schedule_event(self, condition, func, *args):
+    def _schedule_event(self, condition, event_executed, func, *args):
         """ Schedules event on running simulation, and wait until
             event is executed"""
 
-        def execute_event(contextId, condition, has_event_occurred, func, *args):
+        def execute_event(contextId, condition, event_executed, func, *args):
             try:
                 func(*args)
+                event_executed[0] = True
             finally:
-                # flag event occured
-                has_event_occurred[0] = True
-                # notify condition indicating attribute was set
+                # notify condition indicating event was executed
                 condition.acquire()
                 condition.notifyAll()
                 condition.release()
@@ -221,71 +346,37 @@ class NS3Wrapper(object):
 
         # delay 0 means that the event is expected to execute inmediately
         delay = self.ns3.Seconds(0)
+    
+        # Mark event as not executed
+        event_executed[0] = False
 
-        # flag to indicate that the event occured
-        # because bool is an inmutable object in python, in order to create a
-        # bool flag, a list is used as wrapper
-        has_event_occurred = [False]
         condition.acquire()
         try:
+            self.ns3.Simulator.ScheduleWithContext(contextId, delay, execute_event, 
+                    condition, event_executed, func, *args)
             if not self.ns3.Simulator.IsFinished():
-                self.ns3.Simulator.ScheduleWithContext(contextId, delay, execute_event,
-                     condition, has_event_occurred, func, *args)
-                while not has_event_occurred[0] and not self.ns3.Simulator.IsFinished():
-                    condition.wait()
+                condition.wait()
         finally:
             condition.release()
 
-    def _set_ns3_attr(self, uuid, name, value):
-        resource = self.get_resource(uuid)
-        ns3_value = self._to_ns3_value(uuid, name, value)
-
-        def set_attr(resource, name, ns3_value):
-            resource.SetAttribute(name, ns3_value)
-
-        if self._is_running:
-            # schedule the event in the Simulator
-            self._schedule_event(self._condition, set_attr, resource,
-                    name, ns3_value)
-        else:
-            set_attr(resource, name, ns3_value)
-
-    def _get_ns3_attr(self, uuid, name):
-        resource = self.get_resource(uuid)
-        ns3_value = self._create_ns3_value(uuid, name)
-
-        def get_attr(resource, name, ns3_value):
-            resource.GetAttribute(name, ns3_value)
-
-        if self._is_running:
-            # schedule the event in the Simulator
-            self._schedule_event(self._condition, get_attr, resource,
-                    name, ns3_value)
-        else:
-            get_attr(resource, name, ns3_value)
-
-        return self._from_ns3_value(uuid, name, ns3_value)
-
-    def _create_ns3_value(self, uuid, name):
-        typeid = get_typeid(uuid)
+    def _create_attr_ns3_value(self, type_name, name):
         TypeId = self.ns3.TypeId()
-        tid = TypeId.LookupByName(typeid)
+        tid = TypeId.LookupByName(type_name)
         info = TypeId.AttributeInformation()
         if not tid.LookupAttributeByName(name, info):
-            msg = "TypeId %s has no attribute %s" % (typeid, name) 
+            msg = "TypeId %s has no attribute %s" % (type_name, name) 
             self.logger.error(msg)
 
         checker = info.checker
         ns3_value = checker.Create() 
         return ns3_value
 
-    def _from_ns3_value(self, uuid, name, ns3_value):
-        typeid = get_typeid(uuid)
+    def _attr_from_ns3_value_to_string(self, type_name, name, ns3_value):
         TypeId = self.ns3.TypeId()
-        tid = TypeId.LookupByName(typeid)
+        tid = TypeId.LookupByName(type_name)
         info = TypeId.AttributeInformation()
         if not tid.LookupAttributeByName(name, info):
-            msg = "TypeId %s has no attribute %s" % (typeid, name) 
+            msg = "TypeId %s has no attribute %s" % (type_name, name) 
             self.logger.error(msg)
 
         checker = info.checker
@@ -301,13 +392,12 @@ class NS3Wrapper(object):
 
         return value
 
-    def _to_ns3_value(self, uuid, name, value):
-        typeid = get_typeid(uuid)
+    def _attr_from_string_to_ns3_value(self, type_name, name, value):
         TypeId = self.ns3.TypeId()
-        typeid = TypeId.LookupByName(typeid)
+        tid = TypeId.LookupByName(type_name)
         info = TypeId.AttributeInformation()
         if not tid.LookupAttributeByName(name, info):
-            msg = "TypeId %s has no attribute %s" % (typeid, name) 
+            msg = "TypeId %s has no attribute %s" % (type_name, name) 
             self.logger.error(msg)
 
         str_value = str(value)
@@ -319,62 +409,105 @@ class NS3Wrapper(object):
         ns3_value.DeserializeFromString(str_value, checker)
         return ns3_value
 
-    def _load_ns3_module(self):
-        if self.ns3:
-            return 
-
-        import ctypes
-        import imp
-        import re
-        import pkgutil
-
-        bindings = os.environ.get("NS3BINDINGS")
-        libdir = os.environ.get("NS3LIBRARIES")
-
-        # Load the ns-3 modules shared libraries
-        if libdir:
-            files = os.listdir(libdir)
-            regex = re.compile("(.*\.so)$")
-            libs = [m.group(1) for filename in files for m in [regex.search(filename)] if m]
-
-            libscp = list(libs)
-            while len(libs) > 0:
-                for lib in libs:
-                    libfile = os.path.join(libdir, lib)
-                    try:
-                        ctypes.CDLL(libfile, ctypes.RTLD_GLOBAL)
-                        libs.remove(lib)
-                    except:
-                        pass
-
-                # if did not load any libraries in the last iteration break
-                # to prevent infinit loop
-                if len(libscp) == len(libs):
-                    raise RuntimeError("Imposible to load shared libraries %s" % str(libs))
-                libscp = list(libs)
-
-        # import the python bindings for the ns-3 modules
-        if bindings:
-            sys.path.append(bindings)
-
-        # create a module to add all ns3 classes
-        ns3mod = imp.new_module("ns3")
-        sys.modules["ns3"] = ns3mod
-
-        # retrieve all ns3 classes and add them to the ns3 module
-        import ns
-        for importer, modname, ispkg in pkgutil.iter_modules(ns.__path__):
-            fullmodname = "ns.%s" % modname
-            module = __import__(fullmodname, globals(), locals(), ['*'])
-
-            # netanim.Config singleton overrides ns3::Config
-            if modname in ['netanim']:
-                continue
+    # singletons are identified as "ns3::ClassName"
+    def _singleton(self, ident):
+        if not ident.startswith(SINGLETON):
+            return None
 
-            for sattr in dir(module):
-                if not sattr.startswith("_"):
-                    attr = getattr(module, sattr)
-                    setattr(ns3mod, sattr, attr)
+        clazzname = ident[ident.find("::")+2:]
+        if not hasattr(self.ns3, clazzname):
+            msg = "Type %s not supported" % (clazzname)
+            self.logger.error(msg)
 
-        self._ns3 = ns3mod
+        return getattr(self.ns3, clazzname)
+
+    # replace uuids and singleton references for the real objects
+    def replace_args(self, args):
+        realargs = [self.get_object(arg) if \
+                str(arg).startswith("uuid") else arg for arg in args]
+        realargs = [self._singleton(arg) if \
+                str(arg).startswith(SINGLETON) else arg for arg in realargs]
+
+        return realargs
+
+    # replace uuids and singleton references for the real objects
+    def replace_kwargs(self, kwargs):
+        realkwargs = dict([(k, self.get_object(v) \
+                if str(v).startswith("uuid") else v) \
+                for k,v in kwargs.iteritems()])
+        realkwargs = dict([(k, self._singleton(v) \
+                if str(v).startswith(SINGLETON) else v )\
+                for k, v in realkwargs.iteritems()])
+
+        return realkwargs
+
+    def _is_app_running(self, uuid): 
+        now = self.ns3.Simulator.Now()
+        if now.IsZero():
+            return False
+
+        app = self.get_object(uuid)
+        stop_time_value = self.ns3.TimeValue()
+        app.GetAttribute("StopTime", stop_time_value)
+        stop_time = stop_time_value.Get()
+
+        start_time_value = self.ns3.TimeValue()
+        app.GetAttribute("StartTime", start_time_value)
+        start_time = start_time_value.Get()
+        
+        if now.Compare(start_time) >= 0 and now.Compare(stop_time) < 0:
+            return True
+
+        return False
+
+    def _add_static_route(self, ipv4_uuid, network, prefix, nexthop):
+        ipv4 = self.get_object(ipv4_uuid)
+
+        list_routing = ipv4.GetRoutingProtocol()
+        (static_routing, priority) = list_routing.GetRoutingProtocol(0)
+
+        ifindex = self._find_ifindex(ipv4, nexthop)
+        if ifindex == -1:
+            return False
+        
+        nexthop = self.ns3.Ipv4Address(nexthop)
+
+        if network in ["0.0.0.0", "0", None]:
+            # Default route: 0.0.0.0/0
+            static_routing.SetDefaultRoute(nexthop, ifindex)
+        else:
+            mask = self.ns3.Ipv4Mask("/%s" % prefix) 
+            network = self.ns3.Ipv4Address(network)
+
+            if prefix == 32:
+                # Host route: x.y.z.w/32
+                static_routing.AddHostRouteTo(network, nexthop, ifindex)
+            else:
+                # Network route: x.y.z.w/n
+                static_routing.AddNetworkRouteTo(network, mask, nexthop, 
+                        ifindex) 
+        return True
+
+    def _find_ifindex(self, ipv4, nexthop):
+        ifindex = -1
+
+        nexthop = self.ns3.Ipv4Address(nexthop)
+
+        # For all the interfaces registered with the ipv4 object, find
+        # the one that matches the network of the nexthop
+        nifaces = ipv4.GetNInterfaces()
+        for ifidx in xrange(nifaces):
+            iface = ipv4.GetInterface(ifidx)
+            naddress = iface.GetNAddresses()
+            for addridx in xrange(naddress):
+                ifaddr = iface.GetAddress(addridx)
+                ifmask = ifaddr.GetMask()
+                
+                ifindex = ipv4.GetInterfaceForPrefix(nexthop, ifmask)
+
+                if ifindex == ifidx:
+                    return ifindex
+        return ifindex
 
diff --git a/src/nepi/resources/ns3/ns3wrapper_server.py b/src/nepi/resources/ns3/ns3wrapper_server.py
deleted file mode 100644 (file)
index 2773948..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-#
-#    NEPI, a framework to manage network experiments
-#    Copyright (C) 2013 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/>.
-#
-
-
-
-class Server(object):
-    def __init__(self, root_dir = ".", log_level = "ERROR", 
-            environment_setup = "", clean_root = False):
-        self._root_dir = root_dir
-        self._clean_root = clean_root
-        self._stop = False
-        self._ctrl_sock = None
-        self._log_level = log_level
-        self._rdbuf = ""
-        self._environment_setup = environment_setup
-
-    def run(self):
-        try:
-            if self.daemonize():
-                self.post_daemonize()
-                self.loop()
-                self.cleanup()
-                # ref: "os._exit(0)"
-                # can not return normally after fork beacuse no exec was done.
-                # This means that if we don't do a os._exit(0) here the code that 
-                # follows the call to "Server.run()" in the "caller code" will be 
-                # executed... but by now it has already been executed after the 
-                # first process (the one that did the first fork) returned.
-                os._exit(0)
-        except:
-            print >>sys.stderr, "SERVER_ERROR."
-            self.log_error()
-            self.cleanup()
-            os._exit(0)
-        print >>sys.stderr, "SERVER_READY."
-
-    def daemonize(self):
-        # pipes for process synchronization
-        (r, w) = os.pipe()
-        
-        # build root folder
-        root = os.path.normpath(self._root_dir)
-        if self._root_dir not in [".", ""] and os.path.exists(root) \
-                and self._clean_root:
-            shutil.rmtree(root)
-        if not os.path.exists(root):
-            os.makedirs(root, 0755)
-
-        pid1 = os.fork()
-        if pid1 > 0:
-            os.close(w)
-            while True:
-                try:
-                    os.read(r, 1)
-                except OSError, e: # pragma: no cover
-                    if e.errno == errno.EINTR:
-                        continue
-                    else:
-                        raise
-                break
-            os.close(r)
-            # os.waitpid avoids leaving a <defunc> (zombie) process
-            st = os.waitpid(pid1, 0)[1]
-            if st:
-                raise RuntimeError("Daemonization failed")
-            # return 0 to inform the caller method that this is not the 
-            # daemonized process
-            return 0
-        os.close(r)
-
-        # Decouple from parent environment.
-        os.chdir(self._root_dir)
-        os.umask(0)
-        os.setsid()
-
-        # fork 2
-        pid2 = os.fork()
-        if pid2 > 0:
-            # see ref: "os._exit(0)"
-            os._exit(0)
-
-        # close all open file descriptors.
-        max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
-        if (max_fd == resource.RLIM_INFINITY):
-            max_fd = MAX_FD
-        for fd in range(3, max_fd):
-            if fd != w:
-                try:
-                    os.close(fd)
-                except OSError:
-                    pass
-
-        # Redirect standard file descriptors.
-        stdin = open(DEV_NULL, "r")
-        stderr = stdout = open(STD_ERR, "a", 0)
-        os.dup2(stdin.fileno(), sys.stdin.fileno())
-        # NOTE: sys.stdout.write will still be buffered, even if the file
-        # was opened with 0 buffer
-        os.dup2(stdout.fileno(), sys.stdout.fileno())
-        os.dup2(stderr.fileno(), sys.stderr.fileno())
-        
-        # setup environment
-        if self._environment_setup:
-            # parse environment variables and pass to child process
-            # do it by executing shell commands, in case there's some heavy setup involved
-            envproc = subprocess.Popen(
-                [ "bash", "-c", 
-                    "( %s python -c 'import os,sys ; print \"\\x01\".join(\"\\x02\".join(map(str,x)) for x in os.environ.iteritems())' ) | tail -1" %
-                        ( self._environment_setup, ) ],
-                stdin = subprocess.PIPE, 
-                stdout = subprocess.PIPE,
-                stderr = subprocess.PIPE
-            )
-            out,err = envproc.communicate()
-
-            # parse new environment
-            if out:
-                environment = dict(map(lambda x:x.split("\x02"), out.split("\x01")))
-            
-                # apply to current environment
-                for name, value in environment.iteritems():
-                    os.environ[name] = value
-                
-                # apply pythonpath
-                if 'PYTHONPATH' in environment:
-                    sys.path = environment['PYTHONPATH'].split(':') + sys.path
-
-        # create control socket
-        self._ctrl_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        try:
-            self._ctrl_sock.bind(CTRL_SOCK)
-        except socket.error:
-            # Address in use, check pidfile
-            pid = None
-            try:
-                pidfile = open(CTRL_PID, "r")
-                pid = pidfile.read()
-                pidfile.close()
-                pid = int(pid)
-            except:
-                # no pidfile
-                pass
-            
-            if pid is not None:
-                # Check process liveliness
-                if not os.path.exists("/proc/%d" % (pid,)):
-                    # Ok, it's dead, clean the socket
-                    os.remove(CTRL_SOCK)
-            
-            # try again
-            self._ctrl_sock.bind(CTRL_SOCK)
-            
-        self._ctrl_sock.listen(0)
-        
-        # Save pidfile
-        pidfile = open(CTRL_PID, "w")
-        pidfile.write(str(os.getpid()))
-        pidfile.close()
-
-        # let the parent process know that the daemonization is finished
-        os.write(w, "\n")
-        os.close(w)
-        return 1
-
-    def post_daemonize(self):
-        os.environ["NEPI_CONTROLLER_LOGLEVEL"] = self._log_level
-        # QT, for some strange reason, redefines the SIGCHILD handler to write
-        # a \0 to a fd (lets say fileno 'x'), when ever a SIGCHILD is received.
-        # Server dameonization closes all file descriptors from fileno '3',
-        # but the overloaded handler (inherited by the forked process) will
-        # keep trying to write the \0 to fileno 'x', which might have been reused 
-        # after closing, for other operations. This is bad bad bad when fileno 'x'
-        # is in use for communication pouroses, because unexpected \0 start
-        # appearing in the communication messages... this is exactly what happens 
-        # when using netns in daemonized form. Thus, be have no other alternative than
-        # restoring the SIGCHLD handler to the default here.
-        import signal
-        signal.signal(signal.SIGCHLD, signal.SIG_DFL)
-
-    def loop(self):
-        while not self._stop:
-            conn, addr = self._ctrl_sock.accept()
-            self.log_error("ACCEPTED CONNECTION: %s" % (addr,))
-            conn.settimeout(5)
-            while not self._stop:
-                try:
-                    msg = self.recv_msg(conn)
-                except socket.timeout, e:
-                    #self.log_error("SERVER recv_msg: connection timedout ")
-                    continue
-                
-                if not msg:
-                    self.log_error("CONNECTION LOST")
-                    break
-                    
-                if msg == STOP_MSG:
-                    self._stop = True
-                    reply = self.stop_action()
-                else:
-                    reply = self.reply_action(msg)
-                
-                try:
-                    self.send_reply(conn, reply)
-                except socket.error:
-                    self.log_error()
-                    self.log_error("NOTICE: Awaiting for reconnection")
-                    break
-            try:
-                conn.close()
-            except:
-                # Doesn't matter
-                self.log_error()
-
-    def recv_msg(self, conn):
-        data = [self._rdbuf]
-        chunk = data[0]
-        while '\n' not in chunk:
-            try:
-                chunk = conn.recv(1024)
-            except (OSError, socket.error), e:
-                if e[0] != errno.EINTR:
-                    raise
-                else:
-                    continue
-            if chunk:
-                data.append(chunk)
-            else:
-                # empty chunk = EOF
-                break
-        data = ''.join(data).split('\n',1)
-        while len(data) < 2:
-            data.append('')
-        data, self._rdbuf = data
-        
-        decoded = base64.b64decode(data)
-        return decoded.rstrip()
-
-    def send_reply(self, conn, reply):
-        encoded = base64.b64encode(reply)
-        conn.send("%s\n" % encoded)
-       
-    def cleanup(self):
-        try:
-            self._ctrl_sock.close()
-            os.remove(CTRL_SOCK)
-        except:
-            self.log_error()
-
-    def stop_action(self):
-        return "Stopping server"
-
-    def reply_action(self, msg):
-        return "Reply to: %s" % msg
-
-    def log_error(self, text = None, context = ''):
-        if text == None:
-            text = traceback.format_exc()
-        date = time.strftime("%Y-%m-%d %H:%M:%S")
-        if context:
-            context = " (%s)" % (context,)
-        sys.stderr.write("ERROR%s: %s\n%s\n" % (context, date, text))
-        return text
-
-    def log_debug(self, text):
-        if self._log_level == DC.DEBUG_LEVEL:
-            date = time.strftime("%Y-%m-%d %H:%M:%S")
-            sys.stderr.write("DEBUG: %s\n%s\n" % (date, text))
-
-class Forwarder(object):
-    def __init__(self, root_dir = "."):
-        self._ctrl_sock = None
-        self._root_dir = root_dir
-        self._stop = False
-        self._rdbuf = ""
-
-    def forward(self):
-        self.connect()
-        print >>sys.stderr, "FORWARDER_READY."
-        while not self._stop:
-            data = self.read_data()
-            if not data:
-                # Connection to client lost
-                break
-            self.send_to_server(data)
-            
-            data = self.recv_from_server()
-            if not data:
-                # Connection to server lost
-                raise IOError, "Connection to server lost while "\
-                    "expecting response"
-            self.write_data(data)
-        self.disconnect()
-
-    def read_data(self):
-        return sys.stdin.readline()
-
-    def write_data(self, data):
-        sys.stdout.write(data)
-        # sys.stdout.write is buffered, this is why we need to do a flush()
-        sys.stdout.flush()
-
-    def send_to_server(self, data):
-        try:
-            self._ctrl_sock.send(data)
-        except (IOError, socket.error), e:
-            if e[0] == errno.EPIPE:
-                self.connect()
-                self._ctrl_sock.send(data)
-            else:
-                raise e
-        encoded = data.rstrip() 
-        msg = base64.b64decode(encoded)
-        if msg == STOP_MSG:
-            self._stop = True
-
-    def recv_from_server(self):
-        data = [self._rdbuf]
-        chunk = data[0]
-        while '\n' not in chunk:
-            try:
-                chunk = self._ctrl_sock.recv(1024)
-            except (OSError, socket.error), e:
-                if e[0] != errno.EINTR:
-                    raise
-                continue
-            if chunk:
-                data.append(chunk)
-            else:
-                # empty chunk = EOF
-                break
-        data = ''.join(data).split('\n',1)
-        while len(data) < 2:
-            data.append('')
-        data, self._rdbuf = data
-        
-        return data+'\n'
-    def connect(self):
-        self.disconnect()
-        self._ctrl_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        sock_addr = os.path.join(self._root_dir, CTRL_SOCK)
-        self._ctrl_sock.connect(sock_addr)
-
-    def disconnect(self):
-        try:
-            self._ctrl_sock.close()
-        except:
-            pass
-
diff --git a/src/nepi/resources/ns3/resource_manager_generator.py b/src/nepi/resources/ns3/resource_manager_generator.py
new file mode 100644 (file)
index 0000000..9ec844e
--- /dev/null
@@ -0,0 +1,225 @@
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 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>
+
+# Force the load of ns3 libraries
+from nepi.resources.ns3.ns3wrapper import load_ns3_module
+
+import os
+import re
+
+base_types = ["ns3::Node",
+        "ns3::Application", 
+        "ns3::NetDevice",
+        "ns3::Channel",
+        "ns3::Queue",
+        "ns3::Icmpv4L4Protocol",
+        "ns3::ArpL3Protocol",
+        "ns3::Ipv4L3Protocol",
+        "ns3::PropagationLossModel",
+        "ns3::MobilityModel",
+        "ns3::PropagationDelayModel",
+        "ns3::WifiRemoteStationManager",
+        "ns3::WifiNetDevice",
+        "ns3::WifiChannel",
+        "ns3::WifiPhy",
+        "ns3::WifiMac",
+        "ns3::ErrorModel",
+        "ns3::ErrorRateModel"]
+
+def discard(ns3, tid):
+    rtype = tid.GetName()
+    type_id = ns3.TypeId()
+
+    for type_name in base_types:
+        tid_base = type_id.LookupByName(type_name)
+        if type_name == rtype or tid.IsChildOf(tid_base):
+            return False
+
+    return True
+
+def select_base_class(ns3, tid): 
+    base_class_import = "from nepi.resources.ns3.ns3base import NS3Base"
+    base_class = "NS3Base"
+   
+    rtype = tid.GetName()
+
+    type_id = ns3.TypeId()
+
+    for type_name in base_types:
+        tid_base = type_id.LookupByName(type_name)
+        if type_name == rtype or tid.IsChildOf(tid_base):
+            base_class = "NS3Base" + type_name.replace("ns3::", "")
+            base_module = "ns3" + type_name.replace("ns3::", "").lower()
+            base_class_import = "from nepi.resources.ns3.%s import %s " % (
+                    base_module, base_class)
+
+    return (base_class_import, base_class)
+
+def create_ns3_rms():
+    ns3 = load_ns3_module()
+
+    type_id = ns3.TypeId()
+    
+    tid_count = type_id.GetRegisteredN()
+    base = type_id.LookupByName("ns3::Object")
+
+    # Create a .py file using the ns-3 RM template for each ns-3 TypeId
+    for i in xrange(tid_count):
+        tid = type_id.GetRegistered(i)
+        
+        if discard(ns3, tid):
+            continue
+        
+        if tid.MustHideFromDocumentation() or \
+                not tid.HasConstructor() or \
+                not tid.IsChildOf(base): 
+            continue
+       
+        attributes = template_attributes(ns3, tid)
+        traces = template_traces(ns3, tid)
+        ptid = tid
+        while ptid.HasParent():
+            ptid = ptid.GetParent()
+            attributes += template_attributes(ns3, ptid)
+            traces += template_traces(ns3, ptid)
+
+        attributes = "\n" + attributes if attributes else "pass"
+        traces = "\n" + traces if traces else "pass"
+
+        (base_class_import, base_class) = select_base_class(ns3, tid)
+
+        category = tid.GetGroupName()
+
+        rtype = tid.GetName()
+        classname = rtype.replace("ns3::", "NS3").replace("::","")
+        uncamm_rtype = re.sub('([a-z])([A-Z])', r'\1-\2', rtype).lower()
+        short_rtype = uncamm_rtype.replace("::","-")
+
+        d = os.path.dirname(os.path.realpath(__file__))
+        ftemp = open(os.path.join(d, "templates", "resource_manager_template.txt"), "r")
+        template = ftemp.read()
+        ftemp.close()
+
+        template = template. \
+                replace("<CLASS_NAME>", classname). \
+                replace("<RTYPE>", rtype). \
+                replace("<ATTRIBUTES>", attributes). \
+                replace("<TRACES>", traces). \
+                replace("<BASE_CLASS_IMPORT>", base_class_import). \
+                replace("<BASE_CLASS>", base_class). \
+                replace("<SHORT-RTYPE>", short_rtype)
+
+        fname = uncamm_rtype.replace('ns3::', ''). \
+                replace('::', ''). \
+                replace("-","_").lower() + ".py"
+
+        f = open(os.path.join(d, "classes", fname), "w")
+        print os.path.join(d, fname)
+        print template
+        f.write(template)
+        f.close()
+
+def template_attributes(ns3, tid): 
+    d = os.path.dirname(os.path.realpath(__file__))
+    ftemp = open(os.path.join(d, "templates", "attribute_template.txt"), "r")
+    template = ftemp.read()
+    ftemp.close()
+
+    attributes = ""
+
+    attr_count = tid.GetAttributeN()
+    for i in xrange(attr_count):
+        attr_info = tid.GetAttribute(i)
+        if not attr_info.accessor.HasGetter():
+            continue
+
+        attr_flags = "Flags.Reserved"
+        flags = attr_info.flags
+        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
+        attr_help = attr_info.help.replace('"', '\\"').replace("'", "\\'")
+        value = attr_info.initialValue
+        attr_value = value.SerializeToString(checker)
+        attr_allowed = "None"
+        attr_range = "None"
+        attr_type = "Types.String"
+
+        if isinstance(value, ns3.ObjectVectorValue):
+            continue
+        elif isinstance(value, ns3.PointerValue):
+            continue
+        elif isinstance(value, ns3.WaypointValue):
+            continue
+        elif isinstance(value, ns3.BooleanValue):
+            attr_type = "Types.Bool"
+            attr_value = "True" if attr_value == "true" else "False"
+        elif isinstance(value, ns3.EnumValue):
+            attr_type = "Types.Enumerate"
+            allowed = checker.GetUnderlyingTypeInformation().split("|")
+            attr_allowed = "[%s]" % ",".join(map(lambda x: "\"%s\"" % x, allowed))
+        elif isinstance(value, ns3.DoubleValue):
+            attr_type = "Types.Double"
+            # TODO: range
+        elif isinstance(value, ns3.UintegerValue):
+            attr_type = "Types.Integer"
+            # TODO: range
+
+        attr_id = "attr_" + attr_name.lower().replace("-", "_")
+        attributes += template.replace("<ATTR_ID>", attr_id) \
+                .replace("<ATTR_NAME>", attr_name) \
+                .replace("<ATTR_HELP>", attr_help) \
+                .replace("<ATTR_TYPE>", attr_type) \
+                .replace("<ATTR_DEFAULT>", attr_value) \
+                .replace("<ATTR_ALLOWED>", attr_allowed) \
+                .replace("<ATTR_RANGE>", attr_range) \
+                .replace("<ATTR_FLAGS>", attr_flags) 
+
+    return attributes
+
+def template_traces(ns3, tid): 
+    d = os.path.dirname(os.path.realpath(__file__))
+    ftemp = open(os.path.join(d, "templates", "trace_template.txt"), "r")
+    template = ftemp.read()
+    ftemp.close()
+
+    traces = ""
+
+    trace_count = tid.GetTraceSourceN()
+    for i in xrange(trace_count):
+        trace_info = tid.GetTraceSource(i)
+        trace_name = trace_info.name
+        trace_help = trace_info.help.replace('"', '\\"').replace("'", "\\'")
+
+        trace_id = trace_name.lower()
+        traces += template.replace("<TRACE_ID>", trace_id) \
+                .replace("<TRACE_NAME>", trace_name) \
+                .replace("<TRACE_HELP>", trace_help) 
+
+    return traces
+
+if __name__ == "__main__":
+    create_ns3_rms()
diff --git a/src/nepi/resources/ns3/templates/attribute_template.txt b/src/nepi/resources/ns3/templates/attribute_template.txt
new file mode 100644 (file)
index 0000000..651496e
--- /dev/null
@@ -0,0 +1,10 @@
+        <ATTR_ID> = Attribute("<ATTR_NAME>",
+            "<ATTR_HELP>",
+            type = <ATTR_TYPE>,
+            default = "<ATTR_DEFAULT>",  
+            allowed = <ATTR_ALLOWED>,
+            range = <ATTR_RANGE>,    
+            flags = <ATTR_FLAGS>)
+
+        cls._register_attribute(<ATTR_ID>)
+
diff --git a/src/nepi/resources/ns3/templates/resource_manager_template.txt b/src/nepi/resources/ns3/templates/resource_manager_template.txt
new file mode 100644 (file)
index 0000000..c3b6a58
--- /dev/null
@@ -0,0 +1,39 @@
+#
+#    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/>.
+#
+
+from nepi.execution.attribute import Attribute, Flags, Types
+from nepi.execution.trace import Trace, TraceAttr
+from nepi.execution.resource import ResourceManager, clsinit_copy, \
+        ResourceState, reschedule_delay
+<BASE_CLASS_IMPORT>
+
+@clsinit_copy
+class <CLASS_NAME>(<BASE_CLASS>):
+    _rtype = "<RTYPE>"
+
+    @classmethod
+    def _register_attributes(cls):
+        <ATTRIBUTES>
+
+    @classmethod
+    def _register_traces(cls):
+        <TRACES>
+
+    def __init__(self, ec, guid):
+        super(<CLASS_NAME>, self).__init__(ec, guid)
+        self._home = "<SHORT-RTYPE>-%s" % self.guid
diff --git a/src/nepi/resources/ns3/templates/trace_template.txt b/src/nepi/resources/ns3/templates/trace_template.txt
new file mode 100644 (file)
index 0000000..9cedb1e
--- /dev/null
@@ -0,0 +1,4 @@
+        <TRACE_ID> = Trace("<TRACE_NAME>", "<TRACE_HELP>")
+
+        cls._register_trace(<TRACE_ID>)
+
index bc4d0e7..8ef2b50 100644 (file)
@@ -52,11 +52,11 @@ class OMFApplication(OMFResource):
         env = Attribute("env", "Environnement variable of the application")
         stdin = Attribute("stdin", "Input of the application", default = "")
         sources = Attribute("sources", "Sources of the application", 
-                     flags = Flags.ExecReadOnly)
+                     flags = Flags.Design)
         sshuser = Attribute("sshUser", "user to connect with ssh", 
-                     flags = Flags.ExecReadOnly)
+                     flags = Flags.Design)
         sshkey = Attribute("sshKey", "key to use for ssh", 
-                     flags = Flags.ExecReadOnly)
+                     flags = Flags.Design)
         cls._register_attribute(appid)
         cls._register_attribute(path)
         cls._register_attribute(args)
index 330ad64..eb229cd 100644 (file)
@@ -44,7 +44,7 @@ class PlanetlabNode(LinuxNode):
     @classmethod
     def _register_attributes(cls):
         ip = Attribute("ip", "PlanetLab host public IP address",
-                flags = Flags.ReadOnly)
+                    flags = Flags.Design)
 
         pl_url = Attribute("plcApiUrl", "URL of PlanetLab PLCAPI host \
                     (e.g. www.planet-lab.eu or www.planet-lab.org) ",
@@ -54,7 +54,7 @@ class PlanetlabNode(LinuxNode):
         pl_ptn = Attribute("plcApiPattern", "PLC API service regexp pattern \
                     (e.g. https://%(hostname)s:443/PLCAPI/ ) ",
                     default = "https://%(hostname)s:443/PLCAPI/",
-                    flags = Flags.ExecReadOnly)
+                    flags = Flags.Design)
     
         pl_user = Attribute("pluser", "PlanetLab account user, as the one to \
                     authenticate in the website) ",
index b3ce59d..f4b50c6 100644 (file)
@@ -43,13 +43,13 @@ class OVSWitch(LinuxApplication):
 
         """
         bridge_name = Attribute("bridge_name", "Name of the switch/bridge",
-                flags = Flags.ExecReadOnly)    
+                flags = Flags.Design)  
         virtual_ip_pref = Attribute("virtual_ip_pref", "Virtual IP/PREFIX of the switch",
-                flags = Flags.ExecReadOnly)       
+                flags = Flags.Design)  
         controller_ip = Attribute("controller_ip", "IP of the controller",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)  
         controller_port = Attribute("controller_port", "Port of the controller",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)  
 
         cls._register_attribute(bridge_name)
         cls._register_attribute(virtual_ip_pref)
index 57b6f16..cd2e848 100644 (file)
@@ -51,7 +51,7 @@ class OVSPort(LinuxApplication):
 
         """
         port_name = Attribute("port_name", "Name of the port",
-            flags = Flags.ExecReadOnly)                        
+            flags = Flags.Design)                      
 
         cls._register_attribute(port_name)
 
index 0b28327..f076ec1 100644 (file)
@@ -66,25 +66,25 @@ class OVSTunnel(LinuxApplication):
                 default = None,
                 allowed = ["PLAIN", "AES", "Blowfish", "DES", "DES3"],
                 type = Types.Enumerate, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cipher_key = Attribute("cipherKey",
                 "Specify a symmetric encryption key with which to protect "
                 "packets across the tunnel. python-crypto must be installed "
                 "on the system." ,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         txqueuelen = Attribute("txQueueLen",
                 "Specifies the interface's transmission queue length. "
                 "Defaults to 1000. ", 
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         bwlimit = Attribute("bwLimit",
                 "Specifies the interface's emulated bandwidth in bytes "
                 "per second.",
                 type = Types.Integer, 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(network)
         cls._register_attribute(cipher)
index b6b1744..5301265 100644 (file)
@@ -42,35 +42,35 @@ class PlanetlabTap(LinuxApplication):
     @classmethod
     def _register_attributes(cls):
         ip4 = Attribute("ip4", "IPv4 Address",
-              flags = Flags.ExecReadOnly)
+              flags = Flags.Design)
 
         mac = Attribute("mac", "MAC Address",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         prefix4 = Attribute("prefix4", "IPv4 network prefix",
                 type = Types.Integer,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         mtu = Attribute("mtu", "Maximum transmition unit for device",
                 type = Types.Integer)
 
         devname = Attribute("deviceName", 
                 "Name of the network interface (e.g. eth0, wlan0, etc)",
-                flags = Flags.ReadOnly)
+                flags = Flags.NoWrite)
 
         up = Attribute("up", "Link up", 
                 type = Types.Bool)
         
         snat = Attribute("snat", "Set SNAT=1", 
                 type = Types.Bool,
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
         
         pointopoint = Attribute("pointopoint", "Peer IP address", 
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         tear_down = Attribute("tearDown", "Bash script to be executed before " + \
                 "releasing the resource",
-                flags = Flags.ExecReadOnly)
+                flags = Flags.Design)
 
         cls._register_attribute(ip4)
         cls._register_attribute(mac)
@@ -169,7 +169,6 @@ class PlanetlabTap(LinuxApplication):
             self.do_discover()
             self.do_provision()
 
-            self.debug("----- READY ---- ")
             self.set_ready()
 
     def do_start(self):
index b25ae98..d2da3ac 100644 (file)
@@ -24,7 +24,6 @@ import subprocess
 def lexec(command, 
         user = None, 
         sudo = False,
-        stdin = None,
         env = None):
     """
     Executes a local command, returns ((stdout,stderr),process)
@@ -41,13 +40,12 @@ def lexec(command,
         command = "su %s ; %s " % (user, command)
 
 
-    p = subprocess.Popen(command
+    proc = subprocess.Popen(command, shell=True
             stdout = subprocess.PIPE, 
-            stderr = subprocess.PIPE,
-            stdin  = stdin)
+            stderr = subprocess.PIPE)
 
-    out, err = p.communicate()
-    return (out, err)
+    out, err = proc.communicate()
+    return ((out, err), proc)
 
 def lcopy(source, dest, recursive = False):
     """
@@ -71,11 +69,11 @@ def lcopy(source, dest, recursive = False):
 
     args.extend(dest)
 
-    p = subprocess.Popen(command, 
+    proc = subprocess.Popen(command, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE)
 
-    out, err = p.communicate()
+    out, err = proc.communicate()
     return ((out, err), proc)
    
 def lspawn(command, pidfile, 
@@ -135,12 +133,12 @@ def lspawn(command, pidfile,
             'create' : 'mkdir -p %s ; ' % (shell_escape(home),) if create_home else '',
         }
 
-    (out,err),proc = lexec(cmd)
+    (out,err), proc = lexec(cmd)
     
     if proc.wait():
         raise RuntimeError, "Failed to set up application on host %s: %s %s" % (host, out,err,)
 
-    return (out,err),proc
+    return ((out,err), proc)
 
 def lgetpid(pidfile):
     """
@@ -155,7 +153,7 @@ def lgetpid(pidfile):
         or None if the pidfile isn't valid yet (maybe the process is still starting).
     """
 
-    (out,err),proc = lexec("cat %s" % pidfile )
+    (out,err), proc = lexec("cat %s" % pidfile )
         
     if proc.wait():
         return None
@@ -179,7 +177,7 @@ def lstatus(pid, ppid):
         One of NOT_STARTED, RUNNING, FINISHED
     """
 
-    (out,err),proc = lexec(
+    (out,err), proc = lexec(
         # Check only by pid. pid+ppid does not always work (especially with sudo) 
         " (( ps --pid %(pid)d -o pid | grep -c %(pid)d && echo 'wait')  || echo 'done' ) | tail -n 1" % {
             'ppid' : ppid,
@@ -194,8 +192,8 @@ def lstatus(pid, ppid):
         status = (out.strip() == 'wait')
     else:
         return ProcStatus.NOT_STARTED
+
     return ProcStatus.RUNNING if status else ProcStatus.FINISHED
 
 def lkill(pid, ppid, sudo = False):
     """
index 1df46b9..b9b5342 100644 (file)
@@ -18,6 +18,8 @@
 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
 #         Claudio Freire <claudio-daniel.freire@inria.fr>
 
+## TODO: This code needs reviewing !!!
+
 import base64
 import errno
 import hashlib
@@ -210,15 +212,12 @@ def rexec(command, host, user,
         gw = None, 
         agent = True,
         sudo = False,
-        stdin = None,
         identity = None,
         server_key = None,
         env = None,
         tty = False,
-        timeout = None,
-        retry = 3,
-        err_on_timeout = True,
         connect_timeout = 30,
+        retry = 3,
         persistent = True,
         forward_x11 = False,
         blocking = True,
@@ -285,60 +284,21 @@ def rexec(command, host, user,
         command = "sudo " + command
 
     args.append(command)
-
-    for x in xrange(retry):
-        # connects to the remote host and starts a remote connection
-        proc = subprocess.Popen(args,
-                env = env,
-                stdout = subprocess.PIPE,
-                stdin = subprocess.PIPE, 
-                stderr = subprocess.PIPE)
-       
-        # attach tempfile object to the process, to make sure the file stays
-        # alive until the process is finished with it
-        proc._known_hosts = tmp_known_hosts
     
-        # by default, rexec calls _communicate which will block 
-        # until the process has exit. The argument block == False 
-        # forces to rexec to return immediately, without blocking 
-        try:
-            if blocking:
-                out, err = _communicate(proc, stdin, timeout, err_on_timeout)
-            else:
-                err = proc.stderr.read()
-                out = proc.stdout.read()
-
-            msg = " rexec - host %s - command %s " % (host, " ".join(args))
-            log(msg, logging.DEBUG, out, err)
-
-            if proc.poll():
-                skip = False
-
-                if err.strip().startswith('ssh: ') or err.strip().startswith('mux_client_hello_exchange: '):
-                    # SSH error, can safely retry
-                    skip = True 
-                elif retry:
-                    # Probably timed out or plain failed but can retry
-                    skip = True 
-                
-                if skip:
-                    t = x*2
-                    msg = "SLEEPING %d ... ATEMPT %d - host %s - command %s " % ( 
-                            t, x, host, " ".join(args))
-                    log(msg, logging.DEBUG)
+    log_msg = " rexec - host %s - command %s " % (host, " ".join(args))
 
-                    time.sleep(t)
-                    continue
-            break
-        except RuntimeError, e:
-            msg = " rexec EXCEPTION - host %s - command %s - TIMEOUT -> %s" % (host, " ".join(args), e.args)
-            log(msg, logging.DEBUG, out, err)
+    stdout = stderr = stdin = subprocess.PIPE
+    if forward_x11:
+        stdout = stderr = stdin = None
 
-            if retry <= 0:
-                raise
-            retry -= 1
-        
-    return ((out, err), proc)
+    return _retry_rexec(args, log_msg, 
+            stderr = stderr,
+            stdin = stdin,
+            stdout = stdout,
+            env = env, 
+            retry = retry, 
+            tmp_known_hosts = tmp_known_hosts,
+            blocking = blocking)
 
 def rcopy(source, dest,
         port = None,
@@ -410,59 +370,24 @@ def rcopy(source, dest,
     if not strict_host_checking:
         # Do not check for Host key. Unsafe.
         args.extend(['-o', 'StrictHostKeyChecking=no'])
-
-    if openssh_has_persist():
-        args.extend([
-            '-o', 'ControlMaster=auto',
-            '-o', 'ControlPath=%s' % (make_control_path(agent, False),)
-            ])
-
-    if isinstance(dest, str):
-        dest = map(str.strip, dest.split(";"))
-
-    if isinstance(source, str):
-        source = map(str.strip, source.split(";"))
-
-    args.extend(source)
-
-    args.extend(dest)
-
-    for x in xrange(retry):
-        # connects to the remote host and starts a remote connection
-        proc = subprocess.Popen(args,
-                stdout = subprocess.PIPE,
-                stdin = subprocess.PIPE, 
-                stderr = subprocess.PIPE)
-        
-        # attach tempfile object to the process, to make sure the file stays
-        # alive until the process is finished with it
-        proc._known_hosts = tmp_known_hosts
     
-        try:
-            (out, err) = proc.communicate()
-            eintr_retry(proc.wait)()
-            msg = " rcopy - host %s - command %s " % (host, " ".join(args))
-            log(msg, logging.DEBUG, out, err)
-
-            if proc.poll():
-                t = x*2
-                msg = "SLEEPING %d ... ATEMPT %d - host %s - command %s " % ( 
-                        t, x, host, " ".join(args))
-                log(msg, logging.DEBUG)
-
-                time.sleep(t)
-                continue
+    if isinstance(source, list):
+        args.extend(source)
+    else:
+        if openssh_has_persist():
+            args.extend([
+                '-o', 'ControlMaster=auto',
+                '-o', 'ControlPath=%s' % (make_control_path(agent, False),)
+                ])
+        args.append(source)
 
-            break
-        except RuntimeError, e:
-            msg = " rcopy EXCEPTION - host %s - command %s - TIMEOUT -> %s" % (host, " ".join(args), e.args)
-            log(msg, logging.DEBUG, out, err)
+    args.append(dest)
 
-            if retry <= 0:
-                raise
-            retry -= 1
-        
-    return ((out, err), proc)
+    log_msg = " rcopy - host %s - command %s " % (host, " ".join(args))
+    
+    return _retry_rexec(args, log_msg, env = None, retry = retry, 
+            tmp_known_hosts = tmp_known_hosts,
+            blocking = True)
 
 def rspawn(command, pidfile, 
         stdout = '/dev/null', 
@@ -736,120 +661,67 @@ fi
 
     return (out, err), proc
 
-# POSIX
-def _communicate(proc, input, timeout=None, err_on_timeout=True):
-    read_set = []
-    write_set = []
-    stdout = None # Return
-    stderr = None # Return
-    
-    killed = False
-    
-    if timeout is not None:
-        timelimit = time.time() + timeout
-        killtime = timelimit + 4
-        bailtime = timelimit + 4
-
-    if proc.stdin:
-        # Flush stdio buffer.  This might block, if the user has
-        # been writing to .stdin in an uncontrolled fashion.
-        proc.stdin.flush()
-        if input:
-            write_set.append(proc.stdin)
-        else:
-            proc.stdin.close()
-
-    if proc.stdout:
-        read_set.append(proc.stdout)
-        stdout = []
-
-    if proc.stderr:
-        read_set.append(proc.stderr)
-        stderr = []
-
-    input_offset = 0
-    while read_set or write_set:
-        if timeout is not None:
-            curtime = time.time()
-            if timeout is None or curtime > timelimit:
-                if curtime > bailtime:
-                    break
-                elif curtime > killtime:
-                    signum = signal.SIGKILL
-                else:
-                    signum = signal.SIGTERM
-                # Lets kill it
-                os.kill(proc.pid, signum)
-                select_timeout = 0.5
-            else:
-                select_timeout = timelimit - curtime + 0.1
-        else:
-            select_timeout = 1.0
+def _retry_rexec(args,
+        log_msg,
+        stdout = subprocess.PIPE,
+        stdin = subprocess.PIPE, 
+        stderr = subprocess.PIPE,
+        env = None,
+        retry = 3,
+        tmp_known_hosts = None,
+        blocking = True):
+
+    for x in xrange(retry):
+        # connects to the remote host and starts a remote connection
+        proc = subprocess.Popen(args,
+                env = env,
+                stdout = stdout,
+                stdin = stdin, 
+                stderr = stderr)
         
-        if select_timeout > 1.0:
-            select_timeout = 1.0
-            
+        # attach tempfile object to the process, to make sure the file stays
+        # alive until the process is finished with it
+        proc._known_hosts = tmp_known_hosts
+    
+        # The argument block == False forces to rexec to return immediately, 
+        # without blocking 
         try:
-            rlist, wlist, xlist = select.select(read_set, write_set, [], select_timeout)
-        except select.error,e:
-            if e[0] != 4:
-                raise
-            else:
-                continue
-        
-        if not rlist and not wlist and not xlist and proc.poll() is not None:
-            # timeout and process exited, say bye
+            err = out = " "
+            if blocking:
+                (out, err) = proc.communicate()
+            elif stdout:
+                out = proc.stdout.read()
+                if proc.poll() and stderr:
+                    err = proc.stderr.read()
+
+            log(log_msg, logging.DEBUG, out, err)
+
+            if proc.poll():
+                skip = False
+
+                if err.strip().startswith('ssh: ') or err.strip().startswith('mux_client_hello_exchange: '):
+                    # SSH error, can safely retry
+                    skip = True 
+                elif retry:
+                    # Probably timed out or plain failed but can retry
+                    skip = True 
+                
+                if skip:
+                    t = x*2
+                    msg = "SLEEPING %d ... ATEMPT %d - command %s " % ( 
+                            t, x, " ".join(args))
+                    log(msg, logging.DEBUG)
+
+                    time.sleep(t)
+                    continue
             break
+        except RuntimeError, e:
+            msg = " rexec EXCEPTION - TIMEOUT -> %s \n %s" % ( e.args, log_msg )
+            log(msg, logging.DEBUG, out, err)
 
-        if proc.stdin in wlist:
-            # When select has indicated that the file is writable,
-            # we can write up to PIPE_BUF bytes without risk
-            # blocking.  POSIX defines PIPE_BUF >= 512
-            bytes_written = os.write(proc.stdin.fileno(),
-                    buffer(input, input_offset, 512))
-            input_offset += bytes_written
-
-            if input_offset >= len(input):
-                proc.stdin.close()
-                write_set.remove(proc.stdin)
-
-        if proc.stdout in rlist:
-            data = os.read(proc.stdout.fileno(), 1024)
-            if data == "":
-                proc.stdout.close()
-                read_set.remove(proc.stdout)
-            stdout.append(data)
-
-        if proc.stderr in rlist:
-            data = os.read(proc.stderr.fileno(), 1024)
-            if data == "":
-                proc.stderr.close()
-                read_set.remove(proc.stderr)
-            stderr.append(data)
-    
-    # All data exchanged.  Translate lists into strings.
-    if stdout is not None:
-        stdout = ''.join(stdout)
-    if stderr is not None:
-        stderr = ''.join(stderr)
-
-    # Translate newlines, if requested.  We cannot let the file
-    # object do the translation: It is based on stdio, which is
-    # impossible to combine with select (unless forcing no
-    # buffering).
-    if proc.universal_newlines and hasattr(file, 'newlines'):
-        if stdout:
-            stdout = proc._translate_newlines(stdout)
-        if stderr:
-            stderr = proc._translate_newlines(stderr)
-
-    if killed and err_on_timeout:
-        errcode = proc.poll()
-        raise RuntimeError, ("Operation timed out", errcode, stdout, stderr)
-    else:
-        if killed:
-            proc.poll()
-        else:
-            proc.wait()
-        return (stdout, stderr)
+            if retry <= 0:
+                raise
+            retry -= 1
+        
+    return ((out, err), proc)
 
index 672a11c..a740128 100644 (file)
@@ -29,7 +29,7 @@ import unittest
 class LinuxCCNPingTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
index 00ac5e8..c6b219c 100644 (file)
@@ -29,7 +29,7 @@ import unittest
 class LinuxFIBEntryTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "nepi"
index bd4d74d..379f92e 100755 (executable)
@@ -35,7 +35,7 @@ import unittest
 class LinuxInterfaceTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
index c62848a..a34068d 100755 (executable)
@@ -29,7 +29,7 @@ import unittest
 class LinuxMtrTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
index b6af3dc..19c4ef4 100755 (executable)
@@ -29,7 +29,7 @@ import unittest
 class LinuxNPingTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
diff --git a/test/resources/linux/ns3/ns-3.18-user.tar.gz b/test/resources/linux/ns3/ns-3.18-user.tar.gz
new file mode 100644 (file)
index 0000000..fcbfb70
Binary files /dev/null and b/test/resources/linux/ns3/ns-3.18-user.tar.gz differ
diff --git a/test/resources/linux/ns3/ns3client.py b/test/resources/linux/ns3/ns3client.py
new file mode 100644 (file)
index 0000000..8fad928
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/env python
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 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>
+
+
+# Test based on ns-3 csma/examples/csma-ping.cc file
+#
+# Network topology
+#
+#       n0    n1   n2   n3
+#       |     |    |    |
+#       -----------------
+#
+#  node n0 sends IGMP traffic to node n3
+
+
+from nepi.resources.ns3.ns3server import run_server
+from nepi.resources.linux.ns3.ns3client import LinuxNS3Client
+
+import os
+import threading
+import time
+import unittest
+
+class DummySimulation(object):
+    def __init__(self, socket_name):
+        self.socket_name = socket_name
+        self.node = dict({'hostname': 'localhost'})
+
+    @property
+    def remote_socket(self):
+        return self.socket_name
+
+class LinuxNS3ClientTest(unittest.TestCase):
+    def setUp(self):
+        self.socket_name = os.path.join("/", "tmp", "NS3WrapperServer.sock")
+        if os.path.exists(self.socket_name):
+            os.remove(self.socket_name) 
+
+    def tearDown(self):
+        os.remove(self.socket_name) 
+
+    def test_runtime_attr_modify(self):
+        thread = threading.Thread(target = run_server,
+                args = [self.socket_name])
+
+        thread.setDaemon(True)
+        thread.start()
+
+        time.sleep(3)
+
+        # Verify that the communication socket was created
+        self.assertTrue(os.path.exists(self.socket_name))
+
+        # Create a dummy simulation object
+        simulation = DummySimulation(self.socket_name) 
+
+        # Instantiate the NS3 client
+        client = LinuxNS3Client(simulation)
+        # Define a real time simulation 
+        stype = client.create("StringValue", "ns3::RealtimeSimulatorImpl")
+        client.invoke("singleton::GlobalValue", "Bind", "SimulatorImplementationType", stype)
+        btrue = client.create("BooleanValue", True)
+        client.invoke("singleton::GlobalValue", "Bind", "ChecksumEnabled", btrue)
+        
+        # Create Node
+        n1 = client.create("Node")
+        self.assertTrue(n1.startswith("uuid"))
+
+        ## Install internet stack
+        ipv41 = client.create("Ipv4L3Protocol")
+        client.invoke(n1, "AggregateObject", ipv41)
+
+        arp1 = client.create("ArpL3Protocol")
+        client.invoke(n1, "AggregateObject", arp1)
+        
+        icmp1 = client.create("Icmpv4L4Protocol")
+        client.invoke(n1, "AggregateObject", icmp1)
+
+        ## Add IPv4 routing
+        lr1 = client.create("Ipv4ListRouting")
+        client.invoke(ipv41, "SetRoutingProtocol", lr1)
+        sr1 = client.create("Ipv4StaticRouting")
+        client.invoke(lr1, "AddRoutingProtocol", sr1, 1)
+
+        ## NODE 2
+        n2 = client.create("Node")
+
+        ## Install internet stack
+        ipv42 = client.create("Ipv4L3Protocol")
+        client.invoke(n2, "AggregateObject", ipv42)
+
+        arp2 = client.create("ArpL3Protocol")
+        client.invoke(n2, "AggregateObject", arp2)
+        
+        icmp2 = client.create("Icmpv4L4Protocol")
+        client.invoke(n2, "AggregateObject", icmp2)
+
+        ## Add IPv4 routing
+        lr2 = client.create("Ipv4ListRouting")
+        client.invoke(ipv42, "SetRoutingProtocol", lr2)
+        sr2 = client.create("Ipv4StaticRouting")
+        client.invoke(lr2, "AddRoutingProtocol", sr2, 1)
+
+        ##### Create p2p device and enable ascii tracing
+        p2pHelper = client.create("PointToPointHelper")
+        asciiHelper = client.create("AsciiTraceHelper")
+
+        # Iface for node1
+        p1 = client.create("PointToPointNetDevice")
+        client.invoke(n1, "AddDevice", p1)
+        q1 = client.create("DropTailQueue")
+        client.invoke(p1, "SetQueue", q1)
+      
+        # Add IPv4 address
+        ifindex1 = client.invoke(ipv41, "AddInterface", p1)
+        mask1 = client.create("Ipv4Mask", "/30")
+        addr1 = client.create("Ipv4Address", "10.0.0.1")
+        inaddr1 = client.create("Ipv4InterfaceAddress", addr1, mask1)
+        client.invoke(ipv41, "AddAddress", ifindex1, inaddr1)
+        client.invoke(ipv41, "SetMetric", ifindex1, 1)
+        client.invoke(ipv41, "SetUp", ifindex1)
+
+        # Enable collection of Ascii format to a specific file
+        filepath1 = "trace-p2p-1.tr"
+        stream1 = client.invoke(asciiHelper, "CreateFileStream", filepath1)
+        client.invoke(p2pHelper, "EnableAscii", stream1, p1)
+       
+        # Iface for node2
+        p2 = client.create("PointToPointNetDevice")
+        client.invoke(n2, "AddDevice", p2)
+        q2 = client.create("DropTailQueue")
+        client.invoke(p2, "SetQueue", q2)
+
+        # Add IPv4 address
+        ifindex2 = client.invoke(ipv42, "AddInterface", p2)
+        mask2 = client.create("Ipv4Mask", "/30")
+        addr2 = client.create("Ipv4Address", "10.0.0.2")
+        inaddr2 = client.create("Ipv4InterfaceAddress", addr2, mask2)
+        client.invoke(ipv42, "AddAddress", ifindex2, inaddr2)
+        client.invoke(ipv42, "SetMetric", ifindex2, 1)
+        client.invoke(ipv42, "SetUp", ifindex2)
+
+        # Enable collection of Ascii format to a specific file
+        filepath2 = "trace-p2p-2.tr"
+        stream2 = client.invoke(asciiHelper, "CreateFileStream", filepath2)
+        client.invoke(p2pHelper, "EnableAscii", stream2, p2)
+
+        # Create channel
+        chan = client.create("PointToPointChannel")
+        client.set(chan, "Delay", "0s")
+        client.invoke(p1, "Attach", chan)
+        client.invoke(p2, "Attach", chan)
+
+        ### create pinger
+        ping = client.create("V4Ping")
+        client.invoke(n1, "AddApplication", ping)
+        client.set (ping, "Remote", "10.0.0.2")
+        client.set (ping, "Interval", "1s")
+        client.set (ping, "Verbose", True)
+        client.set (ping, "StartTime", "0s")
+        client.set (ping, "StopTime", "20s")
+
+        ### run Simulation
+        client.stop(time = "21s")
+        client.start()
+
+        time.sleep(1)
+
+        client.set(chan, "Delay", "5s")
+
+        time.sleep(5)
+
+        client.set(chan, "Delay", "0s")
+
+        # wait until simulation is over
+        client.shutdown()
+
+        ## TODO: Add assertions !!
+
+if __name__ == '__main__':
+    unittest.main()
+
diff --git a/test/resources/linux/ns3/ns3simulation.py b/test/resources/linux/ns3/ns3simulation.py
new file mode 100644 (file)
index 0000000..25a11b2
--- /dev/null
@@ -0,0 +1,722 @@
+#!/usr/bin/env python
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 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>
+
+
+#
+# Network topology
+#
+#       n0    n1   n2   n3
+#       |     |    |    |
+#       -----------------
+#
+#  node n0 sends IGMP traffic to node n3
+
+
+from nepi.execution.ec import ExperimentController 
+from nepi.execution.trace import TraceAttr
+
+import os
+import time
+import unittest
+
+def add_ns3_node(ec, simu):
+    node = ec.register_resource("ns3::Node")
+    ec.register_connection(node, simu)
+
+    ipv4 = ec.register_resource("ns3::Ipv4L3Protocol")
+    ec.register_connection(node, ipv4)
+
+    arp = ec.register_resource("ns3::ArpL3Protocol")
+    ec.register_connection(node, arp)
+    
+    icmp = ec.register_resource("ns3::Icmpv4L4Protocol")
+    ec.register_connection(node, icmp)
+
+    return node
+
+def add_point2point_device(ec, node, address = None,  prefix = None):
+    dev = ec.register_resource("ns3::PointToPointNetDevice")
+    if address:
+       ec.set(dev, "ip", address)
+    if prefix:
+       ec.set(dev, "prefix", prefix)
+    ec.register_connection(node, dev)
+
+    queue = ec.register_resource("ns3::DropTailQueue")
+    ec.register_connection(dev, queue)
+
+    return dev
+
+def add_csma_device(ec, node, address = None, prefix = None):
+    dev = ec.register_resource("ns3::CsmaNetDevice")
+    if address:
+        ec.set(dev, "ip", address)
+    if prefix:
+        ec.set(dev, "prefix", prefix)
+    ec.register_connection(node, dev)
+
+    queue = ec.register_resource("ns3::DropTailQueue")
+    ec.register_connection(dev, queue)
+
+    return dev
+
+def add_wifi_device(ec, node, address = None, prefix = None, 
+        access_point = False):
+    dev = ec.register_resource("ns3::WifiNetDevice")
+    if address:
+        ec.set(dev, "ip", address)
+    if prefix:
+        ec.set(dev, "prefix", prefix)
+    ec.register_connection(node, dev)
+
+    phy = ec.register_resource("ns3::YansWifiPhy")
+    ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")
+    ec.register_connection(dev, phy)
+
+    error = ec.register_resource("ns3::NistErrorRateModel")
+    ec.register_connection(phy, error)
+
+    manager = ec.register_resource("ns3::ArfWifiManager")
+    ec.register_connection(dev, manager)
+
+    if access_point:
+        mac = ec.register_resource("ns3::ApWifiMac")
+    else:
+        mac = ec.register_resource("ns3::StaWifiMac")
+
+    ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")
+    ec.register_connection(dev, mac)
+
+    return dev, phy
+
+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 = "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",  pause)
+    ec.register_connection(node, mobility)
+    return mobility
+
+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)
+    ec.register_connection(node, mobility)
+    return mobility
+
+def add_wifi_channel(ec):
+    channel = ec.register_resource("ns3::YansWifiChannel")
+    delay = ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")
+    ec.register_connection(channel, delay)
+
+    loss  = ec.register_resource("ns3::LogDistancePropagationLossModel")
+    ec.register_connection(channel, loss)
+
+    return channel
+
+class LinuxNS3ClientTest(unittest.TestCase):
+    def setUp(self):
+        #self.fedora_host = "nepi2.pl.sophia.inria.fr"
+        self.fedora_host = "planetlabpc1.upf.edu"
+        #self.fedora_host = "peeramide.irisa.fr"
+        self.fedora_user = "inria_nepi"
+        self.fedora_identity = "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])
+
+    def test_simple_p2p_ping(self):
+        ec = ExperimentController(exp_id = "test-ns3-p2p-ping")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #ec.set(node, "cleanHome", True)
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        dev1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        dev2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
+
+        # Create channel
+        chan = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, dev1)
+        ec.register_connection(chan, dev2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+        
+        stdout = ec.trace(simu, "stdout") 
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+
+        ec.shutdown()
+
+    def test_simple_cmsa_ping(self):
+        ec = ExperimentController(exp_id = "test-ns3-csma-ping")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #ec.set(node, "cleanHome", True)
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        dev1 = add_csma_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        dev2 = add_csma_device(ec, nsnode2, "10.0.0.2", "30")
+
+        # Create channel
+        chan = ec.register_resource("ns3::CsmaChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, dev1)
+        ec.register_connection(chan, dev2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+        
+        stdout = ec.trace(simu, "stdout") 
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+
+        ec.shutdown()
+
+    def test_compile_local_source(self):
+        ec = ExperimentController(exp_id = "test-ns3-local-source")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #ec.set(node, "cleanHome", True)
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        sources = os.path.join(os.path.dirname(os.path.realpath(__file__)), 
+                "ns-3.18-user.tar.gz")
+        ec.set(simu, "sources", sources)
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        dev1 = add_csma_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        dev2 = add_csma_device(ec, nsnode2, "10.0.0.2", "30")
+
+        # Create channel
+        chan = ec.register_resource("ns3::CsmaChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, dev1)
+        ec.register_connection(chan, dev2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+        
+        stdout = ec.trace(simu, "stdout") 
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+        
+        ec.shutdown()
+
+    def test_compile_debug_mode(self):
+        ec = ExperimentController(exp_id = "test-ns3-debug-mode")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #ec.set(node, "cleanHome", True)
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.set(simu, "verbose", True)
+        ec.set(simu, "nsLog", "V4Ping:Node")
+        ec.set(simu, "buildMode", "debug")
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        dev1 = add_csma_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        dev2 = add_csma_device(ec, nsnode2, "10.0.0.2", "30")
+
+        # Create channel
+        chan = ec.register_resource("ns3::CsmaChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, dev1)
+        ec.register_connection(chan, dev2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+        
+        stdout = ec.trace(simu, "stdout") 
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+        
+        stderr = ec.trace(simu, "stderr")
+        expected = "V4Ping:Read32"
+        self.assertTrue(stderr.find(expected) > -1)
+
+        ec.shutdown()
+
+    def test_real_time(self):
+        ec = ExperimentController(exp_id = "test-ns3-real-time")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #ec.set(node, "cleanHome", True)
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.set(simu, "simulatorImplementationType", "ns3::RealtimeSimulatorImpl")
+        ec.set(simu, "checksumEnabled", True)
+        ec.set(simu, "verbose", True)
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        dev1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        dev2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
+
+        # Create channel
+        chan = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, dev1)
+        ec.register_connection(chan, dev2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+      
+        stdout = ec.trace(simu, "stdout") 
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+
+        rm = ec.get_resource(ping)
+        start_time = rm.start_time
+        stop_time = rm.stop_time
+        delta =  stop_time - start_time
+
+        self.assertTrue(delta.seconds >= 20)
+        self.assertTrue(delta.seconds < 25)
+
+        ec.shutdown()
+
+    def test_dev2p_traces(self):
+        ec = ExperimentController(exp_id = "test-ns3-dev2p-traces")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #ec.set(node, "cleanHome", True)
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        dev1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        dev2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
+
+        # Create channel
+        chan = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(chan, "Delay", "0s")
+        ec.register_connection(chan, dev1)
+        ec.register_connection(chan, dev2)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.0.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "0s")
+        ec.set (ping, "StopTime", "20s")
+        ec.register_connection(ping, nsnode1)
+
+        # enable traces
+        ec.enable_trace(dev1, "pcap")
+        ec.enable_trace(dev1, "promiscPcap")
+        ec.enable_trace(dev1, "ascii")
+
+        ec.enable_trace(dev2, "pcap")
+        ec.enable_trace(dev2, "promiscPcap")
+        ec.enable_trace(dev2, "ascii")
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+
+        # Trace verification
+        rm_simu = ec.get_resource(simu)
+
+        # TODO: Fix this in ns-3: pcap traces do not flush until the Simulator 
+        #   process is ended, so we can't get the traces of the 'pcap' and
+        #   'promiscPcap' traces.
+        #
+        #for trace in ["pcap", "promiscPcap", "ascii"]:
+        for trace in ["ascii"]:
+            for guid in [dev1, dev2]:
+                output = ec.trace(guid, trace)
+
+                size = ec.trace(guid, trace, attr = TraceAttr.SIZE)
+                self.assertEquals(size, len(output))
+                self.assertTrue(size > 100)
+                
+                block = ec.trace(guid, trace, attr = TraceAttr.STREAM, block = 5, offset = 1)
+                self.assertEquals(block, output[5:10])
+
+                trace_path = ec.trace(guid, trace, attr = TraceAttr.PATH)
+                rm = ec.get_resource(guid)
+                path = os.path.join(rm_simu.run_home, rm._trace_filename.get(trace))
+                self.assertEquals(trace_path, path)
+
+        ec.shutdown()
+
+    def test_simple_wifi_ping(self):
+        bounds_width = bounds_height = 200
+        x = y = 100
+        speed = 1
+
+        ec = ExperimentController(exp_id = "test-ns3-wifi-ping")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #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, 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, 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, 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", "1s")
+        ec.set (ping, "StopTime", "21s")
+        ec.register_connection(ping, nsnode2)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+        
+        stdout = ec.trace(simu, "stdout")
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+
+        ec.shutdown()
+
+    def test_routing(self):
+        """ 
+        network topology:
+                                n4
+                                |
+           n1 -- p2p -- n2 -- csma -- n5 -- p2p -- n6
+           |                    | 
+           ping n6              n3
+           
+
+        """
+        ec = ExperimentController(exp_id = "test-ns3-routes")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #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)
+        p2p12 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        p2p21 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
+        csma2 = add_csma_device(ec, nsnode2, "10.0.1.1", "24")
+
+        nsnode3 = add_ns3_node(ec, simu)
+        csma3 = add_csma_device(ec, nsnode3, "10.0.1.2", "24")
+
+        nsnode4 = add_ns3_node(ec, simu)
+        csma4 = add_csma_device(ec, nsnode4, "10.0.1.3", "24")
+
+        nsnode5 = add_ns3_node(ec, simu)
+        p2p56 = add_point2point_device(ec, nsnode5, "10.0.2.1", "30")
+        csma5 = add_csma_device(ec, nsnode5, "10.0.1.4", "24")
+
+        nsnode6 = add_ns3_node(ec, simu)
+        p2p65 = add_point2point_device(ec, nsnode6, "10.0.2.2", "30")
+
+        # P2P chan1
+        p2p_chan1 = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(p2p_chan1, "Delay", "0s")
+        ec.register_connection(p2p_chan1, p2p12)
+        ec.register_connection(p2p_chan1, p2p21)
+
+        # CSMA chan
+        csma_chan = ec.register_resource("ns3::CsmaChannel")
+        ec.set(csma_chan, "Delay", "0s")
+        ec.register_connection(csma_chan, csma2)
+        ec.register_connection(csma_chan, csma3)
+        ec.register_connection(csma_chan, csma4)
+        ec.register_connection(csma_chan, csma5)
+
+        # P2P chan2
+        p2p_chan2 = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(p2p_chan2, "Delay", "0s")
+        ec.register_connection(p2p_chan2, p2p56)
+        ec.register_connection(p2p_chan2, p2p65)
+
+        # Add routes - n1 - n6
+        r1 = ec.register_resource("ns3::Route")
+        ec.set(r1, "network", "10.0.2.0")
+        ec.set(r1, "prefix", "30")
+        ec.set(r1, "nexthop", "10.0.0.2")
+        ec.register_connection(r1, nsnode1)
+
+        # Add routes - n2 - n6
+        r2 = ec.register_resource("ns3::Route")
+        ec.set(r2, "network", "10.0.2.0")
+        ec.set(r2, "prefix", "30")
+        ec.set(r2, "nexthop", "10.0.1.4")
+        ec.register_connection(r2, nsnode2)
+
+        # Add routes - n5 - n1
+        r5 = ec.register_resource("ns3::Route")
+        ec.set(r5, "network", "10.0.0.0")
+        ec.set(r5, "prefix", "30")
+        ec.set(r5, "nexthop", "10.0.1.1")
+        ec.register_connection(r5, nsnode5)
+
+        # Add routes - n6 - n1
+        r6 = ec.register_resource("ns3::Route")
+        ec.set(r6, "network", "10.0.0.0")
+        ec.set(r6, "prefix", "30")
+        ec.set(r6, "nexthop", "10.0.2.1")
+        ec.register_connection(r6, nsnode6)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.2.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "1s")
+        ec.set (ping, "StopTime", "21s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        ec.wait_finished([ping])
+        
+        stdout = ec.trace(simu, "stdout")
+
+        expected = "20 packets transmitted, 20 received, 0% packet loss"
+        self.assertTrue(stdout.find(expected) > -1)
+
+        ec.shutdown()
+
+    def ztest_automatic_routing(self):
+        """ 
+        network topology:
+                                n4
+                                |
+           n1 -- p2p -- n2 -- csma -- n5 -- p2p -- n6
+           |                    | 
+           ping n6              n3
+           
+
+        """
+        ec = ExperimentController(exp_id = "test-ns3-auto-routes")
+        
+        node = ec.register_resource("LinuxNode")
+        ec.set(node, "hostname", self.fedora_host)
+        ec.set(node, "username", self.fedora_user)
+        ec.set(node, "identity", self.fedora_identity)
+        ec.set(node, "cleanProcesses", True)
+        #ec.set(node, "cleanHome", True)
+
+        simu = ec.register_resource("LinuxNS3Simulation")
+        ec.set(simu, "verbose", True)
+        ec.set(simu, "populateRoutingTables", True)
+        ec.register_connection(simu, node)
+
+        nsnode1 = add_ns3_node(ec, simu)
+        p2p12 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
+
+        nsnode2 = add_ns3_node(ec, simu)
+        p2p21 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
+        csma2 = add_csma_device(ec, nsnode2, "10.0.1.1", "24")
+
+        nsnode3 = add_ns3_node(ec, simu)
+        csma3 = add_csma_device(ec, nsnode3, "10.0.1.2", "24")
+
+        nsnode4 = add_ns3_node(ec, simu)
+        csma4 = add_csma_device(ec, nsnode4, "10.0.1.3", "24")
+
+        nsnode5 = add_ns3_node(ec, simu)
+        p2p56 = add_point2point_device(ec, nsnode5, "10.0.2.1", "30")
+        csma5 = add_csma_device(ec, nsnode5, "10.0.1.4", "24")
+
+        nsnode6 = add_ns3_node(ec, simu)
+        p2p65 = add_point2point_device(ec, nsnode6, "10.0.2.2", "30")
+
+        # P2P chan1
+        p2p_chan1 = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(p2p_chan1, "Delay", "0s")
+        ec.register_connection(p2p_chan1, p2p12)
+        ec.register_connection(p2p_chan1, p2p21)
+
+        # CSMA chan
+        csma_chan = ec.register_resource("ns3::CsmaChannel")
+        ec.set(csma_chan, "Delay", "0s")
+        ec.register_connection(csma_chan, csma2)
+        ec.register_connection(csma_chan, csma3)
+        ec.register_connection(csma_chan, csma4)
+        ec.register_connection(csma_chan, csma5)
+
+        # P2P chan2
+        p2p_chan2 = ec.register_resource("ns3::PointToPointChannel")
+        ec.set(p2p_chan2, "Delay", "0s")
+        ec.register_connection(p2p_chan2, p2p56)
+        ec.register_connection(p2p_chan2, p2p65)
+
+        ### create pinger
+        ping = ec.register_resource("ns3::V4Ping")
+        ec.set (ping, "Remote", "10.0.1.2")
+        ec.set (ping, "Interval", "1s")
+        ec.set (ping, "Verbose", True)
+        ec.set (ping, "StartTime", "1s")
+        ec.set (ping, "StopTime", "21s")
+        ec.register_connection(ping, nsnode1)
+
+        ec.deploy()
+
+        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)
+
+        ec.shutdown()
+
+
+if __name__ == '__main__':
+    unittest.main()
+
index 8846690..6530276 100755 (executable)
@@ -29,7 +29,7 @@ import unittest
 class LinuxPingTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
index 6c9a9be..6ba7375 100755 (executable)
@@ -29,7 +29,7 @@ import unittest
 class LinuxTcpdumpTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
index dfdae42..996472e 100755 (executable)
@@ -29,7 +29,7 @@ import unittest
 class LinuxTracerouteTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
index aeafe6a..37bfc88 100755 (executable)
@@ -29,7 +29,7 @@ import unittest
 class LinuxUdpTestTestCase(unittest.TestCase):
     def setUp(self):
         self.fedora_host = "nepi2.pl.sophia.inria.fr"
-        self.fedora_user = "inria_test"
+        self.fedora_user = "inria_nepi"
 
         self.ubuntu_host = "roseval.pl.sophia.inria.fr"
         self.ubuntu_user = "alina"
index d3b11d1..8765761 100755 (executable)
 
 from nepi.resources.ns3.ns3wrapper import NS3Wrapper
 
-import os.path
+import StringIO
+import subprocess
+import sys
 import time
-import tempfile
 import unittest
 
 class NS3WrapperTest(unittest.TestCase):
@@ -92,11 +93,10 @@ class NS3WrapperTest(unittest.TestCase):
         addresses = wrapper.invoke(ip, "Assign", devs)
 
         ### Create source
-        config = wrapper.singleton("Config")
-        
         # Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
         proto = wrapper.create("StringValue", "2")
-        wrapper.invoke(config, "SetDefault", "ns3::Ipv4RawSocketImpl::Protocol", proto)
+        wrapper.invoke("singleton::Config", "SetDefault", 
+                "ns3::Ipv4RawSocketImpl::Protocol", proto)
 
         # InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
         addr3 = wrapper.invoke(addresses, "GetAddress", 3)
@@ -105,16 +105,6 @@ class NS3WrapperTest(unittest.TestCase):
         # OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
         onoff = wrapper.create("OnOffHelper", "ns3::Ipv4RawSocketFactory", dst)
 
-        # onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
-        cv1 = wrapper.create("ConstantVariable", 1.0)
-        rand1 = wrapper.create("RandomVariableValue", cv1)
-        wrapper.invoke(onoff, "SetAttribute", "OnTime", rand1)
-
-        # onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
-        cv2 = wrapper.create("ConstantVariable", 0.0)
-        rand2 = wrapper.create("RandomVariableValue", cv2)
-        wrapper.invoke(onoff, "SetAttribute", "OffTime", rand2)
-
         # onoff.SetAttribute ("DataRate", DataRateValue (DataRate (15000)));
         dr2 = wrapper.create("DataRate", 15000)
         drv2 = wrapper.create("DataRateValue", dr2)
@@ -183,41 +173,256 @@ class NS3WrapperTest(unittest.TestCase):
         s6 = wrapper.create ("Seconds", 5.0)
         wrapper.invoke (apps, "Stop", s6)
 
+        ### configure tracing
+        #csma.EnablePcapAll ("csma-ping", false);
+        wrapper.invoke(csma, "EnablePcapAll", "/tmp/csma-ping-pcap", False)
+        #csma.EnableAsciiAll ("csma-ping", false);
+        wrapper.invoke(csma, "EnableAsciiAll", "/tmp/csma-ping-ascii")
         def SinkRx(packet, address):
             print packet
 
         def PingRtt(context, rtt):
             print context, rtt
-
-        ### configure tracing
-        #csma.EnablePcapAll ("csma-ping", false);
-        wrapper.invoke(csma, "EnablePcapAll", "csma-ping", False)
-       
-        # No binging for callback
+      
+        # XXX: No biding for MakeCallback
         #Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
         # MakeCallback (&SinkRx));
         #cb = wrapper.create("MakeCallback", SinkRx)
-        #wrapper.invoke(config, "ConnectWithoutContext", 
+        #wrapper.invoke("singleton::Config", "ConnectWithoutContext", 
         #        "/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", cb)
 
         # Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt", 
         # MakeCallback (&PingRtt));
         #cb2 = wrapper.create("MakeCallback", PingRtt)
-        #wrapper.invoke(config, "ConnectWithoutContext", 
+        #wrapper.invoke("singleton::Config", "ConnectWithoutContext", 
         #        "/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt", 
         #        cb2)
 
         # Packet::EnablePrinting ();
-        packet = wrapper.singleton("Packet")
-        wrapper.invoke(packet, "EnablePrinting")
+        wrapper.invoke("singleton::Packet", "EnablePrinting")
 
         ### run Simulation
         # Simulator::Run ();
-        simulator = wrapper.singleton("Simulator")
-        wrapper.invoke(simulator, "Run")
+        wrapper.invoke("singleton::Simulator", "Run")
 
         # Simulator::Destroy ();
-        wrapper.invoke(simulator, "Destroy")
+        wrapper.invoke("singleton::Simulator", "Destroy")
+
+        p = subprocess.Popen("ls /tmp/csma-ping-* | wc -w", stdout = subprocess.PIPE, 
+                stderr = subprocess.PIPE, shell = True)
+        (out, err) = p.communicate()
+
+        self.assertEquals(int(out), 8)
+
+        p = subprocess.Popen("rm /tmp/csma-ping-*",  shell = True)
+        p.communicate()
+
+    def test_start(self):
+        # Instantiate ns-3
+        wrapper = NS3Wrapper()
+
+        ### create 2  nodes
+        c = wrapper.create("NodeContainer")
+
+        # c.Create (2);
+        wrapper.invoke(c, "Create", 2)
+
+        ### connect the nodes to a shared channel
+        # CsmaHelper csma;
+        csma = wrapper.create("CsmaHelper")
+
+        # csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
+        dr = wrapper.create("DataRate", 5000000)
+        drv = wrapper.create("DataRateValue", dr)
+        wrapper.invoke(csma, "SetChannelAttribute", "DataRate", drv)
+
+        # csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+        ms = wrapper.create("MilliSeconds", 2)
+        delay = wrapper.create("TimeValue", ms)
+        wrapper.invoke(csma, "SetChannelAttribute", "Delay", delay)
+
+        # NetDeviceContainer devs = csma.Install (c);
+        devs = wrapper.invoke(csma, "Install", c)
+
+        ### add IP stack to all nodes
+        # InternetStackHelper ipStack;
+        ipStack = wrapper.create("InternetStackHelper")
+        
+        # ipStack.Install (c);
+        wrapper.invoke(ipStack, "Install", c)
+
+        ### assign ip addresses
+        #Ipv4AddressHelper ip;
+        ip = wrapper.create("Ipv4AddressHelper")
+
+        # ip.SetBase ("192.168.1.0", "255.255.255.0");
+        ip4 = wrapper.create("Ipv4Address", "192.168.1.0")
+        mask4 = wrapper.create("Ipv4Mask", "255.255.255.0")
+        wrapper.invoke(ip, "SetBase", ip4, mask4)
+
+        # Ipv4InterfaceContainer addresses = ip.Assign (devs);
+        addresses = wrapper.invoke(ip, "Assign", devs)
+
+        ### create pinger
+        #V4PingHelper ping = V4PingHelper (addresses.GetAddress (1));
+        addr1 = wrapper.invoke(addresses, "GetAddress", 1)
+        ping = wrapper.create("V4PingHelper", addr1)
+        btrue = wrapper.create("BooleanValue", True)
+        wrapper.invoke(ping, "SetAttribute", "Verbose", btrue)
+        
+        #apps = ping.Install (pingers);
+        n0 = wrapper.invoke(c, "Get", 0)
+        apps = wrapper.invoke(ping, "Install", n0)
+        
+        #apps.Start (Seconds (0.0));
+        s = wrapper.create ("Seconds", 0.0)
+        wrapper.invoke (apps, "Start", s)
+        
+        #apps.Stop (Seconds (5.0));
+        s = wrapper.create ("Seconds", 5.0)
+        wrapper.invoke (apps, "Stop", s)
+
+        ### run Simulation
+        # Simulator::Stop (6.0);
+        wrapper.stop(time = "6s")
+
+        # Simulator::Run ();
+        wrapper.start()
+
+        # wait until simulation is over
+        wrapper.shutdown()
+
+        # TODO: Add assertions !!
+
+    def test_runtime_attr_modify(self):
+        wrapper = NS3Wrapper()
+       
+        # Define a real time simulation 
+        stype = wrapper.create("StringValue", "ns3::RealtimeSimulatorImpl")
+        wrapper.invoke("singleton::GlobalValue", "Bind", "SimulatorImplementationType", stype)
+        btrue = wrapper.create("BooleanValue", True)
+        wrapper.invoke("singleton::GlobalValue", "Bind", "ChecksumEnabled", btrue)
+
+        ### create 2  nodes
+        ## NODE 1
+        n1 = wrapper.create("Node")
+
+        ## Install internet stack
+        ipv41 = wrapper.create("Ipv4L3Protocol")
+        wrapper.invoke(n1, "AggregateObject", ipv41)
+
+        arp1 = wrapper.create("ArpL3Protocol")
+        wrapper.invoke(n1, "AggregateObject", arp1)
+        
+        icmp1 = wrapper.create("Icmpv4L4Protocol")
+        wrapper.invoke(n1, "AggregateObject", icmp1)
+
+        ## Add IPv4 routing
+        lr1 = wrapper.create("Ipv4ListRouting")
+        wrapper.invoke(ipv41, "SetRoutingProtocol", lr1)
+        sr1 = wrapper.create("Ipv4StaticRouting")
+        wrapper.invoke(lr1, "AddRoutingProtocol", sr1, 1)
+
+        ## NODE 2
+        n2 = wrapper.create("Node")
+
+        ## Install internet stack
+        ipv42 = wrapper.create("Ipv4L3Protocol")
+        wrapper.invoke(n2, "AggregateObject", ipv42)
+
+        arp2 = wrapper.create("ArpL3Protocol")
+        wrapper.invoke(n2, "AggregateObject", arp2)
+        
+        icmp2 = wrapper.create("Icmpv4L4Protocol")
+        wrapper.invoke(n2, "AggregateObject", icmp2)
+
+        ## Add IPv4 routing
+        lr2 = wrapper.create("Ipv4ListRouting")
+        wrapper.invoke(ipv42, "SetRoutingProtocol", lr2)
+        sr2 = wrapper.create("Ipv4StaticRouting")
+        wrapper.invoke(lr2, "AddRoutingProtocol", sr2, 1)
+
+        ##### Create p2p device and enable ascii tracing
+
+        p2pHelper = wrapper.create("PointToPointHelper")
+        asciiHelper = wrapper.create("AsciiTraceHelper")
+
+        # Iface for node1
+        p1 = wrapper.create("PointToPointNetDevice")
+        wrapper.invoke(n1, "AddDevice", p1)
+        q1 = wrapper.create("DropTailQueue")
+        wrapper.invoke(p1, "SetQueue", q1)
+      
+        # Add IPv4 address
+        ifindex1 = wrapper.invoke(ipv41, "AddInterface", p1)
+        mask1 = wrapper.create("Ipv4Mask", "/30")
+        addr1 = wrapper.create("Ipv4Address", "10.0.0.1")
+        inaddr1 = wrapper.create("Ipv4InterfaceAddress", addr1, mask1)
+        wrapper.invoke(ipv41, "AddAddress", ifindex1, inaddr1)
+        wrapper.invoke(ipv41, "SetMetric", ifindex1, 1)
+        wrapper.invoke(ipv41, "SetUp", ifindex1)
+
+        # Enable collection of Ascii format to a specific file
+        filepath1 = "/tmp/trace-p2p-1.tr"
+        stream1 = wrapper.invoke(asciiHelper, "CreateFileStream", filepath1)
+        wrapper.invoke(p2pHelper, "EnableAscii", stream1, p1)
+       
+        # Iface for node2
+        p2 = wrapper.create("PointToPointNetDevice")
+        wrapper.invoke(n2, "AddDevice", p2)
+        q2 = wrapper.create("DropTailQueue")
+        wrapper.invoke(p2, "SetQueue", q2)
+
+        # Add IPv4 address
+        ifindex2 = wrapper.invoke(ipv42, "AddInterface", p2)
+        mask2 = wrapper.create("Ipv4Mask", "/30")
+        addr2 = wrapper.create("Ipv4Address", "10.0.0.2")
+        inaddr2 = wrapper.create("Ipv4InterfaceAddress", addr2, mask2)
+        wrapper.invoke(ipv42, "AddAddress", ifindex2, inaddr2)
+        wrapper.invoke(ipv42, "SetMetric", ifindex2, 1)
+        wrapper.invoke(ipv42, "SetUp", ifindex2)
+
+        # Enable collection of Ascii format to a specific file
+        filepath2 = "/tmp/trace-p2p-2.tr"
+        stream2 = wrapper.invoke(asciiHelper, "CreateFileStream", filepath2)
+        wrapper.invoke(p2pHelper, "EnableAscii", stream2, p2)
+
+        # Create channel
+        chan = wrapper.create("PointToPointChannel")
+        wrapper.set(chan, "Delay", "0s")
+        wrapper.invoke(p1, "Attach", chan)
+        wrapper.invoke(p2, "Attach", chan)
+
+        ### create pinger
+        ping = wrapper.create("V4Ping")
+        wrapper.invoke(n1, "AddApplication", ping)
+        wrapper.set (ping, "Remote", "10.0.0.2")
+        wrapper.set (ping, "Interval", "1s")
+        wrapper.set (ping, "Verbose", True)
+        wrapper.set (ping, "StartTime", "0s")
+        wrapper.set (ping, "StopTime", "20s")
+
+        ### run Simulation
+        wrapper.stop(time = "21s")
+        wrapper.start()
+
+        time.sleep(1)
+
+        wrapper.set(chan, "Delay", "5s")
+
+        time.sleep(5)
+
+        wrapper.set(chan, "Delay", "0s")
+
+        # wait until simulation is over
+        wrapper.shutdown()
+
+        p = subprocess.Popen("rm /tmp/trace-p2p-*",  shell = True)
+        p.communicate()
+        
+        # TODO: Add assertions !!
 
 if __name__ == '__main__':
     unittest.main()