diff options
Diffstat (limited to 'embassy-stm32-wpan/src/mac/runner.rs')
| -rw-r--r-- | embassy-stm32-wpan/src/mac/runner.rs | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs index 92c74c2ee..acca70019 100644 --- a/embassy-stm32-wpan/src/mac/runner.rs +++ b/embassy-stm32-wpan/src/mac/runner.rs | |||
| @@ -6,12 +6,13 @@ use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; | |||
| 6 | use embassy_sync::channel::Channel; | 6 | use embassy_sync::channel::Channel; |
| 7 | use embassy_sync::mutex::Mutex; | 7 | use embassy_sync::mutex::Mutex; |
| 8 | use embassy_sync::signal::Signal; | 8 | use embassy_sync::signal::Signal; |
| 9 | use smoltcp::wire::Ieee802154FrameType; | ||
| 10 | use smoltcp::wire::ieee802154::Frame; | ||
| 9 | 11 | ||
| 10 | use crate::mac::MTU; | 12 | use crate::mac::MTU; |
| 11 | use crate::mac::commands::*; | 13 | use crate::mac::commands::*; |
| 12 | use crate::mac::driver::NetworkState; | 14 | use crate::mac::driver::NetworkState; |
| 13 | use crate::mac::event::MacEvent; | 15 | use crate::mac::event::MacEvent; |
| 14 | use crate::mac::typedefs::*; | ||
| 15 | use crate::sub::mac::{MacRx, MacTx}; | 16 | use crate::sub::mac::{MacRx, MacTx}; |
| 16 | 17 | ||
| 17 | pub type ZeroCopyPubSub<M, T> = blocking_mutex::Mutex<M, RefCell<Option<Signal<NoopRawMutex, T>>>>; | 18 | pub type ZeroCopyPubSub<M, T> = blocking_mutex::Mutex<M, RefCell<Option<Signal<NoopRawMutex, T>>>>; |
| @@ -68,55 +69,75 @@ impl<'a> Runner<'a> { | |||
| 68 | } | 69 | } |
| 69 | } | 70 | } |
| 70 | 71 | ||
| 72 | async fn send_request<T: MacCommand, U: TryInto<T>>(&self, frame: U) -> Result<(), ()> | ||
| 73 | where | ||
| 74 | (): From<<U as TryInto<T>>::Error>, | ||
| 75 | { | ||
| 76 | let request: T = frame.try_into()?; | ||
| 77 | self.mac_tx.lock().await.send_command(&request).await.map_err(|_| ())?; | ||
| 78 | |||
| 79 | Ok(()) | ||
| 80 | } | ||
| 81 | |||
| 71 | pub async fn run(&'a self) -> ! { | 82 | pub async fn run(&'a self) -> ! { |
| 72 | join::join( | 83 | join::join( |
| 73 | async { | 84 | async { |
| 74 | loop { | 85 | loop { |
| 75 | if let Ok(mac_event) = self.mac_rx.read().await { | 86 | if let Ok(mac_event) = self.mac_rx.read().await { |
| 76 | match mac_event { | 87 | match mac_event { |
| 88 | MacEvent::MlmeAssociateCnf(_) | ||
| 89 | | MacEvent::MlmeDisassociateCnf(_) | ||
| 90 | | MacEvent::MlmeGetCnf(_) | ||
| 91 | | MacEvent::MlmeGtsCnf(_) | ||
| 92 | | MacEvent::MlmeResetCnf(_) | ||
| 93 | | MacEvent::MlmeRxEnableCnf(_) | ||
| 94 | | MacEvent::MlmeScanCnf(_) | ||
| 95 | | MacEvent::MlmeSetCnf(_) | ||
| 96 | | MacEvent::MlmeStartCnf(_) | ||
| 97 | | MacEvent::MlmePollCnf(_) | ||
| 98 | | MacEvent::MlmeDpsCnf(_) | ||
| 99 | | MacEvent::MlmeSoundingCnf(_) | ||
| 100 | | MacEvent::MlmeCalibrateCnf(_) | ||
| 101 | | MacEvent::McpsDataCnf(_) | ||
| 102 | | MacEvent::McpsPurgeCnf(_) => { | ||
| 103 | self.rx_event_channel.lock(|s| { | ||
| 104 | s.borrow().as_ref().map(|signal| signal.signal(mac_event)); | ||
| 105 | }); | ||
| 106 | } | ||
| 77 | MacEvent::McpsDataInd(_) => { | 107 | MacEvent::McpsDataInd(_) => { |
| 108 | // Pattern should match driver | ||
| 78 | self.rx_data_channel.send(mac_event).await; | 109 | self.rx_data_channel.send(mac_event).await; |
| 79 | } | 110 | } |
| 80 | _ => { | 111 | _ => { |
| 81 | self.rx_event_channel.lock(|s| { | 112 | debug!("unhandled mac event: {:#x}", mac_event); |
| 82 | s.borrow().as_ref().map(|signal| signal.signal(mac_event)); | ||
| 83 | }); | ||
| 84 | } | 113 | } |
| 85 | } | 114 | } |
| 86 | } | 115 | } |
| 87 | } | 116 | } |
| 88 | }, | 117 | }, |
| 89 | async { | 118 | async { |
| 90 | let mut msdu_handle = 0x02; | ||
| 91 | |||
| 92 | loop { | 119 | loop { |
| 93 | let (buf, len) = self.tx_data_channel.receive().await; | 120 | let (buf, _) = self.tx_data_channel.receive().await; |
| 94 | let mac_tx = self.mac_tx.lock().await; | 121 | |
| 95 | 122 | // Smoltcp has created this frame, so there's no need to reparse it. | |
| 96 | let pan_id = critical_section::with(|cs| self.network_state.borrow(cs).borrow().pan_id); | 123 | let frame = Frame::new_unchecked(&buf); |
| 97 | 124 | ||
| 98 | // TODO: get the destination address from the packet instead of using the broadcast address | 125 | let result: Result<(), ()> = match frame.frame_type() { |
| 99 | 126 | Ieee802154FrameType::Beacon => Err(()), | |
| 100 | // The mutex should be dropped on the next loop iteration | 127 | Ieee802154FrameType::Data => self.send_request::<DataRequest, _>(frame).await, |
| 101 | mac_tx | 128 | Ieee802154FrameType::Acknowledgement => Err(()), |
| 102 | .send_command( | 129 | Ieee802154FrameType::MacCommand => Err(()), |
| 103 | DataRequest { | 130 | Ieee802154FrameType::Multipurpose => Err(()), |
| 104 | src_addr_mode: AddressMode::Short, | 131 | Ieee802154FrameType::FragmentOrFrak => Err(()), |
| 105 | dst_addr_mode: AddressMode::Short, | 132 | Ieee802154FrameType::Extended => Err(()), |
| 106 | dst_pan_id: PanId(pan_id), | 133 | _ => Err(()), |
| 107 | dst_address: MacAddress::BROADCAST, | 134 | }; |
| 108 | msdu_handle: msdu_handle, | 135 | |
| 109 | ack_tx: 0x00, | 136 | if result.is_err() { |
| 110 | gts_tx: false, | 137 | debug!("failed to parse mac frame"); |
| 111 | security_level: SecurityLevel::Unsecure, | 138 | } else { |
| 112 | ..Default::default() | 139 | trace!("data frame sent!"); |
| 113 | } | 140 | } |
| 114 | .set_buffer(&buf[..len]), | ||
| 115 | ) | ||
| 116 | .await | ||
| 117 | .unwrap(); | ||
| 118 | |||
| 119 | msdu_handle = msdu_handle.wrapping_add(1); | ||
| 120 | 141 | ||
| 121 | // The tx channel should always be of equal capacity to the tx_buf channel | 142 | // The tx channel should always be of equal capacity to the tx_buf channel |
| 122 | self.tx_buf_channel.try_send(buf).unwrap(); | 143 | self.tx_buf_channel.try_send(buf).unwrap(); |
