1/**
2 * \brief This file contains the standard device requests from the USB
3 * Specification Rev. 2.0 Section 9.4
4 */
5
6/*
7 * Copyright (c) 2007-2013 ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15
16
17#include <usb/usb.h>
18#include <usb/usb_request.h>
19
20
21#include "usb_manager_client.h"
22
23/**
24 * \brief this request is used to clear or disable a specific feature.
25 *
26 * \param recipient the receiver of the event: USB_REQUEST_RECIPIENT_*
27 * \param feature   the feature selector: USB_REQUEST_FEATURE_*
28 *
29 * \return USB_ERR_OK   on success
30 *
31 * Behaviour of the device upon receiving a request:
32 *  - default state:    behaviour not specified
33 *  - address state:    valid when recipient is the device or endpoint zero
34 *                      other recpients (endpoints and interfaces) get a
35 *                      USB_ERR_REQUEST
36 *  - configured state: valid request forall recipients
37 */
38usb_error_t usb_clear_feature(uint8_t recipient, uint8_t recipient_index,
39        uint16_t feature)
40{
41    struct usb_device_request req;
42
43    req.bType.direction = USB_REQUEST_WRITE;
44    req.bType.type = USB_REQUEST_TYPE_STANDARD;
45    req.bType.recipient = (recipient & USB_REQUEST_RECIPIENT_MASK);
46    req.bRequest = USB_REQUEST_CLEAR_FEATURE;
47    req.wValue = feature;
48    req.wIndex = 0;
49    if (recipient != USB_REQUEST_RECIPIENT_DEVICE) {
50        req.wIndex = recipient_index;
51    }
52    req.wLength = 0;
53
54    return (usb_do_request(&req));
55}
56
57/**
58 * \brief this request returns the current device configuration value
59 *
60 * \param *ret_config   the current configuration value if zero then
61 *                      the device is not configured yet
62 *
63 * \return USB_ERR_OK   on success
64 *
65 * Behaviour of the device upon receiving a request:
66 *  - default state:    behaviour not specified
67 *  - address state:    must return the value zero
68 *  - configured state: a non zero value must be returned
69 */
70usb_error_t usb_get_configuration(uint8_t *ret_config)
71{
72    struct usb_device_request req;
73
74    req.bType.direction = USB_REQUEST_READ;
75    req.bType.type = USB_REQUEST_TYPE_STANDARD;
76    req.bType.recipient = USB_REQUEST_RECIPIENT_DEVICE;
77    req.bRequest = USB_REQUEST_GET_CONFIG;
78    req.wValue = 0;
79    req.wIndex = 0;
80    req.wLength = 1;
81
82    uint16_t ret_length;
83    void *ret_data;
84
85    usb_error_t err = usb_do_request_read(&req, &ret_length, &ret_data);
86
87    if (err != USB_ERR_OK) {
88        return (err);
89    }
90
91    if (ret_length != 1) {
92        return (USB_ERR_IOERROR);
93    }
94
95    if (ret_config) {
96        *ret_config = *((uint8_t *)ret_data);
97        free(ret_data);
98    }
99
100    return (USB_ERR_OK);
101}
102
103/**
104 * \brief This request returns the specified descriptor if the descriptor exists.
105 *
106 * \param desc_type:    descriptor type to look for
107 * \param desc_index:   which descirptor to return
108 * \param lang:         zero or a language id for string descriptors
109 * \param *ret_desc:
110 *
111 * Behaviour of the device upon receiving a request:
112 *  - default state:    valid request
113 *  - address state:    valid request
114 *  - configured state: valid request
115 */
116usb_error_t usb_get_descriptor(uint8_t desc_type, uint8_t desc_index,
117        uint16_t lang, void **ret_desc, uint16_t *ret_length)
118{
119    struct usb_device_request req;
120
121    req.bType.direction = USB_REQUEST_READ;
122    req.bType.type = USB_REQUEST_TYPE_STANDARD;
123    req.bType.recipient = USB_REQUEST_RECIPIENT_DEVICE;
124    req.bRequest = USB_REQUEST_GET_DESCRIPTOR;
125    req.wValue = (desc_type << 8) | desc_index;
126
127    /* wIndex stores the language id if a string descriptor is requested*/
128    if (desc_type == USB_DESCRIPTOR_TYPE_STRING) {
129        req.wIndex = lang;
130    } else {
131        req.wIndex = 0;
132    }
133    req.wIndex = lang;
134
135    /*
136     the maximum bytes to be returned, if length of the descriptor exceeds
137     this value, only the first wLength bytes are returned.
138     */
139    req.wLength = 0;
140
141    usb_descriptor_t *desc;
142    uint16_t ret_data_length;
143
144    usb_error_t err = usb_do_request_read(&req, &ret_data_length, (void **)&desc);
145
146    if (err != USB_ERR_OK) {
147        return (err);
148    }
149
150    /* we check for the size of the returned descriptors */
151    switch (desc_type) {
152        case USB_DESCRIPTOR_TYPE_DEVICE:
153            if (ret_data_length != sizeof(struct usb_device_descriptor)) {
154                return (USB_ERR_IOERROR);
155            }
156            break;
157        case USB_DESCRIPTOR_TYPE_INTERFACE:
158            if (ret_data_length != sizeof(struct usb_interface_descriptor)) {
159                return (USB_ERR_IOERROR);
160            }
161            break;
162        case USB_DESCRIPTOR_TYPE_ENDPOINT:
163            if (ret_data_length != sizeof(struct usb_endpoint_descriptor)) {
164                return (USB_ERR_IOERROR);
165            }
166            break;
167        case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
168            if (ret_data_length
169                    != sizeof(struct usb_device_qualifier_descriptor)) {
170                return (USB_ERR_IOERROR);
171            }
172            break;
173        default:
174            /* variable sized descriptors */
175            if(ret_data_length != desc->bLength) {
176                return (USB_ERR_IOERROR);
177            }
178            break;
179    }
180
181    /* ok all should be fine */
182
183    if (ret_length) {
184        *ret_length = ret_data_length;
185    }
186
187    if (ret_desc) {
188        *ret_desc = desc;
189    }
190
191    return (USB_ERR_OK);
192
193}
194
195/* XXX: The following functions serve as an easier way to get a specific
196 *      descriptor. In fact they are not really needed and the functionality
197 *      can be done using the generic get_descriptor request
198 */
199usb_error_t usb_get_config_descriptor(uint8_t config_index,
200        struct usb_config_descriptor *ret_desc)
201{
202    assert(!"NYI: usb_get_config_descriptor");
203    return (USB_ERR_BAD_REQUEST);
204}
205
206usb_error_t usb_get_iface_descriptor(uint8_t iface_index,
207        struct usb_config_descriptor *ret_desc)
208{
209    assert(!"NYI: usb_get_iface_descriptor");
210    return (USB_ERR_BAD_REQUEST);
211}
212
213usb_error_t usb_get_ep_descriptor(uint8_t ep_index,
214        struct usb_endpoint_descriptor *ret_desc)
215{
216    assert(!"NYI: usb_get_ep_descriptor");
217    return (USB_ERR_BAD_REQUEST);
218}
219
220usb_error_t usb_get_string_descriptor(uint16_t lang_id, uint8_t string_index,
221        void *ret_desc)
222{
223    assert(!"NYI: usb_get_string_descriptor");
224    return (USB_ERR_BAD_REQUEST);
225}
226
227/**
228 * \brief This requests returns the selected alternate setting for the
229 *        specified interface
230 *
231 * \param iface_number:     the interface we want to get the alternate
232 *                          setting
233 * \param ret_alt_iface:    the alternate setting value
234 *
235 * \return USB_ERR_OK on success
236 *            USB_ERR_* on failure
237 *
238 * Behaviour of the device upon receiving a request:
239 *  - default state:    not specified
240 *  - address state:    USB_ERR_REQUEST
241 *  - configured state: valid request
242 *
243 * If the interface does not exists then the device will reply with a
244 * USB_ERR_REQUEST
245 */
246usb_error_t usb_get_alt_iface(uint16_t iface_number, uint8_t *ret_alt_iface)
247{
248    struct usb_device_request req;
249
250    req.bType.direction = USB_REQUEST_READ;
251    req.bType.type = USB_REQUEST_TYPE_STANDARD;
252    req.bType.recipient = USB_REQUEST_RECIPIENT_INTERFACE;
253    req.bRequest = USB_REQUEST_GET_INTERFACE;
254    req.wValue = 0;
255    req.wIndex = (0x00FF & iface_number);
256    req.wLength = 1;
257
258    usb_error_t err = USB_ERR_OK;
259    void *ret_val;
260    uint16_t ret_length;
261
262    err = usb_do_request_read(&req, &ret_length, &ret_val);
263
264    if (err != USB_ERR_OK) {
265        return (err);
266    }
267
268    if (ret_length != 1) {
269        return (USB_ERR_IOERROR);
270    }
271
272    if (ret_alt_iface) {
273        *ret_alt_iface = *((uint8_t*) (ret_val));
274    }
275
276    return (USB_ERR_OK);
277}
278
279/**
280 * \brief This request returns the status for the specified recipient
281 *
282 * \param recipient_index:   zero for device status, the endpoint or interface
283 *                          number for the respective recipient
284 * \param ret_status:       the status of the recipient
285 *
286 * \return USB_ERR_OK on success
287 *
288 * Behaviour of the device upon receiving a request:
289 *  - default state:    not specified
290 *  - address state:    USB_ERR_REQUEST
291 *  - configured state: valid request
292 *
293 * If the interface or endpoint does not exists then the device will reply
294 * with a USB_ERR_REQUEST
295 */
296usb_error_t usb_get_status(uint8_t recipient, uint16_t recipient_index,
297        struct usb_status *ret_status)
298{
299    struct usb_device_request req;
300
301    req.bType.direction = USB_REQUEST_READ;
302    req.bType.type = USB_REQUEST_TYPE_STANDARD;
303    req.bType.recipient = (recipient & USB_REQUEST_RECIPIENT_MASK);
304    req.bRequest = USB_REQUEST_GET_STATUS;
305    req.wValue = 0;
306
307    req.wIndex = recipient_index;
308    req.wLength = 2;
309
310    void *ret_data;
311    uint16_t ret_length;
312
313    usb_error_t err = usb_do_request_read(&req, &ret_length, &ret_data);
314
315    if (err != USB_ERR_OK) {
316        return (err);
317    }
318
319    if (ret_length != 2) {
320        return (USB_ERR_IOERROR);
321    }
322
323    if (ret_status) {
324        ret_status->wStatus = *((uint16_t *) ret_data);
325        free(ret_data);
326    }
327
328    return (USB_ERR_OK);
329}
330
331/**
332 * \brief This request sets the device address for all future device accesses.
333 *
334 * \param new_address:  the new address to be used for all subsequent accesses
335 *                      new_address < 128 && new_address > 0
336 *
337 * \return USB_ERR_OK on sucess
338 *
339 * Behaviour of the device upon receiving a request:
340 *  - default state:    device enters the address sate if address > 0
341 *  - address state:    device enters default state if address = 0
342 *                      OR device changes its address
343 *  - configured state: not specified
344 *
345 */
346usb_error_t usb_set_address(uint8_t new_address)
347{
348    struct usb_device_request req;
349
350    if (new_address > 127) {
351        return (USB_ERR_INVAL);
352    }
353
354    req.bType.direction = USB_REQUEST_WRITE;
355    req.bType.type = USB_REQUEST_TYPE_STANDARD;
356    req.bType.recipient = USB_REQUEST_RECIPIENT_DEVICE;
357    req.bRequest = USB_REQUEST_SET_ADDRESS;
358    req.wValue = new_address;
359    req.wIndex = 0;
360    req.wLength = 0;
361
362    return (usb_do_request(&req));
363
364}
365
366/**
367 * \brief This request sets the device configuration.
368 *
369 * \param config_value:  the new configuration to activate, this must be
370 *                       zero or match a configuration from the config
371 *                       descriptor.
372 *
373 * \return USB_ERR_OK on sucess
374 *
375 * Behaviour of the device upon receiving a request:
376 *  - default state:    not specified
377 *  - address state:    on matching value, the device enters configured
378 *                      state
379 *  - configured state: if new configuration is zero then device enters
380 *                      address state or activates new configuration
381 *                      if value is matching.
382 *
383 *  There will be a request error if the configuration does not match
384 */
385usb_error_t usb_set_configuration(uint8_t config_value)
386{
387    struct usb_device_request req;
388
389    req.bType.direction = USB_REQUEST_WRITE;
390    req.bType.type = USB_REQUEST_TYPE_STANDARD;
391    req.bType.recipient = USB_REQUEST_RECIPIENT_DEVICE;
392    req.bRequest = USB_REQUEST_SET_CONFIG;
393    req.wValue = (config_value & 0x00FF);
394    req.wIndex = 0;
395    req.wLength = 0;
396
397    return (usb_do_request(&req));
398}
399
400/**
401 * \brief This request is optional and may be used to update existing
402 *           descriptors or new descriptors may be added.
403 *
404 * \param desc_type:    the new configuration to activate, this must be
405 *                      zero or match a configuration from the config
406 *                      descriptor.
407 * \param desc_index:   Used for selecting the descriptor if a device implements
408 *                      multiple descriptors of a certain type (config or string)
409 * \param language
410 * \param descriptor
411 *
412 * \return USB_ERR_OK on sucess
413 *
414 * Behaviour of the device upon receiving a request:
415 *  - default state:    not specified
416 *  - address state:    if supported, a valid request
417 *  - configured state: if supported, a valid request
418 *
419 *  There will be a request error if the configuration does not match
420 */
421usb_error_t usb_set_descriptor(uint8_t desc_type, uint8_t desc_index,
422        uint8_t language, struct usb_descriptor *descriptor)
423{
424    struct usb_device_request req;
425
426    req.bType.direction = USB_REQUEST_WRITE;
427    req.bType.type = USB_REQUEST_TYPE_STANDARD;
428    req.bType.recipient = USB_REQUEST_RECIPIENT_DEVICE;
429    req.bRequest = USB_REQUEST_SET_DESCRIPTOR;
430    /*
431     * the index must be zero if other descriptors as string or config are used
432     * The only allowed values for descriptor type are device, configuration,
433     * and string descriptor types.
434     */
435    switch (desc_type) {
436        case USB_DESCRIPTOR_TYPE_STRING:
437        case USB_DESCRIPTOR_TYPE_CONFIG:
438            req.wValue = (desc_type << 8) | desc_index;
439            break;
440        case USB_DESCRIPTOR_TYPE_DEVICE:
441            req.wValue = (desc_type << 8);
442            break;
443        default:
444            return (USB_ERR_BAD_REQUEST);
445    }
446
447    req.wIndex = 0;
448    req.wLength = 0;
449
450    return (usb_do_request_write(&req, descriptor->bLength, descriptor));
451}
452
453/**
454 * \brief This request is used to set or enable a specific feature.
455 *
456 * \param feature:      The feature to enable. This value must be appropriate to
457 *                      the recipient.
458 * \param recipient:     The recipient of the request: USB_REQUEST_RECIPIENT_*
459 * \param test:
460 * \param index:
461 *
462 * \return USB_ERR_OK on sucess
463 *
464 * Behaviour of the device upon receiving a request:
465 *  - default state:    only accepts TEST_MODE
466 *  - address state:    request error for specific ep or interface
467 *  - configured state: valid request
468 *
469 *  A SetFeature() request that references a feature that cannot be set or
470 *  that does not exist causes a STALL to be returned in the Status stage of
471 *  the request.
472 */
473usb_error_t usb_set_feature(uint8_t recipient, uint16_t feature, uint8_t test,
474        uint8_t recipent_index)
475{
476    struct usb_device_request req;
477
478    req.bType.direction = USB_REQUEST_WRITE;
479    req.bType.type = USB_REQUEST_TYPE_STANDARD;
480    req.bType.recipient = recipient;
481    req.bRequest = USB_REQUEST_SET_FEATURE;
482    req.wLength = 0;
483
484    req.wIndex = 0;
485
486    if (recipient != USB_REQUEST_RECIPIENT_DEVICE) {
487        // the LSb of the wIndex only stores the index of an endpoint/interface
488        req.wIndex = recipent_index;
489    }
490
491    if (feature == USB_REQUEST_FEATURE_TEST_MODE) {
492        if (recipient != USB_REQUEST_RECIPIENT_DEVICE) {
493            // only devices may get an TEST_MODE feature request
494            return (USB_ERR_BAD_REQUEST);
495        } else {
496            req.wIndex = (test << 8);
497        }
498    }
499    return (usb_do_request(&req));
500}
501
502/**
503 * \brief This request allows the host to select an alternate setting
504 *        for the specified interface.
505 *
506 * \param feature:      The feature to enable. This value must be appropriate to
507 *                      the recipient.
508 * \param recipient:     The recipient of the request: USB_REQUEST_RECIPIENT_*
509 * \param test:         The testmode selected
510 * \param index:        The number of the interface / endpoint
511 *
512 * \return USB_ERR_OK on sucess
513 *
514 * Behaviour of the device upon receiving a request:
515 *  - default state:    behaviour not specified
516 *  - address state:    device must respons with a request error
517 *  - configured state: valid request
518 *
519 *  If the interface or the alternate setting does not exist, then the device
520 *  responds with a Request Error.
521 */
522usb_error_t usb_set_alt_iface(uint16_t alt_setting, uint16_t interface)
523{
524    struct usb_device_request req;
525
526    req.bType.direction = USB_REQUEST_WRITE;
527    req.bType.type = USB_REQUEST_TYPE_STANDARD;
528    req.bType.recipient = USB_REQUEST_RECIPIENT_INTERFACE;
529    req.bRequest = USB_REQUEST_SET_INTERFACE;
530    req.wIndex = (0x00FF & interface);
531    req.wValue = (0x00FF & alt_setting);
532    req.wLength = 0;
533
534    return (usb_do_request(&req));
535}
536
537/**
538 * \brief This request is used to set and then report an endpoint���s
539 *           synchronization frame.
540 *
541 * \param endpoint:      The feature to enable. This value must be appropriate
542 *                          to the recipient.
543 * \param ret_frame:     The recipient of the request: USB_REQUEST_RECIPIENT_*
544 *
545 * \return USB_ERR_OK on sucess
546 *
547 * Behavior of the device upon receiving a request:
548 *  - default state:    behavior not specified
549 *  - address state:    device shall response with a request error
550 *  - configured state: valid request
551 */
552usb_error_t usb_synch_frame(uint8_t endpoint, uint16_t *ret_frame)
553{
554    struct usb_device_request req;
555
556    req.bType.direction = USB_REQUEST_READ;
557    req.bType.type = USB_REQUEST_TYPE_STANDARD;
558    req.bType.recipient = USB_REQUEST_RECIPIENT_ENDPOINT;
559    req.bRequest = USB_REQUEST_SYNCH_FRAME;
560    req.wIndex = endpoint;
561    req.wValue = 0;
562    req.wLength = 2;
563
564    uint16_t ret_length;
565    void *ret_data;
566
567    if (ret_frame) {
568        *ret_frame = 0;
569    }
570
571    usb_error_t err = usb_do_request_read(&req, &ret_length, &ret_data);
572
573    if (err != USB_ERR_OK) {
574        return (err);
575    }
576
577    /* the returned data must be of length 2 */
578    if (ret_length != 2) {
579        return (USB_ERR_IOERROR);
580    }
581
582    if (ret_frame) {
583        *ret_frame = *((uint16_t *) ret_data);
584        free(ret_data);
585    }
586    return (USB_ERR_OK);
587}
588
589/**
590 * \brief this function executes a device request without a data stage
591 *
592 * \return USB_ERR_OK on success, error code otherwise
593 */
594usb_error_t usb_do_request(struct usb_device_request *req)
595{
596    errval_t err;
597    uint32_t ret_status = 0;
598
599    USB_DEBUG_IDC("libusb: usb_do_request()\n");
600
601    err = usb_manager->rpc_tx_vtbl.request(usb_manager, (uint8_t*) req, sizeof(*req),
602            &ret_status);
603
604    if (err_is_fail(err)) {
605        DEBUG_ERR(err, "libusb: do_request rpc failed");
606        return (USB_ERR_IDC);
607    }
608
609    USB_DEBUG_IDC("libusb: usb_do_request() succeeded\n");
610
611    return ((usb_error_t) ret_status);
612}
613
614/**
615 * \brief this function executes a device request with a write a data stage
616 *
617 * \return USB_ERR_OK on success, error code otherwise
618 */
619usb_error_t usb_do_request_write(struct usb_device_request *req,
620        uint16_t length, void *data)
621{
622    errval_t err;
623    uint32_t ret_status;
624
625    USB_DEBUG_IDC("libusb: usb_do_request_write()\n");
626
627    err = usb_manager->rpc_tx_vtbl.request_write(usb_manager, (uint8_t*) req,
628            sizeof(*req), (uint8_t *) data, length, &ret_status);
629
630    if (err_is_fail(err)) {
631        DEBUG_ERR(err, "libusb: do_request_write rpc failed");
632        return (USB_ERR_IDC);
633    }
634
635    USB_DEBUG_IDC("libusb: usb_do_request_write() succeeded\n");
636
637    return ((usb_error_t) ret_status);
638}
639
640/**
641 * \brief this function executes a device request with a read a data stage
642 *
643 * \return USB_ERR_OK on success, error code otherwise
644 */
645usb_error_t usb_do_request_read(struct usb_device_request *req,
646        uint16_t *ret_length, void **ret_data)
647{
648    errval_t err;
649    uint32_t ret_status = 0;
650    uint8_t data[2048];
651    size_t length = 0;
652    usb_error_t ret;
653
654    USB_DEBUG_IDC("libusb: usb_do_request_read()\n");
655
656    err = usb_manager->rpc_tx_vtbl.request_read(usb_manager, (uint8_t*) req,
657            sizeof(*req), data, &length, &ret_status);
658
659    *ret_length = length;
660
661    ret = (usb_error_t) ret_status;
662
663
664    if (err_is_fail(err)) {
665        DEBUG_ERR(err, "libusb: do_request_write rpc failed");
666        *ret_length = 0;
667        *ret_data = NULL;
668        return (USB_ERR_IDC);
669    }
670
671    USB_DEBUG_IDC("libusb: usb_do_request_read() got data (len=%i)\n", *ret_length);
672
673    *ret_data = memdup(data, sizeof(data));
674
675    return (ret);
676}
677