Fix #143 - [NS3] Integrate DCE bindings
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 24 Feb 2014 17:42:45 +0000 (18:42 +0100)
committerAlina Quereilhac <alina.quereilhac@inria.fr>
Mon, 24 Feb 2014 17:42:45 +0000 (18:42 +0100)
12 files changed:
src/nepi/resources/linux/ns3/ns3simulation.py
src/nepi/resources/ns3/classes/dce_application.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/dsrdsr_routing.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/icmpv6l4protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/tcp_l4protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/udp_l4protocol.py [new file with mode: 0644]
src/nepi/resources/ns3/classes/wifi_net_device.py
src/nepi/resources/ns3/classes/yans_wifi_channel.py
src/nepi/resources/ns3/ns3dceapplication.py [new file with mode: 0644]
src/nepi/resources/ns3/ns3node.py
src/nepi/resources/ns3/resource_manager_generator.py
test/resources/linux/ns3/ns3simulation.py

index 5745f54..f4a5a6b 100644 (file)
@@ -119,6 +119,8 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
         self._client = None
         self._home = "ns3-simu-%s" % self.guid
         self._socket_name = "ns3-%s.sock" % os.urandom(4).encode('hex')
+        self._dce_helper_uuid = None
+        self._dce_application_helper_uuid = None
 
     @property
     def socket_name(self):
@@ -128,6 +130,14 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
     def remote_socket(self):
         return os.path.join(self.run_home, self.socket_name)
 
