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