Skip to main content

openthread/ot/
radio.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/// Methods from the [OpenThread "Radio" Module][1].
8///
9/// [1]: https://openthread.io/reference/group/radio-operation
10pub trait Radio {
11    /// Functional equivalent of
12    /// [`otsys::otPlatRadioGetCoexMetrics`](crate::otsys::otPlatRadioGetCoexMetrics).
13    fn get_coex_metrics(&self) -> Result<RadioCoexMetrics>;
14
15    /// Functional equivalent of
16    /// [`otsys::otPlatRadioGetRssi`](crate::otsys::otPlatRadioGetRssi).
17    fn get_rssi(&self) -> Decibels;
18
19    /// Functional equivalent of
20    /// [`otsys::otPlatRadioGetRegion`](crate::otsys::otPlatRadioGetRegion).
21    fn get_region(&self) -> Result<RadioRegion>;
22
23    /// Functional equivalent of
24    /// [`otsys::otPlatRadioSetRegion`](crate::otsys::otPlatRadioSetRegion).
25    fn set_region(&self, region: RadioRegion) -> Result;
26
27    /// Functional equivalent of
28    /// [`otsys::otPlatRadioGetTransmitPower`](crate::otsys::otPlatRadioGetTransmitPower).
29    fn get_transmit_power(&self) -> Result<Decibels>;
30
31    /// Functional equivalent of
32    /// [`otsys::otPlatRadioGetVersionString`](crate::otsys::otPlatRadioGetVersionString).
33    fn radio_get_version_string(&self) -> &str;
34
35    /// Functional equivalent of
36    /// [`otsys::otPlatRadioGetCslAccuracy`](crate::otsys::otPlatRadioGetCslAccuracy).
37    fn get_csl_accuracy(&self) -> u8;
38
39    /// Functional equivalent of
40    /// [`otsys::otPlatRadioGetCslUncertainty`](crate::otsys::otPlatRadioGetCslUncertainty).
41    fn get_csl_uncertainty(&self) -> u8;
42
43    /// Calling into OT state change handler in platform radio
44    fn on_radio_handle_state_change(&self, flags: ot::ChangedFlags);
45
46    /// Functional equivalent of [`otsys::otPlatRadioGetCcaEnergyDetectThreshold`]
47    /// (crate::otsys::otPlatRadioGetCcaEnergyDetectThreshold).
48    fn get_cca_threshold(&self) -> Result<Decibels>;
49}
50
51impl<T: Radio + Boxable> Radio for ot::Box<T> {
52    fn get_coex_metrics(&self) -> Result<RadioCoexMetrics> {
53        self.as_ref().get_coex_metrics()
54    }
55
56    fn get_rssi(&self) -> Decibels {
57        self.as_ref().get_rssi()
58    }
59
60    fn get_region(&self) -> Result<RadioRegion> {
61        self.as_ref().get_region()
62    }
63
64    fn set_region(&self, region: RadioRegion) -> Result {
65        self.as_ref().set_region(region)
66    }
67
68    fn get_transmit_power(&self) -> Result<Decibels> {
69        self.as_ref().get_transmit_power()
70    }
71
72    fn radio_get_version_string(&self) -> &str {
73        self.as_ref().radio_get_version_string()
74    }
75
76    fn get_csl_accuracy(&self) -> u8 {
77        self.as_ref().get_csl_accuracy()
78    }
79
80    fn get_csl_uncertainty(&self) -> u8 {
81        self.as_ref().get_csl_uncertainty()
82    }
83
84    fn on_radio_handle_state_change(&self, flags: ot::ChangedFlags) {
85        self.as_ref().on_radio_handle_state_change(flags)
86    }
87
88    fn get_cca_threshold(&self) -> Result<Decibels> {
89        self.as_ref().get_cca_threshold()
90    }
91}
92
93impl Radio for Instance {
94    fn get_coex_metrics(&self) -> Result<RadioCoexMetrics> {
95        let mut ret = RadioCoexMetrics::default();
96        Error::from(unsafe { otPlatRadioGetCoexMetrics(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
97            .into_result()?;
98        Ok(ret)
99    }
100
101    fn get_rssi(&self) -> Decibels {
102        unsafe { otPlatRadioGetRssi(self.as_ot_ptr()) }
103    }
104
105    fn get_region(&self) -> Result<RadioRegion> {
106        let mut ret = 0u16;
107        Error::from(unsafe { otPlatRadioGetRegion(self.as_ot_ptr(), &mut ret as *mut u16) })
108            .into_result()?;
109        Ok(ret.into())
110    }
111
112    fn set_region(&self, region: RadioRegion) -> Result {
113        Error::from(unsafe { otPlatRadioSetRegion(self.as_ot_ptr(), region.into()) }).into()
114    }
115
116    fn get_transmit_power(&self) -> Result<Decibels> {
117        let mut ret = DECIBELS_UNSPECIFIED;
118        Error::from(unsafe {
119            otPlatRadioGetTransmitPower(self.as_ot_ptr(), &mut ret as *mut Decibels)
120        })
121        .into_result()?;
122        Ok(ret)
123    }
124
125    fn radio_get_version_string(&self) -> &str {
126        unsafe {
127            // SAFETY: `otPlatRadioGetVersionString` guarantees to return a C-String that will not
128            //         change.
129            CStr::from_ptr(otPlatRadioGetVersionString(self.as_ot_ptr()))
130                .to_str()
131                .expect("OpenThread version string was bad UTF8")
132        }
133    }
134
135    fn get_csl_accuracy(&self) -> u8 {
136        unsafe { otPlatRadioGetCslAccuracy(self.as_ot_ptr()) }
137    }
138
139    fn get_csl_uncertainty(&self) -> u8 {
140        unsafe { otPlatRadioGetCslUncertainty(self.as_ot_ptr()) }
141    }
142
143    fn on_radio_handle_state_change(&self, flags: ot::ChangedFlags) {
144        unsafe { platformRadioHandleStateChange(self.as_ot_ptr(), flags.bits()) }
145    }
146
147    fn get_cca_threshold(&self) -> Result<Decibels> {
148        let mut ret = DECIBELS_UNSPECIFIED;
149        Error::from(unsafe {
150            otPlatRadioGetCcaEnergyDetectThreshold(self.as_ot_ptr(), &mut ret as *mut Decibels)
151        })
152        .into_result()?;
153        Ok(ret)
154    }
155}