wifi: merge branch 'balrog-kun:platform-wifi-common-call'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/683
This commit is contained in:
Thomas Haller 2020-11-19 13:38:26 +01:00
commit 909533efb4
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
9 changed files with 145 additions and 164 deletions

View file

@ -433,26 +433,26 @@ periodic_update(NMDeviceIwd *self)
platform = nm_device_get_platform(NM_DEVICE(self));
/* TODO: obtain this through the net.connman.iwd.SignalLevelAgent API.
* For now we're waking up for the rate updates anyway.
/* TODO: obtain quality through the net.connman.iwd.SignalLevelAgent API.
* For now we're waking up for the rate/BSSID updates anyway.
*/
percent = nm_platform_wifi_get_quality(platform, ifindex);
if (percent >= 0 && percent <= 100) {
if (nm_wifi_ap_set_strength(priv->current_ap, (gint8) percent)) {
#if NM_MORE_LOGGING
ap_changed = TRUE;
#endif
}
if (!nm_platform_wifi_get_station(platform, ifindex, bssid, &percent, &new_rate)) {
_LOGD(LOGD_WIFI, "BSSID / quality / rate platform query failed");
return;
}
if (nm_wifi_ap_set_strength(priv->current_ap, (gint8) percent)) {
#if NM_MORE_LOGGING
ap_changed = TRUE;
#endif
}
new_rate = nm_platform_wifi_get_rate(platform, ifindex);
if (new_rate != priv->rate) {
priv->rate = new_rate;
_notify(self, PROP_BITRATE);
}
if (nm_platform_wifi_get_bssid(platform, ifindex, bssid)
&& nm_ethernet_address_is_valid(bssid, ETH_ALEN)
if (nm_ethernet_address_is_valid(bssid, ETH_ALEN)
&& memcmp(bssid, priv->current_ap_bssid, ETH_ALEN)) {
gs_free char *bssid_str = NULL;
memcpy(priv->current_ap_bssid, bssid, ETH_ALEN);

View file

@ -728,6 +728,7 @@ periodic_update(NMDeviceWifi *self)
NMDeviceWifiPrivate *priv;
int ifindex;
guint32 new_rate;
int percent;
if (nm_device_get_state(NM_DEVICE(self)) != NM_DEVICE_STATE_ACTIVATED) {
/* BSSID and signal strength have meaningful values only if the device
@ -757,23 +758,22 @@ periodic_update(NMDeviceWifi *self)
if (ifindex <= 0)
g_return_if_reached();
if (priv->current_ap) {
int percent;
percent = nm_platform_wifi_get_quality(nm_device_get_platform(NM_DEVICE(self)), ifindex);
if (percent >= 0 && percent <= 100) {
if (nm_wifi_ap_set_strength(priv->current_ap, (gint8) percent)) {
if (priv->current_ap
&& nm_platform_wifi_get_station(nm_device_get_platform(NM_DEVICE(self)),
ifindex,
NULL,
&percent,
&new_rate)) {
if (nm_wifi_ap_set_strength(priv->current_ap, (gint8) percent)) {
#if NM_MORE_LOGGING
_ap_dump(self, LOGL_TRACE, priv->current_ap, "updated", 0);
_ap_dump(self, LOGL_TRACE, priv->current_ap, "updated", 0);
#endif
}
}
}
new_rate = nm_platform_wifi_get_rate(nm_device_get_platform(NM_DEVICE(self)), ifindex);
if (new_rate != priv->rate) {
priv->rate = new_rate;
_notify(self, PROP_BITRATE);
if (new_rate != priv->rate) {
priv->rate = new_rate;
_notify(self, PROP_BITRATE);
}
}
}
@ -3369,31 +3369,36 @@ activation_success_handler(NMDevice *device)
g_warn_if_fail(priv->current_ap);
if (priv->current_ap) {
if (nm_wifi_ap_get_fake(priv->current_ap)) {
gboolean ap_changed = FALSE;
gboolean ap_changed = FALSE;
gboolean update_bssid = !nm_wifi_ap_get_address(priv->current_ap);
gboolean update_rate = !nm_wifi_ap_get_max_bitrate(priv->current_ap);
guint8 bssid[ETH_ALEN];
guint32 rate;
/* If the activation AP hasn't been seen by the supplicant in a scan
* yet, it will be "fake". This usually happens for Ad-Hoc and
* AP-mode connections. Fill in the details from the device itself
* until the supplicant sends the scan result.
*/
if (!nm_wifi_ap_get_address(priv->current_ap)) {
guint8 bssid[ETH_ALEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
gs_free char *bssid_str = NULL;
if (nm_platform_wifi_get_bssid(nm_device_get_platform(device), ifindex, bssid)
&& nm_ethernet_address_is_valid(bssid, ETH_ALEN)) {
bssid_str = nm_utils_hwaddr_ntoa(bssid, ETH_ALEN);
ap_changed |= nm_wifi_ap_set_address(priv->current_ap, bssid_str);
}
}
if (!nm_wifi_ap_get_freq(priv->current_ap))
ap_changed |= nm_wifi_ap_set_freq(
priv->current_ap,
nm_platform_wifi_get_frequency(nm_device_get_platform(device), ifindex));
if (!nm_wifi_ap_get_max_bitrate(priv->current_ap))
ap_changed |= nm_wifi_ap_set_max_bitrate(
priv->current_ap,
nm_platform_wifi_get_rate(nm_device_get_platform(device), ifindex));
if ((update_bssid || update_rate)
&& nm_platform_wifi_get_station(nm_device_get_platform(device),
ifindex,
update_bssid ? bssid : NULL,
NULL,
update_rate ? &rate : NULL)) {
if (update_bssid && nm_ethernet_address_is_valid(bssid, ETH_ALEN)) {
gs_free char *bssid_str = NULL;
bssid_str = nm_utils_hwaddr_ntoa(bssid, ETH_ALEN);
ap_changed |= nm_wifi_ap_set_address(priv->current_ap, bssid_str);
}
if (update_rate)
ap_changed |= nm_wifi_ap_set_max_bitrate(priv->current_ap, rate);
}
if (ap_changed)
_ap_dump(self, LOGL_DEBUG, priv->current_ap, "updated", 0);

View file

@ -8281,13 +8281,6 @@ wifi_get_capabilities(NMPlatform *platform, int ifindex, NMDeviceWifiCapabilitie
return TRUE;
}
static gboolean
wifi_get_bssid(NMPlatform *platform, int ifindex, guint8 *bssid)
{
WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE);
return nm_wifi_utils_get_bssid(wifi_data, bssid);
}
static guint32
wifi_get_frequency(NMPlatform *platform, int ifindex)
{
@ -8296,17 +8289,14 @@ wifi_get_frequency(NMPlatform *platform, int ifindex)
}
static gboolean
wifi_get_quality(NMPlatform *platform, int ifindex)
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_qual(wifi_data);
}
static guint32
wifi_get_rate(NMPlatform *platform, int ifindex)
{
WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, FALSE);
return nm_wifi_utils_get_rate(wifi_data);
return nm_wifi_utils_get_station(wifi_data, out_bssid, out_quality, out_rate);
}
static NM80211Mode
@ -9669,10 +9659,8 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
platform_class->infiniband_partition_delete = infiniband_partition_delete;
platform_class->wifi_get_capabilities = wifi_get_capabilities;
platform_class->wifi_get_bssid = wifi_get_bssid;
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

@ -3051,16 +3051,6 @@ nm_platform_wifi_get_capabilities(NMPlatform *self, int ifindex, NMDeviceWifiCap
return klass->wifi_get_capabilities(self, ifindex, caps);
}
gboolean
nm_platform_wifi_get_bssid(NMPlatform *self, int ifindex, guint8 *bssid)
{
_CHECK_SELF(self, klass, FALSE);
g_return_val_if_fail(ifindex > 0, FALSE);
return klass->wifi_get_bssid(self, ifindex, bssid);
}
guint32
nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex)
{
@ -3071,24 +3061,18 @@ nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex)
return klass->wifi_get_frequency(self, ifindex);
}
int
nm_platform_wifi_get_quality(NMPlatform *self, int ifindex)
gboolean
nm_platform_wifi_get_station(NMPlatform *self,
int ifindex,
guint8 * out_bssid,
int * out_quality,
guint32 * out_rate)
{
_CHECK_SELF(self, klass, 0);
_CHECK_SELF(self, klass, FALSE);
g_return_val_if_fail(ifindex > 0, 0);
g_return_val_if_fail(ifindex > 0, FALSE);
return klass->wifi_get_quality(self, ifindex);
}
guint32
nm_platform_wifi_get_rate(NMPlatform *self, int ifindex)
{
_CHECK_SELF(self, klass, 0);
g_return_val_if_fail(ifindex > 0, 0);
return klass->wifi_get_rate(self, ifindex);
return klass->wifi_get_station(self, ifindex, out_bssid, out_quality, out_rate);
}
NM80211Mode

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);
@ -1962,10 +1967,12 @@ gboolean nm_platform_link_tun_get_properties(NMPlatform * self,
gboolean
nm_platform_wifi_get_capabilities(NMPlatform *self, int ifindex, NMDeviceWifiCapabilities *caps);
gboolean nm_platform_wifi_get_bssid(NMPlatform *self, int ifindex, guint8 *bssid);
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

@ -41,16 +41,6 @@
} \
G_STMT_END
struct nl80211_station_info {
gboolean valid;
guint8 bssid[ETH_ALEN];
guint32 txrate;
gboolean txrate_valid;
guint8 signal;
gboolean signal_valid;
gint64 timestamp;
};
typedef struct {
NMWifiUtils parent;
struct nl_sock *nl_sock;
@ -59,8 +49,6 @@ typedef struct {
int num_freqs;
int phy;
bool can_wowlan : 1;
struct nl80211_station_info sta_info;
} NMWifiUtilsNl80211;
typedef struct {
@ -422,6 +410,15 @@ nl80211_xbm_to_percent(gint32 xbm, guint32 divisor)
/ ((float) SIGNAL_MAX_DBM - (float) NOISE_FLOOR_DBM));
}
struct nl80211_station_info {
gboolean valid;
guint8 bssid[ETH_ALEN];
guint32 txrate;
gboolean txrate_valid;
guint8 signal;
gboolean signal_valid;
};
static int
nl80211_station_dump_handler(struct nl_msg *msg, void *arg)
{
@ -496,53 +493,31 @@ nl80211_station_dump_handler(struct nl_msg *msg, void *arg)
return NL_SKIP;
}
static void
nl80211_get_sta_info(NMWifiUtilsNl80211 *self)
static gboolean
wifi_nl80211_get_station(NMWifiUtils *data, guint8 *out_bssid, int *out_quality, guint32 *out_rate)
{
nm_auto_nlmsg struct nl_msg *msg = NULL;
gint64 now = nm_utils_get_monotonic_timestamp_msec();
if (self->sta_info.valid && now - self->sta_info.timestamp < 500)
return;
memset(&self->sta_info, 0, sizeof(self->sta_info));
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, &self->sta_info);
self->sta_info.timestamp = now;
}
nl80211_send_and_recv(self, msg, nl80211_station_dump_handler, &sta_info);
static gboolean
wifi_nl80211_get_bssid(NMWifiUtils *data, guint8 *out_bssid)
{
NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
if (!sta_info.valid || (out_quality && !sta_info.signal_valid)
|| (out_rate && !sta_info.txrate_valid))
return FALSE;
nl80211_get_sta_info(self);
if (out_bssid)
memcpy(out_bssid, sta_info.bssid, ETH_ALEN);
if (self->sta_info.valid)
memcpy(out_bssid, self->sta_info.bssid, ETH_ALEN);
if (out_quality)
*out_quality = sta_info.signal;
return self->sta_info.valid;
}
if (out_rate)
*out_rate = sta_info.txrate;
static guint32
wifi_nl80211_get_rate(NMWifiUtils *data)
{
NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
nl80211_get_sta_info(self);
return self->sta_info.txrate;
}
static int
wifi_nl80211_get_qual(NMWifiUtils *data)
{
NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data;
nl80211_get_sta_info(self);
return self->sta_info.signal;
return TRUE;
}
static gboolean
@ -857,9 +832,7 @@ nm_wifi_utils_nl80211_class_init(NMWifiUtilsNl80211Class *klass)
wifi_utils_class->set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan,
wifi_utils_class->get_freq = wifi_nl80211_get_freq;
wifi_utils_class->find_freq = wifi_nl80211_find_freq;
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

