Skip to main content

wlancfg_lib/config_management/
stash_conversion.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use super::network_config::{Credential, NetworkConfig, NetworkIdentifier, SecurityType};
6use crate::client::types as client_types;
7use std::collections::HashMap;
8use wlan_storage::policy as storage;
9
10impl From<storage::NetworkIdentifier> for NetworkIdentifier {
11    fn from(item: storage::NetworkIdentifier) -> Self {
12        Self {
13            ssid: client_types::Ssid::from_bytes_unchecked(item.ssid),
14            security_type: item.security_type.into(),
15        }
16    }
17}
18
19impl From<NetworkIdentifier> for storage::NetworkIdentifier {
20    fn from(item: NetworkIdentifier) -> Self {
21        Self { ssid: item.ssid.into(), security_type: item.security_type.into() }
22    }
23}
24
25impl From<storage::SecurityType> for SecurityType {
26    fn from(item: storage::SecurityType) -> Self {
27        match item {
28            storage::SecurityType::None => SecurityType::None,
29            storage::SecurityType::Wep => SecurityType::Wep,
30            storage::SecurityType::Wpa => SecurityType::Wpa,
31            storage::SecurityType::Wpa2 => SecurityType::Wpa2,
32            storage::SecurityType::Wpa3 => SecurityType::Wpa3,
33        }
34    }
35}
36
37impl From<SecurityType> for storage::SecurityType {
38    fn from(item: SecurityType) -> Self {
39        match item {
40            SecurityType::None => storage::SecurityType::None,
41            SecurityType::Wep => storage::SecurityType::Wep,
42            SecurityType::Wpa => storage::SecurityType::Wpa,
43            SecurityType::Wpa2 => storage::SecurityType::Wpa2,
44            SecurityType::Wpa3 => storage::SecurityType::Wpa3,
45        }
46    }
47}
48
49impl From<storage::Credential> for Credential {
50    fn from(item: storage::Credential) -> Self {
51        match item {
52            storage::Credential::None => Credential::None,
53            storage::Credential::Password(pass) => Credential::Password(pass),
54            storage::Credential::Psk(psk) => Credential::Psk(psk),
55        }
56    }
57}
58
59impl From<Credential> for storage::Credential {
60    fn from(item: Credential) -> Self {
61        match item {
62            Credential::None => storage::Credential::None,
63            Credential::Password(pass) => storage::Credential::Password(pass),
64            Credential::Psk(psk) => storage::Credential::Psk(psk),
65        }
66    }
67}
68
69impl From<NetworkConfig> for storage::PersistentStorageData {
70    fn from(item: NetworkConfig) -> Self {
71        Self {
72            ssid: item.ssid.to_vec(),
73            security_type: item.security_type.into(),
74            credential: item.credential.into(),
75            has_ever_connected: item.has_ever_connected,
76            hidden_probability: if item.hidden_probability
77                == super::network_config::PROB_HIDDEN_DEFAULT
78            {
79                None
80            } else {
81                Some(item.hidden_probability)
82            },
83        }
84    }
85}
86
87/// Convert configs to the persistent data for configs. It takes in a map of NetworkConfigs
88/// corresponding to the way network configs are internally tracked.
89pub fn persistent_data_from_config_map(
90    network_config: &HashMap<NetworkIdentifier, Vec<NetworkConfig>>,
91) -> Vec<storage::PersistentStorageData> {
92    network_config.values().flatten().map(|c| c.clone().into()).collect()
93}
94
95#[cfg(test)]
96mod tests {
97    use super::super::*;
98    use super::*;
99    use test_case::test_case;
100    use wlan_storage::policy as storage;
101
102    #[fuchsia::test]
103    fn network_identifier_to_stash_from_policy() {
104        assert_eq!(
105            storage::NetworkIdentifier::from(NetworkIdentifier {
106                ssid: client_types::Ssid::try_from("ssid").unwrap(),
107                security_type: SecurityType::Wep,
108            }),
109            storage::NetworkIdentifier {
110                ssid: client_types::Ssid::try_from("ssid").unwrap().into(),
111                security_type: storage::SecurityType::Wep,
112            }
113        );
114    }
115
116    #[fuchsia::test]
117    fn network_identifier_to_policy_from_stash() {
118        assert_eq!(
119            NetworkIdentifier::from(storage::NetworkIdentifier {
120                ssid: client_types::Ssid::try_from("ssid").unwrap().into(),
121                security_type: storage::SecurityType::Wep,
122            }),
123            NetworkIdentifier {
124                ssid: client_types::Ssid::try_from("ssid").unwrap(),
125                security_type: SecurityType::Wep
126            }
127        );
128    }
129
130    #[fuchsia::test]
131    fn security_type_to_stash_from_policy() {
132        assert_eq!(storage::SecurityType::from(SecurityType::None), storage::SecurityType::None);
133        assert_eq!(storage::SecurityType::from(SecurityType::Wep), storage::SecurityType::Wep);
134        assert_eq!(storage::SecurityType::from(SecurityType::Wpa), storage::SecurityType::Wpa);
135        assert_eq!(storage::SecurityType::from(SecurityType::Wpa2), storage::SecurityType::Wpa2);
136        assert_eq!(storage::SecurityType::from(SecurityType::Wpa3), storage::SecurityType::Wpa3);
137    }
138
139    #[fuchsia::test]
140    fn security_type_to_policy_from_stash() {
141        assert_eq!(SecurityType::from(storage::SecurityType::None), SecurityType::None);
142        assert_eq!(SecurityType::from(storage::SecurityType::Wep), SecurityType::Wep);
143        assert_eq!(SecurityType::from(storage::SecurityType::Wpa), SecurityType::Wpa);
144        assert_eq!(SecurityType::from(storage::SecurityType::Wpa2), SecurityType::Wpa2);
145        assert_eq!(SecurityType::from(storage::SecurityType::Wpa3), SecurityType::Wpa3);
146    }
147
148    #[fuchsia::test]
149    fn credential_to_stash_from_policy() {
150        assert_eq!(storage::Credential::from(Credential::None), storage::Credential::None);
151        assert_eq!(
152            storage::Credential::from(Credential::Password(b"foo_pass123".to_vec())),
153            storage::Credential::Password(b"foo_pass123".to_vec())
154        );
155        assert_eq!(
156            storage::Credential::from(Credential::Psk(b"foo_psk123".to_vec())),
157            storage::Credential::Psk(b"foo_psk123".to_vec())
158        );
159    }
160
161    #[fuchsia::test]
162    fn credential_to_policy_from_stash() {
163        assert_eq!(Credential::from(storage::Credential::None), Credential::None);
164        assert_eq!(
165            Credential::from(storage::Credential::Password(b"foo_pass123".to_vec())),
166            Credential::Password(b"foo_pass123".to_vec())
167        );
168        assert_eq!(
169            Credential::from(storage::Credential::Password(b"foo_psk123".to_vec())),
170            Credential::Password(b"foo_psk123".to_vec())
171        );
172    }
173
174    #[test_case(true)]
175    #[test_case(false)]
176    #[fuchsia::test(add_test_attr = false)]
177    fn persistent_data_from_network_config_has_connected(has_ever_connected: bool) {
178        // Check that from() works when has_ever_connected is true and false.
179        let ssid = "ssid";
180        let security_type = SecurityType::Wpa3;
181        let stash_security = storage::SecurityType::Wpa3;
182        let id = NetworkIdentifier::try_from(ssid, security_type).unwrap();
183        let credential = Credential::Password(b"foo_pass".to_vec());
184        let network_config = NetworkConfig::new(id, credential, has_ever_connected, None)
185            .expect("failed to create network config");
186        assert_eq!(
187            storage::PersistentStorageData::from(network_config),
188            storage::PersistentStorageData {
189                ssid: ssid.as_bytes().to_vec(),
190                security_type: stash_security,
191                credential: storage::Credential::Password(b"foo_pass".to_vec()),
192                has_ever_connected,
193                hidden_probability: None,
194            }
195        );
196    }
197
198    #[test_case(SecurityType::Wpa, storage::SecurityType::Wpa)]
199    #[fuchsia::test(add_test_attr = false)]
200    fn persistent_data_from_network_config_security(
201        security: SecurityType,
202        storage_security: storage::SecurityType,
203    ) {
204        // Check that from() works for different security types
205        let ssid = "ssid";
206        let id = NetworkIdentifier::try_from(ssid, security).unwrap();
207        let has_ever_connected = true;
208
209        // Use a password for WPA, PSK for WEP, or None for open networks.
210        let (credential, storage_credential) = match security {
211            SecurityType::None => (Credential::None, storage::Credential::None),
212            SecurityType::Wep => {
213                let psk_bytes = vec![1; network_config::WPA_PSK_BYTE_LEN];
214                (Credential::Psk(psk_bytes.clone()), storage::Credential::Psk(psk_bytes))
215            }
216            SecurityType::Wpa | SecurityType::Wpa2 | SecurityType::Wpa3 => (
217                Credential::Password(b"foo_pass".to_vec()),
218                storage::Credential::Password(b"foo_pass".to_vec()),
219            ),
220        };
221
222        let network_config = NetworkConfig::new(id, credential, has_ever_connected, None)
223            .expect("failed to create network config");
224        assert_eq!(
225            storage::PersistentStorageData::from(network_config),
226            storage::PersistentStorageData {
227                ssid: ssid.as_bytes().to_vec(),
228                security_type: storage_security,
229                credential: storage_credential,
230                has_ever_connected,
231                hidden_probability: None,
232            }
233        );
234    }
235
236    #[fuchsia::test]
237    fn test_persistent_data_from_network_config_non_default_hidden_probability() {
238        let id = NetworkIdentifier::try_from("ssid", SecurityType::Wpa3).unwrap();
239        let mut network_config =
240            NetworkConfig::new(id, Credential::Password(b"foo_pass".to_vec()), true, None)
241                .expect("failed to create network config");
242        network_config.hidden_probability = 0.05;
243        assert_eq!(
244            storage::PersistentStorageData::from(network_config),
245            storage::PersistentStorageData {
246                ssid: b"ssid".to_vec(),
247                security_type: storage::SecurityType::Wpa3,
248                credential: storage::Credential::Password(b"foo_pass".to_vec()),
249                has_ever_connected: true,
250                hidden_probability: Some(0.05),
251            }
252        );
253    }
254}