capsules_extra/ieee802154/device.rs
1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! The contract satisfied by an implementation of an IEEE 802.15.4 MAC device.
6//! Any IEEE 802.15.4 MAC device should expose the following high-level
7//! functionality:
8//!
9//! - Configuration of addresses and transmit power
10//! - Preparing frames (data frame, command frames, beacon frames)
11//! - Transmitting and receiving frames
12//!
13//! Outlining this in a trait allows other implementations of MAC devices that
14//! divide the responsibilities of software and hardware differently. For
15//! example, a radio chip might be able to completely inline the frame security
16//! procedure in hardware, as opposed to requiring a software implementation.
17
18use crate::ieee802154::framer::Frame;
19use crate::net::ieee802154::{Header, KeyId, MacAddress, PanID, SecurityLevel};
20use kernel::ErrorCode;
21
22pub trait MacDevice<'a> {
23 /// Sets the transmission client of this MAC device
24 fn set_transmit_client(&self, client: &'a dyn TxClient);
25 /// Sets the receive client of this MAC device
26 fn set_receive_client(&self, client: &'a dyn RxClient);
27
28 /// The short 16-bit address of the MAC device
29 fn get_address(&self) -> u16;
30 /// The long 64-bit address (EUI-64) of the MAC device
31 fn get_address_long(&self) -> [u8; 8];
32 /// The 16-bit PAN ID of the MAC device
33 fn get_pan(&self) -> u16;
34
35 /// Set the short 16-bit address of the MAC device
36 fn set_address(&self, addr: u16);
37 /// Set the long 64-bit address (EUI-64) of the MAC device
38 fn set_address_long(&self, addr: [u8; 8]);
39 /// Set the 16-bit PAN ID of the MAC device
40 fn set_pan(&self, id: u16);
41
42 /// This method must be called after one or more calls to `set_*`. If
43 /// `set_*` is called without calling `config_commit`, there is no guarantee
44 /// that the underlying hardware configuration (addresses, pan ID) is in
45 /// line with this MAC device implementation.
46 fn config_commit(&self);
47
48 /// Returns if the MAC device is currently on.
49 fn is_on(&self) -> bool;
50
51 /// Start the radio.
52 ///
53 /// This serves as a passthrough to the underlying radio's `start` method.
54 ///
55 /// ## Return
56 ///
57 /// `Ok(())` on success. On `Err()`, valid errors are:
58 ///
59 /// - `ErrorCode::FAIL`: Internal error occurred.
60 fn start(&self) -> Result<(), ErrorCode>;
61
62 /// Prepares a mutable buffer slice as an 802.15.4 frame by writing the appropriate
63 /// header bytes into the buffer. This needs to be done before adding the
64 /// payload because the length of the header is not fixed.
65 ///
66 /// - `buf`: The mutable buffer slice to use
67 /// - `dst_pan`: The destination PAN ID
68 /// - `dst_addr`: The destination MAC address
69 /// - `src_pan`: The source PAN ID
70 /// - `src_addr`: The source MAC address
71 /// - `security_needed`: Whether or not this frame should be secured. This
72 /// needs to be specified beforehand so that the auxiliary security header
73 /// can be pre-inserted.
74 ///
75 /// Returns either a Frame that is ready to have payload appended to it, or
76 /// the mutable buffer if the frame cannot be prepared for any reason
77 fn prepare_data_frame(
78 &self,
79 buf: &'static mut [u8],
80 dst_pan: PanID,
81 dst_addr: MacAddress,
82 src_pan: PanID,
83 src_addr: MacAddress,
84 security_needed: Option<(SecurityLevel, KeyId)>,
85 ) -> Result<Frame, &'static mut [u8]>;
86
87 /// Transmits a frame that has been prepared by the above process. If the
88 /// transmission process fails, the buffer inside the frame is returned so
89 /// that it can be re-used.
90 fn transmit(&self, frame: Frame) -> Result<(), (ErrorCode, &'static mut [u8])>;
91}
92
93/// Trait to be implemented by any user of the IEEE 802.15.4 device that
94/// transmits frames. Contains a callback through which the static mutable
95/// reference to the frame buffer is returned to the client.
96pub trait TxClient {
97 /// When transmission is complete or fails, return the buffer used for
98 /// transmission to the client. `result` indicates whether or not
99 /// the transmission was successful.
100 ///
101 /// - `spi_buf`: The buffer used to contain the transmitted frame is
102 /// returned to the client here.
103 /// - `acked`: Whether the transmission was acknowledged.
104 /// - `result`: This is `Ok(())` if the frame was transmitted,
105 /// otherwise an error occurred in the transmission pipeline.
106 fn send_done(&self, spi_buf: &'static mut [u8], acked: bool, result: Result<(), ErrorCode>);
107}
108
109/// Trait to be implemented by users of the IEEE 802.15.4 device that wish to
110/// receive frames.
111///
112/// The callback is triggered whenever a valid frame is received,
113/// verified and unsecured (via the IEEE 802.15.4 security procedure)
114/// successfully.
115pub trait RxClient {
116 /// When a frame is received, this callback is triggered. The client only
117 /// receives an immutable borrow of the buffer. Only completely valid,
118 /// unsecured frames that have passed the incoming security procedure are
119 /// exposed to the client.
120 ///
121 /// - `buf`: The entire buffer containing the frame, including extra bytes
122 /// in front used for the physical layer.
123 /// - `header`: A fully-parsed representation of the MAC header, with the
124 /// caveat that the auxiliary security header is still included if the frame
125 /// was previously secured.
126 /// - `lqi`: The link quality indicator of the received frame.
127 /// - `data_offset`: Offset of the data payload relative to
128 /// `buf`, so that the payload of the frame is contained in
129 /// `buf[data_offset..data_offset + data_len]`.
130 /// - `data_len`: Length of the data payload
131 fn receive<'a>(
132 &self,
133 buf: &'a [u8],
134 header: Header<'a>,
135 lqi: u8,
136 data_offset: usize,
137 data_len: usize,
138 );
139}