diff options
author | Dan Williams <dcbw@redhat.com> | 2014-03-03 16:07:53 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-03-03 16:07:53 -0600 |
commit | c1a064b9a3db40c877b87c7bb56e0e9f2720b2cd (patch) | |
tree | b7d1c859ed3fe6378951bd9a426cf63fd07fc555 | |
parent | 550ce1e631494126f2c8010030b661435e3744fc (diff) | |
parent | 493bbbeb4a98a43c7f13cd89db4b14142fbecb7d (diff) | |
download | NetworkManager-c1a064b9a3db40c877b87c7bb56e0e9f2720b2cd.tar.gz |
merge: move ATM, Bluetooth, and WWAN into device plugins (bgo #724324)
Enhance the device plugin interface and convert ATM, BT, and WWAN to
use it. This saves 15% of the binary size of the core NM binary, and
packagers or users can decide which plugins they would like to install,
thereby saving disk space and memory.
https://bugzilla.gnome.org/show_bug.cgi?id=724324
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | po/POTFILES.in | 10 | ||||
-rw-r--r-- | src/Makefile.am | 45 | ||||
-rw-r--r-- | src/bluez-manager/nm-bluez-manager.h | 71 | ||||
-rw-r--r-- | src/devices/atm/Makefile.am | 48 | ||||
-rw-r--r-- | src/devices/atm/nm-atm-manager.c (renamed from src/nm-atm-manager.c) | 177 | ||||
-rw-r--r-- | src/devices/atm/nm-atm-manager.h (renamed from src/nm-atm-manager.h) | 23 | ||||
-rw-r--r-- | src/devices/atm/nm-device-adsl.c (renamed from src/devices/nm-device-adsl.c) | 0 | ||||
-rw-r--r-- | src/devices/atm/nm-device-adsl.h (renamed from src/devices/nm-device-adsl.h) | 0 | ||||
-rw-r--r-- | src/devices/bluetooth/Makefile.am | 59 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez-common.h (renamed from src/bluez-manager/nm-bluez-common.h) | 0 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez-device.c (renamed from src/bluez-manager/nm-bluez-device.c) | 8 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez-device.h (renamed from src/bluez-manager/nm-bluez-device.h) | 8 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez-manager.c (renamed from src/bluez-manager/nm-bluez-manager.c) | 196 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez-manager.h | 44 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez4-adapter.c (renamed from src/bluez-manager/nm-bluez4-adapter.c) | 0 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez4-adapter.h (renamed from src/bluez-manager/nm-bluez4-adapter.h) | 0 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez4-manager.c (renamed from src/bluez-manager/nm-bluez4-manager.c) | 26 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez4-manager.h (renamed from src/bluez-manager/nm-bluez4-manager.h) | 6 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez5-manager.c (renamed from src/bluez-manager/nm-bluez5-manager.c) | 21 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez5-manager.h (renamed from src/bluez-manager/nm-bluez5-manager.h) | 6 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-device-bt.c (renamed from src/devices/nm-device-bt.c) | 95 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-device-bt.h (renamed from src/devices/nm-device-bt.h) | 2 | ||||
-rw-r--r-- | src/devices/nm-device-factory.c | 114 | ||||
-rw-r--r-- | src/devices/nm-device-factory.h | 125 | ||||
-rw-r--r-- | src/devices/nm-device-olpc-mesh.c | 14 | ||||
-rw-r--r-- | src/devices/nm-device-private.h | 4 | ||||
-rw-r--r-- | src/devices/nm-device-vlan.c | 3 | ||||
-rw-r--r-- | src/devices/nm-device-wifi.c | 31 | ||||
-rw-r--r-- | src/devices/nm-device.c | 152 | ||||
-rw-r--r-- | src/devices/nm-device.h | 18 | ||||
-rw-r--r-- | src/devices/wimax/nm-device-wimax.c | 22 | ||||
-rw-r--r-- | src/devices/wimax/nm-wimax-factory.c | 88 | ||||
-rw-r--r-- | src/devices/wwan/Makefile.am | 75 | ||||
-rw-r--r-- | src/devices/wwan/README (renamed from src/modem-manager/README) | 0 | ||||
-rw-r--r-- | src/devices/wwan/nm-device-modem.c (renamed from src/devices/nm-device-modem.c) | 32 | ||||
-rw-r--r-- | src/devices/wwan/nm-device-modem.h (renamed from src/devices/nm-device-modem.h) | 2 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-broadband.c (renamed from src/modem-manager/nm-modem-broadband.c) | 29 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-broadband.h (renamed from src/modem-manager/nm-modem-broadband.h) | 2 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-manager.c (renamed from src/modem-manager/nm-modem-manager.c) | 84 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-manager.h (renamed from src/modem-manager/nm-modem-manager.h) | 29 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-old-types.h (renamed from src/modem-manager/nm-modem-old-types.h) | 0 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-old.c (renamed from src/modem-manager/nm-modem-old.c) | 0 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-old.h (renamed from src/modem-manager/nm-modem-old.h) | 0 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem.c (renamed from src/modem-manager/nm-modem.c) | 17 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem.h (renamed from src/modem-manager/nm-modem.h) | 6 | ||||
-rw-r--r-- | src/devices/wwan/nm-wwan-factory.c | 160 | ||||
-rw-r--r-- | src/devices/wwan/nm-wwan-factory.h | 37 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/nm-connection-provider.h | 7 | ||||
-rw-r--r-- | src/nm-manager.c | 451 | ||||
-rw-r--r-- | src/nm-policy.c | 33 |
52 files changed, 1371 insertions, 1014 deletions
diff --git a/configure.ac b/configure.ac index 1acfbb2069..a7f60ff616 100644 --- a/configure.ac +++ b/configure.ac @@ -762,7 +762,10 @@ src/platform/Makefile src/platform/tests/Makefile src/rdisc/Makefile 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 b1a4fcc512..d03f5aa8fa 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -40,24 +40,24 @@ 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 src/dns-manager/nm-dns-manager.c src/logging/nm-logging.c src/config/nm-config.c -src/modem-manager/nm-modem-broadband.c -src/modem-manager/nm-modem-old.c +src/devices/atm/nm-device-adsl.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-adsl.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 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 305a9a0dac..fd0bb6964c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,6 +4,9 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ + devices/atm \ + devices/wwan \ + devices/bluetooth \ dhcp-manager \ ppp-manager \ settings/plugins @@ -51,18 +54,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 \ @@ -70,16 +61,13 @@ 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 \ 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 \ devices/nm-device-factory.h \ devices/nm-device-generic.c \ devices/nm-device-generic.h \ @@ -89,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 \ @@ -136,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 \ @@ -224,8 +202,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 \ @@ -274,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 @@ -305,8 +275,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,17 +289,14 @@ 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 \ nm-device-ethernet-glue.h \ nm-device-generic-glue.h \ nm-device-glue.h \ 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 \ @@ -359,7 +326,6 @@ AM_CPPFLAGS += \ $(LIBNL_CFLAGS) \ $(LIBNDP_CFLAGS) \ $(LIBSOUP_CFLAGS) \ - $(MM_GLIB_CFLAGS) \ $(POLKIT_CFLAGS) \ $(SYSTEMD_LOGIN_CFLAGS) \ \ @@ -402,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/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 <glib.h> -#include <glib-object.h> - -#include <config.h> -#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/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 index 19701500e7..886095dad3 100644 --- a/src/nm-atm-manager.c +++ b/src/devices/atm/nm-atm-manager.c @@ -24,52 +24,61 @@ #include <gudev/gudev.h> #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); -enum { - DEVICE_ADDED, - DEVICE_REMOVED, +static void device_factory_interface_init (NMDeviceFactory *factory_iface); - LAST_SIGNAL +G_DEFINE_TYPE_EXTENDED (NMAtmManager, nm_atm_manager, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) + +enum { + PROP_0, + PROP_DEVICE_TYPE, + LAST_PROP }; -static guint signals[LAST_SIGNAL] = { 0 }; +/**************************************************************************/ + +#define PLUGIN_TYPE NM_DEVICE_TYPE_ADSL + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_ATM_MANAGER, NULL); +} -NMAtmManager * -nm_atm_manager_new (void) +G_MODULE_EXPORT NMDeviceType +nm_device_factory_get_device_type (void) { - return NM_ATM_MANAGER (g_object_new (NM_TYPE_ATM_MANAGER, NULL)); + 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; + } + + nm_log_dbg (LOGD_HW, "(%s): found ATM device", ifname); + + if (dev_get_attrs (udev_device, &sysfs_path, &driver)) { + g_assert (sysfs_path); - if (dev_get_attrs (udev_device, &ifname, &path, &driver)) - g_signal_emit (self, signals[DEVICE_ADDED], 0, ifname, path, driver); - g_free (driver); + 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; + + nm_log_dbg (LOGD_HW, "(%s): removing ATM device", iface); + + for (iter = priv->devices; iter; iter = iter->next) { + NMDevice *device = iter->data; - g_signal_emit (self, signals[DEVICE_REMOVED], 0, g_udev_device_get_name (device)); + /* 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 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 <glib.h> #include <glib-object.h> -#include <gudev/gudev.h> - 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 index 7fe626e7ca..7fe626e7ca 100644 --- a/src/devices/nm-device-adsl.c +++ b/src/devices/atm/nm-device-adsl.c diff --git a/src/devices/nm-device-adsl.h b/src/devices/atm/nm-device-adsl.h index b0a094dd95..b0a094dd95 100644 --- a/src/devices/nm-device-adsl.h +++ b/src/devices/atm/nm-device-adsl.h diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am new file mode 100644 index 0000000000..5e716af25f --- /dev/null +++ b/src/devices/bluetooth/Makefile.am @@ -0,0 +1,59 @@ +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/devices/wwan \ + -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 = \ + $(top_builddir)/src/devices/wwan/libnm-wwan.la \ + $(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 index f80cfc2e39..f80cfc2e39 100644 --- a/src/bluez-manager/nm-bluez-common.h +++ b/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 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 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 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 <signal.h> @@ -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); -enum { - PROP_0, - PROP_PROVIDER, +static void device_factory_interface_init (NMDeviceFactory *factory_iface); - LAST_PROP -}; +G_DEFINE_TYPE_EXTENDED (NMBluezManager, nm_bluez_manager, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) enum { - BDADDR_ADDED, - BDADDR_REMOVED, - - LAST_SIGNAL + PROP_0, + PROP_DEVICE_TYPE, + LAST_PROP }; -static guint signals[LAST_SIGNAL] = { 0 }; +static void check_bluez_and_try_setup (NMBluezManager *self); +/**************************************************************************/ -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,31 +139,34 @@ 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); + + 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; -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); + 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,18 +413,24 @@ 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) +{ } static void @@ -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 <glib.h> +#include <glib-object.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_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 index ad1786f02a..ad1786f02a 100644 --- a/src/bluez-manager/nm-bluez4-adapter.c +++ b/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 index 454ca557eb..454ca557eb 100644 --- a/src/bluez-manager/nm-bluez4-adapter.h +++ b/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 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 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 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 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 index 3e5b693354..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" @@ -560,22 +560,50 @@ modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason) /*****************************************************************************/ -gboolean -nm_device_bt_modem_added (NMDeviceBt *self, - NMModem *modem, - const char *driver) +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); +} + +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); @@ -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)); } } @@ -927,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 @@ -1117,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); @@ -1156,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); @@ -1166,7 +1170,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); @@ -1208,6 +1212,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-bt.h b/src/devices/bluetooth/nm-device-bt.h index d983285fb7..83732bc09e 100644 --- a/src/devices/nm-device-bt.h +++ b/src/devices/bluetooth/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-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, - GError **error); +NMDeviceFactory *nm_device_factory_create (GError **error); -/* Should match nm_device_factory() */ -typedef GObject * (*NMDeviceFactoryCreateFunc) (NMPlatformLink *platform_device, - GError **error); +/* Should match nm_device_factory_create() */ +typedef NMDeviceFactory * (*NMDeviceFactoryCreateFunc) (GError **error); /** - * nm_device_factory_get_priority: - * - * Returns the priority of this plugin. Higher numbers mean a higher priority. + * nm_device_factory_get_device_type: * - * Returns: plugin priority + * Returns: the #NMDeviceType that this plugin creates */ -guint32 nm_device_factory_get_priority (void); +NMDeviceType nm_device_factory_get_device_type (void); -typedef guint32 (*NMDeviceFactoryPriorityFunc) (void); +/* Should match nm_device_factory_get_device_type() */ +typedef NMDeviceType (*NMDeviceFactoryDeviceTypeFunc) (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); +/********************************************************************/ + +#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); -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-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/devices/nm-device-private.h b/src/devices/nm-device-private.h index 3da14795c4..e5c9942b36 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); @@ -97,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-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..df90671ed9 100644 --- a/src/devices/nm-device-wifi.c +++ b/src/devices/nm-device-wifi.c @@ -804,18 +804,31 @@ bring_up (NMDevice *device, gboolean *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); } @@ -1603,7 +1616,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 +1628,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, @@ -1789,7 +1801,6 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, } } - /**************************************************************************** * WPA Supplicant control stuff * @@ -1888,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); } } @@ -2901,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 e5db1f5f89..3c069e04f8 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -112,6 +112,8 @@ enum { AUTH_REQUEST, IP4_CONFIG_CHANGED, IP6_CONFIG_CHANGED, + REMOVED, + RECHECK_AUTO_ACTIVATE, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -315,13 +317,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 +608,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 +896,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) { @@ -1219,6 +1194,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) { @@ -1948,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) { @@ -5508,34 +5531,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->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->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_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); @@ -6157,6 +6167,20 @@ 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); + + 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 c346ccb42e..48f7a3a00f 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -71,9 +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_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 @@ -195,6 +197,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; @@ -316,8 +322,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); @@ -333,6 +337,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-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 @@ -222,6 +222,19 @@ activation_timed_out (gpointer data) } 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) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (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/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 <gmodule.h> @@ -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/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 index 4661c04287..4661c04287 100644 --- a/src/modem-manager/README +++ b/src/devices/wwan/README diff --git a/src/devices/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index e047c03e11..d731c809a9 100644 --- a/src/devices/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 @@ -196,6 +197,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 * @@ -206,6 +213,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 @@ -345,14 +361,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); @@ -360,7 +376,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, @@ -369,10 +385,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; } @@ -398,6 +414,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 @@ -485,6 +502,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-modem.h b/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 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 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 index bb85b774ea..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,26 +63,26 @@ struct _NMModemManagerPrivate { enum { MODEM_ADDED, - MODEM_REMOVED, - - 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); } /************************************************************************/ @@ -127,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)"); } @@ -159,7 +158,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 +273,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; } @@ -375,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); @@ -400,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 @@ -426,7 +421,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); } @@ -752,20 +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); - - 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); + 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 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 <glib-object.h> #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 index 976605db2b..976605db2b 100644 --- a/src/modem-manager/nm-modem-old-types.h +++ b/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 index f8bbcebb85..f8bbcebb85 100644 --- a/src/modem-manager/nm-modem-old.c +++ b/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 index 828da6a6d4..828da6a6d4 100644 --- a/src/modem-manager/nm-modem-old.h +++ b/src/devices/wwan/nm-modem-old.h diff --git a/src/modem-manager/nm-modem.c b/src/devices/wwan/nm-modem.c index e88ebe1bd7..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) @@ -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/devices/wwan/nm-modem.h index db20407006..f15be26769 100644 --- a/src/modem-manager/nm-modem.h +++ b/src/devices/wwan/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/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 <string.h> +#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 <glib-object.h> + +#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/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-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 @@ -77,6 +77,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 * @max_requested: if non-zero, the maximum number of connections to return diff --git a/src/nm-manager.c b/src/nm-manager.c index da99a02d77..7e8ae75fa3 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -39,35 +39,27 @@ #include "nm-logging.h" #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" #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" #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" #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" #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" -#include "nm-bluez-common.h" #include "nm-settings.h" #include "nm-settings-connection.h" #include "nm-manager-auth.h" @@ -137,19 +129,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); @@ -165,7 +144,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,9 +197,7 @@ typedef struct { NMDBusManager *dbus_mgr; gboolean prop_filter_added; - NMAtmManager *atm_mgr; NMRfkillManager *rfkill_mgr; - NMBluezManager *bluez_mgr; /* List of NMDeviceFactoryFunc pointers sorted in priority order */ GSList *factories; @@ -235,10 +211,6 @@ typedef struct { NMVPNManager *vpn_manager; - NMModemManager *modem_manager; - guint modem_added_id; - guint modem_removed_id; - DBusGProxy *aipd_proxy; NMSleepMonitor *sleep_monitor; @@ -543,58 +515,6 @@ manager_sleeping (NMManager *self) } 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, *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); - - /* 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; - } - } - - /* 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); -} - -static void set_state (NMManager *manager, NMState state) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); @@ -837,27 +757,9 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting) } static void -modem_removed (NMModemManager *modem_manager, - NMModem *modem, - gpointer user_data) +device_removed_cb (NMDevice *device, 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); + remove_device (NM_MANAGER (user_data), device, FALSE); } static void @@ -1201,6 +1103,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); @@ -1811,6 +1714,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) { @@ -1823,28 +1735,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; - } - nm_device_set_connection_provider (device, NM_CONNECTION_PROVIDER (priv->settings)); + /* 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, device); + priv->devices = g_slist_append (priv->devices, g_object_ref (device)); g_signal_connect (device, "state-changed", G_CALLBACK (manager_device_state_changed), @@ -1854,6 +1769,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), @@ -1875,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); } @@ -1891,6 +1810,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); @@ -1967,61 +1889,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); - } -} - -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) { @@ -2038,54 +1905,45 @@ find_device_by_ip_iface (NMManager *self, const gchar *iface) } static NMDevice * -find_device_by_iface (NMManager *self, const gchar *iface) +find_device_by_ifindex (NMManager *self, guint32 ifindex) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GSList *iter; for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMDevice *candidate = iter->data; + NMDevice *candidate = NM_DEVICE (iter->data); - if (g_strcmp0 (nm_device_get_iface (candidate), iface) == 0) + if (ifindex == nm_device_get_ifindex (candidate)) return candidate; } return NULL; } -static NMDevice * -find_device_by_ifindex (NMManager *self, guint32 ifindex) +static void +factory_device_added_cb (NMDeviceFactory *factory, + NMDevice *device, + gpointer user_data) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter; + add_device (NM_MANAGER (user_data), device, FALSE); +} - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMDevice *candidate = NM_DEVICE (iter->data); +static gboolean +factory_component_added_cb (NMDeviceFactory *factory, + GObject *component, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + GSList *iter; - if (ifindex == nm_device_get_ifindex (candidate)) - return candidate; + 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 NULL; + return FALSE; } #define PLUGIN_PREFIX "libnm-device-plugin-" -typedef struct { - NMDeviceType t; - guint priority; - NMDeviceFactoryCreateFunc create_func; -} PluginInfo; - -static gint -plugin_sort (PluginInfo *a, PluginInfo *b) -{ - /* 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; -} - static void load_device_factories (NMManager *self) { @@ -2094,7 +1952,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) { @@ -2107,11 +1965,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; @@ -2126,60 +1984,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; - - if (plugin_type == candidate->t) { - info = candidate; + dev_type = type_func (); + for (iter = priv->factories; iter; iter = iter->next) { + NMDeviceType t = NM_DEVICE_TYPE_UNKNOWN; + + 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 @@ -2201,11 +2062,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! */ @@ -2298,8 +2158,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 @@ -2318,49 +2180,6 @@ platform_link_removed_cb (NMPlatform *platform, } 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, RfKillState udev_state, @@ -4231,8 +4050,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); /* * Connections added before the manager is started do not emit @@ -4690,7 +4507,15 @@ NMManager * nm_manager_get (void) { g_assert (singleton); - return g_object_ref (singleton); + 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 * @@ -4782,40 +4607,20 @@ 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", 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. */ rfkill_change_wifi (priv->radio_states[RFKILL_TYPE_WLAN].desc, initial_wifi_enabled); + load_device_factories (singleton); + return singleton; } @@ -4867,12 +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->modem_removed_id = g_signal_connect (priv->modem_manager, "modem-removed", - G_CALLBACK (modem_removed), manager); - priv->vpn_manager = nm_vpn_manager_get (); g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); @@ -4928,8 +4727,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); } @@ -5057,6 +4854,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; @@ -5091,16 +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; - } - 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 */ if (priv->dbus_mgr) { bus = nm_dbus_manager_get_connection (priv->dbus_mgr); @@ -5115,7 +4903,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); @@ -5131,6 +4918,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) { 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 |