Skip to main content

crab_usb/backend/ty/ep/
ctrl.rs

1use 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]; // 配置描述符头部固定为9字节
138        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        // 获取完整的配置描述符(包括接口和端点描述符)
143        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}