1pub(crate) mod cmd;
2pub(crate) mod debug;
3pub(crate) mod handler;
4pub(crate) mod op;
5pub(crate) mod request;
6pub(crate) mod response;
7
8use crate::{cmd::UsbIpHeader, handler::SocketHandler, request::UsbIpCmdSubmit};
9use std::{
10 collections::VecDeque,
11 sync::{Arc, Mutex, MutexGuard},
12};
13use usb_device::{
14 Result as UsbResult, UsbDirection, UsbError,
15 {
16 bus::{PollResult, UsbBus},
17 endpoint::{EndpointAddress, EndpointType},
18 },
19};
20
21#[derive(Debug, Clone)]
22pub enum UsbIpError {
24 ConnectionClosed,
26
27 PkgTooShort(usize),
29
30 InvalidCommand(u16),
32
33 StatusNotOk(u32),
35}
36
37impl std::fmt::Display for UsbIpError {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 match self {
40 Self::ConnectionClosed => write!(f, "connection no longer exsists"),
41 Self::PkgTooShort(len) => write!(f, "packet of length {} is to short to parse", len),
42 Self::InvalidCommand(cmd) => write!(f, "unknown command: {}", cmd),
43 Self::StatusNotOk(status) => write!(f, "received invalid status: {}", status),
44 }
45 }
46}
47
48impl std::error::Error for UsbIpError {}
49
50const NUM_ENDPOINTS: usize = 8;
51
52#[derive(Debug, Clone)]
53pub(crate) struct Pipe {
54 pub data: VecDeque<Vec<u8>>,
55 pub ty: EndpointType,
56 pub max_packet_size: u16,
57 #[allow(dead_code)]
58 pub interval: u8,
59}
60
61impl Pipe {
62 pub fn is_rts(&self) -> bool {
65 match self.data.back() {
66 None => false,
68 Some(val) => {
69 if self.ty != EndpointType::Control {
70 true
71 } else {
72 val.len() < self.max_packet_size as usize
75 }
76 }
77 }
78 }
79}
80
81#[derive(Debug, Clone)]
82struct Endpoint {
83 pub(crate) pipe_in: Option<Pipe>,
84 pub(crate) pipe_out: Option<Pipe>,
85 pub(crate) pending_ins: VecDeque<(UsbIpHeader, UsbIpCmdSubmit, Vec<u8>)>,
86 pub(crate) stalled: bool,
87 pub(crate) setup_flag: bool,
88 pub(crate) in_complete_flag: bool,
89}
90
91impl Default for Endpoint {
92 fn default() -> Self {
93 Self {
94 pipe_in: None,
95 pipe_out: None,
96 pending_ins: VecDeque::new(),
97 stalled: true,
98 setup_flag: false,
99 in_complete_flag: false,
100 }
101 }
102}
103
104impl Endpoint {
105 fn get_in(&mut self) -> UsbResult<&mut Pipe> {
107 self.pipe_in.as_mut().ok_or(UsbError::InvalidEndpoint)
108 }
109
110 fn get_out(&mut self) -> UsbResult<&mut Pipe> {
112 self.pipe_out.as_mut().ok_or(UsbError::InvalidEndpoint)
113 }
114
115 fn is_rts(&self) -> bool {
117 match self.pipe_in {
118 None => false,
119 Some(ref pipe) => pipe.is_rts(),
120 }
121 }
122
123 fn unlink(&mut self, seqnum: u32) -> bool {
130 let old_len = self.pending_ins.len();
131
132 self.pending_ins = self
133 .pending_ins
134 .drain(..)
135 .filter(|(header, _, _)| header.seqnum != seqnum)
136 .collect();
137
138 old_len != self.pending_ins.len()
141 }
142}
143
144#[derive(Debug)]
145pub(crate) struct UsbIpBusInner {
146 pub handler: SocketHandler,
147 pub endpoint: [Endpoint; NUM_ENDPOINTS],
148 pub device_address: u8,
149 pub reset: bool,
150 pub suspended: bool,
151}
152
153impl UsbIpBusInner {
154 fn new() -> Self {
156 Self {
157 handler: SocketHandler::new(),
158 endpoint: <[Endpoint; NUM_ENDPOINTS]>::default(),
159 device_address: 0,
160 reset: true,
161 suspended: false,
162 }
163 }
164
165 fn reset(&mut self) {
167 self.endpoint = <[Endpoint; NUM_ENDPOINTS]>::default();
168 self.reset = true;
169 self.suspended = false;
170 }
171
172 fn next_available_endpoint(&self, direction: UsbDirection) -> Option<usize> {
175 match direction {
176 UsbDirection::In => {
177 for i in 1..NUM_ENDPOINTS {
178 if self.endpoint[i].pipe_in.is_none() {
179 return Some(i);
180 }
181 }
182 }
183 UsbDirection::Out => {
184 for i in 1..NUM_ENDPOINTS {
185 if self.endpoint[i].pipe_out.is_none() {
186 return Some(i);
187 }
188 }
189 }
190 }
191
192 None
193 }
194
195 fn get_endpoint(&mut self, ep: usize) -> UsbResult<&mut Endpoint> {
198 if ep >= NUM_ENDPOINTS {
201 log::error!("attempt to access out-of-bounds endpoint {:?}", ep);
202 return Err(UsbError::InvalidEndpoint);
203 }
204
205 Ok(&mut self.endpoint[ep])
206 }
207
208 fn unlink(&mut self, seqnum: u32) -> bool {
214 for i in 0..NUM_ENDPOINTS {
215 if self.endpoint[i].unlink(seqnum) {
216 return true;
217 }
218 }
219
220 false
221 }
222}
223
224#[derive(Debug, Clone)]
225pub struct UsbIpBus(Arc<Mutex<UsbIpBusInner>>);
228
229impl UsbIpBus {
230 pub fn new() -> Self {
239 Self(Arc::new(Mutex::new(UsbIpBusInner::new())))
240 }
241
242 fn lock(&self) -> MutexGuard<UsbIpBusInner> {
243 self.0.lock().unwrap()
244 }
245}
246
247impl Default for UsbIpBus {
248 fn default() -> Self {
249 Self::new()
250 }
251}
252
253impl UsbBus for UsbIpBus {
254 fn alloc_ep(
255 &mut self,
256 ep_dir: UsbDirection,
257 ep_addr: Option<EndpointAddress>,
258 ep_type: EndpointType,
259 max_packet_size: u16,
260 interval: u8,
261 ) -> UsbResult<EndpointAddress> {
262 let mut inner = self.lock();
263
264 let endpoint_index = match ep_addr {
266 Some(addr) => {
267 if addr.index() < NUM_ENDPOINTS {
268 addr.index()
269 } else {
270 return Err(UsbError::InvalidEndpoint);
271 }
272 }
273 None => inner
274 .next_available_endpoint(ep_dir)
275 .ok_or(UsbError::EndpointMemoryOverflow)?,
276 };
277
278 let endpoint = &mut inner.endpoint[endpoint_index as usize];
279
280 let maybe_pipe = match ep_dir {
282 UsbDirection::In => endpoint.get_in(),
283 UsbDirection::Out => endpoint.get_out(),
284 };
285
286 match maybe_pipe {
289 Err(UsbError::InvalidEndpoint) => (),
290 Ok(_) => return Err(UsbError::InvalidEndpoint),
291 Err(_) => return Err(UsbError::InvalidEndpoint),
292 }
293
294 let pipe = Pipe {
296 data: VecDeque::new(),
297 ty: ep_type,
298 max_packet_size,
299 interval,
300 };
301 match ep_dir {
302 UsbDirection::In => endpoint.pipe_in = Some(pipe),
303 UsbDirection::Out => endpoint.pipe_out = Some(pipe),
304 }
305
306 log::debug!(
307 "initialized new endpoint {:?} as address {:?}",
308 endpoint,
309 endpoint_index
310 );
311
312 Ok(EndpointAddress::from_parts(endpoint_index as usize, ep_dir))
313 }
314
315 fn enable(&mut self) {
316 log::info!("usb device is being enabled");
317 }
318
319 fn reset(&self) {
320 let mut inner = self.lock();
321
322 if inner.reset {
324 return;
325 }
326
327 inner.reset();
328 log::debug!("usb device is being reset");
329 }
330
331 fn set_device_address(&self, addr: u8) {
332 let mut inner = self.lock();
333
334 log::info!("setting device address to {}", addr);
335 inner.device_address = addr;
336 }
337
338 fn write(&self, ep_addr: EndpointAddress, buf: &[u8]) -> UsbResult<usize> {
339 log::trace!("write request at endpoint {}", ep_addr.index());
340 let mut inner = self.lock();
341
342 if !inner.handler.is_connected() {
344 return Err(UsbError::WouldBlock);
345 }
346
347 let ep = inner.get_endpoint(ep_addr.index())?;
349
350 if ep_addr.index() == 0 {
353 ep.in_complete_flag = true;
354 }
355
356 let pipe = ep.get_in()?;
357
358 if pipe.is_rts() {
360 if ep_addr.index() == 0 {
361 ep.in_complete_flag = false;
362 }
363 return Err(UsbError::WouldBlock);
364 }
365
366 pipe.data.push_back(buf.to_vec());
367
368 if pipe.is_rts() {
370 inner.try_send_pending(ep_addr.index());
371 }
372
373 Ok(buf.len())
374 }
375
376 fn read(&self, ep_addr: EndpointAddress, buf: &mut [u8]) -> UsbResult<usize> {
377 log::trace!("read request at endpoint {}", ep_addr.index());
378 let mut inner = self.lock();
379 let ep = inner.get_endpoint(ep_addr.index())?;
380 let pipe = ep.get_out()?;
381
382 let data = match pipe.data.pop_front() {
384 None => {
385 log::trace!("no data available at endpoint");
386 return Err(UsbError::WouldBlock);
387 }
388 Some(data) => data,
389 };
390
391 if buf.len() < data.len() {
392 buf.copy_from_slice(&data[..buf.len()]);
393 } else {
394 buf[..data.len()].copy_from_slice(&data);
395 }
396 Ok(data.len())
397 }
398
399 fn set_stalled(&self, ep_addr: EndpointAddress, stalled: bool) {
400 let mut inner = self.lock();
401
402 let endpoint = match inner.get_endpoint(ep_addr.index()) {
403 Ok(endpoint) => endpoint,
404 _ => return,
405 };
406
407 if endpoint.stalled != stalled {
408 log::debug!(
409 "setting endpoint {:?} to stalled state {}",
410 ep_addr,
411 stalled
412 );
413 }
414 endpoint.stalled = stalled;
415 }
416
417 fn is_stalled(&self, ep_addr: EndpointAddress) -> bool {
418 let mut inner = self.lock();
419
420 let endpoint = match inner.get_endpoint(ep_addr.index()) {
421 Ok(endpoint) => endpoint,
422 _ => return false,
423 };
424
425 endpoint.stalled
426 }
427
428 fn suspend(&self) {
429 let mut inner = self.lock();
430
431 log::info!("suspending device");
432 if inner.suspended {
433 log::warn!("supending already suspended device");
434 }
435
436 inner.suspended = true;
437 }
438
439 fn resume(&self) {
440 let mut inner = self.lock();
441
442 log::info!("resuming device");
443 if !inner.suspended {
444 log::warn!("resuming already active device");
445 }
446
447 inner.suspended = false;
448 }
449
450 fn poll(&self) -> PollResult {
451 let mut inner = self.lock();
452 log::trace!("usb device is being polled");
453
454 inner.handle_socket();
455
456 if inner.reset {
457 log::trace!("device is in reset state");
458 return PollResult::Reset;
459 }
460
461 if inner.suspended {
462 log::trace!("device is suspended");
463 return PollResult::Suspend;
464 }
465
466 let mut ep_in: u16 = 0;
467 let mut ep_out: u16 = 0;
468 let mut ep_setup: u16 = 0;
469
470 for i in (0..NUM_ENDPOINTS).into_iter().rev() {
471 ep_in <<= 1;
472 ep_out <<= 1;
473 ep_setup <<= 1;
474
475 let ep = &mut inner.endpoint[i];
476
477 if let Some(ref pipe) = ep.pipe_out {
479 if !pipe.data.is_empty() {
480 ep_out |= 1;
481 }
482 }
483
484 if ep.in_complete_flag {
485 ep.in_complete_flag = false;
486 ep_in |= 1;
487 }
488
489 if ep.setup_flag {
490 ep.setup_flag = false;
491 ep_setup |= 1;
492 }
493 }
494
495 PollResult::Data {
496 ep_out,
497 ep_in_complete: ep_in,
498 ep_setup,
499 }
500 }
501}