platform: Add a wifi_get_station utility

Merge nm_platform_wifi_get_bssid, nm_platform_wifi_get_quality,
nm_platform_wifi_get_rate into one utility, nm_platform_wifi_get_station
that uses the single NL80211_CMD_GET_STATION command dump when the
nl80211 driver is used.  With wext each function mapped to one ioctl
while with nl80211 all three can be obtained with one netlink command.
The new function should use the minimum number of calls with either
driver.
This commit is contained in:
Andrew Zaborowski 2020-11-17 16:17:13 +01:00 committed by Thomas Haller
parent f37db2c2a5
commit e5a2520069
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
7 changed files with 121 additions and 0 deletions

View file

@ -8309,6 +8309,17 @@ wifi_get_rate(NMPlatform *platform, int ifindex)
return nm_wifi_utils_get_rate(wifi_data);
}
static gboolean
wifi_get_station(NMPlatform *platform,
int ifindex,
guint8 * out_bssid,
int * out_quality,
guint32 * out_rate)
{
WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE);
return nm_wifi_utils_get_station(wifi_data, out_bssid, out_quality, out_rate);
}
static NM80211Mode
wifi_get_mode(NMPlatform *platform, int ifindex)
{
@ -9673,6 +9684,7 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
platform_class->wifi_get_frequency = wifi_get_frequency;
platform_class->wifi_get_quality = wifi_get_quality;
platform_class->wifi_get_rate = wifi_get_rate;
platform_class->wifi_get_station = wifi_get_station;
platform_class->wifi_get_mode = wifi_get_mode;
platform_class->wifi_set_mode = wifi_set_mode;
platform_class->wifi_set_powersave = wifi_set_powersave;

View file

@ -3091,6 +3091,20 @@ nm_platform_wifi_get_rate(NMPlatform *self, int ifindex)
return klass->wifi_get_rate(self, ifindex);
}
gboolean
nm_platform_wifi_get_station(NMPlatform *self,
int ifindex,
guint8 * out_bssid,
int * out_quality,
guint32 * out_rate)
{
_CHECK_SELF(self, klass, FALSE);
g_return_val_if_fail(ifindex > 0, FALSE);
return klass->wifi_get_station(self, ifindex, out_bssid, out_quality, out_rate);
}
NM80211Mode
nm_platform_wifi_get_mode(NMPlatform *self, int ifindex)
{

View file

@ -1182,6 +1182,11 @@ typedef struct {
gboolean (*wifi_get_capabilities)(NMPlatform * self,
int ifindex,
NMDeviceWifiCapabilities *caps);
gboolean (*wifi_get_station)(NMPlatform *self,
int ifindex,
guint8 * out_bssid,
int * out_quality,
guint32 * out_rate);
gboolean (*wifi_get_bssid)(NMPlatform *self, int ifindex, guint8 *bssid);
guint32 (*wifi_get_frequency)(NMPlatform *self, int ifindex);
int (*wifi_get_quality)(NMPlatform *self, int ifindex);
@ -1966,6 +1971,11 @@ gboolean nm_platform_wifi_get_bssid(NMPlatform *self, int ifindex, guint8 *bs
guint32 nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex);
int nm_platform_wifi_get_quality(NMPlatform *self, int ifindex);
guint32 nm_platform_wifi_get_rate(NMPlatform *self, int ifindex);
gboolean nm_platform_wifi_get_station(NMPlatform *self,
int ifindex,
guint8 * out_bssid,
int * out_quality,
guint32 * out_rate);
NM80211Mode nm_platform_wifi_get_mode(NMPlatform *self, int ifindex);
void nm_platform_wifi_set_mode(NMPlatform *self, int ifindex, NM80211Mode mode);
void nm_platform_wifi_set_powersave(NMPlatform *self, int ifindex, guint32 powersave);

View file

@ -545,6 +545,33 @@ wifi_nl80211_get_qual(NMWifiUtils *data)
return self->sta_info.signal;
}
static gboolean
wifi_nl80211_get_station(NMWifiUtils *data, guint8 *out_bssid, int *out_quality, guint32 *out_rate)
{
NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data;
nm_auto_nlmsg struct nl_msg *msg = NULL;
struct nl80211_station_info sta_info = {};
msg = nl80211_alloc_msg(self, NL80211_CMD_GET_STATION, NLM_F_DUMP);
nl80211_send_and_recv(self, msg, nl80211_station_dump_handler, &sta_info);
if (!sta_info.valid || (out_quality && !sta_info.signal_valid)
|| (out_rate && !sta_info.txrate_valid))
return FALSE;
if (out_bssid)
memcpy(out_bssid, sta_info.bssid, ETH_ALEN);
if (out_quality)
*out_quality = sta_info.signal;
if (out_rate)
*out_rate = sta_info.txrate;
return TRUE;
}
static gboolean
wifi_nl80211_indicate_addressing_running(NMWifiUtils *data, gboolean running)
{
@ -860,6 +887,7 @@ nm_wifi_utils_nl80211_class_init(NMWifiUtilsNl80211Class *klass)
wifi_utils_class->get_bssid = wifi_nl80211_get_bssid;
wifi_utils_class->get_rate = wifi_nl80211_get_rate;
wifi_utils_class->get_qual = wifi_nl80211_get_qual;
wifi_utils_class->get_station = wifi_nl80211_get_station;
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;

View file

@ -41,6 +41,18 @@ typedef struct {
*/
int (*get_qual)(NMWifiUtils *data);
/*
* @out_bssid: must be NULL or an ETH_ALEN-byte buffer
* @out_quality: receives signal strength percentage 0 - 100% for the current BSSID, if not NULL
* @out_rate: receives current bitrate in Kbps if not NULL
*
* Returns %TRUE on succcess, %FALSE on errors or if not associated.
*/
gboolean (*get_station)(NMWifiUtils *data,
guint8 * out_bssid,
int * out_quality,
guint32 * out_rate);
/* OLPC Mesh-only functions */
guint32 (*get_mesh_channel)(NMWifiUtils *data);

View file

@ -155,6 +155,39 @@ nm_wifi_utils_get_qual(NMWifiUtils *data)
return NM_WIFI_UTILS_GET_CLASS(data)->get_qual(data);
}
gboolean
nm_wifi_utils_get_station(NMWifiUtils *data, guint8 *out_bssid, int *out_quality, guint32 *out_rate)
{
NMWifiUtilsClass *klass;
g_return_val_if_fail(data != NULL, FALSE);
klass = NM_WIFI_UTILS_GET_CLASS(data);
if (klass->get_station != NULL)
return klass->get_station(data, out_bssid, out_quality, out_rate);
if (out_bssid) {
memset(out_bssid, 0, ETH_ALEN);
if (!klass->get_bssid(data, out_bssid))
return FALSE;
}
if (out_quality) {
*out_quality = klass->get_qual(data);
if (*out_quality < 0)
return FALSE;
}
if (out_rate) {
*out_rate = klass->get_rate(data);
if (*out_rate == 0)
return FALSE;
}
return TRUE;
}
gboolean
nm_wifi_utils_is_wifi(int dirfd, const char *ifname)
{

View file

@ -52,6 +52,18 @@ guint32 nm_wifi_utils_get_rate(NMWifiUtils *data);
/* Returns quality 0 - 100% on success, or -1 on error */
int nm_wifi_utils_get_qual(NMWifiUtils *data);
/*
* @out_bssid: must be NULL or an ETH_ALEN-byte buffer
* @out_quality: receives signal quality in 0 - 100% range if not NULL
* @out_rate: receives current bitrate in Kbps if not NULL
*
* Returns %TRUE on succcess.
*/
gboolean nm_wifi_utils_get_station(NMWifiUtils *data,
guint8 * out_bssid,
int * out_quality,
guint32 * out_rate);
/* Tells the driver DHCP or SLAAC is running */
gboolean nm_wifi_utils_indicate_addressing_running(NMWifiUtils *data, gboolean running);