mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-27 05:50:32 +01:00
platform: add the plumbing to get the CSME connection info
This allows to fetch the information about the AP that CSME if connected to. It'll allow us to connect to the exact same AP and shaving off the scan from the connection, improving the connection time.
This commit is contained in:
parent
721008f1c3
commit
526c4b3293
7 changed files with 140 additions and 0 deletions
|
|
@ -8536,6 +8536,14 @@ wifi_set_wake_on_wlan(NMPlatform *platform, int ifindex, _NMSettingWirelessWakeO
|
|||
return nm_wifi_utils_set_wake_on_wlan(wifi_data, wowl);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wifi_get_csme_conn_info(NMPlatform *platform, int ifindex, NMPlatformCsmeConnInfo *out_conn_info)
|
||||
{
|
||||
WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE);
|
||||
|
||||
return nm_wifi_utils_get_csme_conn_info(wifi_data, out_conn_info);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
|
|
@ -9954,6 +9962,7 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
|
|||
platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running;
|
||||
platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan;
|
||||
platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan;
|
||||
platform_class->wifi_get_csme_conn_info = wifi_get_csme_conn_info;
|
||||
|
||||
platform_class->mesh_get_channel = mesh_get_channel;
|
||||
platform_class->mesh_set_channel = mesh_set_channel;
|
||||
|
|
|
|||
|
|
@ -3061,6 +3061,18 @@ nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirel
|
|||
return klass->wifi_set_wake_on_wlan(self, ifindex, wowl);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_wifi_get_csme_conn_info(NMPlatform *self,
|
||||
int ifindex,
|
||||
NMPlatformCsmeConnInfo *out_conn_info)
|
||||
{
|
||||
_CHECK_SELF(self, klass, FALSE);
|
||||
|
||||
g_return_val_if_fail(ifindex > 0, FALSE);
|
||||
|
||||
return klass->wifi_get_csme_conn_info(self, ifindex, out_conn_info);
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_platform_mesh_get_channel(NMPlatform *self, int ifindex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,14 @@ typedef void (*NMPlatformAsyncCallback)(GError *error, gpointer user_data);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NMPlatformCsmeConnInfo {
|
||||
guint8 ssid[32];
|
||||
guint32 channel;
|
||||
NMEtherAddr addr;
|
||||
guint8 sta_cipher;
|
||||
guint8 auth_mode;
|
||||
} NMPlatformCsmeConnInfo;
|
||||
|
||||
typedef enum {
|
||||
NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV,
|
||||
NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE,
|
||||
|
|
@ -1204,6 +1212,9 @@ typedef struct {
|
|||
gboolean (*wifi_set_wake_on_wlan)(NMPlatform *self,
|
||||
int ifindex,
|
||||
_NMSettingWirelessWakeOnWLan wowl);
|
||||
gboolean (*wifi_get_csme_conn_info)(NMPlatform *self,
|
||||
int ifindex,
|
||||
NMPlatformCsmeConnInfo *out_conn_info);
|
||||
|
||||
guint32 (*mesh_get_channel)(NMPlatform *self, int ifindex);
|
||||
gboolean (*mesh_set_channel)(NMPlatform *self, int ifindex, guint32 channel);
|
||||
|
|
@ -2028,6 +2039,9 @@ void nm_platform_wifi_indicate_addressing_running(NMPlatform *self, int ifindex,
|
|||
_NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan(NMPlatform *self, int ifindex);
|
||||
gboolean
|
||||
nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirelessWakeOnWLan wowl);
|
||||
gboolean nm_platform_wifi_get_csme_conn_info(NMPlatform *self,
|
||||
int ifindex,
|
||||
NMPlatformCsmeConnInfo *out_conn_info);
|
||||
|
||||
guint32 nm_platform_mesh_get_channel(NMPlatform *self, int ifindex);
|
||||
gboolean nm_platform_mesh_set_channel(NMPlatform *self, int ifindex, guint32 channel);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include <linux/nl80211.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#include "linux-headers/nl80211-vnd-intel.h"
|
||||
|
||||
#include "libnm-log-core/nm-logging.h"
|
||||
#include "libnm-platform/nm-netlink.h"
|
||||
#include "nm-wifi-utils-private.h"
|
||||
|
|
@ -817,6 +819,90 @@ nla_put_failure:
|
|||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
||||
struct nl80211_csme_conn_info {
|
||||
NMWifiUtilsNl80211 *self;
|
||||
NMPlatformCsmeConnInfo *conn_info;
|
||||
};
|
||||
|
||||
static int
|
||||
nl80211_csme_conn_event_handler(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct nl80211_csme_conn_info *info = arg;
|
||||
NMPlatformCsmeConnInfo *out_conn_info = info->conn_info;
|
||||
NMWifiUtilsNl80211 *self = info->self;
|
||||
struct genlmsghdr *gnlh = (void *) nlmsg_data(nlmsg_hdr(msg));
|
||||
struct nlattr *tb[NL80211_ATTR_MAX + 1];
|
||||
struct nlattr *data;
|
||||
struct nlattr *attrs[NUM_IWL_MVM_VENDOR_ATTR];
|
||||
int err;
|
||||
|
||||
static const struct nla_policy iwl_vendor_policy[NUM_IWL_MVM_VENDOR_ATTR] = {
|
||||
[IWL_MVM_VENDOR_ATTR_AUTH_MODE] = {.type = NLA_U32},
|
||||
[IWL_MVM_VENDOR_ATTR_SSID] = {.type = NLA_UNSPEC, .maxlen = NM_IW_ESSID_MAX_SIZE},
|
||||
[IWL_MVM_VENDOR_ATTR_STA_CIPHER] = {.type = NLA_U32},
|
||||
[IWL_MVM_VENDOR_ATTR_CHANNEL_NUM] = {.type = NLA_U8},
|
||||
[IWL_MVM_VENDOR_ATTR_ADDR] = {.type = NLA_UNSPEC, .minlen = ETH_ALEN, .maxlen = ETH_ALEN},
|
||||
};
|
||||
|
||||
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
|
||||
data = tb[NL80211_ATTR_VENDOR_DATA];
|
||||
|
||||
*out_conn_info = (NMPlatformCsmeConnInfo){};
|
||||
|
||||
err = nla_parse_nested(attrs, MAX_IWL_MVM_VENDOR_ATTR, data, iwl_vendor_policy);
|
||||
if (err) {
|
||||
_LOGD("IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO Failed to parse CSME connection info: %s",
|
||||
nm_strerror(err));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (attrs[IWL_MVM_VENDOR_ATTR_AUTH_MODE])
|
||||
out_conn_info->auth_mode = nla_get_u8(attrs[IWL_MVM_VENDOR_ATTR_AUTH_MODE]);
|
||||
|
||||
if (attrs[IWL_MVM_VENDOR_ATTR_SSID])
|
||||
memcpy(out_conn_info->ssid,
|
||||
nla_data(attrs[IWL_MVM_VENDOR_ATTR_SSID]),
|
||||
nla_len(attrs[IWL_MVM_VENDOR_ATTR_SSID]));
|
||||
|
||||
if (attrs[IWL_MVM_VENDOR_ATTR_STA_CIPHER])
|
||||
out_conn_info->sta_cipher = nla_get_u8(attrs[IWL_MVM_VENDOR_ATTR_STA_CIPHER]);
|
||||
|
||||
if (attrs[IWL_MVM_VENDOR_ATTR_CHANNEL_NUM])
|
||||
out_conn_info->channel = nla_get_u8(attrs[IWL_MVM_VENDOR_ATTR_CHANNEL_NUM]);
|
||||
|
||||
if (attrs[IWL_MVM_VENDOR_ATTR_ADDR])
|
||||
memcpy(&out_conn_info->addr,
|
||||
nla_data(attrs[IWL_MVM_VENDOR_ATTR_ADDR]),
|
||||
sizeof(out_conn_info->addr));
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wifi_nl80211_intel_vnd_get_csme_conn_info(NMWifiUtils *data, NMPlatformCsmeConnInfo *out_conn_info)
|
||||
{
|
||||
NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
|
||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||
int err;
|
||||
struct nl80211_csme_conn_info conn_info = {
|
||||
.self = self,
|
||||
.conn_info = out_conn_info,
|
||||
};
|
||||
|
||||
msg = nl80211_alloc_msg(self, NL80211_CMD_VENDOR, 0);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, INTEL_OUI);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD, IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO);
|
||||
|
||||
err = nl80211_send_and_recv(self, msg, nl80211_csme_conn_event_handler, &conn_info);
|
||||
if (err < 0)
|
||||
_LOGD("IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO request failed: %s", nm_strerror(err));
|
||||
|
||||
return err >= 0;
|
||||
|
||||
nla_put_failure:
|
||||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_wifi_utils_nl80211_init(NMWifiUtilsNl80211 *self)
|
||||
{}
|
||||
|
|
@ -841,6 +927,7 @@ nm_wifi_utils_nl80211_class_init(NMWifiUtilsNl80211Class *klass)
|
|||
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;
|
||||
wifi_utils_class->get_csme_conn_info = wifi_nl80211_intel_vnd_get_csme_conn_info;
|
||||
}
|
||||
|
||||
NMWifiUtils *
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#define __WIFI_UTILS_PRIVATE_H__
|
||||
|
||||
#include "nm-wifi-utils.h"
|
||||
#include "libnm-platform/nm-platform.h"
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
|
|
@ -53,6 +54,8 @@ typedef struct {
|
|||
gboolean (*set_mesh_ssid)(NMWifiUtils *data, const guint8 *ssid, gsize len);
|
||||
|
||||
gboolean (*indicate_addressing_running)(NMWifiUtils *data, gboolean running);
|
||||
|
||||
gboolean (*get_csme_conn_info)(NMWifiUtils *data, NMPlatformCsmeConnInfo *out_conn_info);
|
||||
} NMWifiUtilsClass;
|
||||
|
||||
struct NMWifiUtils {
|
||||
|
|
|
|||
|
|
@ -157,6 +157,17 @@ nm_wifi_utils_is_wifi(int dirfd, const char *ifname)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_wifi_utils_get_csme_conn_info(NMWifiUtils *data, NMPlatformCsmeConnInfo *out_conn_info)
|
||||
{
|
||||
NMWifiUtilsClass *klass;
|
||||
|
||||
g_return_val_if_fail(data != NULL, FALSE);
|
||||
|
||||
klass = NM_WIFI_UTILS_GET_CLASS(data);
|
||||
return klass->get_csme_conn_info ? klass->get_csme_conn_info(data, out_conn_info) : FALSE;
|
||||
}
|
||||
|
||||
/* OLPC Mesh-only functions */
|
||||
|
||||
guint32
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ _NMSettingWirelessWakeOnWLan nm_wifi_utils_get_wake_on_wlan(NMWifiUtils *data);
|
|||
|
||||
gboolean nm_wifi_utils_set_wake_on_wlan(NMWifiUtils *data, _NMSettingWirelessWakeOnWLan wowl);
|
||||
|
||||
struct _NMPlatformCsmeConnInfo;
|
||||
gboolean nm_wifi_utils_get_csme_conn_info(NMWifiUtils *data,
|
||||
struct _NMPlatformCsmeConnInfo *out_conn_info);
|
||||
|
||||
/* OLPC Mesh-only functions */
|
||||
guint32 nm_wifi_utils_get_mesh_channel(NMWifiUtils *data);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue