Tuesday, December 7, 2010
Tuesday, October 13, 2009
Trivial wireless AP selector
(K)ubuntu's NetworkManager is not good enough when the APs are half-broken (e.g., don't associate, don't give DHCP leases or don't route). Too often it simply stops responding, when the user clearly sees that the network is not working.
Manual (open) wireless network configuration is simple:
iwconfig (iface) essid (essid) ap (mac)
dhclient (iface)
... except that you need to parse `iwlist (iface) scan ` for the relevant data identifying the AP. This quickly becomes tedious when there are n-teen cells in the scan results and most of them are broken.
Here is a really shoddy script that replaces NetworkManager with a trivial interactive loop to attempt to connect to one of the detected AP.
Manual (open) wireless network configuration is simple:
iwconfig (iface)
dhclient (iface)
... except that you need to parse `iwlist (iface)
Here is a really shoddy script that replaces NetworkManager with a trivial interactive loop to attempt to connect to one of the detected AP.
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
szym / Oct 2009
NetworkManager is not good enough when the APs are half-broken
(e.g., don't associate, don't give DHCP leases or don't route).
This is a really shoddy script that replaces NetworkManager.
"""
from os import popen, system
class WifiSelector:
def __init__(self, iface):
# test iface first
if(system("ls /sys/class/net/%s/wireless >/dev/null" % iface) != 0):
raise Exception("%s is not wireless" % iface)
self.iface = iface
self.aps = []
def scan(self):
""" iwlist <iface> scan
parse output and store in aps
"""
aps = []
cur = None
for l in popen("iwlist %s scan" % self.iface):
l = l.strip()
if (not l):
continue
if (l.startswith('Cell')):
if (cur != None):
aps.append(cur)
keys = [ 'essid','mode','chan','key','q','sig','noise','last' ]
cur = dict([(x, '???') for x in keys])
cur['ap'] = l.split()[4]
if (cur == None):
continue
if (l.startswith('ESSID')):
cur['essid'] = l.split(':')[1]
if (l.startswith('Mode')):
cur['mode'] = l.split(':')[1]
if (l.startswith('Channel')):
cur['chan'] = int(l.split(':')[1])
if (l.startswith('Encryption')):
cur['key'] = l.split(':')[1]
if (l.startswith('Quality')):
# Quality=15/100 Signal level:-84 dBm Noise level=-90 dBm
ls = l.replace(':', ' ').replace('/', ' ').replace('=', ' ').split()
cur['q'] = int(ls[1])
cur['sig'] = int(ls[5])
#cur['noise'] = int(ls[9])
if (l.startswith('Extra: Last beacon:')):
#Extra: Last beacon: 1888ms ago
cur['last'] = int(l.split()[3][:-2])
self.aps = aps
def show(self):
""" pretty print aps
"""
for i, ap in enumerate(self.aps):
print i, "%(mode)-6s %(key)-3s %(q)2d %(essid)-30s %(chan)4s %(ap)s %(last)5d" % ap
def sortq(self):
""" sort aps by quality
"""
self.aps.sort(key=lambda d: d['q'], reverse=True)
def refresh(self):
self.scan()
self.sortq()
self.show()
def select(self, i):
""" attempt to associate with aps[i]
"""
ap = self.aps[i]
system("iwconfig wlan0 essid %(essid)s ap %(ap)s" % ap)
system("dhclient %s" % self.iface)
def kill_nm(self):
if (system("/etc/init.d/network-manager status") == 0):
system("/etc/init.d/network-manager stop")
system("ifconfig %s up" % self.iface)
def main(args):
from sys import stderr
if (len(args) > 1 and args[1] == '-h'):
print >> stderr, "Usage: %s <iface>" % args[0]
return -1
if len(args) < 2:
iface = 'wlan0'
else:
iface = args[1]
ws = WifiSelector(iface)
ws.kill_nm()
ws.refresh()
while(True):
try:
which = int(raw_input('select (<0 refresh): '))
except:
break
if (which >= 0 and which < len(ws.aps)):
ws.select(which)
else:
ws.refresh()
if (__name__ == '__main__'):
from sys import argv
main(argv)
Subscribe to:
Posts (Atom)