Compare commits
	
		
			16 Commits
		
	
	
		
			stm32-docs
			...
			embassy-ne
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 93bb34d8d1 | ||
|  | c3b827d8cd | ||
|  | 4dfae9328e | ||
|  | 89cfdcb9f5 | ||
|  | abea4dde3d | ||
|  | 52a801fdb7 | ||
|  | fc6e70caa5 | ||
|  | 97e919ea64 | ||
|  | c7841a37fa | ||
|  | 589a16b255 | ||
|  | 4567b87482 | ||
|  | 12de90e13d | ||
|  | 871ed538b1 | ||
|  | efd5dbe019 | ||
|  | 9d46ee0758 | ||
|  | e5912972ec | 
| @@ -26,25 +26,22 @@ features = ["defmt"] | |||||||
| defmt = { version = "0.3", optional = true } | defmt = { version = "0.3", optional = true } | ||||||
| digest = "0.10" | digest = "0.10" | ||||||
| log = { version = "0.4", optional = true } | log = { version = "0.4", optional = true } | ||||||
| ed25519-dalek = { version = "1.0.1", default_features = false, features = ["u32_backend"], optional = true } | ed25519-dalek = { version = "2", default_features = false, features = ["digest"], optional = true } | ||||||
| embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } | ||||||
| embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } | embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } | ||||||
| embedded-storage = "0.3.1" | embedded-storage = "0.3.1" | ||||||
| embedded-storage-async = { version = "0.4.1" } | embedded-storage-async = { version = "0.4.1" } | ||||||
| salty = { git = "https://github.com/ycrypto/salty.git", rev = "a9f17911a5024698406b75c0fac56ab5ccf6a8c7", optional = true } | salty = { version = "0.3", optional = true } | ||||||
| signature = { version = "1.6.4", default-features = false } | signature = { version = "2.0", default-features = false } | ||||||
|  |  | ||||||
| [dev-dependencies] | [dev-dependencies] | ||||||
| log = "0.4" | log = "0.4" | ||||||
| env_logger = "0.9" | env_logger = "0.9" | ||||||
| rand = "0.7" # ed25519-dalek v1.0.1 depends on this exact version | rand = "0.8" | ||||||
| futures = { version = "0.3", features = ["executor"] } | futures = { version = "0.3", features = ["executor"] } | ||||||
| sha1 = "0.10.5" | sha1 = "0.10.5" | ||||||
| critical-section = { version = "1.1.1", features = ["std"] } | critical-section = { version = "1.1.1", features = ["std"] } | ||||||
|  | ed25519-dalek = { version = "2", default_features = false, features = ["std", "rand_core", "digest"]  } | ||||||
| [dev-dependencies.ed25519-dalek] |  | ||||||
| default_features = false |  | ||||||
| features = ["rand", "std", "u32_backend"] |  | ||||||
|  |  | ||||||
| [features] | [features] | ||||||
| ed25519-dalek = ["dep:ed25519-dalek", "_verify"] | ed25519-dalek = ["dep:ed25519-dalek", "_verify"] | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| use digest::typenum::U64; | use digest::typenum::U64; | ||||||
| use digest::{FixedOutput, HashMarker, OutputSizeUser, Update}; | use digest::{FixedOutput, HashMarker, OutputSizeUser, Update}; | ||||||
| use ed25519_dalek::Digest as _; | use ed25519_dalek::Digest; | ||||||
|  |  | ||||||
| pub struct Sha512(ed25519_dalek::Sha512); | pub struct Sha512(ed25519_dalek::Sha512); | ||||||
|  |  | ||||||
| @@ -12,7 +12,7 @@ impl Default for Sha512 { | |||||||
|  |  | ||||||
| impl Update for Sha512 { | impl Update for Sha512 { | ||||||
|     fn update(&mut self, data: &[u8]) { |     fn update(&mut self, data: &[u8]) { | ||||||
|         self.0.update(data) |         Digest::update(&mut self.0, data) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -79,8 +79,8 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> { | |||||||
|     #[cfg(feature = "_verify")] |     #[cfg(feature = "_verify")] | ||||||
|     pub async fn verify_and_mark_updated( |     pub async fn verify_and_mark_updated( | ||||||
|         &mut self, |         &mut self, | ||||||
|         _public_key: &[u8], |         _public_key: &[u8; 32], | ||||||
|         _signature: &[u8], |         _signature: &[u8; 64], | ||||||
|         _update_len: u32, |         _update_len: u32, | ||||||
|     ) -> Result<(), FirmwareUpdaterError> { |     ) -> Result<(), FirmwareUpdaterError> { | ||||||
|         assert!(_update_len <= self.dfu.capacity() as u32); |         assert!(_update_len <= self.dfu.capacity() as u32); | ||||||
| @@ -89,14 +89,14 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> { | |||||||
|  |  | ||||||
|         #[cfg(feature = "ed25519-dalek")] |         #[cfg(feature = "ed25519-dalek")] | ||||||
|         { |         { | ||||||
|             use ed25519_dalek::{PublicKey, Signature, SignatureError, Verifier}; |             use ed25519_dalek::{Signature, SignatureError, Verifier, VerifyingKey}; | ||||||
|  |  | ||||||
|             use crate::digest_adapters::ed25519_dalek::Sha512; |             use crate::digest_adapters::ed25519_dalek::Sha512; | ||||||
|  |  | ||||||
|             let into_signature_error = |e: SignatureError| FirmwareUpdaterError::Signature(e.into()); |             let into_signature_error = |e: SignatureError| FirmwareUpdaterError::Signature(e.into()); | ||||||
|  |  | ||||||
|             let public_key = PublicKey::from_bytes(_public_key).map_err(into_signature_error)?; |             let public_key = VerifyingKey::from_bytes(_public_key).map_err(into_signature_error)?; | ||||||
|             let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?; |             let signature = Signature::from_bytes(_signature); | ||||||
|  |  | ||||||
|             let mut chunk_buf = [0; 2]; |             let mut chunk_buf = [0; 2]; | ||||||
|             let mut message = [0; 64]; |             let mut message = [0; 64]; | ||||||
| @@ -106,7 +106,6 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> { | |||||||
|         } |         } | ||||||
|         #[cfg(feature = "ed25519-salty")] |         #[cfg(feature = "ed25519-salty")] | ||||||
|         { |         { | ||||||
|             use salty::constants::{PUBLICKEY_SERIALIZED_LENGTH, SIGNATURE_SERIALIZED_LENGTH}; |  | ||||||
|             use salty::{PublicKey, Signature}; |             use salty::{PublicKey, Signature}; | ||||||
|  |  | ||||||
|             use crate::digest_adapters::salty::Sha512; |             use crate::digest_adapters::salty::Sha512; | ||||||
| @@ -115,10 +114,8 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> { | |||||||
|                 FirmwareUpdaterError::Signature(signature::Error::default()) |                 FirmwareUpdaterError::Signature(signature::Error::default()) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             let public_key: [u8; PUBLICKEY_SERIALIZED_LENGTH] = _public_key.try_into().map_err(into_signature_error)?; |             let public_key = PublicKey::try_from(_public_key).map_err(into_signature_error)?; | ||||||
|             let public_key = PublicKey::try_from(&public_key).map_err(into_signature_error)?; |             let signature = Signature::try_from(_signature).map_err(into_signature_error)?; | ||||||
|             let signature: [u8; SIGNATURE_SERIALIZED_LENGTH] = _signature.try_into().map_err(into_signature_error)?; |  | ||||||
|             let signature = Signature::try_from(&signature).map_err(into_signature_error)?; |  | ||||||
|  |  | ||||||
|             let mut message = [0; 64]; |             let mut message = [0; 64]; | ||||||
|             let mut chunk_buf = [0; 2]; |             let mut chunk_buf = [0; 2]; | ||||||
|   | |||||||
| @@ -86,8 +86,8 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE> | |||||||
|     #[cfg(feature = "_verify")] |     #[cfg(feature = "_verify")] | ||||||
|     pub fn verify_and_mark_updated( |     pub fn verify_and_mark_updated( | ||||||
|         &mut self, |         &mut self, | ||||||
|         _public_key: &[u8], |         _public_key: &[u8; 32], | ||||||
|         _signature: &[u8], |         _signature: &[u8; 64], | ||||||
|         _update_len: u32, |         _update_len: u32, | ||||||
|     ) -> Result<(), FirmwareUpdaterError> { |     ) -> Result<(), FirmwareUpdaterError> { | ||||||
|         assert!(_update_len <= self.dfu.capacity() as u32); |         assert!(_update_len <= self.dfu.capacity() as u32); | ||||||
| @@ -96,14 +96,14 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE> | |||||||
|  |  | ||||||
|         #[cfg(feature = "ed25519-dalek")] |         #[cfg(feature = "ed25519-dalek")] | ||||||
|         { |         { | ||||||
|             use ed25519_dalek::{PublicKey, Signature, SignatureError, Verifier}; |             use ed25519_dalek::{Signature, SignatureError, Verifier, VerifyingKey}; | ||||||
|  |  | ||||||
|             use crate::digest_adapters::ed25519_dalek::Sha512; |             use crate::digest_adapters::ed25519_dalek::Sha512; | ||||||
|  |  | ||||||
|             let into_signature_error = |e: SignatureError| FirmwareUpdaterError::Signature(e.into()); |             let into_signature_error = |e: SignatureError| FirmwareUpdaterError::Signature(e.into()); | ||||||
|  |  | ||||||
|             let public_key = PublicKey::from_bytes(_public_key).map_err(into_signature_error)?; |             let public_key = VerifyingKey::from_bytes(_public_key).map_err(into_signature_error)?; | ||||||
|             let signature = Signature::from_bytes(_signature).map_err(into_signature_error)?; |             let signature = Signature::from_bytes(_signature); | ||||||
|  |  | ||||||
|             let mut message = [0; 64]; |             let mut message = [0; 64]; | ||||||
|             let mut chunk_buf = [0; 2]; |             let mut chunk_buf = [0; 2]; | ||||||
| @@ -113,7 +113,6 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE> | |||||||
|         } |         } | ||||||
|         #[cfg(feature = "ed25519-salty")] |         #[cfg(feature = "ed25519-salty")] | ||||||
|         { |         { | ||||||
|             use salty::constants::{PUBLICKEY_SERIALIZED_LENGTH, SIGNATURE_SERIALIZED_LENGTH}; |  | ||||||
|             use salty::{PublicKey, Signature}; |             use salty::{PublicKey, Signature}; | ||||||
|  |  | ||||||
|             use crate::digest_adapters::salty::Sha512; |             use crate::digest_adapters::salty::Sha512; | ||||||
| @@ -122,10 +121,8 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE> | |||||||
|                 FirmwareUpdaterError::Signature(signature::Error::default()) |                 FirmwareUpdaterError::Signature(signature::Error::default()) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             let public_key: [u8; PUBLICKEY_SERIALIZED_LENGTH] = _public_key.try_into().map_err(into_signature_error)?; |             let public_key = PublicKey::try_from(_public_key).map_err(into_signature_error)?; | ||||||
|             let public_key = PublicKey::try_from(&public_key).map_err(into_signature_error)?; |             let signature = Signature::try_from(_signature).map_err(into_signature_error)?; | ||||||
|             let signature: [u8; SIGNATURE_SERIALIZED_LENGTH] = _signature.try_into().map_err(into_signature_error)?; |  | ||||||
|             let signature = Signature::try_from(&signature).map_err(into_signature_error)?; |  | ||||||
|  |  | ||||||
|             let mut message = [0; 64]; |             let mut message = [0; 64]; | ||||||
|             let mut chunk_buf = [0; 2]; |             let mut chunk_buf = [0; 2]; | ||||||
|   | |||||||
| @@ -275,21 +275,19 @@ mod tests { | |||||||
|         // The following key setup is based on: |         // The following key setup is based on: | ||||||
|         // https://docs.rs/ed25519-dalek/latest/ed25519_dalek/#example |         // https://docs.rs/ed25519-dalek/latest/ed25519_dalek/#example | ||||||
|  |  | ||||||
|         use ed25519_dalek::Keypair; |         use ed25519_dalek::{Digest, Sha512, Signature, Signer, SigningKey, VerifyingKey}; | ||||||
|         use rand::rngs::OsRng; |         use rand::rngs::OsRng; | ||||||
|  |  | ||||||
|         let mut csprng = OsRng {}; |         let mut csprng = OsRng {}; | ||||||
|         let keypair: Keypair = Keypair::generate(&mut csprng); |         let keypair = SigningKey::generate(&mut csprng); | ||||||
|  |  | ||||||
|         use ed25519_dalek::{Digest, Sha512, Signature, Signer}; |  | ||||||
|         let firmware: &[u8] = b"This are bytes that would otherwise be firmware bytes for DFU."; |         let firmware: &[u8] = b"This are bytes that would otherwise be firmware bytes for DFU."; | ||||||
|         let mut digest = Sha512::new(); |         let mut digest = Sha512::new(); | ||||||
|         digest.update(&firmware); |         digest.update(&firmware); | ||||||
|         let message = digest.finalize(); |         let message = digest.finalize(); | ||||||
|         let signature: Signature = keypair.sign(&message); |         let signature: Signature = keypair.sign(&message); | ||||||
|  |  | ||||||
|         use ed25519_dalek::PublicKey; |         let public_key = keypair.verifying_key(); | ||||||
|         let public_key: PublicKey = keypair.public; |  | ||||||
|  |  | ||||||
|         // Setup flash |         // Setup flash | ||||||
|         let flash = BlockingTestFlash::new(BootLoaderConfig { |         let flash = BlockingTestFlash::new(BootLoaderConfig { | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #![no_std] | #![no_std] | ||||||
| #![doc = include_str!("../README.md")] | #![doc = include_str!("../README.md")] | ||||||
|  | #![warn(missing_docs)] | ||||||
|  |  | ||||||
| // must go first! | // must go first! | ||||||
| mod fmt; | mod fmt; | ||||||
| @@ -15,6 +16,9 @@ use embassy_sync::blocking_mutex::Mutex; | |||||||
| use embassy_sync::waitqueue::WakerRegistration; | use embassy_sync::waitqueue::WakerRegistration; | ||||||
| use embassy_sync::zerocopy_channel; | use embassy_sync::zerocopy_channel; | ||||||
|  |  | ||||||
|  | /// Channel state. | ||||||
|  | /// | ||||||
|  | /// Holds a buffer of packets with size MTU, for both TX and RX. | ||||||
| pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | ||||||
|     rx: [PacketBuf<MTU>; N_RX], |     rx: [PacketBuf<MTU>; N_RX], | ||||||
|     tx: [PacketBuf<MTU>; N_TX], |     tx: [PacketBuf<MTU>; N_TX], | ||||||
| @@ -24,6 +28,7 @@ pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> { | |||||||
| impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { | impl<const MTU: usize, const N_RX: usize, const N_TX: usize> State<MTU, N_RX, N_TX> { | ||||||
|     const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); |     const NEW_PACKET: PacketBuf<MTU> = PacketBuf::new(); | ||||||
|  |  | ||||||
|  |     /// Create a new channel state. | ||||||
|     pub const fn new() -> Self { |     pub const fn new() -> Self { | ||||||
|         Self { |         Self { | ||||||
|             rx: [Self::NEW_PACKET; N_RX], |             rx: [Self::NEW_PACKET; N_RX], | ||||||
| @@ -39,33 +44,45 @@ struct StateInner<'d, const MTU: usize> { | |||||||
|     shared: Mutex<NoopRawMutex, RefCell<Shared>>, |     shared: Mutex<NoopRawMutex, RefCell<Shared>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| /// State of the LinkState |  | ||||||
| struct Shared { | struct Shared { | ||||||
|     link_state: LinkState, |     link_state: LinkState, | ||||||
|     waker: WakerRegistration, |     waker: WakerRegistration, | ||||||
|     hardware_address: driver::HardwareAddress, |     hardware_address: driver::HardwareAddress, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Channel runner. | ||||||
|  | /// | ||||||
|  | /// Holds the shared state and the lower end of channels for inbound and outbound packets. | ||||||
| pub struct Runner<'d, const MTU: usize> { | pub struct Runner<'d, const MTU: usize> { | ||||||
|     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
|     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
|     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// State runner. | ||||||
|  | /// | ||||||
|  | /// Holds the shared state of the channel such as link state. | ||||||
| #[derive(Clone, Copy)] | #[derive(Clone, Copy)] | ||||||
| pub struct StateRunner<'d> { | pub struct StateRunner<'d> { | ||||||
|     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, |     shared: &'d Mutex<NoopRawMutex, RefCell<Shared>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// RX runner. | ||||||
|  | /// | ||||||
|  | /// Holds the lower end of the channel for passing inbound packets up the stack. | ||||||
| pub struct RxRunner<'d, const MTU: usize> { | pub struct RxRunner<'d, const MTU: usize> { | ||||||
|     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |     rx_chan: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// TX runner. | ||||||
|  | /// | ||||||
|  | /// Holds the lower end of the channel for passing outbound packets down the stack. | ||||||
| pub struct TxRunner<'d, const MTU: usize> { | pub struct TxRunner<'d, const MTU: usize> { | ||||||
|     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |     tx_chan: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d, const MTU: usize> Runner<'d, MTU> { | impl<'d, const MTU: usize> Runner<'d, MTU> { | ||||||
|  |     /// Split the runner into separate runners for controlling state, rx and tx. | ||||||
|     pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { |     pub fn split(self) -> (StateRunner<'d>, RxRunner<'d, MTU>, TxRunner<'d, MTU>) { | ||||||
|         ( |         ( | ||||||
|             StateRunner { shared: self.shared }, |             StateRunner { shared: self.shared }, | ||||||
| @@ -74,6 +91,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Split the runner into separate runners for controlling state, rx and tx borrowing the underlying state. | ||||||
|     pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { |     pub fn borrow_split(&mut self) -> (StateRunner<'_>, RxRunner<'_, MTU>, TxRunner<'_, MTU>) { | ||||||
|         ( |         ( | ||||||
|             StateRunner { shared: self.shared }, |             StateRunner { shared: self.shared }, | ||||||
| @@ -86,10 +104,12 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Create a state runner sharing the state channel. | ||||||
|     pub fn state_runner(&self) -> StateRunner<'d> { |     pub fn state_runner(&self) -> StateRunner<'d> { | ||||||
|         StateRunner { shared: self.shared } |         StateRunner { shared: self.shared } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the link state. | ||||||
|     pub fn set_link_state(&mut self, state: LinkState) { |     pub fn set_link_state(&mut self, state: LinkState) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -98,6 +118,7 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the hardware address. | ||||||
|     pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { |     pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -106,16 +127,19 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Wait until there is space for more inbound packets and return a slice they can be copied into. | ||||||
|     pub async fn rx_buf(&mut self) -> &mut [u8] { |     pub async fn rx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.rx_chan.send().await; |         let p = self.rx_chan.send().await; | ||||||
|         &mut p.buf |         &mut p.buf | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more inbound packets right now. | ||||||
|     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.rx_chan.try_send()?; |         let p = self.rx_chan.try_send()?; | ||||||
|         Some(&mut p.buf) |         Some(&mut p.buf) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the inbound channel if there is space for packets. | ||||||
|     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.rx_chan.poll_send(cx) { |         match self.rx_chan.poll_send(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf), |             Poll::Ready(p) => Poll::Ready(&mut p.buf), | ||||||
| @@ -123,22 +147,26 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark packet of len bytes as pushed to the inbound channel. | ||||||
|     pub fn rx_done(&mut self, len: usize) { |     pub fn rx_done(&mut self, len: usize) { | ||||||
|         let p = self.rx_chan.try_send().unwrap(); |         let p = self.rx_chan.try_send().unwrap(); | ||||||
|         p.len = len; |         p.len = len; | ||||||
|         self.rx_chan.send_done(); |         self.rx_chan.send_done(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Wait until there is space for more outbound packets and return a slice they can be copied into. | ||||||
|     pub async fn tx_buf(&mut self) -> &mut [u8] { |     pub async fn tx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.tx_chan.receive().await; |         let p = self.tx_chan.receive().await; | ||||||
|         &mut p.buf[..p.len] |         &mut p.buf[..p.len] | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more outbound packets right now. | ||||||
|     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.tx_chan.try_receive()?; |         let p = self.tx_chan.try_receive()?; | ||||||
|         Some(&mut p.buf[..p.len]) |         Some(&mut p.buf[..p.len]) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the outbound channel if there is space for packets. | ||||||
|     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.tx_chan.poll_receive(cx) { |         match self.tx_chan.poll_receive(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | ||||||
| @@ -146,12 +174,14 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark outbound packet as copied. | ||||||
|     pub fn tx_done(&mut self) { |     pub fn tx_done(&mut self) { | ||||||
|         self.tx_chan.receive_done(); |         self.tx_chan.receive_done(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d> StateRunner<'d> { | impl<'d> StateRunner<'d> { | ||||||
|  |     /// Set link state. | ||||||
|     pub fn set_link_state(&self, state: LinkState) { |     pub fn set_link_state(&self, state: LinkState) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -160,6 +190,7 @@ impl<'d> StateRunner<'d> { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the hardware address. | ||||||
|     pub fn set_hardware_address(&self, address: driver::HardwareAddress) { |     pub fn set_hardware_address(&self, address: driver::HardwareAddress) { | ||||||
|         self.shared.lock(|s| { |         self.shared.lock(|s| { | ||||||
|             let s = &mut *s.borrow_mut(); |             let s = &mut *s.borrow_mut(); | ||||||
| @@ -170,16 +201,19 @@ impl<'d> StateRunner<'d> { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d, const MTU: usize> RxRunner<'d, MTU> { | impl<'d, const MTU: usize> RxRunner<'d, MTU> { | ||||||
|  |     /// Wait until there is space for more inbound packets and return a slice they can be copied into. | ||||||
|     pub async fn rx_buf(&mut self) -> &mut [u8] { |     pub async fn rx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.rx_chan.send().await; |         let p = self.rx_chan.send().await; | ||||||
|         &mut p.buf |         &mut p.buf | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more inbound packets right now. | ||||||
|     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_rx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.rx_chan.try_send()?; |         let p = self.rx_chan.try_send()?; | ||||||
|         Some(&mut p.buf) |         Some(&mut p.buf) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the inbound channel if there is space for packets. | ||||||
|     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_rx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.rx_chan.poll_send(cx) { |         match self.rx_chan.poll_send(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf), |             Poll::Ready(p) => Poll::Ready(&mut p.buf), | ||||||
| @@ -187,6 +221,7 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark packet of len bytes as pushed to the inbound channel. | ||||||
|     pub fn rx_done(&mut self, len: usize) { |     pub fn rx_done(&mut self, len: usize) { | ||||||
|         let p = self.rx_chan.try_send().unwrap(); |         let p = self.rx_chan.try_send().unwrap(); | ||||||
|         p.len = len; |         p.len = len; | ||||||
| @@ -195,16 +230,19 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d, const MTU: usize> TxRunner<'d, MTU> { | impl<'d, const MTU: usize> TxRunner<'d, MTU> { | ||||||
|  |     /// Wait until there is space for more outbound packets and return a slice they can be copied into. | ||||||
|     pub async fn tx_buf(&mut self) -> &mut [u8] { |     pub async fn tx_buf(&mut self) -> &mut [u8] { | ||||||
|         let p = self.tx_chan.receive().await; |         let p = self.tx_chan.receive().await; | ||||||
|         &mut p.buf[..p.len] |         &mut p.buf[..p.len] | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Check if there is space for more outbound packets right now. | ||||||
|     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { |     pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> { | ||||||
|         let p = self.tx_chan.try_receive()?; |         let p = self.tx_chan.try_receive()?; | ||||||
|         Some(&mut p.buf[..p.len]) |         Some(&mut p.buf[..p.len]) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Polling the outbound channel if there is space for packets. | ||||||
|     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { |     pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> { | ||||||
|         match self.tx_chan.poll_receive(cx) { |         match self.tx_chan.poll_receive(cx) { | ||||||
|             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), |             Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]), | ||||||
| @@ -212,11 +250,18 @@ impl<'d, const MTU: usize> TxRunner<'d, MTU> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Mark outbound packet as copied. | ||||||
|     pub fn tx_done(&mut self) { |     pub fn tx_done(&mut self) { | ||||||
|         self.tx_chan.receive_done(); |         self.tx_chan.receive_done(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Create a channel. | ||||||
|  | /// | ||||||
|  | /// Returns a pair of handles for interfacing with the peripheral and the networking stack. | ||||||
|  | /// | ||||||
|  | /// The runner is interfacing with the peripheral at the lower part of the stack. | ||||||
|  | /// The device is interfacing with the networking stack on the layer above. | ||||||
| pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | ||||||
|     state: &'d mut State<MTU, N_RX, N_TX>, |     state: &'d mut State<MTU, N_RX, N_TX>, | ||||||
|     hardware_address: driver::HardwareAddress, |     hardware_address: driver::HardwareAddress, | ||||||
| @@ -257,17 +302,22 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( | |||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Represents a packet of size MTU. | ||||||
| pub struct PacketBuf<const MTU: usize> { | pub struct PacketBuf<const MTU: usize> { | ||||||
|     len: usize, |     len: usize, | ||||||
|     buf: [u8; MTU], |     buf: [u8; MTU], | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<const MTU: usize> PacketBuf<MTU> { | impl<const MTU: usize> PacketBuf<MTU> { | ||||||
|  |     /// Create a new packet buffer. | ||||||
|     pub const fn new() -> Self { |     pub const fn new() -> Self { | ||||||
|         Self { len: 0, buf: [0; MTU] } |         Self { len: 0, buf: [0; MTU] } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Channel device. | ||||||
|  | /// | ||||||
|  | /// Holds the shared state and upper end of channels for inbound and outbound packets. | ||||||
| pub struct Device<'d, const MTU: usize> { | pub struct Device<'d, const MTU: usize> { | ||||||
|     rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, |     rx: zerocopy_channel::Receiver<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
|     tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, |     tx: zerocopy_channel::Sender<'d, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| @@ -314,6 +364,9 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// A rx token. | ||||||
|  | /// | ||||||
|  | /// Holds inbound receive channel and interfaces with embassy-net-driver. | ||||||
| pub struct RxToken<'a, const MTU: usize> { | pub struct RxToken<'a, const MTU: usize> { | ||||||
|     rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, |     rx: zerocopy_channel::Receiver<'a, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
| @@ -331,6 +384,9 @@ impl<'a, const MTU: usize> embassy_net_driver::RxToken for RxToken<'a, MTU> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// A tx token. | ||||||
|  | /// | ||||||
|  | /// Holds outbound transmit channel and interfaces with embassy-net-driver. | ||||||
| pub struct TxToken<'a, const MTU: usize> { | pub struct TxToken<'a, const MTU: usize> { | ||||||
|     tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, |     tx: zerocopy_channel::Sender<'a, NoopRawMutex, PacketBuf<MTU>>, | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,6 +2,10 @@ | |||||||
| name = "embassy-net-esp-hosted" | name = "embassy-net-esp-hosted" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| edition = "2021" | edition = "2021" | ||||||
|  | description = "embassy-net driver for ESP-Hosted" | ||||||
|  | keywords = ["embedded", "esp-hosted", "embassy-net", "embedded-hal-async", "wifi", "async"] | ||||||
|  | categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"] | ||||||
|  | license = "MIT OR Apache-2.0" | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| defmt = { version = "0.3", optional = true } | defmt = { version = "0.3", optional = true } | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								embassy-net-esp-hosted/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								embassy-net-esp-hosted/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | # ESP-Hosted `embassy-net` integration | ||||||
|  |  | ||||||
|  | [`embassy-net`](https://crates.io/crates/embassy-net) integration for Espressif SoCs running the the ESP-Hosted stack. | ||||||
|  |  | ||||||
|  | See [`examples`](https://github.com/embassy-rs/embassy/tree/main/examples/nrf52840) directory for usage examples with the nRF52840. | ||||||
|  |  | ||||||
|  | ## Supported chips | ||||||
|  |  | ||||||
|  | - W5500 | ||||||
|  | - W5100S | ||||||
|  |  | ||||||
|  | ## Interoperability | ||||||
|  |  | ||||||
|  | This crate can run on any executor. | ||||||
|  |  | ||||||
|  | It supports any SPI driver implementing [`embedded-hal-async`](https://crates.io/crates/embedded-hal-async). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## License | ||||||
|  |  | ||||||
|  | This work is licensed under either of | ||||||
|  |  | ||||||
|  | - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or | ||||||
|  |   http://www.apache.org/licenses/LICENSE-2.0) | ||||||
|  | - MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) | ||||||
|  |  | ||||||
|  | at your option. | ||||||
| @@ -5,38 +5,54 @@ use heapless::String; | |||||||
| use crate::ioctl::Shared; | use crate::ioctl::Shared; | ||||||
| use crate::proto::{self, CtrlMsg}; | use crate::proto::{self, CtrlMsg}; | ||||||
|  |  | ||||||
|  | /// Errors reported by control. | ||||||
| #[derive(Copy, Clone, PartialEq, Eq, Debug)] | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum Error { | pub enum Error { | ||||||
|  |     /// The operation failed with the given error code. | ||||||
|     Failed(u32), |     Failed(u32), | ||||||
|  |     /// The operation timed out. | ||||||
|     Timeout, |     Timeout, | ||||||
|  |     /// Internal error. | ||||||
|     Internal, |     Internal, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Handle for managing the network and WiFI state. | ||||||
| pub struct Control<'a> { | pub struct Control<'a> { | ||||||
|     state_ch: ch::StateRunner<'a>, |     state_ch: ch::StateRunner<'a>, | ||||||
|     shared: &'a Shared, |     shared: &'a Shared, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// WiFi mode. | ||||||
| #[allow(unused)] | #[allow(unused)] | ||||||
| #[derive(Copy, Clone, PartialEq, Eq, Debug)] | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| enum WifiMode { | enum WifiMode { | ||||||
|  |     /// No mode. | ||||||
|     None = 0, |     None = 0, | ||||||
|  |     /// Client station. | ||||||
|     Sta = 1, |     Sta = 1, | ||||||
|  |     /// Access point mode. | ||||||
|     Ap = 2, |     Ap = 2, | ||||||
|  |     /// Repeater mode. | ||||||
|     ApSta = 3, |     ApSta = 3, | ||||||
| } | } | ||||||
|  |  | ||||||
| pub use proto::CtrlWifiSecProt as Security; | pub use proto::CtrlWifiSecProt as Security; | ||||||
|  |  | ||||||
|  | /// WiFi status. | ||||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct Status { | pub struct Status { | ||||||
|  |     /// Service Set Identifier. | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|  |     /// Basic Service Set Identifier. | ||||||
|     pub bssid: [u8; 6], |     pub bssid: [u8; 6], | ||||||
|  |     /// Received Signal Strength Indicator. | ||||||
|     pub rssi: i32, |     pub rssi: i32, | ||||||
|  |     /// WiFi channel. | ||||||
|     pub channel: u32, |     pub channel: u32, | ||||||
|  |     /// Security mode. | ||||||
|     pub security: Security, |     pub security: Security, | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -65,6 +81,7 @@ impl<'a> Control<'a> { | |||||||
|         Self { state_ch, shared } |         Self { state_ch, shared } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Initialize device. | ||||||
|     pub async fn init(&mut self) -> Result<(), Error> { |     pub async fn init(&mut self) -> Result<(), Error> { | ||||||
|         debug!("wait for init event..."); |         debug!("wait for init event..."); | ||||||
|         self.shared.init_wait().await; |         self.shared.init_wait().await; | ||||||
| @@ -82,6 +99,7 @@ impl<'a> Control<'a> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Get the current status. | ||||||
|     pub async fn get_status(&mut self) -> Result<Status, Error> { |     pub async fn get_status(&mut self) -> Result<Status, Error> { | ||||||
|         let req = proto::CtrlMsgReqGetApConfig {}; |         let req = proto::CtrlMsgReqGetApConfig {}; | ||||||
|         ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp); |         ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp); | ||||||
| @@ -95,6 +113,7 @@ impl<'a> Control<'a> { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Connect to the network identified by ssid using the provided password. | ||||||
|     pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { |     pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> { | ||||||
|         let req = proto::CtrlMsgReqConnectAp { |         let req = proto::CtrlMsgReqConnectAp { | ||||||
|             ssid: unwrap!(String::try_from(ssid)), |             ssid: unwrap!(String::try_from(ssid)), | ||||||
| @@ -108,6 +127,7 @@ impl<'a> Control<'a> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Disconnect from any currently connected network. | ||||||
|     pub async fn disconnect(&mut self) -> Result<(), Error> { |     pub async fn disconnect(&mut self) -> Result<(), Error> { | ||||||
|         let req = proto::CtrlMsgReqGetStatus {}; |         let req = proto::CtrlMsgReqGetStatus {}; | ||||||
|         ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp); |         ioctl!(self, ReqDisconnectAp, RespDisconnectAp, req, resp); | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| #![no_std] | #![no_std] | ||||||
|  | #![doc = include_str!("../README.md")] | ||||||
|  | #![warn(missing_docs)] | ||||||
|  |  | ||||||
| use embassy_futures::select::{select4, Either4}; | use embassy_futures::select::{select4, Either4}; | ||||||
| use embassy_net_driver_channel as ch; | use embassy_net_driver_channel as ch; | ||||||
| @@ -97,12 +99,14 @@ enum InterfaceType { | |||||||
| const MAX_SPI_BUFFER_SIZE: usize = 1600; | const MAX_SPI_BUFFER_SIZE: usize = 1600; | ||||||
| const HEARTBEAT_MAX_GAP: Duration = Duration::from_secs(20); | const HEARTBEAT_MAX_GAP: Duration = Duration::from_secs(20); | ||||||
|  |  | ||||||
|  | /// State for the esp-hosted driver. | ||||||
| pub struct State { | pub struct State { | ||||||
|     shared: Shared, |     shared: Shared, | ||||||
|     ch: ch::State<MTU, 4, 4>, |     ch: ch::State<MTU, 4, 4>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl State { | impl State { | ||||||
|  |     /// Create a new state. | ||||||
|     pub fn new() -> Self { |     pub fn new() -> Self { | ||||||
|         Self { |         Self { | ||||||
|             shared: Shared::new(), |             shared: Shared::new(), | ||||||
| @@ -111,8 +115,13 @@ impl State { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Type alias for network driver. | ||||||
| pub type NetDriver<'a> = ch::Device<'a, MTU>; | pub type NetDriver<'a> = ch::Device<'a, MTU>; | ||||||
|  |  | ||||||
|  | /// Create a new esp-hosted driver using the provided state, SPI peripheral and pins. | ||||||
|  | /// | ||||||
|  | /// Returns a device handle for interfacing with embassy-net, a control handle for | ||||||
|  | /// interacting with the driver, and a runner for communicating with the WiFi device. | ||||||
| pub async fn new<'a, SPI, IN, OUT>( | pub async fn new<'a, SPI, IN, OUT>( | ||||||
|     state: &'a mut State, |     state: &'a mut State, | ||||||
|     spi: SPI, |     spi: SPI, | ||||||
| @@ -144,6 +153,7 @@ where | |||||||
|     (device, Control::new(state_ch, &state.shared), runner) |     (device, Control::new(state_ch, &state.shared), runner) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Runner for communicating with the WiFi device. | ||||||
| pub struct Runner<'a, SPI, IN, OUT> { | pub struct Runner<'a, SPI, IN, OUT> { | ||||||
|     ch: ch::Runner<'a, MTU>, |     ch: ch::Runner<'a, MTU>, | ||||||
|     state_ch: ch::StateRunner<'a>, |     state_ch: ch::StateRunner<'a>, | ||||||
| @@ -166,6 +176,7 @@ where | |||||||
| { | { | ||||||
|     async fn init(&mut self) {} |     async fn init(&mut self) {} | ||||||
|  |  | ||||||
|  |     /// Run the packet processing. | ||||||
|     pub async fn run(mut self) -> ! { |     pub async fn run(mut self) -> ! { | ||||||
|         debug!("resetting..."); |         debug!("resetting..."); | ||||||
|         self.reset.set_low().unwrap(); |         self.reset.set_low().unwrap(); | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ use heapless::{String, Vec}; | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct ScanResult { | pub(crate) struct ScanResult { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -19,7 +19,7 @@ pub struct ScanResult { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct ConnectedStaList { | pub(crate) struct ConnectedStaList { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mac: String<32>, |     pub mac: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -29,14 +29,14 @@ pub struct ConnectedStaList { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetMacAddress { | pub(crate) struct CtrlMsgReqGetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mode: u32, |     pub mode: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetMacAddress { | pub(crate) struct CtrlMsgRespGetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mac: String<32>, |     pub mac: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -45,11 +45,11 @@ pub struct CtrlMsgRespGetMacAddress { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetMode {} | pub(crate) struct CtrlMsgReqGetMode {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetMode { | pub(crate) struct CtrlMsgRespGetMode { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mode: u32, |     pub mode: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -58,32 +58,32 @@ pub struct CtrlMsgRespGetMode { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetMode { | pub(crate) struct CtrlMsgReqSetMode { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mode: u32, |     pub mode: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetMode { | pub(crate) struct CtrlMsgRespSetMode { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetStatus {} | pub(crate) struct CtrlMsgReqGetStatus {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetStatus { | pub(crate) struct CtrlMsgRespGetStatus { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetMacAddress { | pub(crate) struct CtrlMsgReqSetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub mac: String<32>, |     pub mac: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -92,18 +92,18 @@ pub struct CtrlMsgReqSetMacAddress { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetMacAddress { | pub(crate) struct CtrlMsgRespSetMacAddress { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetApConfig {} | pub(crate) struct CtrlMsgReqGetApConfig {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetApConfig { | pub(crate) struct CtrlMsgRespGetApConfig { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -120,7 +120,7 @@ pub struct CtrlMsgRespGetApConfig { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqConnectAp { | pub(crate) struct CtrlMsgReqConnectAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -135,7 +135,7 @@ pub struct CtrlMsgReqConnectAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespConnectAp { | pub(crate) struct CtrlMsgRespConnectAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -144,11 +144,11 @@ pub struct CtrlMsgRespConnectAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetSoftApConfig {} | pub(crate) struct CtrlMsgReqGetSoftApConfig {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetSoftApConfig { | pub(crate) struct CtrlMsgRespGetSoftApConfig { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -169,7 +169,7 @@ pub struct CtrlMsgRespGetSoftApConfig { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqStartSoftAp { | pub(crate) struct CtrlMsgReqStartSoftAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ssid: String<32>, |     pub ssid: String<32>, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -188,7 +188,7 @@ pub struct CtrlMsgReqStartSoftAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespStartSoftAp { | pub(crate) struct CtrlMsgRespStartSoftAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -197,11 +197,11 @@ pub struct CtrlMsgRespStartSoftAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqScanResult {} | pub(crate) struct CtrlMsgReqScanResult {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespScanResult { | pub(crate) struct CtrlMsgRespScanResult { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub count: u32, |     pub count: u32, | ||||||
|     #[noproto(repeated, tag = "2")] |     #[noproto(repeated, tag = "2")] | ||||||
| @@ -212,11 +212,11 @@ pub struct CtrlMsgRespScanResult { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSoftApConnectedSta {} | pub(crate) struct CtrlMsgReqSoftApConnectedSta {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSoftApConnectedSta { | pub(crate) struct CtrlMsgRespSoftApConnectedSta { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub num: u32, |     pub num: u32, | ||||||
|     #[noproto(repeated, tag = "2")] |     #[noproto(repeated, tag = "2")] | ||||||
| @@ -227,43 +227,43 @@ pub struct CtrlMsgRespSoftApConnectedSta { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqOtaBegin {} | pub(crate) struct CtrlMsgReqOtaBegin {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespOtaBegin { | pub(crate) struct CtrlMsgRespOtaBegin { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqOtaWrite { | pub(crate) struct CtrlMsgReqOtaWrite { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub ota_data: Vec<u8, 1024>, |     pub ota_data: Vec<u8, 1024>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespOtaWrite { | pub(crate) struct CtrlMsgRespOtaWrite { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqOtaEnd {} | pub(crate) struct CtrlMsgReqOtaEnd {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespOtaEnd { | pub(crate) struct CtrlMsgRespOtaEnd { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqVendorIeData { | pub(crate) struct CtrlMsgReqVendorIeData { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub element_id: u32, |     pub element_id: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -278,7 +278,7 @@ pub struct CtrlMsgReqVendorIeData { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetSoftApVendorSpecificIe { | pub(crate) struct CtrlMsgReqSetSoftApVendorSpecificIe { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub enable: bool, |     pub enable: bool, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -291,32 +291,32 @@ pub struct CtrlMsgReqSetSoftApVendorSpecificIe { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetSoftApVendorSpecificIe { | pub(crate) struct CtrlMsgRespSetSoftApVendorSpecificIe { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqSetWifiMaxTxPower { | pub(crate) struct CtrlMsgReqSetWifiMaxTxPower { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub wifi_max_tx_power: u32, |     pub wifi_max_tx_power: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespSetWifiMaxTxPower { | pub(crate) struct CtrlMsgRespSetWifiMaxTxPower { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqGetWifiCurrTxPower {} | pub(crate) struct CtrlMsgReqGetWifiCurrTxPower {} | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespGetWifiCurrTxPower { | pub(crate) struct CtrlMsgRespGetWifiCurrTxPower { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub wifi_curr_tx_power: u32, |     pub wifi_curr_tx_power: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -325,7 +325,7 @@ pub struct CtrlMsgRespGetWifiCurrTxPower { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgReqConfigHeartbeat { | pub(crate) struct CtrlMsgReqConfigHeartbeat { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub enable: bool, |     pub enable: bool, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -334,7 +334,7 @@ pub struct CtrlMsgReqConfigHeartbeat { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgRespConfigHeartbeat { | pub(crate) struct CtrlMsgRespConfigHeartbeat { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
| @@ -342,28 +342,28 @@ pub struct CtrlMsgRespConfigHeartbeat { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventEspInit { | pub(crate) struct CtrlMsgEventEspInit { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub init_data: Vec<u8, 64>, |     pub init_data: Vec<u8, 64>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventHeartbeat { | pub(crate) struct CtrlMsgEventHeartbeat { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub hb_num: u32, |     pub hb_num: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventStationDisconnectFromAp { | pub(crate) struct CtrlMsgEventStationDisconnectFromAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsgEventStationDisconnectFromEspSoftAp { | pub(crate) struct CtrlMsgEventStationDisconnectFromEspSoftAp { | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub resp: u32, |     pub resp: u32, | ||||||
|     #[noproto(tag = "2")] |     #[noproto(tag = "2")] | ||||||
| @@ -372,7 +372,7 @@ pub struct CtrlMsgEventStationDisconnectFromEspSoftAp { | |||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | #[derive(Debug, Default, Clone, Eq, PartialEq, noproto::Message)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub struct CtrlMsg { | pub(crate) struct CtrlMsg { | ||||||
|     /// msg_type could be req, resp or Event |     /// msg_type could be req, resp or Event | ||||||
|     #[noproto(tag = "1")] |     #[noproto(tag = "1")] | ||||||
|     pub msg_type: CtrlMsgType, |     pub msg_type: CtrlMsgType, | ||||||
| @@ -390,7 +390,7 @@ pub struct CtrlMsg { | |||||||
| /// union of all msg ids | /// union of all msg ids | ||||||
| #[derive(Debug, Clone, Eq, PartialEq, noproto::Oneof)] | #[derive(Debug, Clone, Eq, PartialEq, noproto::Oneof)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlMsgPayload { | pub(crate) enum CtrlMsgPayload { | ||||||
|     /// * Requests * |     /// * Requests * | ||||||
|     #[noproto(tag = "101")] |     #[noproto(tag = "101")] | ||||||
|     ReqGetMacAddress(CtrlMsgReqGetMacAddress), |     ReqGetMacAddress(CtrlMsgReqGetMacAddress), | ||||||
| @@ -492,7 +492,7 @@ pub enum CtrlMsgPayload { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlVendorIeType { | pub(crate) enum CtrlVendorIeType { | ||||||
|     #[default] |     #[default] | ||||||
|     Beacon = 0, |     Beacon = 0, | ||||||
|     ProbeReq = 1, |     ProbeReq = 1, | ||||||
| @@ -504,7 +504,7 @@ pub enum CtrlVendorIeType { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlVendorIeid { | pub(crate) enum CtrlVendorIeid { | ||||||
|     #[default] |     #[default] | ||||||
|     Id0 = 0, |     Id0 = 0, | ||||||
|     Id1 = 1, |     Id1 = 1, | ||||||
| @@ -513,7 +513,7 @@ pub enum CtrlVendorIeid { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlWifiMode { | pub(crate) enum CtrlWifiMode { | ||||||
|     #[default] |     #[default] | ||||||
|     None = 0, |     None = 0, | ||||||
|     Sta = 1, |     Sta = 1, | ||||||
| @@ -524,7 +524,7 @@ pub enum CtrlWifiMode { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlWifiBw { | pub(crate) enum CtrlWifiBw { | ||||||
|     #[default] |     #[default] | ||||||
|     BwInvalid = 0, |     BwInvalid = 0, | ||||||
|     Ht20 = 1, |     Ht20 = 1, | ||||||
| @@ -534,13 +534,15 @@ pub enum CtrlWifiBw { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlWifiPowerSave { | pub(crate) enum CtrlWifiPowerSave { | ||||||
|     #[default] |     #[default] | ||||||
|     PsInvalid = 0, |     PsInvalid = 0, | ||||||
|     MinModem = 1, |     MinModem = 1, | ||||||
|     MaxModem = 2, |     MaxModem = 2, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Wifi Security Settings | ||||||
|  | #[allow(missing_docs)] | ||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| @@ -560,7 +562,7 @@ pub enum CtrlWifiSecProt { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlStatus { | pub(crate) enum CtrlStatus { | ||||||
|     #[default] |     #[default] | ||||||
|     Connected = 0, |     Connected = 0, | ||||||
|     NotConnected = 1, |     NotConnected = 1, | ||||||
| @@ -573,7 +575,7 @@ pub enum CtrlStatus { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlMsgType { | pub(crate) enum CtrlMsgType { | ||||||
|     #[default] |     #[default] | ||||||
|     MsgTypeInvalid = 0, |     MsgTypeInvalid = 0, | ||||||
|     Req = 1, |     Req = 1, | ||||||
| @@ -585,7 +587,7 @@ pub enum CtrlMsgType { | |||||||
| #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord, noproto::Enumeration)] | ||||||
| #[repr(u32)] | #[repr(u32)] | ||||||
| #[cfg_attr(feature = "defmt", derive(defmt::Format))] | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||||||
| pub enum CtrlMsgId { | pub(crate) enum CtrlMsgId { | ||||||
|     #[default] |     #[default] | ||||||
|     MsgIdInvalid = 0, |     MsgIdInvalid = 0, | ||||||
|     /// * Request Msgs * |     /// * Request Msgs * | ||||||
|   | |||||||
| @@ -130,7 +130,7 @@ impl RtcTimeProvider { | |||||||
|             let weekday = day_of_week_from_u8(dr.wdu()).map_err(RtcError::InvalidDateTime)?; |             let weekday = day_of_week_from_u8(dr.wdu()).map_err(RtcError::InvalidDateTime)?; | ||||||
|             let day = bcd2_to_byte((dr.dt(), dr.du())); |             let day = bcd2_to_byte((dr.dt(), dr.du())); | ||||||
|             let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); |             let month = bcd2_to_byte((dr.mt() as u8, dr.mu())); | ||||||
|             let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 1970_u16; |             let year = bcd2_to_byte((dr.yt(), dr.yu())) as u16 + 2000_u16; | ||||||
|  |  | ||||||
|             DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) |             DateTime::from(year, month, day, weekday, hour, minute, second).map_err(RtcError::InvalidDateTime) | ||||||
|         }) |         }) | ||||||
| @@ -261,7 +261,7 @@ impl Rtc { | |||||||
|             let (dt, du) = byte_to_bcd2(t.day() as u8); |             let (dt, du) = byte_to_bcd2(t.day() as u8); | ||||||
|             let (mt, mu) = byte_to_bcd2(t.month() as u8); |             let (mt, mu) = byte_to_bcd2(t.month() as u8); | ||||||
|             let yr = t.year() as u16; |             let yr = t.year() as u16; | ||||||
|             let yr_offset = (yr - 1970_u16) as u8; |             let yr_offset = (yr - 2000_u16) as u8; | ||||||
|             let (yt, yu) = byte_to_bcd2(yr_offset); |             let (yt, yu) = byte_to_bcd2(yr_offset); | ||||||
|  |  | ||||||
|             use crate::pac::rtc::vals::Ampm; |             use crate::pac::rtc::vals::Ampm; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user