def update(self, bss, iface): assert bss.ssid == self.ssid assert bss.bssid == self.bssid if self.frequency != bss.frequency: print "Frequency for bss %s, %s has changed from %i to %i MHz."%(mac_addr.pretty(bss.bssid), bss.ssid, self.frequency, bss.frequency) # FIXME self.frequency = bss.frequency self.by_iface[iface] = bss
class WirelessInterface(DhcpInterface): def __init__(self, iface, tableid): DhcpInterface.__init__(self, iface, tableid) self.wifi = pythonwifi.iwlibs.Wireless(iface) self.iwinfo = pythonwifi.iwlibs.WirelessInfo(iface) self.radio_sm = radio_sm.radio_sm(iface) self.ping_monitor = ping_tester.PingMonitor(self) self.had_exception_last_time = False def _update_specialized(self): has_link = self.status > IFSTATE.LINK_ADDR had_exception_this_time = False try: self.essid = self.wifi.getEssid() self.diags.append(('ESSID', self.essid)) except Exception, e: if has_link: had_exception_this_time = True if self.had_exception_last_time: traceback.print_exc(10) print self.diags.append(('ESSID', 'Error collecting data.')) self.essid = "###ERROR-COLLECTING-DATA###" try: self.bssid = mac_addr.pretty(self.wifi.getAPaddr()) self.diags.append(('BSSID', self.bssid)) except Exception, e: if has_link: had_exception_this_time = True if self.had_exception_last_time: traceback.print_exc(10) print self.bssid = "00:00:00:00:00:00" self.diags.append(('BSSID', 'Error collecting data.'))
def _log_associations(self, iface, old_state, new_state): if new_state: print >> radio_manager_decisions, "--> Associated to %s on %s."%(mac_addr.pretty(new_state.bssid), iface.iface) elif new_state == radio.Associating: print >> radio_manager_decisions, "--> Associating on %s."%iface.iface elif new_state == radio.Unassociated: print >> radio_manager_decisions, "--> Unassociated on %s."%iface.iface else: print >> radio_manager_decisions, "--> ERROR!! Unknown association state %s on %s."%(new_state, iface.iface)
def update(self, bss, iface): assert bss.ssid == self.ssid assert bss.bssid == self.bssid if self.frequency != bss.frequency: print "Frequency for bss %s, %s has changed from %i to %i MHz." % ( mac_addr.pretty(bss.bssid), bss.ssid, self.frequency, bss.frequency, ) # FIXME self.frequency = bss.frequency self.by_iface[iface] = bss
def _log_associations(self, iface, old_state, new_state): if new_state: print >> radio_manager_decisions, "--> Associated to %s on %s." % ( mac_addr.pretty(new_state.bssid), iface.iface, ) elif new_state == radio.Associating: print >> radio_manager_decisions, "--> Associating on %s." % iface.iface elif new_state == radio.Unassociated: print >> radio_manager_decisions, "--> Unassociated on %s." % iface.iface else: print >> radio_manager_decisions, "--> ERROR!! Unknown association state %s on %s." % ( new_state, iface.iface, )
def _check_cur_bss(self, iface): """Makes sure that the current bss satisfies forcing constraints.""" #print "_check_cur_bss" cur_bss = iface.radio_sm.associated.get() if not cur_bss: return if not self.check_bss_matches_forcing(cur_bss): print iface.iface, "associated to", cur_bss.ssid, mac_addr.pretty(cur_bss.bssid), cur_bss.frequency print "but want", self.forced_ssid, self.forced_ssid, self.forced_band print "Unassociating because bss does not match requirements." iface.radio_sm.unassociate() return if not self.check_iface_matches_forcing(iface): print "Unassociating %s because interface forced to %s"%(iface, self.forced_iface) iface.radio_sm.unassociate() return
def _check_cur_bss(self, iface): """Makes sure that the current bss satisfies forcing constraints.""" # print "_check_cur_bss" cur_bss = iface.radio_sm.associated.get() if not cur_bss: return if not self.check_bss_matches_forcing(cur_bss): print iface.iface, "associated to", cur_bss.ssid, mac_addr.pretty(cur_bss.bssid), cur_bss.frequency print "but want", self.forced_ssid, self.forced_ssid, self.forced_band print "Unassociating because bss does not match requirements." iface.radio_sm.unassociate() return if not self.check_iface_matches_forcing(iface): print "Unassociating %s because interface forced to %s" % (iface, self.forced_iface) iface.radio_sm.unassociate() return
def update(self, bsses, iface): for bss in bsses: id = (bss.ssid, bss.bssid) if id not in self.bsses: self.bsses[id] = Bss(bss) self.bsses[id].update(bss, iface) self.freq_list.hit(bss.frequency, bss.stamp.to_sec()) if True: # Gives an overview of currently known bsses. all = self.bsses.items() all.sort(key=lambda (x, y): (y.frequency, x)) now = time.time() print >> known_bsses_log, "\033[2J\033[0;0H" print >> known_bsses_log, "Known BSSes bsses:" for _, bss in all: print >> known_bsses_log, mac_addr.pretty(bss.bssid), "%20.20s" % bss.ssid, bss.frequency, ifaces = bss.by_iface.keys() ifaces.sort() min_stamp = now - max(bss.by_iface.itervalues(), key=lambda bss: bss.stamp).stamp.to_sec() max_level = max(bss.by_iface.itervalues(), key=lambda bss: bss.level).level print >> known_bsses_log, "%5.1f/%3i" % (min_stamp, max_level), for iface in ifaces: print >> known_bsses_log, iface.iface, "%5.1f/%3i" % ( now - bss.by_iface[iface].stamp.to_sec(), bss.by_iface[iface].level, ), print >> known_bsses_log print >> known_bsses_log fl = self.freq_list.frequencies.keys() fl.sort() for f in fl: fc = self.freq_list.frequencies[f] if fc.last_hit: print >> known_bsses_log, f, "%5.1f" % (now - fc.last_hit), else: print >> known_bsses_log, f, "never", print >> known_bsses_log, "%5.1f" % (fc.next_scan_time - now), for iface in fc.next_scan_time_by_iface: print >> known_bsses_log, "%s %5.1f" % (iface.iface, now - fc.next_scan_time_by_iface[iface]), print >> known_bsses_log print >> known_bsses_log
def update(self, bsses, iface): for bss in bsses: id = (bss.ssid, bss.bssid) if id not in self.bsses: self.bsses[id] = Bss(bss) self.bsses[id].update(bss, iface) self.freq_list.hit(bss.frequency, bss.stamp.to_sec()) if True: # Gives an overview of currently known bsses. all = self.bsses.items() all.sort(key=lambda (x,y):(y.frequency, x)) now = time.time() print >> known_bsses_log, "\033[2J\033[0;0H" print >> known_bsses_log, "Known BSSes bsses:" for _, bss in all: print >> known_bsses_log, mac_addr.pretty(bss.bssid), "%20.20s"%bss.ssid, bss.frequency, ifaces = bss.by_iface.keys() ifaces.sort() min_stamp = now - max(bss.by_iface.itervalues(), key = lambda bss: bss.stamp).stamp.to_sec() max_level = max(bss.by_iface.itervalues(), key = lambda bss: bss.level).level print >> known_bsses_log, "%5.1f/%3i"%(min_stamp,max_level), for iface in ifaces: print >> known_bsses_log, iface.iface, "%5.1f/%3i"%(now - bss.by_iface[iface].stamp.to_sec(), bss.by_iface[iface].level), print >> known_bsses_log print >> known_bsses_log fl = self.freq_list.frequencies.keys() fl.sort() for f in fl: fc = self.freq_list.frequencies[f] if fc.last_hit: print >> known_bsses_log, f, "%5.1f"%(now - fc.last_hit), else: print >> known_bsses_log, f, "never", print >> known_bsses_log, "%5.1f"%(fc.next_scan_time - now), for iface in fc.next_scan_time_by_iface: print >> known_bsses_log, "%s %5.1f"%(iface.iface, now - fc.next_scan_time_by_iface[iface]), print >> known_bsses_log print >> known_bsses_log
def update(self): """Called in the main update cycle after all the scores have been computed. Decides which interfaces should be activated.""" def iface_score(iface): """Used to decide what to activate and disactivate.""" return iface.prescore now = time.time() active = set() verified = set() for iface in self.interfaces: iface.active = iface.radio_sm.is_active.get() if iface.active: active.add(iface) if iface.ping_monitor.is_verified.get(): verified.add(iface) inactive_verified = verified - active # Only keep one active interface. if active: self.best_active = max(active, key = iface_score) else: self.best_active = None if len(active) > 1: for iface in active: if iface != self.best_active: iface.radio_sm.activate_request.set(False) print >> radio_manager_decisions, "XXX Disactivating %s because %s is active and better."%(iface.iface, self.best_active.iface) # Activate a verified interface if it is better than the current # active interface. if inactive_verified: #print >> radio_manager_decisions, "Active interface selection." #for iface in verified: # print >> radio_manager_decisions, iface.iface, iface_score(iface), iface in active best_inactive_verified = max(inactive_verified, key = iface_score) if not self.best_active or iface_score(best_inactive_verified) > iface_score(self.best_active) + self.activate_hysteresis: if not self.best_active: print >> radio_manager_decisions, "XXX Activating %s because no current best active."%best_inactive_verified.iface else: print >> radio_manager_decisions, "XXX Activating %s because it is better than %s."%(best_inactive_verified.iface, self.best_active.iface) best_inactive_verified.radio_sm.activate_request.set(True) # Keep a closer watch on the most relevant frequencies. #print self.scan_manager.bss_list.bsses #print [candidate_bsses] candidate_bsses = filter(self.check_bss_matches_forcing, self.scan_manager.bss_list.bsses.itervalues()) expiry_time = now - self.hot_bss_expiry_time candidate_bsses.sort(key = lambda bss: self.desirability(bss, expiry_time), reverse = True) #print [candidate_bsses] periods = dict((f, self.scan_manager.frequencies.scan_period_cold) for f in self.scan_manager.frequencies.frequencies) hot_frequencies = 0 print >> scan_periods_log, "\033[2J\033[0;0H" print >> scan_periods_log, "Candidate bsses:" for bss in candidate_bsses: print >> scan_periods_log, bss.ssid, mac_addr.pretty(bss.bssid), bss.frequency, self.desirability(bss, expiry_time), now - bss.last_seen() if hot_frequencies < self.max_hot_frequencies and periods[bss.frequency] != self.scan_period_hot: hot_frequencies += 1 p = self.scan_period_hot elif bss.last_seen(iface) > now - self.warm_bss_expiry_time: p = self.scan_period_warm periods[bss.frequency] = min(periods[bss.frequency], p) print >> scan_periods_log, "Frequencies" #for f in self.scan_manager.frequencies.frequencies: freqs = [ f for f in self.scan_manager.frequencies.frequencies if check_band(f, self.forced_band) ] freqs.sort() for f in freqs: print >> scan_periods_log, f, periods[f], self.scan_manager.frequencies.frequencies[f].next_scan_time - now self.scan_manager.frequencies.set_freq_period(f, periods[f])
def _new_scan_data(self): print "_new_scan_data" #print "\033[2J" #print "\033[0;0H" now = time.time() if now < self.initial_inhibit_end: print "inhibited" return for iface in self.interfaces: if not self.check_iface_matches_forcing(iface): continue cur_assoc = iface.radio_sm.associated.get() #print "OK to try reassociating?", iface.iface, iface.radio_sm.scanning_enabled.get(), cur_assoc if cur_assoc and iface == self.best_active: continue if iface.radio_sm.scanning_enabled.get() and cur_assoc != radio.Associating: # Pick the best bss for this interface. candidate_bsses = filter(self.check_bss_matches_forcing, self.scan_manager.bss_list.bsses.itervalues()) #print "Candidate bsses:", [mac_addr.pretty(bss.bssid) for bss in candidate_bsses] if candidate_bsses: expiry_time = now - self.bss_expiry_time best_bss = max(candidate_bsses, key = lambda bss: self.desirability(bss, expiry_time, iface)) if iface not in best_bss.by_iface or best_bss.by_iface[iface].stamp.to_sec() < expiry_time: print "Best bss is expired.", mac_addr.pretty(best_bss.bssid) best_bss = None else: print "No candidate bsses." best_bss = None if best_bss is None: print "No candidate bsses or expired." #print bool(candidate_bsses), [candidate_bsses] #print self.scan_manager.bss_list.bsses.values() continue best_desirability = self.desirability(best_bss, expiry_time, iface) print "Best bss:", mac_addr.pretty(best_bss.bssid), best_desirability if cur_assoc: # Are we already associated to the best AP? if make_id(cur_assoc) == best_bss.id: print "Already associated to best bss." continue # Compute desirability for current association. cur_id = make_id(cur_assoc) if cur_id in self.scan_manager.bss_list.bsses: cur_bss = self.scan_manager.bss_list.bsses[make_id(cur_assoc)] cur_desirability = self.desirability(cur_bss, expiry_time, iface) else: cur_desirability = -1e1000 # Is the best ap better enough than the current best? if cur_desirability + self.reassociate_hysteresis > best_desirability: print "Best bss not over hysteresis threshold: %s %f > %s %f"%(mac_addr.pretty(cur_assoc.bssid), cur_desirability, mac_addr.pretty(best_bss.bssid), self.desirability(best_bss)) continue # Let's associate print >> radio_manager_decisions, "Associating to %s (%f) on %s"%(mac_addr.pretty(best_bss.bssid), best_desirability, iface.iface), if cur_assoc: print >> radio_manager_decisions, "from %s (%f)"%(mac_addr.pretty(cur_assoc.bssid), cur_desirability) else: print >> radio_manager_decisions, "from unassociated" iface.radio_sm.associate_request.trigger(best_bss.id) self.iface_associations[iface] = best_bss.id
def update(self): """Called in the main update cycle after all the scores have been computed. Decides which interfaces should be activated.""" def iface_score(iface): """Used to decide what to activate and disactivate.""" return iface.prescore now = time.time() active = set() verified = set() for iface in self.interfaces: iface.active = iface.radio_sm.is_active.get() if iface.active: active.add(iface) if iface.ping_monitor.is_verified.get(): verified.add(iface) inactive_verified = verified - active # Only keep one active interface. if active: self.best_active = max(active, key=iface_score) else: self.best_active = None if len(active) > 1: for iface in active: if iface != self.best_active: iface.radio_sm.activate_request.set(False) print >> radio_manager_decisions, "XXX Disactivating %s because %s is active and better." % ( iface.iface, self.best_active.iface, ) # Activate a verified interface if it is better than the current # active interface. if inactive_verified: # print >> radio_manager_decisions, "Active interface selection." # for iface in verified: # print >> radio_manager_decisions, iface.iface, iface_score(iface), iface in active best_inactive_verified = max(inactive_verified, key=iface_score) if ( not self.best_active or iface_score(best_inactive_verified) > iface_score(self.best_active) + self.activate_hysteresis ): if not self.best_active: print >> radio_manager_decisions, "XXX Activating %s because no current best active." % best_inactive_verified.iface else: print >> radio_manager_decisions, "XXX Activating %s because it is better than %s." % ( best_inactive_verified.iface, self.best_active.iface, ) best_inactive_verified.radio_sm.activate_request.set(True) # Keep a closer watch on the most relevant frequencies. # print self.scan_manager.bss_list.bsses # print [candidate_bsses] candidate_bsses = filter(self.check_bss_matches_forcing, self.scan_manager.bss_list.bsses.itervalues()) expiry_time = now - self.hot_bss_expiry_time candidate_bsses.sort(key=lambda bss: self.desirability(bss, expiry_time), reverse=True) # print [candidate_bsses] periods = dict( (f, self.scan_manager.frequencies.scan_period_cold) for f in self.scan_manager.frequencies.frequencies ) hot_frequencies = 0 print >> scan_periods_log, "\033[2J\033[0;0H" print >> scan_periods_log, "Candidate bsses:" for bss in candidate_bsses: print >> scan_periods_log, bss.ssid, mac_addr.pretty(bss.bssid), bss.frequency, self.desirability( bss, expiry_time ), now - bss.last_seen() if hot_frequencies < self.max_hot_frequencies and periods[bss.frequency] != self.scan_period_hot: hot_frequencies += 1 p = self.scan_period_hot elif bss.last_seen(iface) > now - self.warm_bss_expiry_time: p = self.scan_period_warm periods[bss.frequency] = min(periods[bss.frequency], p) print >> scan_periods_log, "Frequencies" # for f in self.scan_manager.frequencies.frequencies: freqs = [f for f in self.scan_manager.frequencies.frequencies if check_band(f, self.forced_band)] freqs.sort() for f in freqs: print >> scan_periods_log, f, periods[f], self.scan_manager.frequencies.frequencies[f].next_scan_time - now self.scan_manager.frequencies.set_freq_period(f, periods[f])
def _new_scan_data(self): print "_new_scan_data" # print "\033[2J" # print "\033[0;0H" now = time.time() if now < self.initial_inhibit_end: print "inhibited" return for iface in self.interfaces: if not self.check_iface_matches_forcing(iface): continue cur_assoc = iface.radio_sm.associated.get() # print "OK to try reassociating?", iface.iface, iface.radio_sm.scanning_enabled.get(), cur_assoc if cur_assoc and iface == self.best_active: continue if iface.radio_sm.scanning_enabled.get() and cur_assoc != radio.Associating: # Pick the best bss for this interface. candidate_bsses = filter(self.check_bss_matches_forcing, self.scan_manager.bss_list.bsses.itervalues()) # print "Candidate bsses:", [mac_addr.pretty(bss.bssid) for bss in candidate_bsses] if candidate_bsses: expiry_time = now - self.bss_expiry_time best_bss = max(candidate_bsses, key=lambda bss: self.desirability(bss, expiry_time, iface)) if iface not in best_bss.by_iface or best_bss.by_iface[iface].stamp.to_sec() < expiry_time: print "Best bss is expired.", mac_addr.pretty(best_bss.bssid) best_bss = None else: print "No candidate bsses." best_bss = None if best_bss is None: print "No candidate bsses or expired." # print bool(candidate_bsses), [candidate_bsses] # print self.scan_manager.bss_list.bsses.values() continue best_desirability = self.desirability(best_bss, expiry_time, iface) print "Best bss:", mac_addr.pretty(best_bss.bssid), best_desirability if cur_assoc: # Are we already associated to the best AP? if make_id(cur_assoc) == best_bss.id: print "Already associated to best bss." continue # Compute desirability for current association. cur_id = make_id(cur_assoc) if cur_id in self.scan_manager.bss_list.bsses: cur_bss = self.scan_manager.bss_list.bsses[make_id(cur_assoc)] cur_desirability = self.desirability(cur_bss, expiry_time, iface) else: cur_desirability = -1e1000 # Is the best ap better enough than the current best? if cur_desirability + self.reassociate_hysteresis > best_desirability: print "Best bss not over hysteresis threshold: %s %f > %s %f" % ( mac_addr.pretty(cur_assoc.bssid), cur_desirability, mac_addr.pretty(best_bss.bssid), self.desirability(best_bss), ) continue # Let's associate print >> radio_manager_decisions, "Associating to %s (%f) on %s" % ( mac_addr.pretty(best_bss.bssid), best_desirability, iface.iface, ), if cur_assoc: print >> radio_manager_decisions, "from %s (%f)" % ( mac_addr.pretty(cur_assoc.bssid), cur_desirability, ) else: print >> radio_manager_decisions, "from unassociated" iface.radio_sm.associate_request.trigger(best_bss.id) self.iface_associations[iface] = best_bss.id