summaryrefslogtreecommitdiff
path: root/src/services/network-service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/services/network-service.c')
-rw-r--r--src/services/network-service.c1577
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] );
- }
-}