From 0ee299dd7a8f6ab9d32d65f7b18f47d5e0dd30ca Mon Sep 17 00:00:00 2001 From: Mladen Horvat Date: Wed, 30 Mar 2011 09:48:29 +0200 Subject: [PATCH] Network.py/NetworkSetup.py: improve wireless lan device detection. Dont depend on device names where possible. Some code cleanups and improvements for wlan devices. refs #389 --- lib/python/Components/Network.py | 83 +++++++------ lib/python/Screens/NetworkSetup.py | 189 +++++++++++------------------ 2 files changed, 119 insertions(+), 153 deletions(-) diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py index 46c7571d..f38ee515 100755 --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -76,14 +76,14 @@ class Network: globalIPpattern = re_compile("scope global") ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' netRegexp = '[0-9]{1,2}' - macRegexp = '[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}' + macRegexp = '[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}' ipLinePattern = re_compile('inet ' + ipRegexp + '/') ipPattern = re_compile(ipRegexp) netmaskLinePattern = re_compile('/' + netRegexp) netmaskPattern = re_compile(netRegexp) bcastLinePattern = re_compile(' brd ' + ipRegexp) upPattern = re_compile('UP') - macPattern = re_compile('[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}') + macPattern = re_compile(macRegexp) macLinePattern = re_compile('link/ether ' + macRegexp) for line in result.splitlines(): @@ -160,7 +160,7 @@ class Network: fp.write(iface["preup"]) if iface["predown"] is not False and not iface.has_key("configStrings"): fp.write(iface["predown"]) - fp.write("\n") + fp.write("\n") fp.close() self.configuredNetworkAdapters = self.configuredInterfaces self.writeNameserverConfig() @@ -253,6 +253,9 @@ class Network: print "nameservers:", self.nameservers + def getInstalledAdapters(self): + return [x for x in listdir('/sys/class/net') if not x in ('lo','wifi0', 'wmaster0')] + def getConfiguredAdapters(self): return self.configuredNetworkAdapters @@ -286,13 +289,7 @@ class Network: if not self.isWirelessInterface(iface): return _('Ethernet network interface') - moduledir = self.sysfsPath(iface) + '/device/driver/module' - if not os_path.isdir(moduledir): - tmpfiles = listdir(self.sysfsPath(iface) + '/device') - for x in tmpfiles: - if x.startswith("1-"): - moduledir = self.sysfsPath(iface) + '/device/' + x + '/driver/module' - + moduledir = self.getWlanModuleDir(iface) if os_path.isdir(moduledir): name = os_path.basename(os_path.realpath(moduledir)) if name in ('ath_pci','ath5k'): @@ -301,6 +298,8 @@ class Network: name = 'Ralink' elif name == 'zd1211b': name = 'Zydas' + elif name == 'r871x_usb_drv': + name = 'Realtek' else: name = _('Unknown') @@ -539,31 +538,27 @@ class Network: self.config_ready = False self.msgPlugins() commands = [] + def buildCommands(iface): + commands.append("ifdown " + iface) + commands.append("ip addr flush dev " + iface) + # HACK: wpa_supplicant sometimes doesn't quit properly on SIGTERM + if os_path.exists('/var/run/wpa_supplicant/'+ iface): + commands.append("wpa_cli -i" + iface + " terminate") + if not self.deactivateInterfaceConsole: self.deactivateInterfaceConsole = Console() + if isinstance(ifaces, (list, tuple)): for iface in ifaces: if iface != 'eth0' or not self.onRemoteRootFS(): - commands.append("ifdown " + iface) - commands.append("ip addr flush dev " + iface) - # HACK: wpa_supplicant sometimes doesn't quit properly on SIGTERM - if os_path.exists('/var/run/wpa_supplicant/'+ iface): - commands.append("killall -9 wpa_supplicant") - commands.append("rm -rf /var/run/wpa_supplicant/" + iface) - self.deactivateInterfaceConsole.eBatch(commands, self.deactivateInterfaceFinished, callback, debug=True) + buildCommands(iface) else: - iface = ifaces - if iface == 'eth0' and self.onRemoteRootFS(): + if ifaces == 'eth0' and self.onRemoteRootFS(): if callback is not None: callback(True) return - commands.append("ifdown " + iface) - commands.append("ip addr flush dev " + iface) - # HACK: wpa_supplicant sometimes doesn't quit properly on SIGTERM - if os_path.exists('/var/run/wpa_supplicant/'+ iface): - commands.append("killall -9 wpa_supplicant") - commands.append("rm -rf /var/run/wpa_supplicant/" + iface) - self.deactivateInterfaceConsole.eBatch(commands, self.deactivateInterfaceFinished, callback, debug=True) + buildCommands(ifaces) + self.deactivateInterfaceConsole.eBatch(commands, self.deactivateInterfaceFinished, callback, debug=True) def deactivateInterfaceFinished(self,extra_args): callback = extra_args @@ -594,7 +589,31 @@ class Network: return '/sys/class/net/' + iface def isWirelessInterface(self, iface): - return os_path.isdir(self.sysfsPath(iface) + '/wireless') + if os_path.isdir(self.sysfsPath(iface) + '/wireless'): + return True + else: + ifaces = file('/proc/net/wireless').read().strip() + if iface in ifaces: + return True + else: + return False + + def getWlanModuleDir(self, iface = None): + devicedir = self.sysfsPath(iface) + '/device' + moduledir = devicedir + '/driver/module' + if not os_path.isdir(moduledir): + tmpfiles = listdir(devicedir) + moduledir_found = False + for x in tmpfiles: + if x.startswith("1-"): + moduledir_found = True + moduledir = devicedir + '/' + x + '/driver/module' + if not moduledir_found: + moduledir_found = True + if os_path.isdir(devicedir + '/driver'): + moduledir = devicedir + '/driver' + + return moduledir def detectWlanModule(self, iface = None): if not self.isWirelessInterface(iface): @@ -604,13 +623,7 @@ class Network: if os_path.isdir(devicedir + '/ieee80211'): return 'nl80211' - moduledir = devicedir + "/driver/module" - if not os_path.isdir(moduledir): - tmpfiles = listdir(devicedir) - for x in tmpfiles: - if x.startswith("1-"): - moduledir = devicedir + "/" + x + "/driver/module" - + moduledir = self.getWlanModuleDir(iface) if os_path.isdir(moduledir): module = os_path.basename(os_path.realpath(moduledir)) if module in ('ath_pci','ath5k'): @@ -619,8 +632,6 @@ class Network: return 'ralink' if module == 'zd1211b': return 'zydas' - if module in ('rt3070sta'): - return 'wext' return 'wext' def calc_netmask(self,nmask): diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py index 96a4c20c..5d378524 100755 --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -42,11 +42,6 @@ class NetworkAdapterSelection(Screen,HelpableScreen): self["key_blue"] = StaticText("") self["introduction"] = StaticText(self.edittext) - self.adapters = [(iNetwork.getFriendlyAdapterName(x),x) for x in iNetwork.getAdapterList()] - - if not self.adapters: - self.onFirstExecBegin.append(self.NetworkFallback) - self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", { "cancel": (self.close, _("exit network interface list")), @@ -65,6 +60,14 @@ class NetworkAdapterSelection(Screen,HelpableScreen): "yellow": (self.setDefaultInterface, [_("Set interface as default Interface"),_("* Only available if more than one interface is active.")] ), }) + self.adapters = [(iNetwork.getFriendlyAdapterName(x),x) for x in iNetwork.getAdapterList()] + + if not self.adapters: + self.adapters = [(iNetwork.getFriendlyAdapterName(x),x) for x in iNetwork.getConfiguredAdapters()] + + if len(self.adapters) == 0: + self.adapters = [(iNetwork.getFriendlyAdapterName(x),x) for x in iNetwork.getInstalledAdapters()] + self.list = [] self["list"] = List(self.list) self.updateList() @@ -80,14 +83,14 @@ class NetworkAdapterSelection(Screen,HelpableScreen): description = None interfacepng = None - if iface in iNetwork.lan_interfaces: + if not iNetwork.isWirelessInterface(iface): if active is True: interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired-active.png")) elif active is False: interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired-inactive.png")) else: interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wired.png")) - elif iface in iNetwork.wlan_interfaces: + elif iNetwork.isWirelessInterface(iface): if active is True: interfacepng = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/network_wireless-active.png")) elif active is False: @@ -132,19 +135,16 @@ class NetworkAdapterSelection(Screen,HelpableScreen): fp.close() default_gw = result - if len(self.adapters) == 0: # no interface available => display only eth0 - self.list.append(self.buildInterfaceList("eth0",iNetwork.getFriendlyAdapterName('eth0'),True,True )) - else: - for x in self.adapters: - if x[1] == default_gw: - default_int = True - else: - default_int = False - if iNetwork.getAdapterAttribute(x[1], 'up') is True: - active_int = True - else: - active_int = False - self.list.append(self.buildInterfaceList(x[1],_(x[0]),default_int,active_int )) + for x in self.adapters: + if x[1] == default_gw: + default_int = True + else: + default_int = False + if iNetwork.getAdapterAttribute(x[1], 'up') is True: + active_int = True + else: + active_int = False + self.list.append(self.buildInterfaceList(x[1],_(x[0]),default_int,active_int )) if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): self["key_blue"].setText(_("NetworkWizard")) @@ -179,26 +179,6 @@ class NetworkAdapterSelection(Screen,HelpableScreen): else: self.updateList() - def NetworkFallback(self): - if iNetwork.configuredNetworkAdapters.has_key('wlan0') is True: - self.session.openWithCallback(self.ErrorMessageClosed, MessageBox, self.wlan_errortext, type = MessageBox.TYPE_INFO,timeout = 10) - if iNetwork.configuredNetworkAdapters.has_key('ath0') is True: - self.session.openWithCallback(self.ErrorMessageClosed, MessageBox, self.wlan_errortext, type = MessageBox.TYPE_INFO,timeout = 10) - if iNetwork.configuredNetworkAdapters.has_key('ra0') is True: - self.session.openWithCallback(self.ErrorMessageClosed, MessageBox, self.wlan_errortext, type = MessageBox.TYPE_INFO,timeout = 10) - else: - self.session.openWithCallback(self.ErrorMessageClosed, MessageBox, self.lan_errortext, type = MessageBox.TYPE_INFO,timeout = 10) - - def ErrorMessageClosed(self, *ret): - if iNetwork.configuredNetworkAdapters.has_key('wlan0') is True: - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, 'wlan0') - elif iNetwork.configuredNetworkAdapters.has_key('ath0') is True: - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, 'ath0') - elif iNetwork.configuredNetworkAdapters.has_key('ra0') is True: - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, 'ra0') - else: - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, 'eth0') - def cleanup(self): iNetwork.stopLinkStateConsole() iNetwork.stopRestartConsole() @@ -427,10 +407,11 @@ class AdapterSetup(Screen, ConfigListScreen, HelpableScreen): self.wsconfig = None self.default = None - if self.iface in iNetwork.wlan_interfaces: - from Plugins.SystemPlugins.WirelessLan.Wlan import wpaSupplicant,Wlan - self.w = Wlan(self.iface) - self.ws = wpaSupplicant(self.iface) + if iNetwork.isWirelessInterface(self.iface): + from Plugins.SystemPlugins.WirelessLan.Wlan import wpaSupplicant, iWlan + iWlan.setInterface(self.iface) + self.w = iWlan.getInterface() + self.ws = wpaSupplicant() self.encryptionlist = [] self.encryptionlist.append(("WEP", _("WEP"))) self.encryptionlist.append(("WPA", _("WPA"))) @@ -446,7 +427,7 @@ class AdapterSetup(Screen, ConfigListScreen, HelpableScreen): self.nwlist = [] self.aps = None try: - self.aps = self.w.getNetworkList() + self.aps = iWlan.getNetworkList() if self.aps is not None: for ap in self.aps: a = self.aps[ap] @@ -454,10 +435,11 @@ class AdapterSetup(Screen, ConfigListScreen, HelpableScreen): if a['essid'] != '': self.nwlist.append((a['essid'],a['essid'])) self.nwlist.sort(key = lambda x: x[0]) + iWlan.stopGetNetworkList() except: self.nwlist.append(("No Networks found",_("No Networks found"))) - self.wsconfig = self.ws.loadConfig() + self.wsconfig = self.ws.loadConfig(self.iface) if self.essid is not None: # ssid from wlan scan self.default = self.essid else: @@ -550,7 +532,7 @@ class AdapterSetup(Screen, ConfigListScreen, HelpableScreen): self.createSetup() if self["config"].getCurrent() == self.gatewayEntry: self.createSetup() - if self.iface in iNetwork.wlan_interfaces: + if iNetwork.isWirelessInterface(self.iface): if self["config"].getCurrent() == self.wlanSSID: self.createSetup() if self["config"].getCurrent() == self.encryptionEnabled: @@ -617,7 +599,7 @@ class AdapterSetup(Screen, ConfigListScreen, HelpableScreen): iNetwork.removeAdapterAttribute(self.iface, "gateway") if self.extended is not None and self.configStrings is not None: iNetwork.setAdapterAttribute(self.iface, "configStrings", self.configStrings(self.iface)) - self.ws.writeConfig() + self.ws.writeConfig(self.iface) if self.activateInterfaceEntry.value is False: iNetwork.deactivateInterface(self.iface,self.deactivateInterfaceCB) @@ -723,7 +705,8 @@ class AdapterSetupConfiguration(Screen, HelpableScreen): self.oktext = _("Press OK on your remote control to continue.") self.reboottext = _("Your Dreambox will restart after pressing OK on your remote control.") - self.errortext = _("No working wireless network interface found.\n Please verify that you have attached a compatible WLAN device or enable your local network interface.") + self.errortext = _("No working wireless network interface found.\n Please verify that you have attached a compatible WLAN device or enable your local network interface.") + self.missingwlanplugintxt = _("The wireless LAN plugin is not installed!\nPlease install it.") self["WizardActions"] = HelpableActionMap(self, "WizardActions", { @@ -759,31 +742,39 @@ class AdapterSetupConfiguration(Screen, HelpableScreen): self.onLayoutFinish.append(self.layoutFinished) self.onClose.append(self.cleanup) + + def queryWirelessDevice(self,iface): + try: + from pythonwifi.iwlibs import Wireless + import errno + except ImportError: + return False + else: + try: + ifobj = Wireless(iface) # a Wireless NIC Object + wlanresponse = ifobj.getAPaddr() + except IOError, (error_no, error_str): + if error_no in (errno.EOPNOTSUPP, errno.EINVAL, errno.ENODEV, errno.EPERM): + return False + else: + print "error: ",error_no,error_str + return True + else: + return True + def ok(self): self.cleanup() if self["menulist"].getCurrent()[1] == 'edit': - if self.iface in iNetwork.wlan_interfaces: + if iNetwork.isWirelessInterface(self.iface): try: from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan - from pythonwifi.iwlibs import Wireless except ImportError: - self.session.open(MessageBox, _("The wireless LAN plugin is not installed!\nPlease install it."), type = MessageBox.TYPE_INFO,timeout = 10 ) + self.session.open(MessageBox, self.missingwlanplugintxt, type = MessageBox.TYPE_INFO,timeout = 10 ) else: - ifobj = Wireless(self.iface) # a Wireless NIC Object - wlanresponse = None - try: - wlanresponse = ifobj.getAPaddr() - except IOError, (errno, strerror): - wlanresponse = (errno,strerror) - if wlanresponse: - if wlanresponse[0] not in (19,95): # 19 = 'No such device', 95 = 'Operation not supported' - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup,self.iface) - else: - # Display Wlan not available Message - self.showErrorMessage() + if self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup,self.iface) else: - # Display Wlan not available Message - self.showErrorMessage() + self.showErrorMessage() # Display Wlan not available Message else: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup,self.iface) if self["menulist"].getCurrent()[1] == 'test': @@ -793,47 +784,23 @@ class AdapterSetupConfiguration(Screen, HelpableScreen): if self["menulist"].getCurrent()[1] == 'scanwlan': try: from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan - from pythonwifi.iwlibs import Wireless except ImportError: - self.session.open(MessageBox, _("The wireless LAN plugin is not installed!\nPlease install it."), type = MessageBox.TYPE_INFO,timeout = 10 ) + self.session.open(MessageBox, self.missingwlanplugintxt, type = MessageBox.TYPE_INFO,timeout = 10 ) else: - ifobj = Wireless(self.iface) # a Wireless NIC Object - wlanresponse = None - try: - wlanresponse = ifobj.getAPaddr() - except IOError, (errno, strerror): - wlanresponse = (errno,strerror) - if wlanresponse: - if wlanresponse[0] not in (19,95): # 19 = 'No such device', 95 = 'Operation not supported' - self.session.openWithCallback(self.WlanScanClosed, WlanScan, self.iface) - else: - # Display Wlan not available Message - self.showErrorMessage() + if self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.WlanScanClosed, WlanScan, self.iface) else: - # Display Wlan not available Message - self.showErrorMessage() + self.showErrorMessage() # Display Wlan not available Message if self["menulist"].getCurrent()[1] == 'wlanstatus': try: from Plugins.SystemPlugins.WirelessLan.plugin import WlanStatus - from pythonwifi.iwlibs import Wireless except ImportError: - self.session.open(MessageBox, _("The wireless LAN plugin is not installed!\nPlease install it."), type = MessageBox.TYPE_INFO,timeout = 10 ) - else: - ifobj = Wireless(self.iface) # a Wireless NIC Object - wlanresponse = None - try: - wlanresponse = ifobj.getAPaddr() - except IOError, (errno, strerror): - wlanresponse = (errno,strerror) - if wlanresponse: - if wlanresponse[0] not in (19,95): # 19 = 'No such device', 95 = 'Operation not supported' - self.session.openWithCallback(self.WlanStatusClosed, WlanStatus,self.iface) - else: - # Display Wlan not available Message - self.showErrorMessage() + self.session.open(MessageBox, self.missingwlanplugintxt, type = MessageBox.TYPE_INFO,timeout = 10 ) + else: + if self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.WlanStatusClosed, WlanStatus,self.iface) else: - # Display Wlan not available Message - self.showErrorMessage() + self.showErrorMessage() # Display Wlan not available Message if self["menulist"].getCurrent()[1] == 'lanrestart': self.session.openWithCallback(self.restartLan, MessageBox, (_("Are you sure you want to restart your network interfaces?\n\n") + self.oktext ) ) if self["menulist"].getCurrent()[1] == 'openwizard': @@ -889,7 +856,7 @@ class AdapterSetupConfiguration(Screen, HelpableScreen): self["IF"].setText(iNetwork.getFriendlyAdapterName(self.iface)) self["Statustext"].setText(_("Link:")) - if self.iface in iNetwork.wlan_interfaces: + if iNetwork.isWirelessInterface(self.iface): try: from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus except: @@ -939,28 +906,16 @@ class AdapterSetupConfiguration(Screen, HelpableScreen): def AdapterSetupClosed(self, *ret): if ret is not None and len(ret): - if ret[0] == 'ok' and (self.iface in iNetwork.wlan_interfaces) and iNetwork.getAdapterAttribute(self.iface, "up") is True: + if ret[0] == 'ok' and (iNetwork.isWirelessInterface(self.iface) and iNetwork.getAdapterAttribute(self.iface, "up") is True): try: from Plugins.SystemPlugins.WirelessLan.plugin import WlanStatus - from pythonwifi.iwlibs import Wireless except ImportError: - self.session.open(MessageBox, _("The wireless LAN plugin is not installed!\nPlease install it."), type = MessageBox.TYPE_INFO,timeout = 10 ) + self.session.open(MessageBox, self.missingwlanplugintxt, type = MessageBox.TYPE_INFO,timeout = 10 ) else: - ifobj = Wireless(self.iface) # a Wireless NIC Object - wlanresponse = None - try: - wlanresponse = ifobj.getAPaddr() - except IOError, (errno, strerror): - wlanresponse = (errno,strerror) - if wlanresponse: - if wlanresponse[0] not in (19,95): # 19 = 'No such device', 95 = 'Operation not supported' - self.session.openWithCallback(self.WlanStatusClosed, WlanStatus,self.iface) - else: - # Display Wlan not available Message - self.showErrorMessage() + if self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.WlanStatusClosed, WlanStatus,self.iface) else: - # Display Wlan not available Message - self.showErrorMessage() + self.showErrorMessage() # Display Wlan not available Message else: self.updateStatusbar() else: -- 2.30.2