Merge branch 'bug_747_cancel_waiting_tasks'
[enigma2.git] / lib / python / Plugins / SystemPlugins / WirelessLan / Wlan.py
1 from Components.config import config, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
2 from Components.Console import Console
3 from Components.Network import iNetwork
4
5 from os import system, path as os_path
6 from string import maketrans, strip
7 import sys
8 import types
9 from re import compile as re_compile, search as re_search, escape as re_escape
10 from pythonwifi.iwlibs import getNICnames, Wireless, Iwfreq, getWNICnames
11 from pythonwifi import flags as wififlags
12
13 list = []
14 list.append("Unencrypted")
15 list.append("WEP")
16 list.append("WPA")
17 list.append("WPA/WPA2")
18 list.append("WPA2")
19
20 weplist = []
21 weplist.append("ASCII")
22 weplist.append("HEX")
23
24 config.plugins.wlan = ConfigSubsection()
25 config.plugins.wlan.essid = NoSave(ConfigText(default = "", fixed_size = False))
26 config.plugins.wlan.hiddenessid = NoSave(ConfigYesNo(default = False))
27 config.plugins.wlan.encryption = NoSave(ConfigSelection(list, default = "WPA2"))
28 config.plugins.wlan.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII"))
29 config.plugins.wlan.psk = NoSave(ConfigPassword(default = "", fixed_size = False))
30
31
32 def getWlanConfigName(iface):
33         return '/etc/wpa_supplicant.' + iface + '.conf'
34
35 class Wlan:
36         def __init__(self, iface = None):
37                 self.iface = iface
38                 self.oldInterfaceState = None
39                 
40                 a = ''; b = ''
41                 for i in range(0, 255):
42                         a = a + chr(i)
43                         if i < 32 or i > 127:
44                                 b = b + ' '
45                         else:
46                                 b = b + chr(i)
47                 
48                 self.asciitrans = maketrans(a, b)
49
50         def asciify(self, str):
51                 return str.translate(self.asciitrans)
52         
53         def getWirelessInterfaces(self):
54                 return getWNICnames()
55
56         def setInterface(self, iface = None):
57                 self.iface = iface
58
59         def getInterface(self):
60                 return self.iface
61
62         def getNetworkList(self):
63                 if self.oldInterfaceState is None:
64                         self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up")
65                 if self.oldInterfaceState is False:
66                         if iNetwork.getAdapterAttribute(self.iface, "up") is False:
67                                 iNetwork.setAdapterAttribute(self.iface, "up", True)
68                                 system("ifconfig "+self.iface+" up")
69
70                 ifobj = Wireless(self.iface) # a Wireless NIC Object
71
72                 try:
73                         scanresults = ifobj.scan()
74                 except:
75                         scanresults = None
76                         print "[Wlan.py] No wireless networks could be found"
77                 aps = {}
78                 if scanresults is not None:
79                         (num_channels, frequencies) = ifobj.getChannelInfo()
80                         index = 1
81                         for result in scanresults:
82                                 bssid = result.bssid
83
84                                 if result.encode.flags & wififlags.IW_ENCODE_DISABLED > 0:
85                                         encryption = False
86                                 elif result.encode.flags & wififlags.IW_ENCODE_NOKEY > 0:
87                                         encryption = True
88                                 else:
89                                         encryption = None
90                                 
91                                 signal = str(result.quality.siglevel-0x100) + " dBm"
92                                 quality = "%s/%s" % (result.quality.quality,ifobj.getQualityMax().quality)
93                                 
94                                 extra = []
95                                 for element in result.custom:
96                                         element = element.encode()
97                                         extra.append( strip(self.asciify(element)) )
98                                 for element in extra:
99                                         if 'SignalStrength' in element:
100                                                 signal = element[element.index('SignalStrength')+15:element.index(',L')]                                        
101                                         if 'LinkQuality' in element:
102                                                 quality = element[element.index('LinkQuality')+12:len(element)]                         
103
104                                 aps[bssid] = {
105                                         'active' : True,
106                                         'bssid': result.bssid,
107                                         'channel': frequencies.index(ifobj._formatFrequency(result.frequency.getFrequency())) + 1,
108                                         'encrypted': encryption,
109                                         'essid': strip(self.asciify(result.essid)),
110                                         'iface': self.iface,
111                                         'maxrate' : ifobj._formatBitrate(result.rate[-1][-1]),
112                                         'noise' : '',#result.quality.nlevel-0x100,
113                                         'quality' : str(quality),
114                                         'signal' : str(signal),
115                                         'custom' : extra,
116                                 }
117
118                                 index = index + 1
119                 return aps
120                 
121         def stopGetNetworkList(self):
122                 if self.oldInterfaceState is not None:
123                         if self.oldInterfaceState is False:
124                                 iNetwork.setAdapterAttribute(self.iface, "up", False)
125                                 system("ifconfig "+self.iface+" down")
126                                 self.oldInterfaceState = None
127                                 self.iface = None
128
129 iWlan = Wlan()
130
131 class wpaSupplicant:
132         def __init__(self):
133                 pass
134                 
135         def writeConfig(self, iface):
136                 essid = config.plugins.wlan.essid.value
137                 hiddenessid = config.plugins.wlan.hiddenessid.value
138                 encryption = config.plugins.wlan.encryption.value
139                 wepkeytype = config.plugins.wlan.wepkeytype.value
140                 psk = config.plugins.wlan.psk.value
141                 fp = file(getWlanConfigName(iface), 'w')
142                 fp.write('#WPA Supplicant Configuration by enigma2\n')
143                 fp.write('ctrl_interface=/var/run/wpa_supplicant\n')
144                 fp.write('eapol_version=1\n')
145                 fp.write('fast_reauth=1\n')     
146
147                 if hiddenessid:
148                         fp.write('ap_scan=2\n')
149                 else:
150                         fp.write('ap_scan=1\n')
151                 fp.write('network={\n')
152                 fp.write('\tssid="'+essid+'"\n')
153                 fp.write('\tscan_ssid=0\n')                     
154                 if encryption in ('WPA', 'WPA2', 'WPA/WPA2'):
155                         fp.write('\tkey_mgmt=WPA-PSK\n')
156                         if encryption == 'WPA':
157                                 fp.write('\tproto=WPA\n')
158                                 fp.write('\tpairwise=TKIP\n')
159                                 fp.write('\tgroup=TKIP\n')
160                         elif encryption == 'WPA2':
161                                 fp.write('\tproto=RSN\n')
162                                 fp.write('\tpairwise=CCMP\n')
163                                 fp.write('\tgroup=CCMP\n')
164                         else:
165                                 fp.write('\tproto=WPA RSN\n')
166                                 fp.write('\tpairwise=CCMP TKIP\n')
167                                 fp.write('\tgroup=CCMP TKIP\n')
168                         fp.write('\tpsk="'+psk+'"\n')
169                 elif encryption == 'WEP':
170                         fp.write('\tkey_mgmt=NONE\n')
171                         if wepkeytype == 'ASCII':
172                                 fp.write('\twep_key0="'+psk+'"\n')
173                         else:
174                                 fp.write('\twep_key0='+psk+'\n')
175                 else:
176                         fp.write('\tkey_mgmt=NONE\n')
177                 fp.write('}')
178                 fp.write('\n')
179                 fp.close()
180                 #system('cat ' + getWlanConfigName(iface))
181                 
182         def loadConfig(self,iface):
183                 configfile = getWlanConfigName(iface)
184                 if not os_path.exists(configfile):
185                         configfile = '/etc/wpa_supplicant.conf'
186                 try:
187                         #parse the wpasupplicant configfile
188                         print "[Wlan.py] parsing configfile: ",configfile
189                         fp = file(configfile, 'r')
190                         supplicant = fp.readlines()
191                         fp.close()
192                         essid = None
193                         encryption = "Unencrypted"
194
195                         for s in supplicant:
196                                 split = s.strip().split('=',1)
197                                 if split[0] == 'ap_scan':
198                                         if split[1] == '2':
199                                                 config.plugins.wlan.hiddenessid.value = True
200                                         else:
201                                                 config.plugins.wlan.hiddenessid.value = False
202
203                                 elif split[0] == 'ssid':
204                                         essid = split[1][1:-1]
205                                         config.plugins.wlan.essid.value = essid
206
207                                 elif split[0] == 'proto':
208                                         if split[1] == 'WPA' :
209                                                 mode = 'WPA'
210                                         if split[1] == 'RSN':
211                                                 mode = 'WPA2'
212                                         if split[1] in ('WPA RSN', 'WPA WPA2'):
213                                                 mode = 'WPA/WPA2'
214                                         encryption = mode
215                                         
216                                 elif split[0] == 'wep_key0':
217                                         encryption = 'WEP'
218                                         if split[1].startswith('"') and split[1].endswith('"'):
219                                                 config.plugins.wlan.wepkeytype.value = 'ASCII'
220                                                 config.plugins.wlan.psk.value = split[1][1:-1]
221                                         else:
222                                                 config.plugins.wlan.wepkeytype.value = 'HEX'
223                                                 config.plugins.wlan.psk.value = split[1]                                                
224                                         
225                                 elif split[0] == 'psk':
226                                         config.plugins.wlan.psk.value = split[1][1:-1]
227                                 else:
228                                         pass
229
230                         config.plugins.wlan.encryption.value = encryption
231                                 
232                         wsconfig = {
233                                         'hiddenessid': config.plugins.wlan.hiddenessid.value,
234                                         'ssid': config.plugins.wlan.essid.value,
235                                         'encryption': config.plugins.wlan.encryption.value,
236                                         'wepkeytype': config.plugins.wlan.wepkeytype.value,
237                                         'key': config.plugins.wlan.psk.value,
238                                 }
239                 
240                         for (key, item) in wsconfig.items():
241                                 if item is "None" or item is "":
242                                         if key == 'hiddenessid':
243                                                 wsconfig['hiddenessid'] = False
244                                         if key == 'ssid':
245                                                 wsconfig['ssid'] = ""
246                                         if key == 'encryption':
247                                                 wsconfig['encryption'] = "WPA2"                 
248                                         if key == 'wepkeytype':
249                                                 wsconfig['wepkeytype'] = "ASCII"
250                                         if key == 'key':
251                                                 wsconfig['key'] = ""
252                 except:
253                         print "[Wlan.py] Error parsing ",configfile
254                         wsconfig = {
255                                         'hiddenessid': False,
256                                         'ssid': "",
257                                         'encryption': "WPA2",
258                                         'wepkeytype': "ASCII",
259                                         'key': "",
260                                 }
261                 #print "[Wlan.py] WS-CONFIG-->",wsconfig
262                 return wsconfig
263
264
265 class Status:
266         def __init__(self):
267                 self.wlaniface = {}
268                 self.backupwlaniface = {}
269                 self.statusCallback = None
270                 self.WlanConsole = Console()
271
272         def stopWlanConsole(self):
273                 if self.WlanConsole is not None:
274                         print "[iStatus] killing self.WlanConsole"
275                         self.WlanConsole.killAll()
276                         self.WlanConsole = None
277                         
278         def getDataForInterface(self, iface, callback = None):
279                 self.WlanConsole = Console()
280                 cmd = "iwconfig " + iface
281                 if callback is not None:
282                         self.statusCallback = callback
283                 self.WlanConsole.ePopen(cmd, self.iwconfigFinished, iface)
284
285         def iwconfigFinished(self, result, retval, extra_args):
286                 iface = extra_args
287                 data = { 'essid': False, 'frequency': False, 'accesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
288                 for line in result.splitlines():
289                         line = line.strip()
290                         if "ESSID" in line:
291                                 if "off/any" in line:
292                                         ssid = "off"
293                                 else:
294                                         if "Nickname" in line:
295                                                 ssid=(line[line.index('ESSID')+7:line.index('"  Nickname')])
296                                         else:
297                                                 ssid=(line[line.index('ESSID')+7:len(line)-1])
298                                 if ssid is not None:
299                                         data['essid'] = ssid
300                         if "Frequency" in line:
301                                 frequency = line[line.index('Frequency')+10 :line.index(' GHz')]
302                                 if frequency is not None:
303                                         data['frequency'] = frequency
304                         if "Access Point" in line:
305                                 if "Sensitivity" in line:
306                                         ap=line[line.index('Access Point')+14:line.index('   Sensitivity')]
307                                 else:
308                                         ap=line[line.index('Access Point')+14:len(line)]
309                                 if ap is not None:
310                                         data['accesspoint'] = ap
311                         if "Bit Rate" in line:
312                                 if "kb" in line:
313                                         br = line[line.index('Bit Rate')+9 :line.index(' kb/s')]
314                                 else:
315                                         br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')]
316                                 if br is not None:
317                                         data['bitrate'] = br
318                         if "Encryption key" in line:
319                                 if ":off" in line:
320                                         enc = "off"
321                                 elif "Security" in line:
322                                         enc = line[line.index('Encryption key')+15 :line.index('   Security')]
323                                         if enc is not None:
324                                                 enc = "on"
325                                 else:
326                                         enc = line[line.index('Encryption key')+15 :len(line)]
327                                         if enc is not None:
328                                                 enc = "on"
329                                 if enc is not None:
330                                         data['encryption'] = enc
331                         if 'Quality' in line:
332                                 if "/100" in line:
333                                         qual = line[line.index('Quality')+8:line.index('  Signal')]
334                                 else:
335                                         qual = line[line.index('Quality')+8:line.index('Sig')]
336                                 if qual is not None:
337                                         data['quality'] = qual
338                         if 'Signal level' in line:
339                                 if "dBm" in line:
340                                         signal = line[line.index('Signal level')+13 :line.index(' dBm')] + " dBm"
341                                 elif "/100" in line:
342                                         if "Noise" in line:
343                                                 signal = line[line.index('Signal level')+13:line.index('  Noise')]
344                                         else:
345                                                 signal = line[line.index('Signal level')+13:len(line)]
346                                 else:
347                                         if "Noise" in line:
348                                                 signal = line[line.index('Signal level')+13:line.index('  Noise')]
349                                         else:
350                                                 signal = line[line.index('Signal level')+13:len(line)]                                          
351                                 if signal is not None:
352                                         data['signal'] = signal
353
354                 self.wlaniface[iface] = data
355                 self.backupwlaniface = self.wlaniface
356                 
357                 if self.WlanConsole is not None:
358                         if len(self.WlanConsole.appContainers) == 0:
359                                 print "[Wlan.py] self.wlaniface after loading:", self.wlaniface
360                                 if self.statusCallback is not None:
361                                                 self.statusCallback(True,self.wlaniface)
362                                                 self.statusCallback = None
363
364         def getAdapterAttribute(self, iface, attribute):
365                 self.iface = iface
366                 if self.wlaniface.has_key(self.iface):
367                         if self.wlaniface[self.iface].has_key(attribute):
368                                 return self.wlaniface[self.iface][attribute]
369                 return None
370         
371 iStatus = Status()