diff --git a/capsules/extra/src/ieee802154/device.rs b/capsules/extra/src/ieee802154/device.rs index 7d6c009241..dce17bc7af 100644 --- a/capsules/extra/src/ieee802154/device.rs +++ b/capsules/extra/src/ieee802154/device.rs @@ -48,6 +48,17 @@ pub trait MacDevice<'a> { /// Returns if the MAC device is currently on. fn is_on(&self) -> bool; + /// Start the radio. + /// + /// This serves as a passthrough to the underlying radio's `start` method. + /// + /// ## Return + /// + /// `Ok(())` on success. On `Err()`, valid errors are: + /// + /// - `ErrorCode::FAIL`: Internal error occurred. + fn start(&self) -> Result<(), ErrorCode>; + /// Prepares a mutable buffer slice as an 802.15.4 frame by writing the appropriate /// header bytes into the buffer. This needs to be done before adding the /// payload because the length of the header is not fixed. diff --git a/capsules/extra/src/ieee802154/driver.rs b/capsules/extra/src/ieee802154/driver.rs index a0bbf0db3d..f29acef2cf 100644 --- a/capsules/extra/src/ieee802154/driver.rs +++ b/capsules/extra/src/ieee802154/driver.rs @@ -668,6 +668,7 @@ impl<'a, M: device::MacDevice<'a>> SyscallDriver for RadioDriver<'a, M> { /// parameters to encrypt, form headers, and transmit the frame. /// - `28`: Set long address. /// - `29`: Get the long MAC address. + /// - `30`: Turn the radio on. fn command( &self, command_number: usize, @@ -967,6 +968,7 @@ impl<'a, M: device::MacDevice<'a>> SyscallDriver for RadioDriver<'a, M> { let addr = u64::from_be_bytes(self.mac.get_address_long()); CommandReturn::success_u64(addr) } + 30 => self.mac.start().into(), _ => CommandReturn::failure(ErrorCode::NOSUPPORT), } } diff --git a/capsules/extra/src/ieee802154/framer.rs b/capsules/extra/src/ieee802154/framer.rs index e6bf6580c8..d62bde61ec 100644 --- a/capsules/extra/src/ieee802154/framer.rs +++ b/capsules/extra/src/ieee802154/framer.rs @@ -774,6 +774,10 @@ impl<'a, M: Mac<'a>, A: AES128CCM<'a>> MacDevice<'a> for Framer<'a, M, A> { self.mac.is_on() } + fn start(&self) -> Result<(), ErrorCode> { + self.mac.start() + } + fn prepare_data_frame( &self, buf: &'static mut [u8], diff --git a/capsules/extra/src/ieee802154/mac.rs b/capsules/extra/src/ieee802154/mac.rs index a4c0dc95c3..6b20cb48ed 100644 --- a/capsules/extra/src/ieee802154/mac.rs +++ b/capsules/extra/src/ieee802154/mac.rs @@ -57,6 +57,17 @@ pub trait Mac<'a> { /// Indicates whether or not the MAC protocol is active and can send frames fn is_on(&self) -> bool; + /// Start the radio. + /// + /// This serves as a passthrough to the underlying radio's `start` method. + /// + /// ## Return + /// + /// `Ok(())` on success. On `Err()`, valid errors are: + /// + /// - `ErrorCode::FAIL`: Internal error occurred. + fn start(&self) -> Result<(), ErrorCode>; + /// Transmits complete MAC frames, which must be prepared by an ieee802154::device::MacDevice /// before being passed to the Mac layer. Returns the frame buffer in case of an error. fn transmit( @@ -98,6 +109,10 @@ impl<'a, R: radio::Radio<'a>> Mac<'a> for AwakeMac<'a, R> { self.radio.is_on() } + fn start(&self) -> Result<(), ErrorCode> { + self.radio.start() + } + fn set_config_client(&self, client: &'a dyn radio::ConfigClient) { self.radio.set_config_client(client) } diff --git a/capsules/extra/src/ieee802154/virtual_mac.rs b/capsules/extra/src/ieee802154/virtual_mac.rs index e224efed60..823226b7f7 100644 --- a/capsules/extra/src/ieee802154/virtual_mac.rs +++ b/capsules/extra/src/ieee802154/virtual_mac.rs @@ -288,6 +288,10 @@ impl<'a, M: device::MacDevice<'a>> device::MacDevice<'a> for MacUser<'a, M> { self.mux.mac.is_on() } + fn start(&self) -> Result<(), ErrorCode> { + self.mux.mac.start() + } + fn prepare_data_frame( &self, buf: &'static mut [u8], diff --git a/capsules/extra/src/ieee802154/xmac.rs b/capsules/extra/src/ieee802154/xmac.rs index eb2cf0504b..d017f400ce 100644 --- a/capsules/extra/src/ieee802154/xmac.rs +++ b/capsules/extra/src/ieee802154/xmac.rs @@ -369,6 +369,11 @@ impl<'a, R: radio::Radio<'a>, A: Alarm<'a>> Mac<'a> for XMac<'a, R, A> { self.radio.is_on() } + fn start(&self) -> Result<(), ErrorCode> { + self.state.set(XMacState::STARTUP); + self.radio.start() + } + fn set_config_client(&self, client: &'a dyn radio::ConfigClient) { self.radio.set_config_client(client) }