4a7b1e88c6a10426807fbb89e1e446bd3780cd51
[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(ConfigYesNo(default = 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
150                 if hiddenessid:
151                         fp.write('ap_scan=2\n')
152                 else:
153                         fp.write('ap_scan=1\n')
154                 fp.write('network={\n')
155                 fp.write('\tssid="'+essid+'"\n')
156                 fp.write('\tscan_ssid=0\n')                     
157                 if encrypted:
158                         if encryption in ('WPA', 'WPA2', 'WPA/WPA2'):
159                                 fp.write('\tkey_mgmt=WPA-PSK\n')
160                 
161                                 if encryption == 'WPA':
162                                         fp.write('\tproto=WPA\n')
163                                         fp.write('\tpairwise=TKIP\n')
164                                         fp.write('\tgroup=TKIP\n')
165                                 elif encryption == 'WPA2':
166                                         fp.write('\tproto=RSN\n')
167                                         fp.write('\tpairwise=CCMP\n')
168                                         fp.write('\tgroup=CCMP\n')
169                                 else:
170                                         fp.write('\tproto=WPA RSN\n')
171                                         fp.write('\tpairwise=CCMP TKIP\n')
172                                         fp.write('\tgroup=CCMP TKIP\n')
173                                 fp.write('\tpsk="'+psk+'"\n')
174                         elif encryption == 'WEP':
175                                 fp.write('\tkey_mgmt=NONE\n')
176                                 if wepkeytype == 'ASCII':
177                                         fp.write('\twep_key0="'+psk+'"\n')
178                                 else:
179                                         fp.write('\twep_key0='+psk+'\n')
180                 else:
181                         fp.write('\tkey_mgmt=NONE\n')                   
182                 fp.write('}')
183                 fp.write('\n')
184                 fp.close()
185                 #system('cat ' + getWlanConfigName(iface))
186                 
187         def loadConfig(self,iface):
188                 configfile = getWlanConfigName(iface)
189                 if not os_path.exists(configfile):
190                         configfile = '/etc/wpa_supplicant.conf'
191                 try:
192                         #parse the wpasupplicant configfile
193                         print "[Wlan.py] parsing configfile: ",configfile
194                         fp = file(configfile, 'r')
195                         supplicant = fp.readlines()
196                         fp.close()
197                         essid = None
198
199                         for s in supplicant:
200                                 split = s.strip().split('=',1)
201                                 if split[0] == 'ap_scan':
202                                         #print "[Wlan.py] Got Hidden SSID Scan Value ",split[1]
203                                         if split[1] == '2':
204                                                 config.plugins.wlan.hiddenessid.value = True
205                                         else:
206                                                 config.plugins.wlan.hiddenessid.value = False
207                                         
208                                 elif split[0] == 'ssid':
209                                         #print "[Wlan.py] Got SSID ",split[1][1:-1]
210                                         essid = split[1][1:-1]
211                                         config.plugins.wlan.essid.value = essid
212                                 
213                                 elif split[0] == 'proto':
214                                         config.plugins.wlan.encryption.enabled.value = True
215                                         if split[1] == 'WPA' :
216                                                 mode = 'WPA'
217                                         if split[1] == 'RSN':
218                                                 mode = 'WPA2'
219                                         if split[1] in ('WPA RSN', 'WPA WPA2'):
220                                                 mode = 'WPA/WPA2'
221                                         #print "[Wlan.py] Got Encryption: ",mode
222                                         config.plugins.wlan.encryption.type.value = mode
223                                         
224                                 elif split[0] == 'wep_key0':
225                                         config.plugins.wlan.encryption.enabled.value = True
226                                         config.plugins.wlan.encryption.type.value = 'WEP'
227                                         if split[1].startswith('"') and split[1].endswith('"'):
228                                                 config.plugins.wlan.encryption.wepkeytype.value = 'ASCII'
229                                                 config.plugins.wlan.encryption.psk.value = split[1][1:-1]
230                                         else:
231                                                 config.plugins.wlan.encryption.wepkeytype.value = 'HEX'
232                                                 config.plugins.wlan.encryption.psk.value = split[1]                                             
233                                         
234                                 elif split[0] == 'psk':
235                                         config.plugins.wlan.encryption.psk.value = split[1][1:-1]
236                                 else:
237                                         pass
238                                 
239                         wsconfig = {
240                                         'hiddenessid': config.plugins.wlan.hiddenessid.value,
241                                         'ssid': config.plugins.wlan.essid.value,
242                                         'encryption': config.plugins.wlan.encryption.enabled.value,
243                                         'encryption_type': config.plugins.wlan.encryption.type.value,
244                                         'encryption_wepkeytype': config.plugins.wlan.encryption.wepkeytype.value,
245                                         'key': config.plugins.wlan.encryption.psk.value,
246                                 }
247                 
248                         for (key, item) in wsconfig.items():
249                                 if item is "None" or item is "":
250                                         if key == 'hiddenessid':
251                                                 wsconfig['hiddenessid'] = False
252                                         if key == 'ssid':
253                                                 wsconfig['ssid'] = "home"
254                                         if key == 'encryption':
255                                                 wsconfig['encryption'] = True                           
256                                         if key == 'encryption_type':
257                                                 wsconfig['encryption_type'] = "WPA/WPA2"
258                                         if key == 'encryption_wepkeytype':
259                                                 wsconfig['encryption_wepkeytype'] = "ASCII"
260                                         if key == 'key':
261                                                 wsconfig['key'] = "mysecurewlan"
262                 except:
263                         print "[Wlan.py] Error parsing ",configfile
264                         wsconfig = {
265                                         'hiddenessid': False,
266                                         'ssid': "home",
267                                         'encryption': True,
268                                         'encryption_type': "WPA/WPA2",
269                                         'encryption_wepkeytype': "ASCII",
270                                         'key': "mysecurewlan",
271                                 }
272                 #print "[Wlan.py] WS-CONFIG-->",wsconfig
273                 return wsconfig
274
275
276 class Status:
277         def __init__(self):
278                 self.wlaniface = {}
279                 self.backupwlaniface = {}
280                 self.WlanConsole = Console()
281
282         def stopWlanConsole(self):
283                 if self.WlanConsole is not None:
284                         print "[iStatus] killing self.WlanConsole"
285                         self.WlanConsole.killAll()
286                         self.WlanConsole = None
287                         
288         def getDataForInterface(self, iface, callback = None):
289                 self.WlanConsole = Console()
290                 cmd = "iwconfig " + iface
291                 self.WlanConsole.ePopen(cmd, self.iwconfigFinished, [iface, callback])
292
293         def iwconfigFinished(self, result, retval, extra_args):
294                 (iface, callback) = extra_args
295                 data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
296                 for line in result.splitlines():
297                         line = line.strip()
298                         if "ESSID" in line:
299                                 if "off/any" in line:
300                                         ssid = _("No Connection")
301                                 else:
302                                         if "Nickname" in line:
303                                                 tmpssid=(line[line.index('ESSID')+7:line.index('"  Nickname')])
304                                                 if tmpssid in ('', ' '):
305                                                         ssid = _("Hidden networkname")
306                                                 else:
307                                                         ssid = tmpssid
308                                         else:
309                                                 tmpssid=(line[line.index('ESSID')+7:len(line)-1])
310                                                 if tmpssid in ('', ' '):
311                                                         ssid = _("Hidden networkname")
312                                                 else:
313                                                         ssid = tmpssid                                          
314                                 if ssid is not None:
315                                         data['essid'] = ssid
316                         if 'Frequency' in line:
317                                 frequency = line[line.index('Frequency')+10 :line.index(' GHz')]
318                                 if frequency is not None:
319                                         data['frequency'] = frequency
320                         if "Access Point" in line:
321                                 ap=line[line.index('Access Point')+14:len(line)]
322                                 if ap is not None:
323                                         data['acesspoint'] = ap
324                                         if ap == "Not-Associated":
325                                                 data['essid'] = _("No Connection")
326                         if "Bit Rate" in line:
327                                 if "kb" in line:
328                                         br = line[line.index('Bit Rate')+9 :line.index(' kb/s')]
329                                         if br == '0':
330                                                 br = _("Unsupported")
331                                         else:
332                                                 br += " Mb/s"
333                                 else:
334                                         br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')] + " Mb/s"
335                                 if br is not None:
336                                         data['bitrate'] = br
337                         if 'Encryption key' in line:
338                                 if ":off" in line:
339                                         if data['acesspoint'] is not "Not-Associated":
340                                                 enc = _("Unsupported")
341                                         else:
342                                                 enc = _("Disabled")
343                                 elif "Security" in line:
344                                         enc = line[line.index('Encryption key')+15 :line.index('   Security')]
345                                         if enc is not None:
346                                                 enc = _("Enabled")
347                                 else:
348                                         enc = line[line.index('Encryption key')+15 :len(line)]
349                                         if enc is not None:
350                                                 enc = _("Enabled")                                      
351                                 if enc is not None:
352                                         data['encryption'] = enc
353                         if 'Quality' in line:
354                                 if "/100" in line:
355                                         qual = line[line.index('Quality')+8:line.index('  Signal')]
356                                 else:
357                                         qual = line[line.index('Quality')+8:line.index('Sig')]
358                                 if qual is not None:
359                                         data['quality'] = qual
360                         if 'Signal level' in line:
361                                 if "dBm" in line:
362                                         signal = line[line.index('Signal level')+13 :line.index(' dBm')]
363                                         signal += " dBm"
364                                 elif "/100" in line:
365                                         if "Noise" in line:
366                                                 signal = line[line.index('Signal level')+13:line.index('  Noise')]
367                                         else:
368                                                 signal = line[line.index('Signal level')+13:len(line)]
369                                 else:
370                                         if "Noise" in line:
371                                                 signal = line[line.index('Signal level')+13:line.index('  Noise')]
372                                         else:
373                                                 signal = line[line.index('Signal level')+13:len(line)]                                          
374                                 if signal is not None:
375                                         data['signal'] = signal
376
377                 self.wlaniface[iface] = data
378                 self.backupwlaniface = self.wlaniface
379                 
380                 if self.WlanConsole is not None:
381                         if len(self.WlanConsole.appContainers) == 0:
382                                 print "[Wlan.py] self.wlaniface after loading:", self.wlaniface
383                                 if callback is not None:
384                                         callback(True,self.wlaniface)
385
386         def getAdapterAttribute(self, iface, attribute):
387                 self.iface = iface
388                 if self.wlaniface.has_key(self.iface):
389                         if self.wlaniface[self.iface].has_key(attribute):
390                                 return self.wlaniface[self.iface][attribute]
391                 return None
392         
393 iStatus = Status()