Skip to content

Commit 503ecf7

Browse files
committed
Split the control state machine into a separate object.
1 parent 6b606d3 commit 503ecf7

File tree

9 files changed

+724
-596
lines changed

9 files changed

+724
-596
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ version = "0.1.0"
44
authors = ["Matti Virkkunen <[email protected]>"]
55

66
[dependencies]
7-
heapless = "0.2.1"
7+
heapless = "0.2.1"

src/bus.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ impl<B: UsbBus> UsbBusWrapper<B> {
155155
func(&mut *self.bus.borrow_mut())
156156
}
157157

158+
// TODO: There is no need for this whole pointer mess...
158159
pub(crate) fn freeze<'a>(&'a self) -> &B {
159160
mem::forget(self.state.borrow_mut());
160161

src/class.rs

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
use ::Result;
2-
use bus::StringIndex;
3-
use device::{ControlOutResult, ControlInResult};
1+
use ::{Result, UsbError};
2+
use bus::{UsbBus, StringIndex};
43
use descriptor::DescriptorWriter;
54
use control;
65
use endpoint::EndpointAddress;
76

87
/// A trait implemented by USB class implementations.
9-
pub trait UsbClass {
8+
pub trait UsbClass<B: UsbBus> {
109
/// Called after a USB reset after the bus reset sequence is complete.
1110
fn reset(&self) -> Result<()> {
1211
Ok(())
@@ -44,9 +43,8 @@ pub trait UsbClass {
4443
/// * `req` - The request from the SETUP packet.
4544
/// * `data` - Data received in the DATA stage of the control transfer. Empty if there was no
4645
/// DATA stage.
47-
fn control_out(&self, req: &control::Request, data: &[u8]) -> ControlOutResult {
48-
let _ = (req, data);
49-
ControlOutResult::Ignore
46+
fn control_out(&self, xfer: ControlOut<'_, '_, '_, B>) {
47+
let _ = xfer;
5048
}
5149

5250
/// Called when a control request is received with direction DeviceToHost.
@@ -68,9 +66,8 @@ pub trait UsbClass {
6866
///
6967
/// * `req` - The request from the SETUP packet.
7068
/// * `data` - Data to send in the DATA stage of the control transfer.
71-
fn control_in(&self, req: &control::Request, data: &mut [u8]) -> ControlInResult {
72-
let _ = (req, data);
73-
ControlInResult::Ignore
69+
fn control_in(&self, xfer: ControlIn<'_, '_, '_, B>) {
70+
let _ = xfer;
7471
}
7572

7673
/// Called when endpoint with address `addr` has received a SETUP packet. Implementing this
@@ -111,4 +108,60 @@ pub trait UsbClass {
111108
let _ = (index, lang_id);
112109
None
113110
}
111+
}
112+
113+
pub struct ControlIn<'a, 'p, 'o, B: UsbBus + 'a>(&'o mut Option<&'p mut control::ControlPipe<'a, B>>);
114+
115+
impl<'a, 'p, 'o, B: UsbBus + 'a> ControlIn<'a, 'p, 'o, B> {
116+
pub(crate) fn new(pipe: &'o mut Option<&'p mut control::ControlPipe<'a, B>>) -> Self {
117+
ControlIn(pipe)
118+
}
119+
120+
pub fn request(&self) -> &control::Request {
121+
self.0.as_ref().unwrap().request()
122+
}
123+
124+
pub fn accept_with(self, data: &[u8]) -> Result<()> {
125+
self.0.take().unwrap().accept_in(|buf| {
126+
if data.len() > buf.len() {
127+
return Err(UsbError::BufferOverflow);
128+
}
129+
130+
buf[..data.len()].copy_from_slice(data);
131+
132+
Ok(data.len())
133+
})
134+
}
135+
136+
pub fn accept(self, f: impl FnOnce(&mut [u8]) -> Result<usize>) -> Result<()> {
137+
self.0.take().unwrap().accept_in(f)
138+
}
139+
140+
pub fn reject(self) -> Result<()> {
141+
self.0.take().unwrap().reject()
142+
}
143+
}
144+
145+
pub struct ControlOut<'a, 'p, 'o, B: UsbBus + 'a>(&'o mut Option<&'p mut control::ControlPipe<'a, B>>);
146+
147+
impl<'a, 'p, 'o, B: UsbBus + 'a> ControlOut<'a, 'p, 'o, B> {
148+
pub(crate) fn new(pipe: &'o mut Option<&'p mut control::ControlPipe<'a, B>>) -> Self {
149+
ControlOut(pipe)
150+
}
151+
152+
pub fn request(&self) -> &control::Request {
153+
self.0.as_ref().unwrap().request()
154+
}
155+
156+
pub fn data(&self) -> &[u8] {
157+
self.0.as_ref().unwrap().data()
158+
}
159+
160+
pub fn accept(self) -> Result<()> {
161+
self.0.take().unwrap().accept_out()
162+
}
163+
164+
pub fn reject(self) -> Result<()> {
165+
self.0.take().unwrap().reject()
166+
}
114167
}

0 commit comments

Comments
 (0)