1use crate::error::{ReadOutcome, Result, UsbSerialError};
7use crate::transport::{BulkIn, BulkOut, ControlRequest, EndpointInfo, InterfaceInfo, Transport};
8use std::collections::VecDeque;
9use std::sync::{Arc, Mutex};
10
11#[derive(Debug, Clone)]
13pub struct RecordedControl {
14 pub request_type: u8,
15 pub request: u8,
16 pub value: u16,
17 pub index: u16,
18 pub data: Vec<u8>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct RecordedBulkOut {
24 pub endpoint: u8,
25 pub data: Vec<u8>,
26}
27
28#[derive(Debug, Default)]
29struct FakeState {
30 device_descriptor: [u8; 18],
31 raw_descriptors: Vec<u8>,
32 interfaces: Vec<InterfaceInfo>,
33 endpoints: Vec<(u8, EndpointInfo)>,
34 recorded: Vec<RecordedControl>,
35 recorded_bulk_out: Vec<RecordedBulkOut>,
36 control_in_responses: Vec<Vec<u8>>,
37 interrupt_in_queue: VecDeque<u8>,
38 rx_queue: VecDeque<u8>,
39 tx_log: Vec<u8>,
40 bulk_read_error: Option<String>,
41 claimed: Vec<u8>,
42 open_endpoints: Vec<u8>,
44}
45
46#[derive(Debug, Clone)]
48pub struct FakeTransport {
49 inner: Arc<Mutex<FakeState>>,
50}
51
52impl Default for FakeTransport {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58impl FakeTransport {
59 pub fn new() -> Self {
61 Self::cdc_single_iface()
62 }
63
64 pub fn cdc_single_iface() -> Self {
66 let t = Self {
67 inner: Arc::new(Mutex::new(FakeState::default())),
68 };
69 {
70 let mut s = t.inner.lock().unwrap();
71 s.device_descriptor = [
72 18, 1, 0x00, 0x02, 0x02, 0x00, 0x00, 64, 0x34, 0x12, 0x78, 0x56, 0x00, 0x01, 0x01,
73 0x02, 0x00, 1,
74 ];
75 s.interfaces = vec![InterfaceInfo {
76 id: 0,
77 class: 2,
78 subclass: 2,
79 protocol: 0,
80 }];
81 s.endpoints = vec![
82 (
83 0,
84 EndpointInfo {
85 address: 0x81,
86 attributes: 2,
87 max_packet_size: 64,
88 interval: 0,
89 },
90 ),
91 (
92 0,
93 EndpointInfo {
94 address: 0x02,
95 attributes: 2,
96 max_packet_size: 64,
97 interval: 0,
98 },
99 ),
100 ];
101 }
102 t
103 }
104
105 pub fn ftdi_ft232r() -> Self {
107 let t = Self::cdc_single_iface();
108 t.set_vendor_product(0x0403, 0x6001);
109 t.set_interfaces(vec![InterfaceInfo {
110 id: 0,
111 class: 255,
112 subclass: 0,
113 protocol: 0,
114 }]);
115 t.configure_endpoints(&[(
116 0,
117 vec![
118 EndpointInfo {
119 address: 0x81,
120 attributes: 2,
121 max_packet_size: 64,
122 interval: 0,
123 },
124 EndpointInfo {
125 address: 0x02,
126 attributes: 2,
127 max_packet_size: 64,
128 interval: 0,
129 },
130 ],
131 )]);
132 t
133 }
134
135 pub fn ftdi_ft2232() -> Self {
136 let t = Self::ftdi_ft232r();
137 t.set_vendor_product(0x0403, 0x6010);
138 t.set_interfaces(vec![
139 InterfaceInfo {
140 id: 0,
141 class: 255,
142 subclass: 0,
143 protocol: 0,
144 },
145 InterfaceInfo {
146 id: 1,
147 class: 255,
148 subclass: 0,
149 protocol: 0,
150 },
151 ]);
152 t.configure_endpoints(&[
153 (
154 0,
155 vec![
156 EndpointInfo {
157 address: 0x81,
158 attributes: 2,
159 max_packet_size: 64,
160 interval: 0,
161 },
162 EndpointInfo {
163 address: 0x02,
164 attributes: 2,
165 max_packet_size: 64,
166 interval: 0,
167 },
168 ],
169 ),
170 (
171 1,
172 vec![
173 EndpointInfo {
174 address: 0x83,
175 attributes: 2,
176 max_packet_size: 64,
177 interval: 0,
178 },
179 EndpointInfo {
180 address: 0x04,
181 attributes: 2,
182 max_packet_size: 64,
183 interval: 0,
184 },
185 ],
186 ),
187 ]);
188 t.patch_device_descriptor(|d| d[13] = 7);
189 t
190 }
191
192 pub fn cp2102() -> Self {
193 Self::ftdi_ft232r().also(|t| t.set_vendor_product(0x10C4, 0xEA60))
194 }
195
196 pub fn cp2105() -> Self {
197 let t = Self::cp2102();
198 t.set_vendor_product(0x10C4, 0xEA70);
199 t.set_interfaces(vec![
200 InterfaceInfo {
201 id: 0,
202 class: 255,
203 subclass: 0,
204 protocol: 0,
205 },
206 InterfaceInfo {
207 id: 1,
208 class: 255,
209 subclass: 0,
210 protocol: 0,
211 },
212 ]);
213 t.configure_endpoints(&[
214 (
215 0,
216 vec![
217 EndpointInfo {
218 address: 0x81,
219 attributes: 2,
220 max_packet_size: 64,
221 interval: 0,
222 },
223 EndpointInfo {
224 address: 0x02,
225 attributes: 2,
226 max_packet_size: 64,
227 interval: 0,
228 },
229 ],
230 ),
231 (
232 1,
233 vec![
234 EndpointInfo {
235 address: 0x83,
236 attributes: 2,
237 max_packet_size: 64,
238 interval: 0,
239 },
240 EndpointInfo {
241 address: 0x04,
242 attributes: 2,
243 max_packet_size: 64,
244 interval: 0,
245 },
246 ],
247 ),
248 ]);
249 t
250 }
251
252 pub fn ch340_dual_iface() -> Self {
253 let t = Self::cdc_single_iface();
254 t.set_vendor_product(0x1A86, 0x7523);
255 t.set_interfaces(vec![
256 InterfaceInfo {
257 id: 0,
258 class: 255,
259 subclass: 0,
260 protocol: 0,
261 },
262 InterfaceInfo {
263 id: 1,
264 class: 255,
265 subclass: 0,
266 protocol: 0,
267 },
268 ]);
269 t.configure_endpoints(&[(
270 1,
271 vec![
272 EndpointInfo {
273 address: 0x82,
274 attributes: 2,
275 max_packet_size: 64,
276 interval: 0,
277 },
278 EndpointInfo {
279 address: 0x03,
280 attributes: 2,
281 max_packet_size: 64,
282 interval: 0,
283 },
284 ],
285 )]);
286 t
287 }
288
289 pub fn pl2303_hx() -> Self {
290 let t = Self::cdc_single_iface();
291 t.set_vendor_product(0x067B, 0x2303);
292 t.patch_device_descriptor(|d| d[4] = 0);
293 t.configure_endpoints(&[(
294 0,
295 vec![
296 EndpointInfo {
297 address: 0x81,
298 attributes: 3,
299 max_packet_size: 64,
300 interval: 1,
301 },
302 EndpointInfo {
303 address: 0x02,
304 attributes: 2,
305 max_packet_size: 64,
306 interval: 0,
307 },
308 EndpointInfo {
309 address: 0x83,
310 attributes: 2,
311 max_packet_size: 64,
312 interval: 0,
313 },
314 ],
315 )]);
316 t.set_interfaces(vec![InterfaceInfo {
317 id: 0,
318 class: 255,
319 subclass: 0,
320 protocol: 0,
321 }]);
322 t
323 }
324
325 pub fn pl2303_hxn() -> Self {
326 let t = Self::pl2303_hx();
327 t.patch_device_descriptor(|d| {
328 d[4] = 0x00;
329 d[7] = 64;
330 d[2] = 0x00;
331 d[3] = 0x02;
332 });
333 t
334 }
335
336 pub fn pl2303_type01() -> Self {
337 let t = Self::pl2303_hx();
338 t.patch_device_descriptor(|d| d[4] = 0x02);
339 t
340 }
341
342 pub fn pl2303_ta() -> Self {
343 let t = Self::pl2303_hx();
344 t.patch_device_descriptor(|d| {
345 d[2] = 0x00;
346 d[3] = 0x02;
347 d[12] = 0x00;
348 d[13] = 0x03;
349 });
350 t
351 }
352
353 pub fn cdc_iad() -> Self {
354 let t = Self::cdc_single_iface();
355 t.set_vendor_product(0x2341, 0x0043);
356 t.patch_device_descriptor(|d| {
357 d[4] = 0xEF;
358 d[5] = 0x02;
359 d[6] = 0x01;
360 });
361 let i0 = InterfaceInfo {
362 id: 0,
363 class: 2,
364 subclass: 2,
365 protocol: 0,
366 };
367 let i1 = InterfaceInfo {
368 id: 1,
369 class: 10,
370 subclass: 0,
371 protocol: 0,
372 };
373 t.set_interfaces(vec![i0, i1]);
374 t.configure_endpoints(&[
375 (
376 0,
377 vec![EndpointInfo {
378 address: 0x81,
379 attributes: 3,
380 max_packet_size: 64,
381 interval: 1,
382 }],
383 ),
384 (
385 1,
386 vec![
387 EndpointInfo {
388 address: 0x82,
389 attributes: 2,
390 max_packet_size: 64,
391 interval: 0,
392 },
393 EndpointInfo {
394 address: 0x03,
395 attributes: 2,
396 max_packet_size: 64,
397 interval: 0,
398 },
399 ],
400 ),
401 ]);
402 t.set_raw_descriptors(vec![
404 9, 4, 0, 0, 1, 2, 2, 0, 0, 7, 5, 0x81, 3, 64, 0, 1, 9, 4, 1, 0, 2, 10, 0, 0, 7, 5,
405 0x82, 2, 64, 0, 7, 5, 0x03, 2, 64, 0, 8, 11, 0, 2, 2, 2, 0, 0,
406 ]);
407 t
408 }
409
410 pub fn cdc_multi() -> Self {
411 let t = Self::cdc_iad();
412 t.set_interfaces(vec![
413 InterfaceInfo {
414 id: 0,
415 class: 2,
416 subclass: 2,
417 protocol: 0,
418 },
419 InterfaceInfo {
420 id: 1,
421 class: 10,
422 subclass: 0,
423 protocol: 0,
424 },
425 InterfaceInfo {
426 id: 2,
427 class: 2,
428 subclass: 2,
429 protocol: 0,
430 },
431 InterfaceInfo {
432 id: 3,
433 class: 10,
434 subclass: 0,
435 protocol: 0,
436 },
437 ]);
438 t.configure_endpoints(&[
439 (
440 1,
441 vec![
442 EndpointInfo {
443 address: 0x82,
444 attributes: 2,
445 max_packet_size: 64,
446 interval: 0,
447 },
448 EndpointInfo {
449 address: 0x03,
450 attributes: 2,
451 max_packet_size: 64,
452 interval: 0,
453 },
454 ],
455 ),
456 (
457 3,
458 vec![
459 EndpointInfo {
460 address: 0x84,
461 attributes: 2,
462 max_packet_size: 64,
463 interval: 0,
464 },
465 EndpointInfo {
466 address: 0x05,
467 attributes: 2,
468 max_packet_size: 64,
469 interval: 0,
470 },
471 ],
472 ),
473 ]);
474 t
475 }
476
477 pub fn gsm_modem() -> Self {
478 let t = Self::cdc_single_iface();
479 t.set_vendor_product(0x1782, 0x4D10);
480 t.set_interfaces(vec![InterfaceInfo {
481 id: 0,
482 class: 255,
483 subclass: 0,
484 protocol: 0,
485 }]);
486 t.configure_endpoints(&[(
487 0,
488 vec![
489 EndpointInfo {
490 address: 0x81,
491 attributes: 2,
492 max_packet_size: 64,
493 interval: 0,
494 },
495 EndpointInfo {
496 address: 0x02,
497 attributes: 2,
498 max_packet_size: 64,
499 interval: 0,
500 },
501 ],
502 )]);
503 t
504 }
505
506 pub fn chrome_ccd_3port() -> Self {
507 let t = Self::cdc_single_iface();
508 t.set_vendor_product(0x18D1, 0x5014);
509 let mut ifaces = Vec::new();
510 let mut eps = Vec::new();
511 for n in 0..3u8 {
512 ifaces.push(InterfaceInfo {
513 id: n,
514 class: 255,
515 subclass: 0,
516 protocol: 0,
517 });
518 eps.push((
519 n,
520 vec![
521 EndpointInfo {
522 address: 0x81 + n * 2,
523 attributes: 2,
524 max_packet_size: 64,
525 interval: 0,
526 },
527 EndpointInfo {
528 address: 0x02 + n * 2,
529 attributes: 2,
530 max_packet_size: 64,
531 interval: 0,
532 },
533 ],
534 ));
535 }
536 t.set_interfaces(ifaces);
537 t.configure_endpoints(&eps);
538 t
539 }
540
541 fn also<F: FnOnce(&Self)>(self, f: F) -> Self {
542 f(&self);
543 self
544 }
545
546 pub fn recorded_bulk_out(&self) -> Vec<RecordedBulkOut> {
547 self.inner.lock().unwrap().recorded_bulk_out.clone()
548 }
549
550 pub fn push_rx(&self, data: &[u8]) {
551 let mut s = self.inner.lock().unwrap();
552 s.rx_queue.extend(data);
553 }
554
555 pub fn push_interrupt_in(&self, data: &[u8]) {
556 let mut s = self.inner.lock().unwrap();
557 s.interrupt_in_queue.extend(data);
558 }
559
560 pub fn take_tx(&self) -> Vec<u8> {
562 let mut s = self.inner.lock().unwrap();
563 std::mem::take(&mut s.tx_log)
564 }
565
566 pub fn recorded_controls(&self) -> Vec<RecordedControl> {
568 self.inner.lock().unwrap().recorded.clone()
569 }
570
571 pub fn clear_recorded(&self) {
572 let mut s = self.inner.lock().unwrap();
573 s.recorded.clear();
574 s.recorded_bulk_out.clear();
575 }
576
577 pub fn claimed_interfaces(&self) -> Vec<u8> {
578 self.inner.lock().unwrap().claimed.clone()
579 }
580
581 pub fn script_control_in_response(&self, data: Vec<u8>) {
583 self.inner.lock().unwrap().control_in_responses.push(data);
584 }
585
586 pub fn inject_bulk_read_error(&self, msg: impl Into<String>) {
587 self.inner.lock().unwrap().bulk_read_error = Some(msg.into());
588 }
589
590 pub fn set_interfaces(&self, interfaces: Vec<InterfaceInfo>) {
591 self.inner.lock().unwrap().interfaces = interfaces;
592 }
593
594 pub fn configure_endpoints(&self, layout: &[(u8, Vec<EndpointInfo>)]) {
595 let mut s = self.inner.lock().unwrap();
596 s.endpoints = layout
597 .iter()
598 .flat_map(|(iface, eps)| eps.iter().map(move |ep| (*iface, *ep)))
599 .collect();
600 }
601
602 pub fn set_raw_descriptors(&self, raw: Vec<u8>) {
603 self.inner.lock().unwrap().raw_descriptors = raw;
604 }
605
606 pub fn set_vendor_product(&self, vendor_id: u16, product_id: u16) {
607 let mut s = self.inner.lock().unwrap();
608 s.device_descriptor[8] = (vendor_id & 0xff) as u8;
609 s.device_descriptor[9] = (vendor_id >> 8) as u8;
610 s.device_descriptor[10] = (product_id & 0xff) as u8;
611 s.device_descriptor[11] = (product_id >> 8) as u8;
612 }
613
614 pub fn patch_device_descriptor(&self, mut patch: impl FnMut(&mut [u8; 18])) {
615 let mut s = self.inner.lock().unwrap();
616 patch(&mut s.device_descriptor);
617 }
618}
619
620struct FakeBulkIn {
621 inner: Arc<Mutex<FakeState>>,
622 interrupt: bool,
623 endpoint: u8,
624}
625
626impl Drop for FakeBulkIn {
627 fn drop(&mut self) {
628 if let Ok(mut s) = self.inner.lock() {
629 s.open_endpoints.retain(|&e| e != self.endpoint);
630 }
631 }
632}
633
634impl BulkIn for FakeBulkIn {
635 fn read(&mut self, buf: &mut [u8], _timeout_ms: u32) -> Result<ReadOutcome> {
636 let mut s = self.inner.lock().unwrap();
637 if let Some(err) = s.bulk_read_error.take() {
638 return Err(UsbSerialError::Io(err));
639 }
640 let queue = if self.interrupt {
641 &mut s.interrupt_in_queue
642 } else {
643 &mut s.rx_queue
644 };
645 if queue.is_empty() {
646 return Ok(ReadOutcome::TimedOut);
647 }
648 let n = buf.len().min(queue.len());
649 for (i, byte) in queue.drain(..n).enumerate() {
650 buf[i] = byte;
651 }
652 Ok(ReadOutcome::Data(buf[..n].to_vec()))
653 }
654
655 fn cancel_all(&mut self) {}
656
657 fn clear_halt(&mut self) -> Result<()> {
658 Ok(())
659 }
660}
661
662struct FakeBulkOut {
663 inner: Arc<Mutex<FakeState>>,
664 endpoint: u8,
665}
666
667impl Drop for FakeBulkOut {
668 fn drop(&mut self) {
669 if let Ok(mut s) = self.inner.lock() {
670 s.open_endpoints.retain(|&e| e != self.endpoint);
671 }
672 }
673}
674
675impl BulkOut for FakeBulkOut {
676 fn write(&mut self, data: &[u8], _timeout_ms: u32) -> Result<usize> {
677 let mut s = self.inner.lock().unwrap();
678 s.tx_log.extend_from_slice(data);
679 s.recorded_bulk_out.push(RecordedBulkOut {
680 endpoint: self.endpoint,
681 data: data.to_vec(),
682 });
683 Ok(data.len())
684 }
685
686 fn clear_halt(&mut self) -> Result<()> {
687 Ok(())
688 }
689}
690
691impl Transport for FakeTransport {
692 fn raw_device_descriptor(&self) -> [u8; 18] {
693 self.inner.lock().unwrap().device_descriptor
694 }
695
696 fn raw_descriptors(&self) -> Vec<u8> {
697 self.inner.lock().unwrap().raw_descriptors.clone()
698 }
699
700 fn device_class(&self) -> u8 {
701 self.raw_device_descriptor()[4]
702 }
703
704 fn interfaces(&self) -> Vec<InterfaceInfo> {
705 self.inner.lock().unwrap().interfaces.clone()
706 }
707
708 fn endpoints(&self, interface: u8) -> Vec<EndpointInfo> {
709 self.inner
710 .lock()
711 .unwrap()
712 .endpoints
713 .iter()
714 .filter(|(iface, _)| *iface == interface)
715 .map(|(_, ep)| *ep)
716 .collect()
717 }
718
719 fn claim_interface(&self, interface: u8) -> Result<()> {
720 self.inner.lock().unwrap().claimed.push(interface);
721 Ok(())
722 }
723
724 fn release_interface(&self, interface: u8) -> Result<()> {
725 let mut s = self.inner.lock().unwrap();
726 s.claimed.retain(|&i| i != interface);
727 Ok(())
728 }
729
730 fn control_out(&self, req: &ControlRequest) -> Result<usize> {
731 let mut s = self.inner.lock().unwrap();
732 s.recorded.push(RecordedControl {
733 request_type: req.request_type,
734 request: req.request,
735 value: req.value,
736 index: req.index,
737 data: req.data.clone(),
738 });
739 Ok(req.data.len())
740 }
741
742 fn control_in(&self, req: &ControlRequest) -> Result<Vec<u8>> {
743 let mut s = self.inner.lock().unwrap();
744 s.recorded.push(RecordedControl {
745 request_type: req.request_type,
746 request: req.request,
747 value: req.value,
748 index: req.index,
749 data: req.data.clone(),
750 });
751 if let Some(resp) = s.control_in_responses.pop() {
752 return Ok(resp);
753 }
754 Ok(req.data.clone())
755 }
756
757 fn open_bulk_in(&self, endpoint: u8, _max_packet_size: u16) -> Result<Box<dyn BulkIn>> {
758 self.mark_endpoint_open(endpoint)?;
759 Ok(Box::new(FakeBulkIn {
760 inner: self.inner.clone(),
761 interrupt: false,
762 endpoint,
763 }))
764 }
765
766 fn open_bulk_out(&self, endpoint: u8, _max_packet_size: u16) -> Result<Box<dyn BulkOut>> {
767 self.mark_endpoint_open(endpoint)?;
768 Ok(Box::new(FakeBulkOut {
769 inner: self.inner.clone(),
770 endpoint,
771 }))
772 }
773
774 fn open_interrupt_in(&self, endpoint: u8, _max_packet_size: u16) -> Result<Box<dyn BulkIn>> {
775 self.mark_endpoint_open(endpoint)?;
776 Ok(Box::new(FakeBulkIn {
777 inner: self.inner.clone(),
778 interrupt: true,
779 endpoint,
780 }))
781 }
782}
783
784impl FakeTransport {
785 fn mark_endpoint_open(&self, endpoint: u8) -> Result<()> {
786 let mut s = self.inner.lock().unwrap();
787 if s.open_endpoints.contains(&endpoint) {
788 return Err(UsbSerialError::Io("endpoint already in use".into()));
789 }
790 s.open_endpoints.push(endpoint);
791 Ok(())
792 }
793}