crab_usb/backend/ty/ep/
ctrl.rs1use core::ptr::NonNull;
2
3use usb_if::descriptor::{ConfigurationDescriptor, DescriptorType, DeviceDescriptor};
4use usb_if::err::{TransferError, USBError};
5use usb_if::host::ControlSetup;
6use usb_if::transfer::{Direction, Recipient, Request, RequestType};
7
8use crate::backend::ty::transfer::TransferKind;
9
10use super::{EndpointBase, EndpointOp};
11
12pub struct EndpointControl {
13 pub(crate) raw: EndpointBase,
14}
15
16impl EndpointControl {
17 pub(crate) fn new(raw: impl EndpointOp) -> Self {
18 Self {
19 raw: EndpointBase::new(raw),
20 }
21 }
22
23 pub async fn control_in(
24 &mut self,
25 param: usb_if::host::ControlSetup,
26 buff: &mut [u8],
27 ) -> Result<usize, TransferError> {
28 let buff = if buff.is_empty() {
29 None
30 } else {
31 Some((NonNull::new(buff.as_mut_ptr()).unwrap(), buff.len()))
32 };
33
34 let transfer = self
35 .raw
36 .new_transfer(TransferKind::Control(param), Direction::In, buff);
37
38 let t = self.raw.submit_and_wait(transfer).await?;
39 let n = t.transfer_len;
40 Ok(n)
41 }
42
43 pub async fn control_out(
44 &mut self,
45 param: usb_if::host::ControlSetup,
46 buff: &[u8],
47 ) -> Result<usize, TransferError> {
48 let buff = if buff.is_empty() {
49 None
50 } else {
51 Some((
52 NonNull::new(buff.as_ptr() as usize as *mut u8).unwrap(),
53 buff.len(),
54 ))
55 };
56
57 let transfer = self
58 .raw
59 .new_transfer(TransferKind::Control(param), Direction::Out, buff);
60
61 let t = self.raw.submit_and_wait(transfer).await?;
62 let n = t.transfer_len;
63 Ok(n)
64 }
65
66 pub async fn set_configuration(
67 &mut self,
68 configuration_value: u8,
69 ) -> Result<(), TransferError> {
70 self.control_out(
71 ControlSetup {
72 request_type: RequestType::Standard,
73 recipient: Recipient::Device,
74 request: Request::SetConfiguration,
75 value: configuration_value as u16,
76 index: 0,
77 },
78 &[],
79 )
80 .await?;
81 Ok(())
82 }
83
84 pub async fn get_descriptor(
85 &mut self,
86 desc_type: DescriptorType,
87 desc_index: u8,
88 language_id: u16,
89 buff: &mut [u8],
90 ) -> Result<(), TransferError> {
91 self.control_in(
92 ControlSetup {
93 request_type: RequestType::Standard,
94 recipient: Recipient::Device,
95 request: Request::GetDescriptor,
96 value: ((desc_type.0 as u16) << 8) | desc_index as u16,
97 index: language_id,
98 },
99 buff,
100 )
101 .await?;
102 Ok(())
103 }
104
105 pub async fn get_device_descriptor(&mut self) -> Result<DeviceDescriptor, USBError> {
106 let mut buff = alloc::vec![0u8; DeviceDescriptor::LEN];
107 self.get_descriptor(DescriptorType::DEVICE, 0, 0, &mut buff)
108 .await?;
109 trace!("data: {buff:?}");
110 let desc = DeviceDescriptor::parse(&buff).ok_or(anyhow!("device descriptor parse err"))?;
111
112 Ok(desc)
113 }
114
115 pub async fn get_configuration(&mut self) -> Result<u8, TransferError> {
116 let mut buff = alloc::vec![0u8; 1];
117 self.control_in(
118 ControlSetup {
119 request_type: RequestType::Standard,
120 recipient: Recipient::Device,
121 request: Request::GetConfiguration,
122 value: 0,
123 index: 0,
124 },
125 &mut buff,
126 )
127 .await?;
128 let config_value = buff[0];
129
130 Ok(config_value)
131 }
132
133 pub async fn get_configuration_descriptor(
134 &mut self,
135 index: u8,
136 ) -> Result<ConfigurationDescriptor, USBError> {
137 let mut header = alloc::vec![0u8; ConfigurationDescriptor::LEN]; self.get_descriptor(DescriptorType::CONFIGURATION, index, 0, &mut header)
139 .await?;
140
141 let total_length = u16::from_le_bytes(header[2..4].try_into().unwrap()) as usize;
142 let mut full_data = alloc::vec![0u8; total_length];
144 debug!("Reading configuration descriptor for index {index}, total length: {total_length}");
145 self.get_descriptor(DescriptorType::CONFIGURATION, index, 0, &mut full_data)
146 .await?;
147
148 let parsed_config = ConfigurationDescriptor::parse(&full_data)
149 .ok_or(anyhow!("config descriptor parse err"))?;
150
151 Ok(parsed_config)
152 }
153}
154
155impl From<EndpointBase> for EndpointControl {
156 fn from(raw: EndpointBase) -> Self {
157 Self { raw }
158 }
159}