diff --git a/embassy-net-esp-hosted/src/control.rs b/embassy-net-esp-hosted/src/control.rs index ec51933b..c98d0ebf 100644 --- a/embassy-net-esp-hosted/src/control.rs +++ b/embassy-net-esp-hosted/src/control.rs @@ -3,7 +3,7 @@ use defmt::Debug2Format; use embassy_net_driver_channel as ch; use heapless::String; -use crate::ioctl::IoctlState; +use crate::ioctl::Shared; use crate::proto::{self, CtrlMsg}; #[derive(Debug)] @@ -13,7 +13,7 @@ pub struct Error { pub struct Control<'a> { state_ch: ch::StateRunner<'a>, - ioctl_state: &'a IoctlState, + shared: &'a Shared, } enum WifiMode { @@ -24,8 +24,8 @@ enum WifiMode { } impl<'a> Control<'a> { - pub(crate) fn new(state_ch: ch::StateRunner<'a>, ioctl_state: &'a IoctlState) -> Self { - Self { state_ch, ioctl_state } + pub(crate) fn new(state_ch: ch::StateRunner<'a>, shared: &'a Shared) -> Self { + Self { state_ch, shared } } pub async fn init(&mut self) { @@ -118,7 +118,7 @@ impl<'a> Control<'a> { let req_len = noproto::write(&req, &mut buf).unwrap(); - struct CancelOnDrop<'a>(&'a IoctlState); + struct CancelOnDrop<'a>(&'a Shared); impl CancelOnDrop<'_> { fn defuse(self) { @@ -128,13 +128,13 @@ impl<'a> Control<'a> { impl Drop for CancelOnDrop<'_> { fn drop(&mut self) { - self.0.cancel_ioctl(); + self.0.ioctl_cancel(); } } - let ioctl = CancelOnDrop(self.ioctl_state); + let ioctl = CancelOnDrop(self.shared); - let resp_len = ioctl.0.do_ioctl(&mut buf, req_len).await; + let resp_len = ioctl.0.ioctl(&mut buf, req_len).await; ioctl.defuse(); diff --git a/embassy-net-esp-hosted/src/ioctl.rs b/embassy-net-esp-hosted/src/ioctl.rs index 689dd2a8..7cbe80b2 100644 --- a/embassy-net-esp-hosted/src/ioctl.rs +++ b/embassy-net-esp-hosted/src/ioctl.rs @@ -13,105 +13,86 @@ pub struct PendingIoctl { } #[derive(Clone, Copy)] -enum IoctlStateInner { +enum IoctlState { Pending(PendingIoctl), Sent { buf: *mut [u8] }, Done { resp_len: usize }, } -struct Wakers { - control: WakerRegistration, - runner: WakerRegistration, +pub struct Shared(RefCell); + +struct SharedInner { + ioctl: IoctlState, + control_waker: WakerRegistration, + runner_waker: WakerRegistration, } -impl Default for Wakers { - fn default() -> Self { - Self { - control: WakerRegistration::new(), - runner: WakerRegistration::new(), - } - } -} - -pub struct IoctlState { - state: Cell, - wakers: RefCell, -} - -impl IoctlState { +impl Shared { pub fn new() -> Self { - Self { - state: Cell::new(IoctlStateInner::Done { resp_len: 0 }), - wakers: Default::default(), - } + Self(RefCell::new(SharedInner { + ioctl: IoctlState::Done { resp_len: 0 }, + control_waker: WakerRegistration::new(), + runner_waker: WakerRegistration::new(), + })) } - fn wake_control(&self) { - self.wakers.borrow_mut().control.wake(); - } - - fn register_control(&self, waker: &Waker) { - self.wakers.borrow_mut().control.register(waker); - } - - fn wake_runner(&self) { - self.wakers.borrow_mut().runner.wake(); - } - - fn register_runner(&self, waker: &Waker) { - self.wakers.borrow_mut().runner.register(waker); - } - - pub async fn wait_complete(&self) -> usize { + pub async fn ioctl_wait_complete(&self) -> usize { poll_fn(|cx| { - if let IoctlStateInner::Done { resp_len } = self.state.get() { + let mut this = self.0.borrow_mut(); + if let IoctlState::Done { resp_len } = this.ioctl { Poll::Ready(resp_len) } else { - self.register_control(cx.waker()); + this.control_waker.register(cx.waker()); Poll::Pending } }) .await } - pub async fn wait_pending(&self) -> PendingIoctl { + pub async fn ioctl_wait_pending(&self) -> PendingIoctl { let pending = poll_fn(|cx| { - if let IoctlStateInner::Pending(pending) = self.state.get() { + let mut this = self.0.borrow_mut(); + if let IoctlState::Pending(pending) = this.ioctl { Poll::Ready(pending) } else { - self.register_runner(cx.waker()); + this.runner_waker.register(cx.waker()); Poll::Pending } }) .await; - self.state.set(IoctlStateInner::Sent { buf: pending.buf }); + self.0.borrow_mut().ioctl = IoctlState::Sent { buf: pending.buf }; pending } - pub fn cancel_ioctl(&self) { - self.state.set(IoctlStateInner::Done { resp_len: 0 }); + pub fn ioctl_cancel(&self) { + self.0.borrow_mut().ioctl = IoctlState::Done { resp_len: 0 }; } - pub async fn do_ioctl(&self, buf: &mut [u8], req_len: usize) -> usize { + pub async fn ioctl(&self, buf: &mut [u8], req_len: usize) -> usize { trace!("ioctl req bytes: {:02x}", Bytes(&buf[..req_len])); - self.state.set(IoctlStateInner::Pending(PendingIoctl { buf, req_len })); - self.wake_runner(); - self.wait_complete().await + { + let mut this = self.0.borrow_mut(); + this.ioctl = IoctlState::Pending(PendingIoctl { buf, req_len }); + this.runner_waker.wake(); + } + + self.ioctl_wait_complete().await } pub fn ioctl_done(&self, response: &[u8]) { - if let IoctlStateInner::Sent { buf } = self.state.get() { + let mut this = self.0.borrow_mut(); + if let IoctlState::Sent { buf } = this.ioctl { trace!("ioctl resp bytes: {:02x}", Bytes(response)); // TODO fix this (unsafe { &mut *buf }[..response.len()]).copy_from_slice(response); - self.state.set(IoctlStateInner::Done { + this.ioctl = IoctlState::Done { resp_len: response.len(), - }); - self.wake_control(); + }; + this.control_waker.wake(); } else { warn!("IOCTL Response but no pending Ioctl"); } diff --git a/embassy-net-esp-hosted/src/lib.rs b/embassy-net-esp-hosted/src/lib.rs index 08400996..700a5221 100644 --- a/embassy-net-esp-hosted/src/lib.rs +++ b/embassy-net-esp-hosted/src/lib.rs @@ -7,7 +7,7 @@ use embassy_time::{Duration, Instant, Timer}; use embedded_hal::digital::{InputPin, OutputPin}; use embedded_hal_async::digital::Wait; use embedded_hal_async::spi::SpiDevice; -use ioctl::IoctlState; +use ioctl::Shared; use proto::CtrlMsg; use crate::ioctl::PendingIoctl; @@ -95,14 +95,14 @@ enum InterfaceType { const MAX_SPI_BUFFER_SIZE: usize = 1600; pub struct State { - ioctl_state: IoctlState, + shared: Shared, ch: ch::State, } impl State { pub fn new() -> Self { Self { - ioctl_state: IoctlState::new(), + shared: Shared::new(), ch: ch::State::new(), } } @@ -127,7 +127,7 @@ where let mut runner = Runner { ch: ch_runner, - ioctl_state: &state.ioctl_state, + shared: &state.shared, next_seq: 1, handshake, ready, @@ -136,12 +136,12 @@ where }; runner.init().await; - (device, Control::new(state_ch, &state.ioctl_state), runner) + (device, Control::new(state_ch, &state.shared), runner) } pub struct Runner<'a, SPI, IN, OUT> { ch: ch::Runner<'a, MTU>, - ioctl_state: &'a IoctlState, + shared: &'a Shared, next_seq: u16, @@ -172,7 +172,7 @@ where loop { self.handshake.wait_for_high().await.unwrap(); - let ioctl = self.ioctl_state.wait_pending(); + let ioctl = self.shared.ioctl_wait_pending(); let tx = self.ch.tx_buf(); let ev = async { self.ready.wait_for_high().await.unwrap() }; @@ -294,7 +294,7 @@ where if isEvent { self.handle_event(data); } else { - self.ioctl_state.ioctl_done(data); + self.shared.ioctl_done(data); } } _ => warn!("unknown iftype {}", if_type_and_num),