@ -132,27 +132,36 @@ nm_wifi_utils_find_freq(NMWifiUtils *data, const guint32 *freqs)
}
gboolean
nm_wifi_utils_get_bssid(NMWifiUtils *data, guint8 *out_bssid)
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);
g_return_val_if_fail(out_bssid != NULL, FALSE);
memset(out_bssid, 0, ETH_ALEN);
return NM_WIFI_UTILS_GET_CLASS(data)->get_bssid(data, out_bssid);
}
klass = NM_WIFI_UTILS_GET_CLASS(data);
guint32
nm_wifi_utils_get_rate(NMWifiUtils *data)
{
g_return_val_if_fail(data != NULL, 0);
return NM_WIFI_UTILS_GET_CLASS(data)->get_rate(data);
}
if (klass->get_station != NULL)
return klass->get_station(data, out_bssid, out_quality, out_rate);
int
nm_wifi_utils_get_qual(NMWifiUtils *data)
{
g_return_val_if_fail(data != NULL, 0);
return NM_WIFI_UTILS_GET_CLASS(data)->get_qual(data);
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

View file

@ -43,14 +43,17 @@ guint32 nm_wifi_utils_get_freq(NMWifiUtils *data);
* Frequencies are specified in MHz. */
guint32 nm_wifi_utils_find_freq(NMWifiUtils *data, const guint32 *freqs);
/* out_bssid must be ETH_ALEN bytes */
gboolean nm_wifi_utils_get_bssid(NMWifiUtils *data, guint8 *out_bssid);
/* Returns current bitrate in Kbps */
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);