Skip to content

Instantly share code, notes, and snippets.

@sharun-s
Last active March 21, 2024 07:39
Show Gist options
  • Save sharun-s/08c9bd5099aaa19148ce76752239025f to your computer and use it in GitHub Desktop.
Save sharun-s/08c9bd5099aaa19148ce76752239025f to your computer and use it in GitHub Desktop.
Catch Signals from NetworkManager on DBus when Network Connection/Device State changes (Tested on Ubuntu 18.04)
#For more info see-
#https://dbus.freedesktop.org/doc/dbus-python/tutorial.html#receiving-signals
#https://developer.gnome.org/NetworkManager/stable/nm-dbus-types.html
#https://dbus.freedesktop.org/doc/dbus-specification.html
import dbus
from gi.repository import GLib
from dbus.mainloop.glib import DBusGMainLoop
NMState={
'0':'STATE_UNKNOWN',#Networking state is unknown. This indicates a daemon error that makes it unable to reasonably assess the state. In such event the applications are expected to assume Internet connectivity might be present and not disable controls that require network access. The graphical shells may hide the network accessibility indicator altogether since no meaningful status indication can be provided.
'10':'STATE_ASLEEP',#Networking is not enabled, the system is being suspended or resumed from suspend.
'20':'STATE_DISCONNECTED',#There is no active network connection. The graphical shell should indicate no network connectivity and the applications should not attempt to access the network.
'30':'STATE_DISCONNECTING',#Network connections are being cleaned up. The applications should tear down their network sessions.
'40':'STATE_CONNECTING',#A network connection is being started The graphical shell should indicate the network is being connected while the applications should still make no attempts to connect the network.
'50':'STATE_CONNECTED_LOCAL',#There is only local IPv4 and/or IPv6 connectivity, but no default route to access the Internet. The graphical shell should indicate no network connectivity.
'60':'STATE_CONNECTED_SITE',#There is only site-wide IPv4 and/or IPv6 connectivity. This means a default route is available, but the Internet connectivity check (see "Connectivity" property) did not succeed. The graphical shell should indicate limited network connectivity.
'70':'STATE_CONNECTED_GLOBAL',#There is global IPv4 and/or IPv6 Internet connectivity This means the Internet connectivity check succeeded, the graphical shell should indicate full network connectivity.
}
NMDeviceState={
'0':'DEVICE_STATE_UNKNOWN',#the device's state is unknown
'10':'DEVICE_STATE_UNMANAGED',#the device is recognized, but not managed by NetworkManager
'20':'DEVICE_STATE_UNAVAILABLE',#the device is managed by NetworkManager, but is not available for use. Reasons may include the wireless switched off, missing firmware, no ethernet carrier, missing supplicant or modem manager, etc.
'30':'DEVICE_STATE_DISCONNECTED',#the device can be activated, but is currently idle and not connected to a network.
'40':'DEVICE_STATE_PREPARE',#the device is preparing the connection to the network. This may include operations like changing the MAC address, setting physical link properties, and anything else required to connect to the requested network.
'50':'DEVICE_STATE_CONFIG',#the device is connecting to the requested network. This may include operations like associating with the Wi-Fi AP, dialing the modem, connecting to the remote Bluetooth device, etc.
'60':'DEVICE_STATE_NEED_AUTH',#the device requires more information to continue connecting to the requested network. This includes secrets like WiFi passphrases, login passwords, PIN codes, etc.
'70':'DEVICE_STATE_IP_CONFIG',#the device is requesting IPv4 and/or IPv6 addresses and routing information from the network.
'80':'DEVICE_STATE_IP_CHECK',#the device is checking whether further action is required for the requested network connection. This may include checking whether only local network access is available, whether a captive portal is blocking access to the Internet, etc.
'90':'DEVICE_STATE_SECONDARIES',#the device is waiting for a secondary connection (like a VPN) which must activated before the device can be activated
'100':'DEVICE_STATE_ACTIVATED',#the device has a network connection, either local or global.
'110':'DEVICE_STATE_DEACTIVATING',#a disconnection from the current network connection was requested, and the device is cleaning up resources used for that connection. The network connection may still be valid.
'120':'DEVICE_STATE_FAILED',#the device failed to connect to the requested network and is cleaning up the connection request
}
NMActiveConnectionState={
'0':'ACTIVE_CONNECTION_STATE_UNKNOWN',#the state of the connection is unknown
'1':'ACTIVE_CONNECTION_STATE_ACTIVATING',#a network connection is being prepared
'2':'ACTIVE_CONNECTION_STATE_ACTIVATED',#there is a connection to the network
'3':'ACTIVE_CONNECTION_STATE_DEACTIVATING',#the network connection is being torn down and cleaned up
'4':'ACTIVE_CONNECTION_STATE_DEACTIVATED',#the network connection is disconnected and will be removed
}
def signal_handler(*args, **kwargs):
#for i, arg in enumerate(args):
# print("arg:%d %s" % (i, str(arg)))
# print(type(arg))
#print('kwargs:')
#print(kwargs)
if len(args) <= 1:
return
if not isinstance(args[1],dbus.Dictionary):
return
#else:
#print(args[0])
if 'State' in args[1] and str(args[0]) == "org.freedesktop.NetworkManager":
s=str(args[1]['State'])
print('State', NMState[s] if s in NMState else s)
print(args[1]['PrimaryConnection'] if 'PrimaryConnection' in args[1] else args[0])
if 'State' in args[1] and str(args[0]) == "org.freedesktop.NetworkManager.Connection.Active":
s=str(args[1]['State'])
print('State', NMActiveConnectionState[s] if s in NMActiveConnectionState else s, args[0])
#if 'State' in args[1] and str(args[0]) == "org.freedesktop.NetworkManager.Device":
# s=str(args[1]['State'])
# print('State', NMDeviceState[s] if s in NMDeviceState else s, args[0])
#else:
# return#print(args[0])
#if 'StateReason' in args[1]:
# print('StateReason',args[1]['StateReason'])
#if 'PrimaryConnection' in args[1]:
# print('Primary',args[1]['PrimaryConnection'])
# print(args[0])
DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
#register your signal callback
bus.add_signal_receiver(signal_handler,
bus_name='org.freedesktop.NetworkManager')#,
#interface_keyword='interface',
#member_keyword='member',
#path_keyword='path',
#message_keyword='msg')
loop = GLib.MainLoop()
loop.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment