X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Fns3%2Fns3wrapper.py;h=a9a5e126f693096aa363ee134d239ea48c69c6c3;hb=9199b66cf4e5c3bdf8926153a63084c352c40721;hp=0e95a2bd62e8eeab1dea20cc23264a0a809dff0a;hpb=2d175bc378aa7ec034d24b6d3f04714fd9efab41;p=nepi.git diff --git a/src/nepi/resources/ns3/ns3wrapper.py b/src/nepi/resources/ns3/ns3wrapper.py index 0e95a2bd..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,20 @@ class NS3Wrapper(object): @property def is_running(self): - return self._started and 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): + return self.ns3.Simulator.IsFinished() def make_uuid(self): return "uuid%s" % uuid.uuid4() @@ -195,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) @@ -212,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 @@ -229,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) @@ -245,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 @@ -260,20 +270,44 @@ 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 == "addStaticRoute": - ### DEBUG - self.debuger.dump_add_static_route(uuid, args) - ######## + 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 uuid.startswith(SINGLETON): obj = self._singleton(uuid) @@ -312,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() @@ -340,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 @@ -351,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() @@ -372,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 @@ -389,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() @@ -407,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") @@ -431,7 +457,6 @@ class NS3Wrapper(object): ### DEBUG self.logger.debug("SHUTDOWN") - ######## def _simulator_run(self, condition): # Run simulation @@ -550,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) @@ -572,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) @@ -613,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() @@ -626,3 +658,48 @@ class NS3Wrapper(object): return ifindex return ifindex + def _retrieve_object(self, uuid, typeid, search = False): + obj = self.get_object(uuid) + + type_id = self.ns3.TypeId() + tid = type_id.LookupByName(typeid) + nobj = obj.GetObject(tid) + + newuuid = None + if search: + # search object + for ouuid, oobj in self._objects.items(): + if nobj == oobj: + newuuid = ouuid + break + else: + newuuid = self.make_uuid() + self._objects[newuuid] = nobj + + 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 + +