e0d3b4a19d5a90987860b03484ce8e986352f5be
[openblackhole/openblackhole-enigma2.git] / lib / python / Plugins / SystemPlugins / WirelessLan / plugin.py
1 from enigma import eTimer, eEnv
2 from Screens.Screen import Screen
3 from Components.ActionMap import ActionMap, NumberActionMap
4 from Components.Pixmap import Pixmap,MultiPixmap
5 from Components.Label import Label
6 from Components.Sources.StaticText import StaticText
7 from Components.Sources.List import List
8 from Components.MenuList import MenuList
9 from Components.config import config, getConfigListEntry, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
10 from Components.ConfigList import ConfigListScreen
11 from Components.Network import iNetwork
12 from Components.Console import Console
13 from Plugins.Plugin import PluginDescriptor
14 from os import system, path as os_path, listdir
15 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
16 from Tools.LoadPixmap import LoadPixmap
17 from Wlan import iWlan, wpaSupplicant, iStatus, getWlanConfigName
18 from time import time
19 from os import system
20 from re import escape as re_escape
21
22 plugin_path = eEnv.resolve("${libdir}/enigma2/python/Plugins/SystemPlugins/WirelessLan")
23
24
25 list = []
26 list.append("Unencrypted")
27 list.append("WEP")
28 list.append("WPA")
29 list.append("WPA/WPA2")
30 list.append("WPA2")
31
32 weplist = []
33 weplist.append("ASCII")
34 weplist.append("HEX")
35
36 config.plugins.wlan = ConfigSubsection()
37 config.plugins.wlan.essid = NoSave(ConfigText(default = "", fixed_size = False))
38 config.plugins.wlan.hiddenessid = NoSave(ConfigYesNo(default = False))
39 config.plugins.wlan.encryption = NoSave(ConfigSelection(list, default = "WPA2"))
40 config.plugins.wlan.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII"))
41 config.plugins.wlan.psk = NoSave(ConfigPassword(default = "", fixed_size = False))
42
43
44
45 class WlanStatus(Screen):
46         skin = """
47                 <screen name="WlanStatus" position="center,center" size="560,400" title="Wireless network status" >
48                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
49                         <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
50
51                         <widget source="LabelBSSID" render="Label" position="10,60" size="200,25" valign="left" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
52                         <widget source="LabelESSID" render="Label" position="10,100" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
53                         <widget source="LabelQuality" render="Label" position="10,140" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
54                         <widget source="LabelSignal" render="Label" position="10,180" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
55                         <widget source="LabelBitrate" render="Label" position="10,220" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
56                         <widget source="LabelEnc" render="Label" position="10,260" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
57                         <widget source="BSSID" render="Label" position="220,60" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
58                         <widget source="ESSID" render="Label" position="220,100" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
59                         <widget source="quality" render="Label" position="220,140" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
60                         <widget source="signal" render="Label" position="220,180" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
61                         <widget source="bitrate" render="Label" position="220,220" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
62                         <widget source="enc" render="Label" position="220,260" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
63
64                         <ePixmap pixmap="skin_default/div-h.png" position="0,350" zPosition="1" size="560,2" />
65                         <widget source="IFtext" render="Label" position="10,355" size="120,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
66                         <widget source="IF" render="Label" position="120,355" size="400,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
67                         <widget source="Statustext" render="Label" position="10,375" size="115,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1"/>
68                         <widget name="statuspic" pixmaps="skin_default/buttons/button_green.png,skin_default/buttons/button_green_off.png" position="130,380" zPosition="10" size="15,16" transparent="1" alphatest="on"/>
69                 </screen>"""
70
71         def __init__(self, session, iface):
72                 Screen.__init__(self, session)
73                 self.session = session
74                 self.iface = iface
75
76                 self["LabelBSSID"] = StaticText(_('Accesspoint:'))
77                 self["LabelESSID"] = StaticText(_('SSID:'))
78                 self["LabelQuality"] = StaticText(_('Link quality:'))
79                 self["LabelSignal"] = StaticText(_('Signal strength:'))
80                 self["LabelBitrate"] = StaticText(_('Bitrate:'))
81                 self["LabelEnc"] = StaticText(_('Encryption:'))
82
83                 self["BSSID"] = StaticText()
84                 self["ESSID"] = StaticText()
85                 self["quality"] = StaticText()
86                 self["signal"] = StaticText()
87                 self["bitrate"] = StaticText()
88                 self["enc"] = StaticText()
89
90                 self["IFtext"] = StaticText()
91                 self["IF"] = StaticText()
92                 self["Statustext"] = StaticText()
93                 self["statuspic"] = MultiPixmap()
94                 self["statuspic"].hide()
95                 self["key_red"] = StaticText(_("Close"))
96
97                 self.resetList()
98                 self.updateStatusbar()
99
100                 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions", "ShortcutActions"],
101                 {
102                         "ok": self.exit,
103                         "back": self.exit,
104                         "red": self.exit,
105                 }, -1)
106                 self.timer = eTimer()
107                 self.timer.timeout.get().append(self.resetList)
108                 self.onShown.append(lambda: self.timer.start(8000))
109                 self.onLayoutFinish.append(self.layoutFinished)
110                 self.onClose.append(self.cleanup)
111
112         def cleanup(self):
113                 iStatus.stopWlanConsole()
114
115         def layoutFinished(self):
116                 self.setTitle(_("Wireless network state"))
117
118         def resetList(self):
119                 iStatus.getDataForInterface(self.iface,self.getInfoCB)
120
121         def getInfoCB(self,data,status):
122                 if data is not None:
123                         if data is True:
124                                 if status is not None:
125                                         if status[self.iface]["essid"] == "off":
126                                                 essid = _("No Connection")
127                                         else:
128                                                 essid = status[self.iface]["essid"]
129                                         if status[self.iface]["accesspoint"] == "Not-Associated":
130                                                 accesspoint = _("Not associated")
131                                                 essid = _("No Connection")
132                                         else:
133                                                 accesspoint = status[self.iface]["accesspoint"]
134                                         if self.has_key("BSSID"):
135                                                 self["BSSID"].setText(accesspoint)
136                                         if self.has_key("ESSID"):
137                                                 self["ESSID"].setText(essid)
138
139                                         quality = status[self.iface]["quality"]
140                                         if self.has_key("quality"):
141                                                 self["quality"].setText(quality)
142
143                                         if status[self.iface]["bitrate"] == '0':
144                                                 bitrate = _("Unsupported")
145                                         else:
146                                                 bitrate = str(status[self.iface]["bitrate"]) + " Mb/s"
147                                         if self.has_key("bitrate"):
148                                                 self["bitrate"].setText(bitrate)
149
150                                         signal = status[self.iface]["signal"]
151                                         if self.has_key("signal"):
152                                                 self["signal"].setText(signal)
153
154                                         if status[self.iface]["encryption"] == "off":
155                                                 if accesspoint == "Not-Associated":
156                                                         encryption = _("Disabled")
157                                                 else:
158                                                         encryption = _("Unsupported")
159                                         else:
160                                                 encryption = _("Enabled")
161                                         if self.has_key("enc"):
162                                                 self["enc"].setText(encryption)
163                                         self.updateStatusLink(status)
164
165         def exit(self):
166                 self.timer.stop()
167                 self.close(True)
168
169         def updateStatusbar(self):
170                 wait_txt = _("Please wait...")
171                 self["BSSID"].setText(wait_txt)
172                 self["ESSID"].setText(wait_txt)
173                 self["quality"].setText(wait_txt)
174                 self["signal"].setText(wait_txt)
175                 self["bitrate"].setText(wait_txt)
176                 self["enc"].setText(wait_txt)
177                 self["IFtext"].setText(_("Network:"))
178                 self["IF"].setText(iNetwork.getFriendlyAdapterName(self.iface))
179                 self["Statustext"].setText(_("Link:"))
180
181         def updateStatusLink(self,status):
182                 if status is not None:
183                         if status[self.iface]["essid"] == "off" or status[self.iface]["accesspoint"] == "Not-Associated" or status[self.iface]["accesspoint"] == False:
184                                 self["statuspic"].setPixmapNum(1)
185                         else:
186                                 self["statuspic"].setPixmapNum(0)
187                         self["statuspic"].show()
188
189
190 class WlanScan(Screen):
191         skin = """
192                 <screen name="WlanScan" position="center,center" size="560,400" title="Select a wireless network" >
193                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
194                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
195                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
196                         <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
197                         <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
198                         <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
199                         <widget source="list" render="Listbox" position="5,40" size="550,300" scrollbarMode="showOnDemand">
200                                 <convert type="TemplatedMultiContent">
201                                         {"template": [
202                                                         MultiContentEntryText(pos = (0, 0), size = (550, 30), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the essid
203                                                         MultiContentEntryText(pos = (0, 30), size = (175, 20), font=1, flags = RT_HALIGN_LEFT, text = 5), # index 5 is the interface
204                                                         MultiContentEntryText(pos = (175, 30), size = (175, 20), font=1, flags = RT_HALIGN_LEFT, text = 4), # index 0 is the encryption
205                                                         MultiContentEntryText(pos = (350, 0), size = (200, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 0 is the signal
206                                                         MultiContentEntryText(pos = (350, 30), size = (200, 20), font=1, flags = RT_HALIGN_LEFT, text = 3), # index 0 is the maxrate
207                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (550, 2), png = 6), # index 6 is the div pixmap
208                                                 ],
209                                         "fonts": [gFont("Regular", 28),gFont("Regular", 18)],
210                                         "itemHeight": 54
211                                         }
212                                 </convert>
213                         </widget>
214                         <ePixmap pixmap="skin_default/div-h.png" position="0,340" zPosition="1" size="560,2" />
215                         <widget source="info" render="Label" position="0,350" size="560,50" font="Regular;24" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
216                 </screen>"""
217
218         def __init__(self, session, iface):
219                 Screen.__init__(self, session)
220                 self.session = session
221                 self.iface = iface
222                 self.skin_path = plugin_path
223                 self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up")
224                 self.APList = None
225                 self.newAPList = None
226                 self.WlanList = None
227                 self.cleanList = None
228                 self.oldlist = {}
229                 self.listLength = None
230                 self.divpng = LoadPixmap(path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
231
232                 self.rescanTimer = eTimer()
233                 self.rescanTimer.callback.append(self.rescanTimerFired)
234
235                 self["info"] = StaticText()
236
237                 self.list = []
238                 self["list"] = List(self.list)
239
240                 self["key_red"] = StaticText(_("Close"))
241                 self["key_green"] = StaticText(_("Connect"))
242                 self["key_yellow"] = StaticText()
243
244                 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions"],
245                 {
246                         "ok": self.select,
247                         "back": self.cancel,
248                 }, -1)
249
250                 self["shortcuts"] = ActionMap(["ShortcutActions"],
251                 {
252                         "red": self.cancel,
253                         "green": self.select,
254                 })
255                 iWlan.setInterface(self.iface)
256                 self.w = iWlan.getInterface()
257                 self.onLayoutFinish.append(self.layoutFinished)
258                 self.getAccessPoints(refresh = False)
259
260         def layoutFinished(self):
261                 self.setTitle(_("Select a wireless network"))
262
263         def select(self):
264                 cur = self["list"].getCurrent()
265                 if cur is not None:
266                         iWlan.stopGetNetworkList()
267                         self.rescanTimer.stop()
268                         del self.rescanTimer
269                         if cur[0] is not None:
270                                 self.close(cur[0])
271                         else:
272                                 self.close(None)
273                 else:
274                         iWlan.stopGetNetworkList()
275                         self.rescanTimer.stop()
276                         del self.rescanTimer
277                         self.close(None)
278
279         def cancel(self):
280                 iWlan.stopGetNetworkList()
281                 self.rescanTimer.stop()
282                 del self.rescanTimer
283                 self.close(None)
284
285         def rescanTimerFired(self):
286                 self.rescanTimer.stop()
287                 self.updateAPList()
288
289         def buildEntryComponent(self, essid, bssid, encrypted, iface, maxrate, signal):
290                 encryption = encrypted and _("Yes") or _("No")
291                 return((essid, bssid, _("Signal: ") + str(signal), _("Max. bitrate: ") + str(maxrate), _("Encrypted: ") + encryption, _("Interface: ") + str(iface), self.divpng))
292
293         def updateAPList(self):
294                 newList = []
295                 newList = self.getAccessPoints(refresh = True)
296                 self.newAPList = []
297                 tmpList = []
298                 newListIndex = None
299                 currentListEntry = None
300                 currentListIndex = None
301
302                 for ap in self.oldlist.keys():
303                         data = self.oldlist[ap]['data']
304                         if data is not None:
305                                 tmpList.append(data)
306
307                 if len(tmpList):
308                         for entry in tmpList:
309                                 self.newAPList.append(self.buildEntryComponent( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ))
310
311                         currentListEntry = self["list"].getCurrent()
312                         if currentListEntry is not None:
313                                 idx = 0
314                                 for entry in self.newAPList:
315                                         if entry[0] == currentListEntry[0]:
316                                                 newListIndex = idx
317                                         idx +=1
318                         self['list'].setList(self.newAPList)
319                         if newListIndex is not None:
320                                 self["list"].setIndex(newListIndex)
321                         self["list"].updateList(self.newAPList)
322                         self.listLength = len(self.newAPList)
323                         self.buildWlanList()
324                         self.setInfo()
325
326         def getAccessPoints(self, refresh = False):
327                 self.APList = []
328                 self.cleanList = []
329                 aps = iWlan.getNetworkList()
330                 if aps is not None:
331                         print "[WirelessLan.py] got Accespoints!"
332                         tmpList = []
333                         compList = []
334                         for ap in aps:
335                                 a = aps[ap]
336                                 if a['active']:
337                                         tmpList.append( (a['essid'], a['bssid']) )
338                                         compList.append( (a['essid'], a['bssid'], a['encrypted'], a['iface'], a['maxrate'], a['signal']) )
339
340                         for entry in tmpList:
341                                 if entry[0] == "":
342                                         for compentry in compList:
343                                                 if compentry[1] == entry[1]:
344                                                         compList.remove(compentry)
345                         for entry in compList:
346                                 self.cleanList.append( ( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ) )
347                                 if not self.oldlist.has_key(entry[0]):
348                                         self.oldlist[entry[0]] = { 'data': entry }
349                                 else:
350                                         self.oldlist[entry[0]]['data'] = entry
351
352                 for entry in self.cleanList:
353                         self.APList.append(self.buildEntryComponent( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ))
354
355                 if refresh is False:
356                         self['list'].setList(self.APList)
357                 self.listLength = len(self.APList)
358                 self.setInfo()
359                 self.rescanTimer.start(5000)
360                 return self.cleanList
361
362         def setInfo(self):
363                 length = self.getLength()
364                 if length == 0:
365                         self["info"].setText(_("No wireless networks found! Searching..."))
366                 else:
367                         self["info"].setText(ngettext("%d wireless network found!", "%d wireless networks found!", length) % length)
368
369         def buildWlanList(self):
370                 self.WlanList = []
371                 for entry in self['list'].list:
372                         self.WlanList.append( (entry[0], entry[0]) )
373
374         def getLength(self):
375                 return self.listLength
376
377         def getWlanList(self):
378                 if self.WlanList is None:
379                         self.buildWlanList()
380                 return self.WlanList
381
382
383 def WlanStatusScreenMain(session, iface):
384         session.open(WlanStatus, iface)
385
386 def callFunction(iface):
387         iWlan.setInterface(iface)
388         i = iWlan.getWirelessInterfaces()
389         if iface in i or iNetwork.isWirelessInterface(iface):
390                 return WlanStatusScreenMain
391         return None
392
393 def configStrings(iface):
394         driver = iNetwork.detectWlanModule(iface)
395         ret = ""
396         if driver == 'madwifi' and config.plugins.wlan.hiddenessid.value:
397                 ret += "\tpre-up iwconfig " + iface + " essid \"" + re_escape(config.plugins.wlan.essid.value) + "\" || true\n"
398         ret += "\tpre-up wpa_supplicant -i" + iface + " -c" + getWlanConfigName(iface) + " -B -dd -D" + driver + " || true\n"
399         ret += "\tpre-down wpa_cli -i" + iface + " terminate || true\n"
400         return ret
401
402 def Plugins(**kwargs):
403         return PluginDescriptor(name=_("Wireless LAN"), description=_("Connect to a wireless network"), where = PluginDescriptor.WHERE_NETWORKSETUP, needsRestart = False, fnc={"ifaceSupported": callFunction, "configStrings": configStrings, "WlanPluginEntry": lambda x: _("Wireless network configuration...")})