Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.10.1 #20

Merged
merged 3 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "i3stat"
version = "0.10.0"
version = "0.10.1"
edition = "2021"
authors = ["acheronfail <[email protected]>"]
description = "A lightweight and batteries-included status_command for i3 and sway"
Expand Down
4 changes: 4 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ build *args:
_lbuild:
cargo lbuild --all

# runs rustfmt with nightly to enable all its features
fmt:
rustup run nightly cargo fmt

# run `i3stat` in the terminal and interact with it
dev *args: _lbuild
cd ./scripts/node && RUST_BACKTRACE=1 RUST_LOG=i3stat=trace yarn dev "$@"
Expand Down
14 changes: 14 additions & 0 deletions src/util/netlink/nl80211/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,20 @@ pub enum Nl80211Bss {
}
impl neli::consts::genl::NlAttrType for Nl80211Bss {}

/// The BSS status is a BSS attribute in scan dumps, which indicates the status
/// the interface has wrt. this BSS.
#[neli::neli_enum(serialized_type = "u32")]
pub enum Nl80211BssStatus {
/// Authenticated with this BSS. Note that this is no longer used since
/// cfg80211 no longer keeps track of whether or not authentication was done
/// with a given BSS.
Authenticated = 0,
/// Associated with this BSS.
Associated = 1,
/// Joined to this IBSS.
IbssJoined = 2,
}

#[neli::neli_enum(serialized_type = "u32")]
pub enum Nl80211IfType {
/// unspecified type, driver decides
Expand Down
93 changes: 60 additions & 33 deletions src/util/netlink/nl80211/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,10 @@ use neli::utils::Groups;
use tokio::sync::OnceCell;

use self::enums::{
Nl80211Attribute,
Nl80211Bss,
Nl80211Command,
Nl80211IfType,
Nl80211StationInfo,
Nl80211Attribute, Nl80211Bss, Nl80211Command, Nl80211IfType, Nl80211StationInfo,
};
use super::NetlinkInterface;
use crate::util::nl80211::enums::Nl80211BssStatus;
use crate::util::{MacAddr, Result};

// init ------------------------------------------------------------------------
Expand All @@ -52,7 +49,10 @@ async fn init_socket() -> Result<Nl80211Socket> {
}

async fn init_family(socket: &NlRouter) -> Result<u16> {
Ok(socket.resolve_genl_family(NL80211_FAMILY_NAME).await?)
let id = socket.resolve_genl_family(NL80211_FAMILY_NAME).await?;
log::debug!("nl80211 family id: {id}");

Ok(id)
}

// util ------------------------------------------------------------------------
Expand Down Expand Up @@ -95,6 +95,14 @@ async fn genl80211_send(
.get_or_try_init(|| init_family(socket))
.await?;

log::trace!(
"genl80211_send: cmd={cmd:?}, flags={flags:?}, attrs={:02x?}",
attrs
.iter()
.map(|attr| (attr.nla_type().nla_type(), attr.nla_payload().as_ref()))
.collect::<Vec<_>>()
);

// create generic netlink message
let genl_payload: Nl80211Payload = {
let mut builder = GenlmsghdrBuilder::default().version(1).cmd(cmd);
Expand All @@ -106,6 +114,7 @@ async fn genl80211_send(
};

// send it to netlink

Ok(socket
.send::<_, _, u16, Nl80211Payload>(family_id, flags, NlPayload::Payload(genl_payload))
.await?)
Expand Down Expand Up @@ -334,45 +343,63 @@ async fn get_scan(
)
.await?;

// look for our requested data inside netlink's results
// look for our requested data inside netlink's results - GetScan returns a list of scanned stations...
while let Some(result) = recv.next().await as NextNl80211 {
match result {
Ok(msg) => {
if let NlPayload::Payload(gen_msg) = msg.nl_payload() {
let attr_handle = gen_msg.attrs().get_attr_handle();

// extract the `Nl80211Bss` attributes so we can inspect them
if let Ok(bss_attrs) =
attr_handle.get_nested_attributes::<Nl80211Bss>(Nl80211Attribute::Bss)
{
// set the ssid if it's not set
if ssid.is_none() {
if let Ok(bytes) = bss_attrs
.get_attr_payload_as_with_len_borrowed::<&[u8]>(
Nl80211Bss::InformationElements,
)
{
log::debug!(
"index {} updating ssid from information elements",
index
);
match ssid_from_ie(bytes) {
Ok(option) => *ssid = option,
Err(e) => log::error!(
"index {} failed to parse information elements: {}",
index,
e
),
}
}
}

if let Ok(bytes) = bss_attrs
// extract the bssid itself
let bssid = match bss_attrs
.get_attr_payload_as_with_len_borrowed::<&[u8]>(Nl80211Bss::Bssid)
.map(|bytes| MacAddr::try_from(bytes))
{
if let Ok(bssid) = MacAddr::try_from(bytes) {
log::debug!("index {} found bssid: {}", index, bssid);
return Ok(Some(bssid));
Ok(Ok(mac_addr)) => mac_addr,
// if we can't find a bssid, then keep looking for another one
_ => continue,
};

// NOTE: this is the important part - we find the bssid that the device is currently associated
// with! The GetScan can return multiple stations (even when we're connected to one) but we only
// want the information about the station we're currently associated with
if let Ok(Nl80211BssStatus::Associated) =
bss_attrs.get_attr_payload_as::<Nl80211BssStatus>(Nl80211Bss::Status)
{
log::debug!("index {} found associated bssid: {}", index, bssid);

// set the ssid if it's not set already, this works around a quirk in netlink
// see: https://github.com/systemd/systemd/issues/24585
// either way, this seems to be the more "reliable" way of getting the ssid
if ssid.is_none() {
// parse the information elements attributes
if let Ok(bytes) = bss_attrs
.get_attr_payload_as_with_len_borrowed::<&[u8]>(
Nl80211Bss::InformationElements,
)
{
match ssid_from_ie(bytes) {
Ok(option) => {
*ssid = option;
log::debug!(
"index {} updated ssid {:?} from information elements",
index,
ssid
);
}
Err(e) => log::error!(
"index {} failed to parse information elements: {}",
index,
e
),
}
}
}
return Ok(Some(bssid));
}
}
}
Expand Down
11 changes: 9 additions & 2 deletions tests/i3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ use serde_json::Value;
use self::util::x_click;
use crate::i3::util::MouseButton;
use crate::util::{
find_object_containing, get_current_exe, get_exe, get_fakeroot_lib, get_faketime_lib,
wait_for_file, LogOnDropChild, Test, FAKE_TIME,
find_object_containing,
get_current_exe,
get_exe,
get_fakeroot_lib,
get_faketime_lib,
wait_for_file,
LogOnDropChild,
Test,
FAKE_TIME,
};

// start nested x server displays at 10
Expand Down
7 changes: 6 additions & 1 deletion tests/spawn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ use serde_json::Value;
use timeout_readwrite::{TimeoutReadExt, TimeoutReader};

use crate::util::{
get_current_exe, get_fakeroot_lib, get_faketime_lib, LogOnDropChild, Test, FAKE_TIME,
get_current_exe,
get_fakeroot_lib,
get_faketime_lib,
LogOnDropChild,
Test,
FAKE_TIME,
};

/// Convenience struct for running assertions on and communicating with a running instance of the program
Expand Down
Loading