1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! High level node abstraction on top of Fuchsia's Stash service.
//! Allows to insert structured, hierarchical data into a Stash backed
//! store.

use {
    anyhow::Error,
    async_trait::async_trait,
    std::collections::HashMap,
    wlan_stash_constants::{NetworkIdentifier, PersistentData},
};

pub mod policy;
mod stash_store;
mod storage_store;

#[async_trait]
trait Store: Send + Sync {
    /// Flushes all changes. Blocks until the flush is complete.
    async fn flush(&self) -> Result<(), Error>;

    /// Deletes the whole store.
    async fn delete_store(&mut self) -> Result<(), Error>;

    /// Update the network configs of a given network identifier to persistent storage, deleting the
    /// key entirely if the new list of configs is empty.  This does *not* flush the change.
    async fn write(
        &self,
        id: &NetworkIdentifier,
        network_configs: &[PersistentData],
    ) -> Result<(), Error>;

    /// Load all saved network configs from stash. Will create HashMap of network configs by SSID
    /// as saved in the stash. If something in stash can't be interpreted, we ignore it.
    async fn load(&self) -> Result<HashMap<NetworkIdentifier, Vec<PersistentData>>, Error>;
}

#[cfg(test)]
mod tests {
    use {
        fuchsia_zircon::AsHandleRef,
        std::sync::atomic::{AtomicU64, Ordering},
        wlan_stash_constants::{NetworkIdentifier, SecurityType, StashedSsid},
    };

    /// Returns a new ID that is guaranteed to be unique (which is required since the tests run in
    /// parallel).
    pub fn new_stash_id() -> String {
        static COUNTER: AtomicU64 = AtomicU64::new(0);
        format!(
            "{}-{}",
            fuchsia_runtime::process_self().get_koid().unwrap().raw_koid(),
            COUNTER.fetch_add(1, Ordering::Relaxed)
        )
    }

    pub fn network_id(
        ssid: impl Into<StashedSsid>,
        security_type: SecurityType,
    ) -> NetworkIdentifier {
        NetworkIdentifier { ssid: ssid.into(), security_type }
    }
}