From 3b50bda73c2dbc9038376a0d70d47343589f7fea Mon Sep 17 00:00:00 2001 From: acid-burn Date: Fri, 6 Nov 2009 08:49:12 +0100 Subject: [PATCH] Enigma2-SystemPlugins: -move NetworkWizard and WirelessLan Plugins into Enigma2 git repo. This fixes bug #140 --- configure.ac | 3 + lib/python/Plugins/SystemPlugins/Makefile.am | 2 +- .../SystemPlugins/NetworkWizard/LICENSE | 12 + .../SystemPlugins/NetworkWizard/Makefile.am | 12 + .../NetworkWizard/NetworkWizard.py | 244 ++++ .../SystemPlugins/NetworkWizard/__init__.py | 0 .../NetworkWizard/meta/Makefile.am | 3 + .../meta/plugin_networkwizard.xml | 25 + .../NetworkWizard/networkwizard.xml | 172 +++ .../SystemPlugins/NetworkWizard/plugin.py | 22 + .../Plugins/SystemPlugins/WirelessLan/LICENSE | 12 + .../SystemPlugins/WirelessLan/Makefile.am | 13 + .../Plugins/SystemPlugins/WirelessLan/Wlan.py | 612 +++++++++ .../SystemPlugins/WirelessLan/__init__.py | 0 .../SystemPlugins/WirelessLan/flags.py | 104 ++ .../SystemPlugins/WirelessLan/iwlibs.py | 1114 +++++++++++++++++ .../SystemPlugins/WirelessLan/plugin.py | 286 +++++ 17 files changed, 2635 insertions(+), 1 deletion(-) create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/LICENSE create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile.am create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/__init__.py create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml create mode 100755 lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py create mode 100755 lib/python/Plugins/SystemPlugins/WirelessLan/LICENSE create mode 100755 lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am create mode 100755 lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py create mode 100755 lib/python/Plugins/SystemPlugins/WirelessLan/__init__.py create mode 100755 lib/python/Plugins/SystemPlugins/WirelessLan/flags.py create mode 100755 lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py create mode 100755 lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py diff --git a/configure.ac b/configure.ac index 2b557fc2..5e403deb 100755 --- a/configure.ac +++ b/configure.ac @@ -155,6 +155,8 @@ lib/python/Plugins/SystemPlugins/FrontprocessorUpgrade/meta/Makefile lib/python/Plugins/SystemPlugins/Hotplug/Makefile lib/python/Plugins/SystemPlugins/Hotplug/meta/Makefile lib/python/Plugins/SystemPlugins/Makefile +lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile +lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile lib/python/Plugins/SystemPlugins/NFIFlash/Makefile lib/python/Plugins/SystemPlugins/NFIFlash/meta/Makefile lib/python/Plugins/SystemPlugins/PositionerSetup/Makefile @@ -173,6 +175,7 @@ lib/python/Plugins/SystemPlugins/VideoTune/Makefile lib/python/Plugins/SystemPlugins/VideoTune/meta/Makefile lib/python/Plugins/SystemPlugins/Videomode/Makefile lib/python/Plugins/SystemPlugins/Videomode/meta/Makefile +lib/python/Plugins/SystemPlugins/WirelessLan/Makefile lib/python/Tools/Makefile lib/service/Makefile lib/components/Makefile diff --git a/lib/python/Plugins/SystemPlugins/Makefile.am b/lib/python/Plugins/SystemPlugins/Makefile.am index db71c31e..a8b187dc 100755 --- a/lib/python/Plugins/SystemPlugins/Makefile.am +++ b/lib/python/Plugins/SystemPlugins/Makefile.am @@ -3,7 +3,7 @@ installdir = $(pkglibdir)/python/Plugins/SystemPlugins SUBDIRS = SoftwareManager FrontprocessorUpgrade PositionerSetup Satfinder \ SkinSelector SatelliteEquipmentControl Videomode VideoTune Hotplug \ DefaultServicesScanner NFIFlash DiseqcTester CommonInterfaceAssignment \ - CrashlogAutoSubmit CleanupWizard VideoEnhancement + CrashlogAutoSubmit CleanupWizard VideoEnhancement WirelessLan NetworkWizard install_PYTHON = \ __init__.py diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/LICENSE b/lib/python/Plugins/SystemPlugins/NetworkWizard/LICENSE new file mode 100755 index 00000000..99700593 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/LICENSE @@ -0,0 +1,12 @@ +This plugin is licensed under the Creative Commons +Attribution-NonCommercial-ShareAlike 3.0 Unported +License. To view a copy of this license, visit +http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative +Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. + +Alternatively, this plugin may be distributed and executed on hardware which +is licensed by Dream Multimedia GmbH. + +This plugin is NOT free software. It is open source, you are allowed to +modify it (if you keep the license), but it may not be commercially +distributed other than under the conditions noted above. diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile.am b/lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile.am new file mode 100755 index 00000000..2a71bb2d --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile.am @@ -0,0 +1,12 @@ +installdir = $(pkglibdir)/python/Plugins/SystemPlugins/NetworkWizard + +SUBDIRS = meta + +install_PYTHON = \ + __init__.py \ + NetworkWizard.py \ + plugin.py + +dist_install_DATA = \ + LICENSE \ + networkwizard.xml \ No newline at end of file diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py new file mode 100755 index 00000000..4d361157 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py @@ -0,0 +1,244 @@ +from Screens.Wizard import wizardManager, WizardSummary +from Screens.WizardLanguage import WizardLanguage +from Screens.Rc import Rc +from Screens.MessageBox import MessageBox + +from Components.Pixmap import Pixmap, MovingPixmap, MultiPixmap +from Components.config import config, ConfigBoolean, configfile, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, getConfigListEntry, ConfigSelection, ConfigPassword +from Components.Network import iNetwork + +#from Components.Label import Label +#from Components.MenuList import MenuList +#from Components.PluginComponent import plugins +#from Plugins.Plugin import PluginDescriptor +from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE +#import time, os, re + + +config.misc.firstrun = ConfigBoolean(default = True) +list = [] +list.append("WEP") +list.append("WPA") +list.append("WPA2") +list.append("WPA/WPA2") + +weplist = [] +weplist.append("ASCII") +weplist.append("HEX") + +config.plugins.wlan = ConfigSubsection() +config.plugins.wlan.essid = NoSave(ConfigText(default = "home", fixed_size = False)) +config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = "home", fixed_size = False)) + +config.plugins.wlan.encryption = ConfigSubsection() +config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = False)) +config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = "WPA/WPA2" )) +config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII")) +config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = "mysecurewlan", fixed_size = False)) + +class NetworkWizard(WizardLanguage, Rc): + skin = """ + + + + + + + + + + + + + + + """ + def __init__(self, session): + self.xmlfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml") + WizardLanguage.__init__(self, session, showSteps = False, showStepSlider = False) + Rc.__init__(self) + self.session = session + self["wizard"] = Pixmap() + + self.InterfaceState = None + self.isInterfaceUp = None + self.WlanPluginInstalled = None + self.ap = None + self.selectedInterface = None + self.NextStep = None + self.myref = None + self.checkRef = None + self.AdapterRef = None + self.WlanList = None + self.isWlanPluginInstalled() + + def listInterfaces(self): + list = [(iNetwork.getFriendlyAdapterName(x),x) for x in iNetwork.getAdapterList()] + list.append((_("Exit network wizard"), "end")) + return list + + def InterfaceSelectionMade(self, index): + self.selectedInterface = index + self.InterfaceSelect(index) + + def InterfaceSelect(self, index): + if index == 'end': + self.NextStep = 'end' + elif index == 'eth0': + self.NextStep = 'nwconfig' + else: + self.NextStep = 'scanwlan' + + def InterfaceSelectionMoved(self): + self.InterfaceSelect(self.selection) + + def checkInterface(self,iface): + self.Adapterlist = iNetwork.getAdapterList() + if self.NextStep is not 'end': + if len(self.Adapterlist) == 0: + #Reset Network to defaults if network broken + iNetwork.resetNetworkConfig('lan', self.checkInterfaceCB) + self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False) + if iface == 'eth0': + if iface in iNetwork.configuredNetworkAdapters and len(iNetwork.configuredNetworkAdapters) == 1: + if iNetwork.getAdapterAttribute(iface, 'up') is True: + self.isInterfaceUp = True + else: + self.isInterfaceUp = False + self.resetfinishedCB(False) + else: + iNetwork.resetNetworkConfig('lan',self.checkInterfaceCB) + self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False) + elif iface == 'wlan0': + if iface in iNetwork.configuredNetworkAdapters and len(iNetwork.configuredNetworkAdapters) == 1: + if iNetwork.getAdapterAttribute(iface, 'up') is True: + self.isInterfaceUp = True + else: + self.isInterfaceUp = False + self.resetfinishedCB(False) + else: + iNetwork.resetNetworkConfig('wlan',self.checkInterfaceCB) + self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False) + elif iface == 'ath0': + if iface in iNetwork.configuredNetworkAdapters and len(iNetwork.configuredNetworkAdapters) == 1: + if iNetwork.getAdapterAttribute(iface, 'up') is True: + self.isInterfaceUp = True + else: + self.isInterfaceUp = False + self.resetfinishedCB(False) + else: + iNetwork.resetNetworkConfig('wlan-mpci',self.checkInterfaceCB) + self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False) + else: + self.resetfinishedCB(False) + + def resetfinishedCB(self,data): + if data is True: + self.currStep = self.getStepWithID(self.NextStep) + self.afterAsyncCode() + else: + self.currStep = self.getStepWithID(self.NextStep) + self.afterAsyncCode() + + def checkInterfaceCB(self,callback,iface): + if callback is not None: + if callback is True: + iNetwork.getInterfaces(self.getInterfacesDataAvail) + + + def getInterfacesDataAvail(self, data): + if data is True: + if iNetwork.getAdapterAttribute(self.selectedInterface, 'up') is True: + self.isInterfaceUp = True + else: + self.isInterfaceUp = False + self.myref.close(True) + + def AdapterSetupEnd(self, iface): + if iNetwork.getAdapterAttribute(iface, "dhcp") is True: + iNetwork.checkNetworkState(self.AdapterSetupEndFinished) + self.AdapterRef = self.session.openWithCallback(self.AdapterSetupEndCB, MessageBox, _("Please wait while we test your network..."), type = MessageBox.TYPE_INFO, enable_input = False) + + else: + self.currStep = self.getStepWithID("confdns") + self.afterAsyncCode() + + def AdapterSetupEndCB(self,data): + if data is True: + self.currStep = self.getStepWithID("checklanstatusend") + self.afterAsyncCode() + + def AdapterSetupEndFinished(self,data): + if data <= 2: + self.InterfaceState = True + else: + self.InterfaceState = False + self.AdapterRef.close(True) + + def checkNetwork(self): + iNetwork.checkNetworkState(self.checkNetworkStateFinished) + self.checkRef = self.session.openWithCallback(self.checkNetworkCB, MessageBox, _("Please wait while we test your network..."), type = MessageBox.TYPE_INFO, enable_input = False) + + def checkNetworkCB(self,data): + if data is True: + self.currStep = self.getStepWithID("checklanstatusend") + self.afterAsyncCode() + + def checkNetworkStateFinished(self,data): + if data <= 2: + self.InterfaceState = True + else: + self.InterfaceState = False + self.checkRef.close(True) + + def markDone(self): + pass + + def listModes(self): + list = [] + self.WlanList = [] + try: + from Plugins.SystemPlugins.WirelessLan.Wlan import Wlan + except ImportError: + list.append( ( _("No networks found"),_("unavailable") ) ) + self.WlanList.append(_("No networks found")) + return list + else: + self.w = Wlan(self.selectedInterface) + aps = self.w.getNetworkList() + if aps is not None: + print "[NetworkWizard.py] got Accespoints!" + for ap in aps: + a = aps[ap] + if a['active']: + if a['essid'] != "": + #a['essid'] = a['bssid'] + list.append( (a['essid'], a['essid']) ) + self.WlanList.append(a['essid']) + if "hidden..." not in list: + list.append( ( _("enter hidden network SSID"),_("hidden...") ) ) + self.WlanList.append(_("hidden...")) + return list + + def modeSelectionMade(self, index): + self.modeSelect(index) + + def modeSelectionMoved(self): + self.modeSelect(self.selection) + + def modeSelect(self, mode): + self.ap = mode + print "ModeSelected:", mode + + def restartNetwork(self): + iNetwork.restartNetwork() + self.checkNetwork() + + def isWlanPluginInstalled(self): + try: + from Plugins.SystemPlugins.WirelessLan.Wlan import Wlan + except ImportError: + self.WlanPluginInstalled = False + else: + self.WlanPluginInstalled = True + diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/__init__.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am b/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am new file mode 100755 index 00000000..98dbe80b --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am @@ -0,0 +1,3 @@ +installdir = $(datadir)/meta/ + +dist_install_DATA = plugin_networkwizard.xml diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml b/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml new file mode 100755 index 00000000..660bbcd2 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml @@ -0,0 +1,25 @@ + + + + + + Dream Multimedia + NetworkWizard + enigma2-plugin-systemplugins-networkwizard + Step by step network configuration + With the NetworkWizard you can easy configure your network step by step. + + + + Dream Multimedia + NetzwerkWizard + enigma2-plugin-systemplugins-networkwizard + Schritt für Schritt Netzwerk konfiguration + Mit dem NetzwerkWizard können Sie Ihr Netzwerk konfigurieren. Sie werden Schritt + für Schritt durch die Konfiguration geleitet. + + + + + + diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml b/lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml new file mode 100755 index 00000000..134797a7 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml @@ -0,0 +1,172 @@ + + + + + +self.clearSelectedKeys() +self.selectKey("OK") + + + + + + + + +self.clearSelectedKeys() +self.selectKey("OK") +self.selectKey("UP") +self.selectKey("DOWN") + + +self.checkInterface(self.selectedInterface) + + + + + + + + +self.clearSelectedKeys() +self.selectKey("OK") +self.selectKey("UP") +self.selectKey("DOWN") +self.selectKey("LEFT") +self.selectKey("RIGHT") + + +self.AdapterSetupEnd(self.selectedInterface) + + + + + + + + +self.clearSelectedKeys() +self.selectKey("OK") + + +self.checkNetwork() + + + + + +self.condition = (self.InterfaceState == True ) + + + + +self.clearSelectedKeys() +self.selectKey("OK") + + +currStep = self.numSteps +self.wizard[currStep]["nextstep"] = None +self.markDone() +self.close() + + + + + +self.condition = (self.InterfaceState == False ) + + + + +self.clearSelectedKeys() +self.selectKey("OK") +self.selectKey("UP") +self.selectKey("DOWN") + + + + + + + + + +self.condition = (self.isInterfaceUp == True and self.WlanPluginInstalled == True) + + + + + +self.clearSelectedKeys() +self.selectKey("OK") +self.selectKey("UP") +self.selectKey("DOWN") +self.selectKey("LEFT") +self.selectKey("RIGHT") + + + + + +self.condition = (self.isInterfaceUp == False and self.WlanPluginInstalled == True) + + + + + + + + + +self.clearSelectedKeys() +self.selectKey("OK") +self.selectKey("UP") +self.selectKey("DOWN") + + + + + +self.condition = (self.isInterfaceUp == True and self.WlanPluginInstalled == False) + + + + + + + + +self.clearSelectedKeys() +self.selectKey("OK") +self.selectKey("UP") +self.selectKey("DOWN") + + + + + + + + +self.clearSelectedKeys() +self.selectKey("OK") +self.selectKey("UP") +self.selectKey("DOWN") +self.selectKey("LEFT") +self.selectKey("RIGHT") + + +self.AdapterSetupEnd(self.selectedInterface) + + + + + + +self.clearSelectedKeys() +self.selectKey("OK") + + + + + diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py new file mode 100755 index 00000000..dc3becac --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py @@ -0,0 +1,22 @@ +from Screens.Screen import Screen +from Plugins.Plugin import PluginDescriptor +from Components.config import getConfigListEntry, config + +def NetworkWizardMain(session, **kwargs): + session.open(NetworkWizard) + +def startSetup(menuid): + if menuid != "system": + return [ ] + + return [(_("Network Wizard") + "...", NetworkWizardMain, "nw_wizard", 40)] + +def NetworkWizard(*args, **kwargs): + from NetworkWizard import NetworkWizard + return NetworkWizard(*args, **kwargs) + +def Plugins(**kwargs): + list = [] + if config.misc.firstrun.value: + list.append(PluginDescriptor(name=_("Network Wizard"), where = PluginDescriptor.WHERE_WIZARD, fnc=(25, NetworkWizard))) + return list diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/LICENSE b/lib/python/Plugins/SystemPlugins/WirelessLan/LICENSE new file mode 100755 index 00000000..99700593 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/LICENSE @@ -0,0 +1,12 @@ +This plugin is licensed under the Creative Commons +Attribution-NonCommercial-ShareAlike 3.0 Unported +License. To view a copy of this license, visit +http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative +Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. + +Alternatively, this plugin may be distributed and executed on hardware which +is licensed by Dream Multimedia GmbH. + +This plugin is NOT free software. It is open source, you are allowed to +modify it (if you keep the license), but it may not be commercially +distributed other than under the conditions noted above. diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am b/lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am new file mode 100755 index 00000000..365372c2 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am @@ -0,0 +1,13 @@ +installdir = $(pkglibdir)/python/Plugins/SystemPlugins/WirelessLan + +#SUBDIRS = meta + +install_PYTHON = \ + __init__.py \ + flags.py \ + iwlibs.py \ + plugin.py \ + Wlan.py + +dist_install_DATA = \ + LICENSE diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py b/lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py new file mode 100755 index 00000000..ba1e13d4 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py @@ -0,0 +1,612 @@ +from enigma import eListboxPythonMultiContent, eListbox, gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER +from Components.MultiContent import MultiContentEntryText +from Components.GUIComponent import GUIComponent +from Components.HTMLComponent import HTMLComponent +from Components.config import config, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword +from Components.Console import Console + +from os import system +from string import maketrans, strip +import sys +import types +from re import compile as re_compile, search as re_search +from iwlibs import getNICnames, Wireless, Iwfreq + +list = [] +list.append("WEP") +list.append("WPA") +list.append("WPA2") +list.append("WPA/WPA2") + +weplist = [] +weplist.append("ASCII") +weplist.append("HEX") + +config.plugins.wlan = ConfigSubsection() +config.plugins.wlan.essid = NoSave(ConfigText(default = "home", fixed_size = False)) +config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = "home", fixed_size = False)) + +config.plugins.wlan.encryption = ConfigSubsection() +config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = True)) +config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = "WPA/WPA2")) +config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII")) +config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = "mysecurewlan", fixed_size = False)) + +class Wlan: + def __init__(self, iface): + a = ''; b = '' + + for i in range(0, 255): + a = a + chr(i) + if i < 32 or i > 127: + b = b + ' ' + else: + b = b + chr(i) + + self.iface = iface + self.wlaniface = {} + self.WlanConsole = Console() + self.asciitrans = maketrans(a, b) + + def stopWlanConsole(self): + if self.WlanConsole is not None: + print "killing self.WlanConsole" + self.WlanConsole = None + del self.WlanConsole + + def getDataForInterface(self, callback = None): + #get ip out of ip addr, as avahi sometimes overrides it in ifconfig. + print "self.iface im getDataForInterface",self.iface + if len(self.WlanConsole.appContainers) == 0: + self.WlanConsole = Console() + cmd = "iwconfig " + self.iface + self.WlanConsole.ePopen(cmd, self.iwconfigFinished, callback) + + def iwconfigFinished(self, result, retval, extra_args): + print "self.iface im iwconfigFinished",self.iface + callback = extra_args + data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False } + #print "result im iwconfigFinished",result + + for line in result.splitlines(): + #print "line",line + line = line.strip() + if "ESSID" in line: + if "off/any" in line: + ssid = _("No Connection") + else: + tmpssid=(line[line.index('ESSID')+7:len(line)-1]) + if tmpssid == '': + ssid = _("Hidden networkname") + elif tmpssid ==' ': + ssid = _("Hidden networkname") + else: + ssid = tmpssid + #print "SSID->",ssid + if ssid is not None: + data['essid'] = ssid + if 'Frequency' in line: + frequency = line[line.index('Frequency')+10 :line.index(' GHz')] + #print "Frequency",frequency + if frequency is not None: + data['frequency'] = frequency + if "Access Point" in line: + ap=line[line.index('Access Point')+14:len(line)-1] + #print "AP",ap + if ap is not None: + data['acesspoint'] = ap + if "Bit Rate" in line: + br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')] + #print "Bitrate",br + if br is not None: + data['bitrate'] = br + if 'Encryption key' in line: + if ":off" in line: + enc = _("Disabled") + else: + enc = line[line.index('Encryption key')+15 :line.index(' Security')] + #print "Encryption key",enc + if enc is not None: + data['encryption'] = _("Enabled") + if 'Quality' in line: + if "/100" in line: + qual = line[line.index('Quality')+8:line.index('/100')] + else: + qual = line[line.index('Quality')+8:line.index('Sig')] + #print "Quality",qual + if qual is not None: + data['quality'] = qual + if 'Signal level' in line: + signal = line[line.index('Signal level')+14 :line.index(' dBm')] + #print "Signal level",signal + if signal is not None: + data['signal'] = signal + + self.wlaniface[self.iface] = data + + if len(self.WlanConsole.appContainers) == 0: + print "self.wlaniface after loading:", self.wlaniface + self.WlanConsole = None + if callback is not None: + callback(True,self.wlaniface) + + def getAdapterAttribute(self, attribute): + print "im getAdapterAttribute" + if self.wlaniface.has_key(self.iface): + print "self.wlaniface.has_key",self.iface + if self.wlaniface[self.iface].has_key(attribute): + return self.wlaniface[self.iface][attribute] + return None + + def asciify(self, str): + return str.translate(self.asciitrans) + + + def getWirelessInterfaces(self): + iwifaces = None + try: + iwifaces = getNICnames() + except: + print "[Wlan.py] No Wireless Networkcards could be found" + + return iwifaces + + + def getNetworkList(self): + system("ifconfig "+self.iface+" up") + ifobj = Wireless(self.iface) # a Wireless NIC Object + + #Association mappings + stats, quality, discard, missed_beacon = ifobj.getStatistics() + snr = quality.signallevel - quality.noiselevel + + try: + scanresults = ifobj.scan() + except: + scanresults = None + print "[Wlan.py] No Wireless Networks could be found" + + if scanresults is not None: + aps = {} + for result in scanresults: + + bssid = result.bssid + + encryption = map(lambda x: hex(ord(x)), result.encode) + + if encryption[-1] == "0x8": + encryption = True + else: + encryption = False + + extra = [] + for element in result.custom: + element = element.encode() + extra.append( strip(self.asciify(element)) ) + + if result.quality.sl is 0 and len(extra) > 0: + begin = extra[0].find('SignalStrength=')+15 + + done = False + end = begin+1 + + while not done: + if extra[0][begin:end].isdigit(): + end += 1 + else: + done = True + end -= 1 + + signal = extra[0][begin:end] + #print "[Wlan.py] signal is:" + str(signal) + + else: + signal = str(result.quality.sl) + + aps[bssid] = { + 'active' : True, + 'bssid': result.bssid, + 'channel': result.frequency.getChannel(result.frequency.getFrequency()), + 'encrypted': encryption, + 'essid': strip(self.asciify(result.essid)), + 'iface': self.iface, + 'maxrate' : result.rate[-1], + 'noise' : result.quality.getNoiselevel(), + 'quality' : str(result.quality.quality), + 'signal' : signal, + 'custom' : extra, + } + print aps[bssid] + return aps + + + def getStatus(self): + ifobj = Wireless(self.iface) + fq = Iwfreq() + try: + self.channel = str(fq.getChannel(str(ifobj.getFrequency()[0:-3]))) + except: + self.channel = 0 + #print ifobj.getStatistics() + status = { + 'BSSID': str(ifobj.getAPaddr()), + 'ESSID': str(ifobj.getEssid()), + 'quality': str(ifobj.getStatistics()[1].quality), + 'signal': str(ifobj.getStatistics()[1].sl), + 'bitrate': str(ifobj.getBitrate()), + 'channel': str(self.channel), + #'channel': str(fq.getChannel(str(ifobj.getFrequency()[0:-3]))), + } + + for (key, item) in status.items(): + if item is "None" or item is "": + status[key] = _("N/A") + + return status + + + +class WlanList(HTMLComponent, GUIComponent): + def __init__(self, session, iface): + + GUIComponent.__init__(self) + self.w = Wlan(iface) + self.iface = iface + + self.length = 0 + self.aplist = None + self.list = None + self.oldlist = None + self.l = None + self.l = eListboxPythonMultiContent() + + self.l.setFont(0, gFont("Regular", 32)) + self.l.setFont(1, gFont("Regular", 18)) + self.l.setFont(2, gFont("Regular", 16)) + self.l.setBuildFunc(self.buildWlanListEntry) + + self.reload() + + def buildWlanListEntry(self, essid, bssid, encrypted, iface, maxrate, signal): + + res = [ (essid, encrypted, iface) ] + + if essid == "": + essid = bssid + + e = encrypted and _("Yes") or _("No") + res.append( MultiContentEntryText(pos=(0, 0), size=(470, 35), font=0, flags=RT_HALIGN_LEFT, text=essid) ) + res.append( MultiContentEntryText(pos=(425, 0), size=(60, 20), font=1, flags=RT_HALIGN_LEFT, text=_("Signal: "))) + res.append( MultiContentEntryText(pos=(480, 0), size=(70, 35), font=0, flags=RT_HALIGN_RIGHT, text="%s" %signal)) + res.append( MultiContentEntryText(pos=(0, 40), size=(180, 20), font=1, flags=RT_HALIGN_LEFT, text=_("Max. Bitrate: %s") %maxrate )) + res.append( MultiContentEntryText(pos=(190, 40), size=(180, 20), font=1, flags=RT_HALIGN_CENTER, text=_("Encrypted: %s") %e )) + res.append( MultiContentEntryText(pos=(345, 40), size=(190, 20), font=1, flags=RT_HALIGN_RIGHT, text=_("Interface: %s") %iface )) + return res + + + def reload(self): + aps = self.w.getNetworkList() + + self.list = [] + self.aplist = [] + if aps is not None: + print "[Wlan.py] got Accespoints!" + for ap in aps: + a = aps[ap] + if a['active']: + if a['essid'] != '': + # a['essid'] = a['bssid'] + self.list.append( (a['essid'], a['bssid'], a['encrypted'], a['iface'], a['maxrate'], a['signal']) ) + #self.aplist.append( a['essid']) + if self.oldlist is not None: + for entry in self.oldlist: + if entry not in self.list: + self.list.append(entry) + + if len(self.list): + for entry in self.list: + self.aplist.append( entry[0]) + self.length = len(self.list) + self.oldlist = self.list + self.l.setList([]) + self.l.setList(self.list) + + GUI_WIDGET = eListbox + + + def getCurrent(self): + return self.l.getCurrentSelection() + + + def postWidgetCreate(self, instance): + instance.setContent(self.l) + instance.setItemHeight(60) + + + def getLength(self): + return self.length + + def getList(self): + return self.aplist + + +class wpaSupplicant: + def __init__(self): + pass + + + def writeConfig(self): + + essid = config.plugins.wlan.essid.value + hiddenessid = config.plugins.wlan.hiddenessid.value + encrypted = config.plugins.wlan.encryption.enabled.value + encryption = config.plugins.wlan.encryption.type.value + wepkeytype = config.plugins.wlan.encryption.wepkeytype.value + psk = config.plugins.wlan.encryption.psk.value + fp = file('/etc/wpa_supplicant.conf', 'w') + fp.write('#WPA Supplicant Configuration by enigma2\n') + fp.write('ctrl_interface=/var/run/wpa_supplicant\n') + fp.write('eapol_version=1\n') + fp.write('fast_reauth=1\n') + if essid == 'hidden...': + fp.write('ap_scan=2\n') + else: + fp.write('ap_scan=1\n') + fp.write('network={\n') + if essid == 'hidden...': + fp.write('\tssid="'+hiddenessid+'"\n') + else: + fp.write('\tssid="'+essid+'"\n') + fp.write('\tscan_ssid=0\n') + if encrypted: + if encryption == 'WPA' or encryption == 'WPA2' or encryption == 'WPA/WPA2' : + fp.write('\tkey_mgmt=WPA-PSK\n') + + if encryption == 'WPA': + fp.write('\tproto=WPA\n') + fp.write('\tpairwise=TKIP\n') + fp.write('\tgroup=TKIP\n') + elif encryption == 'WPA2': + fp.write('\tproto=WPA RSN\n') + fp.write('\tpairwise=CCMP TKIP\n') + fp.write('\tgroup=CCMP TKIP\n') + else: + fp.write('\tproto=WPA WPA2\n') + fp.write('\tpairwise=CCMP\n') + fp.write('\tgroup=TKIP\n') + fp.write('\tpsk="'+psk+'"\n') + + elif encryption == 'WEP': + fp.write('\tkey_mgmt=NONE\n') + if wepkeytype == 'ASCII': + fp.write('\twep_key0="'+psk+'"\n') + else: + fp.write('\twep_key0='+psk+'\n') + else: + fp.write('\tkey_mgmt=NONE\n') + fp.write('}') + fp.write('\n') + fp.close() + system("cat /etc/wpa_supplicant.conf") + + def loadConfig(self): + try: + #parse the wpasupplicant configfile + fp = file('/etc/wpa_supplicant.conf', 'r') + supplicant = fp.readlines() + fp.close() + ap_scan = False + essid = None + + for s in supplicant: + split = s.strip().split('=',1) + if split[0] == 'ap_scan': + print "[Wlan.py] Got Hidden SSID Scan Value "+split[1] + if split[1] == '2': + ap_scan = True + else: + ap_scan = False + + elif split[0] == 'ssid': + print "[Wlan.py] Got SSID "+split[1][1:-1] + essid = split[1][1:-1] + + elif split[0] == 'proto': + print "split[1]",split[1] + config.plugins.wlan.encryption.enabled.value = True + if split[1] == "WPA" : + mode = 'WPA' + if split[1] == "WPA WPA2" : + mode = 'WPA/WPA2' + if split[1] == "WPA RSN" : + mode = 'WPA2' + config.plugins.wlan.encryption.type.value = mode + print "[Wlan.py] Got Encryption: "+mode + + #currently unused ! + #elif split[0] == 'key_mgmt': + # print "split[1]",split[1] + # if split[1] == "WPA-PSK" : + # config.plugins.wlan.encryption.enabled.value = True + # config.plugins.wlan.encryption.type.value = "WPA/WPA2" + # print "[Wlan.py] Got Encryption: "+ config.plugins.wlan.encryption.type.value + + elif split[0] == 'wep_key0': + config.plugins.wlan.encryption.enabled.value = True + config.plugins.wlan.encryption.type.value = 'WEP' + if split[1].startswith('"') and split[1].endswith('"'): + config.plugins.wlan.encryption.wepkeytype.value = 'ASCII' + config.plugins.wlan.encryption.psk.value = split[1][1:-1] + else: + config.plugins.wlan.encryption.wepkeytype.value = 'HEX' + config.plugins.wlan.encryption.psk.value = split[1] + print "[Wlan.py] Got Encryption: WEP - keytype is: "+config.plugins.wlan.encryption.wepkeytype.value + print "[Wlan.py] Got Encryption: WEP - key0 is: "+config.plugins.wlan.encryption.psk.value + + elif split[0] == 'psk': + config.plugins.wlan.encryption.psk.value = split[1][1:-1] + print "[Wlan.py] Got PSK: "+split[1][1:-1] + else: + pass + + if ap_scan is True: + config.plugins.wlan.hiddenessid.value = essid + config.plugins.wlan.essid.value = 'hidden...' + else: + config.plugins.wlan.hiddenessid.value = essid + config.plugins.wlan.essid.value = essid + wsconfig = { + 'hiddenessid': config.plugins.wlan.hiddenessid.value, + 'ssid': config.plugins.wlan.essid.value, + 'encryption': config.plugins.wlan.encryption.enabled.value, + 'encryption_type': config.plugins.wlan.encryption.type.value, + 'encryption_wepkeytype': config.plugins.wlan.encryption.wepkeytype.value, + 'key': config.plugins.wlan.encryption.psk.value, + } + + for (key, item) in wsconfig.items(): + if item is "None" or item is "": + if key == 'hiddenessid': + wsconfig['hiddenessid'] = "home" + if key == 'ssid': + wsconfig['ssid'] = "home" + if key == 'encryption': + wsconfig['encryption'] = True + if key == 'encryption': + wsconfig['encryption_type'] = "WPA/WPA2" + if key == 'encryption': + wsconfig['encryption_wepkeytype'] = "ASCII" + if key == 'encryption': + wsconfig['key'] = "mysecurewlan" + + except: + print "[Wlan.py] Error parsing /etc/wpa_supplicant.conf" + wsconfig = { + 'hiddenessid': "home", + 'ssid': "home", + 'encryption': True, + 'encryption_type': "WPA/WPA2", + 'encryption_wepkeytype': "ASCII", + 'key': "mysecurewlan", + } + print "[Wlan.py] WS-CONFIG-->",wsconfig + return wsconfig + + + def restart(self, iface): + system("start-stop-daemon -K -x /usr/sbin/wpa_supplicant") + system("start-stop-daemon -S -x /usr/sbin/wpa_supplicant -- -B -i"+iface+" -c/etc/wpa_supplicant.conf") + +class Status: + def __init__(self): + self.wlaniface = {} + self.backupwlaniface = {} + self.WlanConsole = Console() + + def stopWlanConsole(self): + if self.WlanConsole is not None: + print "killing self.WlanConsole" + self.WlanConsole = None + + def getDataForInterface(self, iface, callback = None): + self.WlanConsole = Console() + cmd = "iwconfig " + iface + self.WlanConsole.ePopen(cmd, self.iwconfigFinished, [iface, callback]) + + def iwconfigFinished(self, result, retval, extra_args): + (iface, callback) = extra_args + data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False } + for line in result.splitlines(): + line = line.strip() + if "ESSID" in line: + if "off/any" in line: + ssid = _("No Connection") + else: + tmpssid=(line[line.index('ESSID')+7:len(line)-1]) + if tmpssid == '': + ssid = _("Hidden networkname") + elif tmpssid ==' ': + ssid = _("Hidden networkname") + else: + ssid = tmpssid + #print "SSID->",ssid + if ssid is not None: + data['essid'] = ssid + if 'Frequency' in line: + frequency = line[line.index('Frequency')+10 :line.index(' GHz')] + #print "Frequency",frequency + if frequency is not None: + data['frequency'] = frequency + if "Access Point" in line: + ap=line[line.index('Access Point')+14:len(line)] + #print "AP",ap + if ap is not None: + data['acesspoint'] = ap + if ap == "Not-Associated": + data['essid'] = _("No Connection") + if "Bit Rate" in line: + if "kb" in line: + br = line[line.index('Bit Rate')+9 :line.index(' kb/s')] + if br == '0': + br = _("Unsupported") + else: + br += " Mb/s" + else: + br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')] + " Mb/s" + #print "Bitrate",br + if br is not None: + data['bitrate'] = br + if 'Encryption key' in line: + if ":off" in line: + if data['acesspoint'] is not "Not-Associated": + enc = _("Unsupported") + else: + enc = _("Disabled") + else: + enc = line[line.index('Encryption key')+15 :line.index(' Security')] + if enc is not None: + enc = _("Enabled") + #print "Encryption key",enc + if enc is not None: + data['encryption'] = enc + if 'Quality' in line: + if "/100" in line: + qual = line[line.index('Quality')+8:line.index('/100')] + else: + qual = line[line.index('Quality')+8:line.index('Sig')] + #print "Quality",qual + if qual is not None: + data['quality'] = qual + if 'Signal level' in line: + if "dBm" in line: + signal = line[line.index('Signal level')+14 :line.index(' dBm')] + signal += " dBm" + elif "/100" in line: + signal = line[line.index('Signal level')+13:line.index('/100 Noise')] + signal += "%" + else: + signal = line[line.index('Signal level')+13:line.index(' Noise')] + signal += "%" + #print "Signal level",signal + if signal is not None: + data['signal'] = signal + + self.wlaniface[iface] = data + self.backupwlaniface = self.wlaniface + + if self.WlanConsole is not None: + if len(self.WlanConsole.appContainers) == 0: + print "self.wlaniface after loading:", self.wlaniface + if callback is not None: + callback(True,self.wlaniface) + + def getAdapterAttribute(self, iface, attribute): + print "im getAdapterAttribute" + self.iface = iface + if self.wlaniface.has_key(self.iface): + print "self.wlaniface.has_key",self.iface + if self.wlaniface[self.iface].has_key(attribute): + return self.wlaniface[self.iface][attribute] + return None + +iStatus = Status() \ No newline at end of file diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/__init__.py b/lib/python/Plugins/SystemPlugins/WirelessLan/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/flags.py b/lib/python/Plugins/SystemPlugins/WirelessLan/flags.py new file mode 100755 index 00000000..4435f845 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/flags.py @@ -0,0 +1,104 @@ +# -*- coding: ISO-8859-1 -*- +# python-wifi -- a wireless library to access wireless cards via python +# Copyright (C) 2004, 2005, 2006 Róman Joost +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +modes = ['Auto', + 'Ad-Hoc', + 'Managed', + 'Master', + 'Repeat', + 'Second', + 'Monitor'] + +IFNAMSIZE = 16 +IW_ESSID_MAX_SIZE = 16 + +KILO = 10**3 +MEGA = 10**6 +GIGA = 10**9 + +# ioctl calls for the Linux/i386 kernel +SIOCIWFIRST = 0x8B00 # FIRST ioctl identifier +SIOCGIFCONF = 0x8912 # ifconf struct +SIOCGIWNAME = 0x8B01 # get name == wireless protocol +SIOCGIWFREQ = 0x8B05 # get channel/frequency +SIOCSIWMODE = 0x8B06 # set the operation mode +SIOCGIWMODE = 0x8B07 # get operation mode +SIOCGIWSENS = 0x8B09 # get sensitivity +SIOCGIWAP = 0x8B15 # get AP MAC address +SIOCSIWSCAN = 0x8B18 # set scanning off +SIOCGIWSCAN = 0x8B19 # get scanning results +SIOCGIWRATE = 0x8B21 # get default bit rate +SIOCGIWRTS = 0x8B23 # get rts/cts threshold +SIOCGIWFRAG = 0x8B25 # get fragmention thrh +SIOCGIWTXPOW = 0x8B27 # get transmit power (dBm) +SIOCGIWRETRY = 0x8B29 # get retry limit +SIOCGIWRANGE = 0x8B0B # range +SIOCGIWSTATS = 0x8B0F # get wireless statistics +SIOCSIWESSID = 0x8B1A # set essid +SIOCGIWESSID = 0x8B1B # get essid +SIOCGIWPOWER = 0x8B2D # get power managment settings +SIOCGIWENCODE = 0x8B2B # get encryption information +SIOCIWLAST = 0x8BFF # LAST ioctl identifier + +# Power management flags +IW_POWER_ON = 0x0000 # No details ... +IW_POWER_TYPE = 0xF000 # Type of parameter +IW_POWER_PERIOD = 0x1000 # Value is a period/duration of +IW_POWER_TIMEOUT = 0x2000 # Value is a timeout +IW_POWER_MODE = 0x0F00 # Power management mode +IW_POWER_MIN = 0x0001 # Value is a minimum +IW_POWER_MAX = 0x0002 # Value is a maximum +IW_POWER_RELATIVE = 0x0004 # Value is not in seconds/ms/us + +# Retry limits +IW_RETRY_TYPE = 0xF000 # Type of parameter + +# encoding stuff +IW_ENCODE_DISABLED = 0x8000 # encoding is disabled +IW_ENCODE_NOKEY = 0x0800 # key is write only, not present + +# constants responsible for scanning +IW_SCAN_MAX_DATA = 4096 + +IW_EV_LCP_LEN = 4 +IW_EV_CHAR_LEN = IW_EV_LCP_LEN + IFNAMSIZE +IW_EV_UINT_LEN = IW_EV_LCP_LEN + 4 +IW_EV_FREQ_LEN = IW_EV_LCP_LEN + 8 +IW_EV_ADDR_LEN = IW_EV_LCP_LEN + 16 +IW_EV_POINT_LEN = IW_EV_LCP_LEN + 4 +IW_EV_PARAM_LEN = IW_EV_LCP_LEN + 8 +IW_EV_QUAL_LEN = IW_EV_LCP_LEN + 4 + +EPERM = 1 +E2BIG = 7 +EAGAIN = 11 + +IWHT_NULL = 0 +IWHT_CHAR = 2 +IWHT_UINT = 4 +IWHT_FREQ = 5 +IWHT_ADDR = 6 +IWHT_POINT = 8 +IWHT_PARAM = 9 +IWHT_QUAL = 10 + +IWEVFIRST = 0x8C00 # FIRST event identifier +IWEVQUAL = 0x8C01 # Quality statistics from scan +IWEVCUSTOM = 0x8C02 # Custom Ascii string from Driver +IWEVLAST = 0x8C0A # LAST event identifier diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py b/lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py new file mode 100755 index 00000000..c5f9c6d2 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py @@ -0,0 +1,1114 @@ +# -*- coding: ISO-8859-1 -*- +# python-wifi -- a wireless library to access wireless cards via python +# Copyright (C) 2004, 2005, 2006 Róman Joost +# +# Contributions from: +# Mike Auty (Iwscanresult, Iwscan) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +from struct import pack as struct_pack, \ + unpack as struct_unpack, \ + calcsize as struct_calcsize + +from array import array +from math import ceil, log10 +from fcntl import ioctl +from socket import AF_INET, SOCK_DGRAM, socket +from time import sleep +from re import compile + +from flags import * + +def getNICnames(): + """ extract wireless device names of /proc/net/wireless + + returns empty list if no devices are present + + >>> getNICnames() + ['eth1', 'wifi0'] + """ + device = compile('[a-z]+[0-9]+') + ifnames = [] + + f = open('/proc/net/wireless', 'r') + data = f.readlines() + for line in data: + try: + ifnames.append(device.search(line).group()) + except AttributeError: + pass + # if we couldn't lookup the devices, try to ask the kernel + if ifnames == []: + ifnames = getConfiguredNICnames() + + return ifnames + +def getConfiguredNICnames(): + """get the *configured* ifnames by a systemcall + + >>> getConfiguredNICnames() + [] + """ + iwstruct = Iwstruct() + ifnames = [] + buff = array('c', '\0'*1024) + caddr_t, length = buff.buffer_info() + s = iwstruct.pack('iP', length, caddr_t) + try: + result = iwstruct._fcntl(SIOCGIFCONF, s) + except IOError, (i, e): + return i, e + + # get the interface names out of the buffer + for i in range(0, 1024, 32): + ifname = buff.tostring()[i:i+32] + ifname = struct_unpack('32s', ifname)[0] + ifname = ifname.split('\0', 1)[0] + if ifname: + # verify if ifnames are really wifi devices + wifi = Wireless(ifname) + result = wifi.getAPaddr() + if result[0] == 0: + ifnames.append(ifname) + + return ifnames + +def makedict(**kwargs): + return kwargs + + +class Wireless(object): + """Access to wireless interfaces""" + + def __init__(self, ifname): + self.sockfd = socket(AF_INET, SOCK_DGRAM) + self.ifname = ifname + self.iwstruct = Iwstruct() + + def getAPaddr(self): + """ returns accesspoint mac address + + >>> from iwlibs import Wireless, getNICnames + >>> ifnames = getNICnames() + >>> ifnames + ['eth1', 'wifi0'] + >>> wifi = Wireless(ifnames[0]) + >>> wifi.getAPaddr() + '00:0D:88:8E:4E:93' + + Test with non-wifi card: + >>> wifi = Wireless('eth0') + >>> wifi.getAPaddr() + (95, 'Operation not supported') + + Test with non-existant card: + >>> wifi = Wireless('eth2') + >>> wifi.getAPaddr() + (19, 'No such device') + """ + buff, s = self.iwstruct.pack_wrq(32) + i, result = self.iwstruct.iw_get_ext(self.ifname, + SIOCGIWAP, + data=s) + if i > 0: + return result + + return self.iwstruct.getMAC(result) + + def getBitrate(self): + """returns device currently set bit rate + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getBitrate() + '11 Mb/s' + """ + i, result = self.iwstruct.iw_get_ext(self.ifname, + SIOCGIWRATE) + if i > 0: + return result + iwfreq = Iwfreq(result) + return iwfreq.getBitrate() + + def getBitrates(self): + """returns the number of available bitrates for the device + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> num, rates = wifi.getBitrates() + >>> num == len(rates) + True + """ + range = Iwrange(self.ifname) + if range.errorflag: + return (range.errorflag, range.error) + return (range.num_bitrates, range.bitrates) + + def getChannelInfo(self): + """returns the number of channels and available frequency for + the device + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> num, rates = wifi.getChannelInfo() + >>> num == len(rates) + True + """ + range = Iwrange(self.ifname) + if range.errorflag: + return (range.errorflag, range.error) + return (range.num_channels, range.frequencies) + + def getEssid(self): + """get essid information + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getEssid() + 'romanofski' + """ + essid = "" + buff, s = self.iwstruct.pack_wrq(32) + i, result = self.iwstruct.iw_get_ext(self.ifname, + SIOCGIWESSID, + data=s) + if i > 0: + return result + str = buff.tostring() + return str.strip('\x00') + + def setEssid(self, essid): + """set essid """ + raise NotImplementedError + if len(essid) > IW_ESSID_MAX_SIZE: + return "essid to big" + buff, s = self.iwstruct.pack_test(essid, 32) + i, result = self.iwstruct.iw_get_ext(self.ifname, + SIOCSIWESSID, + data=s) + if i > 0: + return result + + def getEncryption(self): + """get encryption information which is probably a string of '*', + 'open', 'private' + + as a normal user, you will get a 'Operation not permitted' + error: + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getEncryption() + (1, 'Operation not permitted') + """ + iwpoint = Iwpoint(self.ifname) + if iwpoint.errorflag: + return (iwpoint.errorflag, iwpoint.error) + return iwpoint.getEncryptionKey() + + def getFragmentation(self): + """returns fragmentation threshold + + It depends on what the driver says. If you have fragmentation + threshold turned on, you'll get an int. If it's turned of + you'll get a string: 'off'. + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getFragmentation() + 'off' + """ + iwparam = Iwparam(self.ifname, SIOCGIWFRAG) + if iwparam.errorflag: + return (iwparam.errorflag, iwparam.error) + return iwparam.getValue() + + def getFrequency(self): + """returns currently set frequency of the card + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getFrequency() + '2.417GHz' + """ + i, r = self.iwstruct.iw_get_ext(self.ifname, + SIOCGIWFREQ) + if i > 0: + return (i, r) + iwfreq = Iwfreq(r) + return iwfreq.getFrequency() + + + def getMode(self): + """returns currently set operation mode + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getMode() + 'Managed' + """ + i, result = self.iwstruct.iw_get_ext(self.ifname, + SIOCGIWMODE) + if i > 0: + return result + mode = self.iwstruct.unpack('i', result[:4])[0] + return modes[mode] + + def setMode(self, mode): + """sets the operation mode """ + try: + this_modes = [x.lower() for x in modes] + mode = mode.lower() + wifimode = this_modes.index(mode) + except ValueError: + return "Invalid operation mode!" + + s = self.iwstruct.pack('I', wifimode) + i, result = self.iwstruct.iw_get_ext(self.ifname, + SIOCSIWMODE, + data=s) + if i > 0: + return result + + def getWirelessName(self): + """ returns wireless name + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getWirelessName() + 'IEEE 802.11-DS' + """ + i, result = self.iwstruct.iw_get_ext(self.ifname, + SIOCGIWNAME) + if i > 0: + return result + return result.split('\0')[0] + + def getPowermanagement(self): + """returns power management settings + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getPowermanagement() + 'off' + """ + iwparam = Iwparam(self.ifname, SIOCGIWPOWER) + if iwparam.errorflag: + return (iwparam.errorflag, iwparam.error) + return iwparam.getValue() + + + def getRetrylimit(self): + """returns limit retry/lifetime + + man iwconfig: + Most cards have MAC retransmissions, and some allow to set + the behaviour of the retry mechanism. + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getRetrylimit() + 16 + """ + iwparam = Iwparam(self.ifname, SIOCGIWRETRY) + if iwparam.errorflag: + return (iwparam.errorflag, iwparam.error) + return iwparam.getValue() + + def getRTS(self): + """returns rts threshold + + returns int, 'auto', 'fixed', 'off' + + man iwconfig: + RTS/CTS adds a handshake before each packet transmission to + make sure that the channel is clear. This adds overhead, but + increases performance in case of hidden nodes or a large + number of active nodes. This parameter sets the size of the + smallest packet for which the node sends RTS; a value equal + to the maximum packet size disable the mechanism. + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getRTS() + 'off' + """ + iwparam = Iwparam(self.ifname, SIOCGIWRTS) + if iwparam.errorflag: + return (iwparam.errorflag, iwparam.error) + return iwparam.getValue() + + def getSensitivity(self): + """returns sensitivity information + + man iwconfig: + This is the lowest signal level for which the hardware + attempt packet reception, signals weaker than this are + ignored. This is used to avoid receiving background noise, + so you should set it according to the average noise + level. Positive values are assumed to be the raw value used + by the hardware or a percentage, negative values are + assumed to be dBm. + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getSensitivity() + 'off' + + """ + iwparam = Iwparam(self.ifname, SIOCGIWSENS) + if iwparam.errorflag: + return (iwparam.errorflag, iwparam.error) + return iwparam.getValue() + + def getTXPower(self): + """returns transmit power in dBm + + >>> from iwlibs import Wireless + >>> wifi = Wireless('eth1') + >>> wifi.getTXPower() + '17 dBm' + """ + i, r = self.iwstruct.iw_get_ext(self.ifname, + SIOCGIWTXPOW) + if i > 0: + return (i, r) + iwfreq = Iwfreq(r) + return iwfreq.getTransmitPower() + + def getStatistics(self): + """returns statistics information which can also be found in + /proc/net/wireless + """ + iwstats = Iwstats(self.ifname) + if iwstats.errorflag > 0: + return (iwstats.errorflag, iwstats.error) + return [iwstats.status, iwstats.qual, iwstats.discard, + iwstats.missed_beacon] + + def scan(self): + """returns Iwscanresult objects, after a successful scan""" + iwscan = Iwscan(self.ifname) + return iwscan.scan() + + +class Iwstruct(object): + """basic class to handle iwstruct data """ + + def __init__(self): + self.idx = 0 + self.sockfd = socket(AF_INET, SOCK_DGRAM) + + def parse_data(self, fmt, data): + """ unpacks raw C data """ + size = struct_calcsize(fmt) + idx = self.idx + + str = data[idx:idx + size] + self.idx = idx+size + value = struct_unpack(fmt, str) + + # take care of a tuple like (int, ) + if len(value) == 1: + return value[0] + else: + return value + + def pack(self, fmt, *args): + """ calls struct_pack and returns the result """ + return struct_pack(fmt, *args) + + def pack_wrq(self, buffsize): + """ packs wireless request data for sending it to the kernel """ + # Prepare a buffer + # We need the address of our buffer and the size for it. The + # ioctl itself looks for the pointer to the address in our + # memory and the size of it. + # Dont change the order how the structure is packed!!! + buff = array('c', '\0'*buffsize) + caddr_t, length = buff.buffer_info() + s = struct_pack('Pi', caddr_t, length) + return buff, s + + def pack_test(self, string, buffsize): + """ packs wireless request data for sending it to the kernel """ + buffsize = buffsize - len(string) + buff = array('c', string+'\0'*buffsize) + caddr_t, length = buff.buffer_info() + s = struct_pack('Pii', caddr_t, length, 1) + return buff, s + + def unpack(self, fmt, packed_data): + """ unpacks data with given format """ + return struct_unpack(fmt, packed_data) + + def _fcntl(self, request, args): + return ioctl(self.sockfd.fileno(), request, args) + + def iw_get_ext(self, ifname, request, data=None): + """ read information from ifname """ + # put some additional data behind the interface name + if data is not None: + buff = IFNAMSIZE-len(ifname) + ifreq = ifname + '\0'*buff + ifreq = ifreq + data + else: + ifreq = (ifname + '\0'*32) + + try: + result = self._fcntl(request, ifreq) + except IOError, (i, e): + return i, e + + return (0, result[16:]) + + def getMAC(self, packed_data): + """ extracts mac addr from packed data and returns it as str """ + mac_addr = struct_unpack('xxBBBBBB', packed_data[:8]) + return "%02X:%02X:%02X:%02X:%02X:%02X" % mac_addr + +class Iwparam(object): + """class to hold iwparam data """ + + def __init__(self, ifname, ioctl): + # (i) value, (b) fixed, (b) disabled, (b) flags + self.fmt = "ibbH" + self.value = 0 + self.fixed = 0 + self.disabled = 0 + self.flags = 0 + self.errorflag = 0 + self.error = "" + self.ioctl = ioctl + self.ifname = ifname + self.update() + + def getValue(self): + """returns the value if not disabled """ + + if self.disabled: + return 'off' + if self.flags & IW_RETRY_TYPE == 0: + return self.getRLAttributes() + else: + return self.getPMAttributes() + + def getRLAttributes(self): + """returns a string with attributes determined by self.flags + """ + return self.value + + def getPMAttributes(self): + """returns a string with attributes determined by self.flags + and IW_POWER* + """ + result = "" + + # Modifiers + if self.flags & IW_POWER_MIN == 0: + result = " min" + if self.flags & IW_POWER_MAX == 0: + result = " max" + + # Type + if self.flags & IW_POWER_TIMEOUT == 0: + result = " period:" + else: + result = " timeout:" + # Value with or without units + # IW_POWER_RELATIVE - value is *not* in s/ms/us + if self.flags & IW_POWER_RELATIVE: + result += "%f" %(float(self.value)/MEGA) + else: + if self.value >= MEGA: + result += "%fs" %(float(self.value)/MEGA) + elif self.value >= KILO: + result += "%fms" %(float(self.value)/KILO) + else: + result += "%dus" % self.value + + return result + + def update(self): + iwstruct = Iwstruct() + i, r = iwstruct.iw_get_ext(self.ifname, + self.ioctl) + if i > 0: + self.errorflag = i + self.error = r + self._parse(r) + + def _parse(self, data): + """ unpacks iwparam data """ + iwstruct = Iwstruct() + self.value, self.fixed, self.disabled, self.flags =\ + iwstruct.parse_data(self.fmt, data) + +class Iwfreq(object): + """ class to hold iwfreq data + delegates to Iwstruct class + """ + + def __init__(self, data=None): + self.fmt = "ihbb" + if data is not None: + self.frequency = self.parse(data) + else: + self.frequency = 0 + self.iwstruct = Iwstruct() + + def __getattr__(self, attr): + return getattr(self.iwstruct, attr) + + def parse(self, data): + """ unpacks iwparam""" + + size = struct_calcsize(self.fmt) + m, e, i, pad = struct_unpack(self.fmt, data[:size]) + # XXX well, its not *the* frequency - we need a better name + if e == 0: + return m + else: + return float(m)*10**e + + def getFrequency(self): + """returns Frequency (str) + + data - binary data returned by systemcall (iw_get_ext()) + """ + freq = self.frequency + + if freq >= GIGA: + return "%0.3fGHz" %(freq/GIGA) + + if freq >= MEGA: + return "%0.3fMHZ" %(freq/MEGA) + + if freq >= KILO: + return "%0.3fKHz" %(freq/KILO) + + def getBitrate(self): + """ returns Bitrate in Mbit + + data - binary data returned by systemcall (iw_get_ext()) + """ + bitrate = self.frequency + + if bitrate >= GIGA: + return "%i Gb/s" %(bitrate/GIGA) + + if bitrate >= MEGA: + return "%i Mb/s" %(bitrate/MEGA) + + if bitrate >= KILO: + return "%i Kb/s" %(bitrate/KILO) + + def getTransmitPower(self): + """ returns transmit power in dbm """ + # XXX something flaky is going on with m and e + # eg. m = 50 and e should than be 0, because the number is stored in + # m and don't needs to be recalculated + return "%i dBm" %self.mw2dbm(self.frequency/10) + + def getChannel(self, freq): + """returns channel information given by frequency + + returns None if frequency can't be converted + freq = frequency to convert (int) + iwrange = Iwrange object + """ + + try: + freq = float(freq) + except: + return None + + lut = {} + #13 Channels beginning at 2.412GHz and inreasing by 0,005 GHz steps + for i in range(0,12): + cur = float( 2.412 + ( i * 0.005 ) ) + lut[str(cur)] = i+1 + # Channel 14 need special actions ;) + lut['2.484'] = 14 + + + if str(freq) in lut.keys(): + return lut[str(freq)] + + return None + + + def mw2dbm(self, mwatt): + """ converts mw to dbm(float) """ + return ceil(10.0 * log10(mwatt)) + + def _setFrequency(self, list): + """sets self.frequency by given list + + currently only used by Iwrange + """ + assert len(list) == 4 + m, e, i, pad = list + if e == 0: + self.frequency = m + else: + self.frequency = m #float(m)*10**e + +class Iwstats(object): + """ class to hold iwstat data """ + + def __init__(self, ifname): + # (2B) status, 4B iw_quality, 6i iw_discarded + self.fmt = "2B4B6i" + self.status = 0 + self.qual = Iwquality() + self.discard = {} + self.missed_beacon = 0 + self.ifname = ifname + self.errorflag = 0 + self.error = "" + self.update() + + def update(self): + iwstruct = Iwstruct() + buff, s = iwstruct.pack_wrq(32) + i, result = iwstruct.iw_get_ext(self.ifname, + SIOCGIWSTATS, + data=s) + if i > 0: + self.error = result + self.errorflag = i + self._parse(buff.tostring()) + + def _parse(self, data): + """ unpacks iwstruct data """ + struct = Iwstruct() + iwqual = Iwquality() + iwstats_data = struct.parse_data(self.fmt, data) + + self.status = iwstats_data[0:2] + self.qual.quality, self.qual.sl, self.qual.nl,\ + self.qual.flags = iwstats_data[2:6] + nwid, code, frag, retries, flags = iwstats_data[6:11] + self.missed_beacon = iwstats_data[11:12][0] + self.discard = makedict(nwid=nwid, code=code, + fragment=frag, retries=retries, misc=flags) + +class Iwquality(object): + """ class to hold iwquality data """ + + def __init__(self): + self.quality = 0 + self.sl = 0 + self.nl = 0 + self.updated = 0 + self.fmt = "4B" + + def parse(self, data): + """ unpacks iwquality data """ + struct = Iwstruct() + qual, sl, nl, flags = struct.parse_data(self.fmt, data) + + # compute signal and noise level + self.signal_level = sl + self.noise_level = nl + + # asign the other values + self.quality = qual + self.updated = flags + + def setValues(self, list): + """ assigns values given by a list to our attributes """ + attributes = ["quality", "signallevel", "noise_level", + "updated"] + assert len(list) == 4 + + for i in range(len(list)): + setattr(self, attributes[i], list[i]) + + def getSignallevel(self): + """ returns signal level """ + return self.sl-0x100 + + def setSignallevel(self, sl): + """ sets signal level """ + self.sl = sl + signallevel = property(getSignallevel, setSignallevel) + + def getNoiselevel(self): + """ returns noise level """ + return self.nl - 0x100 + + def setNoiselevel(self): + raise NotImplementedError + self.nl = nl + noiselevel = property(getNoiselevel, setNoiselevel) + +class Iwpoint(object): + """ class to hold iwpoint data """ + + def __init__(self, ifname): + self.key = [0,0,0,0] + self.fields = 0 + self.flags = 0 + # (4B) pointer to data, H length, H flags + self.fmt = "4BHH" + self.errorflag = 0 + self.error = "" + self.ifname = ifname + self.update() + + def __getattr__(self, attr): + return getattr(self.iwstruct, attr) + + def update(self): + iwstruct = Iwstruct() + buff, s = iwstruct.pack_wrq(32) + i, result = iwstruct.iw_get_ext(self.ifname, + SIOCGIWENCODE, + data=s) + if i > 0: + self.errorflag = i + self.error = result + self._parse(result) + + def getEncryptionKey(self): + """ returns encryption key as '**' or 'off' as str """ + if self.flags & IW_ENCODE_DISABLED != 0: + return 'off' + elif self.flags & IW_ENCODE_NOKEY != 0: + # a key is set, so print it + return '**' * self.fields + + def _parse(self, data): + """ unpacks iwpoint data + """ + iwstruct = Iwstruct() + ptr, ptr, ptr, ptr, self.fields, self.flags =\ + iwstruct.parse_data(self.fmt, data) + self.key = [ptr, ptr, ptr, ptr] + +class Iwrange(object): + """holds iwrange struct """ + IW_MAX_FREQUENCIES = 32 + + def __init__(self, ifname): + self.fmt = "iiihb6ii4B4Bi32i2i2i2i2i3h8h2b2bhi8i2b3h2i2ihB17x"\ + + self.IW_MAX_FREQUENCIES*"ihbb" + + self.ifname = ifname + self.errorflag = 0 + self.error = "" + + # informative stuff + self.throughput = 0 + + # nwid (or domain id) + self.min_nwid = self.max_nwid = 0 + + # frequency for backward compatibility + self.old_num_channels = self.old_num_frequency = self.old_freq = 0 + + # signal level threshold + self.sensitivity = 0 + + # link quality + self.max_qual = Iwquality() + self.avg_qual = Iwquality() + + # rates + self.num_bitrates = 0 + self.bitrates = [] + + # rts threshold + self.min_rts = self.max_rts = 0 + + # fragmention threshold + self.min_frag = self.max_frag = 0 + + # power managment + self.min_pmp = self.max_pmp = 0 + self.min_pmt = self.max_pmt = 0 + self.pmp_flags = self.pmt_flags = self.pm_capa = 0 + + # encoder stuff + self.encoding_size = 0 + self.num_encoding_sizes = self.max_encoding_tokens = 0 + self.encoding_login_index = 0 + + # transmit power + self.txpower_capa = self.num_txpower = self.txpower = 0 + + # wireless extension version info + self.we_vers_compiled = self.we_vers_src = 0 + + # retry limits and lifetime + self.retry_capa = self.retry_flags = self.r_time_flags = 0 + self.min_retry = self.max_retry = 0 + self.min_r_time = self.max_r_time = 0 + + # frequency + self.num_channels = self.num_frequency = 0 + self.frequencies = [] + self.update() + + def update(self): + """updates Iwrange object by a system call to the kernel + and updates internal attributes + """ + iwstruct = Iwstruct() + buff, s = iwstruct.pack_wrq(640) + i, result = iwstruct.iw_get_ext(self.ifname, + SIOCGIWRANGE, + data=s) + if i > 0: + self.errorflag = i + self.error = result + data = buff.tostring() + self._parse(data) + + def _parse(self, data): + struct = Iwstruct() + result = struct.parse_data(self.fmt, data) + + # XXX there is maybe a much more elegant way to do this + self.throughput, self.min_nwid, self.max_nwid = result[0:3] + self.old_num_channels, self.old_num_frequency = result[3:5] + self.old_freq = result[5:11] + self.sensitivity = result[11] + self.max_qual.setValues(result[12:16]) + self.avg_qual.setValues(result[16:20]) + self.num_bitrates = result[20] # <- XXX + raw_bitrates = result[21:53] + for rate in raw_bitrates: + iwfreq = Iwfreq() + iwfreq.frequency = rate + br = iwfreq.getBitrate() + if br is not None: + self.bitrates.append(br) + + self.min_rts, self.max_rts = result[53:55] + self.min_frag, self.max_frag = result[55:57] + self.min_pmp, self.max_pmp = result[57:59] + self.min_pmt, self.max_pmt = result[59:61] + self.pmp_flags, self.pmt_flags, self.pm_capa = result[61:64] + self.encoding_size = result[64:72] + self.num_encoding_sizes, self.max_encoding_tokens = result[72:74] + self.encoding_login_index = result[74:76] + self.txpower_capa, self.num_txpower = result[76:78] + self.txpower = result[78:86] + self.we_vers_compiled, self.we_vers_src = result[86:88] + self.retry_capa, self.retry_flags, self.r_time_flags = result[88:91] + self.min_retry, self.max_retry = result[91:93] + self.min_r_time, self.max_r_time = result[93:95] + self.num_channels = result[95] + self.num_frequency = result[96] + freq = result[97:] + + i = self.num_frequency + for x in range(0, len(freq), 4): + iwfreq = Iwfreq() + iwfreq._setFrequency(freq[x:x+4]) + fq = iwfreq.getFrequency() + if fq is not None: + self.frequencies.append(fq) + i -= 1 + if i <= 0: + break + +class Iwscan(object): + """class to handle AP scanning""" + + def __init__(self, ifname): + self.ifname = ifname + self.range = Iwrange(ifname) + self.errorflag = 0 + self.error = "" + self.stream = None + self.aplist = None + + def scan(self, fullscan=True): + """Completes a scan for available access points, + and returns them in Iwscanresult format + + fullscan: If False, data is read from a cache of the last scan + If True, a scan is conducted, and then the data is read + """ + # By default everything is fine, do not wait + result = 1 + if fullscan: + self.setScan() + if self.errorflag > EPERM: + raise RuntimeError, 'setScan failure ' + str(self.errorflag) + " " + str(self.error) + return None + elif self.errorflag < EPERM: + # Permission was NOT denied, therefore we must WAIT to get results + result = 250 + + while (result > 0): + sleep(result/1000) + result = self.getScan() + + if result < 0 or self.errorflag != 0: + raise RuntimeError, 'getScan failure ' + str(self.errorflag) + " " + str(self.error) + + return self.aplist + + + def setScan(self): + """Triggers the scan, if we have permission + """ + iwstruct = Iwstruct() + s = iwstruct.pack('Pii', 0, 0, 0) + i, result = iwstruct.iw_get_ext(self.ifname, + SIOCSIWSCAN,s) + if i > 0: + self.errorflag = i + self.error = result + return result + + def getScan(self): + """Retreives results, stored from the most recent scan + Returns 0 if successful, a delay if the data isn't ready yet + or -1 if something really nasty happened + """ + iwstruct = Iwstruct() + i = E2BIG + bufflen = IW_SCAN_MAX_DATA + + # Keep resizing the buffer until it's large enough to hold the scan + while (i == E2BIG): + buff, s = iwstruct.pack_wrq(bufflen) + i, result = iwstruct.iw_get_ext(self.ifname, + SIOCGIWSCAN, + data=s) + if i == E2BIG: + pbuff, newlen = iwstruct.unpack('Pi', s) + if bufflen < newlen: + bufflen = newlen + else: + bufflen = bufflen * 2 + + if i == EAGAIN: + return 100 + if i > 0: + self.errorflag = i + self.error = result + return -1 + + pbuff, reslen = iwstruct.unpack('Pi', s) + if reslen > 0: + # Initialize the stream, and turn it into an enumerator + self.aplist = self._parse(buff.tostring()) + return 0 + + def _parse(self, data): + """Parse the event stream, and return a list of Iwscanresult objects + """ + iwstruct = Iwstruct() + scanresult = None + aplist = [] + + # Run through the stream, until broken + while 1: + # If we're the stream doesn't have enough space left for a header, break + if len(data) < IW_EV_LCP_LEN: + break; + + # Unpack the header + length, cmd = iwstruct.unpack('HH', data[:4]) + # If the header says the following data is shorter than the header, then break + if length < IW_EV_LCP_LEN: + break; + + # Put the events into their respective result data + if cmd == SIOCGIWAP: + if scanresult is not None: + aplist.append(scanresult) + scanresult = Iwscanresult(data[IW_EV_LCP_LEN:length], self.range) + elif scanresult is None: + raise RuntimeError, 'Attempting to add an event without AP data' + else: + scanresult.addEvent(cmd, data[IW_EV_LCP_LEN:length]) + + # We're finished with the preveious event + data = data[length:] + + # Don't forgset the final result + if scanresult.bssid != "00:00:00:00:00:00": + aplist.append(scanresult) + else: + raise RuntimeError, 'Attempting to add an AP without a bssid' + return aplist + +class Iwscanresult(object): + """An object to contain all the events associated with a single scanned AP + """ + + def __init__(self, data, range): + """Initialize the scan result with the access point data""" + self.iwstruct = Iwstruct() + self.range = range + self.bssid = "%02X:%02X:%02X:%02X:%02X:%02X" % struct_unpack('BBBBBB', data[2:8]) + self.essid = None + self.mode = None + self.rate = [] + self.quality = Iwquality() + self.frequency = None + self.encode = None + self.custom = [] + self.protocol = None + + def addEvent(self, cmd, data): + """Attempts to add the data from an event to a scanresult + Only certain data is accept, in which case the result is True + If the event data is invalid, None is returned + If the data is valid but unused, False is returned + """ + if cmd <= SIOCIWLAST: + if cmd < SIOCIWFIRST: + return None + elif cmd >= IWEVFIRST: + if cmd > IWEVLAST: + return None + else: + return None + + if cmd == SIOCGIWESSID: + self.essid = data[4:] + elif cmd == SIOCGIWMODE: + self.mode = modes[self.iwstruct.unpack('i', data[:4])[0]] + elif cmd == SIOCGIWRATE: + # TODO, deal with multiple rates, or at least the highest rate + freqsize = struct_calcsize("ihbb") + while len(data) >= freqsize: + iwfreq = Iwfreq(data) + self.rate.append(iwfreq.getBitrate()) + data = data[freqsize:] + elif cmd == IWEVQUAL: + self.quality.parse(data) + elif cmd == SIOCGIWFREQ: + self.frequency = Iwfreq(data) + elif cmd == SIOCGIWENCODE: + self.encode = data + elif cmd == IWEVCUSTOM: + self.custom.append(data[1:]) + elif cmd == SIOCGIWNAME: + self.protocol = data[:len(data)-2] + else: + #print "Cmd:", cmd + return False + return True \ No newline at end of file diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py new file mode 100755 index 00000000..74520dcc --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py @@ -0,0 +1,286 @@ +from enigma import eTimer +from Screens.Screen import Screen +from Components.ActionMap import ActionMap, NumberActionMap +from Components.Pixmap import Pixmap,MultiPixmap +from Components.Label import Label +from Components.Sources.StaticText import StaticText +from Components.MenuList import MenuList +from Components.config import config, getConfigListEntry, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword +from Components.ConfigList import ConfigListScreen +from Components.Network import Network, iNetwork +from Components.Console import Console +from Plugins.Plugin import PluginDescriptor +from os import system, path as os_path, listdir +from Wlan import Wlan, WlanList, wpaSupplicant +from Wlan import Status, iStatus + +plugin_path = "/usr/lib/enigma2/python/Plugins/SystemPlugins/WirelessLan" + +list = [] +list.append("WEP") +list.append("WPA") +list.append("WPA2") +list.append("WPA/WPA2") + +weplist = [] +weplist.append("ASCII") +weplist.append("HEX") + +config.plugins.wlan = ConfigSubsection() +config.plugins.wlan.essid = NoSave(ConfigText(default = "home", fixed_size = False)) +config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = "home", fixed_size = False)) + +config.plugins.wlan.encryption = ConfigSubsection() +config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = False)) +config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = "WPA/WPA2" )) +config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII")) +config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = "mysecurewlan", fixed_size = False)) + + +class WlanStatus(Screen): + skin = """ + + + + + + + + + + + + + + + + + + + + + + + + + """ + + def __init__(self, session, iface): + Screen.__init__(self, session) + self.session = session + self.iface = iface + self.skin = WlanStatus.skin + + self["LabelBSSID"] = StaticText(_('Accesspoint:')) + self["LabelESSID"] = StaticText(_('SSID:')) + self["LabelQuality"] = StaticText(_('Link Quality:')) + self["LabelSignal"] = StaticText(_('Signal Strength:')) + self["LabelBitrate"] = StaticText(_('Bitrate:')) + self["LabelEnc"] = StaticText(_('Encryption:')) + + self["BSSID"] = StaticText() + self["ESSID"] = StaticText() + self["quality"] = StaticText() + self["signal"] = StaticText() + self["bitrate"] = StaticText() + self["enc"] = StaticText() + + self["IFtext"] = StaticText() + self["IF"] = StaticText() + self["Statustext"] = StaticText() + self["statuspic"] = MultiPixmap() + self["statuspic"].hide() + self["key_red"] = StaticText(_("Close")) + + self.resetList() + self.updateStatusbar() + + self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions", "ShortcutActions"], + { + "ok": self.exit, + "back": self.exit, + "red": self.exit, + }, -1) + self.timer = eTimer() + self.timer.timeout.get().append(self.resetList) + self.onShown.append(lambda: self.timer.start(5000)) + self.onLayoutFinish.append(self.layoutFinished) + self.onClose.append(self.cleanup) + + def cleanup(self): + iStatus.stopWlanConsole() + + def layoutFinished(self): + self.setTitle(_("Wireless Network State")) + + def resetList(self): + print "self.iface im resetlist",self.iface + iStatus.getDataForInterface(self.iface,self.getInfoCB) + + def getInfoCB(self,data,status): + if data is not None: + if data is True: + if status is not None: + self["BSSID"].setText(status[self.iface]["acesspoint"]) + self["ESSID"].setText(status[self.iface]["essid"]) + self["quality"].setText(status[self.iface]["quality"]+"%") + self["signal"].setText(status[self.iface]["signal"]) + self["bitrate"].setText(status[self.iface]["bitrate"]) + self["enc"].setText(status[self.iface]["encryption"]) + self.updateStatusLink(status) + + def exit(self): + self.timer.stop() + self.close() + + def updateStatusbar(self): + print "self.iface im updateStatusbar",self.iface + self["BSSID"].setText(_("Please wait...")) + self["ESSID"].setText(_("Please wait...")) + self["quality"].setText(_("Please wait...")) + self["signal"].setText(_("Please wait...")) + self["bitrate"].setText(_("Please wait...")) + self["enc"].setText(_("Please wait...")) + self["IFtext"].setText(_("Network:")) + self["IF"].setText(iNetwork.getFriendlyAdapterName(self.iface)) + self["Statustext"].setText(_("Link:")) + + def updateStatusLink(self,status): + if status is not None: + if status[self.iface]["acesspoint"] == "No Connection" or status[self.iface]["acesspoint"] == "Not-Associated" or status[self.iface]["acesspoint"] == False: + self["statuspic"].setPixmapNum(1) + else: + self["statuspic"].setPixmapNum(0) + self["statuspic"].show() + +class WlanScan(Screen): + skin = """ + + + + + + + + + + + + """ + + def __init__(self, session, iface): + Screen.__init__(self, session) + self.session = session + self.iface = iface + self.skin = WlanScan.skin + self.skin_path = plugin_path + self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up") + + self["info"] = StaticText() + + self.list = [] + self["list"] = WlanList(self.session, self.iface) + + self.setInfo() + + self["key_red"] = StaticText(_("Close")) + self["key_green"] = StaticText(_("Connect")) + self["key_yellow"] = StaticText(_("Refresh")) + + self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions"], + { + "ok": self.select, + "back": self.cancel, + }, -1) + + self["shortcuts"] = ActionMap(["ShortcutActions"], + { + "red": self.cancel, + "green": self.select, + "yellow": self.rescan, + }) + self.onLayoutFinish.append(self.layoutFinished) + + def layoutFinished(self): + self.setTitle(_("Choose a wireless network")) + + def select(self): + cur = self["list"].getCurrent() + #print "CURRENT",cur + if cur is not None: + if cur[1] is not None: + essid = cur[0] + if essid == '': + essid = cur[1] + encrypted = cur[2] + self.close(essid,self["list"].getList()) + else: + self.close(None,None) + else: + self.close(None,None) + + def WlanSetupClosed(self, *ret): + if ret[0] == 2: + self.close(None) + + def rescan(self): + self["list"].reload() + self.setInfo() + + def cancel(self): + if self.oldInterfaceState is False: + iNetwork.deactivateInterface(self.iface,self.deactivateInterfaceCB) + else: + self.close(None) + + def deactivateInterfaceCB(self,data): + if data is not None: + if data is True: + iNetwork.getInterfaces(self.cancelCB) + + def cancelCB(self,data): + if data is not None: + if data is True: + self.close(None) + + def setInfo(self): + length = self["list"].getLength() + + if length == 0: + self["info"].setText(_("No wireless networks found! Please refresh.")) + elif length == 1: + self["info"].setText(_("1 wireless network found!")) + else: + self["info"].setText(str(length)+_(" wireless networks found!")) + + +def WlanStatusScreenMain(session, iface): + session.open(WlanStatus, iface) + + +def callFunction(iface): + + w = Wlan(iface) + i = w.getWirelessInterfaces() + if i: + if iface in i: + return WlanStatusScreenMain + + return None + + +def configStrings(iface): + driver = iNetwork.detectWlanModule() + print "WLAN-MODULE",driver + if driver == 'ralink': + return " pre-up /usr/sbin/wpa_supplicant -i"+iface+" -c/etc/wpa_supplicant.conf -B -Dralink\n post-down wpa_cli terminate" + if driver == 'madwifi': + if config.plugins.wlan.essid.value == "hidden...": + 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 -Dmadwifi\n post-down wpa_cli terminate" + 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 -Dmadwifi\n post-down wpa_cli terminate" + if driver == 'zydas': + return " pre-up /usr/sbin/wpa_supplicant -i"+iface+" -c/etc/wpa_supplicant.conf -B -dd -Dzydas\n post-down wpa_cli terminate" + +def Plugins(**kwargs): + 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..."}) + \ No newline at end of file -- 2.30.2