diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2019-09-05 13:51:09 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2019-09-07 17:22:00 +0200 |
commit | cc96771f32f55c57f56c7e70f937d9837411c44d (patch) | |
tree | e5b8e0272cb5c7dad552a09c17dc51f5151abbbb | |
parent | 11cf082a6233a5c2f17da1b49457a66266062678 (diff) | |
download | NetworkManager-cc96771f32f55c57f56c7e70f937d9837411c44d.tar.gz |
wifi: add OLPC Mesh support via nl80211
-rw-r--r-- | src/platform/wifi/nm-wifi-utils-nl80211.c | 67 |
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 * |