openthread/ot/
dataset.rs

1// Copyright 2021 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 crate::prelude_internal::*;
6
7/// Methods from the [OpenThread "OperationalDataset" Module][1].
8///
9/// [1]: https://openthread.io/reference/group/api-operational-dataset
10pub trait Dataset {
11    /// Functional equivalent of
12    /// [`otsys::otDatasetIsCommissioned`](crate::otsys::otDatasetIsCommissioned).
13    #[must_use]
14    fn is_commissioned(&self) -> bool;
15
16    /// Functional equivalent of
17    /// [`otsys::otDatasetCreateNewNetwork`](crate::otsys::otDatasetCreateNewNetwork).
18    fn dataset_create_new_network(&self, dataset: &mut OperationalDataset) -> Result;
19
20    /// Functional equivalent of [`otsys::otDatasetGetActive`](crate::otsys::otDatasetGetActive).
21    fn dataset_get_active(&self, dataset: &mut OperationalDataset) -> Result;
22
23    /// Functional equivalent of [`otsys::otDatasetSetActive`](crate::otsys::otDatasetSetActive).
24    fn dataset_set_active(&self, dataset: &OperationalDataset) -> Result;
25
26    /// Functional equivalent of [`otsys::otDatasetSetPending`](crate::otsys::otDatasetSetPending).
27    fn dataset_set_pending(&self, dataset: &OperationalDataset) -> Result;
28
29    /// Functional equivalent of [`otsys::otDatasetGetActiveTlvs`](crate::otsys::otDatasetGetActiveTlvs).
30    fn dataset_get_active_tlvs(&self) -> Result<OperationalDatasetTlvs>;
31
32    /// Functional equivalent of [`otsys::otDatasetSetActiveTlvs`](crate::otsys::otDatasetSetActiveTlvs).
33    fn dataset_set_active_tlvs(&self, dataset: &OperationalDatasetTlvs) -> Result;
34
35    /// Functional equivalent of [`otsys::otDatasetGetPendingTlvs`](crate::otsys::otDatasetGetPendingTlvs).
36    fn dataset_get_pending_tlvs(&self) -> Result<OperationalDatasetTlvs>;
37
38    /// Functional equivalent of [`otsys::otDatasetSetPendingTlvs`](crate::otsys::otDatasetSetPendingTlvs).
39    fn dataset_set_pending_tlvs(&self, dataset: &OperationalDatasetTlvs) -> Result;
40
41    /// Functional equivalent of [`otsys::otDatasetSendMgmtPendingSet`](crate::otsys::otDatasetSendMgmtPendingSet).
42    fn dataset_send_mgmt_pending_set<'a, F>(
43        &self,
44        dataset: OperationalDataset,
45        dataset_tlvs: &[u8],
46        f: F,
47    ) -> Result
48    where
49        F: FnOnce(Result) + 'a;
50
51    /// Async version of [`dataset_send_mgmt_pending_set`].
52    fn dataset_send_mgmt_pending_set_async(
53        &self,
54        dataset: OperationalDataset,
55        dataset_tlvs: &[u8],
56    ) -> futures::channel::oneshot::Receiver<Result> {
57        let (sender, receiver) = futures::channel::oneshot::channel();
58
59        if let Err(err) = self.dataset_send_mgmt_pending_set(dataset, dataset_tlvs, move |result| {
60            let _ = sender.send(result);
61        }) {
62            let (err_sender, err_receiver) = futures::channel::oneshot::channel();
63            err_sender.send(Err(err)).unwrap();
64            err_receiver
65        } else {
66            receiver
67        }
68    }
69}
70
71impl<T: Dataset + Boxable> Dataset for ot::Box<T> {
72    fn is_commissioned(&self) -> bool {
73        self.as_ref().is_commissioned()
74    }
75
76    fn dataset_create_new_network(&self, dataset: &mut OperationalDataset) -> Result {
77        self.as_ref().dataset_create_new_network(dataset)
78    }
79
80    fn dataset_get_active(&self, dataset: &mut OperationalDataset) -> Result {
81        self.as_ref().dataset_get_active(dataset)
82    }
83
84    fn dataset_set_active(&self, dataset: &OperationalDataset) -> Result {
85        self.as_ref().dataset_set_active(dataset)
86    }
87
88    fn dataset_set_pending(&self, dataset: &OperationalDataset) -> Result {
89        self.as_ref().dataset_set_pending(dataset)
90    }
91
92    fn dataset_get_active_tlvs(&self) -> Result<OperationalDatasetTlvs> {
93        self.as_ref().dataset_get_active_tlvs()
94    }
95
96    fn dataset_set_active_tlvs(&self, dataset: &OperationalDatasetTlvs) -> Result {
97        self.as_ref().dataset_set_active_tlvs(dataset)
98    }
99
100    fn dataset_get_pending_tlvs(&self) -> Result<OperationalDatasetTlvs> {
101        self.as_ref().dataset_get_pending_tlvs()
102    }
103
104    fn dataset_set_pending_tlvs(&self, dataset: &OperationalDatasetTlvs) -> Result {
105        self.as_ref().dataset_set_pending_tlvs(dataset)
106    }
107
108    fn dataset_send_mgmt_pending_set<'a, F>(
109        &self,
110        dataset: OperationalDataset,
111        dataset_tlvs: &[u8],
112        f: F,
113    ) -> Result
114    where
115        F: FnOnce(Result) + 'a,
116    {
117        self.as_ref().dataset_send_mgmt_pending_set(dataset, dataset_tlvs, f)
118    }
119}
120
121impl Dataset for Instance {
122    fn is_commissioned(&self) -> bool {
123        unsafe { otDatasetIsCommissioned(self.as_ot_ptr()) }
124    }
125
126    fn dataset_create_new_network(&self, dataset: &mut OperationalDataset) -> Result {
127        Error::from(unsafe { otDatasetCreateNewNetwork(self.as_ot_ptr(), dataset.as_ot_mut_ptr()) })
128            .into()
129    }
130
131    fn dataset_get_active(&self, dataset: &mut OperationalDataset) -> Result {
132        Error::from(unsafe { otDatasetGetActive(self.as_ot_ptr(), dataset.as_ot_mut_ptr()) }).into()
133    }
134
135    fn dataset_set_active(&self, dataset: &OperationalDataset) -> Result {
136        Error::from(unsafe { otDatasetSetActive(self.as_ot_ptr(), dataset.as_ot_ptr()) }).into()
137    }
138
139    fn dataset_set_pending(&self, dataset: &OperationalDataset) -> Result {
140        Error::from(unsafe { otDatasetSetPending(self.as_ot_ptr(), dataset.as_ot_ptr()) }).into()
141    }
142
143    fn dataset_get_active_tlvs(&self) -> Result<OperationalDatasetTlvs> {
144        let mut ret = OperationalDatasetTlvs::default();
145
146        Error::from(unsafe { otDatasetGetActiveTlvs(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
147            .into_result()?;
148
149        Ok(ret)
150    }
151
152    fn dataset_set_active_tlvs(&self, dataset: &OperationalDatasetTlvs) -> Result {
153        Error::from(unsafe { otDatasetSetActiveTlvs(self.as_ot_ptr(), dataset.as_ot_ptr()) }).into()
154    }
155
156    fn dataset_get_pending_tlvs(&self) -> Result<OperationalDatasetTlvs> {
157        let mut ret = OperationalDatasetTlvs::default();
158
159        Error::from(unsafe { otDatasetGetPendingTlvs(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
160            .into_result()?;
161
162        Ok(ret)
163    }
164
165    fn dataset_set_pending_tlvs(&self, dataset: &OperationalDatasetTlvs) -> Result {
166        Error::from(unsafe { otDatasetSetPendingTlvs(self.as_ot_ptr(), dataset.as_ot_ptr()) })
167            .into()
168    }
169
170    fn dataset_send_mgmt_pending_set<'a, F>(
171        &self,
172        dataset: OperationalDataset,
173        dataset_tlvs: &[u8],
174        f: F,
175    ) -> Result
176    where
177        F: FnOnce(Result) + 'a,
178    {
179        unsafe extern "C" fn _ot_dataset_mgmt_set_callback<'a, F: FnOnce(Result) + 'a>(
180            err: otError,
181            context: *mut ::std::os::raw::c_void,
182        ) {
183            trace!("_ot_dataset_mgmt_set_callback");
184
185            // Reconstitute our box from the pointer.
186            // SAFETY: The pointer we are passing into `Box::from_raw` came from `Box::leak`.
187            let sender = *Box::<F>::from_raw(context as *mut F);
188
189            sender(ot::Error::from(err).into_result())
190        }
191
192        let dataset_tlvs_len: u8 =
193            dataset_tlvs.len().try_into().map_err(|_| ot::Error::InvalidArgs)?;
194
195        let context = Box::leak(Box::new(f)) as *mut F as *mut ::std::os::raw::c_void;
196
197        unsafe {
198            ot::Error::from(otDatasetSendMgmtPendingSet(
199                self.as_ot_ptr(),
200                dataset.as_ot_ptr(),
201                dataset_tlvs.as_ptr(),
202                dataset_tlvs_len,
203                Some(_ot_dataset_mgmt_set_callback::<F>),
204                context,
205            ))
206            .into_result()?;
207        }
208
209        Ok(())
210    }
211}