Merge branch 'bug_202_networkconfig_cleanup'
[enigma2.git] / lib / python / Plugins / SystemPlugins / WirelessLan / Wlan.py
1 #from enigma import eListboxPythonMultiContent, eListbox, gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER
2 #from Components.MultiContent import MultiContentEntryText
3 #from Components.GUIComponent import GUIComponent
4 #from Components.HTMLComponent import HTMLComponent
5 from Components.config import config, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
6 from Components.Console import Console
7
8 from os import system
9 from string import maketrans, strip
10 import sys
11 import types
12 from re import compile as re_compile, search as re_search
13 from iwlibs import getNICnames, Wireless, Iwfreq
14
15 list = []
16 list.append("WEP")
17 list.append("WPA")
18 list.append("WPA2")
19 list.append("WPA/WPA2")
20
21 weplist = []
22 weplist.append("ASCII")
23 weplist.append("HEX")
24
25 config.plugins.wlan = ConfigSubsection()
26 config.plugins.wlan.essid = NoSave(ConfigText(default = "home", fixed_size = False))
27 config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = "home", fixed_size = False))
28
29 config.plugins.wlan.encryption = ConfigSubsection()
30 config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = True))
31 config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = "WPA/WPA2"))
32 config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII"))
33 config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = "mysecurewlan", fixed_size = False))
34
35 class Wlan:
36         def __init__(self, iface):
37                 a = ''; b = ''
38                 for i in range(0, 255):
39                         a = a + chr(i)
40                         if i < 32 or i > 127:
41                                 b = b + ' '
42                         else:
43                                 b = b + chr(i)
44                 
45                 self.iface = iface
46                 self.wlaniface = {}
47                 self.WlanConsole = Console()
48                 self.asciitrans = maketrans(a, b)
49
50         def stopWlanConsole(self):
51                 if self.WlanConsole is not None:
52                         print "killing self.WlanConsole"
53                         self.WlanConsole = None
54                         del self.WlanConsole
55                         
56         def getDataForInterface(self, callback = None):
57                 #get ip out of ip addr, as avahi sometimes overrides it in ifconfig.
58                 print "self.iface im getDataForInterface",self.iface
59                 if len(self.WlanConsole.appContainers) == 0:
60                         self.WlanConsole = Console()
61                         cmd = "iwconfig " + self.iface
62                         self.WlanConsole.ePopen(cmd, self.iwconfigFinished, callback)
63
64         def iwconfigFinished(self, result, retval, extra_args):
65                 print "self.iface im iwconfigFinished",self.iface
66                 callback = extra_args
67                 data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
68                 #print "result im iwconfigFinished",result
69                 
70                 for line in result.splitlines():
71                         #print "line",line
72                         line = line.strip()
73                         if "ESSID" in line:
74                                 if "off/any" in line:
75                                         ssid = _("No Connection")
76                                 else:
77                                         tmpssid=(line[line.index('ESSID')+7:len(line)-1])
78                                         if tmpssid == '':
79                                                 ssid = _("Hidden networkname")
80                                         elif tmpssid ==' ':
81                                                 ssid = _("Hidden networkname")
82                                         else:
83                                             ssid = tmpssid
84                                 #print "SSID->",ssid
85                                 if ssid is not None:
86                                         data['essid'] = ssid
87                         if 'Frequency' in line:
88                                 frequency = line[line.index('Frequency')+10 :line.index(' GHz')]
89                                 #print "Frequency",frequency   
90                                 if frequency is not None:
91                                         data['frequency'] = frequency
92                         if "Access Point" in line:
93                                 ap=line[line.index('Access Point')+14:len(line)-1]
94                                 #print "AP",ap
95                                 if ap is not None:
96                                         data['acesspoint'] = ap
97                         if "Bit Rate" in line:
98                                 br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')]
99                                 #print "Bitrate",br
100                                 if br is not None:
101                                         data['bitrate'] = br
102                         if 'Encryption key' in line:
103                                 if ":off" in line:
104                                     enc = _("Disabled")
105                                 else:
106                                     enc = line[line.index('Encryption key')+15 :line.index('   Security')]
107                                 #print "Encryption key",enc 
108                                 if enc is not None:
109                                         data['encryption'] = _("Enabled")
110                         if 'Quality' in line:
111                                 if "/100" in line:
112                                         qual = line[line.index('Quality')+8:line.index('/100')]
113                                 else:
114                                         qual = line[line.index('Quality')+8:line.index('Sig')]
115                                 #print "Quality",qual
116                                 if qual is not None:
117                                         data['quality'] = qual
118                         if 'Signal level' in line:
119                                 signal = line[line.index('Signal level')+14 :line.index(' dBm')]
120                                 #print "Signal level",signal            
121                                 if signal is not None:
122                                         data['signal'] = signal
123
124                 self.wlaniface[self.iface] = data
125                 
126                 if len(self.WlanConsole.appContainers) == 0:
127                         print "self.wlaniface after loading:", self.wlaniface
128                         self.WlanConsole = None
129                         if callback is not None:
130                                 callback(True,self.wlaniface)
131
132         def getAdapterAttribute(self, attribute):
133                 print "im getAdapterAttribute"
134                 if self.wlaniface.has_key(self.iface):
135                         print "self.wlaniface.has_key",self.iface
136                         if self.wlaniface[self.iface].has_key(attribute):
137                                 return self.wlaniface[self.iface][attribute]
138                 return None
139                 
140         def asciify(self, str):
141                 return str.translate(self.asciitrans)
142
143         
144         def getWirelessInterfaces(self):
145                 iwifaces = None
146                 try:
147                         iwifaces = getNICnames()
148                 except:
149                         print "[Wlan.py] No Wireless Networkcards could be found"
150                 
151                 return iwifaces
152
153         
154         def getNetworkList(self):
155                 system("ifconfig "+self.iface+" up")
156                 ifobj = Wireless(self.iface) # a Wireless NIC Object
157                 
158                 #Association mappings
159                 stats, quality, discard, missed_beacon = ifobj.getStatistics()
160                 snr = quality.signallevel - quality.noiselevel
161
162                 try:
163                         scanresults = ifobj.scan()
164                 except:
165                         scanresults = None
166                         print "[Wlan.py] No Wireless Networks could be found"
167                 
168                 if scanresults is not None:
169                         aps = {}
170                         for result in scanresults:
171                         
172                                 bssid = result.bssid
173                 
174                                 encryption = map(lambda x: hex(ord(x)), result.encode)
175                 
176                                 if encryption[-1] == "0x8":
177                                         encryption = True
178                                 else:
179                                         encryption = False
180                 
181                                 extra = []
182                                 for element in result.custom:
183                                         element = element.encode()
184                                         extra.append( strip(self.asciify(element)) )
185                                 
186                                 if result.quality.sl is 0 and len(extra) > 0:
187                                         begin = extra[0].find('SignalStrength=')+15
188                                                                         
189                                         done = False
190                                         end = begin+1
191                                         
192                                         while not done:
193                                                 if extra[0][begin:end].isdigit():
194                                                         end += 1
195                                                 else:
196                                                         done = True
197                                                         end -= 1
198                                         
199                                         signal = extra[0][begin:end]
200                                         #print "[Wlan.py] signal is:" + str(signal)
201
202                                 else:
203                                         signal = str(result.quality.sl)
204                                 
205                                 aps[bssid] = {
206                                         'active' : True,
207                                         'bssid': result.bssid,
208                                         'channel': result.frequency.getChannel(result.frequency.getFrequency()),
209                                         'encrypted': encryption,
210                                         'essid': strip(self.asciify(result.essid)),
211                                         'iface': self.iface,
212                                         'maxrate' : result.rate[-1],
213                                         'noise' : result.quality.getNoiselevel(),
214                                         'quality' : str(result.quality.quality),
215                                         'signal' : signal,
216                                         'custom' : extra,
217                                 }
218                                 print aps[bssid]
219                         return aps
220
221                 
222         def getStatus(self):
223                 ifobj = Wireless(self.iface)
224                 fq = Iwfreq()
225                 try:
226                         self.channel = str(fq.getChannel(str(ifobj.getFrequency()[0:-3])))
227                 except:
228                         self.channel = 0
229                 #print ifobj.getStatistics()
230                 status = {
231                                   'BSSID': str(ifobj.getAPaddr()),
232                                   'ESSID': str(ifobj.getEssid()),
233                                   'quality': str(ifobj.getStatistics()[1].quality),
234                                   'signal': str(ifobj.getStatistics()[1].sl),
235                                   'bitrate': str(ifobj.getBitrate()),
236                                   'channel': str(self.channel),
237                                   #'channel': str(fq.getChannel(str(ifobj.getFrequency()[0:-3]))),
238                 }
239                 
240                 for (key, item) in status.items():
241                         if item is "None" or item is "":
242                                         status[key] = _("N/A")
243                                 
244                 return status
245
246
247 class wpaSupplicant:
248         def __init__(self):
249                 pass
250         
251                 
252         def writeConfig(self):  
253                         
254                         essid = config.plugins.wlan.essid.value
255                         hiddenessid = config.plugins.wlan.hiddenessid.value
256                         encrypted = config.plugins.wlan.encryption.enabled.value
257                         encryption = config.plugins.wlan.encryption.type.value
258                         wepkeytype = config.plugins.wlan.encryption.wepkeytype.value
259                         psk = config.plugins.wlan.encryption.psk.value
260                         fp = file('/etc/wpa_supplicant.conf', 'w')
261                         fp.write('#WPA Supplicant Configuration by enigma2\n')
262                         fp.write('ctrl_interface=/var/run/wpa_supplicant\n')
263                         fp.write('eapol_version=1\n')
264                         fp.write('fast_reauth=1\n')     
265                         if essid == 'hidden...':
266                                 fp.write('ap_scan=2\n')
267                         else:
268                                 fp.write('ap_scan=1\n')
269                         fp.write('network={\n')
270                         if essid == 'hidden...':
271                                 fp.write('\tssid="'+hiddenessid+'"\n')
272                         else:
273                                 fp.write('\tssid="'+essid+'"\n')
274                         fp.write('\tscan_ssid=0\n')                     
275                         if encrypted:
276                                 if encryption == 'WPA' or encryption == 'WPA2' or encryption == 'WPA/WPA2' :
277                                         fp.write('\tkey_mgmt=WPA-PSK\n')
278                                         
279                                         if encryption == 'WPA':
280                                                 fp.write('\tproto=WPA\n')
281                                                 fp.write('\tpairwise=TKIP\n')
282                                                 fp.write('\tgroup=TKIP\n')
283                                         elif encryption == 'WPA2':
284                                                 fp.write('\tproto=WPA RSN\n')
285                                                 fp.write('\tpairwise=CCMP TKIP\n')
286                                                 fp.write('\tgroup=CCMP TKIP\n')                                         
287                                         else:
288                                                 fp.write('\tproto=WPA WPA2\n')
289                                                 fp.write('\tpairwise=CCMP\n')
290                                                 fp.write('\tgroup=TKIP\n')                                      
291                                         fp.write('\tpsk="'+psk+'"\n')
292                                                 
293                                 elif encryption == 'WEP':
294                                         fp.write('\tkey_mgmt=NONE\n')
295                                         if wepkeytype == 'ASCII':
296                                                 fp.write('\twep_key0="'+psk+'"\n')
297                                         else:
298                                                 fp.write('\twep_key0='+psk+'\n')
299                         else:
300                                 fp.write('\tkey_mgmt=NONE\n')                   
301                         fp.write('}')
302                         fp.write('\n')
303                         fp.close()
304                         system("cat /etc/wpa_supplicant.conf")
305                 
306         def loadConfig(self):
307                 try:
308                         #parse the wpasupplicant configfile
309                         fp = file('/etc/wpa_supplicant.conf', 'r')
310                         supplicant = fp.readlines()
311                         fp.close()
312                         ap_scan = False
313                         essid = None
314
315                         for s in supplicant:
316                                 split = s.strip().split('=',1)
317                                 if split[0] == 'ap_scan':
318                                         print "[Wlan.py] Got Hidden SSID Scan  Value "+split[1]
319                                         if split[1] == '2':
320                                                 ap_scan = True
321                                         else:
322                                                 ap_scan = False
323                                                 
324                                 elif split[0] == 'ssid':
325                                         print "[Wlan.py] Got SSID "+split[1][1:-1]
326                                         essid = split[1][1:-1]
327                                         
328                                 elif split[0] == 'proto':
329                                         print "split[1]",split[1]
330                                         config.plugins.wlan.encryption.enabled.value = True
331                                         if split[1] == "WPA" :
332                                                 mode = 'WPA'
333                                         if split[1] == "WPA WPA2" :
334                                                 mode = 'WPA/WPA2'
335                                         if split[1] == "WPA RSN" :
336                                                 mode = 'WPA2'
337                                         config.plugins.wlan.encryption.type.value = mode
338                                         print "[Wlan.py] Got Encryption: "+mode
339                                         
340                                 #currently unused !
341                                 #elif split[0] == 'key_mgmt':
342                                 #       print "split[1]",split[1]
343                                 #       if split[1] == "WPA-PSK" :
344                                 #               config.plugins.wlan.encryption.enabled.value = True
345                                 #               config.plugins.wlan.encryption.type.value = "WPA/WPA2"
346                                 #       print "[Wlan.py] Got Encryption: "+ config.plugins.wlan.encryption.type.value
347                                         
348                                 elif split[0] == 'wep_key0':
349                                         config.plugins.wlan.encryption.enabled.value = True
350                                         config.plugins.wlan.encryption.type.value = 'WEP'
351                                         if split[1].startswith('"') and split[1].endswith('"'):
352                                                 config.plugins.wlan.encryption.wepkeytype.value = 'ASCII'
353                                                 config.plugins.wlan.encryption.psk.value = split[1][1:-1]
354                                         else:
355                                                 config.plugins.wlan.encryption.wepkeytype.value = 'HEX'
356                                                 config.plugins.wlan.encryption.psk.value = split[1]                                             
357                                         print "[Wlan.py] Got Encryption: WEP - keytype is: "+config.plugins.wlan.encryption.wepkeytype.value
358                                         print "[Wlan.py] Got Encryption: WEP - key0 is: "+config.plugins.wlan.encryption.psk.value
359                                         
360                                 elif split[0] == 'psk':
361                                         config.plugins.wlan.encryption.psk.value = split[1][1:-1]
362                                         print "[Wlan.py] Got PSK: "+split[1][1:-1]
363                                 else:
364                                         pass
365                                 
366                         if ap_scan is True:
367                                 config.plugins.wlan.hiddenessid.value = essid
368                                 config.plugins.wlan.essid.value = 'hidden...'
369                         else:
370                                 config.plugins.wlan.hiddenessid.value = essid
371                                 config.plugins.wlan.essid.value = essid
372                         wsconfig = {
373                                         'hiddenessid': config.plugins.wlan.hiddenessid.value,
374                                         'ssid': config.plugins.wlan.essid.value,
375                                         'encryption': config.plugins.wlan.encryption.enabled.value,
376                                         'encryption_type': config.plugins.wlan.encryption.type.value,
377                                         'encryption_wepkeytype': config.plugins.wlan.encryption.wepkeytype.value,
378                                         'key': config.plugins.wlan.encryption.psk.value,
379                                 }
380                 
381                         for (key, item) in wsconfig.items():
382                                 if item is "None" or item is "":
383                                         if key == 'hiddenessid':
384                                                 wsconfig['hiddenessid'] = "home"
385                                         if key == 'ssid':
386                                                 wsconfig['ssid'] = "home"
387                                         if key == 'encryption':
388                                                 wsconfig['encryption'] = True                           
389                                         if key == 'encryption':
390                                                 wsconfig['encryption_type'] = "WPA/WPA2"
391                                         if key == 'encryption':
392                                                 wsconfig['encryption_wepkeytype'] = "ASCII"
393                                         if key == 'encryption':
394                                                 wsconfig['key'] = "mysecurewlan"
395
396                 except:
397                         print "[Wlan.py] Error parsing /etc/wpa_supplicant.conf"
398                         wsconfig = {
399                                         'hiddenessid': "home",
400                                         'ssid': "home",
401                                         'encryption': True,
402                                         'encryption_type': "WPA/WPA2",
403                                         'encryption_wepkeytype': "ASCII",
404                                         'key': "mysecurewlan",
405                                 }
406                 print "[Wlan.py] WS-CONFIG-->",wsconfig
407                 return wsconfig
408
409         
410         def restart(self, iface):
411                 system("start-stop-daemon -K -x /usr/sbin/wpa_supplicant")
412                 system("start-stop-daemon -S -x /usr/sbin/wpa_supplicant -- -B -i"+iface+" -c/etc/wpa_supplicant.conf")
413
414 class Status:
415         def __init__(self):
416                 self.wlaniface = {}
417                 self.backupwlaniface = {}
418                 self.WlanConsole = Console()
419
420         def stopWlanConsole(self):
421                 if self.WlanConsole is not None:
422                         print "killing self.WlanConsole"
423                         self.WlanConsole = None
424                         
425         def getDataForInterface(self, iface, callback = None):
426                 self.WlanConsole = Console()
427                 cmd = "iwconfig " + iface
428                 self.WlanConsole.ePopen(cmd, self.iwconfigFinished, [iface, callback])
429
430         def iwconfigFinished(self, result, retval, extra_args):
431                 (iface, callback) = extra_args
432                 data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
433                 for line in result.splitlines():
434                         line = line.strip()
435                         if "ESSID" in line:
436                                 if "off/any" in line:
437                                         ssid = _("No Connection")
438                                 else:
439                                         tmpssid=(line[line.index('ESSID')+7:len(line)-1])
440                                         if tmpssid == '':
441                                                 ssid = _("Hidden networkname")
442                                         elif tmpssid ==' ':
443                                                 ssid = _("Hidden networkname")
444                                         else:
445                                             ssid = tmpssid
446                                 #print "SSID->",ssid
447                                 if ssid is not None:
448                                         data['essid'] = ssid
449                         if 'Frequency' in line:
450                                 frequency = line[line.index('Frequency')+10 :line.index(' GHz')]
451                                 #print "Frequency",frequency   
452                                 if frequency is not None:
453                                         data['frequency'] = frequency
454                         if "Access Point" in line:
455                                 ap=line[line.index('Access Point')+14:len(line)]
456                                 #print "AP",ap
457                                 if ap is not None:
458                                         data['acesspoint'] = ap
459                                         if ap == "Not-Associated":
460                                                 data['essid'] = _("No Connection")
461                         if "Bit Rate" in line:
462                                 if "kb" in line:
463                                         br = line[line.index('Bit Rate')+9 :line.index(' kb/s')]
464                                         if br == '0':
465                                                 br = _("Unsupported")
466                                         else:
467                                                 br += " Mb/s"
468                                 else:
469                                         br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')] + " Mb/s"
470                                 #print "Bitrate",br
471                                 if br is not None:
472                                         data['bitrate'] = br
473                         if 'Encryption key' in line:
474                                 if ":off" in line:
475                                         if data['acesspoint'] is not "Not-Associated":
476                                                 enc = _("Unsupported")
477                                         else:
478                                                 enc = _("Disabled")
479                                 else:
480                                         enc = line[line.index('Encryption key')+15 :line.index('   Security')]
481                                         if enc is not None:
482                                                 enc = _("Enabled")
483                                 #print "Encryption key",enc 
484                                 if enc is not None:
485                                         data['encryption'] = enc
486                         if 'Quality' in line:
487                                 if "/100" in line:
488                                         qual = line[line.index('Quality')+8:line.index('/100')]
489                                 else:
490                                         qual = line[line.index('Quality')+8:line.index('Sig')]
491                                 #print "Quality",qual
492                                 if qual is not None:
493                                         data['quality'] = qual
494                         if 'Signal level' in line:
495                                 if "dBm" in line:
496                                         signal = line[line.index('Signal level')+14 :line.index(' dBm')]
497                                         signal += " dBm"
498                                 elif "/100" in line:
499                                         signal = line[line.index('Signal level')+13:line.index('/100  Noise')]
500                                         signal += "%"
501                                 else:
502                                         signal = line[line.index('Signal level')+13:line.index('  Noise')]
503                                         signal += "%"
504                                 #print "Signal level",signal            
505                                 if signal is not None:
506                                         data['signal'] = signal
507
508                 self.wlaniface[iface] = data
509                 self.backupwlaniface = self.wlaniface
510                 
511                 if self.WlanConsole is not None:
512                         if len(self.WlanConsole.appContainers) == 0:
513                                 print "self.wlaniface after loading:", self.wlaniface
514                                 if callback is not None:
515                                         callback(True,self.wlaniface)
516
517         def getAdapterAttribute(self, iface, attribute):
518                 print "im getAdapterAttribute"
519                 self.iface = iface
520                 if self.wlaniface.has_key(self.iface):
521                         print "self.wlaniface.has_key",self.iface
522                         if self.wlaniface[self.iface].has_key(attribute):
523                                 return self.wlaniface[self.iface][attribute]
524                 return None
525         
526 iStatus = Status()