support for automatically adding BSSIDs to the allowed MAC list as one roams.



Hey folks,

I just checked in code to CVS (patch attached if curious) that allows NM
to detect when you roam[1].  Thus we can do three things:

	(1) Print a cool debug message.
	(2) Update NM's internal AP object with the new BSSID.
	(2) See if the BSSID changed and, if so, notify the applet that
	    we have updated information about the current wireless
	    network, allowing the allowed-MAC address to grow
	    automatically as one roams.

If your card/driver supports roaming, it should Just Work.

Building on the code, we can consider other interesting options w.r.t.
BSSIDs.  Dan, for example, has suggested _not_ allowing roaming when
connected to one of the blacklisted default wireless networks (linksys,
NETGEAR, and so on).

	Robert Love


[1] Roaming is a hardware-level feature where the driver can seamlessly
move from one access point to another on the same wireless network.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/NetworkManager/ChangeLog,v
retrieving revision 1.866.2.63
diff -u -r1.866.2.63 ChangeLog
--- ChangeLog	16 May 2006 17:25:37 -0000	1.866.2.63
+++ ChangeLog	17 May 2006 14:56:05 -0000
@@ -1,7 +1,22 @@
+2006-05-17  Robert Love  <rml novell com>
+
+	Functionality to automatically add BSSIDs to the allowed-MAC list as
+	one roams from access point to access point on a given network:
+	* gnome/applet/applet-dbus-info.c:
+	* src/NetworkManagerUtils.c: Add nm_ethernet_addresses_are_equal(),
+	  helper function to compare two ether_addr structures and return TRUE
+	  if they contain the same MAC address.
+	* src/NetworkManagerUtils.h: Add nm_ethernet_addresses_are_equal()
+	  prototype.
+	* src/nm-device-802-11-wireless.c: New function to update the BSSID
+	  stored with the current AP.  If the BSSID has indeed changed, we
+	  send it out to the applet, allowing the allowed-MAC list to grow
+	  automatically in response to roaming.
+
 2006-05-16  Robert Love  <rml novell com>
 
-	* src/backends/NetworkManagerSuSE.c: Don't touch ypbind or autofs unless
-	  dhcp:DHCLIENT_MODIFY_NIS_CONF is set to "yes".
+	* src/backends/NetworkManagerSuSE.c: Don't touch ypbind or autofs
+	  unless dhcp:DHCLIENT_MODIFY_NIS_CONF is set to "yes".
 
 2006-05-13  Dan Williams  <dcbw redhat com>
 
Index: gnome/applet/applet-dbus-info.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/gnome/applet/applet-dbus-info.c,v
retrieving revision 1.45.2.2
diff -u -r1.45.2.2 applet-dbus-info.c
--- gnome/applet/applet-dbus-info.c	20 Apr 2006 20:39:51 -0000	1.45.2.2
+++ gnome/applet/applet-dbus-info.c	17 May 2006 14:56:05 -0000
@@ -955,7 +955,7 @@
                               DBusMessage *message,
                               void *user_data)
 {
-	NMApplet *	applet = (NMApplet *) user_data;
+	NMApplet *		applet = (NMApplet *) user_data;
 	char *			essid = NULL;
 	gboolean			automatic;
 	NMGConfWSO *		gconf_wso = NULL;
Index: src/NetworkManagerUtils.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManagerUtils.c,v
retrieving revision 1.54
diff -u -r1.54 NetworkManagerUtils.c
--- src/NetworkManagerUtils.c	6 Feb 2006 17:12:04 -0000	1.54
+++ src/NetworkManagerUtils.c	17 May 2006 14:56:09 -0000
@@ -333,7 +333,7 @@
 /*
  * nm_ethernet_address_is_valid
  *
- * Compares an ethernet address against known invalid addresses.
+ * Compares an Ethernet address against known invalid addresses.
  *
  */
 gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr)
@@ -355,6 +355,19 @@
 		valid = TRUE;
 
 	return (valid);
+}
+
+
+/*
+ * nm_ethernet_addresses_are_equal
+ *
+ * Compare two Ethernet addresses and return TRUE if equal and FALSE if not.
+ */
+gboolean nm_ethernet_addresses_are_equal (const struct ether_addr *a, const struct ether_addr *b)
+{
+	if (memcmp (a, b, sizeof (struct ether_addr)))
+		return FALSE;
+	return TRUE;
 }
 
 
Index: src/NetworkManagerUtils.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManagerUtils.h,v
retrieving revision 1.22
diff -u -r1.22 NetworkManagerUtils.h
--- src/NetworkManagerUtils.h	5 Jan 2006 04:44:11 -0000	1.22
+++ src/NetworkManagerUtils.h	17 May 2006 14:56:09 -0000
@@ -57,6 +57,7 @@
 int			nm_null_safe_strcmp				(const char *s1, const char *s2);
 
 gboolean		nm_ethernet_address_is_valid		(const struct ether_addr *test_addr);
+gboolean		nm_ethernet_addresses_are_equal	(const struct ether_addr *a, const struct ether_addr *b);
 
 int			nm_spawn_process				(const char *args);
 
