1use alloc::{boxed::Box, string::String};
2use anyhow::anyhow;
3use core::{
4 any::Any,
5 fmt::{Debug, Display},
6};
7
8use usb_if::{
9 descriptor::{
10 ConfigurationDescriptor, DescriptorType, DeviceDescriptor, InterfaceDescriptor, LanguageId,
11 decode_string_descriptor,
12 },
13 err::{TransferError, USBError},
14 host::ControlSetup,
15};
16
17use crate::backend::ty::ep::EndpointKind;
18use crate::backend::ty::{DeviceInfoOp, DeviceOp, ep::EndpointControl};
19
20pub struct DeviceInfo {
21 pub(crate) inner: Box<dyn DeviceInfoOp>,
22}
23
24impl DeviceInfo {
25 pub fn descriptor(&self) -> &DeviceDescriptor {
26 self.inner.descriptor()
27 }
28
29 pub fn configurations(&self) -> &[ConfigurationDescriptor] {
30 self.inner.configuration_descriptors()
31 }
32
33 pub fn interface_descriptors<'a>(
34 &'a self,
35 ) -> impl Iterator<Item = &'a InterfaceDescriptor> + 'a {
36 self.configurations().iter().flat_map(|config| {
37 config
38 .interfaces
39 .iter()
40 .flat_map(|interface| interface.alt_settings.first())
41 })
42 }
43
44 pub fn product_id(&self) -> u16 {
45 self.descriptor().product_id
46 }
47
48 pub fn vendor_id(&self) -> u16 {
49 self.descriptor().vendor_id
50 }
51}
52
53impl Debug for DeviceInfo {
54 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55 f.debug_struct("DeviceInfo")
56 .field("backend", &self.inner.backend_name())
57 .field("vender_id", &self.inner.descriptor().vendor_id)
58 .field("product_id", &self.inner.descriptor().product_id)
59 .finish()
60 }
61}
62
63impl Display for DeviceInfo {
64 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
65 write!(
66 f,
67 "{:04x}:{:04x}",
68 self.inner.descriptor().vendor_id,
69 self.inner.descriptor().product_id
70 )
71 }
72}
73
74pub struct Device {
75 pub(crate) inner: Box<dyn DeviceOp>,
76 lang_id: LanguageId,
77 manufacturer: Option<String>,
78 current_interface: Option<(u8, u8)>,
79}
80
81impl Debug for Device {
82 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83 f.debug_struct("Device")
84 .field("backend", &self.inner.backend_name())
85 .field("vender_id", &self.inner.descriptor().vendor_id)
86 .field("product_id", &self.inner.descriptor().product_id)
87 .finish()
88 }
89}
90
91impl<T: DeviceOp> From<T> for Device {
92 fn from(inner: T) -> Self {
93 Self {
94 inner: Box::new(inner),
95 current_interface: None,
96 lang_id: LanguageId::default(),
97 manufacturer: None,
98 }
99 }
100}
101
102impl From<Box<dyn DeviceOp>> for Device {
103 fn from(inner: Box<dyn DeviceOp>) -> Self {
104 Self {
105 inner,
106 current_interface: None,
107 lang_id: LanguageId::default(),
108 manufacturer: None,
109 }
110 }
111}
112
113impl Device {
114 pub(crate) async fn init(&mut self) -> Result<(), USBError> {
115 self.manufacturer = self.read_manufacturer().await;
116 Ok(())
117 }
118
119 pub fn product_id(&self) -> u16 {
120 self.descriptor().product_id
121 }
122
123 pub fn vendor_id(&self) -> u16 {
124 self.descriptor().vendor_id
125 }
126
127 pub fn slot_id(&self) -> u8 {
128 self.inner.id() as _
129 }
130
131 pub async fn claim_interface(&mut self, interface: u8, alternate: u8) -> Result<(), USBError> {
132 trace!("Claiming interface {interface}, alternate {alternate}");
133 self.inner.claim_interface(interface, alternate).await?;
134 self.current_interface = Some((interface, alternate));
135 Ok(())
136 }
137
138 pub fn descriptor(&self) -> &DeviceDescriptor {
139 self.inner.descriptor()
140 }
141
142 pub fn configurations(&self) -> &[ConfigurationDescriptor] {
143 self.inner.configuration_descriptors()
144 }
145
146 pub fn manufacturer(&self) -> Option<&str> {
147 self.manufacturer.as_deref()
148 }
149
150 pub async fn set_configuration(&mut self, configuration_value: u8) -> crate::err::Result {
151 self.inner.set_configuration(configuration_value).await
152 }
153
154 pub fn ep_ctrl(&mut self) -> &mut EndpointControl {
155 self.inner.ep_ctrl()
156 }
157
158 async fn read_manufacturer(&mut self) -> Option<String> {
159 let idx = self.descriptor().manufacturer_string_index?;
160 self.string_descriptor(idx.get()).await.ok()
161 }
162
163 pub fn lang_id(&self) -> LanguageId {
164 self.lang_id
165 }
166
167 pub fn set_lang_id(&mut self, lang_id: LanguageId) {
168 self.lang_id = lang_id;
169 }
170
171 pub async fn string_descriptor(&mut self, index: u8) -> Result<String, USBError> {
172 let mut data = alloc::vec![0u8; 256];
173 let lang_id = self.lang_id();
174 self.ep_ctrl()
175 .get_descriptor(DescriptorType::STRING, index, lang_id.into(), &mut data)
176 .await?;
177 let res = decode_string_descriptor(&data)?;
178 Ok(res)
179 }
180
181 pub async fn control_in(
182 &mut self,
183 param: ControlSetup,
184 buff: &mut [u8],
185 ) -> Result<usize, TransferError> {
186 self.ep_ctrl().control_in(param, buff).await
187 }
188
189 pub async fn control_out(
190 &mut self,
191 param: ControlSetup,
192 buff: &[u8],
193 ) -> Result<usize, TransferError> {
194 self.ep_ctrl().control_out(param, buff).await
195 }
196
197 pub async fn update_hub(
198 &mut self,
199 params: crate::backend::ty::HubParams,
200 ) -> Result<(), USBError> {
201 self.inner.update_hub(params).await
202 }
203
204 pub async fn current_configuration_descriptor(
205 &mut self,
206 ) -> Result<ConfigurationDescriptor, USBError> {
207 let value = self.ep_ctrl().get_configuration().await?;
208 if value == 0 {
209 return Err(USBError::NotFound);
210 }
211 for config in self.configurations() {
212 if config.configuration_value == value {
213 return Ok(config.clone());
214 }
215 }
216 Err(USBError::NotFound)
217 }
218
219 pub async fn get_endpoint(&mut self, address: u8) -> Result<EndpointKind, USBError> {
220 let ep_desc = self.find_ep_desc(address)?.clone();
221 let base = self.inner.get_endpoint(&ep_desc)?;
222 match (ep_desc.transfer_type, ep_desc.direction) {
223 (usb_if::descriptor::EndpointType::Control, _) => {
224 Ok(EndpointKind::Control(base.into()))
225 }
226 (usb_if::descriptor::EndpointType::Isochronous, usb_if::transfer::Direction::In) => {
227 Ok(EndpointKind::IsochronousIn(base.into()))
228 }
229 (usb_if::descriptor::EndpointType::Isochronous, usb_if::transfer::Direction::Out) => {
230 Ok(EndpointKind::IsochronousOut(base.into()))
231 }
232 (usb_if::descriptor::EndpointType::Bulk, usb_if::transfer::Direction::In) => {
233 Ok(EndpointKind::BulkIn(base.into()))
234 }
235 (usb_if::descriptor::EndpointType::Bulk, usb_if::transfer::Direction::Out) => {
236 Ok(EndpointKind::BulkOut(base.into()))
237 }
238 (usb_if::descriptor::EndpointType::Interrupt, usb_if::transfer::Direction::In) => {
239 Ok(EndpointKind::InterruptIn(base.into()))
240 }
241 (usb_if::descriptor::EndpointType::Interrupt, usb_if::transfer::Direction::Out) => {
242 Ok(EndpointKind::InterruptOut(base.into()))
243 }
244 }
245 }
246
247 #[allow(unused)]
248 pub(crate) fn as_raw<T: DeviceOp>(&self) -> &T {
249 (self.inner.as_ref() as &dyn Any)
250 .downcast_ref::<T>()
251 .unwrap()
252 }
253
254 #[allow(unused)]
255 pub(crate) fn as_raw_mut<T: DeviceOp>(&mut self) -> &mut T {
256 (self.inner.as_mut() as &mut dyn Any)
257 .downcast_mut::<T>()
258 .unwrap()
259 }
260
261 fn find_ep_desc(
262 &self,
263 address: u8,
264 ) -> core::result::Result<&usb_if::descriptor::EndpointDescriptor, USBError> {
265 let (interface_number, alternate_setting) = match self.current_interface {
266 Some((i, a)) => (i, a),
267 None => Err(anyhow!("Interface not claim"))?,
268 };
269 for config in self.configurations() {
270 for interface in &config.interfaces {
271 if interface.interface_number == interface_number {
272 for alt in &interface.alt_settings {
273 if alt.alternate_setting == alternate_setting {
274 for ep in &alt.endpoints {
275 if ep.address == address {
276 return Ok(ep);
277 }
278 }
279 }
280 }
281 }
282 }
283 }
284 Err(USBError::NotFound)
285 }
286}
287
288impl Display for Device {
289 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
290 write!(
291 f,
292 "{:04x}:{:04x}",
293 self.inner.descriptor().vendor_id,
294 self.inner.descriptor().product_id
295 )
296 }
297}