00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <assert.h>
00038 #include <errno.h>
00039 #include <str_error.h>
00040
00041 #include <usb/debug.h>
00042 #include <usb/hid/hidparser.h>
00043 #include <usb/dev/dp.h>
00044 #include <usb/dev/driver.h>
00045 #include <usb/dev/pipes.h>
00046 #include <usb/hid/hid.h>
00047 #include <usb/descriptor.h>
00048 #include <usb/dev/request.h>
00049
00050 #include <usb/hid/hidreport.h>
00051
00052 static int usb_hid_get_report_descriptor(usb_device_t *dev,
00053 uint8_t **report_desc, size_t *size)
00054 {
00055 assert(report_desc != NULL);
00056 assert(size != NULL);
00057
00058 usb_dp_parser_t parser = {
00059 .nesting = usb_dp_standard_descriptor_nesting
00060 };
00061
00062 usb_dp_parser_data_t parser_data = {
00063 .data = dev->descriptors.configuration,
00064 .size = dev->descriptors.configuration_size,
00065 .arg = NULL
00066 };
00067
00068
00069
00070
00071 uint8_t *d =
00072 usb_dp_get_nested_descriptor(&parser, &parser_data,
00073 dev->descriptors.configuration);
00074
00075
00076
00077
00078 int i = 0;
00079 while (d != NULL && i < dev->interface_no) {
00080 d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
00081 dev->descriptors.configuration, d);
00082 ++i;
00083 }
00084
00085 if (d == NULL) {
00086 usb_log_error("The %d. interface descriptor not found!\n",
00087 dev->interface_no);
00088 return ENOENT;
00089 }
00090
00091
00092
00093
00094 uint8_t *iface_desc = d;
00095 d = usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);
00096
00097
00098
00099
00100 while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) {
00101 d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
00102 iface_desc, d);
00103 }
00104
00105 if (d == NULL) {
00106 usb_log_fatal("No HID descriptor found!\n");
00107 return ENOENT;
00108 }
00109
00110 if (*d != sizeof(usb_standard_hid_descriptor_t)) {
00111 usb_log_error("HID descriptor has wrong size (%u, expected %zu"
00112 ")\n", *d, sizeof(usb_standard_hid_descriptor_t));
00113 return EINVAL;
00114 }
00115
00116 usb_standard_hid_descriptor_t *hid_desc =
00117 (usb_standard_hid_descriptor_t *)d;
00118
00119 uint16_t length = hid_desc->report_desc_info.length;
00120 size_t actual_size = 0;
00121
00122
00123
00124
00125 *report_desc = (uint8_t *)malloc(length);
00126 if (*report_desc == NULL) {
00127 usb_log_error("Failed to allocate space for Report descriptor."
00128 "\n");
00129 return ENOMEM;
00130 }
00131
00132 usb_log_debug("Getting Report descriptor, expected size: %u\n", length);
00133
00134
00135
00136
00137 int rc = usb_request_get_descriptor(&dev->ctrl_pipe,
00138 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
00139 USB_DESCTYPE_HID_REPORT, 0, dev->interface_no,
00140 *report_desc, length, &actual_size);
00141
00142 if (rc != EOK) {
00143 free(*report_desc);
00144 *report_desc = NULL;
00145 return rc;
00146 }
00147
00148 if (actual_size != length) {
00149 free(*report_desc);
00150 *report_desc = NULL;
00151 usb_log_error("Report descriptor has wrong size (%zu, expected "
00152 "%u)\n", actual_size, length);
00153 return EINVAL;
00154 }
00155
00156 *size = length;
00157
00158 usb_log_debug("Done.\n");
00159
00160 return EOK;
00161 }
00162
00163
00164
00165 int usb_hid_process_report_descriptor(usb_device_t *dev,
00166 usb_hid_report_t *report, uint8_t **report_desc, size_t *report_size)
00167 {
00168 if (dev == NULL || report == NULL) {
00169 usb_log_error("Failed to process Report descriptor: wrong "
00170 "parameters given.\n");
00171 return EINVAL;
00172 }
00173
00174
00175
00176
00177 int rc = usb_hid_get_report_descriptor(dev, report_desc, report_size);
00178
00179 if (rc != EOK) {
00180 usb_log_error("Problem with getting Report descriptor: %s.\n",
00181 str_error(rc));
00182 if (*report_desc != NULL) {
00183 free(*report_desc);
00184 *report_desc = NULL;
00185 }
00186 return rc;
00187 }
00188
00189 assert(*report_desc != NULL);
00190
00191 rc = usb_hid_parse_report_descriptor(report, *report_desc, *report_size);
00192 if (rc != EOK) {
00193 usb_log_error("Problem parsing Report descriptor: %s.\n",
00194 str_error(rc));
00195 free(*report_desc);
00196 *report_desc = NULL;
00197 return rc;
00198 }
00199
00200 usb_hid_descriptor_print(report);
00201
00202 return EOK;
00203 }
00204