You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.7KB

  1. /* USB Device Info class
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a
  4. * copy of this software and associated documentation files (the
  5. * "Software"), to deal in the Software without restriction, including
  6. * without limitation the rights to use, copy, modify, merge, publish,
  7. * distribute, sublicense, and/or sell copies of the Software, and to
  8. * permit persons to whom the Software is furnished to do so, subject to
  9. * the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included
  12. * in all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  17. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  18. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  19. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  20. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. // This simple class does nothing, but print out information about the device it
  23. // extracts from calls to claim...
  24. #include <Arduino.h>
  25. #include <USBHost_t36.h>
  26. #include "USBDeviceInfo.h"
  27. extern void dump_hexbytes(const void *ptr, uint32_t len);
  28. static void println(const char *title, uint32_t val, uint8_t b = DEC) {
  29. Serial.print(title);
  30. Serial.println(val, b);
  31. }
  32. static void print(const char *title, uint32_t val, uint8_t b = DEC) {
  33. Serial.print(title);
  34. Serial.print(val, b);
  35. }
  36. void USBDeviceInfo::init()
  37. {
  38. driver_ready_for_device(this);
  39. }
  40. // Again this class is solely to display as much information about a device as we can...
  41. // This all comes from the information passed to it through the claim method.
  42. bool USBDeviceInfo::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len) {
  43. println("\nUSBDeviceInfo claim this=", (uint32_t)this, HEX);
  44. if (type == 0) {
  45. // At device level
  46. Serial.println("\n****************************************");
  47. Serial.println("** Device Level **");
  48. println(" vid=", dev->idVendor, HEX);
  49. println(" pid=", dev->idProduct, HEX);
  50. println(" bDeviceClass = ", dev->bDeviceClass);
  51. println(" bDeviceSubClass = ", dev->bDeviceSubClass);
  52. println(" bDeviceProtocol = ", dev->bDeviceProtocol);
  53. dump_hexbytes(descriptors, len);
  54. return false;
  55. }
  56. // only claim at interface level
  57. Serial.println("\n****************************************");
  58. Serial.println("** Interface Level **");
  59. dump_hexbytes(descriptors, len);
  60. if (len < 9+9+7) return false;
  61. // interface descriptor
  62. uint32_t numendpoint = descriptors[4];
  63. println(" bInterfaceNumber = ", descriptors[2]);
  64. println(" number end points = ", numendpoint);
  65. println(" bInterfaceClass = ", descriptors[5]);
  66. println(" bInterfaceSubClass = ", descriptors[6]);
  67. switch (descriptors[5]) {
  68. case 2: Serial.println(" Communicatons and CDC"); break;
  69. case 3:
  70. if (descriptors[6] == 1) Serial.println(" HID (BOOT)");
  71. else Serial.println(" HID");
  72. break;
  73. case 0xa: Serial.println(" CDC-Data"); break;
  74. }
  75. println(" bInterfaceProtocol = ", descriptors[7]);
  76. //if (numendpoint < 1 || numendpoint > 2) return false;
  77. // hid interface descriptor
  78. uint32_t offset = 9;
  79. uint32_t hidlen = descriptors[offset];
  80. uint16_t descsize = 0;
  81. if (hidlen < 9) return false;
  82. if (descriptors[10] == 33) { // This is a HID Descriptor type. return false; // descriptor type, 33=HID
  83. if (descriptors[14] < 1) return false; // must be at least 1 extra descriptor
  84. if (hidlen != (uint32_t)(6 + descriptors[14] * 3)) return false; // must be correct size
  85. if (9 + hidlen > len) return false;
  86. uint32_t i=0;
  87. while (1) {
  88. if (descriptors[15 + i * 3] == 34) { // found HID report descriptor
  89. descsize = descriptors[16 + i * 3] | (descriptors[17 + i * 3] << 8);
  90. println("report descriptor size = ", descsize);
  91. break;
  92. }
  93. i++;
  94. if (i >= descriptors[14]) break;;
  95. }
  96. offset += hidlen;
  97. }
  98. // endpoint descriptor(s)
  99. while (numendpoint && (offset < len)) {
  100. if ((descriptors[offset] == 7) && (descriptors[offset+1] == 5)) {
  101. // we have an end point:
  102. println(" endpoint = ", descriptors[offset+2], HEX);
  103. print( " attributes = ", descriptors[offset+3], HEX);
  104. switch (descriptors[offset+3] & 0x3) {
  105. case 0: Serial.println(" Control"); break;
  106. case 1: Serial.println(" Isochronous"); break;
  107. case 2: Serial.println(" Bulk"); break;
  108. case 3: Serial.println(" Interrupt"); break;
  109. }
  110. uint32_t size = descriptors[offset+4] | (descriptors[offset+5] << 8);
  111. println(" size = ", size);
  112. println(" interval = ", descriptors[offset+6]);
  113. numendpoint--;
  114. }
  115. offset += descriptors[offset];
  116. }
  117. return false;
  118. }