fix bitrate and quality
[dumbwifi.git] / network.py
blob3cce8d5ddb151c12a5087e89999b846704488596
1 #!/usr/bin/env python
3 # Author: Martin Matusiak <numerodix@gmail.com>
4 # Licensed under the GNU Public License, version 3.
6 import re
7 import time
9 from conf import config
10 import opts
11 import procs
12 import regex
13 from sdict import sdict
14 import ui
17 # Interface status
19 def read_iface(iface_name):
20 fields = sdict(); info = sdict()
21 fields.ip = "inet addr:([0-9.]+)"
22 fields.up = "(UP)"
23 output = procs.run("%s %s" % (config.ifconfig, iface_name))
24 for key in fields.keys():
25 info[key] = regex.find1(fields[key], output)
26 return info
28 def has_ip(iface_name):
29 invalid_range = "169.254."
30 info = read_iface(iface_name)
31 if info.up and info.ip and not regex.matches(invalid_range, info.ip):
32 return info.ip
34 def iface_up(iface_name, ip=None):
35 ip_str = ""
36 if ip: ip_str = "inet %s" % ip
37 info = read_iface(iface_name)
38 if not info.up:
39 procs.run("%s %s %s up" % (config.ifconfig, iface_name, ip_str))
41 def iface_down(iface_name):
42 info = read_iface(iface_name)
43 if info.up:
44 procs.run("%s %s inet 0.0.0.0 down" % (config.ifconfig, iface_name))
47 # DHCP
49 def request_ip(iface_name):
50 if config.dhcpcd:
51 procs.kill_by_name(config.dhcpcd)
52 procs.kill_by_name(config.dhclient)
54 for i in config.interfaces:
55 if i.interface != iface_name: iface_down(i.interface)
56 iface_up(iface_name)
58 if config.dhcpcd[0] == '/':
59 procs.run("%s -d -t5 %s" % (config.dhcpcd, iface_name))
60 else:
61 procs.run("%s %s 2>&1" % (config.dhclient, iface_name))
62 return has_ip(iface_name)
65 # Wired network
67 def wire_connected(iface_name):
68 iface_up(iface_name)
69 output = procs.run("%s %s" % (config.mii_tool, iface_name))
70 link = regex.matches("link ok", output)
71 if output and link: return iface_name
74 # Wireless network
76 wpa="""
77 IE: (?P<wpa_ver>.*%s.*)\s+
78 Group Cipher : (?P<group_cipher>[^\s]+)\s+
79 Pairwise Ciphers \(.\) : (?P<pairwise_ciphers>.+)\s+
80 Authentication Suites \(.\) : (?P<auth_suites>.+)\s*
81 (?P<preauth>Preauthentication Supported)*
82 """
83 wpa = regex.replaceall("\n", "", wpa)
84 wpa_subfields = ['wpa_ver', 'group_cipher', 'pairwise_ciphers', 'auth_suites', 'preauth']
86 def read_wifi(iface_name):
87 fields = sdict(); info = sdict()
88 fields.assoc = "(IEEE 802.11)"
89 fields.mode = "Mode:([^\s]+)"
90 fields.essid = "ESSID:\"(.*?)\""
91 fields.bssid = "Access Point: ([^\s]+)"
92 fields.key = "Encryption key:([^\s]+)"
93 output = procs.run("%s %s" % (config.iwconfig, iface_name))
94 for key in fields.keys():
95 info[key] = regex.find1(fields[key], output)
96 if info.mode: info.mode = info.mode.lower()
97 return info
99 def setup_wifi(iface_name, network=None):
100 extra = ""
101 if network:
102 extra += "ap %s " % network.bssid
103 extra += "essid \"%s\" " % network.essid
105 key = "s:%s" % network.key
106 if not network.key: key = "off"
107 extra += "key %s " % key
109 procs.run("%s %s mode managed %s" % (config.iwconfig, iface_name, extra))
111 if network:
112 deadline = time.time()+1.5
113 while deadline > time.time():
114 info = read_wifi(iface_name)
115 if info.assoc: return True
116 time.sleep(0.75)
117 return False
119 def normal_scan(iface_name):
120 output = ""
121 deadline = time.time()+3
122 while 1:
123 if time.time() > deadline: break
124 output += regex.replaceall("^.+\n" , "", single_scan(iface_name))
125 time.sleep(0.5)
126 return output
128 def single_scan(iface_name):
129 procs.kill_by_name(config.iwlist)
130 iface_up(iface_name)
131 setup_wifi(iface_name)
132 return procs.run("%s %s scan" % (config.iwlist, iface_name))
134 def read_scan(scan_data):
135 if not scan_data:
136 return config.live_networks
138 blocks = scan_data.split("Cell")[1:]
140 fields = sdict()
141 fields.bssid = "Address: ([^\s]*)"
142 fields.essid = "ESSID:\"(.*?)\""
143 fields.channel = "Channel:([^\s]*)"
144 fields.encrypted = "Encryption key:(on)"
145 fields.bitrate = "Bit Rates:(?:([0-9.]* [Mbs;/]*)*)"
146 fields.quality = "Quality=([0-9]+/[0-9]+)"
147 fields.signal = "Signal level=([^\s]* dBm)"
148 fields.noise = "Noise level=([^\s]* dBm)"
149 fields.beacon = "Last beacon: ([^\s]*ms)"
151 for block in blocks:
152 net = sdict()
153 for key in fields.keys():
154 s = regex.find1(fields[key], block)
155 if s and s.strip(): net[key] = s.strip()
157 # special handling for bitrate
158 bitrates = regex.findall(fields.bitrate, block)
159 if bitrates:
160 net.bitrate = bitrates[-1]
162 # extract wpa details
163 fields.wpa = wpa % "WPA Version"
164 fields.wpa2 = wpa % "WPA2 Version"
165 for field in ['wpa', 'wpa2']:
166 m = regex.find(fields[field], block)
167 if m:
168 wpa_info = sdict()
169 for subfield in wpa_subfields:
170 wpa_info[subfield] = m.group(subfield)
171 net[field] = wpa_info
173 # shorthand security value for display
174 if net.wpa and net.wpa2: net.sec = 'wpa/wpa2'
175 elif net.wpa: net.sec = 'wpa'
176 elif net.wpa2: net.sec = 'wpa2'
177 elif net.encrypted and net.encrypted == "on":
178 net.sec = 'wep'
180 config.live_networks = config.live_networks.merge1(net, 'bssid')
181 config.live_networks = opts.post_negate_nets(config.live_networks, 'essid')
182 return config.live_networks
185 if __name__ == "__main__":
186 pass
187 ui.init_config()
188 #print config.networks
189 #print has_ip("eth1")
190 #print wire_connected("eth0")
192 # print display_live_networks(read_scan(normal_scan("eth1")), field='sec')
194 # print display_live_networks(read_scan(None))
196 # curse("eth1",-1)
198 nets = read_scan(single_scan("wlan0"))
199 # nets = [n for n in nets if 'sec' not in n]
200 print ui.display_live_networks(nets, column=3)
202 #print request_ip("eth1")
203 #print read_iface("eth1")
204 #iface_up("eth1")
205 #iface_down("eth1")
206 #print read_wifi("eth1")