1use crate::flag;
2use crate::usb;
3use rusb::UsbContext;
4
5#[derive(Debug, Clone)]
6pub struct ListedDevice {
7 pub bus_number: u8,
8 pub address: u8,
9 pub speed: usb::Speed,
10 pub serial: Result<String, usb::Error>,
11}
12
13#[derive(Debug, Clone, Copy)]
14pub struct TemperatureCelsius(pub f32);
15
16pub type HandleAndProperties = (rusb::DeviceHandle<rusb::Context>, (u16, u16), String);
17
18#[derive(Debug, Clone, Copy)]
19pub enum SerialOrBusNumberAndAddress<'a> {
20 Serial(&'a str),
21 BusNumberAndAddress((u8, u8)),
22 None,
23}
24
25pub trait Usb: Sized {
26 type Adapter;
27 type Configuration;
28 type Error;
29 type Properties;
30
31 const VENDOR_AND_PRODUCT_IDS: &'static [(u16, u16)];
32
33 const PROPERTIES: Self::Properties;
34
35 const DEFAULT_USB_CONFIGURATION: usb::Configuration;
36
37 fn read_serial(handle: &mut rusb::DeviceHandle<rusb::Context>) -> rusb::Result<Option<String>>;
45
46 fn default_configuration(&self) -> Self::Configuration;
47
48 fn current_configuration(&self) -> Self::Configuration;
49
50 fn update_configuration(&self, configuration: Self::Configuration);
51
52 fn open<IntoError, IntoWarning>(
53 serial_or_bus_number_and_address: SerialOrBusNumberAndAddress,
54 configuration: Self::Configuration,
55 usb_configuration: &usb::Configuration,
56 event_loop: std::sync::Arc<usb::EventLoop>,
57 flag: flag::Flag<IntoError, IntoWarning>,
58 ) -> Result<Self, Self::Error>
59 where
60 IntoError: From<Self::Error> + Clone + Send + 'static,
61 IntoWarning: From<crate::usb::Overflow> + Clone + Send + 'static;
62
63 fn next_with_timeout(&self, timeout: &std::time::Duration) -> Option<usb::BufferView>;
64
65 fn backlog(&self) -> usize;
66
67 fn clutch(&self) -> usb::Clutch;
68
69 fn vendor_and_product_id(&self) -> (u16, u16);
70
71 fn serial(&self) -> String;
72
73 fn chip_firmware_configuration(&self) -> Self::Configuration;
74
75 fn bus_number(&self) -> u8;
76
77 fn address(&self) -> u8;
78
79 fn speed(&self) -> usb::Speed;
80
81 fn create_adapter(&self) -> Self::Adapter;
82
83 fn list_devices(devices: &rusb::DeviceList<rusb::Context>) -> rusb::Result<Vec<ListedDevice>> {
84 let mut result = Vec::new();
85 for device in devices
86 .iter()
87 .filter(|device| match device.device_descriptor() {
88 Ok(descriptor) => {
89 let device_vendor_and_product_id =
90 (descriptor.vendor_id(), descriptor.product_id());
91 Self::VENDOR_AND_PRODUCT_IDS
92 .iter()
93 .any(|vendor_and_product_id| {
94 device_vendor_and_product_id == *vendor_and_product_id
95 })
96 }
97 Err(_) => false,
98 })
99 {
100 if let Some(serial) = Self::read_serial(&mut device.open()?).transpose() {
101 result.push(ListedDevice {
102 bus_number: device.bus_number(),
103 address: device.address(),
104 speed: device.speed().into(),
105 serial: serial.map_err(|error| error.into()),
106 });
107 }
108 }
109 Ok(result)
110 }
111
112 fn open_any(context: &rusb::Context) -> Result<HandleAndProperties, usb::Error> {
113 match context.devices()?.iter().find_map(
114 |device| -> Option<rusb::Result<HandleAndProperties>> {
115 match device.device_descriptor() {
116 Ok(descriptor) => {
117 let device_vendor_and_product_id =
118 (descriptor.vendor_id(), descriptor.product_id());
119 if Self::VENDOR_AND_PRODUCT_IDS
120 .iter()
121 .any(|vendor_and_product_id| {
122 device_vendor_and_product_id == *vendor_and_product_id
123 })
124 {
125 let mut handle = match device.open() {
126 Ok(handle) => handle,
127 Err(error) => return Some(Err(error)),
128 };
129 let device_serial = match Self::read_serial(&mut handle) {
130 Ok(Some(serial)) => serial,
131 Ok(None) => return None, Err(_) => return None, };
134 let _ = handle.set_auto_detach_kernel_driver(true);
135 Some(Ok((handle, device_vendor_and_product_id, device_serial)))
136 } else {
137 None
138 }
139 }
140 Err(_) => None,
141 }
142 },
143 ) {
144 Some(result) => Ok(result?),
145 None => Err(usb::Error::Device),
146 }
147 }
148
149 fn open_serial(
150 context: &rusb::Context,
151 serial: &str,
152 ) -> Result<HandleAndProperties, usb::Error> {
153 match context.devices()?.iter().find_map(
154 |device| -> Option<rusb::Result<HandleAndProperties>> {
155 match device.device_descriptor() {
156 Ok(descriptor) => {
157 let device_vendor_and_product_id =
158 (descriptor.vendor_id(), descriptor.product_id());
159 if Self::VENDOR_AND_PRODUCT_IDS
160 .iter()
161 .any(|vendor_and_product_id| {
162 device_vendor_and_product_id == *vendor_and_product_id
163 })
164 {
165 let mut handle = match device.open() {
166 Ok(handle) => handle,
167 Err(error) => return Some(Err(error)),
168 };
169 let device_serial = match Self::read_serial(&mut handle) {
170 Ok(Some(serial)) => serial,
171 Ok(None) => return None, Err(_) => return None, };
174 if *serial == device_serial {
175 let _ = handle.set_auto_detach_kernel_driver(true);
176 Some(Ok((handle, device_vendor_and_product_id, device_serial)))
177 } else {
178 None
179 }
180 } else {
181 None
182 }
183 }
184 Err(_) => None,
185 }
186 },
187 ) {
188 Some(result) => Ok(result?),
189 None => Err(usb::Error::Serial((*serial).to_owned())),
190 }
191 }
192
193 fn open_bus_number_and_address(
194 context: &rusb::Context,
195 bus_number: u8,
196 address: u8,
197 ) -> Result<HandleAndProperties, usb::Error> {
198 match context.devices()?.iter().find_map(
199 |device| -> Option<Result<HandleAndProperties, usb::Error>> {
200 if device.bus_number() == bus_number && device.address() == address {
201 Some(match device.device_descriptor() {
202 Ok(descriptor) => {
203 let device_vendor_and_product_id =
204 (descriptor.vendor_id(), descriptor.product_id());
205 if Self::VENDOR_AND_PRODUCT_IDS
206 .iter()
207 .any(|vendor_and_product_id| {
208 device_vendor_and_product_id == *vendor_and_product_id
209 })
210 {
211 let mut handle = match device.open() {
212 Ok(handle) => handle,
213 Err(error) => return Some(Err(error.into())),
214 };
215 match Self::read_serial(&mut handle) {
216 Ok(Some(serial)) => {
217 let _ = handle.set_auto_detach_kernel_driver(true);
218 Ok((handle, device_vendor_and_product_id, serial))
219 }
220 Ok(None) => {
221 Err(usb::Error::BusNumberAndAddressUnsupportedDevice {
222 bus_number,
223 address,
224 })
225 }
226 Err(error) => Err(usb::Error::BusNumberAndAddressAccessError {
227 bus_number,
228 address,
229 error,
230 }),
231 }
232 } else {
233 Err(usb::Error::BusNumberAndAddressUnexpectedIds {
234 bus_number,
235 address,
236 vendor_id: device_vendor_and_product_id.0,
237 product_id: device_vendor_and_product_id.1,
238 })
239 }
240 }
241 Err(error) => Err(usb::Error::BusNumberAndAddressAccessError {
242 bus_number,
243 address,
244 error,
245 }),
246 })
247 } else {
248 None
249 }
250 },
251 ) {
252 Some(result) => Ok(result?),
253 None => Err(usb::Error::BusNumberAndAddressNotFound {
254 bus_number,
255 address,
256 }),
257 }
258 }
259}