Bugfixing for ns3::MatrixPropagationLossModel ...
[nepi.git] / src / nepi / testbeds / ns3 / execute.py
index 1a76576..7de7bde 100644 (file)
@@ -1,6 +1,6 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
+from util import  _get_ipv4_protocol_guid, _get_node_guid, _get_dev_number
 from nepi.core import testbed_impl
 from nepi.core.attributes import Attribute
 from constants import TESTBED_ID, TESTBED_VERSION
@@ -45,12 +45,9 @@ def load_ns3_module():
                 raise RuntimeError("Imposible to load shared libraries %s" % str(libs))
             libscp = list(libs)
 
-    if not bindings:
-        import ns3
-        sys.modules["ns3"] = ns3
-        return
-    
-    sys.path.append(bindings)
+    if bindings:
+        sys.path.append(bindings)
+
     import ns3_bindings_import as mod
     sys.modules["ns3"] = mod
 
@@ -60,7 +57,9 @@ class TestbedController(testbed_impl.TestbedController):
     LOCAL_FACTORIES = {
         'ns3::Nepi::TunChannel' : TunChannel,
     }
-    
+   
+    DUMMY_FACTORIES = ['ns3::Nepi::MobilityPair']
+
     LOCAL_TYPES = tuple(LOCAL_FACTORIES.values())
 
     def __init__(self):
@@ -101,25 +100,46 @@ class TestbedController(testbed_impl.TestbedController):
 
     def stop(self, time = TIME_NOW):
         super(TestbedController, self).stop(time)
-        #self.ns3.Simulator.Stop()
         self._stop_simulation(time)
 
     def set(self, guid, name, value, time = TIME_NOW):
         super(TestbedController, self).set(guid, name, value, time)
+
         # TODO: take on account schedule time for the task
         factory_id = self._create[guid]
+        if factory_id in self.DUMMY_FACTORIES:
+            return 
+
         factory = self._factories[factory_id]
         element = self._elements[guid]
         if factory_id in self.LOCAL_FACTORIES:
             setattr(element, name, value)
         elif not factory.box_attributes.is_attribute_metadata(name):
-            ns3_value = self._to_ns3_value(guid, name, value)
-            self._set_attribute(name, ns3_value, element)
+            if name == "Up":
+                ipv4_guid =  _get_ipv4_protocol_guid(self, guid)
+                if not ipv4_guid in self._elements:
+                    return
+                ipv4 = self._elements[ipv4_guid]
+                if value == False:
+                    nint = ipv4.GetNInterfaces()
+                    for i in xrange(0, nint):
+                        ipv4.SetDown(i)
+                else:
+                    nint = ipv4.GetNInterfaces()
+                    for i in xrange(0, nint):
+                        ipv4.SetUp(i)
+            else:
+                ns3_value = self._to_ns3_value(guid, name, value)
+                self._set_attribute(name, ns3_value, element)
 
     def get(self, guid, name, time = TIME_NOW):
         value = super(TestbedController, self).get(guid, name, time)
+
         # TODO: take on account schedule time for the task
         factory_id = self._create[guid]
+        if factory_id in self.DUMMY_FACTORIES:
+            return 
+
         factory = self._factories[factory_id]
         element = self._elements[guid]
         if factory_id in self.LOCAL_FACTORIES:
@@ -127,12 +147,25 @@ class TestbedController(testbed_impl.TestbedController):
                 return getattr(element, name)
             else:
                 return value
+        else: 
+            if name == "Up":
+                ipv4_guid =  _get_ipv4_protocol_guid(self, guid)
+                if not ipv4_guid in self._elements:
+                    return True
+                ipv4 = self._elements[ipv4_guid]
+                nint = ipv4.GetNInterfaces()
+                value = True
+                for i in xrange(0, nint):
+                    value = ipv4.IsUp(i)
+                    if not value: break
+                return value
+
         if factory.box_attributes.is_attribute_metadata(name):
             return value
 
         TypeId = self.ns3.TypeId()
         typeid = TypeId.LookupByName(factory_id)
