X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Fns3%2Fns3wrapper.py;h=a9a5e126f693096aa363ee134d239ea48c69c6c3;hb=9199b66cf4e5c3bdf8926153a63084c352c40721;hp=eea32d06ef677d0ae0d96f8a7e5323a38828fb1f;hpb=c7aa07353fb951c845b82ff33e88bbe6f9bfced8;p=nepi.git diff --git a/src/nepi/resources/ns3/ns3wrapper.py b/src/nepi/resources/ns3/ns3wrapper.py index eea32d06..a9a5e126 100644 --- a/src/nepi/resources/ns3/ns3wrapper.py +++ b/src/nepi/resources/ns3/ns3wrapper.py @@ -3,9 +3,8 @@ # 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. +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation; # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -131,7 +130,7 @@ class NS3Wrapper(object): self._allowed_types = None # Object to dump instructions to reproduce and debug experiment - from ns3wrapper_debug import NS3WrapperDebuger + from nepi.resources.ns3.ns3wrapper_debug import NS3WrapperDebuger self._debuger = NS3WrapperDebuger(enabled = enable_dump) @property @@ -155,7 +154,7 @@ class NS3Wrapper(object): tid_count = type_id.GetRegisteredN() base = type_id.LookupByName("ns3::Object") - for i in xrange(tid_count): + for i in range(tid_count): tid = type_id.GetRegistered(i) if tid.MustHideFromDocumentation() or \ @@ -174,7 +173,16 @@ class NS3Wrapper(object): @property def is_running(self): - return self._started and not self.ns3.Simulator.IsFinished() + return self.is_started and not self.ns3.Simulator.IsFinished() + + @property + def is_started(self): + if not self._started: + now = self.ns3.Simulator.Now() + if not now.IsZero(): + self._started = True + + return self._started @property def is_finished(self): @@ -199,13 +207,13 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("FACTORY %s( %s )" % (type_name, str(kwargs))) + ### DUMP self.debuger.dump_factory(uuid, type_name, kwargs) - ######## factory = self.ns3.ObjectFactory() factory.SetTypeId(type_name) - for name, value in kwargs.iteritems(): + for name, value in kwargs.items(): ns3_value = self._attr_from_string_to_ns3_value(type_name, name, value) factory.Set(name, ns3_value) @@ -216,7 +224,6 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("RET FACTORY ( uuid %s ) %s = %s( %s )" % ( str(uuid), str(obj), type_name, str(kwargs))) - ######## return uuid @@ -233,8 +240,8 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("CREATE %s( %s )" % (clazzname, str(args))) + ### DUMP self.debuger.dump_create(uuid, clazzname, args) - ######## clazz = getattr(self.ns3, clazzname) @@ -249,7 +256,6 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("RET CREATE ( uuid %s ) %s = %s( %s )" % (str(uuid), str(obj), clazzname, str(args))) - ######## return uuid @@ -264,45 +270,66 @@ class NS3Wrapper(object): if operation == "isRunning": result = self.is_running + + elif operation == "isStarted": + result = self.is_started + elif operation == "isFinished": result = self.is_finished + elif operation == "isAppRunning": result = self._is_app_running(uuid) + + elif operation == "isAppStarted": + result = self._is_app_started(uuid) + + elif operation == "recvFD": + ### passFD operation binds to a different random socket + ### en every execution, so the socket name that could be + ### dumped to the debug script using dump_invoke is + ### not be valid accross debug executions. + result = self._recv_fd(uuid, *args, **kwargs) + + elif operation == "addStaticRoute": + result = self._add_static_route(uuid, *args) + + ### DUMP - result is static, so will be dumped as plain text + self.debuger.dump_invoke(result, uuid, operation, args, kwargs) + + elif operation == "retrieveObject": + result = self._retrieve_object(uuid, *args, **kwargs) + + ### DUMP - result is static, so will be dumped as plain text + self.debuger.dump_invoke(result, uuid, operation, args, kwargs) + else: newuuid = self.make_uuid() - ### DEBUG + ### DUMP - result is a uuid that encoded an dynamically generated + ### object self.debuger.dump_invoke(newuuid, uuid, operation, args, kwargs) - ######## - - if operation == "addStaticRoute": - result = self._add_static_route(uuid, *args) - - elif operation == "retrieveObject": - result = self._retrieve_object(uuid, *args, **kwargs) + if uuid.startswith(SINGLETON): + obj = self._singleton(uuid) else: - if uuid.startswith(SINGLETON): - obj = self._singleton(uuid) - else: - obj = self.get_object(uuid) - - method = getattr(obj, operation) + obj = self.get_object(uuid) + + method = getattr(obj, operation) - # 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) + # 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) - result = method(*realargs, **realkwargs) + result = method(*realargs, **realkwargs) - # If the result is an object (not a base value), - # then keep track of the object a return the object - # reference (newuuid) - if not (result is None or type(result) in [ - bool, float, long, str, int]): - self._objects[newuuid] = result - result = newuuid + # If the result is an object (not a base value), + # then keep track of the object a return the object + # reference (newuuid) + if not (result is None or type(result) in [ + bool, float, long, str, int]): + self._objects[newuuid] = result + result = newuuid ### DEBUG self.logger.debug("RET INVOKE %s%s = %s -> %s(%s, %s) " % ( @@ -319,8 +346,8 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("SET %s %s %s" % (uuid, name, str(value))) + ### DUMP self.debuger.dump_set(uuid, name, value) - ######## obj = self.get_object(uuid) type_name = obj.GetInstanceTypeId().GetName() @@ -347,7 +374,6 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("RET SET %s = %s -> set(%s, %s)" % (str(value), uuid, name, str(value))) - ######## return value @@ -358,8 +384,8 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("GET %s %s" % (uuid, name)) + ### DUMP self.debuger.dump_get(uuid, name) - ######## obj = self.get_object(uuid) type_name = obj.GetInstanceTypeId().GetName() @@ -379,14 +405,12 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("RET GET %s = %s -> get(%s)" % (str(result), uuid, name)) - ######## return result def start(self): - ### DEBUG + ### DUMP self.debuger.dump_start() - ######## # Launch the simulator thread and Start the # simulator in that thread @@ -396,16 +420,13 @@ class NS3Wrapper(object): args = [self._condition]) self._simulator_thread.setDaemon(True) self._simulator_thread.start() - self._started = True - + ### DEBUG self.logger.debug("START") - ######## def stop(self, time = None): - ### DEBUG + ### DUMP self.debuger.dump_stop(time=time) - ######## if time is None: self.ns3.Simulator.Stop() @@ -414,12 +435,10 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("STOP time=%s" % str(time)) - ######## def shutdown(self): - ### DEBUG + ### DUMP self.debuger.dump_shutdown() - ######## while not self.ns3.Simulator.IsFinished(): #self.logger.debug("Waiting for simulation to finish") @@ -438,7 +457,6 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("SHUTDOWN") - ######## def _simulator_run(self, condition): # Run simulation @@ -557,19 +575,22 @@ class NS3Wrapper(object): 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()]) + for k,v in kwargs.items()]) realkwargs = dict([(k, self._singleton(v) \ if str(v).startswith(SINGLETON) else v )\ - for k, v in realkwargs.iteritems()]) + for k, v in realkwargs.items()]) return realkwargs - def _is_app_running(self, uuid): + def _is_app_running(self, uuid): now = self.ns3.Simulator.Now() if now.IsZero(): return False + if self.ns3.Simulator.IsFinished(): + return False + app = self.get_object(uuid) stop_time_value = self.ns3.TimeValue() app.GetAttribute("StopTime", stop_time_value) @@ -579,10 +600,14 @@ class NS3Wrapper(object): 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 + if now.Compare(start_time) >= 0: + if stop_time.IsZero() or now.Compare(stop_time) < 0: + return True return False + + def _is_app_started(self, uuid): + return self._is_app_running(uuid) or self.is_finished def _add_static_route(self, ipv4_uuid, network, prefix, nexthop): ipv4 = self.get_object(ipv4_uuid) @@ -620,10 +645,10 @@ class NS3Wrapper(object): # 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): + for ifidx in range(nifaces): iface = ipv4.GetInterface(ifidx) naddress = iface.GetNAddresses() - for addridx in xrange(naddress): + for addridx in range(naddress): ifaddr = iface.GetAddress(addridx) ifmask = ifaddr.GetMask() @@ -643,7 +668,7 @@ class NS3Wrapper(object): newuuid = None if search: # search object - for ouuid, oobj in self._objects.iteritems(): + for ouuid, oobj in self._objects.items(): if nobj == oobj: newuuid = ouuid break @@ -653,5 +678,28 @@ class NS3Wrapper(object): return newuuid + def _recv_fd(self, uuid): + """ Waits on a local address to receive a file descriptor + from a local process. The file descriptor is associated + to a FdNetDevice to stablish communication between the + simulation and what ever process writes on that file descriptor + """ + + def recvfd(sock, fdnd): + (fd, msg) = passfd.recvfd(sock) + # Store a reference to the endpoint to keep the socket alive + fdnd.SetFileDescriptor(fd) + + import passfd + import socket + sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) + sock.bind("") + address = sock.getsockname() + + fdnd = self.get_object(uuid) + t = threading.Thread(target=recvfd, args=(sock,fdnd)) + t.start() + + return address