diff options
Diffstat (limited to 'src/services/network-service.c')
| -rw-r--r-- | src/services/network-service.c | 1577 |
1 files changed, 0 insertions, 1577 deletions
diff --git a/src/services/network-service.c b/src/services/network-service.c deleted file mode 100644 index b2d1334..0000000 --- a/src/services/network-service.c +++ /dev/null @@ -1,1577 +0,0 @@ -#include "services/network-service.h" -#include <NetworkManager.h> -#include <gtk/gtk.h> -#include <stdint.h> - -typedef struct _ApNetworkMembership ApNetworkMembership; - -#define SCAN_REFRESH_INTERVAL 10000 - -// -// FoobarNetwork: -// -// Represents a Wi-Fi network, identified by its SSID. Instances contain a set of NMAccessPoints and the strength is -// updated to match that of the best available AP. -// - -struct _FoobarNetwork -{ - GObject parent_instance; - GBytes* ssid; - gchar* name; - gint strength; - gboolean is_active; - GHashTable* aps; -}; - -enum -{ - NETWORK_PROP_NAME = 1, - NETWORK_PROP_STRENGTH, - NETWORK_PROP_IS_ACTIVE, - N_NETWORK_PROPS, -}; - -static GParamSpec* network_props[N_NETWORK_PROPS] = { 0 }; - -static void foobar_network_class_init ( FoobarNetworkClass* klass ); -static void foobar_network_init ( FoobarNetwork* self ); -static void foobar_network_get_property ( GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ); -static void foobar_network_finalize ( GObject* object ); -static FoobarNetwork* foobar_network_new ( void ); -static void foobar_network_set_ssid ( FoobarNetwork* self, - GBytes* value ); -static void foobar_network_set_active ( FoobarNetwork* self, - gboolean value ); -static void foobar_network_add_ap ( FoobarNetwork* self, - NMAccessPoint* ap ); -static void foobar_network_remove_ap ( FoobarNetwork* self, - NMAccessPoint* ap ); -static void foobar_network_update_strength ( FoobarNetwork* self ); -static void foobar_network_handle_strength_change( GObject* ap, - GParamSpec* pspec, - gpointer userdata ); - -G_DEFINE_FINAL_TYPE( FoobarNetwork, foobar_network, G_TYPE_OBJECT ) - -// -// FoobarNetworkAdapterState: -// -// The current connection/connectivity state of a network adapter. -// - -G_DEFINE_ENUM_TYPE( - FoobarNetworkAdapterState, - foobar_network_adapter_state, - G_DEFINE_ENUM_VALUE( FOOBAR_NETWORK_ADAPTER_STATE_DISCONNECTED, "disconnected" ), - G_DEFINE_ENUM_VALUE( FOOBAR_NETWORK_ADAPTER_STATE_CONNECTING, "connecting" ), - G_DEFINE_ENUM_VALUE( FOOBAR_NETWORK_ADAPTER_STATE_CONNECTED, "connected" ), - G_DEFINE_ENUM_VALUE( FOOBAR_NETWORK_ADAPTER_STATE_LIMITED, "limited" ) ) - -// -// FoobarNetworkAdapter: -// -// Base class for Wi-Fi/ethernet network adapters. -// - -typedef struct _FoobarNetworkAdapterPrivate -{ - NMDevice* device; - NMActiveConnection* connection; - FoobarNetworkAdapterState state; - gulong connectivity_handler_id; - gulong connection_handler_id; - gulong connection_state_handler_id; -} FoobarNetworkAdapterPrivate; - -enum -{ - ADAPTER_PROP_STATE = 1, - N_ADAPTER_PROPS, -}; - -static GParamSpec* adapter_props[N_ADAPTER_PROPS] = { 0 }; - -static void foobar_network_adapter_class_init ( FoobarNetworkAdapterClass* klass ); -static void foobar_network_adapter_init ( FoobarNetworkAdapter* self ); -static void foobar_network_adapter_get_property ( GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ); -static void foobar_network_adapter_finalize ( GObject* object ); -static void foobar_network_adapter_set_device ( FoobarNetworkAdapter* self, - NMDevice* value ); -static void foobar_network_adapter_update_state ( FoobarNetworkAdapter* self ); -static void foobar_network_adapter_handle_state_change ( GObject* sender, - GParamSpec* pspec, - gpointer userdata ); -static void foobar_network_adapter_handle_connection_change( GObject* sender, - GParamSpec* pspec, - gpointer userdata ); - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE( FoobarNetworkAdapter, foobar_network_adapter, G_TYPE_OBJECT ) - -// -// FoobarNetworkAdapterWired: -// -// Represents an ethernet network adapter. -// - -struct _FoobarNetworkAdapterWired -{ - FoobarNetworkAdapter parent_instance; - NMDeviceEthernet* device; - gulong speed_handler_id; -}; - -static void foobar_network_adapter_wired_class_init ( FoobarNetworkAdapterWiredClass* klass ); -static void foobar_network_adapter_wired_init ( FoobarNetworkAdapterWired* self ); -static void foobar_network_adapter_wired_get_property ( GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ); -static void foobar_network_adapter_wired_finalize ( GObject* object ); -static FoobarNetworkAdapterWired* foobar_network_adapter_wired_new ( NMDeviceEthernet* device ); -static void foobar_network_adapter_wired_handle_speed_change( GObject* device, - GParamSpec* pspec, - gpointer userdata ); - -enum -{ - WIRED_PROP_SPEED = 1, - N_WIRED_PROPS, -}; - -static GParamSpec* wired_props[N_WIRED_PROPS] = { 0 }; - -G_DEFINE_FINAL_TYPE( FoobarNetworkAdapterWired, foobar_network_adapter_wired, FOOBAR_TYPE_NETWORK_ADAPTER ) - -// -// FoobarNetworkAdapterWifi: -// -// Represents a Wi-Fi network adapter. -// - -struct _FoobarNetworkAdapterWifi -{ - FoobarNetworkAdapter parent_instance; - GHashTable* ap_networks; - GHashTable* named_networks; - GListStore* networks; - GtkFilterListModel* filtered_networks; - GtkSortListModel* sorted_networks; - FoobarNetwork* active; - gboolean is_scanning; - NMClient* client; - NMDeviceWifi* device; - gulong enabled_handler_id; - gulong active_handler_id; - gulong added_handler_id; - gulong removed_handler_id; - guint refresh_source_id; -}; - -enum -{ - WIFI_PROP_NETWORKS = 1, - WIFI_PROP_ACTIVE, - WIFI_PROP_IS_ENABLED, - WIFI_PROP_IS_SCANNING, - N_WIFI_PROPS, -}; - -static GParamSpec* wifi_props[N_WIFI_PROPS] = { 0 }; - -static void foobar_network_adapter_wifi_class_init ( FoobarNetworkAdapterWifiClass* klass ); -static void foobar_network_adapter_wifi_init ( FoobarNetworkAdapterWifi* self ); -static void foobar_network_adapter_wifi_get_property ( GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ); -static void foobar_network_adapter_wifi_set_property ( GObject* object, - guint prop_id, - GValue const* value, - GParamSpec* pspec ); -static void foobar_network_adapter_wifi_finalize ( GObject* object ); -static FoobarNetworkAdapterWifi* foobar_network_adapter_wifi_new ( NMClient* client, - NMDeviceWifi* device ); -static void foobar_network_adapter_wifi_add_ap_to_network ( FoobarNetworkAdapterWifi* self, - NMAccessPoint* ap ); -static void foobar_network_adapter_wifi_update_active ( FoobarNetworkAdapterWifi* self ); -static void foobar_network_adapter_wifi_handle_ssid_change ( GObject* ap, - GParamSpec* pspec, - gpointer userdata ); -static void foobar_network_adapter_wifi_handle_enabled_change( GObject* client, - GParamSpec* pspec, - gpointer userdata ); -static void foobar_network_adapter_wifi_handle_active_change ( GObject* device, - GParamSpec* pspec, - gpointer userdata ); -static void foobar_network_adapter_wifi_handle_added ( NMDeviceWifi* device, - NMAccessPoint* ap, - gpointer userdata ); -static void foobar_network_adapter_wifi_handle_removed ( NMDeviceWifi* device, - NMAccessPoint* ap, - gpointer userdata ); -static gboolean foobar_network_adapter_wifi_refresh_list ( gpointer userdata ); -static gboolean foobar_network_adapter_wifi_filter_func ( gpointer item, - gpointer userdata ); -static gint foobar_network_adapter_wifi_sort_func ( gconstpointer item_a, - gconstpointer item_b, - gpointer userdata ); - -G_DEFINE_FINAL_TYPE( FoobarNetworkAdapterWifi, foobar_network_adapter_wifi, FOOBAR_TYPE_NETWORK_ADAPTER ) - -// -// ApNetworkMembership: -// -// Structure representing an AP's membership in a network. The AP is removed when the structure is destroyed. -// - -struct _ApNetworkMembership -{ - NMAccessPoint* ap; - FoobarNetwork* network; -}; - -static ApNetworkMembership* ap_network_membership_new ( NMAccessPoint* ap, - FoobarNetwork* network ); -static void ap_network_membership_destroy( ApNetworkMembership* self ); - -// -// FoobarNetworkService: -// -// Service monitoring the network state of the computer. This is implemented using the NetworkManager client library. -// - -struct _FoobarNetworkService -{ - GObject parent_instance; - NMClient* client; - FoobarNetworkAdapterWired* wired; - FoobarNetworkAdapterWifi* wifi; - FoobarNetworkAdapter* active; - gulong primary_handler_id; - gulong activating_handler_id; -}; - -enum -{ - PROP_WIRED = 1, - PROP_WIFI, - PROP_ACTIVE, - N_PROPS, -}; - -static GParamSpec* props[N_PROPS] = { 0 }; - -static void foobar_network_service_class_init ( FoobarNetworkServiceClass* klass ); -static void foobar_network_service_init ( FoobarNetworkService* self ); -static void foobar_network_service_get_property ( GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ); -static void foobar_network_service_finalize ( GObject* object ); -static void foobar_network_service_handle_connection_change( GObject* client, - GParamSpec* pspec, - gpointer userdata ); -static void foobar_network_service_update_active ( FoobarNetworkService* self ); - -G_DEFINE_FINAL_TYPE( FoobarNetworkService, foobar_network_service, G_TYPE_OBJECT ) - -// --------------------------------------------------------------------------------------------------------------------- -// Wi-Fi Network -// --------------------------------------------------------------------------------------------------------------------- - -// -// Static initialization for networks. -// -void foobar_network_class_init( FoobarNetworkClass* klass ) -{ - GObjectClass* object_klass = G_OBJECT_CLASS( klass ); - object_klass->get_property = foobar_network_get_property; - object_klass->finalize = foobar_network_finalize; - - network_props[NETWORK_PROP_NAME] = g_param_spec_string( - "name", - "Name", - "The advertised SSID of the network.", - NULL, - G_PARAM_READABLE ); - network_props[NETWORK_PROP_STRENGTH] = g_param_spec_int( - "strength", - "Strength", - "The strength of the network in percent.", - 0, - 100, - 0, - G_PARAM_READABLE ); - network_props[NETWORK_PROP_IS_ACTIVE] = g_param_spec_boolean( - "is-active", - "Is Active", - "Indicates whether the network is currently used by the client.", - FALSE, - G_PARAM_READABLE ); - g_object_class_install_properties( object_klass, N_NETWORK_PROPS, network_props ); -} - -// -// Instance initialization for networks. -// -void foobar_network_init( FoobarNetwork* self ) -{ - self->aps = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, NULL ); -} - -// -// Property getter implementation, mapping a property id to a method. -// -void foobar_network_get_property( - GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ) -{ - FoobarNetwork* self = (FoobarNetwork*)object; - - switch ( prop_id ) - { - case NETWORK_PROP_NAME: - g_value_set_string( value, foobar_network_get_name( self ) ); - break; - case NETWORK_PROP_STRENGTH: - g_value_set_int( value, foobar_network_get_strength( self ) ); - break; - case NETWORK_PROP_IS_ACTIVE: - g_value_set_boolean( value, foobar_network_is_active( self ) ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); - break; - } -} - -// -// Instance cleanup for networks. -// -void foobar_network_finalize( GObject* object ) -{ - FoobarNetwork* self = (FoobarNetwork*)object; - - GHashTableIter iter; - gpointer ap; - g_hash_table_iter_init( &iter, self->aps ); - while ( g_hash_table_iter_next( &iter, &ap, NULL ) ) - { - g_signal_handlers_disconnect_by_data( ap, self ); - } - - g_clear_pointer( &self->ssid, g_bytes_unref ); - g_clear_pointer( &self->name, g_free ); - g_clear_pointer( &self->aps, g_hash_table_unref ); - - G_OBJECT_CLASS( foobar_network_parent_class )->finalize( object ); -} - -// -// Create a new network instance. -// -FoobarNetwork* foobar_network_new( void ) -{ - return g_object_new( FOOBAR_TYPE_NETWORK, NULL ); -} - -// -// Get the advertized SSID of the network. -// -gchar const* foobar_network_get_name( FoobarNetwork* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK( self ), NULL ); - return self->name; -} - -// -// Get the current strength percentage value for the network. -// -gint foobar_network_get_strength( FoobarNetwork* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK( self ), 0 ); - return self->strength; -} - -// -// Check whether the network is currently used by the client. -// -gboolean foobar_network_is_active( FoobarNetwork* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK( self ), FALSE ); - return self->is_active; -} - -// -// Update the advertized SSID of the network. -// -// This also updates the string representation (which may be a lossy conversion). -// -void foobar_network_set_ssid( - FoobarNetwork* self, - GBytes* value ) -{ - g_return_if_fail( FOOBAR_IS_NETWORK( self ) ); - - if ( self->ssid != value ) - { - g_clear_pointer( &self->ssid, g_bytes_unref ); - g_clear_pointer( &self->name, g_free ); - - if ( value ) - { - self->ssid = g_bytes_ref( value ); - gsize ssid_len; - guint8 const* ssid_data = g_bytes_get_data( self->ssid, &ssid_len ); - self->name = nm_utils_ssid_to_utf8( ssid_data, ssid_len ); - } - - g_object_notify_by_pspec( G_OBJECT( self ), network_props[NETWORK_PROP_NAME] ); - } -} - -// -// Update the "active" flag of the network. This does not actually activate the network. -// -void foobar_network_set_active( - FoobarNetwork* self, - gboolean value ) -{ - g_return_if_fail( FOOBAR_IS_NETWORK( self ) ); - - value = !!value; - if ( self->is_active != value ) - { - self->is_active = value; - g_object_notify_by_pspec( G_OBJECT( self ), network_props[NETWORK_PROP_NAME] ); - } -} - -// -// Include the specified AP when computing the network's strength. -// -void foobar_network_add_ap( - FoobarNetwork* self, - NMAccessPoint* ap ) -{ - if ( g_hash_table_add( self->aps, g_object_ref( ap ) ) ) - { - g_signal_connect( ap, "notify::strength", G_CALLBACK( foobar_network_handle_strength_change ), self ); - foobar_network_update_strength( self ); - } -} - -// -// Stop including the specified AP when computing the network's strength. -// -void foobar_network_remove_ap( - FoobarNetwork* self, - NMAccessPoint* ap ) -{ - if ( g_hash_table_remove( self->aps, ap ) ) - { - g_signal_handlers_disconnect_by_data( ap, self ); - foobar_network_update_strength( self ); - } -} - -// -// Update the network's "strength" property to match that of the best AP for it. -// -void foobar_network_update_strength( FoobarNetwork* self ) -{ - gint strength = 0; - GHashTableIter iter; - gpointer ap; - g_hash_table_iter_init( &iter, self->aps ); - while ( g_hash_table_iter_next( &iter, &ap, NULL ) ) - { - gint ap_strength = nm_access_point_get_strength( ap ); - strength = MAX( strength, ap_strength ); - } - - strength = CLAMP( strength, 0, 100 ); - if ( self->strength != strength ) - { - self->strength = strength; - g_object_notify_by_pspec( G_OBJECT( self ), network_props[NETWORK_PROP_STRENGTH] ); - } -} - -// -// Called when the strength of an access point for this network has changed. -// -void foobar_network_handle_strength_change( - GObject* ap, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)ap; - (void)pspec; - FoobarNetwork* self = (FoobarNetwork*)userdata; - - foobar_network_update_strength( self ); -} - -// --------------------------------------------------------------------------------------------------------------------- -// Network Adapter -// --------------------------------------------------------------------------------------------------------------------- - -// -// Static initialization for network adapters. -// -void foobar_network_adapter_class_init( FoobarNetworkAdapterClass* klass ) -{ - GObjectClass* object_klass = G_OBJECT_CLASS( klass ); - object_klass->get_property = foobar_network_adapter_get_property; - object_klass->finalize = foobar_network_adapter_finalize; - - adapter_props[ADAPTER_PROP_STATE] = g_param_spec_enum( - "state", - "State", - "The current connection state of the network.", - FOOBAR_TYPE_NETWORK_ADAPTER_STATE, - FOOBAR_NETWORK_ADAPTER_STATE_DISCONNECTED, - G_PARAM_READABLE ); - g_object_class_install_properties( object_klass, N_ADAPTER_PROPS, adapter_props ); -} - -// -// Instance initialization for network adapters. -// -void foobar_network_adapter_init( FoobarNetworkAdapter* self ) -{ - (void)self; -} - -// -// Property getter implementation, mapping a property id to a method. -// -void foobar_network_adapter_get_property( - GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ) -{ - FoobarNetworkAdapter* self = (FoobarNetworkAdapter*)object; - - switch ( prop_id ) - { - case ADAPTER_PROP_STATE: - g_value_set_enum( value, foobar_network_adapter_get_state( self ) ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); - break; - } -} - -// -// Instance cleanup for network adapters. -// -void foobar_network_adapter_finalize( GObject* object ) -{ - FoobarNetworkAdapter* self = (FoobarNetworkAdapter*)object; - - foobar_network_adapter_set_device( self, NULL ); - - G_OBJECT_CLASS( foobar_network_adapter_parent_class )->finalize( object ); -} - -// -// Get the current connection/connectivity state of the adapter. -// -FoobarNetworkAdapterState foobar_network_adapter_get_state( FoobarNetworkAdapter* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_ADAPTER( self ), FOOBAR_NETWORK_ADAPTER_STATE_DISCONNECTED ); - - FoobarNetworkAdapterPrivate* priv = foobar_network_adapter_get_instance_private( self ); - return priv->state; -} - -// -// Update the backing network device which is used to derive the adapter's state. -// -void foobar_network_adapter_set_device( - FoobarNetworkAdapter* self, - NMDevice* value ) -{ - FoobarNetworkAdapterPrivate* priv = foobar_network_adapter_get_instance_private( self ); - if ( priv->device != value ) - { - g_clear_signal_handler( &priv->connection_state_handler_id, priv->connection ); - g_clear_signal_handler( &priv->connectivity_handler_id, priv->device ); - g_clear_signal_handler( &priv->connection_handler_id, priv->device ); - g_clear_object( &priv->connection ); - g_clear_object( &priv->device ); - - priv->device = value; - if ( priv->device ) - { - g_object_ref( priv->device ); - priv->connectivity_handler_id = g_signal_connect( - priv->device, - "notify::ip4-connectivity", - G_CALLBACK( foobar_network_adapter_handle_state_change ), self ); - priv->connection_handler_id = g_signal_connect( - priv->device, - "notify::active-connection", - G_CALLBACK( foobar_network_adapter_handle_connection_change ), self ); - priv->connection = nm_device_get_active_connection( priv->device ); - if ( priv->connection ) - { - g_object_ref( priv->connection ); - priv->connection_state_handler_id = g_signal_connect( - priv->connection, - "notify::state", - G_CALLBACK( foobar_network_adapter_handle_state_change ), - self ); - } - } - - foobar_network_adapter_update_state( self ); - } -} - -// -// Derive the connection/connectivity state for the network from the backing device. -// -void foobar_network_adapter_update_state( FoobarNetworkAdapter* self ) -{ - FoobarNetworkAdapterPrivate* priv = foobar_network_adapter_get_instance_private( self ); - - FoobarNetworkAdapterState state = FOOBAR_NETWORK_ADAPTER_STATE_DISCONNECTED; - if ( priv->device ) - { - NMActiveConnection* connection = nm_device_get_active_connection( priv->device ); - if ( connection ) - { - switch ( nm_active_connection_get_state( connection ) ) - { - case NM_ACTIVE_CONNECTION_STATE_ACTIVATED: - state = ( nm_device_get_connectivity( priv->device, AF_INET ) == NM_CONNECTIVITY_FULL ) - ? FOOBAR_NETWORK_ADAPTER_STATE_CONNECTED - : FOOBAR_NETWORK_ADAPTER_STATE_LIMITED; - break; - case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: - state = FOOBAR_NETWORK_ADAPTER_STATE_CONNECTING; - break; - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING: - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: - case NM_ACTIVE_CONNECTION_STATE_UNKNOWN: - default: - state = FOOBAR_NETWORK_ADAPTER_STATE_DISCONNECTED; - break; - } - } - } - - if ( priv->state != state ) - { - priv->state = state; - g_object_notify_by_pspec( G_OBJECT( self ), adapter_props[ADAPTER_PROP_STATE] ); - } -} - -// -// Called when the "ip4-connectivity" property of the NetworkManager device or the "state" property of the active -// connection has changed. -// -static void foobar_network_adapter_handle_state_change( - GObject* sender, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)sender; - (void)pspec; - FoobarNetworkAdapter* self = (FoobarNetworkAdapter*)userdata; - - foobar_network_adapter_update_state( self ); -} - -// -// Called when the "active-connection" property of the NetworkManager device has changed. -// -// This updates the state of the adapter and sets the connection up for state change listening. -// -static void foobar_network_adapter_handle_connection_change( - GObject* sender, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)sender; - (void)pspec; - FoobarNetworkAdapter* self = (FoobarNetworkAdapter*)userdata; - FoobarNetworkAdapterPrivate* priv = foobar_network_adapter_get_instance_private( self ); - - g_clear_signal_handler( &priv->connection_state_handler_id, priv->connection ); - g_clear_object( &priv->connection ); - - priv->connection = nm_device_get_active_connection( priv->device ); - if ( priv->connection ) - { - g_object_ref( priv->connection ); - priv->connection_state_handler_id = g_signal_connect( - priv->connection, - "notify::state", - G_CALLBACK( foobar_network_adapter_handle_state_change ), - self ); - } - - foobar_network_adapter_update_state( self ); -} - -// --------------------------------------------------------------------------------------------------------------------- -// Wired Network Adapter -// --------------------------------------------------------------------------------------------------------------------- - -// -// Static initialization for wired network adapters. -// -void foobar_network_adapter_wired_class_init( FoobarNetworkAdapterWiredClass* klass ) -{ - GObjectClass* object_klass = G_OBJECT_CLASS( klass ); - object_klass->get_property = foobar_network_adapter_wired_get_property; - object_klass->finalize = foobar_network_adapter_wired_finalize; - - wired_props[WIRED_PROP_SPEED] = g_param_spec_int64( - "speed", - "Speed", - "The supported speed of the adapter in Mbit/s.", - 0, - INT64_MAX, - 0, - G_PARAM_READABLE ); - g_object_class_install_properties( object_klass, N_WIRED_PROPS, wired_props ); -} - -// -// Instance initialization for wired network adapters. -// -void foobar_network_adapter_wired_init( FoobarNetworkAdapterWired* self ) -{ - (void)self; -} - -// -// Property getter implementation, mapping a property id to a method. -// -void foobar_network_adapter_wired_get_property( - GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ) -{ - FoobarNetworkAdapterWired* self = (FoobarNetworkAdapterWired*)object; - - switch ( prop_id ) - { - case WIRED_PROP_SPEED: - g_value_set_int64( value, foobar_network_adapter_wired_get_speed( self ) ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); - break; - } -} - -// -// Instance cleanup for wired network adapters. -// -void foobar_network_adapter_wired_finalize( GObject* object ) -{ - FoobarNetworkAdapterWired* self = (FoobarNetworkAdapterWired*)object; - - g_clear_signal_handler( &self->speed_handler_id, self->device ); - g_clear_object( &self->device ); - - G_OBJECT_CLASS( foobar_network_adapter_wired_parent_class )->finalize( object ); -} - -// -// Create a new wired network adapter wrapping the provided NetworkManager device. -// -FoobarNetworkAdapterWired* foobar_network_adapter_wired_new( NMDeviceEthernet* device ) -{ - FoobarNetworkAdapterWired* self = g_object_new( FOOBAR_TYPE_NETWORK_ADAPTER_WIRED, NULL ); - foobar_network_adapter_set_device( FOOBAR_NETWORK_ADAPTER( self ), NM_DEVICE( device ) ); - - self->device = g_object_ref( device ); - self->speed_handler_id = g_signal_connect( - self->device, - "notify::speed", - G_CALLBACK( foobar_network_adapter_wired_handle_speed_change ), - self ); - return self; -} - -// -// Get the supported speed of the adapter in Mbit/s. -// -gint64 foobar_network_adapter_wired_get_speed( FoobarNetworkAdapterWired* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_ADAPTER_WIRED( self ), 0 ); - return nm_device_ethernet_get_speed( self->device ); -} - -// -// Called when the "speed" property of the NetworkManager device changes. -// -void foobar_network_adapter_wired_handle_speed_change( - GObject* device, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)device; - (void)pspec; - FoobarNetworkAdapterWired* self = (FoobarNetworkAdapterWired*)userdata; - - g_object_notify_by_pspec( G_OBJECT( self ), wired_props[WIRED_PROP_SPEED] ); -} - -// --------------------------------------------------------------------------------------------------------------------- -// Wireless Network Adapter -// --------------------------------------------------------------------------------------------------------------------- - -// -// Static initialization for wireless network adapters. -// -void foobar_network_adapter_wifi_class_init( FoobarNetworkAdapterWifiClass* klass ) -{ - GObjectClass* object_klass = G_OBJECT_CLASS( klass ); - object_klass->get_property = foobar_network_adapter_wifi_get_property; - object_klass->set_property = foobar_network_adapter_wifi_set_property; - object_klass->finalize = foobar_network_adapter_wifi_finalize; - - wifi_props[WIFI_PROP_NETWORKS] = g_param_spec_object( - "networks", - "Networks", - "Sorted list of available networks.", - G_TYPE_LIST_MODEL, - G_PARAM_READABLE ); - wifi_props[WIFI_PROP_ACTIVE] = g_param_spec_object( - "active", - "Active", - "The currently active network (if any).", - FOOBAR_TYPE_NETWORK, - G_PARAM_READABLE ); - wifi_props[WIFI_PROP_IS_ENABLED] = g_param_spec_boolean( - "is-enabled", - "Is Enabled", - "Indicates whether the wifi adapter is currently enabled.", - FALSE, - G_PARAM_READWRITE ); - wifi_props[WIFI_PROP_IS_SCANNING] = g_param_spec_boolean( - "is-scanning", - "Is Scanning", - "Indicates whether the wifi adapter is currently scanning for available networks.", - FALSE, - G_PARAM_READWRITE ); - g_object_class_install_properties( object_klass, N_WIFI_PROPS, wifi_props ); -} - -// -// Instance initialization for wireless network adapters. -// -void foobar_network_adapter_wifi_init( FoobarNetworkAdapterWifi* self ) -{ - self->ap_networks = g_hash_table_new_full( - g_direct_hash, - g_direct_equal, - g_object_unref, - (GDestroyNotify)ap_network_membership_destroy ); - self->named_networks = g_hash_table_new_full( - g_bytes_hash, - g_bytes_equal, - (GDestroyNotify)g_bytes_unref, - g_object_unref ); - self->networks = g_list_store_new( FOOBAR_TYPE_NETWORK ); - - GtkCustomFilter* filter = gtk_custom_filter_new( foobar_network_adapter_wifi_filter_func, NULL, NULL ); - self->filtered_networks = gtk_filter_list_model_new( - G_LIST_MODEL( g_object_ref( self->networks ) ), - GTK_FILTER( filter ) ); - - GtkCustomSorter* sorter = gtk_custom_sorter_new( foobar_network_adapter_wifi_sort_func, NULL, NULL ); - self->sorted_networks = gtk_sort_list_model_new( - G_LIST_MODEL( g_object_ref( self->filtered_networks ) ), - GTK_SORTER( sorter ) ); -} - -// -// Property getter implementation, mapping a property id to a method. -// -void foobar_network_adapter_wifi_get_property( - GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ) -{ - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)object; - - switch ( prop_id ) - { - case WIFI_PROP_NETWORKS: - g_value_set_object( value, foobar_network_adapter_wifi_get_networks( self ) ); - break; - case WIFI_PROP_ACTIVE: - g_value_set_object( value, foobar_network_adapter_wifi_get_active( self ) ); - break; - case WIFI_PROP_IS_ENABLED: - g_value_set_boolean( value, foobar_network_adapter_wifi_is_enabled( self ) ); - break; - case WIFI_PROP_IS_SCANNING: - g_value_set_boolean( value, foobar_network_adapter_wifi_is_scanning( self ) ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); - break; - } -} - -// -// Property setter implementation, mapping a property id to a method. -// -void foobar_network_adapter_wifi_set_property( - GObject* object, - guint prop_id, - GValue const* value, - GParamSpec* pspec ) -{ - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)object; - - switch ( prop_id ) - { - case WIFI_PROP_IS_ENABLED: - foobar_network_adapter_wifi_set_enabled( self, g_value_get_boolean( value ) ); - break; - case WIFI_PROP_IS_SCANNING: - foobar_network_adapter_wifi_set_scanning( self, g_value_get_boolean( value ) ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); - break; - } -} - -// -// Instance cleanup for wireless network adapters. -// -void foobar_network_adapter_wifi_finalize( GObject* object ) -{ - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)object; - - GPtrArray const* aps = nm_device_wifi_get_access_points( self->device ); - for ( guint i = 0; i < aps->len; ++i ) - { - NMAccessPoint* ap = g_ptr_array_index( aps, i ); - g_signal_handlers_disconnect_by_data( ap, self ); - } - - g_clear_handle_id( &self->refresh_source_id, g_source_remove ); - g_clear_signal_handler( &self->enabled_handler_id, self->client ); - g_clear_signal_handler( &self->active_handler_id, self->device ); - g_clear_signal_handler( &self->added_handler_id, self->device ); - g_clear_signal_handler( &self->removed_handler_id, self->device ); - g_clear_object( &self->client ); - g_clear_object( &self->device ); - g_clear_object( &self->sorted_networks ); - g_clear_object( &self->filtered_networks ); - g_clear_object( &self->networks ); - g_clear_object( &self->active ); - g_clear_pointer( &self->named_networks, g_hash_table_unref ); - g_clear_pointer( &self->ap_networks, g_hash_table_unref ); - - G_OBJECT_CLASS( foobar_network_adapter_wifi_parent_class )->finalize( object ); -} - -// -// Create a new wireless network adapter wrapping the provided NetworkManager device. -// -FoobarNetworkAdapterWifi* foobar_network_adapter_wifi_new( - NMClient* client, - NMDeviceWifi* device ) -{ - FoobarNetworkAdapterWifi* self = g_object_new( FOOBAR_TYPE_NETWORK_ADAPTER_WIFI, NULL ); - foobar_network_adapter_set_device( FOOBAR_NETWORK_ADAPTER( self ), NM_DEVICE( device ) ); - - self->client = g_object_ref( client ); - self->device = g_object_ref( device ); - self->enabled_handler_id = g_signal_connect( - self->client, - "notify::wireless-enabled", - G_CALLBACK( foobar_network_adapter_wifi_handle_enabled_change ), - self ); - self->active_handler_id = g_signal_connect( - self->device, - "notify::active-access-point", - G_CALLBACK( foobar_network_adapter_wifi_handle_active_change ), - self ); - self->added_handler_id = g_signal_connect( - self->device, - "access-point-added", - G_CALLBACK( foobar_network_adapter_wifi_handle_added ), - self ); - self->removed_handler_id = g_signal_connect( - self->device, - "access-point-removed", - G_CALLBACK( foobar_network_adapter_wifi_handle_removed ), - self ); - - GPtrArray const* aps = nm_device_wifi_get_access_points( self->device ); - for ( guint i = 0; i < aps->len; ++i ) - { - NMAccessPoint* ap = g_ptr_array_index( aps, i ); - g_signal_connect( - ap, - "notify::ssid", - G_CALLBACK( foobar_network_adapter_wifi_handle_ssid_change ), - self ); - foobar_network_adapter_wifi_add_ap_to_network( self, ap ); - } - - foobar_network_adapter_wifi_update_active( self ); - return self; -} - -// -// Get a sorted list of available networks. -// -GListModel* foobar_network_adapter_wifi_get_networks( FoobarNetworkAdapterWifi* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_ADAPTER_WIFI( self ), NULL ); - return G_LIST_MODEL( self->sorted_networks ); -} - -// -// Get the currently active network (if any). -// -FoobarNetwork* foobar_network_adapter_wifi_get_active( FoobarNetworkAdapterWifi* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_ADAPTER_WIFI( self ), NULL ); - return self->active; -} - -// -// Check whether the wifi adapter is currently enabled. -// -gboolean foobar_network_adapter_wifi_is_enabled( FoobarNetworkAdapterWifi* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_ADAPTER_WIFI( self ), FALSE ); - return nm_client_wireless_get_enabled( self->client ); -} - -// -// Check whether the wifi adapter is currently scanning for available networks. -// -gboolean foobar_network_adapter_wifi_is_scanning( FoobarNetworkAdapterWifi* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_ADAPTER_WIFI( self ), FALSE ); - return self->is_scanning; -} - -// -// Update whether the wifi adapter is currently enabled. -// -void foobar_network_adapter_wifi_set_enabled( - FoobarNetworkAdapterWifi* self, - gboolean value ) -{ - g_return_if_fail( FOOBAR_IS_NETWORK_ADAPTER_WIFI( self ) ); - - if ( !value ) { foobar_network_adapter_wifi_set_scanning( self, FALSE ); } - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - nm_client_wireless_set_enabled( self->client, value ); -#pragma GCC diagnostic pop -} - -// -// Update whether the wifi adapter is currently scanning for available networks. -// -void foobar_network_adapter_wifi_set_scanning( - FoobarNetworkAdapterWifi* self, - gboolean value ) -{ - g_return_if_fail( FOOBAR_IS_NETWORK_ADAPTER_WIFI( self ) ); - - value = value && foobar_network_adapter_wifi_is_enabled( self ); - if ( self->is_scanning != value ) - { - self->is_scanning = value; - g_object_notify_by_pspec( G_OBJECT( self ), wifi_props[WIFI_PROP_IS_SCANNING] ); - - // Periodically start scans until "is-scanning" is disabled again. - - g_clear_handle_id( &self->refresh_source_id, g_source_remove ); - if ( self->is_scanning ) - { - foobar_network_adapter_wifi_refresh_list( self ); - self->refresh_source_id = g_timeout_add( - SCAN_REFRESH_INTERVAL, - foobar_network_adapter_wifi_refresh_list, - self ); - } - } -} - -// -// Ensure that a network for the specified access point exists. -// -// If the AP has an SSID, it is added to the network for this SSID. Otherwise, a new network for this AP is created just -// for this network. -// -void foobar_network_adapter_wifi_add_ap_to_network( - FoobarNetworkAdapterWifi* self, - NMAccessPoint* ap ) -{ - // The AP is automatically added/removed from the network when using g_hash_table_replace because of the - // ApNetworkMembership destroy function. - - GBytes* ssid = nm_access_point_get_ssid( ap ); - if ( ssid ) - { - FoobarNetwork* network = g_hash_table_lookup( self->named_networks, ssid ); - if ( !network ) - { - network = foobar_network_new( ); - foobar_network_set_ssid( network, ssid ); - g_list_store_append( self->networks, network ); - g_hash_table_insert( self->named_networks, g_bytes_ref( ssid ), network ); - } - - g_hash_table_replace( self->ap_networks, g_object_ref( ap ), ap_network_membership_new( ap, network ) ); - } - else - { - g_autoptr( FoobarNetwork ) network = foobar_network_new( ); - g_hash_table_replace( self->ap_networks, g_object_ref( ap ), ap_network_membership_new( ap, network ) ); - } - - gtk_filter_changed( gtk_filter_list_model_get_filter( self->filtered_networks ), GTK_FILTER_CHANGE_DIFFERENT ); -} - -// -// Update the active network based on the active access point. -// -void foobar_network_adapter_wifi_update_active( FoobarNetworkAdapterWifi* self ) -{ - NMAccessPoint* active_ap = nm_device_wifi_get_active_access_point( self->device ); - ApNetworkMembership* membership = active_ap ? g_hash_table_lookup( self->ap_networks, active_ap ) : NULL; - FoobarNetwork* new_active = membership ? membership->network : NULL; - - if ( self->active != new_active ) - { - if ( self->active ) - { - foobar_network_set_active( self->active, FALSE ); - } - g_clear_object( &self->active ); - - self->active = new_active; - if ( self->active ) - { - g_object_ref( self->active ); - foobar_network_set_active( self->active, TRUE ); - } - - g_object_notify_by_pspec( G_OBJECT( self ), wifi_props[WIFI_PROP_ACTIVE] ); - } -} - -// -// Called when the SSID for an access point changes. -// -// This will remove the access point from the old network and associate it with its new network. -// -void foobar_network_adapter_wifi_handle_ssid_change( - GObject* ap, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)pspec; - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)userdata; - - foobar_network_adapter_wifi_add_ap_to_network( self, NM_ACCESS_POINT( ap ) ); - foobar_network_adapter_wifi_update_active( self ); -} - -// -// Called when the "wireless-enabled" state of the client changes. -// -void foobar_network_adapter_wifi_handle_enabled_change( - GObject* client, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)client; - (void)pspec; - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)userdata; - - g_object_notify_by_pspec( G_OBJECT( self ), wifi_props[WIFI_PROP_IS_ENABLED] ); -} - -// -// Called when the active access point of the backing device changes. -// -void foobar_network_adapter_wifi_handle_active_change( - GObject* device, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)device; - (void)pspec; - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)userdata; - - foobar_network_adapter_wifi_update_active( self ); -} - -// -// Called when a new access point is added. -// -// This will associate the access point with its network. -// -void foobar_network_adapter_wifi_handle_added( - NMDeviceWifi* device, - NMAccessPoint* ap, - gpointer userdata ) -{ - (void)device; - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)userdata; - - g_signal_connect( - ap, - "notify::ssid", - G_CALLBACK( foobar_network_adapter_wifi_handle_ssid_change ), - self ); - foobar_network_adapter_wifi_add_ap_to_network( self, ap ); -} - -// -// Called when an access point is removed. -// -// This will remove it from its network. -// -void foobar_network_adapter_wifi_handle_removed( - NMDeviceWifi* device, - NMAccessPoint* ap, - gpointer userdata ) -{ - (void)device; - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)userdata; - - g_signal_handlers_disconnect_by_data( ap, self ); - g_hash_table_remove( self->ap_networks, ap ); // Will remove the AP from the network. - gtk_filter_changed( gtk_filter_list_model_get_filter( self->filtered_networks ), GTK_FILTER_CHANGE_MORE_STRICT ); -} - -// -// Periodic callback to start a network scan. -// -gboolean foobar_network_adapter_wifi_refresh_list( gpointer userdata ) -{ - FoobarNetworkAdapterWifi* self = (FoobarNetworkAdapterWifi*)userdata; - - g_autoptr( GError ) error = NULL; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - if ( !nm_device_wifi_request_scan( self->device, NULL, &error ) ) -#pragma GCC diagnostic pop - { - g_warning( "Unable to start Wi-Fi network scan: %s", error->message ); - } - - return G_SOURCE_CONTINUE; -} - -// -// Filtering callback for the list of networks. Only networks with at least one AP are shown. -// -gboolean foobar_network_adapter_wifi_filter_func( - gpointer item, - gpointer userdata ) -{ - (void)userdata; - - FoobarNetwork* network = (FoobarNetwork*)item; - return g_hash_table_size( network->aps ) > 0; -} - -// -// Sorting callback for the list of networks. -// -gint foobar_network_adapter_wifi_sort_func( - gconstpointer item_a, - gconstpointer item_b, - gpointer userdata ) -{ - (void)userdata; - - FoobarNetwork* network_a = (FoobarNetwork*)item_a; - FoobarNetwork* network_b = (FoobarNetwork*)item_b; - return g_strcmp0( foobar_network_get_name( network_a ), foobar_network_get_name( network_b ) ); -} - -// --------------------------------------------------------------------------------------------------------------------- -// Access Point Network Memberships -// --------------------------------------------------------------------------------------------------------------------- - -// -// Create an association between an access point and the network it belongs to. -// -ApNetworkMembership* ap_network_membership_new( - NMAccessPoint* ap, - FoobarNetwork* network ) -{ - ApNetworkMembership* self = g_new0( ApNetworkMembership, 1 ); - self->ap = ap; - self->network = g_object_ref( network ); - foobar_network_add_ap( self->network, self->ap ); - return self; -} - -// -// Destroy an association between an access point and its previous network. -// -void ap_network_membership_destroy( ApNetworkMembership* self ) -{ - if ( self ) - { - foobar_network_remove_ap( self->network, self->ap ); - g_object_unref( self->network ); - g_free( self ); - } -} - -// --------------------------------------------------------------------------------------------------------------------- -// Service Implementation -// --------------------------------------------------------------------------------------------------------------------- - -// -// Static initialization for the network service. -// -void foobar_network_service_class_init( FoobarNetworkServiceClass* klass ) -{ - GObjectClass* object_klass = G_OBJECT_CLASS( klass ); - object_klass->get_property = foobar_network_service_get_property; - object_klass->finalize = foobar_network_service_finalize; - - props[PROP_WIRED] = g_param_spec_object( - "wired", - "Wired", - "The wired network adapter (if available).", - FOOBAR_TYPE_NETWORK_ADAPTER_WIRED, - G_PARAM_READABLE ); - props[PROP_WIFI] = g_param_spec_object( - "wifi", - "WiFi", - "The wireless network adapter (if available).", - FOOBAR_TYPE_NETWORK_ADAPTER_WIFI, - G_PARAM_READABLE ); - props[PROP_ACTIVE] = g_param_spec_object( - "active", - "Active", - "The network adapter currently in use.", - FOOBAR_TYPE_NETWORK_ADAPTER, - G_PARAM_READABLE ); - g_object_class_install_properties( object_klass, N_PROPS, props ); -} - -// -// Instance initialization for the network service. -// -void foobar_network_service_init( FoobarNetworkService* self ) -{ - g_autoptr( GError ) error = NULL; - self->client = nm_client_new( NULL, &error ); - if ( !self->client ) - { - g_warning( "Unable to connect to NetworkManager: %s", error->message ); - return; - } - - NMDeviceEthernet* device_wired = NULL; - NMDeviceWifi* device_wifi = NULL; - GPtrArray const* devices = nm_client_get_devices( self->client ); - for ( guint i = 0; i < devices->len; ++i ) - { - // XXX: Add support for multiple devices - NMDevice* device = g_ptr_array_index( devices, i ); - if ( !device_wired && NM_IS_DEVICE_ETHERNET( device ) ) - { - device_wired = NM_DEVICE_ETHERNET( device ); - } - if ( !device_wifi && NM_IS_DEVICE_WIFI( device ) ) - { - device_wifi = NM_DEVICE_WIFI( device ); - } - if ( device_wired && device_wifi ) - { - break; - } - } - - self->wired = device_wired ? foobar_network_adapter_wired_new( device_wired ) : NULL; - self->wifi = device_wifi ? foobar_network_adapter_wifi_new( self->client, device_wifi ) : NULL; - - foobar_network_service_update_active( self ); - self->primary_handler_id = g_signal_connect( - self->client, - "notify::primary-connection", - G_CALLBACK( foobar_network_service_handle_connection_change ), - self ); - self->activating_handler_id = g_signal_connect( - self->client, - "notify::activating-connection", - G_CALLBACK( foobar_network_service_handle_connection_change ), - self ); -} - -// -// Property getter implementation, mapping a property id to a method. -// -void foobar_network_service_get_property( - GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ) -{ - FoobarNetworkService* self = (FoobarNetworkService*)object; - - switch ( prop_id ) - { - case PROP_WIRED: - g_value_set_object( value, foobar_network_service_get_wired( self ) ); - break; - case PROP_WIFI: - g_value_set_object( value, foobar_network_service_get_wifi( self ) ); - break; - case PROP_ACTIVE: - g_value_set_object( value, foobar_network_service_get_active( self ) ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); - break; - } -} - -// -// Instance cleanup for the network service. -// -void foobar_network_service_finalize( GObject* object ) -{ - FoobarNetworkService* self = (FoobarNetworkService*)object; - - g_clear_signal_handler( &self->primary_handler_id, self->client ); - g_clear_signal_handler( &self->activating_handler_id, self->client ); - g_clear_object( &self->wifi ); - g_clear_object( &self->wired ); - g_clear_object( &self->client ); - - G_OBJECT_CLASS( foobar_network_service_parent_class )->finalize( object ); -} - -// --------------------------------------------------------------------------------------------------------------------- -// Public API -// --------------------------------------------------------------------------------------------------------------------- - -// -// Create a new network service instance. -// -FoobarNetworkService* foobar_network_service_new( void ) -{ - return g_object_new( FOOBAR_TYPE_NETWORK_SERVICE, NULL ); -} - -// -// Get the wired network adapter (if available). -// -FoobarNetworkAdapterWired* foobar_network_service_get_wired( FoobarNetworkService* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_SERVICE( self ), NULL ); - return self->wired; -} - -// -// Get the wireless network adapter (if available). -// -FoobarNetworkAdapterWifi* foobar_network_service_get_wifi( FoobarNetworkService* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_SERVICE( self ), NULL ); - return self->wifi; -} - -// -// Get the network adapter currently in use. -// -FoobarNetworkAdapter* foobar_network_service_get_active( FoobarNetworkService* self ) -{ - g_return_val_if_fail( FOOBAR_IS_NETWORK_SERVICE( self ), NULL ); - return self->active; -} - -// --------------------------------------------------------------------------------------------------------------------- -// Signal Handlers -// --------------------------------------------------------------------------------------------------------------------- - -// -// Called when either the primary connection or the activating connection of the client has changed. -// -void foobar_network_service_handle_connection_change( - GObject* client, - GParamSpec* pspec, - gpointer userdata ) -{ - (void)client; - (void)pspec; - FoobarNetworkService* self = (FoobarNetworkService*)userdata; - - foobar_network_service_update_active( self ); -} - -// --------------------------------------------------------------------------------------------------------------------- -// Helper Methods -// --------------------------------------------------------------------------------------------------------------------- - -// -// Update the active network adapter. -// -// This uses the primary connection of the client to determine whether the wireless or wired adapter is used. Otherwise, -// the activating connection is used instead. -// -void foobar_network_service_update_active( FoobarNetworkService* self ) -{ - NMActiveConnection* connection = nm_client_get_primary_connection( self->client ); - connection = connection ? connection : nm_client_get_activating_connection( self->client ); - gchar const* type = connection ? nm_active_connection_get_connection_type( connection ) : NULL; - - FoobarNetworkAdapter* new_active; - if ( !g_strcmp0( type, "802-11-wireless" ) ) - { - new_active = FOOBAR_NETWORK_ADAPTER( self->wifi ); - } - else if ( !g_strcmp0( type, "802-3-ethernet" ) ) - { - new_active = FOOBAR_NETWORK_ADAPTER( self->wired ); - } - else - { - new_active = self->wifi ? FOOBAR_NETWORK_ADAPTER( self->wifi ) : FOOBAR_NETWORK_ADAPTER( self->wired ); - } - - if ( self->active != new_active ) - { - self->active = new_active; - g_object_notify_by_pspec( G_OBJECT( self ), props[PROP_ACTIVE] ); - } -} |