Index: src/nm-dbus-nmi.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/nm-dbus-nmi.c,v
retrieving revision 1.12.2.1
diff -u -r1.12.2.1 nm-dbus-nmi.c
--- src/nm-dbus-nmi.c	9 Mar 2006 20:55:46 -0000	1.12.2.1
+++ src/nm-dbus-nmi.c	17 May 2006 14:56:09 -0000
@@ -214,7 +214,6 @@
 }
 
 
-
 /*
  * nm_dbus_update_network_info
  *
Index: src/nm-device-802-11-wireless.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/nm-device-802-11-wireless.c,v
retrieving revision 1.60.2.7
diff -u -r1.60.2.7 nm-device-802-11-wireless.c
--- src/nm-device-802-11-wireless.c	10 May 2006 21:00:07 -0000	1.60.2.7
+++ src/nm-device-802-11-wireless.c	17 May 2006 14:56:09 -0000
@@ -134,6 +134,140 @@
                                            const char *key,
                                            int auth_method);
 
+
+/*
+ * nm_device_802_11_wireless_update_bssid
+ *
+ * Update the current wireless network's BSSID, presumably in response to
+ * roaming.
+ *
+ */
+static void
+nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self)
+{
+	NMAccessPoint *		ap;
+	NMActRequest *			req;
+	struct ether_addr		new_bssid;
+	const struct ether_addr	*old_bssid;
+
+	g_return_if_fail (self != NULL);
+
+	/* Grab the scan lock since the current AP is meaningless during a scan. */
+	if (!nm_try_acquire_mutex (self->priv->scan_mutex, __FUNCTION__))
+		return;
+
+	/* If we aren't the active device with an active AP, there is no meaningful BSSID value */
+	req = nm_device_get_act_request (NM_DEVICE (self));
+	if (!req)
+		goto out;
+
+	ap = nm_act_request_get_ap (req);
+	if (!ap)
+		goto out;
+
+	/* Get the current BSSID.  If it is valid but does not match the stored value, update it. */
+	nm_device_802_11_wireless_get_bssid (self, &new_bssid);
+	old_bssid = nm_ap_get_address (ap);
+	if (nm_ethernet_address_is_valid (&new_bssid) && !nm_ethernet_addresses_are_equal (&new_bssid, old_bssid))
+	{
+		NMData *	app_data;
+		gboolean	automatic;
+		gchar	new_addr[20];
+		gchar	old_addr[20];
+
+		memset (new_addr, '\0', sizeof (new_addr));
+		memset (old_addr, '\0', sizeof (old_addr));
+		iw_ether_ntop (&new_bssid, new_addr);
+		iw_ether_ntop (old_bssid, old_addr);
+		nm_debug ("Roamed from BSSID %s to %s on wireless network '%s'", old_addr, new_addr, nm_ap_get_essid (ap));
+
+		nm_ap_set_address (ap, &new_bssid);
+
+		automatic = !nm_act_request_get_user_requested (req);
+		app_data = nm_device_get_app_data (NM_DEVICE (self));
+		g_assert (app_data);
+		nm_dbus_update_network_info (app_data->dbus_connection, ap, automatic);
+	}
+
+out:
+	nm_unlock_mutex (self->priv->scan_mutex, __func__);
+}
+
+
+/*
+ * nm_device_802_11_wireless_update_signal_strength
+ *
+ * Update the device's idea of the strength of its connection to the
+ * current access point.
+ *
+ */
+static void
+nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
+{
+	NMData *		app_data;
+	gboolean		has_range = FALSE;
+	NMSock *		sk;
+	iwrange		range;
+	iwstats		stats;
+	int			percent = -1;
+
+	g_return_if_fail (self != NULL);
+
+	app_data = nm_device_get_app_data (NM_DEVICE (self));
+	g_assert (app_data);
+
+	/* Grab the scan lock since our strength is meaningless during a scan. */
+	if (!nm_try_acquire_mutex (self->priv->scan_mutex, __FUNCTION__))
+		return;
+
+	/* If we aren't the active device, we don't really have a signal strength
+	 * that would mean anything.
+	 */
+	if (!nm_device_get_act_request (NM_DEVICE (self)))
+	{
+		self->priv->strength = -1;
+		goto out;
+	}
+
+	if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL)))
+	{
+		const char *iface = nm_device_get_iface (NM_DEVICE (self));
+
+		memset (&range, 0, sizeof (iwrange));
+		memset (&stats, 0, sizeof (iwstats));
+#ifdef IOCTL_DEBUG
+		nm_info ("%s: About to GET 'iwrange'.", iface);
+#endif
+		has_range = (iw_get_range_info (nm_dev_sock_get_fd (sk), iface, &range) >= 0);
+#ifdef IOCTL_DEBUG
+		nm_info ("%s: About to GET 'iwstats'.", iface);
+#endif
+		if (iw_get_stats (nm_dev_sock_get_fd (sk), iface, &stats, &range, has_range) == 0)
+		{
+			percent = wireless_qual_to_percent (&stats.qual, (const iwqual *)(&self->priv->max_qual),
+					(const iwqual *)(&self->priv->avg_qual));
+		}
+		nm_dev_sock_close (sk);
+	}
+
+	/* Try to smooth out the strength.  Atmel cards, for example, will give no strength
+	 * one second and normal strength the next.
+	 */
+	if ((percent == -1) && (++self->priv->invalid_strength_counter <= 3))
+		percent = self->priv->strength;
+	else
+		self->priv->invalid_strength_counter = 0;
+
+	if (percent != self->priv->strength)
+		nm_dbus_signal_device_strength_change (app_data->dbus_connection, self, percent);
+
+	self->priv->strength = percent;
+
+out:
+	nm_unlock_mutex (self->priv->scan_mutex, __func__);
+}
+
+
 static guint nm_wireless_scan_interval_to_seconds (NMWirelessScanInterval interval)
 {
 	guint seconds;
@@ -336,6 +470,7 @@
 	g_return_val_if_fail (self != NULL, TRUE);
 
 	nm_device_802_11_wireless_update_signal_strength (self);
+	nm_device_802_11_wireless_update_bssid (self);
 
 	return TRUE;
 }
