wlancfg_lib/client/roaming/
lib.rs1use crate::client::config_management::Credential;
6use crate::client::types;
7use crate::util::historical_list::{HistoricalList, Timestamped};
8use crate::util::pseudo_energy::{EwmaSignalData, RssiVelocity};
9use log::error;
10use wlan_common::sequestered::Sequestered;
11use {
12 fidl_fuchsia_wlan_common as fidl_common, fidl_fuchsia_wlan_internal as fidl_internal,
13 fidl_fuchsia_wlan_sme as fidl_sme, fuchsia_async as fasync,
14};
15
16pub const ROAMING_CHANNEL_BUFFER_SIZE: usize = 100;
17pub const NUM_PLATFORM_MAX_ROAMS_PER_DAY: usize = 5;
21pub const TIMESPAN_TO_LIMIT_SCANS: zx::MonotonicDuration = zx::MonotonicDuration::from_hours(24);
22
23#[derive(Clone, Copy, Debug)]
25pub enum RoamingPolicy {
26 Disabled,
27 Enabled { profile: RoamingProfile, mode: RoamingMode },
28}
29
30#[derive(Clone, Copy, Debug)]
31pub enum RoamingProfile {
32 Stationary,
33}
34#[derive(Clone, Copy, Default, Debug, PartialEq)]
35pub enum RoamingMode {
36 MetricsOnly,
37 #[default]
38 CanRoam,
39}
40
41impl From<String> for RoamingPolicy {
42 fn from(string: String) -> Self {
43 match string.as_str() {
44 "enabled_stationary_can_roam" => RoamingPolicy::Enabled {
45 profile: RoamingProfile::Stationary,
46 mode: RoamingMode::CanRoam,
47 },
48 "enabled_stationary_metrics_only" => RoamingPolicy::Enabled {
49 profile: RoamingProfile::Stationary,
50 mode: RoamingMode::MetricsOnly,
51 },
52 "disabled" => RoamingPolicy::Disabled,
53 _ => {
54 error!(
55 "Unknown roaming profile string ({}). Continuing with roaming disabled.",
56 string
57 );
58 RoamingPolicy::Disabled
59 }
60 }
61 }
62}
63#[derive(Clone)]
67#[cfg_attr(test, derive(Debug, PartialEq))]
68pub struct RoamingConnectionData {
69 pub ap_state: types::ApState,
70 pub network_identifier: types::NetworkIdentifier,
71 pub credential: Credential,
72 pub signal_data: EwmaSignalData,
73 pub rssi_velocity: RssiVelocity,
74 pub previous_roam_scan_data: PreviousRoamScanData,
75}
76impl RoamingConnectionData {
77 pub fn new(
78 ap_state: types::ApState,
79 network_identifier: types::NetworkIdentifier,
80 credential: Credential,
81 signal_data: EwmaSignalData,
82 ) -> Self {
83 Self {
84 ap_state: ap_state.clone(),
85 network_identifier,
86 credential,
87 signal_data,
88 rssi_velocity: RssiVelocity::new(signal_data.ewma_rssi.get()),
89 previous_roam_scan_data: PreviousRoamScanData::new(ap_state.tracked.signal.rssi_dbm),
90 }
91 }
92}
93#[derive(Clone)]
95#[cfg_attr(test, derive(Debug, PartialEq))]
96pub struct PreviousRoamScanData {
97 pub(crate) time: fasync::MonotonicInstant,
98 pub rssi: f64,
100}
101impl PreviousRoamScanData {
102 pub fn new(rssi: impl Into<f64>) -> Self {
103 Self { time: fasync::MonotonicInstant::now(), rssi: rssi.into() }
104 }
105}
106
107#[derive(Clone, Debug)]
110pub enum RoamTriggerData {
111 SignalReportInd(fidl_internal::SignalReportIndication),
112}
113
114#[derive(Clone)]
116#[cfg_attr(test, derive(Debug, PartialEq))]
117pub enum RoamTriggerDataOutcome {
118 Noop,
119 RoamSearch {
120 scan_type: fidl_common::ScanType,
121 network_identifier: types::NetworkIdentifier,
122 credential: Credential,
123 current_security: types::SecurityTypeDetailed,
124 reasons: Vec<RoamReason>,
125 },
126}
127
128#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
129pub enum RoamReason {
130 RssiBelowThreshold,
131 SnrBelowThreshold,
132}
133
134#[derive(Clone)]
135#[cfg_attr(test, derive(Debug, PartialEq))]
136pub struct PolicyRoamRequest {
137 pub candidate: types::ScannedCandidate,
138 pub reasons: Vec<RoamReason>,
139}
140impl From<PolicyRoamRequest> for fidl_sme::RoamRequest {
141 fn from(item: PolicyRoamRequest) -> Self {
142 fidl_sme::RoamRequest {
143 bss_description: Sequestered::release(item.candidate.bss.bss_description),
144 }
145 }
146}
147
148#[derive(Clone)]
150pub struct RoamEvent {
151 time: fasync::MonotonicInstant,
152}
153
154impl RoamEvent {
155 pub fn new_roam_now() -> Self {
156 Self { time: fasync::MonotonicInstant::now() }
157 }
158
159 #[cfg(test)]
160 pub fn new(time: fasync::MonotonicInstant) -> Self {
161 Self { time }
162 }
163}
164
165impl Timestamped for RoamEvent {
166 fn time(&self) -> fasync::MonotonicInstant {
167 self.time
168 }
169}
170
171pub type PastRoamList = HistoricalList<RoamEvent>;