Skip to main content

openthread/ot/
net_data.rs

1// Copyright 2022 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/// The maximum length of Thread network data, in bytes.
8pub const MAX_NET_DATA_LEN: usize = 255;
9
10/// Iterator type for on-mesh prefixes in network data.
11#[allow(missing_debug_implementations)]
12pub struct OnMeshPrefixIterator<'a, T: ?Sized> {
13    ot_instance: &'a T,
14    ot_iter: otNetworkDataIterator,
15}
16
17impl<T: ?Sized + NetData> Iterator for OnMeshPrefixIterator<'_, T> {
18    type Item = BorderRouterConfig;
19    fn next(&mut self) -> Option<Self::Item> {
20        self.ot_instance.iter_next_on_mesh_prefix(&mut self.ot_iter)
21    }
22}
23
24/// Iterator type for external routes in network data.
25#[allow(missing_debug_implementations)]
26pub struct ExternalRouteIterator<'a, T: ?Sized> {
27    ot_instance: &'a T,
28    ot_iter: otNetworkDataIterator,
29}
30
31impl<T: ?Sized + NetData> Iterator for ExternalRouteIterator<'_, T> {
32    type Item = ExternalRouteConfig;
33    fn next(&mut self) -> Option<Self::Item> {
34        self.ot_instance.iter_next_external_route(&mut self.ot_iter)
35    }
36}
37
38/// Iterator type for services in network data.
39#[allow(missing_debug_implementations)]
40pub struct ServiceIterator<'a, T: ?Sized> {
41    ot_instance: &'a T,
42    ot_iter: otNetworkDataIterator,
43}
44
45impl<T: ?Sized + NetData> Iterator for ServiceIterator<'_, T> {
46    type Item = ServiceConfig;
47    fn next(&mut self) -> Option<Self::Item> {
48        self.ot_instance.iter_next_service(&mut self.ot_iter)
49    }
50}
51
52/// Iterator type for lowpan context info in network data.
53#[allow(missing_debug_implementations)]
54pub struct LowpanContextInfoIterator<'a, T: ?Sized> {
55    ot_instance: &'a T,
56    ot_iter: otNetworkDataIterator,
57}
58
59impl<T: ?Sized + NetData> Iterator for LowpanContextInfoIterator<'_, T> {
60    type Item = LowpanContextInfo;
61    fn next(&mut self) -> Option<Self::Item> {
62        self.ot_instance.iter_next_lowpan_context_info(&mut self.ot_iter)
63    }
64}
65
66/// Methods from the [OpenThread "NetData" Module][1].
67///
68/// [1]: https://openthread.io/reference/group/api-thread-general
69pub trait NetData {
70    /// Functional equivalent of [`otsys::otNetDataGet`](crate::otsys::otNetDataGet).
71    fn net_data_get<'a>(&self, stable: bool, data: &'a mut [u8]) -> Result<&'a [u8]>;
72
73    /// Same as [`net_data_get`], but returns the net data as a vector.
74    fn net_data_as_vec(&self, stable: bool) -> Result<Vec<u8>> {
75        let mut ret = vec![0; MAX_NET_DATA_LEN];
76
77        let len = self.net_data_get(stable, ret.as_mut_slice())?.len();
78
79        ret.truncate(len);
80
81        Ok(ret)
82    }
83
84    /// Functional equivalent of [`otsys::otNetDataGetVersion`](crate::otsys::otNetDataGetVersion).
85    fn net_data_get_version(&self) -> u8;
86
87    /// Functional equivalent of
88    /// [`otsys::otNetDataGetStableVersion`](crate::otsys::otNetDataGetStableVersion).
89    fn net_data_get_stable_version(&self) -> u8;
90
91    /// Functional equivalent of
92    /// [`otsys::otNetDataGetCommissioningDataset`](crate::otsys::otNetDataGetCommissioningDataset).
93    fn net_data_get_commissioning_dataset(&self, dataset: &mut CommissioningDataset);
94
95    /// Functional equivalent of [`otsys::otNetDataGetNextOnMeshPrefix`](crate::otsys::otNetDataGetNextOnMeshPrefix).
96    fn iter_next_on_mesh_prefix(
97        &self,
98        ot_iter: &mut otNetworkDataIterator,
99    ) -> Option<BorderRouterConfig>;
100
101    /// Functional equivalent of [`otsys::otNetDataGetNextRoute`](crate::otsys::otNetDataGetNextRoute).
102    fn iter_next_external_route(
103        &self,
104        ot_iter: &mut otNetworkDataIterator,
105    ) -> Option<ExternalRouteConfig>;
106
107    /// Functional equivalent of [`otsys::otNetDataGetNextService`](crate::otsys::otNetDataGetNextService).
108    fn iter_next_service(&self, ot_iter: &mut otNetworkDataIterator) -> Option<ServiceConfig>;
109
110    /// Functional equivalent of [`otsys::otNetDataGetNextLowpanContextInfo`](crate::otsys::otNetDataGetNextLowpanContextInfo).
111    fn iter_next_lowpan_context_info(
112        &self,
113        ot_iter: &mut otNetworkDataIterator,
114    ) -> Option<LowpanContextInfo>;
115
116    /// Returns an iterator for iterating over on-mesh prefixes.
117    fn iter_on_mesh_prefixes(&self) -> OnMeshPrefixIterator<'_, Self> {
118        OnMeshPrefixIterator { ot_instance: self, ot_iter: OT_NETWORK_DATA_ITERATOR_INIT }
119    }
120
121    /// Returns an iterator for iterating over external routes.
122    fn iter_external_routes(&self) -> ExternalRouteIterator<'_, Self> {
123        ExternalRouteIterator { ot_instance: self, ot_iter: OT_NETWORK_DATA_ITERATOR_INIT }
124    }
125
126    /// Returns an iterator for iterating over services.
127    fn iter_services(&self) -> ServiceIterator<'_, Self> {
128        ServiceIterator { ot_instance: self, ot_iter: OT_NETWORK_DATA_ITERATOR_INIT }
129    }
130
131    /// Returns an iterator for iterating over lowpan context info.
132    fn iter_lowpan_contexts_info(&self) -> LowpanContextInfoIterator<'_, Self> {
133        LowpanContextInfoIterator { ot_instance: self, ot_iter: OT_NETWORK_DATA_ITERATOR_INIT }
134    }
135}
136
137impl<T: NetData + Boxable> NetData for ot::Box<T> {
138    fn net_data_get<'a>(&self, stable: bool, data: &'a mut [u8]) -> Result<&'a [u8]> {
139        self.as_ref().net_data_get(stable, data)
140    }
141
142    fn net_data_get_version(&self) -> u8 {
143        self.as_ref().net_data_get_version()
144    }
145
146    fn net_data_get_stable_version(&self) -> u8 {
147        self.as_ref().net_data_get_version()
148    }
149
150    fn net_data_get_commissioning_dataset(&self, dataset: &mut CommissioningDataset) {
151        self.as_ref().net_data_get_commissioning_dataset(dataset);
152    }
153
154    fn iter_next_on_mesh_prefix(
155        &self,
156        ot_iter: &mut otNetworkDataIterator,
157    ) -> Option<BorderRouterConfig> {
158        self.as_ref().iter_next_on_mesh_prefix(ot_iter)
159    }
160
161    fn iter_next_external_route(
162        &self,
163        ot_iter: &mut otNetworkDataIterator,
164    ) -> Option<ExternalRouteConfig> {
165        self.as_ref().iter_next_external_route(ot_iter)
166    }
167
168    fn iter_next_service(&self, ot_iter: &mut otNetworkDataIterator) -> Option<ServiceConfig> {
169        self.as_ref().iter_next_service(ot_iter)
170    }
171
172    fn iter_next_lowpan_context_info(
173        &self,
174        ot_iter: &mut otNetworkDataIterator,
175    ) -> Option<LowpanContextInfo> {
176        self.as_ref().iter_next_lowpan_context_info(ot_iter)
177    }
178}
179
180impl NetData for Instance {
181    fn net_data_get<'a>(&self, stable: bool, data: &'a mut [u8]) -> Result<&'a [u8]> {
182        let mut len: u8 = data.len().min(MAX_NET_DATA_LEN).try_into().unwrap();
183
184        Error::from(unsafe {
185            otNetDataGet(self.as_ot_ptr(), stable, data.as_mut_ptr(), (&mut len) as *mut u8)
186        })
187        .into_result()?;
188
189        Ok(&data[..(len as usize)])
190    }
191
192    fn net_data_get_version(&self) -> u8 {
193        unsafe { otNetDataGetVersion(self.as_ot_ptr()) }
194    }
195
196    fn net_data_get_stable_version(&self) -> u8 {
197        unsafe { otNetDataGetStableVersion(self.as_ot_ptr()) }
198    }
199
200    fn net_data_get_commissioning_dataset(&self, dataset: &mut CommissioningDataset) {
201        unsafe { otNetDataGetCommissioningDataset(self.as_ot_ptr(), dataset.as_ot_mut_ptr()) }
202    }
203
204    fn iter_next_on_mesh_prefix(
205        &self,
206        ot_iter: &mut otNetworkDataIterator,
207    ) -> Option<BorderRouterConfig> {
208        unsafe {
209            let mut ret = BorderRouterConfig::default();
210            match Error::from(otNetDataGetNextOnMeshPrefix(
211                self.as_ot_ptr(),
212                ot_iter as *mut otNetworkDataIterator,
213                ret.as_ot_mut_ptr(),
214            )) {
215                Error::NotFound => None,
216                Error::None => Some(ret),
217                err => panic!("Unexpected error from otNetDataGetNextOnMeshPrefix: {err:?}"),
218            }
219        }
220    }
221
222    fn iter_next_external_route(
223        &self,
224        ot_iter: &mut otNetworkDataIterator,
225    ) -> Option<ExternalRouteConfig> {
226        unsafe {
227            let mut ret = ExternalRouteConfig::default();
228            match Error::from(otNetDataGetNextRoute(
229                self.as_ot_ptr(),
230                ot_iter as *mut otNetworkDataIterator,
231                ret.as_ot_mut_ptr(),
232            )) {
233                Error::NotFound => None,
234                Error::None => Some(ret),
235                err => panic!("Unexpected error from otNetDataGetNextRoute: {err:?}"),
236            }
237        }
238    }
239
240    fn iter_next_service(&self, ot_iter: &mut otNetworkDataIterator) -> Option<ServiceConfig> {
241        unsafe {
242            let mut ret = ServiceConfig::default();
243            match Error::from(otNetDataGetNextService(
244                self.as_ot_ptr(),
245                ot_iter as *mut otNetworkDataIterator,
246                ret.as_ot_mut_ptr(),
247            )) {
248                Error::NotFound => None,
249                Error::None => Some(ret),
250                err => panic!("Unexpected error from otNetDataGetNextService: {err:?}"),
251            }
252        }
253    }
254
255    fn iter_next_lowpan_context_info(
256        &self,
257        ot_iter: &mut otNetworkDataIterator,
258    ) -> Option<LowpanContextInfo> {
259        unsafe {
260            let mut ret = LowpanContextInfo::default();
261            match Error::from(otNetDataGetNextLowpanContextInfo(
262                self.as_ot_ptr(),
263                ot_iter as *mut otNetworkDataIterator,
264                ret.as_ot_mut_ptr(),
265            )) {
266                Error::NotFound => None,
267                Error::None => Some(ret),
268                err => panic!("Unexpected error from otNetDataGetNextLowpanContextInfo: {err:?}"),
269            }
270        }
271    }
272}