From fe6b86a0789551e364908bf21e205c21b75dc0a1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Feb 2014 06:56:54 -0600 Subject: [PATCH 1/9] core: don't ref the Manager singleton The OLPC mesh code did rely on nm_manager_get() referencing the singleton when returning it, but all other callers of nm_manager_get() did not. Thus the manager's refcount would always increase and almost never decrease. Fix the refcounting so that the manager always has only one ref, and it's lifetime is controlled by main() and nothing else. --- src/devices/nm-device-olpc-mesh.c | 14 +++----------- src/main.c | 2 +- src/nm-manager.c | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/devices/nm-device-olpc-mesh.c b/src/devices/nm-device-olpc-mesh.c index c419daa5e7..b85956ef63 100644 --- a/src/devices/nm-device-olpc-mesh.c +++ b/src/devices/nm-device-olpc-mesh.c @@ -362,7 +362,6 @@ dispose (GObject *object) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object); NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - NMManager *manager; if (priv->dispose_has_run) { G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); @@ -375,12 +374,10 @@ dispose (GObject *object) companion_cleanup (self); - manager = nm_manager_get (); if (priv->device_added_id) - g_signal_handler_disconnect (manager, priv->device_added_id); + g_signal_handler_disconnect (nm_manager_get (), priv->device_added_id); if (priv->device_removed_id) - g_signal_handler_disconnect (manager, priv->device_removed_id); - g_object_unref (manager); + g_signal_handler_disconnect (nm_manager_get (), priv->device_removed_id); G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); } @@ -536,7 +533,6 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other) NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); const guint8 *my_addr, *their_addr; guint their_addr_len; - NMManager *manager; if (!NM_IS_DEVICE_WIFI (other)) return FALSE; @@ -550,12 +546,10 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other) priv->companion = other; /* When we've found the companion, stop listening for other devices */ - manager = nm_manager_get (); if (priv->device_added_id) { - g_signal_handler_disconnect (manager, priv->device_added_id); + g_signal_handler_disconnect (nm_manager_get (), priv->device_added_id); priv->device_added_id = 0; } - g_object_unref (manager); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED, @@ -632,8 +626,6 @@ check_companion_cb (gpointer user_data) break; } - g_object_unref (manager); - done: nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion"); return FALSE; diff --git a/src/main.c b/src/main.c index a25432feef..16a124c14f 100644 --- a/src/main.c +++ b/src/main.c @@ -66,7 +66,6 @@ /* * Globals */ -static NMManager *manager = NULL; static GMainLoop *main_loop = NULL; static gboolean quit_early = FALSE; static sigset_t signal_set; @@ -312,6 +311,7 @@ main (int argc, char *argv[]) gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE; gboolean success, show_version = FALSE; int i; + NMManager *manager = NULL; gs_unref_object NMVPNManager *vpn_manager = NULL; gs_unref_object NMDnsManager *dns_mgr = NULL; gs_unref_object NMDBusManager *dbus_mgr = NULL; diff --git a/src/nm-manager.c b/src/nm-manager.c index da99a02d77..6126c86281 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -4690,7 +4690,7 @@ NMManager * nm_manager_get (void) { g_assert (singleton); - return g_object_ref (singleton); + return singleton; } NMManager * From fd3fe2200c13562ea9229fa8d1fa266136ed46e9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Feb 2014 06:59:05 -0600 Subject: [PATCH 2/9] core: add nm_connection_provider_get() In reality the connection provider (NMSettings) is always the same object, and some device plugins need access to it. Instead of cluttering up the device plugin API by passing the provider into every plugin regardless of whether the plugin needs it, create a getter function. --- src/devices/nm-device-private.h | 2 - src/devices/nm-device-vlan.c | 3 +- src/devices/nm-device-wifi.c | 3 +- src/devices/nm-device.c | 88 +++++++++------------------------ src/devices/nm-device.h | 2 - src/nm-connection-provider.h | 7 +++ src/nm-manager.c | 10 +++- 7 files changed, 41 insertions(+), 74 deletions(-) diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 3da14795c4..e4e5a4dbca 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -80,8 +80,6 @@ void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); -NMConnectionProvider *nm_device_get_connection_provider (NMDevice *device); - void nm_device_recheck_available_connections (NMDevice *device); void nm_device_queued_state_clear (NMDevice *device); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index f64fd87eb7..8e10aef5d8 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -341,11 +341,10 @@ update_connection (NMDevice *device, NMConnection *connection) new_parent = nm_device_get_iface (parent); setting_parent = nm_setting_vlan_get_parent (s_vlan); if (setting_parent && nm_utils_is_uuid (setting_parent)) { - NMConnectionProvider *cp = nm_device_get_connection_provider (device); NMConnection *parent_connection; /* Don't change a parent specified by UUID if it's still valid */ - parent_connection = nm_connection_provider_get_connection_by_uuid (cp, setting_parent); + parent_connection = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent); if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection, NULL)) new_parent = NULL; } diff --git a/src/devices/nm-device-wifi.c b/src/devices/nm-device-wifi.c index fe4c7e0f91..f9c77d1409 100644 --- a/src/devices/nm-device-wifi.c +++ b/src/devices/nm-device-wifi.c @@ -1603,7 +1603,6 @@ build_hidden_probe_list (NMDeviceWifi *self) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); guint max_scan_ssids = nm_supplicant_interface_get_max_scan_ssids (priv->supplicant.iface); - NMConnectionProvider *provider = nm_device_get_connection_provider (NM_DEVICE (self)); GSList *connections, *iter; GPtrArray *ssids = NULL; static GByteArray *nullssid = NULL; @@ -1616,7 +1615,7 @@ build_hidden_probe_list (NMDeviceWifi *self) if (G_UNLIKELY (nullssid == NULL)) nullssid = g_byte_array_new (); - connections = nm_connection_provider_get_best_connections (provider, + connections = nm_connection_provider_get_best_connections (nm_connection_provider_get (), max_scan_ssids - 1, NM_SETTING_WIRELESS_SETTING_NAME, NULL, diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e5db1f5f89..5c18a3cb8c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -315,13 +315,6 @@ typedef struct { GSList * slaves; /* list of SlaveInfo */ NMConnectionProvider *con_provider; - - /* connection provider signals for available connections property */ - guint cp_added_id; - guint cp_loaded_id; - guint cp_removed_id; - guint cp_updated_id; - } NMDevicePrivate; static gboolean nm_device_set_ip4_config (NMDevice *dev, @@ -613,6 +606,23 @@ constructed (GObject *object) if (priv->ifindex > 0) priv->mtu = nm_platform_link_get_mtu (priv->ifindex); + priv->con_provider = nm_connection_provider_get (); + g_assert (priv->con_provider); + g_signal_connect (priv->con_provider, + NM_CP_SIGNAL_CONNECTION_ADDED, + G_CALLBACK (cp_connection_added), + dev); + + g_signal_connect (priv->con_provider, + NM_CP_SIGNAL_CONNECTION_REMOVED, + G_CALLBACK (cp_connection_removed), + dev); + + g_signal_connect (priv->con_provider, + NM_CP_SIGNAL_CONNECTION_UPDATED, + G_CALLBACK (cp_connection_updated), + dev); + if (G_OBJECT_CLASS (nm_device_parent_class)->constructed) G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); } @@ -884,43 +894,6 @@ nm_device_get_type_desc (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->type_desc; } -void -nm_device_set_connection_provider (NMDevice *device, - NMConnectionProvider *provider) -{ - NMDevicePrivate *priv; - - g_return_if_fail (device != NULL); - g_return_if_fail (NM_IS_CONNECTION_PROVIDER (provider)); - - priv = NM_DEVICE_GET_PRIVATE (device); - g_return_if_fail (priv->con_provider == NULL); - - priv->con_provider = provider; - priv->cp_added_id = g_signal_connect (priv->con_provider, - NM_CP_SIGNAL_CONNECTION_ADDED, - G_CALLBACK (cp_connection_added), - device); - - priv->cp_removed_id = g_signal_connect (priv->con_provider, - NM_CP_SIGNAL_CONNECTION_REMOVED, - G_CALLBACK (cp_connection_removed), - device); - - priv->cp_updated_id = g_signal_connect (priv->con_provider, - NM_CP_SIGNAL_CONNECTION_UPDATED, - G_CALLBACK (cp_connection_updated), - device); -} - -NMConnectionProvider * -nm_device_get_connection_provider (NMDevice *device) -{ - g_return_val_if_fail (device != NULL, NULL); - - return NM_DEVICE_GET_PRIVATE (device)->con_provider; -} - static SlaveInfo * find_slave_info (NMDevice *self, NMDevice *slave) { @@ -5508,34 +5481,21 @@ dispose (GObject *object) priv->carrier_defer_id = 0; } - if (priv->cp_added_id) { - g_signal_handler_disconnect (priv->con_provider, priv->cp_added_id); - priv->cp_added_id = 0; + if (priv->con_provider) { + g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_added, self); + g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_removed, self); + g_signal_handlers_disconnect_by_func (priv->con_provider, cp_connection_updated, self); + priv->con_provider = NULL; } - if (priv->cp_loaded_id) { - g_signal_handler_disconnect (priv->con_provider, priv->cp_loaded_id); - priv->cp_loaded_id = 0; - } - - if (priv->cp_removed_id) { - g_signal_handler_disconnect (priv->con_provider, priv->cp_removed_id); - priv->cp_removed_id = 0; - } - - if (priv->cp_updated_id) { - g_signal_handler_disconnect (priv->con_provider, priv->cp_updated_id); - priv->cp_updated_id = 0; - } + g_hash_table_unref (priv->available_connections); + priv->available_connections = NULL; if (priv->carrier_wait_id) { g_source_remove (priv->carrier_wait_id); priv->carrier_wait_id = 0; } - g_hash_table_unref (priv->available_connections); - priv->available_connections = NULL; - g_clear_pointer (&priv->physical_port_id, g_free); activation_source_clear (self, TRUE, AF_INET); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index c346ccb42e..c973b9864d 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -316,8 +316,6 @@ gboolean nm_device_get_firmware_missing (NMDevice *self); void nm_device_queue_activation (NMDevice *device, NMActRequest *req); -void nm_device_set_connection_provider (NMDevice *device, NMConnectionProvider *provider); - gboolean nm_device_supports_vlans (NMDevice *device); void nm_device_add_pending_action (NMDevice *device, const char *action); diff --git a/src/nm-connection-provider.h b/src/nm-connection-provider.h index 96db76adf7..5093d05536 100644 --- a/src/nm-connection-provider.h +++ b/src/nm-connection-provider.h @@ -76,6 +76,13 @@ struct _NMConnectionProvider { GType nm_connection_provider_get_type (void); +/** + * nm_connection_provider_get: + * + * Returns: the global #NMConnectionProvider + */ +NMConnectionProvider *nm_connection_provider_get (void); + /** * nm_connection_provider_get_best_connections: * @self: the #NMConnectionProvider diff --git a/src/nm-manager.c b/src/nm-manager.c index 6126c86281..9b00f7e7da 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1842,8 +1842,6 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) return; } - nm_device_set_connection_provider (device, NM_CONNECTION_PROVIDER (priv->settings)); - priv->devices = g_slist_append (priv->devices, device); g_signal_connect (device, "state-changed", @@ -4693,6 +4691,14 @@ nm_manager_get (void) return singleton; } +NMConnectionProvider * +nm_connection_provider_get (void) +{ + g_assert (singleton); + g_assert (NM_MANAGER_GET_PRIVATE (singleton)->settings); + return NM_CONNECTION_PROVIDER (NM_MANAGER_GET_PRIVATE (singleton)->settings); +} + NMManager * nm_manager_new (NMSettings *settings, const char *state_file, From ee66964208c7c0c404e61fe293a380e500f840eb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Feb 2014 08:49:47 -0600 Subject: [PATCH 3/9] core: allow devices to indicate when they should be removed Devices created by plugins will use this to indicate when their backing resources have disappeared, at which point the manager should remove them. --- src/devices/nm-device.c | 8 ++++++++ src/devices/nm-device.h | 3 ++- src/nm-manager.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 5c18a3cb8c..e43df20d07 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -112,6 +112,7 @@ enum { AUTH_REQUEST, IP4_CONFIG_CHANGED, IP6_CONFIG_CHANGED, + REMOVED, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -6117,6 +6118,13 @@ nm_device_class_init (NMDeviceClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT); + signals[REMOVED] = + g_signal_new (NM_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_object_info); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index c973b9864d..807cf6873e 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -71,9 +71,10 @@ #define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */ /* Internal signals */ -#define NM_DEVICE_AUTH_REQUEST "auth-request" +#define NM_DEVICE_AUTH_REQUEST "auth-request" #define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed" #define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed" +#define NM_DEVICE_REMOVED "removed" G_BEGIN_DECLS diff --git a/src/nm-manager.c b/src/nm-manager.c index 9b00f7e7da..a91e1bf153 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -836,6 +836,12 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting) check_if_startup_complete (manager); } +static void +device_removed_cb (NMDevice *device, gpointer user_data) +{ + remove_device (NM_MANAGER (user_data), device, FALSE); +} + static void modem_removed (NMModemManager *modem_manager, NMModem *modem, @@ -1852,6 +1858,10 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) G_CALLBACK (device_auth_request_cb), self); + g_signal_connect (device, NM_DEVICE_REMOVED, + G_CALLBACK (device_removed_cb), + self); + if (priv->startup) { g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION, G_CALLBACK (device_has_pending_action_changed), From 8e9b9fe4234916cdb02c2d893a571c87c9c37f6b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Feb 2014 09:12:46 -0600 Subject: [PATCH 4/9] mobile: convert to device removed signals Instead of having NMManager listen directly to the ModemManager for modem removal signals, have the NMDeviceModem and NMDeviceBt listen for them (since they obviously have a pointer to the backing NMModem object) and then re-emit any necessary device removal signals to the manager. --- src/devices/nm-device-bt.c | 65 ++++++++++++++-------------- src/devices/nm-device-bt.h | 2 - src/devices/nm-device-modem.c | 7 +++ src/modem-manager/nm-modem-manager.c | 17 ++------ src/modem-manager/nm-modem.c | 15 +++++++ src/modem-manager/nm-modem.h | 6 +++ src/nm-manager.c | 31 ------------- 7 files changed, 63 insertions(+), 80 deletions(-) diff --git a/src/devices/nm-device-bt.c b/src/devices/nm-device-bt.c index 3e5b693354..79371ee05a 100644 --- a/src/devices/nm-device-bt.c +++ b/src/devices/nm-device-bt.c @@ -560,6 +560,34 @@ modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason) /*****************************************************************************/ +static void +modem_cleanup (NMDeviceBt *self) +{ + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + + if (priv->modem) { + g_signal_handlers_disconnect_matched (priv->modem, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self); + g_clear_object (&priv->modem); + } +} + +static void +modem_removed_cb (NMModem *modem, gpointer user_data) +{ + NMDeviceBt *self = NM_DEVICE_BT (user_data); + NMDeviceState state; + + /* Fail the device if the modem was removed while active */ + state = nm_device_get_state (NM_DEVICE (self)); + if ( state == NM_DEVICE_STATE_ACTIVATED + || nm_device_is_activating (NM_DEVICE (self))) { + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BT_FAILED); + } else + modem_cleanup (self); +} + gboolean nm_device_bt_modem_added (NMDeviceBt *self, NMModem *modem, @@ -614,7 +642,7 @@ nm_device_bt_modem_added (NMDeviceBt *self, if (priv->modem) { g_warn_if_reached (); - g_object_unref (priv->modem); + modem_cleanup (self); } priv->modem = g_object_ref (modem); @@ -624,6 +652,7 @@ nm_device_bt_modem_added (NMDeviceBt *self, g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self); g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); + g_signal_connect (modem, NM_MODEM_REMOVED, G_CALLBACK (modem_removed_cb), self); /* In the old ModemManager the data port is known from the very beginning; * while in the new ModemManager the data port is set afterwards when the bearer gets @@ -639,35 +668,6 @@ nm_device_bt_modem_added (NMDeviceBt *self, return TRUE; } -gboolean -nm_device_bt_modem_removed (NMDeviceBt *self, NMModem *modem) -{ - NMDeviceBtPrivate *priv; - NMDeviceState state; - - g_return_val_if_fail (NM_IS_DEVICE_BT (self), FALSE); - g_return_val_if_fail (NM_IS_MODEM (modem), FALSE); - - priv = NM_DEVICE_BT_GET_PRIVATE (self); - - if (modem != priv->modem) - return FALSE; - - /* Fail the device if the modem was removed while active */ - state = nm_device_get_state (NM_DEVICE (self)); - if ( state == NM_DEVICE_STATE_ACTIVATED - || nm_device_is_activating (NM_DEVICE (self))) { - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - } else { - g_object_unref (priv->modem); - priv->modem = NULL; - } - - return TRUE; -} - static gboolean modem_find_timeout (gpointer user_data) { @@ -905,8 +905,7 @@ deactivate (NMDevice *device) NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_USER_REQUESTED); - g_object_unref (priv->modem); - priv->modem = NULL; + modem_cleanup (NM_DEVICE_BT (device)); } } @@ -1166,7 +1165,7 @@ dispose (GObject *object) } priv->dbus_mgr = NULL; - g_clear_object (&priv->modem); + modem_cleanup (NM_DEVICE_BT (object)); g_clear_object (&priv->bt_device); G_OBJECT_CLASS (nm_device_bt_parent_class)->dispose (object); diff --git a/src/devices/nm-device-bt.h b/src/devices/nm-device-bt.h index d983285fb7..83732bc09e 100644 --- a/src/devices/nm-device-bt.h +++ b/src/devices/nm-device-bt.h @@ -69,8 +69,6 @@ gboolean nm_device_bt_modem_added (NMDeviceBt *device, NMModem *modem, const char *driver); -gboolean nm_device_bt_modem_removed (NMDeviceBt *device, NMModem *modem); - G_END_DECLS #endif /* NM_DEVICE_BT_H */ diff --git a/src/devices/nm-device-modem.c b/src/devices/nm-device-modem.c index e047c03e11..5c10a8e05d 100644 --- a/src/devices/nm-device-modem.c +++ b/src/devices/nm-device-modem.c @@ -196,6 +196,12 @@ modem_connected_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) } } +static void +modem_removed_cb (NMModem *modem, gpointer user_data) +{ + g_signal_emit_by_name (NM_DEVICE (user_data), NM_DEVICE_REMOVED); +} + /*****************************************************************************/ NMModem * @@ -398,6 +404,7 @@ set_modem (NMDeviceModem *self, NMModem *modem) g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); g_signal_connect (modem, "notify::" NM_MODEM_ENABLED, G_CALLBACK (modem_enabled_cb), self); g_signal_connect (modem, "notify::" NM_MODEM_CONNECTED, G_CALLBACK (modem_connected_cb), self); + g_signal_connect (modem, NM_MODEM_REMOVED, G_CALLBACK (modem_removed_cb), self); /* In the old ModemManager the data port is known from the very beginning; * while in the new ModemManager the data port is set afterwards when the bearer gets diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c index bb85b774ea..f68a569666 100644 --- a/src/modem-manager/nm-modem-manager.c +++ b/src/modem-manager/nm-modem-manager.c @@ -63,8 +63,6 @@ struct _NMModemManagerPrivate { enum { MODEM_ADDED, - MODEM_REMOVED, - LAST_SIGNAL }; @@ -159,7 +157,7 @@ modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data) modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path); if (modem) { - g_signal_emit (self, signals[MODEM_REMOVED], 0, modem); + nm_modem_emit_removed (modem); g_hash_table_remove (self->priv->modems, path); } } @@ -274,8 +272,7 @@ modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices) static gboolean remove_one_modem (gpointer key, gpointer value, gpointer user_data) { - g_signal_emit (user_data, signals[MODEM_REMOVED], 0, value); - + nm_modem_emit_removed (NM_MODEM (value)); return TRUE; } @@ -426,7 +423,7 @@ modem_object_removed (MMManager *manager, if (!modem) return; - g_signal_emit (self, signals[MODEM_REMOVED], 0, modem); + nm_modem_emit_removed (modem); g_hash_table_remove (self->priv->modems, path); } @@ -760,12 +757,4 @@ nm_modem_manager_class_init (NMModemManagerClass *klass) G_STRUCT_OFFSET (NMModemManagerClass, modem_added), NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_STRING); - - signals[MODEM_REMOVED] = - g_signal_new ("modem-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemManagerClass, modem_removed), - NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_OBJECT); } diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index e88ebe1bd7..8327c1c5d9 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -81,6 +81,7 @@ enum { IP4_CONFIG_RESULT, AUTH_REQUESTED, AUTH_RESULT, + REMOVED, LAST_SIGNAL }; @@ -126,6 +127,12 @@ nm_modem_get_mm_connected (NMModem *self) return NM_MODEM_GET_PRIVATE (self)->mm_connected; } +void +nm_modem_emit_removed (NMModem *self) +{ + g_signal_emit (self, signals[REMOVED], 0); +} + /*****************************************************************************/ /* IP method PPP */ @@ -988,6 +995,14 @@ nm_modem_class_init (NMModemClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[REMOVED] = + g_signal_new (NM_MODEM_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, removed), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + dbus_g_error_domain_register (NM_MODEM_ERROR, NM_DBUS_INTERFACE_DEVICE_MODEM, NM_TYPE_MODEM_ERROR); diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h index db20407006..f15be26769 100644 --- a/src/modem-manager/nm-modem.h +++ b/src/modem-manager/nm-modem.h @@ -52,6 +52,7 @@ G_BEGIN_DECLS #define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result" #define NM_MODEM_AUTH_REQUESTED "auth-requested" #define NM_MODEM_AUTH_RESULT "auth-result" +#define NM_MODEM_REMOVED "removed" #define MM_MODEM_IP_METHOD_PPP 0 #define MM_MODEM_IP_METHOD_STATIC 1 @@ -119,6 +120,8 @@ typedef struct { void (*auth_requested) (NMModem *self); void (*auth_result) (NMModem *self, GError *error); + + void (*removed) (NMModem *self); } NMModemClass; GType nm_modem_get_type (void); @@ -182,6 +185,9 @@ void nm_modem_set_mm_enabled (NMModem *self, gboolean enabled); gboolean nm_modem_get_mm_connected (NMModem *self); +/* For the modem-manager only */ +void nm_modem_emit_removed (NMModem *self); + G_END_DECLS #endif /* NM_MODEM_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index a91e1bf153..fc439f0921 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -237,7 +237,6 @@ typedef struct { NMModemManager *modem_manager; guint modem_added_id; - guint modem_removed_id; DBusGProxy *aipd_proxy; NMSleepMonitor *sleep_monitor; @@ -842,30 +841,6 @@ device_removed_cb (NMDevice *device, gpointer user_data) remove_device (NM_MANAGER (user_data), device, FALSE); } -static void -modem_removed (NMModemManager *modem_manager, - NMModem *modem, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMDevice *found; - GSList *iter; - - /* Give Bluetooth DUN devices first chance to handle the modem removal */ - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_BT) { - if (nm_device_bt_modem_removed (NM_DEVICE_BT (iter->data), modem)) - return; - } - } - - /* Otherwise remove the standalone modem */ - found = nm_manager_get_device_by_udi (self, nm_modem_get_path (modem)); - if (found) - remove_device (self, found, FALSE); -} - static void aipd_handle_event (DBusGProxy *proxy, const char *event, @@ -4886,8 +4861,6 @@ nm_manager_init (NMManager *manager) priv->modem_manager = nm_modem_manager_get (); priv->modem_added_id = g_signal_connect (priv->modem_manager, "modem-added", G_CALLBACK (modem_added), manager); - priv->modem_removed_id = g_signal_connect (priv->modem_manager, "modem-removed", - G_CALLBACK (modem_removed), manager); priv->vpn_manager = nm_vpn_manager_get (); @@ -5111,10 +5084,6 @@ dispose (GObject *object) g_source_remove (priv->modem_added_id); priv->modem_added_id = 0; } - if (priv->modem_removed_id) { - g_source_remove (priv->modem_removed_id); - priv->modem_removed_id = 0; - } g_clear_object (&priv->modem_manager); /* Unregister property filter */ From 2a04df856b0cffd7c8c3db27c48a018f3dc0cf69 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 9 Feb 2014 10:22:19 -0600 Subject: [PATCH 5/9] devices: rework device plugin interface to be more flexible In preparation for making WWAN and Bluetooth plugins, rework the device plugin interface to meet those plugins' needs and port WiMAX over in the process. --- src/Makefile.am | 1 + src/devices/nm-device-bt.c | 17 ++- src/devices/nm-device-factory.c | 114 +++++++++++++++ src/devices/nm-device-factory.h | 137 ++++++++++++------ src/devices/nm-device-modem.c | 10 ++ src/devices/nm-device.c | 42 ++++++ src/devices/nm-device.h | 8 + src/devices/wimax/nm-wimax-factory.c | 88 +++++++++-- src/nm-manager.c | 209 +++++++++++++++------------ 9 files changed, 472 insertions(+), 154 deletions(-) create mode 100644 src/devices/nm-device-factory.c diff --git a/src/Makefile.am b/src/Makefile.am index 305a9a0dac..aeae2a0698 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,6 +80,7 @@ nm_sources = \ devices/nm-device-bt.h \ devices/nm-device-ethernet.c \ devices/nm-device-ethernet.h \ + devices/nm-device-factory.c \ devices/nm-device-factory.h \ devices/nm-device-generic.c \ devices/nm-device-generic.h \ diff --git a/src/devices/nm-device-bt.c b/src/devices/nm-device-bt.c index 79371ee05a..ecb015b03c 100644 --- a/src/devices/nm-device-bt.c +++ b/src/devices/nm-device-bt.c @@ -588,22 +588,22 @@ modem_removed_cb (NMModem *modem, gpointer user_data) modem_cleanup (self); } -gboolean -nm_device_bt_modem_added (NMDeviceBt *self, - NMModem *modem, - const char *driver) +static gboolean +component_added (NMDevice *device, GObject *component) { - NMDeviceBtPrivate *priv; + NMDeviceBt *self = NM_DEVICE_BT (device); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMModem *modem; const gchar *modem_data_port; const gchar *modem_control_port; char *base; NMDeviceState state; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - g_return_val_if_fail (NM_IS_DEVICE_BT (self), FALSE); - g_return_val_if_fail (NM_IS_MODEM (modem), FALSE); + if (!NM_IS_MODEM (component)) + return FALSE; + modem = NM_MODEM (component); - priv = NM_DEVICE_BT_GET_PRIVATE (self); modem_data_port = nm_modem_get_data_port (modem); modem_control_port = nm_modem_get_control_port (modem); g_return_val_if_fail (modem_data_port != NULL || modem_control_port != NULL, FALSE); @@ -1207,6 +1207,7 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) device_class->check_connection_available = check_connection_available; device_class->complete_connection = complete_connection; device_class->is_available = is_available; + device_class->component_added = component_added; device_class->state_changed = device_state_changed; diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c new file mode 100644 index 0000000000..423a26f6a7 --- /dev/null +++ b/src/devices/nm-device-factory.c @@ -0,0 +1,114 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "nm-device-factory.h" + +enum { + DEVICE_ADDED, + COMPONENT_ADDED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +gboolean +nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component) +{ + gboolean consumed = FALSE; + + g_signal_emit (factory, signals[COMPONENT_ADDED], 0, component, &consumed); + return consumed; +} + +static void +interface_init (gpointer g_iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); + static gboolean initialized = FALSE; + + if (G_LIKELY (initialized)) + return; + + g_object_interface_install_property + (g_iface, + g_param_spec_uint (NM_DEVICE_FACTORY_DEVICE_TYPE, + "Device type", + "Device type", + 0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, + G_PARAM_READABLE)); + + /* Signals */ + signals[DEVICE_ADDED] = g_signal_new (NM_DEVICE_FACTORY_DEVICE_ADDED, + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceFactory, device_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, NM_TYPE_DEVICE); + + signals[COMPONENT_ADDED] = g_signal_new (NM_DEVICE_FACTORY_COMPONENT_ADDED, + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMDeviceFactory, component_added), + g_signal_accumulator_true_handled, NULL, NULL, + G_TYPE_BOOLEAN, 1, G_TYPE_OBJECT); + + initialized = TRUE; +} + +GType +nm_device_factory_get_type (void) +{ + static GType device_factory_type = 0; + + if (!device_factory_type) { + const GTypeInfo device_factory_info = { + sizeof (NMDeviceFactory), /* class_size */ + interface_init, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + device_factory_type = g_type_register_static (G_TYPE_INTERFACE, + "NMDeviceFactory", + &device_factory_info, + 0); + g_type_interface_add_prerequisite (device_factory_type, G_TYPE_OBJECT); + } + + return device_factory_type; +} + +NMDevice * +nm_device_factory_new_link (NMDeviceFactory *factory, + NMPlatformLink *plink, + GError **error) +{ + g_return_if_fail (factory != NULL); + g_return_if_fail (plink != NULL); + + if (NM_DEVICE_FACTORY_GET_INTERFACE (factory)->new_link) + return NM_DEVICE_FACTORY_GET_INTERFACE (factory)->new_link (factory, plink, error); + return NULL; +} + diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index 7b7efc8702..45ae77a9fb 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. */ #ifndef NM_DEVICE_FACTORY_H @@ -26,6 +26,7 @@ #include "NetworkManager.h" #include "nm-platform.h" +#include "nm-device.h" /* WARNING: this file is private API between NetworkManager and its internal * device plugins. Its API can change at any time and is not guaranteed to be @@ -33,52 +34,106 @@ * not meant to enable third-party plugins. */ +typedef struct _NMDeviceFactory NMDeviceFactory; + /** - * nm_device_factory_create_device: - * @devpath: sysfs path of the device - * @ifname: interface name of the device - * @driver: driver of the device - * @error: error for failure information + * nm_device_factory_create: + * @error: an error if creation of the factory failed, or %NULL * - * Creates a #NMDevice subclass if the given information represents a device - * the factory is capable of creating. If the information does represent a - * device the factory is capable of creating, but the device could not be - * created, %NULL should be returned and @error should be set. If the - * factory is not capable of creating a device with the given information - * (ie, the factory creates Ethernet devices but the information represents - * a WiFi device) it should return %NULL and leave @error untouched. + * Creates a #GObject that implements the #NMDeviceFactory interface. This + * function must not emit any signals or perform any actions that would cause + * devices or components to be created immediately. Instead these should be + * deferred to an idle handler. * - * Returns: the device object (a subclass of #NMDevice) or %NULL + * Returns: the #GObject implementing #NMDeviceFactory or %NULL */ -GObject *nm_device_factory_create_device (NMPlatformLink *platform_device, +NMDeviceFactory *nm_device_factory_create (GError **error); + +/* Should match nm_device_factory_create() */ +typedef NMDeviceFactory * (*NMDeviceFactoryCreateFunc) (GError **error); + +/** + * nm_device_factory_get_device_type: + * + * Returns: the #NMDeviceType that this plugin creates + */ +NMDeviceType nm_device_factory_get_device_type (void); + +/* Should match nm_device_factory_get_device_type() */ +typedef NMDeviceType (*NMDeviceFactoryDeviceTypeFunc) (void); + +/********************************************************************/ + +#define NM_TYPE_DEVICE_FACTORY (nm_device_factory_get_type ()) +#define NM_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_FACTORY, NMDeviceFactory)) +#define NM_IS_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_FACTORY)) +#define NM_DEVICE_FACTORY_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_DEVICE_FACTORY, NMDeviceFactory)) + +/* properties */ +#define NM_DEVICE_FACTORY_DEVICE_TYPE "device-type" + +/* signals */ +#define NM_DEVICE_FACTORY_COMPONENT_ADDED "component-added" +#define NM_DEVICE_FACTORY_DEVICE_ADDED "device-added" + +struct _NMDeviceFactory { + GTypeInterface g_iface; + + /** + * new_link: + * @factory: the #NMDeviceFactory + * @link: the new link + * @error: error if the link could be claimed but an error occurred + * + * The NetworkManager core was notified of a new link which the plugin + * may want to claim and create a #NMDevice subclass for. If the link + * represents a device the factory is capable of claiming, but the device + * could not be created, %NULL should be returned and @error should be set. + * %NULL should always be returned and @error should never be set if the + * factory cannot create devices for the type which @link represents. + * + * Returns: the #NMDevice if the link was claimed and created, %NULL if not + */ + NMDevice * (*new_link) (NMDeviceFactory *factory, + NMPlatformLink *plink, + GError **error); + + /* Signals */ + + /** + * device_added: + * @factory: the #NMDeviceFactory + * @device: the new #NMDevice subclass + * + * The factory emits this signal if it finds a new device by itself. + */ + void (*device_added) (NMDeviceFactory *factory, NMDevice *device); + + /** + * component_added: + * @factory: the #NMDeviceFactory + * @component: a new component which existing devices may wish to claim + * + * The factory emits this signal when it finds a new component. For example, + * the WWAN factory may indicate that a new modem is available, which an + * existing Bluetooth device may wish to claim. If no device claims the + * component, the plugin is allowed to create a new #NMDevice instance for + * that component and emit the "device-added" signal. + * + * Returns: %TRUE if the component was claimed by a device, %FALSE if not + */ + gboolean (*component_added) (NMDeviceFactory *factory, GObject *component); +}; + +GType nm_device_factory_get_type (void); + +NMDevice * nm_device_factory_new_link (NMDeviceFactory *factory, + NMPlatformLink *plink, GError **error); -/* Should match nm_device_factory() */ -typedef GObject * (*NMDeviceFactoryCreateFunc) (NMPlatformLink *platform_device, - GError **error); - -/** - * nm_device_factory_get_priority: - * - * Returns the priority of this plugin. Higher numbers mean a higher priority. - * - * Returns: plugin priority - */ -guint32 nm_device_factory_get_priority (void); - -typedef guint32 (*NMDeviceFactoryPriorityFunc) (void); - -/** - * nm_device_factory_get_type: - * - * Returns the type of device this factory can create. Only one factory for - * each type of device is allowed. - * - * Returns: the %NMDeviceType - */ -NMDeviceType nm_device_factory_get_type (void); - -typedef NMDeviceType (*NMDeviceFactoryTypeFunc) (void); +/* For use by implementations */ +gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, + GObject *component); #endif /* NM_DEVICE_FACTORY_H */ diff --git a/src/devices/nm-device-modem.c b/src/devices/nm-device-modem.c index 5c10a8e05d..6a3656c4e9 100644 --- a/src/devices/nm-device-modem.c +++ b/src/devices/nm-device-modem.c @@ -212,6 +212,15 @@ nm_device_modem_get_modem (NMDeviceModem *self) return NM_DEVICE_MODEM_GET_PRIVATE (self)->modem; } +static gboolean +owns_iface (NMDevice *device, const char *iface) +{ + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + + g_assert (priv->modem); + return nm_modem_owns_port (priv->modem, iface); +} + /*****************************************************************************/ static void @@ -492,6 +501,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->ip4_config_pre_commit = ip4_config_pre_commit; device_class->get_enabled = get_enabled; device_class->set_enabled = set_enabled; + device_class->owns_iface = owns_iface; device_class->state_changed = device_state_changed; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e43df20d07..d4f16a62e7 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1193,6 +1193,48 @@ link_changed (NMDevice *device, NMPlatformLink *info) nm_device_set_carrier (device, info->connected); } +/** + * nm_device_notify_component_added(): + * @device: the #NMDevice + * @component: the component being added by a plugin + * + * Called by the manager to notify the device that a new component has + * been found. The device implementation should return %TRUE if it + * wishes to claim the component, or %FALSE if it cannot. + * + * Returns: %TRUE to claim the component, %FALSE if the component cannot be + * claimed. + */ +gboolean +nm_device_notify_component_added (NMDevice *device, GObject *component) +{ + if (NM_DEVICE_GET_CLASS (device)->component_added) + return NM_DEVICE_GET_CLASS (device)->component_added (device, component); + return FALSE; +} + +/** + * nm_device_owns_iface(): + * @device: the #NMDevice + * @iface: an interface name + * + * Called by the manager to ask if the device or any of its components owns + * @iface. For example, a WWAN implementation would return %TRUE for an + * ethernet interface name that was owned by the WWAN device's modem component, + * because that ethernet interface is controlled by the WWAN device and cannot + * be used independently of the WWAN device. + * + * Returns: %TRUE if @device or it's components owns the interface name, + * %FALSE if not + */ +gboolean +nm_device_owns_iface (NMDevice *device, const char *iface) +{ + if (NM_DEVICE_GET_CLASS (device)->owns_iface) + return NM_DEVICE_GET_CLASS (device)->owns_iface (device, iface); + return FALSE; +} + static void check_carrier (NMDevice *device) { diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 807cf6873e..03e3b87ed0 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -196,6 +196,10 @@ typedef struct { gboolean (* have_any_ready_slaves) (NMDevice *self, const GSList *slaves); + + gboolean (* component_added) (NMDevice *self, GObject *component); + + gboolean (* owns_iface) (NMDevice *self, const char *iface); } NMDeviceClass; @@ -332,6 +336,10 @@ guint32 nm_device_get_mtu (NMDevice *device); gboolean nm_device_connection_is_available (NMDevice *device, NMConnection *connection); +gboolean nm_device_notify_component_added (NMDevice *device, GObject *component); + +gboolean nm_device_owns_iface (NMDevice *device, const char *iface); + G_END_DECLS /* For testing only */ diff --git a/src/devices/wimax/nm-wimax-factory.c b/src/devices/wimax/nm-wimax-factory.c index 738c12eb31..d5bf57f602 100644 --- a/src/devices/wimax/nm-wimax-factory.c +++ b/src/devices/wimax/nm-wimax-factory.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2011 - 2014 Red Hat, Inc. */ #include @@ -23,28 +23,92 @@ #include "nm-device-factory.h" #include "nm-device-wimax.h" -G_MODULE_EXPORT GObject * -nm_device_factory_create_device (NMPlatformLink *platform_device, - GError **error) +#define NM_TYPE_WIMAX_FACTORY (nm_wimax_factory_get_type ()) +#define NM_WIMAX_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_WIMAX_FACTORY, NMWimaxFactory)) + +typedef struct { + GObject parent; +} NMWimaxFactory; + +typedef struct { + GObjectClass parent; +} NMWimaxFactoryClass; + +static GType nm_wimax_factory_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMWimaxFactory, nm_wimax_factory, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) + +/**************************************************************************/ + +#define PLUGIN_TYPE NM_DEVICE_TYPE_WIMAX + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_WIMAX_FACTORY, NULL); +} + +G_MODULE_EXPORT NMDeviceType +nm_device_factory_get_device_type (void) +{ + return PLUGIN_TYPE; +} + +/**************************************************************************/ + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) { /* FIXME: check udev 'DEVTYPE' instead; but since we only support Intel * WiMAX devices for now this is appropriate. */ - if (g_strcmp0 (platform_device->driver, "i2400m_usb") != 0) + if (g_strcmp0 (plink->driver, "i2400m_usb") != 0) return NULL; /* unsupported */ - return (GObject *) nm_device_wimax_new (platform_device); + return (NMDevice *) nm_device_wimax_new (plink); } -G_MODULE_EXPORT guint32 -nm_device_factory_get_priority (void) +enum { + PROP_0 = 0x1000, + PROP_DEVICE_TYPE, +}; + +static void +get_property (GObject *object, guint prop, GValue *value, GParamSpec *pspec) { - return 0; + switch (prop) { + case PROP_DEVICE_TYPE: + g_value_set_uint (value, PLUGIN_TYPE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop, pspec); + break; + } } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_type (void) +static void +device_factory_interface_init (NMDeviceFactory *factory_iface) { - return NM_DEVICE_TYPE_WIMAX; + factory_iface->new_link = new_link; +} + +static void +nm_wimax_factory_init (NMWimaxFactory *factory) +{ +} + +static void +nm_wimax_factory_class_init (NMWimaxFactoryClass *wf_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (wf_class); + + object_class->get_property = get_property; + + g_object_class_override_property (object_class, + PROP_DEVICE_TYPE, + NM_DEVICE_FACTORY_DEVICE_TYPE); } diff --git a/src/nm-manager.c b/src/nm-manager.c index fc439f0921..22e8a32f57 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -551,27 +551,12 @@ modem_added (NMModemManager *modem_manager, NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMDevice *device = NULL; const char *modem_iface; - GSList *iter, *remove = NULL; - - /* Remove ethernet devices that are actually owned by the modem, since - * they cannot be used as normal ethernet. - */ - for (iter = priv->devices; iter; iter = iter->next) { - if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_ETHERNET) { - if (nm_modem_owns_port (modem, nm_device_get_ip_iface (iter->data))) - remove = g_slist_prepend (remove, iter->data); - } - } - for (iter = remove; iter; iter = iter->next) - remove_device (self, NM_DEVICE (iter->data), FALSE); - g_slist_free (remove); + GSList *iter; /* Give Bluetooth DUN devices first chance to claim the modem */ - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - if (nm_device_get_device_type (iter->data) == NM_DEVICE_TYPE_BT) { - if (nm_device_bt_modem_added (NM_DEVICE_BT (iter->data), modem, driver)) - return; - } + for (iter = priv->devices; iter; iter = iter->next) { + if (nm_device_notify_component_added (device, G_OBJECT (modem))) + return; } /* If it was a Bluetooth modem and no bluetooth device claimed it, ignore @@ -589,8 +574,10 @@ modem_added (NMModemManager *modem_manager, /* Make the new modem device */ device = nm_device_modem_new (modem, driver); - if (device) + if (device) { add_device (self, device, FALSE); + g_object_unref (device); + } } static void @@ -1182,6 +1169,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) if (device) { nm_device_set_is_nm_owned (device, TRUE); add_device (self, device, FALSE); + g_object_unref (device); } g_signal_handlers_unblock_by_func (nm_platform_get (), G_CALLBACK (platform_link_added_cb), self); @@ -1792,6 +1780,15 @@ get_existing_connection (NMManager *manager, NMDevice *device) return added ? NM_CONNECTION (added) : NULL; } +/** + * add_device: + * @self: the #NMManager + * @device: the #NMDevice to add + * @generate_con: %TRUE if existing connection (if any) should be assumed + * + * If successful, this function will increase the references count of @device. + * Callers should decrease the reference count. + */ static void add_device (NMManager *self, NMDevice *device, gboolean generate_con) { @@ -1804,26 +1801,31 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) gboolean enabled = FALSE; RfKillType rtype; NMDeviceType devtype; - - iface = nm_device_get_ip_iface (device); - g_assert (iface); + GSList *iter, *remove = NULL; devtype = nm_device_get_device_type (device); - /* Ignore the device if we already know about it. But some modems will - * provide pseudo-ethernet devices that NM has already claimed while - * ModemManager is still detecting the modem's serial ports, so when the - * MM modem object finally shows up it may have the same IP interface as the - * ethernet interface we've already detected. In this case we skip the - * check for an existing device with the same IP interface name and kill - * the ethernet device later in favor of the modem device. - */ - if ((devtype != NM_DEVICE_TYPE_MODEM) && find_device_by_ip_iface (self, iface)) { - g_object_unref (device); + /* No duplicates */ + if (nm_manager_get_device_by_udi (self, nm_device_get_udi (device))) return; - } - priv->devices = g_slist_append (priv->devices, device); + /* Remove existing devices owned by the new device; eg remove ethernet + * ports that are owned by a WWAN modem, since udev may announce them + * before the modem is fully discovered. + * + * FIXME: use parent/child device relationships instead of removing + * the child NMDevice entirely + */ + for (iter = priv->devices; iter; iter = iter->next) { + iface = nm_device_get_ip_iface (iter->data); + if (nm_device_owns_iface (device, iface)) + remove = g_slist_prepend (remove, iter->data); + } + for (iter = remove; iter; iter = iter->next) + remove_device (self, NM_DEVICE (iter->data), FALSE); + g_slist_free (remove); + + priv->devices = g_slist_append (priv->devices, g_object_ref (device)); g_signal_connect (device, "state-changed", G_CALLBACK (manager_device_state_changed), @@ -1874,6 +1876,9 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) nm_device_set_enabled (device, enabled); } + iface = nm_device_get_iface (device); + g_assert (iface); + type_desc = nm_device_get_type_desc (device); g_assert (type_desc); driver = nm_device_get_driver (device); @@ -1983,6 +1988,7 @@ bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, has_nap ? "NAP" : ""); add_device (manager, device, FALSE); + g_object_unref (device); } } @@ -2050,25 +2056,31 @@ find_device_by_ifindex (NMManager *self, guint32 ifindex) return NULL; } -#define PLUGIN_PREFIX "libnm-device-plugin-" - -typedef struct { - NMDeviceType t; - guint priority; - NMDeviceFactoryCreateFunc create_func; -} PluginInfo; - -static gint -plugin_sort (PluginInfo *a, PluginInfo *b) +static void +factory_device_added_cb (NMDeviceFactory *factory, + NMDevice *device, + gpointer user_data) { - /* Higher priority means sort earlier in the list (ie, return -1) */ - if (a->priority > b->priority) - return -1; - else if (a->priority < b->priority) - return 1; - return 0; + add_device (NM_MANAGER (user_data), device, FALSE); } +static gboolean +factory_component_added_cb (NMDeviceFactory *factory, + GObject *component, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + GSList *iter; + + for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) { + if (nm_device_notify_component_added (NM_DEVICE (iter->data), component)) + return TRUE; + } + return FALSE; +} + +#define PLUGIN_PREFIX "libnm-device-plugin-" + static void load_device_factories (NMManager *self) { @@ -2077,7 +2089,7 @@ load_device_factories (NMManager *self) GError *error = NULL; const char *item; char *path; - GSList *list = NULL, *iter; + GSList *iter; dir = g_dir_open (NMPLUGINDIR, 0, &error); if (!dir) { @@ -2090,11 +2102,11 @@ load_device_factories (NMManager *self) while ((item = g_dir_read_name (dir))) { GModule *plugin; + NMDeviceFactory *factory; NMDeviceFactoryCreateFunc create_func; - NMDeviceFactoryPriorityFunc priority_func; - NMDeviceFactoryTypeFunc type_func; - PluginInfo *info = NULL; - NMDeviceType plugin_type; + NMDeviceFactoryDeviceTypeFunc type_func; + NMDeviceType dev_type; + gboolean found = FALSE; if (!g_str_has_prefix (item, PLUGIN_PREFIX)) continue; @@ -2109,60 +2121,63 @@ load_device_factories (NMManager *self) continue; } - if (!g_module_symbol (plugin, "nm_device_factory_get_type", (gpointer) (&type_func))) { - nm_log_warn (LOGD_HW, "(%s): failed to find device factory: %s", item, g_module_error ()); + if (!g_module_symbol (plugin, "nm_device_factory_get_device_type", (gpointer) &type_func)) { + nm_log_warn (LOGD_HW, "(%s): failed to find device factory type: %s", item, g_module_error ()); g_module_close (plugin); continue; } /* Make sure we don't double-load plugins */ - plugin_type = type_func (); - for (iter = list; iter; iter = g_slist_next (iter)) { - PluginInfo *candidate = iter->data; + dev_type = type_func (); + for (iter = priv->factories; iter; iter = iter->next) { + NMDeviceType t = NM_DEVICE_TYPE_UNKNOWN; - if (plugin_type == candidate->t) { - info = candidate; + g_object_get (G_OBJECT (iter->data), + NM_DEVICE_FACTORY_DEVICE_TYPE, &t, + NULL); + if (dev_type == t) { + found = TRUE; break; } } - if (info) { + if (found) { g_module_close (plugin); continue; } - if (!g_module_symbol (plugin, "nm_device_factory_create_device", (gpointer) (&create_func))) { - nm_log_warn (LOGD_HW, "(%s): failed to find device creator: %s", item, g_module_error ()); + if (!g_module_symbol (plugin, "nm_device_factory_create", (gpointer) &create_func)) { + nm_log_warn (LOGD_HW, "(%s): failed to find device factory creator: %s", item, g_module_error ()); g_module_close (plugin); continue; } - info = g_malloc0 (sizeof (*info)); - info->create_func = create_func; - info->t = plugin_type; - - /* Grab priority; higher number equals higher priority */ - if (g_module_symbol (plugin, "nm_device_factory_get_priority", (gpointer) (&priority_func))) - info->priority = priority_func (); - else { - nm_log_dbg (LOGD_HW, "(%s): failed to find device factory priority func: %s", - item, g_module_error ()); + factory = create_func (&error); + if (!factory) { + nm_log_warn (LOGD_HW, "(%s): failed to initialize device factory: %s", + item, error ? error->message : "unknown"); + g_clear_error (&error); + g_module_close (plugin); + continue; } + g_clear_error (&error); g_module_make_resident (plugin); - list = g_slist_insert_sorted (list, info, (GCompareFunc) plugin_sort); + priv->factories = g_slist_prepend (priv->factories, factory); - nm_log_info (LOGD_HW, "Loaded device factory: %s", g_module_name (plugin)); + g_signal_connect (factory, + NM_DEVICE_FACTORY_DEVICE_ADDED, + G_CALLBACK (factory_device_added_cb), + self); + g_signal_connect (factory, + NM_DEVICE_FACTORY_COMPONENT_ADDED, + G_CALLBACK (factory_component_added_cb), + self); + + nm_log_info (LOGD_HW, "Loaded device plugin: %s", g_module_name (plugin)); }; g_dir_close (dir); - /* Ditch the priority info and copy the factory functions to our private data */ - for (iter = list; iter; iter = g_slist_next (iter)) { - PluginInfo *info = iter->data; - - priv->factories = g_slist_append (priv->factories, info->create_func); - g_free (info); - } - g_slist_free (list); + priv->factories = g_slist_reverse (priv->factories); } static void @@ -2184,11 +2199,10 @@ platform_link_added_cb (NMPlatform *platform, return; /* Try registered device factories */ - for (iter = priv->factories; iter; iter = g_slist_next (iter)) { - NMDeviceFactoryCreateFunc create_func = iter->data; + for (iter = priv->factories; iter; iter = iter->next) { + NMDeviceFactory *factory = NM_DEVICE_FACTORY (iter->data); - g_clear_error (&error); - device = (NMDevice *) create_func (plink, &error); + device = nm_device_factory_new_link (factory, plink, &error); if (device && NM_IS_DEVICE (device)) { g_assert_no_error (error); break; /* success! */ @@ -2281,8 +2295,10 @@ platform_link_added_cb (NMPlatform *platform, } } - if (device) + if (device) { add_device (self, device, plink->type != NM_LINK_TYPE_LOOPBACK); + g_object_unref (device); + } } static void @@ -4807,6 +4823,8 @@ nm_manager_new (NMSettings *settings, */ rfkill_change_wifi (priv->radio_states[RFKILL_TYPE_WLAN].desc, initial_wifi_enabled); + load_device_factories (singleton); + return singleton; } @@ -4917,8 +4935,6 @@ nm_manager_init (NMManager *manager) KERNEL_FIRMWARE_DIR); } - load_device_factories (manager); - /* Update timestamps in active connections */ priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, manager); } @@ -5046,6 +5062,7 @@ dispose (GObject *object) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); DBusGConnection *bus; DBusConnection *dbus_connection; + GSList *iter; g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref); priv->auth_chains = NULL; @@ -5116,6 +5133,12 @@ dispose (GObject *object) g_clear_object (&priv->fw_monitor); } + for (iter = priv->factories; iter; iter = iter->next) { + NMDeviceFactory *factory = iter->data; + + g_signal_handlers_disconnect_matched (factory, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, manager); + g_object_unref (factory); + } g_clear_pointer (&priv->factories, g_slist_free); if (priv->timestamp_update_id) { From 71a52347f32d0436c58d4c77eea703011d4157dc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Feb 2014 05:22:57 -0600 Subject: [PATCH 6/9] atm: make ADSL support a plugin Make ADSL support a plugin using the new device factory interface. Provides a 1% size reduction in the core NM binary. Before After NM: 1265336 1253016 (-1%) ATM: 0 27360 (all results from stripped files) --- configure.ac | 1 + po/POTFILES.in | 2 +- src/Makefile.am | 6 +- src/devices/atm/Makefile.am | 48 +++++++ src/{ => devices/atm}/nm-atm-manager.c | 177 ++++++++++++++++++------- src/{ => devices/atm}/nm-atm-manager.h | 23 +--- src/devices/{ => atm}/nm-device-adsl.c | 0 src/devices/{ => atm}/nm-device-adsl.h | 0 src/nm-manager.c | 73 ---------- 9 files changed, 178 insertions(+), 152 deletions(-) create mode 100644 src/devices/atm/Makefile.am rename src/{ => devices/atm}/nm-atm-manager.c (53%) rename src/{ => devices/atm}/nm-atm-manager.h (58%) rename src/devices/{ => atm}/nm-device-adsl.c (100%) rename src/devices/{ => atm}/nm-device-adsl.h (100%) diff --git a/configure.ac b/configure.ac index 1acfbb2069..b428649997 100644 --- a/configure.ac +++ b/configure.ac @@ -762,6 +762,7 @@ src/platform/Makefile src/platform/tests/Makefile src/rdisc/Makefile src/rdisc/tests/Makefile +src/devices/atm/Makefile src/devices/wimax/Makefile libnm-util/libnm-util.pc libnm-util/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index b1a4fcc512..9806ceba19 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -47,10 +47,10 @@ src/dhcp-manager/nm-dhcp-manager.c src/dns-manager/nm-dns-manager.c src/logging/nm-logging.c src/config/nm-config.c +src/devices/atm/nm-device-adsl.c src/modem-manager/nm-modem-broadband.c src/modem-manager/nm-modem-old.c src/devices/nm-device-bond.c -src/devices/nm-device-adsl.c src/devices/nm-device-bridge.c src/devices/nm-device-bt.c src/devices/nm-device-ethernet.c diff --git a/src/Makefile.am b/src/Makefile.am index aeae2a0698..9ca1d68438 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,6 +4,7 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ + devices/atm \ dhcp-manager \ ppp-manager \ settings/plugins @@ -70,8 +71,6 @@ nm_sources = \ \ devices/nm-device.c \ devices/nm-device.h \ - devices/nm-device-adsl.c \ - devices/nm-device-adsl.h \ devices/nm-device-bond.c \ devices/nm-device-bond.h \ devices/nm-device-bridge.c \ @@ -225,8 +224,6 @@ nm_sources = \ nm-activation-request.h \ nm-active-connection.c \ nm-active-connection.h \ - nm-atm-manager.c \ - nm-atm-manager.h \ nm-connection-provider.c \ nm-connection-provider.h \ nm-connectivity.c \ @@ -320,7 +317,6 @@ glue_sources = \ nm-access-point-glue.h \ nm-active-connection-glue.h \ nm-agent-manager-glue.h \ - nm-device-adsl-glue.h \ nm-device-bond-glue.h \ nm-device-bridge-glue.h \ nm-device-bt-glue.h \ diff --git a/src/devices/atm/Makefile.am b/src/devices/atm/Makefile.am new file mode 100644 index 0000000000..8d1e2b3f96 --- /dev/null +++ b/src/devices/atm/Makefile.am @@ -0,0 +1,48 @@ +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +AM_CPPFLAGS = \ + -I${top_srcdir}/src \ + -I${top_builddir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/devices \ + -I${top_srcdir}/src/settings \ + -I${top_srcdir}/src/platform \ + -I${top_srcdir}/src/ppp-manager \ + -I${top_builddir}/include \ + -I${top_srcdir}/include \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-util \ + $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GUDEV_CFLAGS) + +GLIB_GENERATED = nm-adsl-enum-types.h nm-adsl-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_adsl_enum_types_sources = $(srcdir)/nm-device-adsl.h + +nm-device-adsl-glue.h: $(top_srcdir)/introspection/nm-device-adsl.xml + dbus-binding-tool --prefix=nm_device_adsl --mode=glib-server --output=$@ $< + +BUILT_SOURCES = $(GLIB_GENERATED) nm-device-adsl-glue.h + +pkglib_LTLIBRARIES = libnm-device-plugin-atm.la + +libnm_device_plugin_atm_la_SOURCES = \ + nm-atm-manager.c \ + nm-atm-manager.h \ + nm-device-adsl.c \ + nm-device-adsl.h \ + \ + $(BUILT_SOURCES) + +libnm_device_plugin_atm_la_LDFLAGS = -module -avoid-version +libnm_device_plugin_atm_la_LIBADD = \ + $(DBUS_LIBS) \ + $(GUDEV_LIBS) + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/src/nm-atm-manager.c b/src/devices/atm/nm-atm-manager.c similarity index 53% rename from src/nm-atm-manager.c rename to src/devices/atm/nm-atm-manager.c index 19701500e7..886095dad3 100644 --- a/src/nm-atm-manager.c +++ b/src/devices/atm/nm-atm-manager.c @@ -24,52 +24,61 @@ #include #include "nm-atm-manager.h" +#include "nm-device-adsl.h" +#include "nm-device-factory.h" #include "nm-logging.h" typedef struct { GUdevClient *client; - + GSList *devices; + guint start_id; } NMAtmManagerPrivate; #define NM_ATM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ATM_MANAGER, NMAtmManagerPrivate)) -G_DEFINE_TYPE (NMAtmManager, nm_atm_manager, G_TYPE_OBJECT) +static GType nm_atm_manager_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMAtmManager, nm_atm_manager, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) enum { - DEVICE_ADDED, - DEVICE_REMOVED, - - LAST_SIGNAL + PROP_0, + PROP_DEVICE_TYPE, + LAST_PROP }; -static guint signals[LAST_SIGNAL] = { 0 }; +/**************************************************************************/ -NMAtmManager * -nm_atm_manager_new (void) +#define PLUGIN_TYPE NM_DEVICE_TYPE_ADSL + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) { - return NM_ATM_MANAGER (g_object_new (NM_TYPE_ATM_MANAGER, NULL)); + return (NMDeviceFactory *) g_object_new (NM_TYPE_ATM_MANAGER, NULL); } +G_MODULE_EXPORT NMDeviceType +nm_device_factory_get_device_type (void) +{ + return PLUGIN_TYPE; +} + +/************************************************************************/ + static gboolean dev_get_attrs (GUdevDevice *udev_device, - const char **out_ifname, const char **out_path, char **out_driver) { GUdevDevice *parent = NULL; - const char *ifname, *driver, *path; + const char *driver, *path; g_return_val_if_fail (udev_device != NULL, FALSE); - g_return_val_if_fail (out_ifname != NULL, FALSE); g_return_val_if_fail (out_path != NULL, FALSE); g_return_val_if_fail (out_driver != NULL, FALSE); - ifname = g_udev_device_get_name (udev_device); - if (!ifname) { - nm_log_dbg (LOGD_HW, "failed to get device's interface"); - return FALSE; - } - path = g_udev_device_get_sysfs_path (udev_device); if (!path) { nm_log_warn (LOGD_HW, "couldn't determine device path; ignoring..."); @@ -80,51 +89,92 @@ dev_get_attrs (GUdevDevice *udev_device, if (!driver) { /* Try the parent */ parent = g_udev_device_get_parent (udev_device); - if (parent) { + if (parent) driver = g_udev_device_get_driver (parent); - g_object_unref (parent); - } } - *out_ifname = ifname; *out_path = path; *out_driver = g_strdup (driver); + g_clear_object (&parent); return TRUE; } +static void +device_destroyed (gpointer user_data, GObject *dead) +{ + NMAtmManager *self = NM_ATM_MANAGER (user_data); + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + + priv->devices = g_slist_remove (priv->devices, dead); +} + static void adsl_add (NMAtmManager *self, GUdevDevice *udev_device) { - const char *ifname = NULL, *path = NULL; + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + const char *ifname, *sysfs_path = NULL; char *driver = NULL; + NMDevice *device; g_return_if_fail (udev_device != NULL); - nm_log_dbg (LOGD_HW, "adsl_add: ATM Device detected from udev. Adding .."); + ifname = g_udev_device_get_name (udev_device); + if (!ifname) { + nm_log_warn (LOGD_HW, "failed to get device's interface name"); + return; + } - if (dev_get_attrs (udev_device, &ifname, &path, &driver)) - g_signal_emit (self, signals[DEVICE_ADDED], 0, ifname, path, driver); - g_free (driver); + nm_log_dbg (LOGD_HW, "(%s): found ATM device", ifname); + + if (dev_get_attrs (udev_device, &sysfs_path, &driver)) { + g_assert (sysfs_path); + + device = nm_device_adsl_new (sysfs_path, ifname, driver); + g_assert (device); + + priv->devices = g_slist_prepend (priv->devices, device); + g_object_weak_ref (G_OBJECT (device), device_destroyed, self); + + g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); + g_object_unref (device); + + g_free (driver); + } } static void -adsl_remove (NMAtmManager *self, GUdevDevice *device) +adsl_remove (NMAtmManager *self, GUdevDevice *udev_device) { - nm_log_dbg (LOGD_HW, "adsl_remove: Removing ATM Device"); + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + const char *iface = g_udev_device_get_name (udev_device); + GSList *iter; - g_signal_emit (self, signals[DEVICE_REMOVED], 0, g_udev_device_get_name (device)); + nm_log_dbg (LOGD_HW, "(%s): removing ATM device", iface); + + for (iter = priv->devices; iter; iter = iter->next) { + NMDevice *device = iter->data; + + /* Match 'iface' not 'ip_iface' to the ATM device instead of the + * NAS bridge interface or PPPoE interface. + */ + if (g_strcmp0 (nm_device_get_iface (device), iface) != 0) + continue; + + g_object_weak_unref (G_OBJECT (iter->data), device_destroyed, self); + priv->devices = g_slist_remove (priv->devices, device); + g_signal_emit_by_name (device, NM_DEVICE_REMOVED); + break; + } } -void -nm_atm_manager_query_devices (NMAtmManager *self) +static gboolean +query_devices (NMAtmManager *self) { NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); GUdevEnumerator *enumerator; GList *devices, *iter; - g_return_if_fail (NM_IS_ATM_MANAGER (self)); - enumerator = g_udev_enumerator_new (priv->client); g_udev_enumerator_add_match_subsystem (enumerator, "atm"); g_udev_enumerator_add_match_is_initialized (enumerator); @@ -135,6 +185,8 @@ nm_atm_manager_query_devices (NMAtmManager *self) } g_list_free (devices); g_object_unref (enumerator); + + return G_SOURCE_REMOVE; } static void @@ -165,6 +217,8 @@ handle_uevent (GUdevClient *client, adsl_remove (self, device); } +/*********************************************************************/ + static void nm_atm_manager_init (NMAtmManager *self) { @@ -173,6 +227,27 @@ nm_atm_manager_init (NMAtmManager *self) priv->client = g_udev_client_new (subsys); g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); + + priv->start_id = g_idle_add ((GSourceFunc) query_devices, self); +} + +static void +device_factory_interface_init (NMDeviceFactory *factory_iface) +{ +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_DEVICE_TYPE: + g_value_set_uint (value, PLUGIN_TYPE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void @@ -180,9 +255,21 @@ dispose (GObject *object) { NMAtmManager *self = NM_ATM_MANAGER (object); NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + GSList *iter; + if (priv->client) + g_signal_handlers_disconnect_by_func (priv->client, handle_uevent, self); g_clear_object (&priv->client); + if (priv->start_id) { + g_source_remove (priv->start_id); + priv->start_id = 0; + } + + for (iter = priv->devices; iter; iter = iter->next) + g_object_weak_unref (G_OBJECT (iter->data), device_destroyed, self); + g_clear_pointer (&priv->devices, g_slist_free); + G_OBJECT_CLASS (nm_atm_manager_parent_class)->dispose (object); } @@ -195,21 +282,9 @@ nm_atm_manager_class_init (NMAtmManagerClass *klass) /* virtual methods */ object_class->dispose = dispose; + object_class->get_property = get_property; - /* Signals */ - signals[DEVICE_ADDED] = - g_signal_new ("device-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMAtmManagerClass, device_added), - NULL, NULL, NULL, - G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - - signals[DEVICE_REMOVED] = - g_signal_new ("device-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMAtmManagerClass, device_removed), - NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_STRING); + g_object_class_override_property (object_class, + PROP_DEVICE_TYPE, + NM_DEVICE_FACTORY_DEVICE_TYPE); } diff --git a/src/nm-atm-manager.h b/src/devices/atm/nm-atm-manager.h similarity index 58% rename from src/nm-atm-manager.h rename to src/devices/atm/nm-atm-manager.h index 773f33ffc7..0052522075 100644 --- a/src/nm-atm-manager.h +++ b/src/devices/atm/nm-atm-manager.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. */ #ifndef NM_ATM_MANAGER_H @@ -25,16 +25,10 @@ #include #include -#include - G_BEGIN_DECLS #define NM_TYPE_ATM_MANAGER (nm_atm_manager_get_type ()) #define NM_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ATM_MANAGER, NMAtmManager)) -#define NM_ATM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) -#define NM_IS_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ATM_MANAGER)) -#define NM_IS_ATM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ATM_MANAGER)) -#define NM_ATM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) typedef struct { GObject parent; @@ -42,22 +36,7 @@ typedef struct { typedef struct { GObjectClass parent; - - /* signals */ - void (*device_added) (NMAtmManager *manager, - const char *iface, - const char *sysfs_path, - const char *driver); - - void (*device_removed) (NMAtmManager *manager, - const char *iface); } NMAtmManagerClass; -GType nm_atm_manager_get_type (void); - -NMAtmManager *nm_atm_manager_new (void); - -void nm_atm_manager_query_devices (NMAtmManager *manager); - #endif /* NM_ATM_MANAGER_H */ diff --git a/src/devices/nm-device-adsl.c b/src/devices/atm/nm-device-adsl.c similarity index 100% rename from src/devices/nm-device-adsl.c rename to src/devices/atm/nm-device-adsl.c diff --git a/src/devices/nm-device-adsl.h b/src/devices/atm/nm-device-adsl.h similarity index 100% rename from src/devices/nm-device-adsl.h rename to src/devices/atm/nm-device-adsl.h diff --git a/src/nm-manager.c b/src/nm-manager.c index 22e8a32f57..fa76575cf0 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -51,7 +51,6 @@ #include "nm-device-team.h" #include "nm-device-bridge.h" #include "nm-device-vlan.h" -#include "nm-device-adsl.h" #include "nm-device-generic.h" #include "nm-device-veth.h" #include "nm-device-tun.h" @@ -63,7 +62,6 @@ #include "nm-setting-vpn.h" #include "nm-dbus-glib-types.h" #include "nm-platform.h" -#include "nm-atm-manager.h" #include "nm-rfkill-manager.h" #include "nm-hostname-provider.h" #include "nm-bluez-manager.h" @@ -165,7 +163,6 @@ static NMActiveConnection *_new_active_connection (NMManager *self, static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data); static NMDevice *find_device_by_ip_iface (NMManager *self, const gchar *iface); -static NMDevice *find_device_by_iface (NMManager *self, const gchar *iface); static void rfkill_change_wifi (const char *desc, gboolean enabled); @@ -219,7 +216,6 @@ typedef struct { NMDBusManager *dbus_mgr; gboolean prop_filter_added; - NMAtmManager *atm_mgr; NMRfkillManager *rfkill_mgr; NMBluezManager *bluez_mgr; @@ -2026,21 +2022,6 @@ find_device_by_ip_iface (NMManager *self, const gchar *iface) return NULL; } -static NMDevice * -find_device_by_iface (NMManager *self, const gchar *iface) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter; - - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMDevice *candidate = iter->data; - - if (g_strcmp0 (nm_device_get_iface (candidate), iface) == 0) - return candidate; - } - return NULL; -} - static NMDevice * find_device_by_ifindex (NMManager *self, guint32 ifindex) { @@ -2316,49 +2297,6 @@ platform_link_removed_cb (NMPlatform *platform, remove_device (self, device, FALSE); } -static void -atm_device_added_cb (NMAtmManager *atm_mgr, - const char *iface, - const char *sysfs_path, - const char *driver, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMDevice *device; - - g_return_if_fail (iface != NULL); - g_return_if_fail (sysfs_path != NULL); - - device = find_device_by_iface (self, iface); - if (device) - return; - - device = nm_device_adsl_new (sysfs_path, iface, driver); - if (device) - add_device (self, device, TRUE); -} - -static void -atm_device_removed_cb (NMAtmManager *manager, - const char *iface, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMDevice *device = NULL; - GSList *iter; - - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - if (g_strcmp0 (nm_device_get_iface (NM_DEVICE (iter->data)), iface) == 0) { - device = iter->data; - break; - } - } - - if (device) - remove_device (self, device, FALSE); -} - static void rfkill_manager_rfkill_changed_cb (NMRfkillManager *rfkill_mgr, RfKillType rtype, @@ -4230,7 +4168,6 @@ nm_manager_start (NMManager *self) system_hostname_changed_cb (priv->settings, NULL, self); nm_platform_query_devices (); - nm_atm_manager_query_devices (priv->atm_mgr); nm_bluez_manager_query_devices (priv->bluez_mgr); /* @@ -4789,16 +4726,6 @@ nm_manager_new (NMSettings *settings, G_CALLBACK (platform_link_removed_cb), singleton); - priv->atm_mgr = nm_atm_manager_new (); - g_signal_connect (priv->atm_mgr, - "device-added", - G_CALLBACK (atm_device_added_cb), - singleton); - g_signal_connect (priv->atm_mgr, - "device-removed", - G_CALLBACK (atm_device_removed_cb), - singleton); - priv->rfkill_mgr = nm_rfkill_manager_new (); g_signal_connect (priv->rfkill_mgr, "rfkill-changed", From a9591aecaf0118f8e603a4ed0a40f3ea8535529b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Feb 2014 06:35:56 -0600 Subject: [PATCH 7/9] bluez: make Bluetooth support a plugin Make Bluetooth support a plugin using the new device factory interface. Provides a 5% size reduction in the core NM binary. Before After NM: 1253016 1187224 (-5%) BT: 0 85752 (all results from stripped files) --- configure.ac | 1 + po/POTFILES.in | 4 +- src/Makefile.am | 18 +- src/bluez-manager/nm-bluez-manager.h | 71 ------ src/devices/bluetooth/Makefile.am | 56 +++++ .../bluetooth}/nm-bluez-common.h | 0 .../bluetooth}/nm-bluez-device.c | 8 + .../bluetooth}/nm-bluez-device.h | 8 +- .../bluetooth}/nm-bluez-manager.c | 202 ++++++------------ src/devices/bluetooth/nm-bluez-manager.h | 44 ++++ .../bluetooth}/nm-bluez4-adapter.c | 0 .../bluetooth}/nm-bluez4-adapter.h | 0 .../bluetooth}/nm-bluez4-manager.c | 26 +-- .../bluetooth}/nm-bluez4-manager.h | 6 +- .../bluetooth}/nm-bluez5-manager.c | 21 +- .../bluetooth}/nm-bluez5-manager.h | 6 +- src/devices/{ => bluetooth}/nm-device-bt.c | 13 +- src/devices/{ => bluetooth}/nm-device-bt.h | 0 src/nm-manager.c | 88 -------- 19 files changed, 207 insertions(+), 365 deletions(-) delete mode 100644 src/bluez-manager/nm-bluez-manager.h create mode 100644 src/devices/bluetooth/Makefile.am rename src/{bluez-manager => devices/bluetooth}/nm-bluez-common.h (100%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez-device.c (98%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez-device.h (95%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez-manager.c (72%) create mode 100644 src/devices/bluetooth/nm-bluez-manager.h rename src/{bluez-manager => devices/bluetooth}/nm-bluez4-adapter.c (100%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez4-adapter.h (100%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez4-manager.c (92%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez4-manager.h (93%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez5-manager.c (94%) rename src/{bluez-manager => devices/bluetooth}/nm-bluez5-manager.h (93%) rename src/devices/{ => bluetooth}/nm-device-bt.c (99%) rename src/devices/{ => bluetooth}/nm-device-bt.h (100%) diff --git a/configure.ac b/configure.ac index b428649997..79aa225fd5 100644 --- a/configure.ac +++ b/configure.ac @@ -764,6 +764,7 @@ src/rdisc/Makefile src/rdisc/tests/Makefile src/devices/atm/Makefile src/devices/wimax/Makefile +src/devices/bluetooth/Makefile libnm-util/libnm-util.pc libnm-util/Makefile libnm-util/tests/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index 9806ceba19..fa7806f3f4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -40,7 +40,6 @@ libnm-util/nm-setting-wireless.c libnm-util/nm-utils.c policy/org.freedesktop.NetworkManager.policy.in.in src/main.c -src/bluez-manager/nm-bluez-device.c src/dhcp-manager/nm-dhcp-dhclient.c src/dhcp-manager/nm-dhcp-dhclient-utils.c src/dhcp-manager/nm-dhcp-manager.c @@ -50,9 +49,10 @@ src/config/nm-config.c src/devices/atm/nm-device-adsl.c src/modem-manager/nm-modem-broadband.c src/modem-manager/nm-modem-old.c +src/devices/bluetooth/nm-bluez-device.c +src/devices/bluetooth/nm-device-bt.c src/devices/nm-device-bond.c src/devices/nm-device-bridge.c -src/devices/nm-device-bt.c src/devices/nm-device-ethernet.c src/devices/nm-device-infiniband.c src/devices/nm-device-olpc-mesh.c diff --git a/src/Makefile.am b/src/Makefile.am index 9ca1d68438..a50932ed20 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,7 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ devices/atm \ + devices/bluetooth \ dhcp-manager \ ppp-manager \ settings/plugins @@ -52,18 +53,6 @@ NetworkManager_LDADD = libNetworkManager.la $(top_builddir)/libgsystem.la $(LIBN noinst_LTLIBRARIES = libNetworkManager.la nm_sources = \ - bluez-manager/nm-bluez-common.h \ - bluez-manager/nm-bluez-device.c \ - bluez-manager/nm-bluez-device.h \ - bluez-manager/nm-bluez-manager.c \ - bluez-manager/nm-bluez-manager.h \ - bluez-manager/nm-bluez4-adapter.c \ - bluez-manager/nm-bluez4-adapter.h \ - bluez-manager/nm-bluez4-manager.c \ - bluez-manager/nm-bluez4-manager.h \ - bluez-manager/nm-bluez5-manager.c \ - bluez-manager/nm-bluez5-manager.h \ - \ config/nm-config.c \ config/nm-config.h \ config/nm-config-device.c \ @@ -75,8 +64,6 @@ nm_sources = \ devices/nm-device-bond.h \ devices/nm-device-bridge.c \ devices/nm-device-bridge.h \ - devices/nm-device-bt.c \ - devices/nm-device-bt.h \ devices/nm-device-ethernet.c \ devices/nm-device-ethernet.h \ devices/nm-device-factory.c \ @@ -303,8 +290,8 @@ endif GLIB_GENERATED = nm-enum-types.h nm-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM - nm_enum_types_sources = $(nm_sources) + if WITH_WIMAX nm_enum_types_sources += devices/wimax/nm-device-wimax.h AM_CPPFLAGS += -I$(top_srcdir)/src/devices/wimax @@ -319,7 +306,6 @@ glue_sources = \ nm-agent-manager-glue.h \ nm-device-bond-glue.h \ nm-device-bridge-glue.h \ - nm-device-bt-glue.h \ nm-device-ethernet-glue.h \ nm-device-generic-glue.h \ nm-device-glue.h \ diff --git a/src/bluez-manager/nm-bluez-manager.h b/src/bluez-manager/nm-bluez-manager.h deleted file mode 100644 index 836416fa8c..0000000000 --- a/src/bluez-manager/nm-bluez-manager.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2013 Red Hat, Inc. - */ - -#ifndef NM_BLUEZ_MANAGER_H -#define NM_BLUEZ_MANAGER_H - -#include -#include - -#include -#include "nm-connection-provider.h" - -G_BEGIN_DECLS - -#define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type ()) -#define NM_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManager)) -#define NM_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass)) -#define NM_IS_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_BLUEZ_MANAGER)) -#define NM_IS_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_BLUEZ_MANAGER)) -#define NM_BLUEZ_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass)) - -#define NM_BLUEZ_MANAGER_BDADDR_ADDED "bdaddr-added" -#define NM_BLUEZ_MANAGER_BDADDR_REMOVED "bdaddr-removed" - -#define NM_BLUEZ_MANAGER_PROVIDER "provider" - -typedef struct { - GObject parent; -} NMBluezManager; - -typedef struct { - GObjectClass parent; - - /* Virtual functions */ - void (*bdaddr_added) (NMBluezManager *manager, - const char *bdaddr, - const char *name, - const char *object_path, - guint uuids); - - void (*bdaddr_removed) (NMBluezManager *manager, - const char *bdaddr, - const char *object_path); -} NMBluezManagerClass; - -GType nm_bluez_manager_get_type (void); - -NMBluezManager *nm_bluez_manager_new (NMConnectionProvider *provider); - -void nm_bluez_manager_query_devices (NMBluezManager *manager); - -#endif /* NM_BLUEZ_MANAGER_H */ - diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am new file mode 100644 index 0000000000..7713fc9124 --- /dev/null +++ b/src/devices/bluetooth/Makefile.am @@ -0,0 +1,56 @@ +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +AM_CPPFLAGS = \ + -I${top_srcdir}/src \ + -I${top_builddir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/devices \ + -I${top_srcdir}/src/settings \ + -I${top_srcdir}/src/platform \ + -I${top_srcdir}/src/modem-manager \ + -I${top_builddir}/include \ + -I${top_srcdir}/include \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-util \ + $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GUDEV_CFLAGS) + +GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_bt_enum_types_sources = $(srcdir)/nm-device-bt.h + +nm-device-bt-glue.h: $(top_srcdir)/introspection/nm-device-bt.xml + dbus-binding-tool --prefix=nm_device_bt --mode=glib-server --output=$@ $< + +BUILT_SOURCES = $(GLIB_GENERATED) nm-device-bt-glue.h + +pkglib_LTLIBRARIES = libnm-device-plugin-bt.la + +libnm_device_plugin_bt_la_SOURCES = \ + nm-bluez-manager.c \ + nm-bluez-manager.h \ + nm-bluez-common.h \ + nm-bluez-device.c \ + nm-bluez-device.h \ + nm-bluez4-adapter.c \ + nm-bluez4-adapter.h \ + nm-bluez4-manager.c \ + nm-bluez4-manager.h \ + nm-bluez5-manager.c \ + nm-bluez5-manager.h \ + \ + nm-device-bt.c \ + nm-device-bt.h \ + \ + $(BUILT_SOURCES) + +libnm_device_plugin_bt_la_LDFLAGS = -module -avoid-version +libnm_device_plugin_bt_la_LIBADD = $(DBUS_LIBS) $(GUDEV_LIBS) + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/src/bluez-manager/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h similarity index 100% rename from src/bluez-manager/nm-bluez-common.h rename to src/devices/bluetooth/nm-bluez-common.h diff --git a/src/bluez-manager/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c similarity index 98% rename from src/bluez-manager/nm-bluez-device.c rename to src/devices/bluetooth/nm-bluez-device.c index 8e8f39d066..e04e8d4dee 100644 --- a/src/bluez-manager/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -87,6 +87,7 @@ enum { /* Signals */ enum { INITIALIZED, + REMOVED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -1169,5 +1170,12 @@ nm_bluez_device_class_init (NMBluezDeviceClass *config_class) G_STRUCT_OFFSET (NMBluezDeviceClass, initialized), NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + signals[REMOVED] = g_signal_new (NM_BLUEZ_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMBluezDeviceClass, removed), + NULL, NULL, NULL, + G_TYPE_NONE, 0); } diff --git a/src/bluez-manager/nm-bluez-device.h b/src/devices/bluetooth/nm-bluez-device.h similarity index 95% rename from src/bluez-manager/nm-bluez-device.h rename to src/devices/bluetooth/nm-bluez-device.h index 5e586ea5bb..0bf7d898b0 100644 --- a/src/bluez-manager/nm-bluez-device.h +++ b/src/devices/bluetooth/nm-bluez-device.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2012 Red Hat, Inc. + * Copyright (C) 2009 - 2014 Red Hat, Inc. */ #ifndef NM_BLUEZ_DEVICE_H @@ -36,6 +36,7 @@ #define NM_IS_BLUEZ_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_BLUEZ_DEVICE)) #define NM_BLUEZ_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_DEVICE, NMBluezDeviceClass)) +/* Properties */ #define NM_BLUEZ_DEVICE_PATH "path" #define NM_BLUEZ_DEVICE_ADDRESS "address" #define NM_BLUEZ_DEVICE_NAME "name" @@ -43,6 +44,9 @@ #define NM_BLUEZ_DEVICE_USABLE "usable" #define NM_BLUEZ_DEVICE_CONNECTED "connected" +/* Signals */ +#define NM_BLUEZ_DEVICE_REMOVED "removed" + typedef struct { GObject parent; } NMBluezDevice; @@ -53,7 +57,7 @@ typedef struct { /* virtual functions */ void (*initialized) (NMBluezDevice *self, gboolean success); - void (*invalid) (NMBluezDevice *self); + void (*removed) (NMBluezDevice *self); } NMBluezDeviceClass; GType nm_bluez_device_get_type (void); diff --git a/src/bluez-manager/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c similarity index 72% rename from src/bluez-manager/nm-bluez-manager.c rename to src/devices/bluetooth/nm-bluez-manager.c index b3026bc1f5..26ccb70c1a 100644 --- a/src/bluez-manager/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013 - 2014 Red Hat, Inc. */ #include @@ -25,10 +25,13 @@ #include "nm-logging.h" #include "nm-bluez-manager.h" +#include "nm-device-factory.h" #include "nm-bluez4-manager.h" #include "nm-bluez5-manager.h" #include "nm-bluez-device.h" #include "nm-bluez-common.h" +#include "nm-connection-provider.h" +#include "nm-device-bt.h" #include "nm-dbus-manager.h" @@ -47,27 +50,38 @@ typedef struct { #define NM_BLUEZ_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerPrivate)) -G_DEFINE_TYPE (NMBluezManager, nm_bluez_manager, G_TYPE_OBJECT) +static GType nm_bluez_manager_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMBluezManager, nm_bluez_manager, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) enum { - PROP_0, - PROP_PROVIDER, - - LAST_PROP + PROP_0, + PROP_DEVICE_TYPE, + LAST_PROP }; -enum { - BDADDR_ADDED, - BDADDR_REMOVED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - - static void check_bluez_and_try_setup (NMBluezManager *self); +/**************************************************************************/ + +#define PLUGIN_TYPE NM_DEVICE_TYPE_BT + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_BLUEZ_MANAGER, NULL); +} + +G_MODULE_EXPORT NMDeviceType +nm_device_factory_get_device_type (void) +{ + return PLUGIN_TYPE; +} + +/************************************************************************/ struct AsyncData { NMBluezManager *self; @@ -125,30 +139,33 @@ manager_bdaddr_added_cb (NMBluez4Manager *bluez_mgr, const char *bdaddr, const char *name, const char *object_path, - guint32 uuids, + guint32 capabilities, gpointer user_data) { - /* forward the signal... */ - g_signal_emit (NM_BLUEZ_MANAGER (user_data), signals[BDADDR_ADDED], 0, - bt_device, - bdaddr, - name, - object_path, - uuids); -} + NMBluezManager *self = NM_BLUEZ_MANAGER (user_data); + NMDevice *device; + gboolean has_dun = (capabilities & NM_BT_CAPABILITY_DUN); + gboolean has_nap = (capabilities & NM_BT_CAPABILITY_NAP); -static void -manager_bdaddr_removed_cb (NMBluez4Manager *bluez_mgr, - const char *bdaddr, - const char *object_path, - gpointer user_data) -{ - /* forward the signal... */ - g_signal_emit (NM_BLUEZ_MANAGER (user_data), signals[BDADDR_REMOVED], 0, - bdaddr, - object_path); -} + g_return_if_fail (bdaddr != NULL); + g_return_if_fail (name != NULL); + g_return_if_fail (object_path != NULL); + g_return_if_fail (capabilities != NM_BT_CAPABILITY_NONE); + g_return_if_fail (NM_IS_BLUEZ_DEVICE (bt_device)); + device = nm_device_bt_new (bt_device, object_path, bdaddr, name, capabilities); + if (!device) + return; + + nm_log_info (LOGD_BT, "BT device %s (%s) added (%s%s%s)", + name, + bdaddr, + has_dun ? "DUN" : "", + has_dun && has_nap ? " " : "", + has_nap ? "NAP" : ""); + g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); + g_object_unref (device); +} static void setup_version_number (NMBluezManager *self, int bluez_version) @@ -180,10 +197,6 @@ setup_bluez4 (NMBluezManager *self) NM_BLUEZ_MANAGER_BDADDR_ADDED, G_CALLBACK (manager_bdaddr_added_cb), self); - g_signal_connect (manager, - NM_BLUEZ_MANAGER_BDADDR_REMOVED, - G_CALLBACK (manager_bdaddr_removed_cb), - self); nm_bluez4_manager_query_devices (manager); } @@ -203,10 +216,6 @@ setup_bluez5 (NMBluezManager *self) NM_BLUEZ_MANAGER_BDADDR_ADDED, G_CALLBACK (manager_bdaddr_added_cb), self); - g_signal_connect (manager, - NM_BLUEZ_MANAGER_BDADDR_REMOVED, - G_CALLBACK (manager_bdaddr_removed_cb), - self); nm_bluez5_manager_query_devices (manager); } @@ -364,64 +373,15 @@ check_bluez_and_try_setup (NMBluezManager *self) async_data_pack (self)); } - -void -nm_bluez_manager_query_devices (NMBluezManager *self) -{ - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - - switch (priv->bluez_version) { - case 4: - nm_bluez4_manager_query_devices (priv->manager4); - break; - case 5: - nm_bluez5_manager_query_devices (priv->manager5); - break; - default: - /* the proxy implementation does nothing in this case. */ - break; - } -} - - -NMBluezManager * -nm_bluez_manager_new (NMConnectionProvider *provider) -{ - g_return_val_if_fail (NM_IS_CONNECTION_PROVIDER (provider), NULL); - - return g_object_new (NM_TYPE_BLUEZ_MANAGER, - NM_BLUEZ_MANAGER_PROVIDER, - provider, - NULL); -} - - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_PROVIDER: - /* Construct only */ - priv->provider = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} +/*********************************************************************/ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (object); - switch (prop_id) { - case PROP_PROVIDER: - g_value_set_object (value, priv->provider); + case PROP_DEVICE_TYPE: + g_value_set_uint (value, PLUGIN_TYPE); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -429,23 +389,18 @@ get_property (GObject *object, guint prop_id, } } - static void dispose (GObject *object) { NMBluezManager *self = NM_BLUEZ_MANAGER (object); NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - g_clear_object (&priv->provider); - if (priv->manager4) { - g_signal_handlers_disconnect_by_func (priv->manager4, G_CALLBACK (manager_bdaddr_added_cb), self); - g_signal_handlers_disconnect_by_func (priv->manager4, G_CALLBACK (manager_bdaddr_removed_cb), self); + g_signal_handlers_disconnect_by_func (priv->manager4, manager_bdaddr_added_cb, self); g_clear_object (&priv->manager4); } if (priv->manager5) { - g_signal_handlers_disconnect_by_func (priv->manager5, G_CALLBACK (manager_bdaddr_added_cb), self); - g_signal_handlers_disconnect_by_func (priv->manager5, G_CALLBACK (manager_bdaddr_removed_cb), self); + g_signal_handlers_disconnect_by_func (priv->manager5, manager_bdaddr_added_cb, self); g_clear_object (&priv->manager5); } @@ -458,17 +413,23 @@ static void constructed (GObject *object) { NMBluezManager *self = NM_BLUEZ_MANAGER (object); - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); G_OBJECT_CLASS (nm_bluez_manager_parent_class)->constructed (object); - g_return_if_fail (priv->provider); - check_bluez_and_try_setup (self); } static void nm_bluez_manager_init (NMBluezManager *self) +{ + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + + priv->provider = nm_connection_provider_get (); + g_assert (priv->provider); +} + +static void +device_factory_interface_init (NMDeviceFactory *factory_iface) { } @@ -482,33 +443,10 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass) /* virtual methods */ object_class->dispose = dispose; object_class->get_property = get_property; - object_class->set_property = set_property; object_class->constructed = constructed; - g_object_class_install_property - (object_class, PROP_PROVIDER, - g_param_spec_object (NM_BLUEZ_MANAGER_PROVIDER, - "Provider", - "Connection Provider", - NM_TYPE_CONNECTION_PROVIDER, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /* Signals */ - signals[BDADDR_ADDED] = - g_signal_new (NM_BLUEZ_MANAGER_BDADDR_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_added), - NULL, NULL, NULL, - G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); - - signals[BDADDR_REMOVED] = - g_signal_new (NM_BLUEZ_MANAGER_BDADDR_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_removed), - NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); + g_object_class_override_property (object_class, + PROP_DEVICE_TYPE, + NM_DEVICE_FACTORY_DEVICE_TYPE); } diff --git a/src/devices/bluetooth/nm-bluez-manager.h b/src/devices/bluetooth/nm-bluez-manager.h new file mode 100644 index 0000000000..68d6dbe5e8 --- /dev/null +++ b/src/devices/bluetooth/nm-bluez-manager.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2007 - 2008 Novell, Inc. + * Copyright (C) 2007 - 2014 Red Hat, Inc. + */ + +#ifndef NM_BLUEZ_MANAGER_H +#define NM_BLUEZ_MANAGER_H + +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type ()) +#define NM_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManager)) + +#define NM_BLUEZ_MANAGER_BDADDR_ADDED "bdaddr-added" + +typedef struct { + GObject parent; +} NMBluezManager; + +typedef struct { + GObjectClass parent; +} NMBluezManagerClass; + +#endif /* NM_BLUEZ_MANAGER_H */ + diff --git a/src/bluez-manager/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c similarity index 100% rename from src/bluez-manager/nm-bluez4-adapter.c rename to src/devices/bluetooth/nm-bluez4-adapter.c diff --git a/src/bluez-manager/nm-bluez4-adapter.h b/src/devices/bluetooth/nm-bluez4-adapter.h similarity index 100% rename from src/bluez-manager/nm-bluez4-adapter.h rename to src/devices/bluetooth/nm-bluez4-adapter.h diff --git a/src/bluez-manager/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c similarity index 92% rename from src/bluez-manager/nm-bluez4-manager.c rename to src/devices/bluetooth/nm-bluez4-manager.c index 58162f0a81..2660cbd924 100644 --- a/src/bluez-manager/nm-bluez4-manager.c +++ b/src/devices/bluetooth/nm-bluez4-manager.c @@ -50,8 +50,6 @@ G_DEFINE_TYPE (NMBluez4Manager, nm_bluez4_manager, G_TYPE_OBJECT) enum { BDADDR_ADDED, - BDADDR_REMOVED, - LAST_SIGNAL }; @@ -93,11 +91,8 @@ device_added (NMBluez4Adapter *adapter, NMBluezDevice *device, gpointer user_dat static void device_removed (NMBluez4Adapter *adapter, NMBluezDevice *device, gpointer user_data) { - NMBluez4Manager *self = NM_BLUEZ4_MANAGER (user_data); - - g_signal_emit (self, signals[BDADDR_REMOVED], 0, - nm_bluez_device_get_address (device), - nm_bluez_device_get_path (device)); + /* Re-emit the signal on the device for now; flatten this later */ + g_signal_emit_by_name (device, NM_BLUEZ_DEVICE_REMOVED); } static void @@ -132,13 +127,8 @@ adapter_removed (DBusGProxy *proxy, const char *path, NMBluez4Manager *self) GSList *devices, *iter; devices = nm_bluez4_adapter_get_devices (priv->adapter); - for (iter = devices; iter; iter = g_slist_next (iter)) { - NMBluezDevice *device = NM_BLUEZ_DEVICE (iter->data); - - g_signal_emit (self, signals[BDADDR_REMOVED], 0, - nm_bluez_device_get_address (device), - nm_bluez_device_get_path (device)); - } + for (iter = devices; iter; iter = g_slist_next (iter)) + g_signal_emit_by_name (NM_BLUEZ_DEVICE (iter->data), NM_BLUEZ_DEVICE_REMOVED); g_slist_free (devices); } @@ -367,13 +357,5 @@ nm_bluez4_manager_class_init (NMBluez4ManagerClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); - - signals[BDADDR_REMOVED] = - g_signal_new (NM_BLUEZ_MANAGER_BDADDR_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMBluez4ManagerClass, bdaddr_removed), - NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); } diff --git a/src/bluez-manager/nm-bluez4-manager.h b/src/devices/bluetooth/nm-bluez4-manager.h similarity index 93% rename from src/bluez-manager/nm-bluez4-manager.h rename to src/devices/bluetooth/nm-bluez4-manager.h index 20e6c1bc18..19b1c65a1b 100644 --- a/src/bluez-manager/nm-bluez4-manager.h +++ b/src/devices/bluetooth/nm-bluez4-manager.h @@ -44,16 +44,12 @@ typedef struct { typedef struct { GObjectClass parent; - /* Virtual functions */ + /* Signals */ void (*bdaddr_added) (NMBluez4Manager *manager, const char *bdaddr, const char *name, const char *object_path, guint uuids); - - void (*bdaddr_removed) (NMBluez4Manager *manager, - const char *bdaddr, - const char *object_path); } NMBluez4ManagerClass; GType nm_bluez4_manager_get_type (void); diff --git a/src/bluez-manager/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c similarity index 94% rename from src/bluez-manager/nm-bluez5-manager.c rename to src/devices/bluetooth/nm-bluez5-manager.c index 77e5bdd4ba..63006b3ab8 100644 --- a/src/bluez-manager/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -50,8 +50,6 @@ G_DEFINE_TYPE (NMBluez5Manager, nm_bluez5_manager, G_TYPE_OBJECT) enum { BDADDR_ADDED, - BDADDR_REMOVED, - LAST_SIGNAL }; @@ -88,13 +86,10 @@ nm_bluez5_manager_query_devices (NMBluez5Manager *self) static void remove_device (NMBluez5Manager *self, NMBluezDevice *device) { - if (nm_bluez_device_get_usable (device)) { - g_signal_emit (self, signals[BDADDR_REMOVED], 0, - nm_bluez_device_get_address (device), - nm_bluez_device_get_path (device)); - } g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_initialized), self); g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_usable), self); + if (nm_bluez_device_get_usable (device)) + g_signal_emit_by_name (device, NM_BLUEZ_DEVICE_REMOVED); } static void @@ -127,9 +122,7 @@ device_usable (NMBluezDevice *device, GParamSpec *pspec, NMBluez5Manager *self) nm_bluez_device_get_address (device)); emit_bdaddr_added (self, device); } else - g_signal_emit (self, signals[BDADDR_REMOVED], 0, - nm_bluez_device_get_address (device), - nm_bluez_device_get_path (device)); + g_signal_emit_by_name (device, NM_BLUEZ_DEVICE_REMOVED); } static void @@ -425,12 +418,4 @@ nm_bluez5_manager_class_init (NMBluez5ManagerClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); - - signals[BDADDR_REMOVED] = - g_signal_new (NM_BLUEZ_MANAGER_BDADDR_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMBluez5ManagerClass, bdaddr_removed), - NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); } diff --git a/src/bluez-manager/nm-bluez5-manager.h b/src/devices/bluetooth/nm-bluez5-manager.h similarity index 93% rename from src/bluez-manager/nm-bluez5-manager.h rename to src/devices/bluetooth/nm-bluez5-manager.h index 9cef5fd344..79f347bcef 100644 --- a/src/bluez-manager/nm-bluez5-manager.h +++ b/src/devices/bluetooth/nm-bluez5-manager.h @@ -44,16 +44,12 @@ typedef struct { typedef struct { GObjectClass parent; - /* Virtual functions */ + /* Signals */ void (*bdaddr_added) (NMBluez5Manager *manager, const char *bdaddr, const char *name, const char *object_path, guint uuids); - - void (*bdaddr_removed) (NMBluez5Manager *manager, - const char *bdaddr, - const char *object_path); } NMBluez5ManagerClass; GType nm_bluez5_manager_get_type (void); diff --git a/src/devices/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c similarity index 99% rename from src/devices/nm-device-bt.c rename to src/devices/bluetooth/nm-device-bt.c index ecb015b03c..6998bb1e20 100644 --- a/src/devices/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -44,7 +44,7 @@ #include "nm-setting-ppp.h" #include "nm-device-bt-glue.h" #include "NetworkManagerUtils.h" -#include "nm-enum-types.h" +#include "nm-bt-enum-types.h" #include "nm-utils.h" #define MM_OLD_DBUS_SERVICE "org.freedesktop.ModemManager" @@ -926,6 +926,12 @@ deactivate (NMDevice *device) NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate (device); } +static void +bluez_device_removed (NMBluezDevice *bdev, gpointer user_data) +{ + g_signal_emit_by_name (NM_DEVICE_BT (user_data), NM_DEVICE_REMOVED); +} + /*****************************************************************************/ static gboolean @@ -1116,6 +1122,7 @@ set_property (GObject *object, guint prop_id, case PROP_BT_DEVICE: /* Construct only */ priv->bt_device = g_value_dup_object (value); + g_signal_connect (priv->bt_device, "removed", G_CALLBACK (bluez_device_removed), object); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1155,9 +1162,7 @@ dispose (GObject *object) priv->timeout_id = 0; } - g_signal_handlers_disconnect_by_func (priv->bt_device, - G_CALLBACK (bluez_connected_changed), - object); + g_signal_handlers_disconnect_matched (priv->bt_device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, object); if (priv->dbus_mgr && priv->mm_watch_id) { g_signal_handler_disconnect (priv->dbus_mgr, priv->mm_watch_id); diff --git a/src/devices/nm-device-bt.h b/src/devices/bluetooth/nm-device-bt.h similarity index 100% rename from src/devices/nm-device-bt.h rename to src/devices/bluetooth/nm-device-bt.h diff --git a/src/nm-manager.c b/src/nm-manager.c index fa76575cf0..2d6c0f1121 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -40,7 +40,6 @@ #include "nm-dbus-manager.h" #include "nm-vpn-manager.h" #include "nm-modem-manager.h" -#include "nm-device-bt.h" #include "nm-device.h" #include "nm-device-ethernet.h" #include "nm-device-wifi.h" @@ -56,7 +55,6 @@ #include "nm-device-tun.h" #include "nm-device-macvlan.h" #include "nm-device-gre.h" -#include "nm-setting-bluetooth.h" #include "nm-setting-connection.h" #include "nm-setting-wireless.h" #include "nm-setting-vpn.h" @@ -64,8 +62,6 @@ #include "nm-platform.h" #include "nm-rfkill-manager.h" #include "nm-hostname-provider.h" -#include "nm-bluez-manager.h" -#include "nm-bluez-common.h" #include "nm-settings.h" #include "nm-settings-connection.h" #include "nm-manager-auth.h" @@ -135,19 +131,6 @@ static void impl_manager_check_connectivity (NMManager *manager, #include "nm-manager-glue.h" -static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, - NMBluezDevice *bt_device, - const char *bdaddr, - const char *name, - const char *object_path, - guint32 uuids, - NMManager *manager); - -static void bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, - const char *bdaddr, - const char *object_path, - gpointer user_data); - static void add_device (NMManager *self, NMDevice *device, gboolean generate_con); static void remove_device (NMManager *self, NMDevice *device, gboolean quitting); @@ -217,7 +200,6 @@ typedef struct { NMDBusManager *dbus_mgr; gboolean prop_filter_added; NMRfkillManager *rfkill_mgr; - NMBluezManager *bluez_mgr; /* List of NMDeviceFactoryFunc pointers sorted in priority order */ GSList *factories; @@ -1951,62 +1933,6 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) } } -static void -bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, - NMBluezDevice *bt_device, - const char *bdaddr, - const char *name, - const char *object_path, - guint32 capabilities, - NMManager *manager) -{ - NMDevice *device; - gboolean has_dun = (capabilities & NM_BT_CAPABILITY_DUN); - gboolean has_nap = (capabilities & NM_BT_CAPABILITY_NAP); - - g_return_if_fail (bdaddr != NULL); - g_return_if_fail (name != NULL); - g_return_if_fail (object_path != NULL); - g_return_if_fail (capabilities != NM_BT_CAPABILITY_NONE); - g_return_if_fail (NM_IS_BLUEZ_DEVICE (bt_device)); - - /* Make sure the device is not already in the device list */ - if (nm_manager_get_device_by_udi (manager, object_path)) - return; - - device = nm_device_bt_new (bt_device, object_path, bdaddr, name, capabilities); - if (device) { - nm_log_info (LOGD_HW, "BT device %s (%s) added (%s%s%s)", - name, - bdaddr, - has_dun ? "DUN" : "", - has_dun && has_nap ? " " : "", - has_nap ? "NAP" : ""); - - add_device (manager, device, FALSE); - g_object_unref (device); - } -} - -static void -bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, - const char *bdaddr, - const char *object_path, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMDevice *device; - - g_return_if_fail (bdaddr != NULL); - g_return_if_fail (object_path != NULL); - - device = nm_manager_get_device_by_udi (self, object_path); - if (device) { - nm_log_info (LOGD_HW, "BT device %s removed", bdaddr); - remove_device (self, device, FALSE); - } -} - static NMDevice * find_device_by_ip_iface (NMManager *self, const gchar *iface) { @@ -4168,7 +4094,6 @@ nm_manager_start (NMManager *self) system_hostname_changed_cb (priv->settings, NULL, self); nm_platform_query_devices (); - nm_bluez_manager_query_devices (priv->bluez_mgr); /* * Connections added before the manager is started do not emit @@ -4732,18 +4657,6 @@ nm_manager_new (NMSettings *settings, G_CALLBACK (rfkill_manager_rfkill_changed_cb), singleton); - priv->bluez_mgr = nm_bluez_manager_new (NM_CONNECTION_PROVIDER (priv->settings)); - - g_signal_connect (priv->bluez_mgr, - NM_BLUEZ_MANAGER_BDADDR_ADDED, - G_CALLBACK (bluez_manager_bdaddr_added_cb), - singleton); - - g_signal_connect (priv->bluez_mgr, - NM_BLUEZ_MANAGER_BDADDR_REMOVED, - G_CALLBACK (bluez_manager_bdaddr_removed_cb), - singleton); - /* Force kernel WiFi rfkill state to follow NM saved wifi state in case * the BIOS doesn't save rfkill state, and to be consistent with user * changes to the WirelessEnabled property which toggles kernel rfkill. @@ -5044,7 +4957,6 @@ dispose (GObject *object) priv->dbus_mgr = NULL; } - g_clear_object (&priv->bluez_mgr); g_clear_object (&priv->aipd_proxy); g_clear_object (&priv->sleep_monitor); From aeb1e103d809210c4fffb719e72f3b9fb1c8fb90 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Feb 2014 18:57:09 -0600 Subject: [PATCH 8/9] mobile: make WWAN support a plugin Make WWAN support a plugin using the new device factory interface. Provides a 5% size reduction in the core NM binary. Before After NM: 1187224 1125208 (-5%) MM: 0 100576 (all results from stripped files) --- configure.ac | 1 + po/POTFILES.in | 4 +- src/Makefile.am | 20 +-- src/devices/bluetooth/Makefile.am | 7 +- src/devices/wwan/Makefile.am | 75 ++++++++ src/{modem-manager => devices/wwan}/README | 0 src/devices/{ => wwan}/nm-device-modem.c | 14 +- src/devices/{ => wwan}/nm-device-modem.h | 2 +- .../wwan}/nm-modem-broadband.c | 29 ++-- .../wwan}/nm-modem-broadband.h | 2 +- .../wwan}/nm-modem-manager.c | 67 ++++---- .../wwan}/nm-modem-manager.h | 29 ++-- .../wwan}/nm-modem-old-types.h | 0 .../wwan}/nm-modem-old.c | 0 .../wwan}/nm-modem-old.h | 0 .../wwan}/nm-modem.c | 2 +- .../wwan}/nm-modem.h | 0 src/devices/wwan/nm-wwan-factory.c | 160 ++++++++++++++++++ src/devices/wwan/nm-wwan-factory.h | 37 ++++ src/nm-manager.c | 56 +----- 20 files changed, 353 insertions(+), 152 deletions(-) create mode 100644 src/devices/wwan/Makefile.am rename src/{modem-manager => devices/wwan}/README (100%) rename src/devices/{ => wwan}/nm-device-modem.c (97%) rename src/devices/{ => wwan}/nm-device-modem.h (96%) rename src/{modem-manager => devices/wwan}/nm-modem-broadband.c (96%) rename src/{modem-manager => devices/wwan}/nm-modem-broadband.h (97%) rename src/{modem-manager => devices/wwan}/nm-modem-manager.c (95%) rename src/{modem-manager => devices/wwan}/nm-modem-manager.h (54%) rename src/{modem-manager => devices/wwan}/nm-modem-old-types.h (100%) rename src/{modem-manager => devices/wwan}/nm-modem-old.c (100%) rename src/{modem-manager => devices/wwan}/nm-modem-old.h (100%) rename src/{modem-manager => devices/wwan}/nm-modem.c (99%) rename src/{modem-manager => devices/wwan}/nm-modem.h (100%) create mode 100644 src/devices/wwan/nm-wwan-factory.c create mode 100644 src/devices/wwan/nm-wwan-factory.h diff --git a/configure.ac b/configure.ac index 79aa225fd5..a7f60ff616 100644 --- a/configure.ac +++ b/configure.ac @@ -765,6 +765,7 @@ src/rdisc/tests/Makefile src/devices/atm/Makefile src/devices/wimax/Makefile src/devices/bluetooth/Makefile +src/devices/wwan/Makefile libnm-util/libnm-util.pc libnm-util/Makefile libnm-util/tests/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index fa7806f3f4..d03f5aa8fa 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -47,8 +47,6 @@ src/dns-manager/nm-dns-manager.c src/logging/nm-logging.c src/config/nm-config.c src/devices/atm/nm-device-adsl.c -src/modem-manager/nm-modem-broadband.c -src/modem-manager/nm-modem-old.c src/devices/bluetooth/nm-bluez-device.c src/devices/bluetooth/nm-device-bt.c src/devices/nm-device-bond.c @@ -58,6 +56,8 @@ src/devices/nm-device-infiniband.c src/devices/nm-device-olpc-mesh.c src/devices/nm-device-team.c src/devices/nm-device-vlan.c +src/devices/wwan/nm-modem-broadband.c +src/devices/wwan/nm-modem-old.c src/nm-manager.c src/nm-sleep-monitor-systemd.c src/settings/plugins/ifcfg-rh/reader.c diff --git a/src/Makefile.am b/src/Makefile.am index a50932ed20..fd0bb6964c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,7 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ devices/atm \ + devices/wwan \ devices/bluetooth \ dhcp-manager \ ppp-manager \ @@ -76,8 +77,6 @@ nm_sources = \ devices/nm-device-infiniband.h \ devices/nm-device-macvlan.c \ devices/nm-device-macvlan.h \ - devices/nm-device-modem.c \ - devices/nm-device-modem.h \ devices/nm-device-olpc-mesh.c \ devices/nm-device-olpc-mesh.h \ devices/nm-device-private.h \ @@ -123,14 +122,6 @@ nm_sources = \ logging/nm-logging.c \ logging/nm-logging.h \ \ - modem-manager/nm-modem-old.c \ - modem-manager/nm-modem-old.h \ - modem-manager/nm-modem-old-types.h \ - modem-manager/nm-modem-manager.c \ - modem-manager/nm-modem-manager.h \ - modem-manager/nm-modem.c \ - modem-manager/nm-modem.h \ - \ platform/nm-fake-platform.c \ platform/nm-fake-platform.h \ platform/nm-linux-platform.c \ @@ -259,12 +250,6 @@ nm_sources = \ NetworkManagerUtils.c \ NetworkManagerUtils.h -if WITH_MODEM_MANAGER_1 -nm_sources += \ - modem-manager/nm-modem-broadband.c \ - modem-manager/nm-modem-broadband.h -endif - if SESSION_TRACKING_SYSTEMD nm_sources += nm-session-monitor-systemd.c else @@ -312,7 +297,6 @@ glue_sources = \ nm-device-gre-glue.h \ nm-device-infiniband-glue.h \ nm-device-macvlan-glue.h \ - nm-device-modem-glue.h \ nm-device-olpc-mesh-glue.h \ nm-device-team-glue.h \ nm-device-tun-glue.h \ @@ -342,7 +326,6 @@ AM_CPPFLAGS += \ $(LIBNL_CFLAGS) \ $(LIBNDP_CFLAGS) \ $(LIBSOUP_CFLAGS) \ - $(MM_GLIB_CFLAGS) \ $(POLKIT_CFLAGS) \ $(SYSTEMD_LOGIN_CFLAGS) \ \ @@ -385,7 +368,6 @@ libNetworkManager_la_LIBADD = \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ $(LIBNL_LIBS) \ - $(MM_GLIB_LIBS) \ $(POLKIT_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ $(LIBDL) \ diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am index 7713fc9124..5e716af25f 100644 --- a/src/devices/bluetooth/Makefile.am +++ b/src/devices/bluetooth/Makefile.am @@ -9,7 +9,7 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/modem-manager \ + -I${top_srcdir}/src/devices/wwan \ -I${top_builddir}/include \ -I${top_srcdir}/include \ -I${top_builddir}/libnm-util \ @@ -50,7 +50,10 @@ libnm_device_plugin_bt_la_SOURCES = \ $(BUILT_SOURCES) libnm_device_plugin_bt_la_LDFLAGS = -module -avoid-version -libnm_device_plugin_bt_la_LIBADD = $(DBUS_LIBS) $(GUDEV_LIBS) +libnm_device_plugin_bt_la_LIBADD = \ + $(top_builddir)/src/devices/wwan/libnm-wwan.la \ + $(DBUS_LIBS) \ + $(GUDEV_LIBS) CLEANFILES = $(BUILT_SOURCES) diff --git a/src/devices/wwan/Makefile.am b/src/devices/wwan/Makefile.am new file mode 100644 index 0000000000..46ae255ea0 --- /dev/null +++ b/src/devices/wwan/Makefile.am @@ -0,0 +1,75 @@ +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +AM_CPPFLAGS = \ + -I${top_srcdir}/src \ + -I${top_builddir}/src \ + -I${top_srcdir}/src/logging \ + -I${top_srcdir}/src/devices \ + -I${top_srcdir}/src/settings \ + -I${top_srcdir}/src/platform \ + -I${top_builddir}/include \ + -I${top_srcdir}/include \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-util \ + $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(MM_GLIB_CFLAGS) + +BUILT_SOURCES = $(null) + +pkglib_LTLIBRARIES = libnm-wwan.la libnm-device-plugin-wwan.la + +########################################################### + +GLIB_GENERATED = nm-modem-enum-types.h nm-modem-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_modem_enum_types_sources = $(srcdir)/nm-modem.h + +BUILT_SOURCES += $(GLIB_GENERATED) + +libnm_wwan_la_SOURCES = \ + nm-modem-old.c \ + nm-modem-old.h \ + nm-modem-old-types.h \ + nm-modem-manager.c \ + nm-modem-manager.h \ + nm-modem.c \ + nm-modem.h \ + \ + $(GLIB_GENERATED) + +if WITH_MODEM_MANAGER_1 +libnm_wwan_la_SOURCES += \ + nm-modem-broadband.c \ + nm-modem-broadband.h +endif + +libnm_wwan_la_LDFLAGS = -avoid-version +libnm_wwan_la_LIBADD = $(DBUS_LIBS) $(MM_GLIB_LIBS) + +########################################################### + +nm-device-modem-glue.h: $(top_srcdir)/introspection/nm-device-modem.xml + dbus-binding-tool --prefix=nm_device_modem --mode=glib-server --output=$@ $< + +BUILT_SOURCES += nm-device-modem-glue.h + +libnm_device_plugin_wwan_la_SOURCES = \ + nm-wwan-factory.c \ + nm-wwan-factory.h \ + nm-device-modem.c \ + nm-device-modem.h \ + nm-device-modem-glue.h + +libnm_device_plugin_wwan_la_LDFLAGS = -module -avoid-version +libnm_device_plugin_wwan_la_LIBADD = \ + libnm-wwan.la \ + $(DBUS_LIBS) + +########################################################### + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/src/modem-manager/README b/src/devices/wwan/README similarity index 100% rename from src/modem-manager/README rename to src/devices/wwan/README diff --git a/src/devices/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c similarity index 97% rename from src/devices/nm-device-modem.c rename to src/devices/wwan/nm-device-modem.c index 6a3656c4e9..723f86e4dd 100644 --- a/src/devices/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -360,14 +360,14 @@ set_enabled (NMDevice *device, gboolean enabled) /*****************************************************************************/ NMDevice * -nm_device_modem_new (NMModem *modem, const char *driver) +nm_device_modem_new (NMModem *modem) { NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE; NMDeviceModemCapabilities current_caps = NM_DEVICE_MODEM_CAPABILITY_NONE; NMDevice *device; + const char *data_port; g_return_val_if_fail (NM_IS_MODEM (modem), NULL); - g_return_val_if_fail (driver != NULL, NULL); /* Load capabilities */ nm_modem_get_capabilities (modem, &caps, ¤t_caps); @@ -375,7 +375,7 @@ nm_device_modem_new (NMModem *modem, const char *driver) device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_MODEM, NM_DEVICE_UDI, nm_modem_get_path (modem), NM_DEVICE_IFACE, nm_modem_get_uid (modem), - NM_DEVICE_DRIVER, driver, + NM_DEVICE_DRIVER, nm_modem_get_driver (modem), NM_DEVICE_TYPE_DESC, "Broadband", NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_MODEM, NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WWAN, @@ -384,10 +384,10 @@ nm_device_modem_new (NMModem *modem, const char *driver) NM_DEVICE_MODEM_CURRENT_CAPABILITIES, current_caps, NULL); - /* In old MM modems, data port is known right away (may be changed - * afterwards during a PPP session setup) */ - if (NM_IS_MODEM_OLD (modem)) - nm_device_set_ip_iface (device, nm_modem_get_data_port (modem)); + /* If the data port is known, set it as the IP interface immediately */ + data_port = nm_modem_get_data_port (modem); + if (data_port) + nm_device_set_ip_iface (device, data_port); return device; } diff --git a/src/devices/nm-device-modem.h b/src/devices/wwan/nm-device-modem.h similarity index 96% rename from src/devices/nm-device-modem.h rename to src/devices/wwan/nm-device-modem.h index aa0c7c351b..1147b57be3 100644 --- a/src/devices/nm-device-modem.h +++ b/src/devices/wwan/nm-device-modem.h @@ -51,7 +51,7 @@ typedef struct { GType nm_device_modem_get_type (void); -NMDevice *nm_device_modem_new (NMModem *modem, const char *driver); +NMDevice *nm_device_modem_new (NMModem *modem); /* Private for subclases */ NMModem *nm_device_modem_get_modem (NMDeviceModem *self); diff --git a/src/modem-manager/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c similarity index 96% rename from src/modem-manager/nm-modem-broadband.c rename to src/devices/wwan/nm-modem-broadband.c index f368c2e0ac..3fd94586a9 100644 --- a/src/modem-manager/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -814,10 +814,12 @@ modem_state_changed (MMModem *modem, /*****************************************************************************/ NMModem * -nm_modem_broadband_new (GObject *object) +nm_modem_broadband_new (GObject *object, GError **error) { + NMModem *modem; MMObject *modem_object; MMModem *modem_iface; + gchar *drivers; g_return_val_if_fail (MM_IS_OBJECT (object), NULL); modem_object = MM_OBJECT (object); @@ -831,18 +833,25 @@ nm_modem_broadband_new (GObject *object) * This happens when a severe error happened when trying to initialize it, * like missing SIM. */ if (mm_modem_get_state (modem_iface) == MM_MODEM_STATE_FAILED) { - nm_log_warn (LOGD_MB, "(%s): unusable modem detected", - mm_modem_get_primary_port (modem_iface)); + g_set_error (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, + "(%s): unusable modem detected", + mm_modem_get_primary_port (modem_iface)); return NULL; } - return (NMModem *) g_object_new (NM_TYPE_MODEM_BROADBAND, - NM_MODEM_PATH, mm_object_get_path (modem_object), - NM_MODEM_UID, mm_modem_get_primary_port (modem_iface), - NM_MODEM_CONTROL_PORT, mm_modem_get_primary_port (modem_iface), - NM_MODEM_DATA_PORT, NULL, /* We don't know it until bearer created */ - NM_MODEM_BROADBAND_MODEM, modem_object, - NULL); + /* Build a single string with all drivers listed */ + drivers = g_strjoinv (", ", (gchar **)mm_modem_get_drivers (modem_iface)); + + modem = g_object_new (NM_TYPE_MODEM_BROADBAND, + NM_MODEM_PATH, mm_object_get_path (modem_object), + NM_MODEM_UID, mm_modem_get_primary_port (modem_iface), + NM_MODEM_CONTROL_PORT, mm_modem_get_primary_port (modem_iface), + NM_MODEM_DATA_PORT, NULL, /* We don't know it until bearer created */ + NM_MODEM_BROADBAND_MODEM, modem_object, + NM_MODEM_DRIVER, drivers, + NULL); + g_free (drivers); + return modem; } static void diff --git a/src/modem-manager/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h similarity index 97% rename from src/modem-manager/nm-modem-broadband.h rename to src/devices/wwan/nm-modem-broadband.h index 635c619a4f..e12ca68caf 100644 --- a/src/modem-manager/nm-modem-broadband.h +++ b/src/devices/wwan/nm-modem-broadband.h @@ -51,7 +51,7 @@ struct _NMModemBroadbandClass { GType nm_modem_broadband_get_type (void); -NMModem *nm_modem_broadband_new (GObject *object); +NMModem *nm_modem_broadband_new (GObject *object, GError **error); G_END_DECLS diff --git a/src/modem-manager/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c similarity index 95% rename from src/modem-manager/nm-modem-manager.c rename to src/devices/wwan/nm-modem-manager.c index f68a569666..c48117004e 100644 --- a/src/modem-manager/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2014 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. * Copyright (C) 2009 Canonical Ltd. */ @@ -63,24 +63,26 @@ struct _NMModemManagerPrivate { enum { MODEM_ADDED, - LAST_SIGNAL + LAST_SIGNAL, }; - static guint signals[LAST_SIGNAL] = { 0 }; +/************************************************************************/ -NMModemManager * -nm_modem_manager_get (void) +static void +handle_new_modem (NMModemManager *self, NMModem *modem) { - static NMModemManager *singleton = NULL; + const char *path; - if (!singleton) - singleton = NM_MODEM_MANAGER (g_object_new (NM_TYPE_MODEM_MANAGER, NULL)); - else - g_object_ref (singleton); + path = nm_modem_get_path (modem); + if (g_hash_table_lookup (self->priv->modems, path)) { + g_warn_if_reached (); + return; + } - g_assert (singleton); - return singleton; + /* Track the new modem */ + g_hash_table_insert (self->priv->modems, g_strdup (path), modem); + g_signal_emit (self, signals[MODEM_ADDED], 0, modem); } /************************************************************************/ @@ -125,10 +127,9 @@ create_modem (NMModemManager *self, const char *path) G_TYPE_INVALID)) { /* Success, create the modem */ modem = nm_modem_old_new (path, properties, &error); - if (modem) { - g_hash_table_insert (self->priv->modems, g_strdup (path), modem); - g_signal_emit (self, signals[MODEM_ADDED], 0, modem, nm_modem_get_driver (modem)); - } else { + if (modem) + handle_new_modem (self, modem); + else { nm_log_warn (LOGD_MB, "failed to create modem: %s", error ? error->message : "(unknown)"); } @@ -372,9 +373,9 @@ modem_object_added (MMManager *modem_manager, NMModemManager *self) { const gchar *path; - gchar *drivers; MMModem *modem_iface; NMModem *modem; + GError *error = NULL; /* Ensure we don't have the same modem already */ path = mm_object_get_path (modem_object); @@ -397,17 +398,14 @@ modem_object_added (MMManager *modem_manager, } /* Create a new modem object */ - modem = nm_modem_broadband_new (G_OBJECT (modem_object)); - if (!modem) - return; - - /* Build a single string with all drivers listed */ - drivers = g_strjoinv (", ", (gchar **)mm_modem_get_drivers (modem_iface)); - - /* Keep track of the new modem and notify about it */ - g_hash_table_insert (self->priv->modems, g_strdup (path), modem); - g_signal_emit (self, signals[MODEM_ADDED], 0, modem, drivers); - g_free (drivers); + modem = nm_modem_broadband_new (G_OBJECT (modem_object), &error); + if (modem) + handle_new_modem (self, modem); + else { + nm_log_warn (LOGD_MB, "failed to create modem: %s", + error ? error->message : "(unknown)"); + } + g_clear_error (&error); } static void @@ -749,12 +747,11 @@ nm_modem_manager_class_init (NMModemManagerClass *klass) object_class->dispose = dispose; - /* signals */ signals[MODEM_ADDED] = - g_signal_new ("modem-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemManagerClass, modem_added), - NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_STRING); + g_signal_new (NM_MODEM_MANAGER_MODEM_ADDED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemManagerClass, modem_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, NM_TYPE_MODEM); } diff --git a/src/modem-manager/nm-modem-manager.h b/src/devices/wwan/nm-modem-manager.h similarity index 54% rename from src/modem-manager/nm-modem-manager.h rename to src/devices/wwan/nm-modem-manager.h index 0c2b243b91..3082bdb39f 100644 --- a/src/modem-manager/nm-modem-manager.h +++ b/src/devices/wwan/nm-modem-manager.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2009 - 2014 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. * Copyright (C) 2009 Canonical Ltd. */ @@ -26,33 +26,24 @@ #include #include "nm-modem.h" -#define NM_TYPE_MODEM_MANAGER (nm_modem_manager_get_type ()) -#define NM_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_MANAGER, NMModemManager)) -#define NM_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) -#define NM_IS_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_MANAGER)) -#define NM_IS_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_MANAGER)) -#define NM_MODEM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) +#define NM_TYPE_MODEM_MANAGER (nm_modem_manager_get_type ()) +#define NM_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_MANAGER, NMModemManager)) + +#define NM_MODEM_MANAGER_MODEM_ADDED "modem-added" -typedef struct _NMModemManager NMModemManager; -typedef struct _NMModemManagerClass NMModemManagerClass; typedef struct _NMModemManagerPrivate NMModemManagerPrivate; -struct _NMModemManager { +typedef struct { GObject parent; NMModemManagerPrivate *priv; -}; +} NMModemManager; -struct _NMModemManagerClass { +typedef struct { GObjectClass parent; - /* Signals */ - void (*modem_added) (NMModemManager *manager, NMModem *modem, const char *driver); - - void (*modem_removed) (NMModemManager *manager, NMModem *modem); -}; + void (*modem_added) (NMModemManager *self, NMModem *modem); +} NMModemManagerClass; GType nm_modem_manager_get_type (void); -NMModemManager *nm_modem_manager_get (void); - #endif /* NM_MODEM_MANAGER_H */ diff --git a/src/modem-manager/nm-modem-old-types.h b/src/devices/wwan/nm-modem-old-types.h similarity index 100% rename from src/modem-manager/nm-modem-old-types.h rename to src/devices/wwan/nm-modem-old-types.h diff --git a/src/modem-manager/nm-modem-old.c b/src/devices/wwan/nm-modem-old.c similarity index 100% rename from src/modem-manager/nm-modem-old.c rename to src/devices/wwan/nm-modem-old.c diff --git a/src/modem-manager/nm-modem-old.h b/src/devices/wwan/nm-modem-old.h similarity index 100% rename from src/modem-manager/nm-modem-old.h rename to src/devices/wwan/nm-modem-old.h diff --git a/src/modem-manager/nm-modem.c b/src/devices/wwan/nm-modem.c similarity index 99% rename from src/modem-manager/nm-modem.c rename to src/devices/wwan/nm-modem.c index 8327c1c5d9..2ff0200894 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -29,7 +29,7 @@ #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-dbus-glib-types.h" -#include "nm-enum-types.h" +#include "nm-modem-enum-types.h" G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT) diff --git a/src/modem-manager/nm-modem.h b/src/devices/wwan/nm-modem.h similarity index 100% rename from src/modem-manager/nm-modem.h rename to src/devices/wwan/nm-modem.h diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c new file mode 100644 index 0000000000..3a02fb1913 --- /dev/null +++ b/src/devices/wwan/nm-wwan-factory.c @@ -0,0 +1,160 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include +#include "config.h" +#include "nm-device-factory.h" +#include "nm-wwan-factory.h" +#include "nm-modem-manager.h" +#include "nm-device-modem.h" +#include "nm-logging.h" + +static GType nm_wwan_factory_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMWwanFactory, nm_wwan_factory, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) + +#define NM_WWAN_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WWAN_FACTORY, NMWwanFactoryPrivate)) + +typedef struct { + NMModemManager *mm; +} NMWwanFactoryPrivate; + +enum { + PROP_0, + PROP_DEVICE_TYPE, + + LAST_PROP +}; + +/************************************************************************/ + +#define PLUGIN_TYPE NM_DEVICE_TYPE_MODEM + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_WWAN_FACTORY, NULL); +} + +G_MODULE_EXPORT NMDeviceType +nm_device_factory_get_device_type (void) +{ + return PLUGIN_TYPE; +} + +/************************************************************************/ + +static void +modem_added_cb (NMModemManager *manager, + NMModem *modem, + gpointer user_data) +{ + NMWwanFactory *self = NM_WWAN_FACTORY (user_data); + NMDevice *device; + const char *driver, *port; + + /* Do nothing if the modem was consumed by some other plugin */ + if (nm_device_factory_emit_component_added (NM_DEVICE_FACTORY (self), G_OBJECT (modem))) + return; + + driver = nm_modem_get_driver (modem); + + /* If it was a Bluetooth modem and no bluetooth device claimed it, ignore + * it. The rfcomm port (and thus the modem) gets created automatically + * by the Bluetooth code during the connection process. + */ + if (driver && strstr (driver, "bluetooth")) { + port = nm_modem_get_data_port (modem); + if (!port) + port = nm_modem_get_control_port (modem); + nm_log_info (LOGD_MB, "ignoring modem '%s' (no associated Bluetooth device)", port); + return; + } + + /* Make the new modem device */ + device = nm_device_modem_new (modem); + g_assert (device); + g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); + g_object_unref (device); +} + +static void +nm_wwan_factory_init (NMWwanFactory *self) +{ + NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE (self); + + priv->mm = g_object_new (NM_TYPE_MODEM_MANAGER, NULL); + g_assert (priv->mm); + g_signal_connect (priv->mm, + NM_MODEM_MANAGER_MODEM_ADDED, + G_CALLBACK (modem_added_cb), + self); +} + +static void +device_factory_interface_init (NMDeviceFactory *factory_iface) +{ +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_DEVICE_TYPE: + g_value_set_uint (value, PLUGIN_TYPE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMWwanFactory *self = NM_WWAN_FACTORY (object); + NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE (self); + + if (priv->mm) + g_signal_handlers_disconnect_by_func (priv->mm, modem_added_cb, self); + g_clear_object (&priv->mm); + + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_wwan_factory_parent_class)->dispose (object); +} + +static void +nm_wwan_factory_class_init (NMWwanFactoryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMWwanFactoryPrivate)); + + object_class->dispose = dispose; + object_class->get_property = get_property; + + g_object_class_override_property (object_class, + PROP_DEVICE_TYPE, + NM_DEVICE_FACTORY_DEVICE_TYPE); +} diff --git a/src/devices/wwan/nm-wwan-factory.h b/src/devices/wwan/nm-wwan-factory.h new file mode 100644 index 0000000000..b7aee01f15 --- /dev/null +++ b/src/devices/wwan/nm-wwan-factory.h @@ -0,0 +1,37 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef NM_WWAN_FACTORY_H +#define NM_WWAN_FACTORY_H + +#include + +#define NM_TYPE_WWAN_FACTORY (nm_wwan_factory_get_type ()) +#define NM_WWAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactory)) + +typedef struct { + GObject parent; +} NMWwanFactory; + +typedef struct { + GObjectClass parent; +} NMWwanFactoryClass; + +#endif /* NM_WWAN_FACTORY_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 2d6c0f1121..7e8ae75fa3 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -39,12 +39,10 @@ #include "nm-logging.h" #include "nm-dbus-manager.h" #include "nm-vpn-manager.h" -#include "nm-modem-manager.h" #include "nm-device.h" #include "nm-device-ethernet.h" #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" -#include "nm-device-modem.h" #include "nm-device-infiniband.h" #include "nm-device-bond.h" #include "nm-device-team.h" @@ -213,9 +211,6 @@ typedef struct { NMVPNManager *vpn_manager; - NMModemManager *modem_manager; - guint modem_added_id; - DBusGProxy *aipd_proxy; NMSleepMonitor *sleep_monitor; @@ -519,45 +514,6 @@ manager_sleeping (NMManager *self) return FALSE; } -static void -modem_added (NMModemManager *modem_manager, - NMModem *modem, - const char *driver, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMDevice *device = NULL; - const char *modem_iface; - GSList *iter; - - /* Give Bluetooth DUN devices first chance to claim the modem */ - for (iter = priv->devices; iter; iter = iter->next) { - if (nm_device_notify_component_added (device, G_OBJECT (modem))) - return; - } - - /* If it was a Bluetooth modem and no bluetooth device claimed it, ignore - * it. The rfcomm port (and thus the modem) gets created automatically - * by the Bluetooth code during the connection process. - */ - if (driver && !strcmp (driver, "bluetooth")) { - modem_iface = nm_modem_get_data_port (modem); - if (!modem_iface) - modem_iface = nm_modem_get_control_port (modem); - - nm_log_info (LOGD_MB, "ignoring modem '%s' (no associated Bluetooth device)", modem_iface); - return; - } - - /* Make the new modem device */ - device = nm_device_modem_new (modem, driver); - if (device) { - add_device (self, device, FALSE); - g_object_unref (device); - } -} - static void set_state (NMManager *manager, NMState state) { @@ -1838,7 +1794,7 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) G_CALLBACK (manager_ipw_rfkill_state_changed), self); } else if (devtype == NM_DEVICE_TYPE_MODEM) { - g_signal_connect (device, NM_DEVICE_MODEM_ENABLE_CHANGED, + g_signal_connect (device, "enable-changed", G_CALLBACK (manager_modem_enabled_changed), self); } @@ -4716,10 +4672,6 @@ nm_manager_init (NMManager *manager) G_CALLBACK (dbus_connection_changed_cb), manager); - priv->modem_manager = nm_modem_manager_get (); - priv->modem_added_id = g_signal_connect (priv->modem_manager, "modem-added", - G_CALLBACK (modem_added), manager); - priv->vpn_manager = nm_vpn_manager_get (); g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); @@ -4937,12 +4889,6 @@ dispose (GObject *object) g_clear_object (&priv->settings); g_clear_object (&priv->vpn_manager); - if (priv->modem_added_id) { - g_source_remove (priv->modem_added_id); - priv->modem_added_id = 0; - } - g_clear_object (&priv->modem_manager); - /* Unregister property filter */ if (priv->dbus_mgr) { bus = nm_dbus_manager_get_connection (priv->dbus_mgr); From 493bbbeb4a98a43c7f13cd89db4b14142fbecb7d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 24 Feb 2014 18:10:18 -0600 Subject: [PATCH 9/9] core: consolidate auto-activation recheck signals Add a generic signal that devices can use to indicate that something material in the network situation changed, and that auto-activation may now be possible. This reduces specific knowledge of device types in the policy. --- src/devices/nm-device-private.h | 2 ++ src/devices/nm-device-wifi.c | 28 +++++++++++++++--------- src/devices/nm-device.c | 14 ++++++++++++ src/devices/nm-device.h | 9 ++++---- src/devices/wimax/nm-device-wimax.c | 22 +++++++++++++------ src/devices/wwan/nm-device-modem.c | 1 + src/nm-policy.c | 33 +++-------------------------- 7 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index e4e5a4dbca..e5c9942b36 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -95,4 +95,6 @@ void nm_device_master_check_slave_physical_port (NMDevice *dev, NMDevice *slave, void nm_device_set_carrier (NMDevice *device, gboolean carrier); +void nm_device_emit_recheck_auto_activate (NMDevice *device); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/devices/nm-device-wifi.c b/src/devices/nm-device-wifi.c index f9c77d1409..df90671ed9 100644 --- a/src/devices/nm-device-wifi.c +++ b/src/devices/nm-device-wifi.c @@ -803,19 +803,32 @@ bring_up (NMDevice *device, gboolean *no_firmware) return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->bring_up (device, no_firmware); } +static void +emit_ap_added_removed (NMDeviceWifi *self, + guint signum, + NMAccessPoint *ap, + gboolean recheck_available_connections) +{ + g_signal_emit (self, signals[signum], 0, ap); + g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACCESS_POINTS); + nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); + if (recheck_available_connections) + nm_device_recheck_available_connections (NM_DEVICE (self)); +} + static void remove_access_point (NMDeviceWifi *device, NMAccessPoint *ap) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); g_return_if_fail (ap); g_return_if_fail (ap != priv->current_ap); g_return_if_fail (g_slist_find (priv->ap_list, ap)); priv->ap_list = g_slist_remove (priv->ap_list, ap); - g_signal_emit (device, signals[ACCESS_POINT_REMOVED], 0, ap); - g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_ACCESS_POINTS); + emit_ap_added_removed (self, ACCESS_POINT_REMOVED, ap, FALSE); g_object_unref (ap); } @@ -1788,7 +1801,6 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, } } - /**************************************************************************** * WPA Supplicant control stuff * @@ -1887,9 +1899,7 @@ merge_scanned_ap (NMDeviceWifi *self, g_object_ref (merge_ap); priv->ap_list = g_slist_prepend (priv->ap_list, merge_ap); nm_ap_export_to_dbus (merge_ap); - g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, merge_ap); - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACCESS_POINTS); - nm_device_recheck_available_connections (NM_DEVICE (self)); + emit_ap_added_removed (self, ACCESS_POINT_ADDED, merge_ap, TRUE); } } @@ -2900,10 +2910,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) nm_ap_export_to_dbus (ap); g_object_freeze_notify (G_OBJECT (self)); set_current_ap (self, ap, FALSE, FALSE); - g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, ap); - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACCESS_POINTS); + emit_ap_added_removed (self, ACCESS_POINT_ADDED, ap, TRUE); g_object_thaw_notify (G_OBJECT (self)); - nm_device_recheck_available_connections (NM_DEVICE (self)); nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (ap)); return NM_ACT_STAGE_RETURN_SUCCESS; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index d4f16a62e7..3c069e04f8 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -113,6 +113,7 @@ enum { IP4_CONFIG_CHANGED, IP6_CONFIG_CHANGED, REMOVED, + RECHECK_AUTO_ACTIVATE, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -1964,6 +1965,12 @@ nm_device_can_assume_connections (NMDevice *device) return !!NM_DEVICE_GET_CLASS (device)->update_connection; } +void +nm_device_emit_recheck_auto_activate (NMDevice *self) +{ + g_signal_emit (self, signals[RECHECK_AUTO_ACTIVATE], 0); +} + static void dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data) { @@ -6167,6 +6174,13 @@ nm_device_class_init (NMDeviceClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[RECHECK_AUTO_ACTIVATE] = + g_signal_new (NM_DEVICE_RECHECK_AUTO_ACTIVATE, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_object_info); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 03e3b87ed0..48f7a3a00f 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -71,10 +71,11 @@ #define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */ /* Internal signals */ -#define NM_DEVICE_AUTH_REQUEST "auth-request" -#define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed" -#define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed" -#define NM_DEVICE_REMOVED "removed" +#define NM_DEVICE_AUTH_REQUEST "auth-request" +#define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed" +#define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed" +#define NM_DEVICE_REMOVED "removed" +#define NM_DEVICE_RECHECK_AUTO_ACTIVATE "recheck-auto-activate" G_BEGIN_DECLS diff --git a/src/devices/wimax/nm-device-wimax.c b/src/devices/wimax/nm-device-wimax.c index 995d3cf01b..bdf7d9d6e8 100644 --- a/src/devices/wimax/nm-device-wimax.c +++ b/src/devices/wimax/nm-device-wimax.c @@ -221,6 +221,19 @@ activation_timed_out (gpointer data) return FALSE; } +static void +emit_nsp_added_removed (NMDeviceWimax *self, + guint signum, + NMWimaxNsp *nsp, + gboolean recheck_available_connections) +{ + g_signal_emit (self, signals[signum], 0, nsp); + g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_NSPS); + nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); + if (recheck_available_connections) + nm_device_recheck_available_connections (NM_DEVICE (self)); +} + static void remove_all_nsps (NMDeviceWimax *self) { @@ -232,8 +245,7 @@ remove_all_nsps (NMDeviceWimax *self) NMWimaxNsp *nsp = NM_WIMAX_NSP (priv->nsp_list->data); priv->nsp_list = g_slist_remove (priv->nsp_list, nsp); - g_signal_emit (self, signals[NSP_REMOVED], 0, nsp); - g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_NSPS); + emit_nsp_added_removed (self, NSP_REMOVED, nsp, FALSE); g_object_unref (nsp); } @@ -971,7 +983,7 @@ remove_outdated_nsps (NMDeviceWimax *self, for (iter = to_remove; iter; iter = iter->next) { NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data); - g_signal_emit (self, signals[NSP_REMOVED], 0, nsp); + emit_nsp_added_removed (self, NSP_REMOVED, nsp, FALSE); priv->nsp_list = g_slist_remove (priv->nsp_list, nsp); g_object_unref (nsp); } @@ -1025,9 +1037,7 @@ wmx_scan_result_cb (struct wmxsdk *wmxsdk, if (new_nsp) { priv->nsp_list = g_slist_append (priv->nsp_list, nsp); nm_wimax_nsp_export_to_dbus (nsp); - g_signal_emit (self, signals[NSP_ADDED], 0, nsp); - g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_NSPS); - nm_device_recheck_available_connections (NM_DEVICE (self)); + emit_nsp_added_removed (self, NSP_ADDED, nsp, TRUE); } } } diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 723f86e4dd..d731c809a9 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -181,6 +181,7 @@ modem_enabled_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) set_enabled (NM_DEVICE (self), nm_modem_get_mm_enabled (priv->modem)); g_signal_emit (G_OBJECT (self), signals[ENABLE_CHANGED], 0); + nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); } static void diff --git a/src/nm-policy.c b/src/nm-policy.c index 0eac715251..9fef8ff75b 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1602,21 +1602,9 @@ device_autoconnect_changed (NMDevice *device, } static void -wireless_networks_changed (NMDevice *device, GObject *ap, gpointer user_data) +device_recheck_auto_activate (NMDevice *device, gpointer user_data) { - schedule_activate_check ((NMPolicy *) user_data, device); -} - -static void -nsps_changed (NMDevice *device, GObject *nsp, gpointer user_data) -{ - schedule_activate_check ((NMPolicy *) user_data, device); -} - -static void -modem_enabled_changed (NMDevice *device, gpointer user_data) -{ - schedule_activate_check ((NMPolicy *) (user_data), device); + schedule_activate_check (NM_POLICY (user_data), device); } typedef struct { @@ -1654,22 +1642,7 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) _connect_device_signal (policy, device, NM_DEVICE_IP4_CONFIG_CHANGED, device_ip4_config_changed, FALSE); _connect_device_signal (policy, device, NM_DEVICE_IP6_CONFIG_CHANGED, device_ip6_config_changed, FALSE); _connect_device_signal (policy, device, "notify::" NM_DEVICE_AUTOCONNECT, device_autoconnect_changed, FALSE); - - switch (nm_device_get_device_type (device)) { - case NM_DEVICE_TYPE_WIFI: - _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed, FALSE); - _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed, FALSE); - break; - case NM_DEVICE_TYPE_WIMAX: - _connect_device_signal (policy, device, "nsp-added", nsps_changed, FALSE); - _connect_device_signal (policy, device, "nsp-removed", nsps_changed, FALSE); - break; - case NM_DEVICE_TYPE_MODEM: - _connect_device_signal (policy, device, "enable-changed", modem_enabled_changed, FALSE); - break; - default: - break; - } + _connect_device_signal (policy, device, NM_DEVICE_RECHECK_AUTO_ACTIVATE, device_recheck_auto_activate, FALSE); } static void