diff --git a/.gitignore b/.gitignore index 3678dc36e1..b3245af97b 100644 --- a/.gitignore +++ b/.gitignore @@ -186,6 +186,7 @@ valgrind-*.log /src/tests/test-ip6-config /src/tests/test-wifi-ap-utils /src/tests/test-resolvconf-capture +/src/devices/wifi/tests/test-wifi-ap-utils /src/dnsmasq-manager/tests/test-dnsmasq-utils /src/dhcp-manager/tests/test-dhcp-dhclient /src/dhcp-manager/tests/test-dnsmasq-utils diff --git a/configure.ac b/configure.ac index 74db8c1129..cfccfc2e00 100644 --- a/configure.ac +++ b/configure.ac @@ -800,6 +800,8 @@ src/rdisc/tests/Makefile src/devices/adsl/Makefile src/devices/wimax/Makefile src/devices/bluetooth/Makefile +src/devices/wifi/Makefile +src/devices/wifi/tests/Makefile src/devices/wwan/Makefile libnm-util/libnm-util.pc libnm-util/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index 36bc69ffa0..6368a9f59f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -53,9 +53,9 @@ src/devices/nm-device-bond.c src/devices/nm-device-bridge.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/wifi/nm-device-olpc-mesh.c src/devices/wwan/nm-modem-broadband.c src/devices/wwan/nm-modem-old.c src/nm-manager.c diff --git a/src/Makefile.am b/src/Makefile.am index d467e803ca..53fc35c1fb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,7 @@ SUBDIRS = \ devices/adsl \ devices/wwan \ devices/bluetooth \ + devices/wifi \ dhcp-manager \ ppp-manager \ settings/plugins @@ -78,8 +79,6 @@ nm_sources = \ devices/nm-device-infiniband.h \ devices/nm-device-macvlan.c \ devices/nm-device-macvlan.h \ - devices/nm-device-olpc-mesh.c \ - devices/nm-device-olpc-mesh.h \ devices/nm-device-private.h \ devices/nm-device-team.c \ devices/nm-device-team.h \ @@ -91,8 +90,6 @@ nm_sources = \ devices/nm-device-vlan.h \ devices/nm-device-vxlan.c \ devices/nm-device-vxlan.h \ - devices/nm-device-wifi.c \ - devices/nm-device-wifi.h \ \ dhcp-manager/nm-dhcp-client.c \ dhcp-manager/nm-dhcp-client.h \ @@ -241,10 +238,6 @@ nm_sources = \ nm-session-utils.h \ nm-sleep-monitor.h \ nm-types.h \ - nm-wifi-ap-utils.c \ - nm-wifi-ap-utils.h \ - nm-wifi-ap.c \ - nm-wifi-ap.h \ NetworkManagerUtils.c \ NetworkManagerUtils.h @@ -297,13 +290,11 @@ glue_sources = \ nm-device-gre-glue.h \ nm-device-infiniband-glue.h \ nm-device-macvlan-glue.h \ - nm-device-olpc-mesh-glue.h \ nm-device-team-glue.h \ nm-device-tun-glue.h \ nm-device-veth-glue.h \ nm-device-vlan-glue.h \ nm-device-vxlan-glue.h \ - nm-device-wifi-glue.h \ nm-dhcp4-config-glue.h \ nm-dhcp6-config-glue.h \ nm-ip4-config-glue.h \ diff --git a/src/devices/wifi/Makefile.am b/src/devices/wifi/Makefile.am new file mode 100644 index 0000000000..5f3ce286b7 --- /dev/null +++ b/src/devices/wifi/Makefile.am @@ -0,0 +1,78 @@ +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +SUBDIRS=. tests + +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/supplicant-manager \ + -I${top_builddir}/include \ + -I${top_srcdir}/include \ + -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-util \ + -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(GUDEV_CFLAGS) + +GLIB_GENERATED = nm-wifi-enum-types.h nm-wifi-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_wifi_enum_types_sources = \ + $(srcdir)/nm-device-wifi.h \ + $(srcdir)/nm-wifi-ap.h \ + $(srcdir)/nm-device-olpc-mesh.h + +glue_sources = \ + nm-device-wifi-glue.h \ + nm-device-olpc-mesh-glue.h + +%-glue.h: $(top_srcdir)/introspection/%.xml + $(AM_V_GEN) dbus-binding-tool --prefix=$(subst -,_,$(subst -glue.h,,$@)) --mode=glib-server --output=$@ $< + +BUILT_SOURCES = $(GLIB_GENERATED) $(glue_sources) + +pkglib_LTLIBRARIES = libnm-device-plugin-wifi.la + +libnm_device_plugin_wifi_la_SOURCES = \ + nm-wifi-factory.c \ + nm-device-wifi.c \ + nm-device-wifi.h \ + nm-wifi-ap.c \ + nm-wifi-ap.h \ + nm-wifi-ap-utils.c \ + nm-wifi-ap-utils.h \ + nm-device-olpc-mesh.c \ + nm-device-olpc-mesh.h \ + \ + $(BUILT_SOURCES) + +SYMBOL_VIS_FILE=$(srcdir)/exports.ver + +libnm_device_plugin_wifi_la_LDFLAGS = \ + -module -avoid-version \ + -Wl,--version-script=$(SYMBOL_VIS_FILE) + +libnm_device_plugin_wifi_la_LIBADD = \ + $(DBUS_LIBS) \ + $(GUDEV_LIBS) + +CLEANFILES = $(BUILT_SOURCES) + +EXTRA_DIST = $(SYMBOL_VIS_FILE) + +if ENABLE_TESTS + +check-local: + $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-wifi.so $(SYMBOL_VIS_FILE) + +endif + diff --git a/src/devices/wifi/exports.ver b/src/devices/wifi/exports.ver new file mode 100644 index 0000000000..d2c451244b --- /dev/null +++ b/src/devices/wifi/exports.ver @@ -0,0 +1,7 @@ +{ +global: + nm_device_factory_create; + nm_device_factory_get_device_type; +local: + *; +}; diff --git a/src/devices/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c similarity index 77% rename from src/devices/nm-device-olpc-mesh.c rename to src/devices/wifi/nm-device-olpc-mesh.c index 19c86975c2..9c25fd026a 100644 --- a/src/devices/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -19,7 +19,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2011 Red Hat, Inc. + * (C) Copyright 2005 - 2014 Red Hat, Inc. * (C) Copyright 2008 Collabora Ltd. * (C) Copyright 2009 One Laptop per Child */ @@ -53,6 +53,7 @@ #include "nm-manager.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" +#include "nm-wifi-enum-types.h" /* This is a bug; but we can't really change API now... */ #include "NetworkManagerVPN.h" @@ -64,7 +65,6 @@ G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) #define NM_DEVICE_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshPrivate)) - enum { PROP_0, PROP_COMPANION, @@ -73,24 +73,12 @@ enum { LAST_PROP }; -#define NM_OLPC_MESH_ERROR (nm_olpc_mesh_error_quark ()) - - struct _NMDeviceOlpcMeshPrivate { - gboolean dispose_has_run; - - NMDevice * companion; - gboolean stage1_waiting; - guint device_added_id; - guint device_removed_id; - guint cmp_state_changed_id; - guint cmp_scanning_id; - guint cmp_scanning_allowed_id; - guint cmp_autoconnect_allowed_id; + NMDevice *companion; + gboolean stage1_waiting; }; -static void state_changed (NMDevice *device, NMDeviceState new_state, - NMDeviceState old_state, NMDeviceStateReason reason); +/*******************************************************************/ static GQuark nm_olpc_mesh_error_quark (void) @@ -101,48 +89,9 @@ nm_olpc_mesh_error_quark (void) return quark; } -static void -nm_device_olpc_mesh_init (NMDeviceOlpcMesh * self) -{ - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); +#define NM_OLPC_MESH_ERROR (nm_olpc_mesh_error_quark ()) - priv->dispose_has_run = FALSE; - priv->companion = NULL; - priv->stage1_waiting = FALSE; -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - GObjectClass *klass; - NMDeviceOlpcMesh *self; - NMDeviceWifiCapabilities caps; - - klass = G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class); - object = klass->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; - - self = NM_DEVICE_OLPC_MESH (object); - - nm_log_dbg (LOGD_HW | LOGD_OLPC, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); - - if (!nm_platform_wifi_get_capabilities (nm_device_get_ifindex (NM_DEVICE (self)), &caps)) { - nm_log_warn (LOGD_HW | LOGD_OLPC, "(%s): failed to initialize WiFi driver", - nm_device_get_iface (NM_DEVICE (self))); - g_object_unref (object); - return NULL; - } - - /* shorter timeout for mesh connectivity */ - nm_device_set_dhcp_timeout (NM_DEVICE (self), 20); - return object; -} +/*******************************************************************/ static gboolean check_connection_compatible (NMDevice *device, @@ -308,141 +257,34 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_SUCCESS; } +static gboolean +is_available (NMDevice *dev) +{ + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (dev); + + if (!NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->companion) { + nm_log_dbg (LOGD_WIFI, "(%s): not available because companion not found", + nm_device_get_iface (dev)); + return FALSE; + } + + return TRUE; +} + +/*******************************************************************/ + static void companion_cleanup (NMDeviceOlpcMesh *self) { NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - if (priv->companion == NULL) - return; - - if (priv->cmp_state_changed_id) { - g_signal_handler_disconnect (priv->companion, priv->cmp_state_changed_id); - priv->cmp_state_changed_id = 0; + if (priv->companion) { + g_signal_handlers_disconnect_by_data (priv->companion, self); + g_clear_object (&priv->companion); } - - if (priv->cmp_scanning_id) { - g_signal_handler_disconnect (priv->companion, priv->cmp_scanning_id); - priv->cmp_scanning_id = 0; - } - - if (priv->cmp_scanning_allowed_id) { - g_signal_handler_disconnect (priv->companion, priv->cmp_scanning_allowed_id); - priv->cmp_scanning_allowed_id = 0; - } - - if (priv->cmp_autoconnect_allowed_id) { - g_signal_handler_disconnect (priv->companion, priv->cmp_autoconnect_allowed_id); - priv->cmp_autoconnect_allowed_id = 0; - } - - priv->companion = NULL; g_object_notify (G_OBJECT (self), NM_DEVICE_OLPC_MESH_COMPANION); } -static void -dispose (GObject *object) -{ - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - - if (priv->dispose_has_run) { - G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); - return; - } - priv->dispose_has_run = TRUE; - - companion_cleanup (self); - - if (priv->device_added_id) - g_signal_handler_disconnect (nm_manager_get (), priv->device_added_id); - if (priv->device_removed_id) - g_signal_handler_disconnect (nm_manager_get (), priv->device_removed_id); - - G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMDeviceOlpcMesh *device = NM_DEVICE_OLPC_MESH (object); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (device); - - switch (prop_id) { - case PROP_COMPANION: - if (priv->companion) - g_value_set_boxed (value, nm_device_get_path (priv->companion)); - else - g_value_set_boxed (value, "/"); - break; - case PROP_ACTIVE_CHANNEL: - g_value_set_uint (value, nm_platform_mesh_get_channel (nm_device_get_ifindex (NM_DEVICE (device)))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMDeviceOlpcMeshPrivate)); - - object_class->constructor = constructor; - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; - - parent_class->check_connection_compatible = check_connection_compatible; - parent_class->can_auto_connect = can_auto_connect; - parent_class->complete_connection = complete_connection; - - parent_class->act_stage1_prepare = act_stage1_prepare; - parent_class->act_stage2_config = act_stage2_config; - - parent_class->state_changed = state_changed; - - /* Properties */ - g_object_class_install_property - (object_class, PROP_COMPANION, - g_param_spec_boxed (NM_DEVICE_OLPC_MESH_COMPANION, - "Companion device", - "Companion device object path", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property - (object_class, PROP_ACTIVE_CHANNEL, - g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, - "Active channel", - "Active channel", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); - - nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), - G_TYPE_FROM_CLASS (klass), - &dbus_glib_nm_device_olpc_mesh_object_info); - - dbus_g_error_domain_register (NM_OLPC_MESH_ERROR, NULL, - NM_TYPE_OLPC_MESH_ERROR); -} - static void companion_notify_cb (NMDeviceWifi *companion, GParamSpec *pspec, gpointer user_data) { @@ -508,7 +350,7 @@ companion_autoconnect_allowed_cb (NMDeviceWifi *companion, gpointer user_data) } static gboolean -is_companion (NMDeviceOlpcMesh *self, NMDevice *other) +check_companion (NMDeviceOlpcMesh *self, NMDevice *other) { NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); const guint8 *my_addr, *their_addr; @@ -523,33 +365,24 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other) || (memcmp (my_addr, their_addr, ETH_ALEN) != 0)) return FALSE; - priv->companion = other; - - /* When we've found the companion, stop listening for other devices */ - if (priv->device_added_id) { - g_signal_handler_disconnect (nm_manager_get (), priv->device_added_id); - priv->device_added_id = 0; - } - - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_NONE); + g_assert (priv->companion == NULL); + priv->companion = g_object_ref (other); nm_log_info (LOGD_OLPC, "(%s): found companion WiFi device %s", nm_device_get_iface (NM_DEVICE (self)), nm_device_get_iface (other)); - priv->cmp_state_changed_id = g_signal_connect (G_OBJECT (other), "state-changed", - G_CALLBACK (companion_state_changed_cb), self); + g_signal_connect (G_OBJECT (other), "state-changed", + G_CALLBACK (companion_state_changed_cb), self); - priv->cmp_scanning_id = g_signal_connect (G_OBJECT (other), "notify::scanning", - G_CALLBACK (companion_notify_cb), self); + g_signal_connect (G_OBJECT (other), "notify::scanning", + G_CALLBACK (companion_notify_cb), self); - priv->cmp_scanning_allowed_id = g_signal_connect (G_OBJECT (other), "scanning-allowed", - G_CALLBACK (companion_scan_allowed_cb), self); + g_signal_connect (G_OBJECT (other), "scanning-allowed", + G_CALLBACK (companion_scan_allowed_cb), self); - priv->cmp_autoconnect_allowed_id = g_signal_connect (G_OBJECT (other), "autoconnect-allowed", - G_CALLBACK (companion_autoconnect_allowed_cb), self); + g_signal_connect (G_OBJECT (other), "autoconnect-allowed", + G_CALLBACK (companion_autoconnect_allowed_cb), self); g_object_notify (G_OBJECT (self), NM_DEVICE_OLPC_MESH_COMPANION); @@ -560,8 +393,14 @@ static void device_added_cb (NMManager *manager, NMDevice *other, gpointer user_data) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - is_companion (self, other); + if (!priv->companion && check_companion (self, other)) { + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_NONE); + nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE); + } } static void @@ -573,71 +412,40 @@ device_removed_cb (NMManager *manager, NMDevice *other, gpointer user_data) companion_cleanup (self); } -static gboolean -check_companion_cb (gpointer user_data) +static void +find_companion (NMDeviceOlpcMesh *self) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - NMManager *manager; GSList *list; - if (priv->companion != NULL) { - nm_device_state_changed (NM_DEVICE (user_data), - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_NONE); - goto done; - } + if (priv->companion) + return; - if (priv->device_added_id != 0) - goto done; - - manager = nm_manager_get (); - - priv->device_added_id = g_signal_connect (manager, "device-added", - G_CALLBACK (device_added_cb), self); - if (!priv->device_removed_id) { - priv->device_removed_id = g_signal_connect (manager, "device-removed", - G_CALLBACK (device_removed_cb), self); - } + nm_device_add_pending_action (NM_DEVICE (self), "waiting for companion", TRUE); /* Try to find the companion if it's already known to the NMManager */ - for (list = nm_manager_get_devices (manager); list ; list = g_slist_next (list)) { - if (is_companion (self, NM_DEVICE (list->data))) + for (list = nm_manager_get_devices (nm_manager_get ()); list ; list = g_slist_next (list)) { + if (check_companion (self, NM_DEVICE (list->data))) { + nm_device_queue_state (NM_DEVICE (self), + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_NONE); + nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE); break; + } } - - done: - nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE); - return FALSE; } static void -state_changed (NMDevice *device, NMDeviceState new_state, - NMDeviceState old_state, NMDeviceStateReason reason) +state_changed (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); - - switch (new_state) { - case NM_DEVICE_STATE_UNMANAGED: - break; - case NM_DEVICE_STATE_UNAVAILABLE: - /* If transitioning to UNAVAILABLE and the companion device is known then - * transition to DISCONNECTED otherwise wait for our companion. - */ - g_idle_add (check_companion_cb, self); - nm_device_add_pending_action (device, "waiting for companion", TRUE); - break; - case NM_DEVICE_STATE_ACTIVATED: - break; - case NM_DEVICE_STATE_FAILED: - break; - case NM_DEVICE_STATE_DISCONNECTED: - break; - default: - break; - } + if (new_state == NM_DEVICE_STATE_UNAVAILABLE) + find_companion (NM_DEVICE_OLPC_MESH (device)); } +/*******************************************************************/ NMDevice * nm_device_olpc_mesh_new (NMPlatformLink *platform_device) @@ -650,3 +458,138 @@ nm_device_olpc_mesh_new (NMPlatformLink *platform_device) NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH, NULL); } + +static void +nm_device_olpc_mesh_init (NMDeviceOlpcMesh * self) +{ +} + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + GObjectClass *klass; + NMDeviceOlpcMesh *self; + NMDeviceWifiCapabilities caps; + + klass = G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class); + object = klass->constructor (type, n_construct_params, construct_params); + if (!object) + return NULL; + + self = NM_DEVICE_OLPC_MESH (object); + + nm_log_dbg (LOGD_HW | LOGD_OLPC, "(%s): kernel ifindex %d", + nm_device_get_iface (NM_DEVICE (self)), + nm_device_get_ifindex (NM_DEVICE (self))); + + if (!nm_platform_wifi_get_capabilities (nm_device_get_ifindex (NM_DEVICE (self)), &caps)) { + nm_log_warn (LOGD_HW | LOGD_OLPC, "(%s): failed to initialize WiFi driver", + nm_device_get_iface (NM_DEVICE (self))); + g_object_unref (object); + return NULL; + } + + g_signal_connect (nm_manager_get (), "device-added", G_CALLBACK (device_added_cb), self); + g_signal_connect (nm_manager_get (), "device-removed", G_CALLBACK (device_removed_cb), self); + + /* shorter timeout for mesh connectivity */ + nm_device_set_dhcp_timeout (NM_DEVICE (self), 20); + return object; +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMDeviceOlpcMesh *device = NM_DEVICE_OLPC_MESH (object); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (device); + + switch (prop_id) { + case PROP_COMPANION: + if (priv->companion) + g_value_set_boxed (value, nm_device_get_path (priv->companion)); + else + g_value_set_boxed (value, "/"); + break; + case PROP_ACTIVE_CHANNEL: + g_value_set_uint (value, nm_platform_mesh_get_channel (nm_device_get_ifindex (NM_DEVICE (device)))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object); + + companion_cleanup (self); + g_signal_handlers_disconnect_by_func (nm_manager_get (), G_CALLBACK (device_added_cb), self); + g_signal_handlers_disconnect_by_func (nm_manager_get (), G_CALLBACK (device_removed_cb), self); + + G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); +} + +static void +nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceOlpcMeshPrivate)); + + object_class->constructor = constructor; + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->can_auto_connect = can_auto_connect; + parent_class->complete_connection = complete_connection; + + parent_class->is_available = is_available; + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->act_stage2_config = act_stage2_config; + + parent_class->state_changed = state_changed; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_COMPANION, + g_param_spec_boxed (NM_DEVICE_OLPC_MESH_COMPANION, + "Companion device", + "Companion device object path", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_ACTIVE_CHANNEL, + g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, + "Active channel", + "Active channel", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), + G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_olpc_mesh_object_info); + + dbus_g_error_domain_register (NM_OLPC_MESH_ERROR, NULL, NM_TYPE_OLPC_MESH_ERROR); +} + diff --git a/src/devices/nm-device-olpc-mesh.h b/src/devices/wifi/nm-device-olpc-mesh.h similarity index 100% rename from src/devices/nm-device-olpc-mesh.h rename to src/devices/wifi/nm-device-olpc-mesh.h diff --git a/src/devices/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c similarity index 90% rename from src/devices/nm-device-wifi.c rename to src/devices/wifi/nm-device-wifi.c index a1e8bed66e..24403eaaad 100644 --- a/src/devices/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -58,6 +58,8 @@ #include "nm-settings-connection.h" #include "nm-enum-types.h" #include "nm-dbus-glib-types.h" +#include "nm-wifi-enum-types.h" +#include "nm-connection-provider.h" static gboolean impl_device_get_access_points (NMDeviceWifi *device, @@ -96,7 +98,6 @@ enum { PROP_ACTIVE_ACCESS_POINT, PROP_CAPABILITIES, PROP_SCANNING, - PROP_IPW_RFKILL_STATE, LAST_PROP }; @@ -104,7 +105,6 @@ enum { enum { ACCESS_POINT_ADDED, ACCESS_POINT_REMOVED, - HIDDEN_AP_FOUND, SCANNING_ALLOWED, LAST_SIGNAL @@ -112,28 +112,12 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -typedef struct Supplicant { - NMSupplicantManager *mgr; - NMSupplicantInterface *iface; - - guint iface_error_id; - - /* Timeouts and idles */ - guint iface_con_error_cb_id; - guint con_timeout_id; -} Supplicant; - struct _NMDeviceWifiPrivate { gboolean disposed; guint8 perm_hw_addr[ETH_ALEN]; /* Permanent MAC address */ guint8 initial_hw_addr[ETH_ALEN]; /* Initial MAC address (as seen when NM starts) */ - /* Legacy rfkill for ipw2x00; will be fixed with 2.6.33 kernel */ - char * ipw_rfkill_path; - guint ipw_rfkill_id; - RfKillState ipw_rfkill_state; - gint8 invalid_strength_counter; GSList * ap_list; @@ -147,7 +131,10 @@ struct _NMDeviceWifiPrivate { guint scanlist_cull_id; gboolean requested_scan; - Supplicant supplicant; + NMSupplicantManager *sup_mgr; + NMSupplicantInterface *sup_iface; + guint sup_timeout_id; /* supplicant association timeout */ + gboolean ssid_found; NM80211Mode mode; @@ -167,8 +154,6 @@ static void cancel_pending_scan (NMDeviceWifi *self); static void cleanup_association_attempt (NMDeviceWifi * self, gboolean disconnect); -static void remove_supplicant_timeouts (NMDeviceWifi *self); - static void supplicant_iface_state_cb (NMSupplicantInterface *iface, guint32 new_state, guint32 old_state, @@ -203,6 +188,8 @@ static gboolean request_wireless_scan (gpointer user_data); static void remove_access_point (NMDeviceWifi *device, NMAccessPoint *ap); +static void remove_supplicant_interface_error_handler (NMDeviceWifi *self); + /*****************************************************************/ #define NM_WIFI_ERROR (nm_wifi_error_quark ()) @@ -218,68 +205,6 @@ nm_wifi_error_quark (void) /*****************************************************************/ -/* IPW rfkill handling (until 2.6.33) */ -RfKillState -nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - char *contents = NULL; - RfKillState state = RFKILL_UNBLOCKED; - const char *str_state = NULL; - - if ( priv->ipw_rfkill_path - && (contents = nm_platform_sysctl_get (priv->ipw_rfkill_path))) { - - if (strlen (contents) != 1) - contents[0] = 0; - - /* 0 - RF kill not enabled - * 1 - SW based RF kill active (sysfs) - * 2 - HW based RF kill active - * 3 - Both HW and SW baed RF kill active - */ - switch (contents[0]) { - case '1': - state = RFKILL_SOFT_BLOCKED; - str_state = "soft-blocked"; - break; - case '2': - case '3': - state = RFKILL_HARD_BLOCKED; - str_state = "hard-blocked"; - break; - case '0': - str_state = "unblocked"; - default: - break; - } - g_free (contents); - - nm_log_dbg (LOGD_RFKILL, "(%s): ipw rfkill state '%s'", - nm_device_get_iface (NM_DEVICE (self)), - str_state ? str_state : "(unknown)"); - } - - return state; -} - -static gboolean -ipw_rfkill_state_work (gpointer user_data) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - RfKillState old_state; - - old_state = priv->ipw_rfkill_state; - priv->ipw_rfkill_state = nm_device_wifi_get_ipw_rfkill_state (self); - if (priv->ipw_rfkill_state != old_state) - g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_IPW_RFKILL_STATE); - - return TRUE; -} - -/*****************************************************************/ - static GObject* constructor (GType type, guint n_construct_params, @@ -316,24 +241,8 @@ constructor (GType type, } /* Connect to the supplicant manager */ - priv->supplicant.mgr = nm_supplicant_manager_get (); - g_assert (priv->supplicant.mgr); - - /* The ipw2x00 drivers don't integrate with the kernel rfkill subsystem until - * 2.6.33. Thus all our nice libgudev magic is useless. So we get to poll. - * - * FIXME: when 2.6.33 comes lands, we can do some sysfs parkour to figure out - * if we need to poll or not by matching /sys/class/net/ethX/device to one - * of the /sys/class/rfkill/rfkillX/device links. If there's a match, we - * don't have to poll. - */ - priv->ipw_rfkill_path = g_strdup_printf ("/sys/class/net/%s/device/rf_kill", - ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (NM_DEVICE (self)))); - if (!g_file_test (priv->ipw_rfkill_path, G_FILE_TEST_IS_REGULAR)) { - g_free (priv->ipw_rfkill_path); - priv->ipw_rfkill_path = NULL; - } - priv->ipw_rfkill_state = nm_device_wifi_get_ipw_rfkill_state (self); + priv->sup_mgr = nm_supplicant_manager_get (); + g_assert (priv->sup_mgr); return object; } @@ -345,41 +254,41 @@ supplicant_interface_acquire (NMDeviceWifi *self) g_return_val_if_fail (self != NULL, FALSE); /* interface already acquired? */ - g_return_val_if_fail (priv->supplicant.iface == NULL, TRUE); + g_return_val_if_fail (priv->sup_iface == NULL, TRUE); - priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, - nm_device_get_iface (NM_DEVICE (self)), - TRUE); - if (priv->supplicant.iface == NULL) { + priv->sup_iface = nm_supplicant_manager_iface_get (priv->sup_mgr, + nm_device_get_iface (NM_DEVICE (self)), + TRUE); + if (priv->sup_iface == NULL) { nm_log_err (LOGD_WIFI, "Couldn't initialize supplicant interface for %s.", nm_device_get_iface (NM_DEVICE (self))); return FALSE; } - if (nm_supplicant_interface_get_state (priv->supplicant.iface) < NM_SUPPLICANT_INTERFACE_STATE_READY) + if (nm_supplicant_interface_get_state (priv->sup_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY) nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant", TRUE); - g_signal_connect (priv->supplicant.iface, + g_signal_connect (priv->sup_iface, NM_SUPPLICANT_INTERFACE_STATE, G_CALLBACK (supplicant_iface_state_cb), self); - g_signal_connect (priv->supplicant.iface, + g_signal_connect (priv->sup_iface, NM_SUPPLICANT_INTERFACE_NEW_BSS, G_CALLBACK (supplicant_iface_new_bss_cb), self); - g_signal_connect (priv->supplicant.iface, + g_signal_connect (priv->sup_iface, NM_SUPPLICANT_INTERFACE_BSS_UPDATED, G_CALLBACK (supplicant_iface_bss_updated_cb), self); - g_signal_connect (priv->supplicant.iface, + g_signal_connect (priv->sup_iface, NM_SUPPLICANT_INTERFACE_BSS_REMOVED, G_CALLBACK (supplicant_iface_bss_removed_cb), self); - g_signal_connect (priv->supplicant.iface, + g_signal_connect (priv->sup_iface, NM_SUPPLICANT_INTERFACE_SCAN_DONE, G_CALLBACK (supplicant_iface_scan_done_cb), self); - g_signal_connect (priv->supplicant.iface, + g_signal_connect (priv->sup_iface, "notify::scanning", G_CALLBACK (supplicant_iface_notify_scanning_cb), self); @@ -387,25 +296,6 @@ supplicant_interface_acquire (NMDeviceWifi *self) return TRUE; } -static void -remove_supplicant_interface_error_handler (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - if (!priv->supplicant.iface) - return; - - if (priv->supplicant.iface_error_id > 0) { - g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_error_id); - priv->supplicant.iface_error_id = 0; - } - - if (priv->supplicant.iface_con_error_cb_id > 0) { - g_source_remove (priv->supplicant.iface_con_error_cb_id); - priv->supplicant.iface_con_error_cb_id = 0; - } -} - static void supplicant_interface_release (NMDeviceWifi *self) { @@ -423,23 +313,22 @@ supplicant_interface_release (NMDeviceWifi *self) nm_device_get_iface (NM_DEVICE (self)), priv->scan_interval); - remove_supplicant_interface_error_handler (self); - if (priv->scanlist_cull_id) { g_source_remove (priv->scanlist_cull_id); priv->scanlist_cull_id = 0; } - if (priv->supplicant.iface) { + if (priv->sup_iface) { + remove_supplicant_interface_error_handler (self); + /* Clear supplicant interface signal handlers */ - g_signal_handlers_disconnect_matched (priv->supplicant.iface, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, self); + g_signal_handlers_disconnect_by_data (priv->sup_iface, self); /* Tell the supplicant to disconnect from the current AP */ - nm_supplicant_interface_disconnect (priv->supplicant.iface); + nm_supplicant_interface_disconnect (priv->sup_iface); - nm_supplicant_manager_iface_release (priv->supplicant.mgr, priv->supplicant.iface); - priv->supplicant.iface = NULL; + nm_supplicant_manager_iface_release (priv->sup_mgr, priv->sup_iface); + priv->sup_iface = NULL; } } @@ -619,7 +508,6 @@ done: static void update_seen_bssids_cache (NMDeviceWifi *self, NMAccessPoint *ap) { - NMActRequest *req; NMConnection *connection; g_return_if_fail (NM_IS_DEVICE_WIFI (self)); @@ -632,9 +520,8 @@ update_seen_bssids_cache (NMDeviceWifi *self, NMAccessPoint *ap) return; if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED) { - req = nm_device_get_act_request (NM_DEVICE (self)); - if (req) { - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (NM_DEVICE (self)); + if (connection) { nm_settings_connection_add_seen_bssid (NM_SETTINGS_CONNECTION (connection), nm_ap_get_address (ap)); } @@ -706,10 +593,10 @@ periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap) * assume the old one (if any) is still valid until we're told otherwise or * the connection fails. */ - supplicant_state = nm_supplicant_interface_get_state (priv->supplicant.iface); + supplicant_state = nm_supplicant_interface_get_state (priv->sup_iface); if ( supplicant_state < NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING || supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED - || nm_supplicant_interface_get_scanning (priv->supplicant.iface)) + || nm_supplicant_interface_get_scanning (priv->sup_iface)) return; /* In AP mode we currently have nothing to do. */ @@ -852,13 +739,11 @@ deactivate (NMDevice *dev) NMDeviceWifi *self = NM_DEVICE_WIFI (dev); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); int ifindex = nm_device_get_ifindex (dev); - NMActRequest *req; NMConnection *connection; NM80211Mode old_mode = priv->mode; - req = nm_device_get_act_request (dev); - if (req) { - connection = nm_act_request_get_connection (req); + connection = nm_device_get_connection (dev); + if (connection) { /* Clear wireless secrets tries when deactivating */ g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); } @@ -1025,8 +910,8 @@ check_connection_compatible (NMDevice *device, return FALSE; } - if (priv->supplicant.iface) { - switch (nm_supplicant_interface_get_ap_support (priv->supplicant.iface)) { + if (priv->sup_iface) { + switch (nm_supplicant_interface_get_ap_support (priv->sup_iface)) { case AP_SUPPORT_NO: g_set_error_literal (error, NM_WIFI_ERROR, @@ -1337,7 +1222,7 @@ is_available (NMDevice *dev) return FALSE; } - sup_iface = priv->supplicant.iface; + sup_iface = priv->sup_iface; if (!sup_iface) { nm_log_dbg (LOGD_WIFI, "(%s): not available because supplicant not running", nm_device_get_iface (dev)); @@ -1484,7 +1369,7 @@ impl_device_request_scan (NMDeviceWifi *self, GError *error; if ( !priv->enabled - || !priv->supplicant.iface + || !priv->sup_iface || nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED || nm_device_is_activating (device)) { error = g_error_new_literal (NM_WIFI_ERROR, @@ -1493,14 +1378,14 @@ impl_device_request_scan (NMDeviceWifi *self, goto error; } - if (nm_supplicant_interface_get_scanning (priv->supplicant.iface)) { + if (nm_supplicant_interface_get_scanning (priv->sup_iface)) { error = g_error_new_literal (NM_WIFI_ERROR, NM_WIFI_ERROR_SCAN_NOT_ALLOWED, "Scanning not allowed while already scanning"); goto error; } - last_scan = nm_supplicant_interface_get_last_scan_time (priv->supplicant.iface); + last_scan = nm_supplicant_interface_get_last_scan_time (priv->sup_iface); if (last_scan && (nm_utils_get_monotonic_timestamp_s () - last_scan) < 10) { error = g_error_new_literal (NM_WIFI_ERROR, NM_WIFI_ERROR_SCAN_NOT_ALLOWED, @@ -1529,9 +1414,9 @@ scanning_allowed (NMDeviceWifi *self) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); guint32 sup_state; - NMActRequest *req; + NMConnection *connection; - g_return_val_if_fail (priv->supplicant.iface != NULL, FALSE); + g_return_val_if_fail (priv->sup_iface != NULL, FALSE); /* Scanning not done in AP mode */ if (priv->mode == NM_802_11_MODE_AP) @@ -1560,23 +1445,21 @@ scanning_allowed (NMDeviceWifi *self) } /* Don't scan if the supplicant is busy */ - sup_state = nm_supplicant_interface_get_state (priv->supplicant.iface); + sup_state = nm_supplicant_interface_get_state (priv->sup_iface); if ( sup_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING || sup_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED || sup_state == NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE || sup_state == NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE - || nm_supplicant_interface_get_scanning (priv->supplicant.iface)) + || nm_supplicant_interface_get_scanning (priv->sup_iface)) return FALSE; - req = nm_device_get_act_request (NM_DEVICE (self)); - if (req) { - NMConnection *connection; + connection = nm_device_get_connection (NM_DEVICE (self)); + if (connection) { NMSettingWireless *s_wifi; const char *ip4_method = NULL; const GByteArray *bssid; /* Don't scan when a shared connection is active; it makes drivers mad */ - connection = nm_act_request_get_connection (req); ip4_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); if (!strcmp (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) @@ -1641,7 +1524,7 @@ static GPtrArray * 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); + guint max_scan_ssids = nm_supplicant_interface_get_max_scan_ssids (priv->sup_iface); GSList *connections, *iter; GPtrArray *ssids = NULL; static GByteArray *nullssid = NULL; @@ -1718,7 +1601,7 @@ request_wireless_scan (gpointer user_data) } } - if (nm_supplicant_interface_request_scan (priv->supplicant.iface, ssids)) { + if (nm_supplicant_interface_request_scan (priv->sup_iface, ssids)) { /* success */ backoff = TRUE; priv->requested_scan = TRUE; @@ -1832,6 +1715,34 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, * */ +static void +try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) +{ + const struct ether_addr *bssid; + const GSList *connections, *iter; + + g_return_if_fail (nm_ap_get_ssid (ap) == NULL); + + bssid = nm_ap_get_address (ap); + g_assert (bssid); + + /* Look for this AP's BSSID in the seen-bssids list of a connection, + * and if a match is found, copy over the SSID */ + connections = nm_connection_provider_get_connections (nm_connection_provider_get ()); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingWireless *s_wifi; + + s_wifi = nm_connection_get_setting_wireless (connection); + if (s_wifi) { + if (nm_settings_connection_has_seen_bssid (NM_SETTINGS_CONNECTION (connection), bssid)) { + nm_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); + break; + } + } + } +} + #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" #define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] @@ -1861,8 +1772,8 @@ merge_scanned_ap (NMDeviceWifi *self, bssid = nm_ap_get_address (merge_ap); ssid = nm_ap_get_ssid (merge_ap); if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) { - /* Let the manager try to fill the AP's SSID from the database */ - g_signal_emit (self, signals[HIDDEN_AP_FOUND], 0, merge_ap); + /* Try to fill the SSID from the AP database */ + try_fill_ssid_for_hidden_ap (merge_ap); ssid = nm_ap_get_ssid (merge_ap); if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) { @@ -2097,6 +2008,21 @@ supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface, g_object_set_data (G_OBJECT (ap), WPAS_REMOVED_TAG, GUINT_TO_POINTER (TRUE)); } +static void +remove_supplicant_timeouts (NMDeviceWifi *self) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + if (priv->sup_timeout_id) { + g_source_remove (priv->sup_timeout_id); + priv->sup_timeout_id = 0; + } + + if (priv->link_timeout_id) { + g_source_remove (priv->link_timeout_id); + priv->link_timeout_id = 0; + } +} static void cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect) @@ -2105,8 +2031,8 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect) remove_supplicant_interface_error_handler (self); remove_supplicant_timeouts (self); - if (disconnect && priv->supplicant.iface) - nm_supplicant_interface_disconnect (priv->supplicant.iface); + if (disconnect && priv->sup_iface) + nm_supplicant_interface_disconnect (priv->sup_iface); } static void @@ -2131,21 +2057,6 @@ wifi_secrets_cb (NMActRequest *req, nm_device_activate_schedule_stage1_device_prepare (dev); } -static void -remove_link_timeout (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv; - - g_return_if_fail (self != NULL); - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - if (priv->link_timeout_id) { - g_source_remove (priv->link_timeout_id); - priv->link_timeout_id = 0; - } -} - - /* * link_timeout_cb * @@ -2425,6 +2336,9 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, case NM_SUPPLICANT_INTERFACE_STATE_DOWN: cleanup_association_attempt (self, FALSE); + if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY) + nm_device_remove_pending_action (device, "waiting for supplicant", TRUE); + /* If the device is already in UNAVAILABLE state then the state change * is a NOP and the interface won't be re-acquired in the device state * change handler. So ensure we have a new one here so that we're @@ -2447,69 +2361,34 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, g_object_notify (G_OBJECT (self), "scanning"); } -struct iface_con_error_cb_data { - NMDeviceWifi *self; - char *name; - char *message; -}; - -static gboolean -supplicant_iface_connection_error_cb_handler (gpointer user_data) +static void +supplicant_iface_connection_error_cb (NMSupplicantInterface *iface, + const char *name, + const char *message, + NMDeviceWifi *self) { - NMDeviceWifi *self; - NMDeviceWifiPrivate *priv; - struct iface_con_error_cb_data * cb_data = (struct iface_con_error_cb_data *) user_data; + NMDevice *device = NM_DEVICE (self); - g_return_val_if_fail (cb_data != NULL, FALSE); + if (nm_device_is_activating (device)) { + nm_log_warn (LOGD_DEVICE | LOGD_WIFI, + "Activation (%s/wireless): supplicant association failed: %s - %s", + nm_device_get_iface (device), name, message); - self = cb_data->self; - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - if (!nm_device_is_activating (NM_DEVICE (self))) - goto out; - - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): association request to the supplicant " - "failed: %s - %s", - nm_device_get_iface (NM_DEVICE (self)), - cb_data->name, - cb_data->message); - - cleanup_association_attempt (self, TRUE); - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - -out: - priv->supplicant.iface_con_error_cb_id = 0; - g_free (cb_data->name); - g_free (cb_data->message); - g_slice_free (struct iface_con_error_cb_data, cb_data); - return FALSE; + cleanup_association_attempt (self, TRUE); + nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + } } - static void -supplicant_iface_connection_error_cb (NMSupplicantInterface * iface, - const char * name, - const char * message, - NMDeviceWifi * self) +remove_supplicant_interface_error_handler (NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv; - struct iface_con_error_cb_data *cb_data; - guint id; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - g_return_if_fail (self != NULL); - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - cb_data = g_slice_new0 (struct iface_con_error_cb_data); - cb_data->self = self; - cb_data->name = g_strdup (name); - cb_data->message = g_strdup (message); - - if (priv->supplicant.iface_con_error_cb_id) - g_source_remove (priv->supplicant.iface_con_error_cb_id); - - id = g_idle_add (supplicant_iface_connection_error_cb_handler, cb_data); - priv->supplicant.iface_con_error_cb_id = id; + if (priv->sup_iface) { + g_signal_handlers_disconnect_by_func (priv->sup_iface, + supplicant_iface_connection_error_cb, + self); + } } static void @@ -2533,21 +2412,6 @@ supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface, periodic_update (self, NULL); } -static void -remove_supplicant_connection_timeout (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv; - - g_return_if_fail (self != NULL); - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - /* Remove any pending timeouts on the request */ - if (priv->supplicant.con_timeout_id) { - g_source_remove (priv->supplicant.con_timeout_id); - priv->supplicant.con_timeout_id = 0; - } -} - static NMActStageReturn handle_auth_or_fail (NMDeviceWifi *self, NMActRequest *req, @@ -2681,40 +2545,6 @@ supplicant_connection_timeout_cb (gpointer user_data) return FALSE; } - -static gboolean -start_supplicant_connection_timeout (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv; - guint id; - - g_return_val_if_fail (self != NULL, FALSE); - - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - /* Set up a timeout on the connection attempt to fail it after 25 seconds */ - id = g_timeout_add_seconds (25, supplicant_connection_timeout_cb, self); - if (id == 0) { - nm_log_err (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): couldn't start supplicant " - "timeout timer.", - nm_device_get_iface (NM_DEVICE (self))); - return FALSE; - } - priv->supplicant.con_timeout_id = id; - return TRUE; -} - - -static void -remove_supplicant_timeouts (NMDeviceWifi *self) -{ - g_return_if_fail (self != NULL); - - remove_supplicant_connection_timeout (self); - remove_link_timeout (self); -} - static NMSupplicantConfig * build_supplicant_config (NMDeviceWifi *self, NMConnection *connection, @@ -2736,7 +2566,7 @@ build_supplicant_config (NMDeviceWifi *self, /* Warn if AP mode may not be supported */ if ( g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0 - && nm_supplicant_interface_get_ap_support (priv->supplicant.iface) == AP_SUPPORT_UNKNOWN) { + && nm_supplicant_interface_get_ap_support (priv->sup_iface) == AP_SUPPORT_UNKNOWN) { nm_log_warn (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); } @@ -2980,7 +2810,6 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; const char *iface = nm_device_get_iface (dev); NMSupplicantConfig *config = NULL; - gulong id = 0; NMActRequest *req; NMAccessPoint *ap; NMConnection *connection; @@ -3053,13 +2882,12 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) } /* Hook up error signal handler to capture association errors */ - id = g_signal_connect (priv->supplicant.iface, - NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR, - G_CALLBACK (supplicant_iface_connection_error_cb), - self); - priv->supplicant.iface_error_id = id; + g_signal_connect (priv->sup_iface, + NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR, + G_CALLBACK (supplicant_iface_connection_error_cb), + self); - if (!nm_supplicant_interface_set_config (priv->supplicant.iface, config)) { + if (!nm_supplicant_interface_set_config (priv->sup_iface, config)) { nm_log_err (LOGD_DEVICE | LOGD_WIFI, "Activation (%s/wireless): couldn't send wireless " "configuration to the supplicant.", iface); @@ -3067,10 +2895,8 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) goto out; } - if (!start_supplicant_connection_timeout (self)) { - *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; - goto out; - } + /* Set up a timeout on the association attempt to fail after 25 seconds */ + priv->sup_timeout_id = g_timeout_add_seconds (25, supplicant_connection_timeout_cb, self); if (!priv->periodic_source_id) priv->periodic_source_id = g_timeout_add_seconds (6, periodic_update_cb, self); @@ -3376,7 +3202,7 @@ device_state_changed (NMDevice *device, /* Clean up the supplicant interface because in these states the * device cannot be used. */ - if (priv->supplicant.iface) + if (priv->sup_iface) supplicant_interface_release (self); if (priv->periodic_source_id) { @@ -3388,19 +3214,6 @@ device_state_changed (NMDevice *device, remove_all_aps (self); } - /* Start or stop the rfkill poll worker for ipw cards */ - if (priv->ipw_rfkill_path) { - if (new_state > NM_DEVICE_STATE_UNMANAGED) { - if (!priv->ipw_rfkill_id) - priv->ipw_rfkill_id = g_timeout_add_seconds (3, ipw_rfkill_state_work, self); - } else if (new_state <= NM_DEVICE_STATE_UNMANAGED) { - if (priv->ipw_rfkill_id) { - g_source_remove (priv->ipw_rfkill_id); - priv->ipw_rfkill_id = 0; - } - } - } - switch (new_state) { case NM_DEVICE_STATE_UNMANAGED: clear_aps = TRUE; @@ -3411,14 +3224,14 @@ device_state_changed (NMDevice *device, * the device is now ready to use. */ if (priv->enabled && (nm_device_get_firmware_missing (device) == FALSE)) { - if (!priv->supplicant.iface) + if (!priv->sup_iface) supplicant_interface_acquire (self); } clear_aps = TRUE; break; case NM_DEVICE_STATE_NEED_AUTH: - if (priv->supplicant.iface) - nm_supplicant_interface_disconnect (priv->supplicant.iface); + if (priv->sup_iface) + nm_supplicant_interface_disconnect (priv->sup_iface); break; case NM_DEVICE_STATE_IP_CHECK: /* Clear any critical protocol notification in the wifi stack */ @@ -3488,7 +3301,7 @@ set_enabled (NMDevice *device, gboolean enabled) } /* Re-initialize the supplicant interface and wait for it to be ready */ - if (priv->supplicant.iface) + if (priv->sup_iface) supplicant_interface_release (self); supplicant_interface_acquire (self); @@ -3544,19 +3357,10 @@ dispose (GObject *object) cleanup_association_attempt (self, TRUE); supplicant_interface_release (self); - if (priv->supplicant.mgr) { - g_object_unref (priv->supplicant.mgr); - priv->supplicant.mgr = NULL; - } + g_clear_object (&priv->sup_mgr); remove_all_aps (self); - g_free (priv->ipw_rfkill_path); - if (priv->ipw_rfkill_id) { - g_source_remove (priv->ipw_rfkill_id); - priv->ipw_rfkill_id = 0; - } - G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object); } @@ -3595,10 +3399,7 @@ get_property (GObject *object, guint prop_id, g_value_set_boxed (value, "/"); break; case PROP_SCANNING: - g_value_set_boolean (value, nm_supplicant_interface_get_scanning (priv->supplicant.iface)); - break; - case PROP_IPW_RFKILL_STATE: - g_value_set_uint (value, nm_device_wifi_get_ipw_rfkill_state (device)); + g_value_set_boolean (value, nm_supplicant_interface_get_scanning (priv->sup_iface)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -3610,13 +3411,7 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); - switch (prop_id) { - case PROP_IPW_RFKILL_STATE: - /* construct only */ - priv->ipw_rfkill_state = g_value_get_uint (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3714,13 +3509,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) FALSE, G_PARAM_READABLE)); - g_object_class_install_property (object_class, PROP_IPW_RFKILL_STATE, - g_param_spec_uint (NM_DEVICE_WIFI_IPW_RFKILL_STATE, - "IpwRfkillState", - "ipw rf-kill state", - RFKILL_UNBLOCKED, RFKILL_HARD_BLOCKED, RFKILL_UNBLOCKED, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - /* Signals */ signals[ACCESS_POINT_ADDED] = g_signal_new ("access-point-added", @@ -3740,15 +3528,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) G_TYPE_NONE, 1, G_TYPE_OBJECT); - signals[HIDDEN_AP_FOUND] = - g_signal_new ("hidden-ap-found", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDeviceWifiClass, hidden_ap_found), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); - signals[SCANNING_ALLOWED] = g_signal_new ("scanning-allowed", G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/devices/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h similarity index 93% rename from src/devices/nm-device-wifi.h rename to src/devices/wifi/nm-device-wifi.h index 18d26e463d..f0a1beacde 100644 --- a/src/devices/nm-device-wifi.h +++ b/src/devices/wifi/nm-device-wifi.h @@ -26,7 +26,6 @@ #include #include -#include "nm-rfkill-manager.h" #include "nm-device.h" #include "nm-wifi-ap.h" @@ -58,7 +57,6 @@ typedef enum { #define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point" #define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" #define NM_DEVICE_WIFI_SCANNING "scanning" -#define NM_DEVICE_WIFI_IPW_RFKILL_STATE "ipw-rfkill-state" #ifndef NM_DEVICE_WIFI_DEFINED #define NM_DEVICE_WIFI_DEFINED @@ -83,7 +81,6 @@ struct _NMDeviceWifiClass /* Signals */ void (*access_point_added) (NMDeviceWifi *device, NMAccessPoint *ap); void (*access_point_removed) (NMDeviceWifi *device, NMAccessPoint *ap); - void (*hidden_ap_found) (NMDeviceWifi *device, NMAccessPoint *ap); gboolean (*scanning_allowed) (NMDeviceWifi *device); }; @@ -92,8 +89,6 @@ GType nm_device_wifi_get_type (void); NMDevice *nm_device_wifi_new (NMPlatformLink *platform_device); -RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self); - G_END_DECLS #endif /* NM_DEVICE_WIFI_H */ diff --git a/src/nm-wifi-ap-utils.c b/src/devices/wifi/nm-wifi-ap-utils.c similarity index 100% rename from src/nm-wifi-ap-utils.c rename to src/devices/wifi/nm-wifi-ap-utils.c diff --git a/src/nm-wifi-ap-utils.h b/src/devices/wifi/nm-wifi-ap-utils.h similarity index 100% rename from src/nm-wifi-ap-utils.h rename to src/devices/wifi/nm-wifi-ap-utils.h diff --git a/src/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c similarity index 100% rename from src/nm-wifi-ap.c rename to src/devices/wifi/nm-wifi-ap.c diff --git a/src/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h similarity index 100% rename from src/nm-wifi-ap.h rename to src/devices/wifi/nm-wifi-ap.h diff --git a/src/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c new file mode 100644 index 0000000000..e4a140a324 --- /dev/null +++ b/src/devices/wifi/nm-wifi-factory.c @@ -0,0 +1,114 @@ +/* -*- 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) 2011 - 2014 Red Hat, Inc. + */ + +#include + +#include "nm-device-factory.h" +#include "nm-device-wifi.h" +#include "nm-device-olpc-mesh.h" +#include "nm-settings-connection.h" + +#define NM_TYPE_WIFI_FACTORY (nm_wifi_factory_get_type ()) +#define NM_WIFI_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_FACTORY, NMWifiFactory)) + +typedef struct { + GObject parent; +} NMWifiFactory; + +typedef struct { + GObjectClass parent; +} NMWifiFactoryClass; + +static GType nm_wifi_factory_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMWifiFactory, nm_wifi_factory, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) + +enum { + PROP_0, + PROP_DEVICE_TYPE, +}; + +/**************************************************************************/ + +#define PLUGIN_TYPE NM_DEVICE_TYPE_WIFI + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_WIFI_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) +{ + if (plink->type == NM_LINK_TYPE_WIFI) + return nm_device_wifi_new (plink); + else if (plink->type == NM_LINK_TYPE_OLPC_MESH) + return nm_device_olpc_mesh_new (plink); + return NULL; +} + +static void +get_property (GObject *object, guint prop, GValue *value, GParamSpec *pspec) +{ + 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; + } +} + +static void +device_factory_interface_init (NMDeviceFactory *factory_iface) +{ + factory_iface->new_link = new_link; +} + +static void +nm_wifi_factory_init (NMWifiFactory *self) +{ +} + +static void +nm_wifi_factory_class_init (NMWifiFactoryClass *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/wifi/tests/Makefile.am b/src/devices/wifi/tests/Makefile.am new file mode 100644 index 0000000000..2667c5f12d --- /dev/null +++ b/src/devices/wifi/tests/Makefile.am @@ -0,0 +1,28 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/src/platform \ + -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/devices/wifi \ + -I$(top_builddir)/src \ + -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +noinst_PROGRAMS = test-wifi-ap-utils + +test_wifi_ap_utils_SOURCES = \ + test-wifi-ap-utils.c \ + $(srcdir)/../nm-wifi-ap.c \ + $(srcdir)/../nm-wifi-ap.h \ + $(srcdir)/../nm-wifi-ap-utils.c \ + $(srcdir)/../nm-wifi-ap-utils.h + +test_wifi_ap_utils_LDADD = $(top_builddir)/src/libNetworkManager.la + +TESTS = test-wifi-ap-utils + diff --git a/src/tests/test-wifi-ap-utils.c b/src/devices/wifi/tests/test-wifi-ap-utils.c similarity index 100% rename from src/tests/test-wifi-ap-utils.c rename to src/devices/wifi/tests/test-wifi-ap-utils.c diff --git a/src/nm-manager.c b/src/nm-manager.c index 97228cc001..dde273923d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -41,8 +41,6 @@ #include "nm-vpn-manager.h" #include "nm-device.h" #include "nm-device-ethernet.h" -#include "nm-device-wifi.h" -#include "nm-device-olpc-mesh.h" #include "nm-device-infiniband.h" #include "nm-device-bond.h" #include "nm-device-team.h" @@ -168,7 +166,6 @@ typedef struct { const char *key; const char *prop; const char *hw_prop; - RfKillState (*other_enabled_func) (NMManager *); } RadioState; typedef struct { @@ -1311,72 +1308,24 @@ manager_update_radio_enabled (NMManager *self, } static void -manager_hidden_ap_found (NMDevice *device, - NMAccessPoint *ap, - gpointer user_data) +update_rstate_from_rfkill (NMRfkillManager *rfkill_mgr, RadioState *rstate) { - NMManager *manager = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - const struct ether_addr *bssid; - GSList *iter; - GSList *connections; - gboolean done = FALSE; - - g_return_if_fail (nm_ap_get_ssid (ap) == NULL); - - bssid = nm_ap_get_address (ap); - g_assert (bssid); - - /* Look for this AP's BSSID in the seen-bssids list of a connection, - * and if a match is found, copy over the SSID */ - connections = nm_settings_get_connections (priv->settings); - for (iter = connections; iter && !done; iter = g_slist_next (iter)) { - NMConnection *connection = NM_CONNECTION (iter->data); - NMSettingWireless *s_wifi; - - s_wifi = nm_connection_get_setting_wireless (connection); - if (s_wifi) { - if (nm_settings_connection_has_seen_bssid (NM_SETTINGS_CONNECTION (connection), bssid)) - nm_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); - } - } - g_slist_free (connections); -} - -static RfKillState -nm_manager_get_ipw_rfkill_state (NMManager *self) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter; - RfKillState ipw_state = RFKILL_UNBLOCKED; - - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMDevice *candidate = NM_DEVICE (iter->data); - RfKillState candidate_state; - - if (nm_device_get_device_type (candidate) == NM_DEVICE_TYPE_WIFI) { - candidate_state = nm_device_wifi_get_ipw_rfkill_state (NM_DEVICE_WIFI (candidate)); - - if (candidate_state > ipw_state) - ipw_state = candidate_state; - } - } - - return ipw_state; -} - -static void -update_rstate_from_rfkill (RadioState *rstate, RfKillState rfkill) -{ - if (rfkill == RFKILL_UNBLOCKED) { + switch (nm_rfkill_manager_get_rfkill_state (rfkill_mgr, rstate->rtype)) { + case RFKILL_UNBLOCKED: rstate->sw_enabled = TRUE; rstate->hw_enabled = TRUE; - } else if (rfkill == RFKILL_SOFT_BLOCKED) { + break; + case RFKILL_SOFT_BLOCKED: rstate->sw_enabled = FALSE; rstate->hw_enabled = TRUE; - } else if (rfkill == RFKILL_HARD_BLOCKED) { + break; + case RFKILL_HARD_BLOCKED: rstate->sw_enabled = FALSE; rstate->hw_enabled = FALSE; + break; + default: + g_warn_if_reached (); + break; } } @@ -1386,29 +1335,14 @@ manager_rfkill_update_one_type (NMManager *self, RfKillType rtype) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - RfKillState udev_state = RFKILL_UNBLOCKED; - RfKillState other_state = RFKILL_UNBLOCKED; - RfKillState composite; gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled, old_hwe; old_enabled = radio_enabled_for_rstate (rstate, TRUE); old_rfkilled = rstate->hw_enabled && rstate->sw_enabled; old_hwe = rstate->hw_enabled; - udev_state = nm_rfkill_manager_get_rfkill_state (priv->rfkill_mgr, rtype); - - if (rstate->other_enabled_func) - other_state = rstate->other_enabled_func (self); - - /* The composite state is the "worst" of either udev or other states */ - if (udev_state == RFKILL_HARD_BLOCKED || other_state == RFKILL_HARD_BLOCKED) - composite = RFKILL_HARD_BLOCKED; - else if (udev_state == RFKILL_SOFT_BLOCKED || other_state == RFKILL_SOFT_BLOCKED) - composite = RFKILL_SOFT_BLOCKED; - else - composite = RFKILL_UNBLOCKED; - - update_rstate_from_rfkill (rstate, composite); + /* recheck kernel rfkill state */ + update_rstate_from_rfkill (priv->rfkill_mgr, rstate); /* Print out all states affecting device enablement */ if (rstate->desc) { @@ -1455,14 +1389,6 @@ nm_manager_rfkill_update (NMManager *self, RfKillType rtype) } } -static void -manager_ipw_rfkill_state_changed (NMDeviceWifi *device, - GParamSpec *pspec, - gpointer user_data) -{ - nm_manager_rfkill_update (NM_MANAGER (user_data), RFKILL_TYPE_WLAN); -} - static void device_auth_done_cb (NMAuthChain *chain, GError *auth_error, @@ -1683,11 +1609,8 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) NMConnection *connection = NULL; gboolean enabled = FALSE; RfKillType rtype; - NMDeviceType devtype; GSList *iter, *remove = NULL; - devtype = nm_device_get_device_type (device); - /* No duplicates */ if (nm_manager_get_device_by_udi (self, nm_device_get_udi (device))) return; @@ -1728,22 +1651,6 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) self); } - if (devtype == NM_DEVICE_TYPE_WIFI) { - /* Attach to the access-point-added signal so that the manager can fill - * non-SSID-broadcasting APs with an SSID. - */ - g_signal_connect (device, "hidden-ap-found", - G_CALLBACK (manager_hidden_ap_found), - self); - - /* Hook up rfkill handling for ipw-based cards until they get converted - * to use the kernel's rfkill subsystem in 2.6.33. - */ - g_signal_connect (device, "notify::" NM_DEVICE_WIFI_IPW_RFKILL_STATE, - G_CALLBACK (manager_ipw_rfkill_state_changed), - self); - } - /* Update global rfkill state for this device type with the device's * rfkill state, and then set this device's rfkill state based on the * global state. @@ -2053,12 +1960,6 @@ platform_link_added (NMManager *self, case NM_LINK_TYPE_INFINIBAND: device = nm_device_infiniband_new (plink); break; - case NM_LINK_TYPE_OLPC_MESH: - device = nm_device_olpc_mesh_new (plink); - break; - case NM_LINK_TYPE_WIFI: - device = nm_device_wifi_new (plink); - break; case NM_LINK_TYPE_BOND: device = nm_device_bond_new (plink); break; @@ -4100,14 +4001,13 @@ nm_manager_start (NMManager *self) /* Set initial radio enabled/disabled state */ for (i = 0; i < RFKILL_TYPE_MAX; i++) { RadioState *rstate = &priv->radio_states[i]; - RfKillState udev_state; gboolean enabled; if (!rstate->desc) continue; - udev_state = nm_rfkill_manager_get_rfkill_state (priv->rfkill_mgr, i); - update_rstate_from_rfkill (rstate, udev_state); + /* recheck kernel rfkill state */ + update_rstate_from_rfkill (priv->rfkill_mgr, rstate); if (rstate->desc) { nm_log_info (LOGD_RFKILL, "%s %s by radio killswitch; %s by state file", @@ -4730,7 +4630,6 @@ nm_manager_init (NMManager *manager) priv->radio_states[RFKILL_TYPE_WLAN].prop = NM_MANAGER_WIRELESS_ENABLED; priv->radio_states[RFKILL_TYPE_WLAN].hw_prop = NM_MANAGER_WIRELESS_HARDWARE_ENABLED; priv->radio_states[RFKILL_TYPE_WLAN].desc = "WiFi"; - priv->radio_states[RFKILL_TYPE_WLAN].other_enabled_func = nm_manager_get_ipw_rfkill_state; priv->radio_states[RFKILL_TYPE_WLAN].rtype = RFKILL_TYPE_WLAN; priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = TRUE; @@ -4745,7 +4644,6 @@ nm_manager_init (NMManager *manager) priv->radio_states[RFKILL_TYPE_WIMAX].prop = NM_MANAGER_WIMAX_ENABLED; priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NM_MANAGER_WIMAX_HARDWARE_ENABLED; priv->radio_states[RFKILL_TYPE_WIMAX].desc = "WiMAX"; - priv->radio_states[RFKILL_TYPE_WIMAX].other_enabled_func = NULL; priv->radio_states[RFKILL_TYPE_WIMAX].rtype = RFKILL_TYPE_WIMAX; for (i = 0; i < RFKILL_TYPE_MAX; i++) diff --git a/src/nm-policy.c b/src/nm-policy.c index 88bc31a161..d751606ed8 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -29,7 +29,6 @@ #include "nm-policy.h" #include "NetworkManagerUtils.h" -#include "nm-wifi-ap.h" #include "nm-activation-request.h" #include "nm-logging.h" #include "nm-device.h" diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 82c2fed26c..95f9854805 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -564,8 +564,8 @@ link_type_from_udev (NMPlatform *platform, int ifindex, const char *ifname, int if (!udev_device) return_type (NM_LINK_TYPE_UNKNOWN, "unknown"); - prop = g_udev_device_get_property (udev_device, "ID_NM_OLPC_MESH"); - if (prop) + if ( g_udev_device_get_property (udev_device, "ID_NM_OLPC_MESH") + || g_udev_device_get_sysfs_attr (udev_device, "anycast_mask")) return_type (NM_LINK_TYPE_OLPC_MESH, "olpc-mesh"); prop = g_udev_device_get_property (udev_device, "DEVTYPE"); @@ -623,6 +623,8 @@ ethtool_get_driver (const char *ifname) { struct ethtool_drvinfo drvinfo = { 0 }; + g_return_val_if_fail (ifname != NULL, NULL); + drvinfo.cmd = ETHTOOL_GDRVINFO; if (!ethtool_get (ifname, &drvinfo)) return NULL; @@ -665,13 +667,15 @@ link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, const char const char *driver; const char *ifname; - if (arptype == ARPHRD_LOOPBACK) return_type (NM_LINK_TYPE_LOOPBACK, "loopback"); else if (arptype == ARPHRD_INFINIBAND) return_type (NM_LINK_TYPE_INFINIBAND, "infiniband"); ifname = rtnl_link_get_name (rtnllink); + if (!ifname) + return_type (NM_LINK_TYPE_UNKNOWN, type); + if (arptype == 256) { /* Some s390 CTC-type devices report 256 for the encapsulation type * for some reason, but we need to call them Ethernet. FIXME: use @@ -1818,6 +1822,7 @@ link_change (NMPlatform *platform, int ifindex, struct rtnl_link *change) if (!rtnllink) return FALSE; + g_return_val_if_fail (rtnl_link_get_ifindex (change) > 0, FALSE); nle = rtnl_link_change (priv->nlh, rtnllink, change, 0); @@ -1943,6 +1948,7 @@ link_change_flags (NMPlatform *platform, int ifindex, unsigned int flags, gboole auto_nl_object struct rtnl_link *change = rtnl_link_alloc (); g_return_val_if_fail (change != NULL, FALSE); + rtnl_link_set_ifindex (change, ifindex); if (value) rtnl_link_set_flags (change, flags); @@ -2093,6 +2099,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size change = rtnl_link_alloc (); g_return_val_if_fail (change, FALSE); + rtnl_link_set_ifindex (change, ifindex); nladdr = nl_addr_build (AF_LLC, address, length); g_return_val_if_fail (nladdr, FALSE); @@ -2129,6 +2136,7 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) auto_nl_object struct rtnl_link *change = rtnl_link_alloc (); g_return_val_if_fail (change != NULL, FALSE); + rtnl_link_set_ifindex (change, ifindex); rtnl_link_set_mtu (change, mtu); debug ("link: change %d: mtu %lu", ifindex, (unsigned long)mtu); @@ -2240,6 +2248,7 @@ link_enslave (NMPlatform *platform, int master, int slave) g_return_val_if_fail (change != NULL, FALSE); + rtnl_link_set_ifindex (change, slave); rtnl_link_set_master (change, master); debug ("link: change %d: enslave to master %d", slave, master); diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index e23ad68761..ee5be17d7b 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -16,7 +16,6 @@ AM_CPPFLAGS = \ noinst_PROGRAMS = \ test-dhcp-options \ test-general \ - test-wifi-ap-utils \ test-ip4-config \ test-ip6-config \ test-dcb \ @@ -35,14 +34,6 @@ test_dhcp_options_CPPFLAGS = \ test_dhcp_options_LDADD = \ $(top_builddir)/src/libNetworkManager.la -####### wifi ap utils test ####### - -test_wifi_ap_utils_SOURCES = \ - test-wifi-ap-utils.c - -test_wifi_ap_utils_LDADD = \ - $(top_builddir)/src/libNetworkManager.la - ####### ip4 config test ####### test_ip4_config_SOURCES = \ @@ -89,5 +80,5 @@ EXTRA_DIST = test-secret-agent.py ########################################### -TESTS = test-dhcp-options test-wifi-ap-utils test-ip4-config test-ip6-config test-dcb test-resolvconf-capture test-general +TESTS = test-dhcp-options test-ip4-config test-ip6-config test-dcb test-resolvconf-capture test-general