1use super::descriptors::Buffer64;
24use super::descriptors::Descriptor;
25use super::descriptors::DescriptorBuffer;
26use super::descriptors::DescriptorType;
27use super::descriptors::DeviceBuffer;
28use super::descriptors::HIDDescriptor;
29use super::descriptors::LanguagesDescriptor;
30use super::descriptors::Recipient;
31use super::descriptors::ReportDescriptor;
32use super::descriptors::SetupData;
33use super::descriptors::StandardRequest;
34use super::descriptors::StringDescriptor;
35use super::descriptors::TransferDirection;
36
37use core::cell::Cell;
38use core::cmp::min;
39
40use kernel::hil;
41use kernel::hil::usb::TransferType;
42
43const DESCRIPTOR_BUFLEN: usize = 128;
44
45const N_ENDPOINTS: usize = 3;
46
47pub struct ClientCtrl<'a, 'b, U: 'a> {
49 controller: &'a U,
51
52 state: [Cell<State>; N_ENDPOINTS],
54
55 pub ctrl_buffer: Buffer64,
58
59 descriptor_storage: [Cell<u8>; DESCRIPTOR_BUFLEN],
61
62 device_descriptor_buffer: DeviceBuffer,
66
67 other_descriptor_buffer: DescriptorBuffer,
70
71 hid_descriptor: Option<&'b HIDDescriptor<'b>>,
74
75 report_descriptor: Option<&'b ReportDescriptor<'b>>,
79
80 language: &'b [u16; 1],
82
83 strings: &'b [&'b str],
85}
86
87#[derive(Copy, Clone, Default)]
89enum State {
90 #[default]
91 Init,
92
93 CtrlIn(usize, usize),
96
97 CtrlOut,
99
100 SetAddress,
101}
102
103impl<'a, 'b, U: hil::usb::UsbController<'a>> ClientCtrl<'a, 'b, U> {
104 pub fn new(
105 controller: &'a U,
106 device_descriptor_buffer: DeviceBuffer,
107 other_descriptor_buffer: DescriptorBuffer,
108 hid_descriptor: Option<&'b HIDDescriptor<'b>>,
109 report_descriptor: Option<&'b ReportDescriptor<'b>>,
110 language: &'b [u16; 1],
111 strings: &'b [&'b str],
112 ) -> Self {
113 ClientCtrl {
114 controller,
115 state: Default::default(),
116 #[rustfmt::skip]
120 descriptor_storage: [
121 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
122 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
123 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
124 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
125 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
126 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
127 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
128 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
129 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
130 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
131 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
132 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
133 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
134 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
135 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
136 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
137 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
138 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
139 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
140 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
141 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
142 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
143 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
144 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
145 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
146 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
147 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
148 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
149 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
150 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
151 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
152 Cell::default(), Cell::default(), Cell::default(), Cell::default(),
153 ],
154 ctrl_buffer: Buffer64::default(),
155 device_descriptor_buffer,
156 other_descriptor_buffer,
157 hid_descriptor,
158 report_descriptor,
159 language,
160 strings,
161 }
162 }
163
164 #[inline]
165 pub fn controller(&self) -> &'a U {
166 self.controller
167 }
168
169 #[inline]
170 fn descriptor_buf(&'a self) -> &'a [Cell<u8>] {
171 &self.descriptor_storage
172 }
173
174 pub fn enable(&'a self) {
175 self.controller
177 .endpoint_set_ctrl_buffer(&self.ctrl_buffer.buf);
178 self.controller
179 .enable_as_device(hil::usb::DeviceSpeed::Full); self.controller
181 .endpoint_out_enable(TransferType::Control, 0);
182 }
183
184 pub fn attach(&'a self) {
185 self.controller.attach();
186 }
187
188 pub fn ctrl_setup(&'a self, endpoint: usize) -> hil::usb::CtrlSetupResult {
190 if endpoint != 0 {
191 return hil::usb::CtrlSetupResult::ErrInvalidDeviceIndex;
193 }
194 SetupData::get(&self.ctrl_buffer.buf).map_or(
195 hil::usb::CtrlSetupResult::ErrNoParse,
196 |setup_data| {
197 let transfer_direction = setup_data.request_type.transfer_direction();
198 let recipient = setup_data.request_type.recipient();
199 setup_data.get_standard_request().map_or_else(
200 || {
201 match transfer_direction {
207 TransferDirection::HostToDevice => {
208 self.state[endpoint].set(State::CtrlOut);
209 hil::usb::CtrlSetupResult::Ok
210 }
211 TransferDirection::DeviceToHost => {
212 let buf = self.descriptor_buf();
214 buf[0].set(0xa);
215 buf[1].set(0xb);
216 buf[2].set(0xc);
217 self.state[endpoint].set(State::CtrlIn(0, 3));
218 hil::usb::CtrlSetupResult::Ok
219 }
220 }
221 },
222 |request| match recipient {
223 Recipient::Device => self.handle_standard_device_request(endpoint, request),
224 Recipient::Interface => {
225 self.handle_standard_interface_request(endpoint, request)
226 }
227 _ => hil::usb::CtrlSetupResult::ErrGeneric,
228 },
229 )
230 },
231 )
232 }
233
234 fn handle_standard_device_request(
235 &'a self,
236 endpoint: usize,
237 request: StandardRequest,
238 ) -> hil::usb::CtrlSetupResult {
239 match request {
240 StandardRequest::GetDescriptor {
241 descriptor_type,
242 descriptor_index,
243 lang_id,
244 requested_length,
245 } => {
246 match descriptor_type {
247 DescriptorType::Device => match descriptor_index {
248 0 => {
249 let buf = self.descriptor_buf();
250 let len = self.device_descriptor_buffer.write_to(buf);
251
252 let end = min(len, requested_length as usize);
253
254 self.state[endpoint].set(State::CtrlIn(0, end));
255 hil::usb::CtrlSetupResult::Ok
256 }
257 _ => hil::usb::CtrlSetupResult::ErrInvalidDeviceIndex,
258 },
259 DescriptorType::Configuration => match descriptor_index {
260 0 => {
261 let buf = self.descriptor_buf();
262 let len = self.other_descriptor_buffer.write_to(buf);
263
264 let end = min(len, requested_length as usize);
265 self.state[endpoint].set(State::CtrlIn(0, end));
266 hil::usb::CtrlSetupResult::Ok
267 }
268 _ => hil::usb::CtrlSetupResult::ErrInvalidConfigurationIndex,
269 },
270 DescriptorType::String => {
271 if let Some(len) = match descriptor_index {
272 0 => {
273 let buf = self.descriptor_buf();
274 let d = LanguagesDescriptor {
275 langs: self.language,
276 };
277 let len = d.write_to(buf);
278 Some(len)
279 }
280 i if i > 0
281 && (i as usize) <= self.strings.len()
282 && lang_id == self.language[0] =>
283 {
284 let buf = self.descriptor_buf();
285 let d = StringDescriptor {
286 string: self.strings[i as usize - 1],
287 };
288 let len = d.write_to(buf);
289 Some(len)
290 }
291 _ => None,
292 } {
293 let end = min(len, requested_length as usize);
294 self.state[endpoint].set(State::CtrlIn(0, end));
295 hil::usb::CtrlSetupResult::Ok
296 } else {
297 hil::usb::CtrlSetupResult::ErrInvalidStringIndex
298 }
299 }
300 DescriptorType::DeviceQualifier => {
301 hil::usb::CtrlSetupResult::ErrNoDeviceQualifier
304 }
305 _ => hil::usb::CtrlSetupResult::ErrUnrecognizedDescriptorType,
306 } }
308 StandardRequest::SetAddress { device_address } => {
309 self.controller.set_address(device_address);
311
312 self.state[endpoint].set(State::SetAddress);
315 hil::usb::CtrlSetupResult::OkSetAddress
316 }
317 StandardRequest::SetConfiguration { .. } => {
318 hil::usb::CtrlSetupResult::Ok
320 }
321 _ => hil::usb::CtrlSetupResult::ErrUnrecognizedRequestType,
322 }
323 }
324
325 fn handle_standard_interface_request(
326 &'a self,
327 endpoint: usize,
328 request: StandardRequest,
329 ) -> hil::usb::CtrlSetupResult {
330 match request {
331 StandardRequest::GetDescriptor {
332 descriptor_type,
333 descriptor_index: _,
335 lang_id: _,
337 requested_length,
338 } => match descriptor_type {
339 DescriptorType::HID => {
340 if let Some(desc) = self.hid_descriptor {
341 let buf = self.descriptor_buf();
342 let len = desc.write_to(buf);
343 let end = min(len, requested_length as usize);
344 self.state[endpoint].set(State::CtrlIn(0, end));
345 hil::usb::CtrlSetupResult::Ok
346 } else {
347 hil::usb::CtrlSetupResult::ErrGeneric
348 }
349 }
350 DescriptorType::Report => {
351 if let Some(desc) = self.report_descriptor {
352 let buf = self.descriptor_buf();
353 let len = desc.write_to(buf);
354 let end = min(len, requested_length as usize);
355 self.state[endpoint].set(State::CtrlIn(0, end));
356 hil::usb::CtrlSetupResult::Ok
357 } else {
358 hil::usb::CtrlSetupResult::ErrGeneric
359 }
360 }
361 _ => hil::usb::CtrlSetupResult::ErrGeneric,
362 },
363 _ => hil::usb::CtrlSetupResult::ErrGeneric,
364 }
365 }
366
367 pub fn ctrl_in(&'a self, endpoint: usize) -> hil::usb::CtrlInResult {
369 match self.state[endpoint].get() {
370 State::CtrlIn(start, end) => {
371 let len = end.saturating_sub(start);
372 if len > 0 {
373 let packet_bytes = min(self.ctrl_buffer.buf.len(), len);
374 let packet = &self.descriptor_storage[start..start + packet_bytes];
375 let buf = &self.ctrl_buffer.buf;
376
377 for (i, b) in packet.iter().enumerate() {
379 buf[i].set(b.get());
380 }
381
382 let start = start + packet_bytes;
383 let len = end.saturating_sub(start);
384 let transfer_complete = len == 0;
385
386 self.state[endpoint].set(State::CtrlIn(start, end));
387
388 hil::usb::CtrlInResult::Packet(packet_bytes, transfer_complete)
389 } else {
390 hil::usb::CtrlInResult::Packet(0, true)
391 }
392 }
393 _ => hil::usb::CtrlInResult::Error,
394 }
395 }
396
397 pub fn ctrl_out(&'a self, endpoint: usize, _packet_bytes: u32) -> hil::usb::CtrlOutResult {
399 match self.state[endpoint].get() {
400 State::CtrlOut => {
401 hil::usb::CtrlOutResult::Ok
403 }
404 _ => {
405 hil::usb::CtrlOutResult::Halted
407 }
408 }
409 }
410
411 pub fn ctrl_status(&'a self, _endpoint: usize) {
412 }
414
415 pub fn ctrl_status_complete(&'a self, endpoint: usize) {
417 match self.state[endpoint].get() {
421 State::SetAddress => {
422 self.controller.enable_address();
423 }
424 _ => {}
425 }
426 self.state[endpoint].set(State::Init);
427 }
428}