wlancfg_lib/util/listener/
access_point.rs1use super::generic::{CurrentStateCache, Listener, Message};
6use crate::access_point::types;
7use fidl_fuchsia_wlan_policy as fidl_policy;
8use futures::channel::mpsc;
9use futures::future::LocalBoxFuture;
10use futures::prelude::*;
11
12#[derive(Copy, Clone, Debug, PartialEq)]
13pub struct ConnectedClientInformation {
14 pub count: u8,
15}
16
17impl From<ConnectedClientInformation> for fidl_policy::ConnectedClientInformation {
18 fn from(connected_client_info: ConnectedClientInformation) -> Self {
19 fidl_policy::ConnectedClientInformation {
20 count: Some(connected_client_info.count),
21 ..Default::default()
22 }
23 }
24}
25
26#[cfg_attr(test, derive(Debug))]
27#[derive(Clone, PartialEq)]
28pub struct ApStatesUpdate {
29 pub access_points: Vec<ApStateUpdate>,
30}
31
32#[cfg_attr(test, derive(Debug))]
33#[derive(Clone, PartialEq)]
34pub struct ApStateUpdate {
35 pub id: types::NetworkIdentifier,
36 pub state: types::OperatingState,
37 pub mode: Option<types::ConnectivityMode>,
38 pub band: Option<types::OperatingBand>,
39 pub frequency: Option<u32>,
40 pub clients: Option<ConnectedClientInformation>,
41}
42
43impl ApStateUpdate {
44 pub fn new(
45 id: types::NetworkIdentifier,
46 state: types::OperatingState,
47 mode: types::ConnectivityMode,
48 band: types::OperatingBand,
49 ) -> Self {
50 ApStateUpdate {
51 id,
52 state,
53 mode: Some(mode),
54 band: Some(band),
55 frequency: None,
56 clients: None,
57 }
58 }
59}
60
61impl From<ApStatesUpdate> for Vec<fidl_policy::AccessPointState> {
62 fn from(ap_updates: ApStatesUpdate) -> Self {
63 ap_updates
64 .access_points
65 .iter()
66 .map(|ap| fidl_policy::AccessPointState {
67 id: Some(fidl_policy::NetworkIdentifier::from(ap.id.clone())),
68 state: Some(fidl_policy::OperatingState::from(ap.state)),
69 mode: ap.mode.map(fidl_policy::ConnectivityMode::from),
70 band: ap.band.map(fidl_policy::OperatingBand::from),
71 frequency: ap.frequency,
72 clients: ap.clients.map(|c| c.into()),
73 ..Default::default()
74 })
75 .collect()
76 }
77}
78
79impl CurrentStateCache for ApStatesUpdate {
80 fn default() -> ApStatesUpdate {
81 ApStatesUpdate { access_points: vec![] }
82 }
83
84 fn merge_in_update(&mut self, update: Self) {
85 self.access_points = update.access_points;
86 }
87
88 fn purge(&mut self) {}
89}
90
91impl Listener<Vec<fidl_policy::AccessPointState>> for fidl_policy::AccessPointStateUpdatesProxy {
92 fn notify_listener(
93 self,
94 update: Vec<fidl_policy::AccessPointState>,
95 ) -> LocalBoxFuture<'static, Option<Box<Self>>> {
96 let fut = async move {
97 let fut = self.on_access_point_state_update(&update);
98 fut.await.ok().map(|()| Box::new(self))
99 };
100 fut.boxed()
101 }
102}
103
104pub type ApMessage = Message<fidl_policy::AccessPointStateUpdatesProxy, ApStatesUpdate>;
106pub type ApListenerMessageSender = mpsc::UnboundedSender<ApMessage>;
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111 use crate::client::types::Ssid;
112 use fidl_fuchsia_wlan_policy as fidl_policy;
113
114 fn create_network_id() -> types::NetworkIdentifier {
115 types::NetworkIdentifier {
116 ssid: Ssid::try_from("test").unwrap(),
117 security_type: types::SecurityType::None,
118 }
119 }
120
121 #[fuchsia::test]
122 fn merge_updates() {
123 let mut current_state_cache = ApStatesUpdate::default();
124 assert_eq!(current_state_cache, ApStatesUpdate { access_points: vec![] });
125
126 let update = ApStatesUpdate {
128 access_points: vec![{
129 ApStateUpdate {
130 id: create_network_id(),
131 state: types::OperatingState::Starting,
132 mode: Some(types::ConnectivityMode::Unrestricted),
133 band: Some(types::OperatingBand::Any),
134 frequency: None,
135 clients: Some(ConnectedClientInformation { count: 0 }),
136 }
137 }],
138 };
139 current_state_cache.merge_in_update(update);
140
141 assert_eq!(
142 current_state_cache,
143 ApStatesUpdate {
144 access_points: vec![{
145 ApStateUpdate {
146 id: create_network_id(),
147 state: types::OperatingState::Starting,
148 mode: Some(types::ConnectivityMode::Unrestricted),
149 band: Some(types::OperatingBand::Any),
150 frequency: None,
151 clients: Some(ConnectedClientInformation { count: 0 }),
152 }
153 }],
154 }
155 );
156 }
157
158 #[fuchsia::test]
159 fn into_fidl() {
160 let state = ApStatesUpdate {
161 access_points: vec![{
162 ApStateUpdate {
163 id: create_network_id(),
164 state: types::OperatingState::Starting,
165 mode: Some(types::ConnectivityMode::Unrestricted),
166 band: Some(types::OperatingBand::Any),
167 frequency: Some(200),
168 clients: Some(ConnectedClientInformation { count: 1 }),
169 }
170 }],
171 };
172 let fidl_state: Vec<fidl_policy::AccessPointState> = state.into();
173 assert_eq!(
174 fidl_state,
175 vec![fidl_policy::AccessPointState {
176 id: Some(fidl_policy::NetworkIdentifier {
177 ssid: Ssid::try_from("test").unwrap().to_vec(),
178 type_: fidl_policy::SecurityType::None,
179 }),
180 state: Some(fidl_policy::OperatingState::Starting),
181 mode: Some(fidl_policy::ConnectivityMode::Unrestricted),
182 band: Some(fidl_policy::OperatingBand::Any),
183 frequency: Some(200),
184 clients: Some(fidl_policy::ConnectedClientInformation {
185 count: Some(1),
186 ..Default::default()
187 }),
188 ..Default::default()
189 }]
190 );
191 }
192}