-        info = TypeId.AttributeInfo()
+        info = TypeId.AttributeInformation()
         if not typeid or not typeid.LookupAttributeByName(name, info):
             raise AttributeError("Invalid attribute %s for element type %d" % \
                 (name, guid))
@@ -141,6 +174,7 @@ class TestbedController(testbed_impl.TestbedController):
         self._get_attribute(name, ns3_value, element)
         value = ns3_value.SerializeToString(checker)
         attr_type = factory.box_attributes.get_attribute_type(name)
+
         if attr_type == Attribute.INTEGER:
             return int(value)
         if attr_type == Attribute.DOUBLE:
@@ -156,6 +190,9 @@ class TestbedController(testbed_impl.TestbedController):
         filename = self._traces[guid][trace_id]
         return os.path.join(self.home_directory, filename)
 
+    def trace_filename(self, guid, trace_id):
+        return self._traces[guid][trace_id]
+
     def follow_trace(self, guid, trace_id, filename):
         if not guid in self._traces:
             self._traces[guid] = dict()
@@ -165,25 +202,19 @@ class TestbedController(testbed_impl.TestbedController):
         for element in self._elements.itervalues():
             if isinstance(element, self.LOCAL_TYPES):
                 # graceful shutdown of locally-implemented objects
-                element.Cleanup()
+                element.cleanup()
         if self.ns3:
-            self.ns3.Simulator.Stop()
+            if not self.ns3.Simulator.IsFinished():
+                self.stop()
             
-            # Wait for it to stop, with a 30s timeout
-            for i in xrange(300):
-                if self.ns3.Simulator.IsFinished():
-                    break
-                time.sleep(0.1)
-            #self._stop_simulation("0s")
-        
-        self._elements.clear()
-        
-        if self.ns3:
             # TODO!!!! SHOULD WAIT UNTIL THE THREAD FINISHES
-            #   if self._simulator_thread:
-            #       self._simulator_thread.join()
+            if self._simulator_thread:
+                self._simulator_thread.join()
+            
             self.ns3.Simulator.Destroy()
         
+        self._elements.clear()
+        
         self._ns3 = None
         sys.stdout.flush()
         sys.stderr.flush()
@@ -198,7 +229,7 @@ class TestbedController(testbed_impl.TestbedController):
 
     def _schedule_event(self, condition, func, *args):
         """Schedules event on running experiment"""
-        def execute_event(condition, has_event_occurred, func, *args):
+        def execute_event(contextId, condition, has_event_occurred, func, *args):
             # exec func
             try:
                 func(*args)
@@ -219,12 +250,14 @@ class TestbedController(testbed_impl.TestbedController):
         # bool flag, a list is used as wrapper
         has_event_occurred = [False]
         condition.acquire()
-        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.release()
+        try:
+            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()
+        finally:
+            condition.release()
 
     def _set_attribute(self, name, ns3_value, element):
         if self.status() == TS.STATUS_STARTED:
@@ -268,7 +301,7 @@ class TestbedController(testbed_impl.TestbedController):
         factory_id = self._create[guid]
         TypeId = self.ns3.TypeId()
         typeid = TypeId.LookupByName(factory_id)
-        info = TypeId.AttributeInfo()
+        info = TypeId.AttributeInformation()
         if not typeid.LookupAttributeByName(name, info):
             raise RuntimeError("Attribute %s doesn't belong to element %s" \
                    % (name, factory_id))
@@ -313,7 +346,7 @@ class TestbedController(testbed_impl.TestbedController):
         TypeId = self.ns3.TypeId()
         typeid = TypeId.LookupByName(factory_id)
         for name, value in params.iteritems():
-            info = self.ns3.TypeId.AttributeInfo()
+            info = self.ns3.TypeId.AttributeInformation()
             found = typeid.LookupAttributeByName(name, info)
             if found and \
                 (info.flags & TypeId.ATTR_CONSTRUCT == TypeId.ATTR_CONSTRUCT):