summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2019-09-05 13:51:09 +0200
committerLubomir Rintel <lkundrak@v3.sk>2019-09-07 17:22:00 +0200
commitcc96771f32f55c57f56c7e70f937d9837411c44d (patch)
treee5b8e0272cb5c7dad552a09c17dc51f5151abbbb
parent11cf082a6233a5c2f17da1b49457a66266062678 (diff)
wifi: add OLPC Mesh support via nl80211
-rw-r--r--src/platform/wifi/nm-wifi-utils-nl80211.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/nm-wifi-utils-nl80211.c
index 33c4e1d31d..24ff2fb5df 100644
--- a/src/platform/wifi/nm-wifi-utils-nl80211.c
+++ b/src/platform/wifi/nm-wifi-utils-nl80211.c
@@ -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 *