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