mirror of
https://github.com/gryf/wicd.git
synced 2025-12-20 12:58:07 +01:00
Added support for monitoring connection status without the need for iwconfig, ifconfig, and ethtool/miitool.
Added a "Disconnect" button to each network entry, which will be visible instead of the "Connect" button for the active network. Fixed a bug where cancelling a connection while validating authentication would leave the GUI in the connecting state forever.
This commit is contained in:
67
daemon.py
67
daemon.py
@@ -195,11 +195,9 @@ class ConnectionWizard(dbus.service.Object):
|
||||
@dbus.service.method('org.wicd.daemon')
|
||||
def SetWiredInterface(self, interface):
|
||||
""" Sets the wired interface for the daemon to use. """
|
||||
print "setting wired interface", str(interface)
|
||||
print "setting wired interface %s" % (str(interface))
|
||||
self.wired.wired_interface = interface
|
||||
self.wired.SetLiface(interface)
|
||||
self.wifi.wired_interface = interface
|
||||
self.wifi.SetLiface(interface)
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(self.app_conf)
|
||||
config.set("Settings","wired_interface", interface)
|
||||
@@ -208,11 +206,9 @@ class ConnectionWizard(dbus.service.Object):
|
||||
@dbus.service.method('org.wicd.daemon')
|
||||
def SetWirelessInterface(self, interface):
|
||||
""" Sets the wireless interface the daemon will use. """
|
||||
print "setting wireless interface" , str(interface)
|
||||
print "setting wireless interface %s" % (str(interface))
|
||||
self.wifi.wireless_interface = interface
|
||||
self.wifi.SetWiface(interface)
|
||||
self.wired.wireless_interface = interface
|
||||
self.wired.SetWiface(interface)
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(self.app_conf)
|
||||
config.set("Settings","wireless_interface", interface)
|
||||
@@ -363,7 +359,7 @@ class ConnectionWizard(dbus.service.Object):
|
||||
if fresh:
|
||||
self.Scan()
|
||||
#self.AutoConnectScan() # Also scans for hidden networks
|
||||
if self.CheckPluggedIn():
|
||||
if self.CheckPluggedIn(True):
|
||||
self._wired_autoconnect()
|
||||
else:
|
||||
self._wireless_autoconnect()
|
||||
@@ -691,6 +687,10 @@ class ConnectionWizard(dbus.service.Object):
|
||||
def GetNumberOfNetworks(self):
|
||||
""" Returns number of networks. """
|
||||
return len(self.LastScan)
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def GetApBssid(self):
|
||||
return self.wifi.GetBSSID()
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, encused,
|
||||
@@ -736,13 +736,19 @@ class ConnectionWizard(dbus.service.Object):
|
||||
print "Couldn't detect a wireless interface."
|
||||
return str(iface)
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def DisconnectWireless(self):
|
||||
""" Disconnects the wireless network. """
|
||||
self.SetForcedDisconnect(True)
|
||||
self.wifi.Disconnect()
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def IsWirelessUp(self):
|
||||
""" Returns a boolean specifying if wireless is up or down. """
|
||||
return self.wifi.IsUp()
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def GetPrintableSignalStrength(self, iwconfig=None):
|
||||
def GetPrintableSignalStrength(self, iwconfig=None, fast=False):
|
||||
""" Assigns a signal strength appropriate for display
|
||||
|
||||
This is used separately from the raw signal strength retrieving
|
||||
@@ -752,38 +758,38 @@ class ConnectionWizard(dbus.service.Object):
|
||||
|
||||
"""
|
||||
if self.GetSignalDisplayType() == 0:
|
||||
return self.GetCurrentSignalStrength(iwconfig)
|
||||
return self.GetCurrentSignalStrength(iwconfig, fast)
|
||||
else:
|
||||
return self.GetCurrentDBMStrength(iwconfig)
|
||||
return self.GetCurrentDBMStrength(iwconfig, fast)
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def GetCurrentSignalStrength(self, iwconfig=None):
|
||||
def GetCurrentSignalStrength(self, iwconfig=None, fast=False):
|
||||
""" Returns the current signal strength. """
|
||||
try:
|
||||
strength = int(self.wifi.GetSignalStrength(iwconfig))
|
||||
strength = int(self.wifi.GetSignalStrength(iwconfig, fast))
|
||||
except:
|
||||
strength = 0
|
||||
return strength
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def GetCurrentDBMStrength(self, iwconfig=None):
|
||||
def GetCurrentDBMStrength(self, iwconfig=None, fast=False):
|
||||
""" Returns the current dbm signal strength. """
|
||||
try:
|
||||
dbm_strength = int(self.wifi.GetDBMStrength(iwconfig))
|
||||
dbm_strength = int(self.wifi.GetDBMStrength(iwconfig, fast))
|
||||
except:
|
||||
dbm_strength = 0
|
||||
return dbm_strength
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def GetCurrentNetwork(self, iwconfig=None):
|
||||
def GetCurrentNetwork(self, iwconfig=None, fast=False):
|
||||
""" Returns the current network. """
|
||||
current_network = str(self.wifi.GetCurrentNetwork(iwconfig))
|
||||
current_network = str(self.wifi.GetCurrentNetwork(iwconfig, fast))
|
||||
return current_network
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def GetCurrentNetworkID(self, iwconfig=None):
|
||||
def GetCurrentNetworkID(self, iwconfig=None, fast=False):
|
||||
""" Returns the id of the current network, or -1 if its not found. """
|
||||
currentESSID = self.GetCurrentNetwork(iwconfig)
|
||||
currentESSID = self.GetCurrentNetwork(iwconfig, fast)
|
||||
for x in xrange(0, len(self.LastScan)):
|
||||
if self.LastScan[x]['essid'] == currentESSID:
|
||||
return x
|
||||
@@ -820,18 +826,15 @@ class ConnectionWizard(dbus.service.Object):
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def CheckIfWirelessConnecting(self):
|
||||
"""Returns True if wireless interface is connecting, otherwise False."""
|
||||
if self.wifi.connecting_thread is not None:
|
||||
# If connecting_thread exists, then check for it's
|
||||
# status, if it doesn't, we aren't connecting.
|
||||
status = self.wifi.connecting_thread.is_connecting
|
||||
return status
|
||||
if self.wifi.connecting_thread:
|
||||
return self.wifi.connecting_thread.is_connecting
|
||||
else:
|
||||
return False
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wireless')
|
||||
def GetWirelessIP(self):
|
||||
def GetWirelessIP(self, fast=False):
|
||||
""" Returns the IP associated with the wireless interface. """
|
||||
ip = self.wifi.GetIP()
|
||||
ip = self.wifi.GetIP(fast)
|
||||
#if self.debug_mode == 1:
|
||||
#print 'returning wireless ip', ip
|
||||
return ip
|
||||
@@ -849,9 +852,9 @@ class ConnectionWizard(dbus.service.Object):
|
||||
#################################
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wired')
|
||||
def GetWiredIP(self):
|
||||
def GetWiredIP(self, fast=False):
|
||||
""" Returns the wired interface's ip address. """
|
||||
ip = self.wired.GetIP()
|
||||
ip = self.wired.GetIP(True)
|
||||
return ip
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wired')
|
||||
@@ -917,6 +920,12 @@ class ConnectionWizard(dbus.service.Object):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wired')
|
||||
def DisconnectWired(self):
|
||||
""" Disconnects the wired network. """
|
||||
self.SetForcedDisconnect(True)
|
||||
self.wired.Disconnect()
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wired')
|
||||
def SetAlwaysShowWiredInterface(self, value):
|
||||
@@ -932,9 +941,9 @@ class ConnectionWizard(dbus.service.Object):
|
||||
return bool(self.always_show_wired_interface)
|
||||
|
||||
@dbus.service.method('org.wicd.daemon.wired')
|
||||
def CheckPluggedIn(self):
|
||||
def CheckPluggedIn(self, fast=False):
|
||||
if self.wired.wired_interface and self.wired.wired_interface != "None":
|
||||
return self.wired.CheckPluggedIn()
|
||||
return self.wired.CheckPluggedIn(fast)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
106
gui.py
106
gui.py
@@ -179,8 +179,6 @@ language['setting_broadcast_address'] = _('Setting broadcast address...')
|
||||
language['setting_static_dns'] = _('Setting static DNS servers...')
|
||||
language['setting_static_ip'] = _('Setting static IP addresses...')
|
||||
language['running_dhcp'] = _('Obtaining IP address...')
|
||||
language['no_dhcp_offers'] = _('Connection Failed: No DHCP offers received. \
|
||||
Couldn\'t get an IP Address.')
|
||||
language['dhcp_failed'] = _('Connection Failed: Unable to Get IP Address')
|
||||
language['aborted'] = _('Connection Cancelled')
|
||||
language['bad_pass'] = _('Connection Failed: Bad password')
|
||||
@@ -647,6 +645,10 @@ class NetworkEntry(gtk.HBox):
|
||||
self.connect_hbox.pack_start(self.connect_button, False, False)
|
||||
self.connect_hbox.show()
|
||||
|
||||
# Set up the Disconnect button
|
||||
self.disconnect_button = gtk.Button(stock=gtk.STOCK_DISCONNECT)
|
||||
self.connect_hbox.pack_start(self.disconnect_button, False, False)
|
||||
|
||||
# Set up the VBox that goes in the gtk.Expander
|
||||
self.expander_vbox = gtk.VBox(False, 1)
|
||||
self.expander_vbox.show()
|
||||
@@ -790,6 +792,7 @@ class WiredNetworkEntry(NetworkEntry):
|
||||
self.expander.set_expanded(True)
|
||||
self.profile_help.show()
|
||||
self.check_enable()
|
||||
self.update_connect_button()
|
||||
self.wireddis = self.connect("destroy", self.destroy_called)
|
||||
|
||||
def destroy_called(self, *args):
|
||||
@@ -827,7 +830,17 @@ class WiredNetworkEntry(NetworkEntry):
|
||||
self.connect_button.set_sensitive(False)
|
||||
self.advanced_button.set_sensitive(False)
|
||||
self.script_button.set_sensitive(False)
|
||||
|
||||
|
||||
def update_connect_button(self, apbssid=None):
|
||||
""" Update the connection/disconnect button for this entry. """
|
||||
state, x = daemon.GetConnectionStatus()
|
||||
if state == misc.WIRED:
|
||||
self.disconnect_button.show()
|
||||
self.connect_button.hide()
|
||||
else:
|
||||
self.disconnect_button.hide()
|
||||
self.connect_button.show()
|
||||
|
||||
def add_profile(self, widget):
|
||||
""" Add a profile to the profile list. """
|
||||
print "adding profile"
|
||||
@@ -871,12 +884,10 @@ class WiredNetworkEntry(NetworkEntry):
|
||||
def toggle_default_profile(self, widget):
|
||||
""" Change the default profile. """
|
||||
if self.chkbox_default_profile.get_active():
|
||||
print 'unsetting previous default profile...'
|
||||
# Make sure there is only one default profile at a time
|
||||
config.UnsetWiredDefault()
|
||||
wired.SetWiredProperty("default",
|
||||
self.chkbox_default_profile.get_active())
|
||||
print 'toggle defualt prof'
|
||||
config.SaveWiredNetworkProfile(self.combo_profile_names.get_active_text())
|
||||
|
||||
def change_profile(self, widget):
|
||||
@@ -967,6 +978,7 @@ class WirelessNetworkEntry(NetworkEntry):
|
||||
# Show everything
|
||||
self.show_all()
|
||||
self.advanced_dialog = WirelessSettingsDialog(networkID)
|
||||
self.update_connect_button(wireless.GetApBssid())
|
||||
self.wifides = self.connect("destroy", self.destroy_called)
|
||||
|
||||
def destroy_called(self, *args):
|
||||
@@ -1032,6 +1044,17 @@ class WirelessNetworkEntry(NetworkEntry):
|
||||
|
||||
self.image.set_from_file(wpath.images + signal_img)
|
||||
self.lbl_strength.set_label(disp_strength + ending)
|
||||
|
||||
def update_connect_button(self, apbssid):
|
||||
""" Update the connection/disconnect button for this entry. """
|
||||
state, x = daemon.GetConnectionStatus()
|
||||
if state == misc.WIRELESS and apbssid == \
|
||||
wireless.GetWirelessProperty(self.networkID, "bssid"):
|
||||
self.disconnect_button.show()
|
||||
self.connect_button.hide()
|
||||
else:
|
||||
self.disconnect_button.hide()
|
||||
self.connect_button.show()
|
||||
|
||||
def set_mac_address(self, address):
|
||||
""" Set the MAC address for the WirelessNetworkEntry. """
|
||||
@@ -1133,7 +1156,7 @@ class appGui:
|
||||
|
||||
dic = { "refresh_clicked" : self.refresh_networks,
|
||||
"quit_clicked" : self.exit,
|
||||
"disconnect_clicked" : self.disconnect,
|
||||
"disconnect_clicked" : self.disconnect_all,
|
||||
"main_exit" : self.exit,
|
||||
"cancel_clicked" : self.cancel_connect,
|
||||
"connect_clicked" : self.connect_hidden,
|
||||
@@ -1157,7 +1180,6 @@ class appGui:
|
||||
self.network_list = self.wTree.get_widget("network_list_vbox")
|
||||
self.status_area = self.wTree.get_widget("connecting_hbox")
|
||||
self.status_bar = self.wTree.get_widget("statusbar")
|
||||
self.refresh_networks(fresh=False)
|
||||
|
||||
self.status_area.hide_all()
|
||||
|
||||
@@ -1168,6 +1190,8 @@ class appGui:
|
||||
self.pulse_active = False
|
||||
self.standalone = standalone
|
||||
self.wpadrivercombo = None
|
||||
self.fast = True # Use ioctl instead of external program calls
|
||||
self.refresh_networks(fresh=False)
|
||||
|
||||
self.window.connect('delete_event', self.exit)
|
||||
|
||||
@@ -1186,7 +1210,7 @@ class appGui:
|
||||
if width > -1 and height > -1:
|
||||
self.window.resize(int(width), int(height))
|
||||
|
||||
gobject.timeout_add(700, self.update_statusbar)
|
||||
gobject.timeout_add(400, self.update_statusbar)
|
||||
|
||||
def create_adhoc_network(self, widget=None):
|
||||
""" Shows a dialog that creates a new adhoc network. """
|
||||
@@ -1238,9 +1262,10 @@ class appGui:
|
||||
""" Toggles the encryption key entry box for the ad-hoc dialog. """
|
||||
self.key_entry.set_sensitive(self.chkbox_use_encryption.get_active())
|
||||
|
||||
def disconnect(self, widget=None):
|
||||
def disconnect_all(self, widget=None):
|
||||
""" Disconnects from any active network. """
|
||||
daemon.Disconnect()
|
||||
self.update_connect_buttons()
|
||||
|
||||
def about_dialog(self, widget, event=None):
|
||||
""" Displays an about dialog. """
|
||||
@@ -1550,45 +1575,59 @@ class appGui:
|
||||
if not self.is_visible:
|
||||
return True
|
||||
|
||||
fast = self.fast
|
||||
wiredConnecting = wired.CheckIfWiredConnecting()
|
||||
wirelessConnecting = wireless.CheckIfWirelessConnecting()
|
||||
connecting = wiredConnecting or wirelessConnecting
|
||||
|
||||
if wirelessConnecting or wiredConnecting:
|
||||
if not self.pulse_active:
|
||||
self.pulse_active = True
|
||||
gobject.timeout_add(100, self.pulse_progress_bar)
|
||||
|
||||
if connecting and not self.pulse_active:
|
||||
self.pulse_active = True
|
||||
gobject.timeout_add(100, self.pulse_progress_bar)
|
||||
self.network_list.set_sensitive(False)
|
||||
self.status_area.show_all()
|
||||
if self.statusID:
|
||||
self.status_bar.remove(1, self.statusID)
|
||||
if wirelessConnecting:
|
||||
iwconfig = wireless.GetIwconfig()
|
||||
self.set_status(wireless.GetCurrentNetwork(iwconfig) + ': ' +
|
||||
if not fast:
|
||||
iwconfig = wireless.GetIwconfig()
|
||||
else:
|
||||
iwconfig = ''
|
||||
self.set_status(wireless.GetCurrentNetwork(iwconfig, fast) + ': ' +
|
||||
language[str(wireless.CheckWirelessConnectingMessage())])
|
||||
if wiredConnecting:
|
||||
self.set_status(language['wired_network'] + ': ' +
|
||||
language[str(wired.CheckWiredConnectingMessage())])
|
||||
else:
|
||||
self.network_list.set_sensitive(True)
|
||||
elif self.pulse_active and not connecting:
|
||||
self.pulse_active = False
|
||||
self.update_connect_buttons()
|
||||
self.network_list.set_sensitive(True)
|
||||
self.status_area.hide_all()
|
||||
if self.statusID:
|
||||
self.status_bar.remove(1, self.statusID)
|
||||
|
||||
# Determine connection status.
|
||||
if self.check_for_wired(wired.GetWiredIP()):
|
||||
if self.check_for_wired(wired.GetWiredIP(fast)):
|
||||
return True
|
||||
|
||||
if self.check_for_wireless(wireless.GetIwconfig(),
|
||||
wireless.GetWirelessIP()):
|
||||
if not fast:
|
||||
iwconfig = wireless.GetIwconfig()
|
||||
else:
|
||||
iwconfig = ''
|
||||
if self.check_for_wireless(iwconfig,
|
||||
wireless.GetWirelessIP(fast)):
|
||||
return True
|
||||
self.set_status(language['not_connected'])
|
||||
return True
|
||||
|
||||
def update_connect_buttons(self):
|
||||
""" Updates the connect/disconnect buttons for each network entry. """
|
||||
apbssid = wireless.GetApBssid()
|
||||
for entry in self.network_list:
|
||||
if hasattr(entry, "update_connect_button"):
|
||||
entry.update_connect_button(apbssid)
|
||||
|
||||
def check_for_wired(self, wired_ip):
|
||||
""" Determine if wired is active, and if yes, set the status. """
|
||||
if wired_ip and wired.CheckPluggedIn():
|
||||
if wired_ip and wired.CheckPluggedIn(self.fast):
|
||||
self.set_status(language['connected_to_wired'].replace('$A',
|
||||
wired_ip))
|
||||
return True
|
||||
@@ -1600,15 +1639,15 @@ class appGui:
|
||||
if not wireless_ip:
|
||||
return False
|
||||
|
||||
network = wireless.GetCurrentNetwork(iwconfig)
|
||||
network = wireless.GetCurrentNetwork(iwconfig, self.fast)
|
||||
if not network:
|
||||
return False
|
||||
|
||||
network = str(network)
|
||||
if daemon.GetSignalDisplayType() == 0:
|
||||
strength = wireless.GetCurrentSignalStrength(iwconfig)
|
||||
strength = wireless.GetCurrentSignalStrength(iwconfig, self.fast)
|
||||
else:
|
||||
strength = wireless.GetCurrentDBMStrength(iwconfig)
|
||||
strength = wireless.GetCurrentDBMStrength(iwconfig, self.fast)
|
||||
|
||||
if strength is None:
|
||||
return False
|
||||
@@ -1644,12 +1683,14 @@ class appGui:
|
||||
z.destroy()
|
||||
del z
|
||||
|
||||
if wired.CheckPluggedIn() or wired.GetAlwaysShowWiredInterface():
|
||||
if wired.CheckPluggedIn(self.fast) or wired.GetAlwaysShowWiredInterface():
|
||||
printLine = True # In this case we print a separator.
|
||||
wirednet = WiredNetworkEntry()
|
||||
self.network_list.pack_start(wirednet, False, False)
|
||||
wirednet.connect_button.connect("button-press-event", self.connect,
|
||||
"wired", 0, wirednet)
|
||||
wirednet.disconnect_button.connect("button-press-event", self.disconnect,
|
||||
"wired", 0, wirednet)
|
||||
wirednet.advanced_button.connect("button-press-event",
|
||||
self.edit_advanced, "wired", 0,
|
||||
wirednet)
|
||||
@@ -1673,11 +1714,13 @@ class appGui:
|
||||
else:
|
||||
printLine = True
|
||||
tempnet = WirelessNetworkEntry(x)
|
||||
tempnet.show_all()
|
||||
self.network_list.pack_start(tempnet, False, False)
|
||||
tempnet.connect_button.connect("button-press-event",
|
||||
self.connect, "wireless", x,
|
||||
tempnet)
|
||||
tempnet.disconnect_button.connect("button-press-event",
|
||||
self.disconnect, "wireless",
|
||||
x, tempnet)
|
||||
tempnet.advanced_button.connect("button-press-event",
|
||||
self.edit_advanced, "wireless",
|
||||
x, tempnet)
|
||||
@@ -1889,6 +1932,13 @@ class appGui:
|
||||
wired.ConnectWired()
|
||||
self.update_statusbar()
|
||||
|
||||
def disconnect(self, widget, event, nettype, networkid, networkentry):
|
||||
if nettype == "wired":
|
||||
wired.DisconnectWired()
|
||||
else:
|
||||
wireless.DisconnectWireless()
|
||||
self.update_connect_buttons()
|
||||
|
||||
def wait_for_events(self, amt=0):
|
||||
""" Wait for any pending gtk events to finish before moving on.
|
||||
|
||||
|
||||
3
misc.py
3
misc.py
@@ -277,4 +277,5 @@ def error(parent, message):
|
||||
gtk.BUTTONS_OK)
|
||||
dialog.set_markup(message)
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
39
monitor.py
39
monitor.py
@@ -67,6 +67,9 @@ class ConnectionStatus():
|
||||
self.reconnect_tries = 0
|
||||
self.last_reconnect_time = time.time()
|
||||
self.signal_changed = False
|
||||
# This determines if we use ioctl or external programs
|
||||
self.fast = True
|
||||
self.iwconfig = ''
|
||||
|
||||
def check_for_wired_connection(self, wired_ip):
|
||||
""" Checks for an active wired connection.
|
||||
@@ -76,7 +79,7 @@ class ConnectionStatus():
|
||||
|
||||
"""
|
||||
|
||||
if wired_ip and wired.CheckPluggedIn():
|
||||
if wired_ip and wired.CheckPluggedIn(self.fast):
|
||||
# Only change the interface if it's not already set for wired
|
||||
if not self.still_wired:
|
||||
daemon.SetCurrentInterface(daemon.GetWiredInterface())
|
||||
@@ -99,6 +102,10 @@ class ConnectionStatus():
|
||||
if wireless_ip is None:
|
||||
return False
|
||||
|
||||
if self.fast:
|
||||
self.iwconfig = ''
|
||||
else:
|
||||
self.iwconfig = wireless.GetIwconfig()
|
||||
# Reset this, just in case.
|
||||
self.tried_reconnect = False
|
||||
|
||||
@@ -106,9 +113,11 @@ class ConnectionStatus():
|
||||
# if something goes wrong.
|
||||
try:
|
||||
if daemon.GetSignalDisplayType() == 0:
|
||||
wifi_signal = int(wireless.GetCurrentSignalStrength(self.iwconfig))
|
||||
wifi_signal = int(wireless.GetCurrentSignalStrength(self.iwconfig,
|
||||
self.fast))
|
||||
else:
|
||||
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig))
|
||||
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig,
|
||||
self.fast))
|
||||
except:
|
||||
wifi_signal = 0
|
||||
|
||||
@@ -127,7 +136,7 @@ class ConnectionStatus():
|
||||
# Only update if the signal strength has changed because doing I/O
|
||||
# calls is expensive, and the icon flickers.
|
||||
if (wifi_signal != self.last_strength or
|
||||
self.network != wireless.GetCurrentNetwork(self.iwconfig)):
|
||||
self.network != wireless.GetCurrentNetwork(self.iwconfig, self.fast)):
|
||||
self.last_strength = wifi_signal
|
||||
self.signal_changed = True
|
||||
daemon.SetCurrentInterface(daemon.GetWirelessInterface())
|
||||
@@ -153,15 +162,15 @@ class ConnectionStatus():
|
||||
|
||||
# Determine what our current state is.
|
||||
# Check for wired.
|
||||
wired_ip = wired.GetWiredIP()
|
||||
wired_ip = wired.GetWiredIP(self.fast)
|
||||
wired_found = self.check_for_wired_connection(wired_ip)
|
||||
if wired_found:
|
||||
self.update_state(misc.WIRED, wired_ip=wired_ip)
|
||||
return True
|
||||
|
||||
|
||||
# Check for wireless
|
||||
wifi_ip = wireless.GetWirelessIP()
|
||||
self.iwconfig = wireless.GetIwconfig()
|
||||
wifi_ip = wireless.GetWirelessIP(self.fast)
|
||||
#self.iwconfig = wireless.GetIwconfig()
|
||||
self.signal_changed = False
|
||||
wireless_found = self.check_for_wireless_connection(wifi_ip)
|
||||
if wireless_found:
|
||||
@@ -184,6 +193,8 @@ class ConnectionStatus():
|
||||
def update_state(self, state, wired_ip=None, wifi_ip=None):
|
||||
""" Set the current connection state. """
|
||||
# Set our connection state/info.
|
||||
iwconfig = self.iwconfig
|
||||
fast = self.fast
|
||||
if state == misc.NOT_CONNECTED:
|
||||
info = [""]
|
||||
elif state == misc.SUSPENDED:
|
||||
@@ -192,12 +203,12 @@ class ConnectionStatus():
|
||||
if wired.CheckIfWiredConnecting():
|
||||
info = ["wired"]
|
||||
else:
|
||||
info = ["wireless", wireless.GetCurrentNetwork(self.iwconfig)]
|
||||
info = ["wireless", wireless.GetCurrentNetwork(iwconfig, fast)]
|
||||
elif state == misc.WIRELESS:
|
||||
self.reconnect_tries = 0
|
||||
info = [wifi_ip, wireless.GetCurrentNetwork(self.iwconfig),
|
||||
str(wireless.GetPrintableSignalStrength(self.iwconfig)),
|
||||
str(wireless.GetCurrentNetworkID(self.iwconfig))]
|
||||
info = [wifi_ip, wireless.GetCurrentNetwork(iwconfig, fast),
|
||||
str(wireless.GetPrintableSignalStrength(iwconfig, fast)),
|
||||
str(wireless.GetCurrentNetworkID(iwconfig, fast))]
|
||||
elif state == misc.WIRED:
|
||||
self.reconnect_tries = 0
|
||||
info = [wired_ip]
|
||||
@@ -240,7 +251,7 @@ class ConnectionStatus():
|
||||
|
||||
# If we just lost a wireless connection, try to connect to that
|
||||
# network again. Otherwise just call Autoconnect.
|
||||
cur_net_id = wireless.GetCurrentNetworkID(self.iwconfig)
|
||||
cur_net_id = wireless.GetCurrentNetworkID(self.iwconfig, self.fast)
|
||||
if from_wireless and cur_net_id > -1:
|
||||
print 'Trying to reconnect to last used wireless ' + \
|
||||
'network'
|
||||
@@ -262,7 +273,7 @@ def err_handle(error):
|
||||
def main():
|
||||
""" Start the connection monitor and set the updater to run every 2 sec. """
|
||||
monitor = ConnectionStatus()
|
||||
gobject.timeout_add(3000, monitor.update_connection_status)
|
||||
gobject.timeout_add(2000, monitor.update_connection_status)
|
||||
|
||||
mainloop = gobject.MainLoop()
|
||||
mainloop.run()
|
||||
|
||||
@@ -53,7 +53,6 @@ if __name__ == '__main__':
|
||||
wpath.chdir(__file__)
|
||||
|
||||
|
||||
|
||||
class Controller(object):
|
||||
""" Parent class for the different interface types. """
|
||||
def __init__(self):
|
||||
@@ -125,17 +124,7 @@ class Controller(object):
|
||||
debug = property(get_debug, set_debug)
|
||||
flush_tool = property(get_flush_tool, set_flush_tool)
|
||||
dhcp_client = property(get_dhcp_client, set_dhcp_client)
|
||||
|
||||
def SetWiface(self, iface):
|
||||
""" Sets the wireless interface for the associated wnettools class. """
|
||||
if self.wiface:
|
||||
self.wiface.SetInterface(iface)
|
||||
|
||||
def SetLiface(self, iface):
|
||||
""" Sets the wired interface for the associated wnettools class. """
|
||||
if self.liface:
|
||||
self.liface.SetInterface(iface)
|
||||
|
||||
|
||||
class ConnectThread(threading.Thread):
|
||||
""" A class to perform network connections in a multi-threaded way.
|
||||
@@ -178,6 +167,7 @@ class ConnectThread(threading.Thread):
|
||||
self.after_script = after_script
|
||||
self.disconnect_script = disconnect_script
|
||||
self.should_die = False
|
||||
self.abort_reason = ""
|
||||
|
||||
self.global_dns_1 = gdns1
|
||||
self.global_dns_2 = gdns2
|
||||
@@ -279,7 +269,7 @@ class ConnectThread(threading.Thread):
|
||||
print "Running DHCP"
|
||||
dhcp_status = iface.StartDHCP()
|
||||
if dhcp_status in ['no_dhcp_offers', 'dhcp_failed']:
|
||||
self.connect_aborted(dhcp_status)
|
||||
self.abort_connection(dhcp_status)
|
||||
return
|
||||
|
||||
def set_dns_addresses(self):
|
||||
@@ -306,12 +296,19 @@ class ConnectThread(threading.Thread):
|
||||
a few seconds to make sure the message is readable
|
||||
|
||||
"""
|
||||
if self.abort_reason:
|
||||
reason = self.abort_reason
|
||||
self.SetStatus(reason)
|
||||
self.is_aborted = True
|
||||
self.abort_msg = reason
|
||||
self.is_connecting = False
|
||||
print 'exiting connection thread'
|
||||
|
||||
def abort_connection(self, reason):
|
||||
""" Schedule a connection abortion for the given reason. """
|
||||
self.abort_reason = reason
|
||||
self.should_die = True
|
||||
|
||||
def stop_dhcp_clients(self, iface):
|
||||
""" Stop and running DHCP clients, as well as wpa_supplicant. """
|
||||
print 'Stopping wpa_supplicant, and any dhcp clients'
|
||||
@@ -399,41 +396,51 @@ class Wireless(Controller):
|
||||
self.connecting_thread.start()
|
||||
return True
|
||||
|
||||
def GetSignalStrength(self, iwconfig=None):
|
||||
def GetSignalStrength(self, iwconfig=None, fast=False):
|
||||
""" Get signal strength of the current network.
|
||||
|
||||
Returns:
|
||||
The current signal strength.
|
||||
|
||||
"""
|
||||
return self.wiface.GetSignalStrength(iwconfig)
|
||||
return self.wiface.GetSignalStrength(iwconfig, fast)
|
||||
|
||||
def GetDBMStrength(self, iwconfig=None):
|
||||
def GetDBMStrength(self, iwconfig=None, fast=False):
|
||||
""" Get the dBm signal strength of the current network.
|
||||
|
||||
Returns:
|
||||
The current dBm signal strength.
|
||||
|
||||
"""
|
||||
return self.wiface.GetDBMStrength(iwconfig)
|
||||
return self.wiface.GetDBMStrength(iwconfig, fast)
|
||||
|
||||
def GetCurrentNetwork(self, iwconfig=None):
|
||||
def GetCurrentNetwork(self, iwconfig=None, fast=False):
|
||||
""" Get current network name.
|
||||
|
||||
Returns:
|
||||
The name of the currently connected network.
|
||||
|
||||
"""
|
||||
return self.wiface.GetCurrentNetwork(iwconfig)
|
||||
return self.wiface.GetCurrentNetwork(iwconfig, fast)
|
||||
|
||||
def GetIP(self):
|
||||
def GetIP(self, fast=False):
|
||||
""" Get the IP of the interface.
|
||||
|
||||
Returns:
|
||||
The IP address of the interface in dotted notation.
|
||||
|
||||
"""
|
||||
return self.wiface.GetIP()
|
||||
return self.wiface.GetIP(fast)
|
||||
|
||||
def GetBSSID(self, fast=True):
|
||||
""" Get the BSSID of the current access point.
|
||||
|
||||
Returns:
|
||||
The MAC Adress of the active access point as a string, or
|
||||
None the BSSID can't be found.
|
||||
|
||||
"""
|
||||
return self.wiface.GetBSSID(fast)
|
||||
|
||||
def GetIwconfig(self):
|
||||
""" Get the out of iwconfig. """
|
||||
@@ -641,8 +648,8 @@ class WirelessConnectThread(ConnectThread):
|
||||
if self.network.get('enctype'):
|
||||
self.SetStatus('validating_authentication')
|
||||
if not wiface.ValidateAuthentication(time.time()):
|
||||
self.connect_aborted('bad_pass')
|
||||
return
|
||||
self.abort_connection('bad_pass')
|
||||
self.abort_if_needed()
|
||||
|
||||
# Set up gateway, IP address, and DNS servers.
|
||||
self.set_broadcast_address(wiface)
|
||||
@@ -657,7 +664,7 @@ class WirelessConnectThread(ConnectThread):
|
||||
self.SetStatus('done')
|
||||
print 'Connecting thread exiting.'
|
||||
if self.debug:
|
||||
print "IP Address is: " + wiface.GetIP()
|
||||
print "IP Address is: " + wiface.GetIP(fast=True)
|
||||
self.is_connecting = False
|
||||
|
||||
def generate_psk_and_authenticate(self, wiface):
|
||||
@@ -709,14 +716,14 @@ class Wired(Controller):
|
||||
""" Load the wnettools controls for the wired/wireless interfaces. """
|
||||
self.liface = wnettools.WiredInterface(self.wired_interface, self.debug)
|
||||
|
||||
def CheckPluggedIn(self):
|
||||
def CheckPluggedIn(self, fast=False):
|
||||
""" Check whether the wired connection is plugged in.
|
||||
|
||||
Returns:
|
||||
The status of the physical connection link.
|
||||
|
||||
"""
|
||||
return self.liface.GetPluggedIn()
|
||||
return self.liface.GetPluggedIn(fast)
|
||||
|
||||
def Connect(self, network, debug=False):
|
||||
""" Spawn a connection thread to connect to the network.
|
||||
@@ -734,14 +741,14 @@ class Wired(Controller):
|
||||
self.connecting_thread.start()
|
||||
return True
|
||||
|
||||
def GetIP(self):
|
||||
def GetIP(self, fast=False):
|
||||
""" Get the IP of the interface.
|
||||
|
||||
Returns:
|
||||
The IP address of the interface in dotted notation.
|
||||
|
||||
"""
|
||||
return self.liface.GetIP()
|
||||
return self.liface.GetIP(fast)
|
||||
|
||||
def Disconnect(self):
|
||||
""" Disconnect from the network. """
|
||||
@@ -858,5 +865,5 @@ class WiredConnectThread(ConnectThread):
|
||||
self.SetStatus('done')
|
||||
print 'Connecting thread exiting.'
|
||||
if self.debug:
|
||||
print "IP Address is: " + liface.GetIP()
|
||||
print "IP Address is: " + liface.GetIP(fast=True)
|
||||
self.is_connecting = False
|
||||
|
||||
2
wicd.py
2
wicd.py
@@ -170,7 +170,7 @@ class TrayIcon:
|
||||
.replace('$A', self.network)
|
||||
.replace('$B', sig_string)
|
||||
.replace('$C', str(wireless_ip)))
|
||||
self.set_signal_image(strength, lock)
|
||||
self.set_signal_image(int(strength), lock)
|
||||
|
||||
def set_connecting_state(self, info):
|
||||
""" Sets the icon info for a connecting state. """
|
||||
|
||||
282
wnettools.py
282
wnettools.py
@@ -33,8 +33,13 @@ class WirelessInterface() -- Control a wireless network interface.
|
||||
|
||||
import misc
|
||||
import re
|
||||
import os
|
||||
import wpath
|
||||
import time
|
||||
import socket
|
||||
import fcntl
|
||||
import struct
|
||||
import array
|
||||
|
||||
# Compile the regex patterns that will be used to search the output of iwlist
|
||||
# scan for info these are well tested, should work on most cards
|
||||
@@ -60,6 +65,15 @@ wpa2_pattern = re.compile('(WPA2)', re.I | re.M | re.S)
|
||||
auth_pattern = re.compile('.*wpa_state=(.*?)\n', re.I | re.M | re.S)
|
||||
|
||||
RALINK_DRIVER = 'ralink legacy'
|
||||
SIOCGIWESSID = 0x8B1B
|
||||
SIOCGIFADDR = 0x8915
|
||||
SIOCGIWSTATS = 0x8B0F
|
||||
SIOCGIFHWADDR = 0x8927
|
||||
SIOCGMIIPHY = 0x8947
|
||||
SIOCGETHTOOL = 0x8946
|
||||
SIOCGIFFLAGS = 0x8913
|
||||
SIOCGIWRANGE = 0x8B0B
|
||||
SIOCGIWAP = 0x8B15
|
||||
|
||||
def SetDNS(dns1=None, dns2=None, dns3=None):
|
||||
""" Set the DNS of the system to the specified DNS servers.
|
||||
@@ -123,7 +137,10 @@ def _fast_get_wifi_interfaces():
|
||||
device = re.compile('[a-z]{3,4}[0-9]')
|
||||
ifnames = []
|
||||
|
||||
f = open('/proc/net/wireless', 'r')
|
||||
try:
|
||||
f = open('/proc/net/wireless', 'r')
|
||||
except IOError:
|
||||
return None
|
||||
data = f.readlines()
|
||||
f.close()
|
||||
for line in data:
|
||||
@@ -136,6 +153,20 @@ def _fast_get_wifi_interfaces():
|
||||
return ifnames[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_iw_ioctl_result(iface, call):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
buff = array.array('c', '\0' * 32)
|
||||
addr, length = buff.buffer_info()
|
||||
arg = struct.pack('Pi', addr, length)
|
||||
data = (iface + '\0' * 16)[:16] + arg
|
||||
try:
|
||||
result = fcntl.ioctl(s.fileno(), call, data)
|
||||
except IOError:
|
||||
return None
|
||||
except OSError:
|
||||
return None
|
||||
return buff.tostring()
|
||||
|
||||
class Interface(object):
|
||||
""" Control a network interface. """
|
||||
@@ -157,6 +188,7 @@ class Interface(object):
|
||||
self.IP_FOUND = False
|
||||
self.flush_tool = None
|
||||
self.link_detect = None
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.Check()
|
||||
|
||||
def SetDebugMode(self, value):
|
||||
@@ -172,7 +204,18 @@ class Interface(object):
|
||||
"""
|
||||
self.iface = str(iface)
|
||||
|
||||
def _find_client_path(self, client):
|
||||
paths = ['/sbin/', '/usr/sbin/', '/bin/', '/usr/bin/',
|
||||
'/usr/local/sbin/', '/usr/local/bin/']
|
||||
for path in paths:
|
||||
if os.access("%s%s" % (path, client), os.F_OK):
|
||||
return "%s%s" % (path, client)
|
||||
if self.verbose:
|
||||
"WARNING: No path found for %s" % (client)
|
||||
return None
|
||||
|
||||
def _client_found(self, client):
|
||||
# TODO: Don't use which anymore. Just search path manually.
|
||||
output = misc.Run("which " + client)
|
||||
if output and not ("no " + client) in output:
|
||||
return True
|
||||
@@ -188,46 +231,57 @@ class Interface(object):
|
||||
|
||||
"""
|
||||
if self.DHCP_CLIENT:
|
||||
DHCP_CLIENT = self.DHCP_CLIENT
|
||||
dhcp_client = self.DHCP_CLIENT
|
||||
else:
|
||||
DHCP_CLIENT = None
|
||||
dhcp_client = None
|
||||
dhcp_path = None
|
||||
dhcpclients = ["dhclient", "dhcpcd", "pump"]
|
||||
for client in dhcpclients:
|
||||
if self._client_found(client):
|
||||
DHCP_CLIENT = client
|
||||
dhcp_path = self._find_client_path(client)
|
||||
if dhcp_path:
|
||||
dhcp_client = client
|
||||
break
|
||||
|
||||
if not DHCP_CLIENT:
|
||||
print "WARNING: NO DHCP CLIENT DETECTED! Make sure there is one \
|
||||
set in your path."
|
||||
if not dhcp_client:
|
||||
print "WARNING: No supported DHCP Client could be found!"
|
||||
return
|
||||
elif DHCP_CLIENT in [misc.DHCLIENT, "dhclient"]:
|
||||
DHCP_CLIENT = misc.DHCLIENT
|
||||
DHCP_CMD = "dhclient"
|
||||
DHCP_RELEASE = "dhclient -r"
|
||||
elif DHCP_CLIENT in [misc.PUMP, "pump"]:
|
||||
DHCP_CLIENT = misc.PUMP
|
||||
DHCP_CMD = "pump -i"
|
||||
DHCP_RELEASE = "pump -r -i"
|
||||
elif DHCP_CLIENT in [misc.DHCPCD, "dhcpcd"]:
|
||||
DHCP_CLIENT = misc.DHCPCD
|
||||
DHCP_CMD = "dhcpcd"
|
||||
DHCP_RELEASE = "dhcpcd -r"
|
||||
elif dhcp_client in [misc.DHCLIENT, "dhclient"]:
|
||||
dhcp_client = misc.DHCLIENT
|
||||
dhcp_cmd = dhcp_path
|
||||
dhcp_release = dhcp_cmd + " -r"
|
||||
elif dhcp_client in [misc.PUMP, "pump"]:
|
||||
dhcp_client = misc.PUMP
|
||||
dhcp_cmd = dhcp_path + " -i"
|
||||
dhcp_release = dhcp_cmd + " -r -i"
|
||||
elif dhcp_client in [misc.DHCPCD, "dhcpcd"]:
|
||||
dhcp_client = misc.DHCPCD
|
||||
dhcp_cmd = dhcp_path
|
||||
dhcp_release = dhcp_cmd + " -r"
|
||||
else:
|
||||
dhcp_client = None
|
||||
dhcp_cmd = None
|
||||
dhcp_release = None
|
||||
|
||||
self.DHCP_CMD = DHCP_CMD
|
||||
self.DHCP_RELEASE = DHCP_RELEASE
|
||||
self.DHCP_CLIENT = DHCP_CLIENT
|
||||
self.DHCP_CMD = dhcp_cmd
|
||||
self.DHCP_RELEASE = dhcp_release
|
||||
self.DHCP_CLIENT = dhcp_client
|
||||
|
||||
def CheckWiredTools(self):
|
||||
""" Check for the existence of ethtool and mii-tool. """
|
||||
if self._client_found("mii-tool"):
|
||||
miitool_path = self._find_client_path("mii-tool")
|
||||
if miitool_path:
|
||||
self.miitool_cmd = miitool_path
|
||||
self.MIITOOL_FOUND = True
|
||||
else:
|
||||
self.miitool_cmd = None
|
||||
self.MIITOOL_FOUND = False
|
||||
|
||||
if self._client_found("ethtool"):
|
||||
ethtool_path = self._find_client_path("ethtool")
|
||||
if ethtool_path:
|
||||
self.ethtool_cmd = ethtool_path
|
||||
self.ETHTOOL_FOUND = True
|
||||
else:
|
||||
self.ethtool_cmd = None
|
||||
self.ETHTOOL_FOUND = False
|
||||
|
||||
def Check(self):
|
||||
@@ -236,9 +290,12 @@ class Interface(object):
|
||||
self.CheckDHCP()
|
||||
self.CheckWiredTools()
|
||||
|
||||
if self._client_found("ip"):
|
||||
ip_path = self._find_client_path("ip")
|
||||
if ip_path:
|
||||
self.ip_cmd = ip_path
|
||||
self.IP_FOUND = True
|
||||
else:
|
||||
self.ip_cmd = None
|
||||
self.IP_FOUND = False
|
||||
|
||||
def Up(self):
|
||||
@@ -427,25 +484,48 @@ class Interface(object):
|
||||
if self.verbose: print cmd
|
||||
misc.Run(cmd)
|
||||
|
||||
def GetIP(self):
|
||||
def GetIP(self, fast=False):
|
||||
""" Get the IP address of the interface.
|
||||
|
||||
Returns:
|
||||
The IP address of the interface in dotted quad form.
|
||||
|
||||
"""
|
||||
if fast:
|
||||
return self._fast_get_ip()
|
||||
cmd = 'ifconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
return misc.RunRegex(ip_pattern, output)
|
||||
|
||||
def IsUp(self):
|
||||
def _fast_get_ip(self):
|
||||
""" Gets the IP Address of the interface using ioctl.
|
||||
|
||||
Using ioctl calls to get the IP Address info is MUCH faster
|
||||
than calling ifconfig and paring it's output. It's less
|
||||
portable though, so there may be problems with it on some
|
||||
systems.
|
||||
|
||||
"""
|
||||
ifstruct = struct.pack('256s', self.iface)
|
||||
try:
|
||||
raw_ip = fcntl.ioctl(self.sock.fileno(), SIOCGIFADDR, ifstruct)
|
||||
except IOError:
|
||||
return None
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
return socket.inet_ntoa(raw_ip[20:24])
|
||||
|
||||
def IsUp(self, fast=True):
|
||||
""" Determines if the interface is up.
|
||||
|
||||
Returns:
|
||||
True if the interface is up, False otherwise.
|
||||
|
||||
"""
|
||||
if fast:
|
||||
return self._fast_is_up()
|
||||
cmd = "ifconfig " + self.iface
|
||||
output = misc.Run(cmd)
|
||||
lines = output.split('\n')
|
||||
@@ -457,6 +537,19 @@ class Interface(object):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _fast_is_up(self):
|
||||
data = (self.iface + '\0' * 16)[:18]
|
||||
try:
|
||||
result = fcntl.ioctl(self.sock.fileno(), SIOCGIFFLAGS, data)
|
||||
except IOError, e:
|
||||
if self.verbose:
|
||||
print "SIOCGIFFLAGS failed: " + str(e)
|
||||
return False
|
||||
|
||||
flags, = struct.unpack('H', result[16:18])
|
||||
return bool(flags & 1)
|
||||
|
||||
|
||||
|
||||
class WiredInterface(Interface):
|
||||
@@ -471,7 +564,7 @@ class WiredInterface(Interface):
|
||||
"""
|
||||
Interface.__init__(self, iface, verbose)
|
||||
|
||||
def GetPluggedIn(self):
|
||||
def GetPluggedIn(self, fast=False):
|
||||
""" Get the current physical connection state.
|
||||
|
||||
The method will first attempt to use ethtool do determine
|
||||
@@ -485,21 +578,23 @@ class WiredInterface(Interface):
|
||||
if not self.iface:
|
||||
return False
|
||||
if self.ETHTOOL_FOUND and self.link_detect != misc.MIITOOL:
|
||||
return self._eth_get_plugged_in()
|
||||
return self._eth_get_plugged_in(fast)
|
||||
elif self.MIITOOL_FOUND:
|
||||
return self._mii_get_plugged_in()
|
||||
return self._mii_get_plugged_in(fast)
|
||||
else:
|
||||
print 'Error: No way of checking for a wired connection. Make \
|
||||
sure that either mii-tool or ethtool is installed.'
|
||||
return False
|
||||
|
||||
def _eth_get_plugged_in(self):
|
||||
def _eth_get_plugged_in(self, fast):
|
||||
""" Use ethtool to determine the physical connection state.
|
||||
|
||||
Returns:
|
||||
True if a link is detected, False otherwise.
|
||||
|
||||
"""
|
||||
if fast:
|
||||
self._fast_eth_get_plugged_in()
|
||||
link_tool = 'ethtool'
|
||||
if not self.IsUp():
|
||||
print 'Wired Interface is down, putting it up'
|
||||
@@ -511,14 +606,33 @@ class WiredInterface(Interface):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def _fast_eth_get_plugged_in(self):
|
||||
if not self.IsUp():
|
||||
self.Up()
|
||||
time.sleep(1)
|
||||
buff = array.array('i', [0x0000000a, 0x00000000])
|
||||
addr, length = buff.buffer_info()
|
||||
arg = struct.pack('Pi', addr, length)
|
||||
data = (self.iface + '\0' * 16)[:16] + arg
|
||||
try:
|
||||
fcntl.ioctl(self.sock.fileno(), SIOCGETHTOOL, data)
|
||||
except IOError, e:
|
||||
if self.verbose:
|
||||
print 'SIOCGETHTOOL failed: ' + str(e)
|
||||
return False
|
||||
return bool(buff.tolist()[1])
|
||||
|
||||
|
||||
def _mii_get_plugged_in(self):
|
||||
def _mii_get_plugged_in(self, fast):
|
||||
""" Use mii-tool to determine the physical connection state.
|
||||
|
||||
Returns:
|
||||
True if a link is detected, False otherwise.
|
||||
|
||||
"""
|
||||
if fast:
|
||||
return self._fast_mii_get_plugged_in()
|
||||
link_tool = 'mii-tool'
|
||||
tool_data = misc.Run(link_tool + ' ' + self.iface, True)
|
||||
if misc.RunRegex(re.compile('(Invalid argument)', re.I | re.M | re.S),
|
||||
@@ -534,6 +648,21 @@ class WiredInterface(Interface):
|
||||
else:
|
||||
return False
|
||||
|
||||
def _fast_mii_get_plugged_in(self):
|
||||
""" Get link status usingthe SIOCGMIIPHY ioctl. """
|
||||
if not self.IsUp():
|
||||
self.Up()
|
||||
time.sleep(1)
|
||||
buff = struct.pack('16shhhh', (self.iface + '\0' * 16)[:16], 0, 1,
|
||||
0x0004, 0)
|
||||
try:
|
||||
result = fcntl.ioctl(self.sock.fileno(), SIOCGMIIPHY, buff)
|
||||
except IOError, e:
|
||||
if self.verbose:
|
||||
print 'SIOCGMIIPHY failed: ' + str(e)
|
||||
return False
|
||||
reg = struct.unpack('16shhhh', result)[-1]
|
||||
return bool(reg & 0x0004)
|
||||
|
||||
class WirelessInterface(Interface):
|
||||
""" Control a wireless network interface. """
|
||||
@@ -974,27 +1103,44 @@ class WirelessInterface(Interface):
|
||||
cmd = 'iwpriv ' + self.iface + ' '
|
||||
if self.verbose: print cmd
|
||||
misc.Run(cmd)
|
||||
|
||||
def GetBSSID(self, fast=True):
|
||||
""" Get the MAC address for the interface. """
|
||||
if fast:
|
||||
return self._fast_get_bssid()
|
||||
else:
|
||||
return ""
|
||||
|
||||
def _fast_get_bssid(self):
|
||||
""" Gets the MAC address for the connected AP using ioctl calls. """
|
||||
data = (self.iface + '\0' * 32)[:32]
|
||||
try:
|
||||
result = fcntl.ioctl(self.sock.fileno(), SIOCGIWAP, data)[16:]
|
||||
except IOError, e:
|
||||
if self.verbose:
|
||||
print "SIOCGIWAP failed: " + str(e)
|
||||
return ""
|
||||
raw_addr = struct.unpack("xxBBBBBB", result[:8])
|
||||
return "%02X:%02X:%02X:%02X:%02X:%02X" % raw_addr
|
||||
|
||||
|
||||
|
||||
def GetSignalStrength(self, iwconfig=None):
|
||||
def GetSignalStrength(self, iwconfig=None, fast=False):
|
||||
""" Get the signal strength of the current network.
|
||||
|
||||
Returns:
|
||||
The signal strength.
|
||||
|
||||
"""
|
||||
if fast:
|
||||
return self._get_signal_strength_fast()
|
||||
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
output = misc.Run(cmd)
|
||||
else:
|
||||
output = iwconfig
|
||||
# implemented the patch provided in
|
||||
# https://bugs.launchpad.net/wicd/+bug/175104
|
||||
# it was for the stable version, so I've improvised here
|
||||
# should work though
|
||||
|
||||
#strength = misc.RunRegex(strength_pattern,output)
|
||||
|
||||
[(strength, max_strength)] = strength_pattern.findall(output)
|
||||
if max_strength and strength:
|
||||
@@ -1004,14 +1150,45 @@ class WirelessInterface(Interface):
|
||||
strength = misc.RunRegex(altstrength_pattern, output)
|
||||
|
||||
return strength
|
||||
|
||||
def GetDBMStrength(self, iwconfig=None):
|
||||
|
||||
def _get_signal_strength_fast(self):
|
||||
""" Get the link quality using ioctl calls. """
|
||||
buff = get_iw_ioctl_result(self.iface, SIOCGIWSTATS)
|
||||
strength = ord(buff[2])
|
||||
max_strength = self._get_max_strength_fast()
|
||||
if strength and max_strength:
|
||||
return 100 * int(strength) // int(max_strength)
|
||||
|
||||
return strength
|
||||
|
||||
def _get_max_strength_fast(self):
|
||||
""" Gets the maximum possible strength from the wireless driver. """
|
||||
buff = array.array('c', '\0' * 700)
|
||||
addr, length = buff.buffer_info()
|
||||
arg = struct.pack('Pi', addr, length)
|
||||
iwfreq = (self.iface + '\0' * 16)[:16] + arg
|
||||
try:
|
||||
result = fcntl.ioctl(self.sock.fileno(), SIOCGIWRANGE, iwfreq)
|
||||
except IOError, e:
|
||||
if self.verbose:
|
||||
print "SIOCGIWRANGE failed: " + str(e)
|
||||
return None
|
||||
fmt = "iiihb6ii4B4Bi32i2i2i2i2i3h8h2b2bhi8i2b3h2i2ihB17x" + 32*"ihbb"
|
||||
size = struct.calcsize(fmt)
|
||||
data = buff.tostring()
|
||||
data = data[0:size]
|
||||
values = struct.unpack(fmt, data)
|
||||
return values[12]
|
||||
|
||||
def GetDBMStrength(self, iwconfig=None, fast=False):
|
||||
""" Get the dBm signal strength of the current network.
|
||||
|
||||
Returns:
|
||||
The dBm signal strength.
|
||||
|
||||
"""
|
||||
if fast:
|
||||
return self._get_dbm_strength_fast()
|
||||
if iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
@@ -1020,15 +1197,25 @@ class WirelessInterface(Interface):
|
||||
output = iwconfig
|
||||
dbm_strength = misc.RunRegex(signaldbm_pattern, output)
|
||||
return dbm_strength
|
||||
|
||||
def _get_dbm_strength_fast(self):
|
||||
buff = misc.get_irwange_ioctl_result(self.iface, SIOCGIWSTATS)
|
||||
if not buff:
|
||||
return None
|
||||
|
||||
return str((ord(buff[3]) - 256))
|
||||
|
||||
|
||||
def GetCurrentNetwork(self, iwconfig=None):
|
||||
def GetCurrentNetwork(self, iwconfig=None, fast=False):
|
||||
""" Get the essid of the current network.
|
||||
|
||||
Returns:
|
||||
The current network essid.
|
||||
|
||||
"""
|
||||
if fast:
|
||||
return self._get_essid_fast()
|
||||
|
||||
if not iwconfig:
|
||||
cmd = 'iwconfig ' + self.iface
|
||||
if self.verbose: print cmd
|
||||
@@ -1040,3 +1227,12 @@ class WirelessInterface(Interface):
|
||||
if network:
|
||||
network = misc.to_unicode(network)
|
||||
return network
|
||||
|
||||
def _get_essid_fast(self):
|
||||
""" Get the current essid using ioctl. """
|
||||
buff = get_iw_ioctl_result(self.iface, SIOCGIWESSID)
|
||||
if not buff:
|
||||
return None
|
||||
|
||||
return buff.strip('\x00')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user