@@ -1119,80 +1254,6 @@
 
 
 /*
- * nm_device_802_11_wireless_update_signal_strength
- *
- * Update the device's idea of the strength of its connection to the
- * current access point.
- *
- */
-void
-nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
-{
-	NMData *		app_data;
-	gboolean		has_range = FALSE;
-	NMSock *		sk;
-	iwrange		range;
-	iwstats		stats;
-	int			percent = -1;
-
-	g_return_if_fail (self != NULL);
-
-	app_data = nm_device_get_app_data (NM_DEVICE (self));
-	g_assert (app_data);
-
-	/* Grab the scan lock since our strength is meaningless during a scan. */
-	if (!nm_try_acquire_mutex (self->priv->scan_mutex, __FUNCTION__))
-		return;
-
-	/* If we aren't the active device, we don't really have a signal strength
-	 * that would mean anything.
-	 */
-	if (!nm_device_get_act_request (NM_DEVICE (self)))
-	{
-		self->priv->strength = -1;
-		goto out;
-	}
-
-	if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL)))
-	{
-		const char *iface = nm_device_get_iface (NM_DEVICE (self));
-
-		memset (&range, 0, sizeof (iwrange));
-		memset (&stats, 0, sizeof (iwstats));
-#ifdef IOCTL_DEBUG
-	nm_info ("%s: About to GET 'iwrange'.", iface);
-#endif
-		has_range = (iw_get_range_info (nm_dev_sock_get_fd (sk), iface, &range) >= 0);
-#ifdef IOCTL_DEBUG
-	nm_info ("%s: About to GET 'iwstats'.", iface);
-#endif
-		if (iw_get_stats (nm_dev_sock_get_fd (sk), iface, &stats, &range, has_range) == 0)
-		{
-			percent = wireless_qual_to_percent (&stats.qual, (const iwqual *)(&self->priv->max_qual),
-					(const iwqual *)(&self->priv->avg_qual));
-		}
-		nm_dev_sock_close (sk);
-	}
-
-	/* Try to smooth out the strength.  Atmel cards, for example, will give no strength
-	 * one second and normal strength the next.
-	 */
-	if ((percent == -1) && (++self->priv->invalid_strength_counter <= 3))
-		percent = self->priv->strength;
-	else
-		self->priv->invalid_strength_counter = 0;
-
-	if (percent != self->priv->strength)
-		nm_dbus_signal_device_strength_change (app_data->dbus_connection, self, percent);
-
-	self->priv->strength = percent;
-
-out:
-	nm_unlock_mutex (self->priv->scan_mutex, __func__);
-}
-
-
-/*
  * nm_device_get_essid
  *
  * If a device is wireless, return the essid that it is attempting
@@ -1512,7 +1573,7 @@
 	if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL)))
 	{
 #ifdef IOCTL_DEBUG
-	nm_info ("%s: About to GET IWAP.", iface);
+		nm_info ("%s: About to GET IWAP.", iface);
 #endif
 		if (iw_get_ext (nm_dev_sock_get_fd (sk), iface, SIOCGIWAP, &wrq) >= 0)
 			memcpy (bssid, &(wrq.u.ap_addr.sa_data), sizeof (struct ether_addr));
Index: src/nm-device-802-11-wireless.h
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/nm-device-802-11-wireless.h,v
retrieving revision 1.6.2.2
diff -u -r1.6.2.2 nm-device-802-11-wireless.h
--- src/nm-device-802-11-wireless.h	9 Mar 2006 21:51:24 -0000	1.6.2.2
+++ src/nm-device-802-11-wireless.h	17 May 2006 14:56:10 -0000
@@ -120,8 +120,6 @@
 
 gint8	nm_device_802_11_wireless_get_signal_strength (NMDevice80211Wireless *self);
 
-void		nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self);
-
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]