Re: Changing Auto-Connect feature



Dan,

Thank you so much for your feedback. I've done as you said and  modified the code of real_get_best_auto_connection() in nm-device-wifi.c
I'm having problems figuring out what does this line do: *specific_object = (char *) nm_ap_get_dbus_path (ap); I think it casts a char pointer of the dbus_path to the ap, but I do not know where it is reflected outside of real_get_best_auto_connection() since its output is the connection found to be the best and the "specific object" doesn't get out (I think it is local).

Anyway I've modified the code and think it should do what I want, all but that line I mentioned, since I've commented it.

I'm sending you the code as an attachment, it'd be great if you could check it. It's really short, but I want to make sure I got your suggestion right.

Thank you,

Cheers,

Franco






2010/5/26 Dan Williams <dcbw redhat com>
On Tue, 2010-05-25 at 13:45 -0300, Franco Miceli wrote:
> Hi,
>
> I'm part of a project in Uruguay (Plan Ceibal), that aims to give
> educational connectivity to primary school students
>
> We've been working with the XO platform (Sugar, Fedora 9 -soon 11-),
> and have had the following issue regarding NM auto-connect feature.
>
> We provide connectivity in the school yard via large outdoor wireless
> equipment and indoors with smaller AP. It has come to our attention
> that NM auto-connects to the last AP the XO connected to. Since the
> outdoor equipment is still visible indoors the XO connects to it even
> if it has less quality than the indoor equipment. This gives us
> problems in capacity planning and coverage.
>
> We consider the auto-connect feature to be most useful at the school,
> but we want the choice of connection to be more than just "the last
> one it connected to". Therefore we want to to make some changes to the
> NM code in order to take into consideration other factors such as:
> SNR, loss %, etc.

This is tricky because actually not all kernel drivers really support
good reporting of SNR and loss %.  But in your case since you're
targeting specific hardware where you can assume that the driver reports
the correct values, you can locally patch NetworkManager in a way that
we cannot do upstream.

You want real_get_best_auto_connection() in nm-device-wifi.c.  You're
passed a list of connections that get sorted through.  The list is
already sorted by timestamp.  What you want to do is to run through the
*entire* list (and not stop at the first compatible AP that's found by
nm_ap_check_compatible() near the bottom) and instead keep a pointer to
the "best" connection as you define it.

This is a bit complicated because remember that connections are simply
packages of settings necessary to connect to a specific network, they do
not describe actual wifi APs.  So the basic procedure would be something
like:

NMConnection *best_yet = NULL;
guint32 best_ap_strength = 0;

for each connection in 'connections':
   <do normal device checking up to AP list iteration>

   for each ap in the device's AP list:
       if (nm_ap_check_compatible (ap, connection)) {
           if (nm_ap_get_strength (ap) > best_ap_strength) {
               best_yet = connection;
               best_ap_strength = nm_ap_get_strength (ap);
           }
       }

   return best_yet;

Dan

> We already have the code of the NM OLPC uses on the XO. What we wanted
> to know is where inside all the *.c files to look for this
> functionality and also if anyone has had any experience with this in
> order to give us some advice on how to approach this subject.
>
> Thanks in advance,
>
>
> _______________________________________________
> networkmanager-list mailing list
> networkmanager-list gnome org
> http://mail.gnome.org/mailman/listinfo/networkmanager-list



static NMConnection *
real_get_best_auto_connection (NMDevice *dev,
                               GSList *connections,
                               char **specific_object)
{
	NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
	GSList *iter, *ap_iter;
	NMConnection *best_yet = NULL;
	guint32 best_ap_strength = 0;

	for (iter = connections; iter; iter = g_slist_next (iter)) {
		NMConnection *connection = NM_CONNECTION (iter->data);
		NMSettingConnection *s_con;
		NMSettingWireless *s_wireless;
		const GByteArray *mac;
		NMSettingIP4Config *s_ip4;
		const char *method = NULL;
		

		s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
		if (s_con == NULL)
			continue;
		if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME))
			continue;
		if (!nm_setting_connection_get_autoconnect (s_con))
			continue;

		s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
		if (!s_wireless)
			continue;

		mac = nm_setting_wireless_get_mac_address (s_wireless);
		if (mac && memcmp (mac->data, priv->hw_addr.ether_addr_octet, ETH_ALEN))
				continue;

		/* Use the connection if it's a shared connection */
		s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
		if (s_ip4)
			method = nm_setting_ip4_config_get_method (s_ip4);

		if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED))
			return connection;

		for (ap_iter = priv->ap_list; ap_iter; ap_iter = g_slist_next (ap_iter)) {
			NMAccessPoint *ap = NM_AP (ap_iter->data);
			if (nm_ap_check_compatible (ap, connection)) {
				if (nm_ap_get_strength (ap) > best_ap_strength) {
					best_yet = connection;
				    best_ap_strength = nm_ap_get_strength (ap);
				}
			}

			/*if (nm_ap_check_compatible (ap, connection)) {
				/* All good; connection is usable */
				/**specific_object = (char *) nm_ap_get_dbus_path (ap);
				return connection;
			}*/
		}		
	}
	return best_yet;
}


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