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