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 <[email protected]>
> 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
> > [email protected]
> > 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;
}
_______________________________________________
networkmanager-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/networkmanager-list