umsh_ux_display_tracker/
wifi.rs

1//! Credential-free WiFi state for the display and its saved-network picker.
2
3pub const MAX_SAVED_NETWORKS: usize = 4;
4
5/// An SSID is an opaque byte string, even when its displayed label is shortened.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct NetworkName {
8    bytes: [u8; 32],
9    len: u8,
10}
11
12impl NetworkName {
13    pub fn new(bytes: &[u8]) -> Option<Self> {
14        if bytes.is_empty() || bytes.len() > 32 {
15            return None;
16        }
17        let mut name = Self {
18            bytes: [0; 32],
19            len: bytes.len() as u8,
20        };
21        name.bytes[..bytes.len()].copy_from_slice(bytes);
22        Some(name)
23    }
24
25    pub fn as_bytes(&self) -> &[u8] {
26        &self.bytes[..usize::from(self.len)]
27    }
28}
29
30#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
31pub enum WifiState {
32    #[default]
33    Off,
34    Disconnected,
35    Connecting,
36    Connected,
37}
38
39/// Only names cross into the UI. The station owns credentials and validation.
40#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
41pub struct WifiMenu {
42    pub enabled: bool,
43    pub state: WifiState,
44    pub network: Option<NetworkName>,
45    pub networks: [Option<NetworkName>; MAX_SAVED_NETWORKS],
46}
47
48impl WifiMenu {
49    pub fn networks(&self) -> impl Iterator<Item = NetworkName> + '_ {
50        self.networks.iter().flatten().copied()
51    }
52}