4.3.0r13
[enigma2.git] / usr / lib / enigma2 / python / Plugins / SystemPlugins / NetworkManager / NetworkConfig.py
1 # -*- coding: utf-8 -*-
2 from enigma import eNetworkManager, eNetworkService, eNetworkServicePtr, StringList, StringMap
3
4 from Components.Label import Label
5 from Components.ActionMap import ActionMap
6 from Components.config import getConfigListEntry, ConfigIP, ConfigOnOff, ConfigIP6, ConfigSelection, ConfigInteger
7 from Components.ConfigList import ConfigListScreen
8 from Components.Sources.List import List
9 from Components.Sources.StaticText import StaticText
10 from Components.Network import NetworkInterface
11 from Screens.Screen import Screen
12
13 from Tools.BoundFunction import boundFunction
14 from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
15 from Tools.Log import Log
16 from Tools.LoadPixmap import LoadPixmap
17
18 from netaddr import IPAddress
19
20 def toIP4List(value):
21         return [ int(v) for v in str(value).split(".") ]
22
23 def toIP4String(cfg):
24         return cfg.tostring(cfg.value)
25
26 class NetworkConfigGeneral(object):
27         @staticmethod
28         def translateSecurity(security):
29                 security_map = {
30                         "none" : _("None"),
31                         "wep"  : "WEP",
32                         "psk"  : "WPA/WPA2",
33                         "wps"  : "WPS",
34                         "ieee8021x" : "ieee8021x",
35                 }
36                 return security_map.get(security, security.upper())
37
38         @staticmethod
39         def translateState(state):
40                 state_map = {
41                         "idle" : _("Idle"),
42                         "failure" : _("Failure"),
43                         "association" : _("Association"),
44                         "configuration" : _("Configuration"),
45                         "disconnect" : _("Disconnect"),
46                         "online" : _("Connected"),
47                 }
48                 return state_map.get(state, state)
49
50         def __init__(self):
51                 self._nm = eNetworkManager.getInstance()
52                 self._nm_conn = [
53                                 self._nm.technologiesChanged.connect(self._technologiesChanged),
54                                 self._nm.stateChanged.connect(self._servicesChanged),
55                                 self._nm.servicesChanged.connect(self._servicesChanged),
56                         ]
57                 self._tech_conn = []
58                 self._services = List([], enableWrapAround = True)
59                 self._services.buildfunc = self._buildServiceListEntry
60
61         def _getCurrentService(self):
62                 service = self._services.getCurrent()
63                 if service:
64                         return service[1]
65                 return None
66         _currentService = property(_getCurrentService)
67
68         def _technologiesChanged(self):
69                 pass
70
71         def _techPoweredChanged(self, powered):
72                 if powered:
73                         self._rescan()
74
75         def _setTechPowered(self, cfg):
76                 tech = cfg.tech
77                 powered = not tech.powered()
78                 tech.setPowered(powered)
79
80         def _scanFinished(self, tech):
81                 pass
82
83         def _rescan(self, tech=None):
84                 if tech is not None and tech.type() == eNetworkService.TYPE_WIFI and tech.powered():
85                         Log.i("Triggering rescan for '%s'" %tech.name())
86                         tech.scan()
87                         return True
88
89                 res = False
90                 for tech in self._nm.getTechnologies():
91                         if tech.type() == eNetworkService.TYPE_WIFI and tech.powered():
92                                 Log.i("Triggering rescan for '%s'" %tech.name())
93                                 tech.scan()
94                                 res = True
95                 return res
96
97         def _removeService(self):
98                 service = self._currentService
99                 if isinstance(service, eNetworkServicePtr):
100                         Log.i("Removing %s" %service.name())
101                         service.setAutoConnect(False)
102                         service.remove()
103
104         def getTechnologyConfig(self):
105                 l = []
106                 techs = self._nm.getTechnologies()
107                 self._tech_conn = []
108                 for tech in techs:
109                         cfg = ConfigOnOff(default=tech.powered())
110                         cfg.tech = tech
111                         cfg.addNotifier(self._setTechPowered, initial_call=False)
112                         self._tech_conn.append(tech.poweredChanged.connect(self._techPoweredChanged))
113                         self._tech_conn.append(tech.scanFinished.connect(boundFunction(self._scanFinished, tech)))
114                         title = "%s (%s)" %(tech.name(), tech.type())
115                         l.append(getConfigListEntry(title, cfg))
116                 Log.w(l)
117                 return l
118
119         def _servicesChanged(self, *args):
120                 pass
121
122         def getServiceList(self, unified=False):
123                 l = []
124                 services = self._nm.getServices()
125                 techs = self._nm.getTechnologies()
126                 self._tech_conn = []
127                 if unified:
128                         for tech in techs:
129                                 self._tech_conn.append(tech.poweredChanged.connect(self._techPoweredChanged))
130                                 self._tech_conn.append(tech.scanFinished.connect(boundFunction(self._scanFinished, tech)))
131                                 l.append( (tech.path(), tech,) )
132                                 for service in services:
133                                         if service.type() == tech.type():
134                                                 l.append( (service.path(), service,) )
135                 else:
136                         for service in services:
137                                 l.append( (service.path(), service,) )
138                 return l
139
140         def _buildListEntry(self, path, instance):
141                 if isinstance(instance, eNetworkServicePtr):
142                         return self._buildServiceListEntry(path, instance)
143                 else:
144                         return self._buildTechnologyListEntry(path, instance)
145
146         def _buildTechnologyListEntry(self, techpath, tech):
147                 #Log.i("technology: %s/%s" %(tech.name(), tech.type()))
148                 enabled = _("on") if tech.powered() else _("off")
149                 name = tech.name()
150                 if tech.isScanning():
151                         name = _("%s - scanning...") %name
152                 return (tech.path(), None, enabled, None, None, None, name, "")
153
154         def _buildServiceListEntry(self, svcpath, service):
155                 #Log.i("service: %s/%s/%s" %(service.name(), service.type(), service.strength()))
156                 strength = ""
157                 security = ""
158                 interfacepng = None
159                 if service.type() == eNetworkService.TYPE_ETHERNET:
160                         if service.connected():
161                                 interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired-active.png"))
162                         else:
163                                 if service.state() != eNetworkManager.STATE_IDLE:
164                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired.png"))
165                                 else:
166                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired-inactive.png"))
167                 elif service.type() == eNetworkService.TYPE_WIFI:
168                         strength = "%s%s" %(service.strength(), "%")
169                         for sec in service.security():
170                                 if not security:
171                                         security = NetworkConfigGeneral.translateSecurity(sec)
172                                 else:
173                                         security = "%s, %s" %(security, NetworkConfigGeneral.translateSecurity(sec))
174                         if service.connected():
175                                 interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wireless-active.png"))
176                         else:
177                                 if service.state() != eNetworkManager.STATE_IDLE:
178                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wireless.png"))
179                                 else:
180                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wireless-inactive.png"))
181                 ip = ""
182                 if service.connected():
183                         ip = service.ipv4().get(eNetworkService.KEY_ADDRESS, "")
184                         if not ip:
185                                 ip = service.ipv6().get(eNetworkService.KEY_ADDRESS, "")
186
187                 if service.type() == eNetworkService.TYPE_BLUETOOTH:
188                         if service.connected():
189                                 interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/bluetooth-active.png"))
190                         else:
191                                 if service.state() != eNetworkManager.STATE_IDLE:
192                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/bluetooth.png"))
193                                 else:
194                                         interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/bluetooth-inactive.png"))
195
196
197                 return (service.path(), interfacepng, strength, service.name(), ip, NetworkConfigGeneral.translateState(service.state()), None, security)
198
199 class NetworkConfigGlobal(Screen, ConfigListScreen):
200         skin = """
201         <screen name="NetworkConfigGlobal" position="center,center" size="720,100" title="Network: General configuration">
202                 <widget name="config" position="10,10" size="700,80" scrollbarMode="showOnDemand" zPosition="1"/>
203         </screen>"""
204
205         def __init__(self, session):
206                 Screen.__init__(self, session)
207                 ConfigListScreen.__init__(self, [], session=session)
208
209                 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
210                 {
211                         "save": self.close,
212                         "cancel": self.close,
213                         "ok" : self.close,
214                 }, -2)
215
216                 self._nm = eNetworkManager.getInstance();
217
218                 choices_timeupdates = { eNetworkManager.TIME_UPDATES_AUTO : _("auto"), eNetworkManager.TIME_UPDATES_MANUAL : _("manual") }
219                 self._config_timeupdates = ConfigSelection(choices_timeupdates, default=self._nm.timeUpdates())
220                 self._config_timeupdates.addNotifier(self._config_changed, initial_call=False)
221                 self._createSetup()
222                 self.onLayoutFinish.append(self._layoutFinished)
223
224         def _layoutFinished(self):
225                 self.setTitle(_("Network: General configuration"))
226
227         def _config_changed(self, element):
228                 self._nm.setTimeUpdates(self._config_timeupdates.value)
229                 self._createSetup()
230
231         def _createSetup(self):
232                 lst = [getConfigListEntry(_("NTP Time Updates"), self._config_timeupdates)]
233                 self["config"].list = lst
234
235 class NetworkServiceConfig(Screen, NetworkConfigGeneral):
236         skin = """
237                 <screen name="NetworkServiceConfig" position="center,120" size="920,520" title="Network Configuration" zPosition="0">
238                         <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="140,40" alphatest="on" />
239                         <ePixmap pixmap="skin_default/buttons/green.png" position="150,5" size="140,40" alphatest="on" />
240                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="290,5" size="140,40" alphatest="on" />
241                         <ePixmap pixmap="skin_default/buttons/blue.png" position="430,5" size="140,40" alphatest="on" />
242                         <widget name="key_red" position="10,5" size="140,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
243                         <widget name="key_green" position="150,5" size="140,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
244                         <widget name="key_yellow" position="290,5" size="140,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
245                         <widget name="key_blue" position="430,5" size="140,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
246                         <eLabel position="10,50" size="560,1" backgroundColor="grey" />
247                         <widget source="list" render="Listbox" position="15,60" size="550,450" scrollbarMode="showOnDemand" zPosition="1">
248                                 <convert type="TemplatedMultiContent">
249                                         {"template":[
250                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 0), size = (50, 50), png = 1), #type icon
251                                                         MultiContentEntryText(pos = (55, 0), size = (300, 24), font=0, flags = RT_HALIGN_LEFT, text = 3), #service name
252                                                         MultiContentEntryText(pos = (360, 0), size = (180, 18), font=1, flags = RT_HALIGN_RIGHT|RT_VALIGN_BOTTOM, text = 7), #security
253                                                         MultiContentEntryText(pos = (430, 30), size = (110, 18), font=1, flags = RT_HALIGN_RIGHT|RT_VALIGN_TOP, text = 2), #signal strength
254                                                         MultiContentEntryText(pos = (55, 30), size = (220, 18), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), #ip
255                                                         MultiContentEntryText(pos = (280, 30), size = (145, 18), font=1, flags = RT_HALIGN_RIGHT|RT_VALIGN_CENTER, text = 5), #state
256                                                         MultiContentEntryText(pos = (5, 0), size = (490, 50), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 6), #technology name
257                                                 ],
258                                         "itemHeight": 50,
259                                         "fonts": [gFont("Regular", 22), gFont("Regular", 16)]
260                                         }
261                                 </convert>
262                         </widget>
263                         <ePixmap position="580,5" size="330,500" pixmap="skin_default/menu.png" zPosition="-1"/>
264                         <widget name="details_label" position="590,30" zPosition="2" size="310,25" font="Regular;22" backgroundColor="background" halign="center" transparent="1" />
265                         <widget name="details" position="590,70" zPosition="2" size="300,360" font="Regular;18" halign="center" backgroundColor="background" transparent="1" />
266                         <widget name="hint" position="590,470" zPosition="2" size="300,25" font="Regular;20" halign="center" backgroundColor="background" transparent="1" />
267                 </screen>"""
268
269         def __init__(self, session):
270                 Screen.__init__(self, session)
271                 NetworkConfigGeneral.__init__(self)
272
273                 self["key_red"] = Label(_("Reset"))
274                 self["key_green"] = Label(_("Scan"))
275                 self["key_yellow"] = Label(_("IP"))
276                 self["key_blue"] = Label(_("DNS"))
277                 self["hint"] = Label(_("Press OK to connect"))
278                 self["details_label"] = Label(_("Active Connection"))
279                 self["details"] = Label("")
280                 self["OkCancelActions"] = ActionMap(["OkCancelActions", "ColorActions", "MenuActions"],
281                 {
282                         "menu": self._menu,
283                         "cancel": self.close,
284                         "ok" : self._ok,
285                         "green": self._rescan,
286                         "red": self._removeService
287                 }, -3)
288                 self["ServiceActions"] = ActionMap(["ColorActions"],
289                 {
290                         "yellow": self._configIP,
291                         "blue": self._configDNS,
292                 }, -2)
293
294                 self["list"] = self._services
295                 self["summary_list"] = StaticText("")
296                 self._hasWireless = False
297
298                 self._services.buildfunc = self._buildListEntry
299                 self._services.onSelectionChanged.append(self._selectionChanged)
300
301                 self._addNotifiers()
302                 self._createSetup()
303
304                 self.onClose.append(self._onClose)
305                 self.onLayoutFinish.append(self.layoutFinished)
306
307         def _menu(self):
308                 self.session.open(NetworkConfigGlobal)
309
310         def _rescan(self):
311                 if not self._currentService or isinstance(self._currentService, eNetworkServicePtr):
312                         return
313                 if self._currentService.type() != eNetworkService.TYPE_WIFI:
314                         return
315                 if NetworkConfigGeneral._rescan(self, self._currentService):
316                         self._createSetup()
317
318         def _scanFinished(self, tech):
319                 Log.i("finished!")
320                 self._createSetup()
321
322         def _removeService(self):
323                 NetworkConfigGeneral._removeService(self)
324                 self._createSetup()
325
326         def _selectionChanged(self):
327                 self._checkButtons()
328                 self._updateSummary()
329
330         def _updateSummary(self):
331                 text = ""
332                 service = self._currentService
333                 if not service:
334                         self["summary_list"].setText(text)
335                         return
336                 if isinstance(service, eNetworkServicePtr):
337                         text = service.name()
338                         if service.connected():
339                                 ni = NetworkInterface(service)
340                                 ip = ni.getIpv4()
341                                 if not ip:
342                                         ip = ni.getIpv6()
343                                 if ip:
344                                         ip = ip.address
345                                 else:
346                                         ip = self.translateState(service.state())
347                                 text = "%s\n%s" %(text, ip)
348                         else:
349                                 text = "%s\n%s" %(text, self.translateState(service.state()))
350                 else:
351                         powered = _("On") if service.powered() else _("Off")
352                         text = "%s - %s" %(service.name(), powered)
353                 self["summary_list"].setText(text)
354
355         def _checkButtons(self):
356                 self["hint"].setText("")
357                 if isinstance(self._currentService, eNetworkServicePtr): #a service
358                         self["key_green"].hide()
359                         if self._currentService.connected():
360                                 self["hint"].setText(_("Press OK to disconnect"))
361                         else:
362                                 self["hint"].setText(_("Press OK to connect"))
363                         if self._currentService.favorite():
364                                 self["key_red"].show()
365                         else:
366                                 self["key_red"].hide()
367                         self["key_yellow"].show()
368                         self["key_blue"].show()
369                         self["ServiceActions"].setEnabled(True)
370                 else: #a technology
371                         if self._currentService and self._currentService.type() == eNetworkService.TYPE_WIFI:
372                                 self["key_green"].show()
373                         else:
374                                 self["key_green"].hide()
375                         self["key_red"].hide()
376                         if self._currentService:
377                                 if self._currentService.powered():
378                                         self["hint"].setText(_("Press OK to disable"))
379                                 else:
380                                         self["hint"].setText(_("Press OK to enable"))
381                         else:
382                                 self["hint"].setText("")
383                         self["key_yellow"].hide()
384                         self["key_blue"].hide()
385                         self["ServiceActions"].setEnabled(False)
386
387         def _configChanged(self, *args, **kwargs):
388                 self._createSetup()
389
390         def _configIP(self):
391                 service = self._currentService
392                 if service:
393                         self.session.open(NetworkServiceIPConfig, service)
394
395         def _configDNS(self):
396                 service = self._currentService
397                 if service:
398                         self.session.open(NetworkServiceNSConfig, service)
399
400         def _technologiesChanged(self):
401                 self._createSetup()
402
403         def _servicesChanged(self, *args):
404                 self._createSetup()
405
406         def _addNotifiers(self):
407                 pass
408
409         def _removeNotifiers(self):
410                 pass
411
412         def _onClose(self):
413                 self._removeNotifiers()
414
415         def keyLeft(self):
416                 ConfigListScreen.keyLeft(self)
417
418         def keyRight(self):
419                 ConfigListScreen.keyRight(self)
420
421         def _ok(self):
422                 item = self._currentService
423                 if not item:
424                         return
425                 if isinstance(item, eNetworkServicePtr):
426                         state = item.state()
427                         Log.i(state)
428                         if state == eNetworkManager.STATE_IDLE or state == eNetworkManager.STATE_FAILURE:
429                                 item.requestDisconnect()
430                                 item.requestConnect()
431                                 item.setAutoConnect(True)
432                         else:
433                                 item.requestDisconnect()
434                 else:
435                         item.setPowered(not item.powered())
436
437         def _createSetup(self):
438                 self._hasWireless = False
439                 for tech in self._nm.getTechnologies():
440                         if tech.type() == eNetworkService.TYPE_WIFI and tech.powered():
441                                 self._hasWireless = True
442                 self._services.updateList(self.getServiceList(unified=True))
443                 self._checkButtons()
444                 self._setDetailText()
445
446         def _setDetailText(self):
447                 text = ""
448                 for service in self._nm.getServices():
449                         if service.connected():
450                                 if text:
451                                         text = "\n\n%s" %(text)
452
453                                 text = "%s\n\n" %(service.name())
454                                 ni = NetworkInterface(service)
455
456                                 ip4 = ni.getIpv4()
457                                 ip6 = ni.getIpv6()
458                                 iptext = _("%s IPv%s\n  Address: %s\n  %s: %s\n  Gateway: %s\n\n")
459                                 #IPv4
460                                 if ip4.method != eNetworkService.METHOD_OFF:
461                                         addr = ip4.address
462                                         mask = ip4.netmask
463                                         gw = ip4.gateway
464                                         text = iptext %(
465                                                         text,
466                                                         4,
467                                                         addr,
468                                                         _("Netmask"),
469                                                         mask,
470                                                         gw,
471                                                 )
472                                 #IPv6
473                                 if ip6.method != eNetworkService.METHOD_OFF:
474                                         addr = ip6.address
475                                         mask = ip6.netmask
476                                         gw = ip6.gateway
477                                         text = iptext %(
478                                                         text,
479                                                         6,
480                                                         addr,
481                                                         _("Prefix length"),
482                                                         mask,
483                                                         gw,
484                                                 )
485                                 ns = self._textFormatIpList( service.nameservers() )
486                                 text = _("%sNameserver\n%s\n") %(text, ns) or _("n/a")
487                                 ts = self._textFormatIpList( service.timeservers() )
488                                 text = _("%s\nTimeserver\n%s\n") %(text, ts)
489
490                                 mac = ni.ethernet.mac
491                                 text = ("%s\n" + _("Hardware address") + "\n%s\n") %(text, mac)
492                                 break
493                 self["details"].setText(text)
494
495         def _textFormatIpList(self, iplist):
496                 if not iplist:
497                         return "  %s" %(_("n/a"))
498                 iplist = "  %s" %("\n  ".join(iplist))
499                 return iplist
500
501         def _techPoweredChanged(self, powered):
502                 if powered:
503                         self._rescan()
504                 self._createSetup()
505
506         def layoutFinished(self):
507                 self.setTitle(_("Network Config"))
508                 self._checkButtons()
509                 self._updateSummary()
510
511 class ServiceBoundConfiguration(object):
512         def __init__(self, service):
513                 self._service = service
514                 nm = eNetworkManager.getInstance()
515                 self._svcRemovedConn = nm.serviceRemoved.connect(self.__onServiceRemoved)
516                 self._isServiceRemoved = False
517
518         def __onServiceRemoved(self, svcpath):
519                 if svcpath == self._service.path():
520                         Log.i("Service '%s' removed. Closing..." %svcpath)
521                         self._isServiceRemoved = True
522                         #TODO show a messagebox! The user will be VERY confused otherwise!
523                         self.close()
524
525 class ServiceIPConfiguration(object):
526         def __init__(self, service):
527                 self._service = service
528                 self.onChanged = []
529                 self.onMethodChanged = []
530                 method_choices_ip4 = {eNetworkService.METHOD_DHCP : "dhcp", eNetworkService.METHOD_MANUAL : _("manual"), eNetworkService.METHOD_OFF : _("off")}
531                 #IPv4
532                 self._config_ip4_method = ConfigSelection(method_choices_ip4, default=eNetworkService.METHOD_DHCP)
533                 self._config_ip4_address = ConfigIP(default=[0,0,0,0])
534                 self._config_ip4_mask = ConfigIP(default=[0,0,0,0])
535                 self._config_ip4_gw = ConfigIP(default=[0,0,0,0])
536                 #IPv6
537                 method_choices_ip6 = {eNetworkService.METHOD_AUTO : _("auto"), eNetworkService.METHOD_6TO4 : "6to4", eNetworkService.METHOD_MANUAL : _("manual"), eNetworkService.METHOD_OFF : _("off")}
538                 choices_privacy_ip6 = {eNetworkService.IPV6_PRIVACY_DISABLED : _("Disabled"), eNetworkService.IPV6_PRIVACY_ENABLED : _("Enabled"), eNetworkService.IPV6_PRIVACY_PREFERRED : _("Preferred")}
539                 self._config_ip6_method = ConfigSelection(method_choices_ip6, default=eNetworkService.METHOD_DHCP)
540                 self._config_ip6_address = ConfigIP6()
541                 self._config_ip6_prefix_length = ConfigInteger(0, limits=(1, 128))
542                 self._config_ip6_gw = ConfigIP6()
543                 self._config_ip6_privacy = ConfigSelection(choices_privacy_ip6, default="disabled")
544
545                 self._isReloading = False
546                 self._ipv4Changed = False
547                 self._ipv6Changed = False
548                 self._addNotifiers()
549                 self._service_conn = [
550                         self._service.ipv4Changed.connect(self._serviceChanged),
551                         self._service.ipv6Changed.connect(self._serviceChanged),
552                         self._service.ipv4ConfigChanged.connect(self._serviceChanged),
553                         self._service.ipv6ConfigChanged.connect(self._serviceChanged),
554                 ]
555
556         def _serviceChanged(self, *args):
557                 self.reload(force=False)
558
559         def _addNotifiers(self):
560                 #Setup refresh
561                 self._config_ip4_method.addNotifier(self._methodChanged, initial_call=False)
562                 self._config_ip6_method.addNotifier(self._methodChanged, initial_call=False)
563
564                 #change tracking
565                 #ipv4
566                 self._config_ip4_method.addNotifier(self._changedIP4, initial_call=False)
567                 self._config_ip4_address.addNotifier(self._changedIP4, initial_call=False)
568                 self._config_ip4_mask.addNotifier(self._changedIP4, initial_call=False)
569                 self._config_ip4_gw.addNotifier(self._changedIP4, initial_call=False)
570                 #ipv6
571                 self._config_ip6_method.addNotifier(self._changedIP6, initial_call=False)
572                 self._config_ip6_address.addNotifier(self._changedIP6, initial_call=False)
573                 self._config_ip6_prefix_length.addNotifier(self._changedIP6, initial_call=False)
574                 self._config_ip6_gw.addNotifier(self._changedIP6, initial_call=False)
575                 self._config_ip6_privacy.addNotifier(self._changedIP6, initial_call=False)
576
577         def _changedIP4(self, element):
578                 if not self._isReloading:
579                         self._ipv4Changed = True
580                 self._changed(element)
581
582         def _changedIP6(self, element):
583                 if not self._isReloading:
584                         self._ipv6Changed = True
585                 self._changed(element)
586
587         def _changed(self, element):
588                 if not self._isReloading:
589                         Log.i()
590                         for fnc in self.onChanged:
591                                 fnc()
592
593         def _methodChanged(self, element):
594                 if not self._isReloading:
595                         Log.i()
596                         for fnc in self.onMethodChanged:
597                                 fnc()
598
599         def reload(self, force=True):
600                 self._isReloading = True
601                 if force:
602                         self._ipv4Changed = False
603                         self._ipv6Changed = False
604                 if not self._ipv6Changed:
605                         ip4 = self._service.ipv4()
606                         if not dict(ip4):
607                                 ip6 = self._service.ipv4Config()
608                         self._config_ip4_method.value = ip4.get(eNetworkService.KEY_METHOD, eNetworkService.METHOD_OFF)
609                         self._config_ip4_address.value = toIP4List( ip4.get("Address", "0.0.0.0") )
610                         self._config_ip4_mask.value = toIP4List( ip4.get(eNetworkService.KEY_NETMASK, "0.0.0.0") )
611                         self._config_ip4_gw.value = toIP4List( ip4.get(eNetworkService.KEY_GATEWAY, "0.0.0.0") )
612                 if not self._ipv6Changed:
613                         ip6 = self._service.ipv6()
614                         Log.i("%s / %s" %(dict(ip6), dict(self._service.ipv6Config())) )
615                         if not dict(ip6):
616                                 ip6 = self._service.ipv6Config()
617                         self._config_ip6_method.value = ip6.get(eNetworkService.KEY_METHOD, eNetworkService.METHOD_OFF)
618                         self._config_ip6_address.value = ip6.get(eNetworkService.KEY_ADDRESS, "::")
619                         self._config_ip6_prefix_length.value = ord( ip6.get(eNetworkService.KEY_PREFIX_LENGTH, chr(1)) )
620                         self._config_ip6_gw.value = ip6.get(eNetworkService.KEY_GATEWAY, "::")
621                         self._config_ip6_privacy.value = ip6.get(eNetworkService.KEY_PRIVACY, eNetworkService.IPV6_PRIVACY_DISABLED)
622                 self._isReloading = False
623                 self._changed(None)
624
625         def getList(self):
626                 if self._config_ip4_method.value == eNetworkService.METHOD_MANUAL:
627                         self._config_ip4_address.enabled = True
628                         self._config_ip4_mask.enabled = True
629                         self._config_ip4_gw.enabled = True
630                 else:
631                         self._config_ip4_address.enabled = False
632                         self._config_ip4_mask.enabled = False
633                         self._config_ip4_gw.enabled = False
634                 if self._config_ip6_method.value == eNetworkService.METHOD_MANUAL:
635                         self._config_ip6_address.enabled = True
636                         self._config_ip6_prefix_length.enabled = True
637                         self._config_ip6_gw.enabled = True
638                 else:
639                         self._config_ip6_address.enabled = False
640                         self._config_ip6_prefix_length.enabled = False
641                         self._config_ip6_gw.enabled = False
642
643                 l = [ getConfigListEntry(_("Method (IPv4)"), self._config_ip4_method), ]
644                 if self._config_ip4_method.value != eNetworkService.METHOD_OFF:
645                         l.extend([
646                                 getConfigListEntry(_("Address (IPv4)"), self._config_ip4_address),
647                                 getConfigListEntry(_("Mask (IPv4)"), self._config_ip4_mask),
648                                 getConfigListEntry(_("Gateway (IPv4)"), self._config_ip4_gw),
649                         ])
650                 l.append( getConfigListEntry(_("Method (IPv6)"), self._config_ip6_method))
651                 if self._config_ip6_method.value != eNetworkService.METHOD_OFF:
652                         l.extend([
653                                 getConfigListEntry(_("Address (IPv6)"), self._config_ip6_address),
654                                 getConfigListEntry(_("Prefix length (IPv6)"), self._config_ip6_prefix_length),
655                                 getConfigListEntry(_("Gateway (IPv6)"), self._config_ip6_gw),
656                         ])
657                 if self._config_ip6_method.value in (eNetworkService.METHOD_AUTO, eNetworkService.METHOD_6TO4):
658                         l.append( getConfigListEntry(_("Privacy (IPv6)"), self._config_ip6_privacy) )
659                 return l
660
661         def save(self):
662                 if self._ipv4Changed:
663                         Log.i("IPv4 Changed, saving!")
664                         if self._config_ip4_method.value == eNetworkService.METHOD_MANUAL:
665                                 ip4_config = {
666                                                 eNetworkService.KEY_METHOD : self._config_ip4_method.value,
667                                                 eNetworkService.KEY_ADDRESS : toIP4String(self._config_ip4_address),
668                                                 eNetworkService.KEY_NETMASK : toIP4String(self._config_ip4_mask),
669                                                 eNetworkService.KEY_GATEWAY : toIP4String(self._config_ip4_gw),
670                                         }
671                         else:
672                                 ip4_config = { eNetworkService.KEY_METHOD : self._config_ip4_method.value }
673                         Log.i(ip4_config)
674                         self._service.setIpv4Config(StringMap(ip4_config))
675
676                 if self._ipv6Changed:
677                         Log.i("IPv6 Changed, saving!")
678                         if self._config_ip6_method.value == eNetworkService.METHOD_MANUAL:
679                                 ip6_config = {
680                                                 eNetworkService.KEY_METHOD : self._config_ip6_method.value,
681                                                 eNetworkService.KEY_ADDRESS : self._config_ip6_address.value,
682                                                 eNetworkService.KEY_PREFIX_LENGTH : self._config_ip6_prefix_length.value,
683                                                 eNetworkService.KEY_GATEWAY : self._config_ip6_gw.value,
684                                                 eNetworkService.KEY_PRIVACY : self._config_ip6_privacy.value,
685                                         }
686                         else:
687                                 val = self._config_ip6_method.value #avoid config element overhead here
688                                 #one can not configure 6to4, it will automatically be applied by connman if applicable -> change it to auto
689                                 if val == eNetworkService.METHOD_6TO4:
690                                         val = eNetworkService.METHOD_AUTO
691
692                                 ip6_config = { eNetworkService.KEY_METHOD : val }
693                                 if val != eNetworkService.METHOD_OFF:
694                                         ip6_config[eNetworkService.KEY_PRIVACY] = self._config_ip6_privacy.value
695                         Log.i(ip6_config)
696                         self._service.setIpv6Config(StringMap(ip6_config))
697
698 class NetworkServiceIPConfig(ConfigListScreen, Screen, ServiceBoundConfiguration):
699         skin = """
700                 <screen name="NetworkServiceIPConfig" position="center,120" size="820,520" title="Network: Service configuration">
701                         <!--
702                         <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
703                         <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40" alphatest="on" />
704                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="410,5" size="200,40" alphatest="on" />
705                         -->
706                         <ePixmap pixmap="skin_default/buttons/blue.png" position="610,5" size="200,40" alphatest="on" />
707                         <!--
708                         <widget source="key_red" render="Label" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
709                         <widget source="key_green" render="Label" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
710                         <widget source="key_yellow" render="Label" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
711                         -->
712                         <widget source="key_blue" render="Label" position="610,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
713                         <eLabel position="10,50" size="800,1" backgroundColor="grey" />
714                         <widget name="config" position="10,60" size="800,450" enableWrapAround="1" scrollbarMode="showOnDemand" />
715                 </screen>"""
716
717         def __init__(self, session, service):
718                 Screen.__init__(self, session)
719                 ConfigListScreen.__init__(self, [], session=session)
720                 ServiceBoundConfiguration.__init__(self, service)
721
722                 self["key_blue"] = StaticText(_("Reset"))
723                 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
724                 {
725                         "blue": self._reload,
726                         "save": self.close,
727                         "cancel": self.close,
728                         "ok" : self.close,
729                 }, -2)
730
731                 self._ipconfig = ServiceIPConfiguration(self._service)
732                 self._ipconfig.onMethodChanged.append(self._createSetup)
733                 self._noSave = False
734
735                 self._reload()
736                 self.onClose.append(self.__onClose)
737
738         def __onClose(self):
739                 self._ipconfig.onMethodChanged.remove(self._createSetup)
740                 self._apply()
741                 del self._ipconfig
742
743         def _apply(self):
744                 if self._isServiceRemoved:
745                         return
746                 self._ipconfig.save()
747
748         def _reload(self):
749                 self._ipconfig.reload()
750                 self._createSetup()
751
752         def _createSetup(self):
753                 self["config"].list = self._ipconfig.getList()
754
755 class ServiceNSConfiguration(object):
756         def __init__(self, service):
757                 self._service = service
758                 self.onChanged = []
759                 self._nameservers = []
760
761         def reload(self):
762                 self._nameservers = []
763                 ns = self._service.nameserversConfig()
764                 for n in ns:
765                         ip = IPAddress(n)
766                         if ip.version == 4:
767                                 cfg = ConfigIP( default=toIP4List(ip.format()))
768                                 self._nameservers.append(cfg)
769                         elif ip.version == 6:
770                                 cfg = ConfigIP6(default=ip.format())
771                                 self._nameservers.append(cfg)
772
773         def getList(self):
774                 return [ getConfigListEntry("Nameserver", ns) for ns in self._nameservers ]
775
776         def add4(self):
777                 self._nameservers.append(ConfigIP([0,0,0,0]))
778
779         def add6(self):
780                 self._nameservers.append(ConfigIP6())
781
782         def remove(self, cfg):
783                 self._nameservers.remove(cfg)
784
785         def save(self):
786                 servers = []
787                 for nscfg in self._nameservers:
788                         if isinstance(nscfg, ConfigIP):
789                                 servers.append(toIP4String(nscfg))
790                         elif isinstance(nscfg, ConfigIP6):
791                                 servers.append(nscfg.value)
792                 self._service.setNameserversConfig(StringList(servers))
793
794 class NetworkServiceNSConfig(ConfigListScreen, Screen, ServiceBoundConfiguration):
795         skin = """
796                 <screen name="NetworkServiceNSConfig" position="center,120" size="820,520" title="Service: Nameserver configuration">
797                         <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
798                         <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40" alphatest="on" />
799                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="410,5" size="200,40" alphatest="on" />
800                         <ePixmap pixmap="skin_default/buttons/blue.png" position="610,5" size="200,40" alphatest="on" />
801                         <widget source="key_red" render="Label" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
802                         <widget source="key_green" render="Label" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
803                         <widget source="key_yellow" render="Label" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
804                         <widget source="key_blue" render="Label" position="610,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
805                         <eLabel position="10,50" size="800,1" backgroundColor="grey" />
806                         <widget name="config" position="10,60" size="800,360" enableWrapAround="1" scrollbarMode="showOnDemand" />
807                         <eLabel position="10,430" size="800,1" backgroundColor="grey" />
808                         <widget source="activedns" render="Label" position="10,440" size="800,75" font="Regular;20" valign="bottom"/>
809                 </screen>"""
810
811         def __init__(self, session, service):
812                 Screen.__init__(self, session)
813                 ConfigListScreen.__init__(self, [], session=session)
814                 ServiceBoundConfiguration.__init__(self, service)
815
816                 self["key_red"] = StaticText(_("Delete"))
817                 self["key_green"] = StaticText(_("New (IPv4)"))
818                 self["key_yellow"] = StaticText(_("New (IPv6)"))
819                 self["key_blue"] = StaticText(_("Reset"))
820                 self["activedns"] = StaticText(self.getActiveDnsText())
821                 self["setupActions"] = ActionMap(["OkCancelActions", "ColorActions"],
822                 {
823                         "red": self._remove,
824                         "green": self._add4,
825                         "yellow": self._add6,
826                         "blue": self._reload,
827                         "save": self.close,
828                         "cancel": self.close,
829                         "ok" : self.close,
830                 }, -2)
831
832                 self._nsconfig = ServiceNSConfiguration(self._service)
833                 self._reload()
834                 self.onClose.append(self.__onClose)
835                 self.onLayoutFinish.append(self._layoutFinished)
836
837         def getActiveDnsText(self):
838                 nameservers = list(self._service.nameservers())
839                 text = ""
840                 if nameservers:
841                         text = _("Active Nameservers:\n%s") %(", ".join(nameservers))
842                         Log.i(text)
843                 return text
844
845         def _layoutFinished(self):
846                 self.setTitle(_("%s Network - Nameservers" %self._service.name()))
847
848         def _remove(self):
849                 cfg = self["config"].getCurrent()
850                 if cfg:
851                         self._nsconfig.remove(cfg[1])
852                         self._createSetup()
853
854         def _add4(self):
855                 self._nsconfig.add4()
856                 self._createSetup()
857
858         def _add6(self):
859                 self._nsconfig.add6()
860                 self._createSetup()
861
862         def __onClose(self):
863                 if self._isServiceRemoved:
864                         return
865                 self._nsconfig.save()
866
867         def _reload(self):
868                 self._nsconfig.reload()
869                 self._createSetup()
870
871         def _createSetup(self):
872                 self["config"].setList( self._nsconfig.getList() )