$search
00001 #! /usr/bin/env python 00002 00003 import roslib; roslib.load_manifest('multi_interface_roam') 00004 from state_publisher import StatePublisher, CompositeStatePublisher 00005 from event import Event 00006 import network_monitor_udp.udpmoncli as udpmoncli 00007 from netlink_monitor import IFSTATE, netlink_monitor 00008 from twisted.internet import reactor 00009 import config 00010 import time 00011 00012 class PingTester: 00013 def __init__(self, iface, rate, pingtarget, state_pub): 00014 self.update_event = Event() 00015 reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown) 00016 self.udp_monitor = udpmoncli.MonitorClient([config.get_parameter('ping_max_latency', 0.2)], pingtarget, rate, 32, True) 00017 CompositeStatePublisher(lambda (addr, ready): None if not ready else addr, [ 00018 netlink_monitor.get_state_publisher(iface, IFSTATE.ADDR), 00019 state_pub, 00020 ]).subscribe(self._addr_cb) 00021 00022 def update(self, update_rate): 00023 result = self.udp_monitor.get_smart_bins(update_rate) 00024 self.update_event.trigger(result) 00025 self.state = result 00026 return result 00027 00028 def _addr_cb(self, old_state, new_state): 00029 if new_state: 00030 # FIXME This should only happen after routes are set up. 00031 #print "New address", new_state 00032 self.udp_monitor.start_monitor((new_state[0], 0)) 00033 print "Starting monitor on %s"%new_state[0] 00034 else: 00035 self.udp_monitor.stop_monitor() 00036 self.state = None 00037 self.update_event.trigger(None) 00038 00039 def _shutdown(self): 00040 try: 00041 self.udp_monitor.shutdown() 00042 except: 00043 import sys 00044 sys.print_exc() 00045 00046 class PingMonitor: 00047 def __init__(self, iface): 00048 self.iface = iface 00049 self.ping_timeout = config.get_parameter('ping_timeout', 4) 00050 self.is_verified = StatePublisher(False) 00051 self.has_address = False 00052 iface.ping_tester.update_event.subscribe_repeating(self._update) 00053 netlink_monitor.get_state_publisher(iface.iface, IFSTATE.ADDR).subscribe(self._has_address_cb, iface) 00054 00055 def _update(self, status): 00056 #print "PingMonitor._update" 00057 if status: 00058 (bins, latency1, latency2) = status 00059 #print "PingMonitor", bins, self.restart_time - time.time() 00060 if status and bins[0]: 00061 self.restart_time = time.time() + self.ping_timeout 00062 self.is_verified.set(True) 00063 elif self.has_address and self.restart_time < time.time(): 00064 if not config.get_parameter('disable_ping_timeout'): 00065 print "PingMonitor restarting", self.iface.iface 00066 self.has_address = False 00067 self.iface.interface_upper.restart() 00068 else: 00069 print "PingMonitor restart was disabled by disable_ping_timeout", self.iface.iface 00070 self._set_timeout() 00071 00072 def _has_address_cb(self, iface, old_state, new_state): 00073 self.is_verified.set(False) 00074 self.has_address = bool(new_state) 00075 if new_state: 00076 self._set_timeout() 00077 else: 00078 self.restart_time = 1e1000 00079 00080 def _set_timeout(self): 00081 self.restart_time = time.time() + self.ping_timeout