openthread_fuchsia/backing/
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 super::*;
6
7impl PlatformBacking {
8    fn on_send_spinel_frame_to_rcp(&self, _instance: Option<&ot::Instance>, buffer: &[u8]) {
9        #[no_mangle]
10        unsafe extern "C" fn platformCallbackSendOneFrameToRadio(
11            instance: *mut otsys::otInstance,
12            buffer_ptr: *const u8,
13            len: usize,
14        ) {
15            PlatformBacking::on_send_spinel_frame_to_rcp(
16                // SAFETY: Must only be called from OpenThread thread,
17                PlatformBacking::as_ref(),
18                // SAFETY: `instance` must be a pointer to a valid `otInstance`
19                ot::Instance::ref_from_ot_ptr(instance),
20                // SAFETY: `buffer_ptr` must point to a `u8` buffer at least `len` bytes long.
21                std::slice::from_raw_parts(buffer_ptr, len),
22            )
23        }
24
25        debug!(tag = "rcp"; "OT-TO-RCP: {:?}", SpinelFrameRef::try_unpack_from_slice(buffer));
26        self.ot_to_rcp_sender.borrow_mut().send(buffer.to_vec()).expect("ot_to_rcp_sender::send");
27    }
28
29    fn on_recv_wait_spinel_frame_from_rcp(
30        &self,
31        _instance: Option<&ot::Instance>,
32        buffer: &mut [u8],
33        duration: Duration,
34    ) -> usize {
35        #[no_mangle]
36        unsafe extern "C" fn platformCallbackWaitForFrameFromRadio(
37            instance: *mut otsys::otInstance,
38            buffer_ptr: *mut u8,
39            len_max: usize,
40            timeout_us: u64,
41        ) -> usize {
42            PlatformBacking::on_recv_wait_spinel_frame_from_rcp(
43                // SAFETY: Must only be called from OpenThread thread,
44                PlatformBacking::as_ref(),
45                // SAFETY: `instance` must be a pointer to a valid `otInstance`
46                ot::Instance::ref_from_ot_ptr(instance),
47                // SAFETY: `buffer_ptr` must point to a mutable `u8` buffer at least `len` bytes long.
48                std::slice::from_raw_parts_mut(buffer_ptr, len_max),
49                Duration::from_micros(timeout_us),
50            )
51        }
52        #[no_mangle]
53        unsafe extern "C" fn platformCallbackFetchQueuedFrameFromRadio(
54            instance: *mut otsys::otInstance,
55            buffer_ptr: *mut u8,
56            len_max: usize,
57        ) -> usize {
58            PlatformBacking::on_recv_wait_spinel_frame_from_rcp(
59                // SAFETY: Must only be called from OpenThread thread,
60                PlatformBacking::as_ref(),
61                // SAFETY: `instance` must be a pointer to a valid `otInstance`
62                ot::Instance::ref_from_ot_ptr(instance),
63                // SAFETY: `buffer_ptr` must point to a mutable `u8` buffer at least `len` bytes long.
64                std::slice::from_raw_parts_mut(buffer_ptr, len_max),
65                Duration::from_micros(0),
66            )
67        }
68
69        if !duration.is_zero() {
70            trace!(
71                tag = "rcp";
72                "on_recv_wait_spinel_frame_from_rcp: Waiting {:?} for spinel frame",
73                duration
74            );
75        }
76        match self.rcp_to_ot_receiver.borrow_mut().recv_timeout(duration) {
77            Ok(vec) => {
78                debug!(
79                    tag = "rcp";
80                    "RCP-TO-OT: {:?}",
81                    SpinelFrameRef::try_unpack_from_slice(vec.as_slice())
82                );
83                buffer[0..vec.len()].clone_from_slice(&vec);
84                vec.len()
85            }
86            Err(mpsc::RecvTimeoutError::Timeout) => {
87                if !duration.is_zero() {
88                    trace!(tag = "rcp"; "on_recv_wait_spinel_frame_from_rcp: Timeout");
89                }
90                0
91            }
92            Err(mpsc::RecvTimeoutError::Disconnected) => panic!("Spinel Thread Disconnected"),
93        }
94    }
95}