wifi: add OLPC Mesh support via nl80211

This commit is contained in:
Lubomir Rintel
2019-09-05 13:51:09 +02:00
parent 11cf082a62
commit cc96771f32

View File

@@ -706,6 +706,7 @@ struct nl80211_device_info {
int phy;
guint32 *freqs;
int num_freqs;
guint32 freq;
guint32 caps;
gboolean can_scan;
gboolean can_scan_ssid;
@@ -767,6 +768,11 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
info->phy = nla_get_u32 (tb[NL80211_ATTR_WIPHY]);
if (tb[NL80211_ATTR_WIPHY_FREQ])
info->freq = nla_get_u32 (tb[NL80211_ATTR_WIPHY_FREQ]);
else
info->freq = 0;
if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) {
info->can_scan_ssid =
nla_get_u8 (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) > 0;
@@ -915,6 +921,64 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
return NL_SKIP;
}
static guint32
wifi_nl80211_get_mesh_channel (NMWifiUtils *data)
{
NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
nm_auto_nlmsg struct nl_msg *msg = NULL;
struct nl80211_device_info device_info = { .self = self };
int i;
msg = nl80211_alloc_msg (self, NL80211_CMD_GET_WIPHY, 0);
if (nl80211_send_and_recv (self, msg, nl80211_wiphy_info_handler,
&device_info) < 0) {
_LOGW ("NL80211_CMD_GET_WIPHY request failed");
return 0;
}
for (i = 0; i < self->num_freqs; i++) {
if (device_info.freq == self->freqs[i])
return i + 1;
}
return 0;
}
static gboolean
wifi_nl80211_set_mesh_channel (NMWifiUtils *data, guint32 channel)
{
NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
nm_auto_nlmsg struct nl_msg *msg = NULL;
int err;
if (channel > self->num_freqs)
return FALSE;
msg = nl80211_alloc_msg (self, NL80211_CMD_SET_WIPHY, 0);
NLA_PUT_U32 (msg, NL80211_ATTR_WIPHY_FREQ, self->freqs[channel - 1]);
err = nl80211_send_and_recv (self, msg, NULL, NULL);
return err >= 0;
nla_put_failure:
g_return_val_if_reached (FALSE);
}
static gboolean
wifi_nl80211_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len)
{
NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
nm_auto_nlmsg struct nl_msg *msg = NULL;
int err;
msg = nl80211_alloc_msg (self, NL80211_CMD_SET_INTERFACE, 0);
NLA_PUT (msg, NL80211_ATTR_MESH_ID, len, ssid);
err = nl80211_send_and_recv (self, msg, NULL, NULL);
return err >= 0;
nla_put_failure:
g_return_val_if_reached (FALSE);
}
static void
nm_wifi_utils_nl80211_init (NMWifiUtilsNl80211 *self)
{
@@ -939,6 +1003,9 @@ nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass)
wifi_utils_class->get_rate = wifi_nl80211_get_rate;
wifi_utils_class->get_qual = wifi_nl80211_get_qual;
wifi_utils_class->indicate_addressing_running = wifi_nl80211_indicate_addressing_running;
wifi_utils_class->get_mesh_channel = wifi_nl80211_get_mesh_channel;
wifi_utils_class->set_mesh_channel = wifi_nl80211_set_mesh_channel;
wifi_utils_class->set_mesh_ssid = wifi_nl80211_set_mesh_ssid;
}
NMWifiUtils *