+    @property
+    def dce_helper_uuid(self):
+        return self._dce_helper_uuid
+
+    @property
+    def dce_application_helper_uuid(self):
+        return self._dce_application_helper_uuid
+
     @property
     def ns3_build_home(self):
         return os.path.join(self.node.bin_dir, "ns-3", self.get("ns3Version"), 
@@ -207,6 +217,10 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
             sched_type = self.get("schedulerType")
             stype = self.create("StringValue", sched_type)
             self.invoke(GLOBAL_VALUE_UUID, "Bind", "SchedulerType", btrue)
+        
+        if self.get("enableDCE"):
+            self._dce_helper_uuid = self.create("DceManagerHelper")
+            self._dce_application_helper_uuid = self.create("DceApplicationHelper")
 
     def do_deploy(self):
         if not self.node or self.node.state < ResourceState.READY:
@@ -302,7 +316,7 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
 
         ns_log = self.get("nsLog")
         if ns_log:
-            command.append("-L %s" % ns_log)
+            command.append("-L '%s'" % ns_log)
 
         if self.get("verbose"):
             command.append("-v")
@@ -464,16 +478,18 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
                         " (   "
                          # If not, copy ns-3 build to bin
                         "  cd ${SRC}/dce/ns-3-dce && "
-                        "  ./waf configure --enable-opt --with-pybindgen=${SRC}/pybindgen/%(pybindgen_version)s "
+                        "  ./waf configure %(enable_opt)s --with-pybindgen=${SRC}/pybindgen/%(pybindgen_version)s "
                         "  --prefix=%(ns3_build_home)s --with-ns3=%(ns3_build_home)s && "
                         "  ./waf build && "
-                        "  ./waf install "
+                        "  ./waf install && "
+                        "  mv %(ns3_build_home)s/lib/python*/site-packages/ns/dce.so %(ns3_build_home)s/lib/python/site-packages/ns/ "
                         " )"
                 ) % { 
                     'ns3_version': self.get("ns3Version"),
                     'pybindgen_version': self.get("pybindgenVersion"),
                     'ns3_build_home': self.ns3_build_home,
                     'build_mode': self.get("buildMode"),
+                    'enable_opt': "--enable-opt" if  self.get("buildMode") == "optimized" else ""
                     }
 
         return (
@@ -517,6 +533,8 @@ class LinuxNS3Simulation(LinuxApplication, NS3Simulation):
         env.append("LD_LIBRARY_PATH=${NS3LIBRARIES:=%(ns3_build_home)s/lib/}" % { 
                     'ns3_build_home': self.ns3_build_home
                  })
+        env.append("DCE_PATH=$PATH:$NS3LIBRARIES/../bin_dce")
+        env.append("DCE_ROOT=$PATH:$NS3LIBRARIES/..")
 
         return " ".join(env) 
 
diff --git a/src/nepi/resources/ns3/classes/dce_application.py b/src/nepi/resources/ns3/classes/dce_application.py
new file mode 100644 (file)
index 0000000..9b42c54
--- /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.ns3dceapplication import NS3BaseDceApplication 
+
+@clsinit_copy
+class NS3DceApplication(NS3BaseDceApplication):
+    _rtype = "ns3::DceApplication"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        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):
+        
+        processstarted = Trace("ProcessStarted", "notify when the dce is started")
+
+        cls._register_trace(processstarted)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3DceApplication, self).__init__(ec, guid)
+        self._home = "ns3-dce-application-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/dsrdsr_routing.py b/src/nepi/resources/ns3/classes/dsrdsr_routing.py
new file mode 100644 (file)
index 0000000..e6f83ff
--- /dev/null
@@ -0,0 +1,449 @@
+#
+#    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.ns3base import NS3Base
+
+@clsinit_copy
+class NS3dsrDsrRouting(NS3Base):
+    _rtype = "ns3::dsr::DsrRouting"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_maxsendbufflen = Attribute("MaxSendBuffLen",
+            "Maximum number of packets that can be stored in send buffer.",
+            type = Types.Integer,
+            default = "64",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxsendbufflen)
+
+        attr_maxsendbufftime = Attribute("MaxSendBuffTime",
+            "Maximum time packets can be queued in the send buffer .",
+            type = Types.String,
+            default = "+30000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxsendbufftime)
+
+        attr_maxmaintlen = Attribute("MaxMaintLen",
+            "Maximum number of packets that can be stored in maintenance buffer.",
+            type = Types.Integer,
+            default = "50",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxmaintlen)
+
+        attr_maxmainttime = Attribute("MaxMaintTime",
+            "Maximum time packets can be queued in maintenance buffer.",
+            type = Types.String,
+            default = "+30000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxmainttime)
+
+        attr_maxcachelen = Attribute("MaxCacheLen",
+            "Maximum number of route entries that can be stored in route cache.",
+            type = Types.Integer,
+            default = "64",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxcachelen)
+
+        attr_routecachetimeout = Attribute("RouteCacheTimeout",
+            "Maximum time the route cache can be queued in route cache.",
+            type = Types.String,
+            default = "+300000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_routecachetimeout)
+
+        attr_maxentrieseachdst = Attribute("MaxEntriesEachDst",
+            "Maximum number of route entries for a single destination to respond.",
+            type = Types.Integer,
+            default = "20",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxentrieseachdst)
+
+        attr_sendbuffinterval = Attribute("SendBuffInterval",
+            "How often to check send buffer for packet with route.",
+            type = Types.String,
+            default = "+500000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sendbuffinterval)
+
+        attr_nodetraversaltime = Attribute("NodeTraversalTime",
+            "The time it takes to traverse two neighboring nodes.",
+            type = Types.String,
+            default = "+40000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nodetraversaltime)
+
+        attr_rreqretries = Attribute("RreqRetries",
+            "Maximum number of retransmissions for request discovery of a route.",
+            type = Types.Integer,
+            default = "16",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rreqretries)
+
+        attr_maintenanceretries = Attribute("MaintenanceRetries",
+            "Maximum number of retransmissions for data packets from maintenance buffer.",
+            type = Types.Integer,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maintenanceretries)
+
+        attr_requesttablesize = Attribute("RequestTableSize",
+            "Maximum number of request entries in the request table, set this as the number of nodes in the simulation.",
+            type = Types.Integer,
+            default = "64",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_requesttablesize)
+
+        attr_requestidsize = Attribute("RequestIdSize",
+            "Maximum number of request source Ids in the request table.",
+            type = Types.Integer,
+            default = "16",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_requestidsize)
+
+        attr_uniquerequestidsize = Attribute("UniqueRequestIdSize",
+            "Maximum number of request Ids in the request table for a single destination.",
+            type = Types.Integer,
+            default = "256",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_uniquerequestidsize)
+
+        attr_nonproprequesttimeout = Attribute("NonPropRequestTimeout",
+            "The timeout value for non-propagation request.",
+            type = Types.String,
+            default = "+30000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_nonproprequesttimeout)
+
+        attr_discoveryhoplimit = Attribute("DiscoveryHopLimit",
+            "The max discovery hop limit for route requests.",
+            type = Types.Integer,
+            default = "255",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_discoveryhoplimit)
+
+        attr_maxsalvagecount = Attribute("MaxSalvageCount",
+            "The max salvage count for a single data packet.",
+            type = Types.Integer,
+            default = "15",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxsalvagecount)
+
+        attr_blacklisttimeout = Attribute("BlacklistTimeout",
+            "The time for a neighbor to stay in blacklist.",
+            type = Types.String,
+            default = "+3000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_blacklisttimeout)
+
+        attr_gratreplyholdoff = Attribute("GratReplyHoldoff",
+            "The time for gratuitous reply entry to expire.",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_gratreplyholdoff)
+
+        attr_broadcastjitter = Attribute("BroadcastJitter",
+            "The jitter time to avoid collision for broadcast packets.",
+            type = Types.Integer,
+            default = "10",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_broadcastjitter)
+
+        attr_linkacktimeout = Attribute("LinkAckTimeout",
+            "The time a packet in maintenance buffer wait for link acknowledgment.",
+            type = Types.String,
+            default = "+100000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_linkacktimeout)
+
+        attr_trylinkacks = Attribute("TryLinkAcks",
+            "The number of link acknowledgment to use.",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_trylinkacks)
+
+        attr_passiveacktimeout = Attribute("PassiveAckTimeout",
+            "The time a packet in maintenance buffer wait for passive acknowledgment.",
+            type = Types.String,
+            default = "+100000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_passiveacktimeout)
+
+        attr_trypassiveacks = Attribute("TryPassiveAcks",
+            "The number of passive acknowledgment to use.",
+            type = Types.Integer,
+            default = "1",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_trypassiveacks)
+
+        attr_requestperiod = Attribute("RequestPeriod",
+            "The base time interval between route requests.",
+            type = Types.String,
+            default = "+500000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_requestperiod)
+
+        attr_maxrequestperiod = Attribute("MaxRequestPeriod",
+            "The max time interval between route requests.",
+            type = Types.String,
+            default = "+10000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxrequestperiod)
+
+        attr_grareplytablesize = Attribute("GraReplyTableSize",
+            "The gratuitous reply table size.",
+            type = Types.Integer,
+            default = "64",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_grareplytablesize)
+
+        attr_cachetype = Attribute("CacheType",
+            "Use Link Cache or use Path Cache",
+            type = Types.String,
+            default = "LinkCache",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_cachetype)
+
+        attr_stabilitydecrfactor = Attribute("StabilityDecrFactor",
+            "The stability decrease factor for link cache",
+            type = Types.Integer,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stabilitydecrfactor)
+
+        attr_stabilityincrfactor = Attribute("StabilityIncrFactor",
+            "The stability increase factor for link cache",
+            type = Types.Integer,
+            default = "4",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_stabilityincrfactor)
+
+        attr_initstability = Attribute("InitStability",
+            "The initial stability factor for link cache",
+            type = Types.String,
+            default = "+25000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_initstability)
+
+        attr_minlifetime = Attribute("MinLifeTime",
+            "The minimal life time for link cache",
+            type = Types.String,
+            default = "+1000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_minlifetime)
+
+        attr_useextends = Attribute("UseExtends",
+            "The extension time for link cache",
+            type = Types.String,
+            default = "+120000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_useextends)
+
+        attr_enablesubroute = Attribute("EnableSubRoute",
+            "Enables saving of sub route when receiving route error messages, only available when using path route cache",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_enablesubroute)
+
+        attr_retransincr = Attribute("RetransIncr",
+            "The increase time for retransmission timer when facing network congestion",
+            type = Types.String,
+            default = "+20000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_retransincr)
+
+        attr_maxnetworkqueuesize = Attribute("MaxNetworkQueueSize",
+            "The max number of packet to save in the network queue.",
+            type = Types.Integer,
+            default = "400",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxnetworkqueuesize)
+
+        attr_maxnetworkqueuedelay = Attribute("MaxNetworkQueueDelay",
+            "The max time for a packet to stay in the network queue.",
+            type = Types.String,
+            default = "+30000000000.0ns",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_maxnetworkqueuedelay)
+
+        attr_numpriorityqueues = Attribute("NumPriorityQueues",
+            "The max number of packet to save in the network queue.",
+            type = Types.Integer,
+            default = "2",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_numpriorityqueues)
+
+        attr_linkacknowledgment = Attribute("LinkAcknowledgment",
+            "Enable Link layer acknowledgment mechanism",
+            type = Types.Bool,
+            default = "False",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_linkacknowledgment)
+
+        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):
+        
+        tx = Trace("Tx", "Send DSR packet.")
+
+        cls._register_trace(tx)
+
+        drop = Trace("Drop", "Drop DSR packet")
+
+        cls._register_trace(drop)
+
+
+
+    def __init__(self, ec, guid):
+        super(NS3dsrDsrRouting, self).__init__(ec, guid)
+        self._home = "ns3-dsr-dsr-routing-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/icmpv6l4protocol.py b/src/nepi/resources/ns3/classes/icmpv6l4protocol.py
new file mode 100644 (file)
index 0000000..23e37b1
--- /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.ns3base import NS3Base
+
+@clsinit_copy
+class NS3Icmpv6L4Protocol(NS3Base):
+    _rtype = "ns3::Icmpv6L4Protocol"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_dad = Attribute("DAD",
+            "Always do DAD check.",
+            type = Types.Bool,
+            default = "True",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_dad)
+
+        attr_solicitationjitter = Attribute("SolicitationJitter",
+            "The jitter in ms a node is allowed to wait before sending any solicitation . 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 SolicitationJitter",
+            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_solicitationjitter)
+
+        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(NS3Icmpv6L4Protocol, self).__init__(ec, guid)
+        self._home = "ns3-icmpv6l4protocol-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/tcp_l4protocol.py b/src/nepi/resources/ns3/classes/tcp_l4protocol.py
new file mode 100644 (file)
index 0000000..ef21f8f
--- /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.ns3base import NS3Base
+
+@clsinit_copy
+class NS3TcpL4Protocol(NS3Base):
+    _rtype = "ns3::TcpL4Protocol"
+
+    @classmethod
+    def _register_attributes(cls):
+        
+        attr_rttestimatortype = Attribute("RttEstimatorType",
+            "Type of RttEstimator objects.",
+            type = Types.String,
+            default = "ns3::RttMeanDeviation",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_rttestimatortype)
+
+        attr_sockettype = Attribute("SocketType",
+            "Socket type of TCP objects.",
+            type = Types.String,
+            default = "ns3::TcpNewReno",  
+            allowed = None,
+            range = None,    
+            flags = Flags.Reserved | Flags.Construct)
+
+        cls._register_attribute(attr_sockettype)
+
+        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(NS3TcpL4Protocol, self).__init__(ec, guid)
+        self._home = "ns3-tcp-l4protocol-%s" % self.guid
diff --git a/src/nepi/resources/ns3/classes/udp_l4protocol.py b/src/nepi/resources/ns3/classes/udp_l4protocol.py
new file mode 100644 (file)
index 0000000..c81c162
--- /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.ns3base import NS3Base
+
+@clsinit_copy
+class NS3UdpL4Protocol(NS3Base):
+    _rtype = "ns3::UdpL4Protocol"
+
+    @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(NS3UdpL4Protocol, self).__init__(ec, guid)
+        self._home = "ns3-udp-l4protocol-%s" % self.guid
index 92dd859..f4f7345 100644 (file)
@@ -20,10 +20,10 @@ 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 
+from nepi.resources.ns3.ns3netdevice import NS3BaseNetDevice 
 
 @clsinit_copy
-class NS3WifiNetDevice(NS3BaseWifiNetDevice):
+class NS3WifiNetDevice(NS3BaseNetDevice):
     _rtype = "ns3::WifiNetDevice"
 
     @classmethod
index 314d391..325c29b 100644 (file)
@@ -20,10 +20,10 @@ 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 
+from nepi.resources.ns3.ns3channel import NS3BaseChannel 
 
 @clsinit_copy
-class NS3YansWifiChannel(NS3BaseWifiChannel):
+class NS3YansWifiChannel(NS3BaseChannel):
     _rtype = "ns3::YansWifiChannel"
 
     @classmethod
diff --git a/src/nepi/resources/ns3/ns3dceapplication.py b/src/nepi/resources/ns3/ns3dceapplication.py
new file mode 100644 (file)
index 0000000..5d34e84
--- /dev/null
@@ -0,0 +1,102 @@
+#
+#    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, ResourceState, reschedule_delay
+from nepi.resources.ns3.ns3application import NS3BaseApplication
+
+@clsinit_copy
+class NS3BaseDceApplication(NS3BaseApplication):
+    _rtype = "abstract::ns3::DceApplication"
+
+    @classmethod
+    def _register_attributes(cls):
+        binary = Attribute("binary", 
+                "Name of binary to execute",
+                flags = Flags.Design)
+
+        stack_size = Attribute("stackSize", 
+                "Stack Size for DCE",
+                type = Types.Integer,
+                default = 1<<20,                
+                flags = Flags.Design)
+
+        arguments = Attribute("arguments", 
+                "Semi-colon separated list of arguments for the application",
+                flags = Flags.Design)
+
+        cls._register_attribute(binary)
+        cls._register_attribute(stack_size)
+        cls._register_attribute(arguments)
+
+    @property
+    def node(self):
+        from nepi.resources.ns3.ns3node import NS3BaseNode
+        nodes = self.get_connected(NS3BaseNode.get_rtype())
+
+        if not nodes: 
+            msg = "DceApplication not connected to node"
+            self.error(msg)
+            raise RuntimeError, msg
+
+        if nodes[0].get("enableDCE") == False:
+            raise RuntimeError("DceApplication not connected to DCE enabled node")
+
+        return nodes[0]
+
+    def _connect_object(self):
+        node = self.node
+        if node.uuid not in self.connected:
+            self._connected.add(node.uuid)
+            self.simulation.invoke(self.simulation.dce_application_helper_uuid, 
+                    "ResetArguments") 
+
+            self.simulation.invoke(self.simulation.dce_application_helper_uuid, 
+                    "SetBinary", self.get("binary")) 
+
+            self.simulation.invoke(self.simulation.dce_application_helper_uuid, 
+                    "SetStackSize", self.get("stackSize")) 
+
+            arguments = self.get("arguments") or ""
+            for arg in map(str.strip, arguments.split(";")):
+                self.simulation.invoke(self.simulation.dce_application_helper_uuid, 
+                    "AddArgument", arg) 
+
+            apps_uuid = self.simulation.invoke(self.simulation.dce_application_helper_uuid, 
+                    "InstallInNode", self.node.uuid)
+
+            #start_time = self.get("StartTime") 
+            #time_uuid = self.simulation.create("Time", start_time)
+            #self.simulation.invoke(apps_uuid, "Start", time_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()
+            self._start_time = self.simulation.start_time
+
index 491cd91..dded05f 100644 (file)
@@ -106,31 +106,8 @@ class NS3BaseNode(NS3Base):
             self.simulation.invoke(self.uuid, "AggregateObject", mobility.uuid)
 
     def _add_dce(self):
-        # TODO: All these component types should be configurable somewhere
-        """
-        manager_uuid = self.simulation.create("ns3::TaskManager")
-        m_schedulerFactory.SetTypeId ("ns3::RrTaskScheduler");
-        m_managerFactory.SetTypeId ("ns3::DceManager");
-        m_networkStackFactory.SetTypeId ("ns3::Ns3SocketFdFactory");
-        m_delayFactory.SetTypeId ("ns3::RandomProcessDelayModel");
-
-         Ptr<TaskManager> taskManager = m_taskManagerFactory.Create<TaskManager> ();
-         Ptr<TaskScheduler> scheduler = m_schedulerFactory.Create<TaskScheduler> ();
-         Ptr<LoaderFactory> loader = m_loaderFactory.Create<LoaderFactory> ();
-         Ptr<SocketFdFactory> networkStack = m_networkStackFactory.Create<SocketFdFactory> ();
-         Ptr<ProcessDelayModel> delay = m_delayFactory.Create<ProcessDelayModel> ();
-
-         taskManager->SetScheduler (scheduler);
-         taskManager->SetDelayModel (delay);
-         manager->SetAttribute ("FirstPid", UintegerValue (g_firstPid.GetInteger (0, 0xffff)));
-         Ptr<Node> node = *i;
-         node->AggregateObject (taskManager);
-         node->AggregateObject (loader);
-         node->AggregateObject (manager);
-         node->AggregateObject (networkStack);
-         node->AggregateObject (CreateObject<LocalSocketFdFactory> ());
-         manager->AggregateObject (CreateObject<DceNodeContext> ());
-         manager->SetVirtualPath (GetVirtualPath ());
-        """
-        pass
+        container_uuid = self.simulation.create("NodeContainer")
+        self.simulation.invoke(container_uuid, "Add", self.uuid)
+        self.simulation.invoke(self.simulation.dce_helper_uuid, "Install", 
+                container_uuid)
 
index 9ec844e..5eae3c8 100644 (file)
@@ -23,8 +23,9 @@ from nepi.resources.ns3.ns3wrapper import load_ns3_module
 import os
 import re
 
-base_types = ["ns3::Node",
+adapted_types = ["ns3::Node",
         "ns3::Application", 
+        #"ns3::DceApplication", 
         "ns3::NetDevice",
         "ns3::Channel",
         "ns3::Queue",
@@ -42,34 +43,34 @@ base_types = ["ns3::Node",
         "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
+base_types = ["ns3::IpL4Protocol"]
 
 def select_base_class(ns3, tid): 
-    base_class_import = "from nepi.resources.ns3.ns3base import NS3Base"
-    base_class = "NS3Base"
+    base_class_import = None
+    base_class = None
    
     rtype = tid.GetName()
 
     type_id = ns3.TypeId()
 
-    for type_name in base_types:
+    for type_name in adapted_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)
 
-    return (base_class_import, base_class)
+    base_class_import = "from nepi.resources.ns3.ns3base import NS3Base"
+    base_class = "NS3Base"
+
+    for type_name in base_types:
+        tid_base = type_id.LookupByName(type_name)
+        if type_name == rtype or tid.IsChildOf(tid_base):
+            return (base_class_import, base_class)
+
+    return (None, None)
 
 def create_ns3_rms():
     ns3 = load_ns3_module()
@@ -83,7 +84,8 @@ def create_ns3_rms():
     for i in xrange(tid_count):
         tid = type_id.GetRegistered(i)
         
-        if discard(ns3, tid):
+        (base_class_import, base_class) = select_base_class(ns3, tid)
+        if not base_class:
             continue
         
         if tid.MustHideFromDocumentation() or \
@@ -102,8 +104,6 @@ def create_ns3_rms():
         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()
index 19f2b32..d5cec09 100644 (file)
@@ -49,6 +49,9 @@ def add_ns3_node(ec, simu):
     icmp = ec.register_resource("ns3::Icmpv4L4Protocol")
     ec.register_connection(node, icmp)
 
+    udp = ec.register_resource("ns3::UdpL4Protocol")
+    ec.register_connection(node, udp)
+
     return node
 
 def add_point2point_device(ec, node, address = None,  prefix = None):
@@ -763,16 +766,6 @@ class LinuxNS3ClientTest(unittest.TestCase):
         ec.shutdown()
 
     def test_dce(self):
-        """ 
-        network topology:
-                                n4
-                                |
-           n1 -- p2p -- n2 -- csma -- n5 -- p2p -- n6
-           |                    | 
-           ping n6              n3
-           
-
-        """
         ec = ExperimentController(exp_id = "test-ns3-dce")
         
         node = ec.register_resource("LinuxNode")
@@ -785,39 +778,52 @@ class LinuxNS3ClientTest(unittest.TestCase):
         simu = ec.register_resource("LinuxNS3Simulation")
         ec.set(simu, "verbose", True)
         ec.set(simu, "enableDCE", True)
+        ec.set(simu, "buildMode", "debug")
+        ec.set(simu, "nsLog", "DceApplication")
         ec.register_connection(simu, node)
 
         nsnode1 = add_ns3_node(ec, simu)
+        ec.set(nsnode1, "enableDCE", True)
         p2p1 = add_point2point_device(ec, nsnode1, "10.0.0.1", "30")
+        ec.set(p2p1, "DataRate", "5Mbps")
 
         nsnode2 = add_ns3_node(ec, simu)
+        ec.set(nsnode2, "enableDCE", True)
         p2p2 = add_point2point_device(ec, nsnode2, "10.0.0.2", "30")
+        ec.set(p2p2, "DataRate", "5Mbps")
 
         # Create channel
         chan = ec.register_resource("ns3::PointToPointChannel")
-        ec.set(chan, "Delay", "0s")
+        ec.set(chan, "Delay", "2ms")
+
         ec.register_connection(chan, p2p1)
         ec.register_connection(chan, p2p2)
 
-        ### 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", "1s")
-        ec.set (ping, "StopTime", "21s")
-        ec.register_connection(ping, nsnode1)
+        ### create applications
+        udp_perf = ec.register_resource("ns3::DceApplication")
+        ec.set (udp_perf, "binary", "udp-perf")
+        ec.set (udp_perf, "stackSize", 1<<20)
+        ec.set (udp_perf, "arguments", "--duration=10;--nodes=2")
+        ec.set (udp_perf, "StartTime", "1s")
+        ec.set (udp_perf, "StopTime", "20s")
+        ec.register_connection(udp_perf, nsnode1)
+
+        udp_perf_client = ec.register_resource("ns3::DceApplication")
+        ec.set (udp_perf_client, "binary", "udp-perf")
+        ec.set (udp_perf_client, "stackSize", 1<<20)
+        ec.set (udp_perf_client, "arguments", "--client;--nodes=2;--host=10.0.0.1;--duration=10")
+        ec.set (udp_perf_client, "StartTime", "2s")
+        ec.set (udp_perf_client, "StopTime", "20s")
+        ec.register_connection(udp_perf_client, nsnode2)
 
         ec.deploy()
 
-        ec.wait_finished([ping])
+        ec.wait_finished([udp_perf_client])
         
-        stdout = ec.trace(simu, "stdout")
-
-        print stdout
+        stderr = ec.trace(simu, "stderr")
 
-        expected = "20 packets transmitted, 20 received, 0% packet loss"
-        self.assertTrue(stdout.find(expected) > -1)
+        expected = "DceApplication:StartApplication"
+        self.assertTrue(stderr.find(expected) > -1)
 
         ec.shutdown()