Tim H / Mbed OS UsbKnob

Dependencies:   USBDevice

Committer:
Timmmm
Date:
Fri Nov 04 22:07:07 2016 +0000
Revision:
0:1a3aa2e25db9
Child:
1:0c3b6cc480b6
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Timmmm 0:1a3aa2e25db9 1 #pragma once
Timmmm 0:1a3aa2e25db9 2
Timmmm 0:1a3aa2e25db9 3 #include "WinUSBDevice.h"
Timmmm 0:1a3aa2e25db9 4
Timmmm 0:1a3aa2e25db9 5 #include <USBDescriptor.h>
Timmmm 0:1a3aa2e25db9 6
Timmmm 0:1a3aa2e25db9 7 #include <cstring>
Timmmm 0:1a3aa2e25db9 8
Timmmm 0:1a3aa2e25db9 9 using std::memcpy;
Timmmm 0:1a3aa2e25db9 10
Timmmm 0:1a3aa2e25db9 11 // Microsoft OS String Descriptor
Timmmm 0:1a3aa2e25db9 12 #define STRING_OFFSET_MSOS (0xEE)
Timmmm 0:1a3aa2e25db9 13
Timmmm 0:1a3aa2e25db9 14 // Vendor-defined request code to get the compatible IDs. I set it to 33 to aid debugging. The actual value doesn't matter.
Timmmm 0:1a3aa2e25db9 15 #define GET_MS_DESCRIPTORS (33)
Timmmm 0:1a3aa2e25db9 16
Timmmm 0:1a3aa2e25db9 17
Timmmm 0:1a3aa2e25db9 18 #define GENRE_INDEX (1)
Timmmm 0:1a3aa2e25db9 19 #define COMPAT_ID_INDEX (4)
Timmmm 0:1a3aa2e25db9 20 #define EXTENDED_PROPERTIES_INDEX (5)
Timmmm 0:1a3aa2e25db9 21
Timmmm 0:1a3aa2e25db9 22 #define USB_DT_STRING (3) // USB 2.0 spec table 9.5; Linux header ch9.h
Timmmm 0:1a3aa2e25db9 23
Timmmm 0:1a3aa2e25db9 24 #ifndef nullptr
Timmmm 0:1a3aa2e25db9 25 #define nullptr NULL
Timmmm 0:1a3aa2e25db9 26 #endif
Timmmm 0:1a3aa2e25db9 27
Timmmm 0:1a3aa2e25db9 28 // Copy a string, *not* including its null terminator to the destination, up to a maximum of maxBytes.
Timmmm 0:1a3aa2e25db9 29 void copyString8(uint8_t* dest, int maxBytes, const char* src)
Timmmm 0:1a3aa2e25db9 30 {
Timmmm 0:1a3aa2e25db9 31 for (int i = 0; i < maxBytes; ++i)
Timmmm 0:1a3aa2e25db9 32 {
Timmmm 0:1a3aa2e25db9 33 if (src[i] == nullptr)
Timmmm 0:1a3aa2e25db9 34 return;
Timmmm 0:1a3aa2e25db9 35 dest[i] = src[i];
Timmmm 0:1a3aa2e25db9 36 }
Timmmm 0:1a3aa2e25db9 37 }
Timmmm 0:1a3aa2e25db9 38
Timmmm 0:1a3aa2e25db9 39 // Copy a string, *not* including its null terminator to the destination, up to a maximum of maxBytes, but in UTF-16.
Timmmm 0:1a3aa2e25db9 40 void copyString16(uint8_t* dest, int maxBytes, const char* src)
Timmmm 0:1a3aa2e25db9 41 {
Timmmm 0:1a3aa2e25db9 42 for (int i = 0; i < maxBytes; ++i)
Timmmm 0:1a3aa2e25db9 43 {
Timmmm 0:1a3aa2e25db9 44 if (i % 2 == 0)
Timmmm 0:1a3aa2e25db9 45 {
Timmmm 0:1a3aa2e25db9 46 if (src[i/2] == nullptr)
Timmmm 0:1a3aa2e25db9 47 return;
Timmmm 0:1a3aa2e25db9 48 dest[i] = src[i/2];
Timmmm 0:1a3aa2e25db9 49 }
Timmmm 0:1a3aa2e25db9 50 else
Timmmm 0:1a3aa2e25db9 51 {
Timmmm 0:1a3aa2e25db9 52 dest[i] = 0;
Timmmm 0:1a3aa2e25db9 53 }
Timmmm 0:1a3aa2e25db9 54 }
Timmmm 0:1a3aa2e25db9 55 }
Timmmm 0:1a3aa2e25db9 56
Timmmm 0:1a3aa2e25db9 57 // Print information about a USB setup transfer.
Timmmm 0:1a3aa2e25db9 58 void debugUsbSetup(const CONTROL_TRANSFER& transfer)
Timmmm 0:1a3aa2e25db9 59 {
Timmmm 0:1a3aa2e25db9 60 printf("\n");
Timmmm 0:1a3aa2e25db9 61
Timmmm 0:1a3aa2e25db9 62 switch (transfer.setup.bmRequestType.Recipient)
Timmmm 0:1a3aa2e25db9 63 {
Timmmm 0:1a3aa2e25db9 64 case DEVICE_RECIPIENT:
Timmmm 0:1a3aa2e25db9 65 printf("Recipient: Device\n");
Timmmm 0:1a3aa2e25db9 66 break;
Timmmm 0:1a3aa2e25db9 67 case INTERFACE_RECIPIENT:
Timmmm 0:1a3aa2e25db9 68 printf("Recipient: Interface\n");
Timmmm 0:1a3aa2e25db9 69 break;
Timmmm 0:1a3aa2e25db9 70 case ENDPOINT_RECIPIENT:
Timmmm 0:1a3aa2e25db9 71 printf("Recipient: Endpoint\n");
Timmmm 0:1a3aa2e25db9 72 break;
Timmmm 0:1a3aa2e25db9 73 case OTHER_RECIPIENT:
Timmmm 0:1a3aa2e25db9 74 printf("Recipient: Other\n");
Timmmm 0:1a3aa2e25db9 75 break;
Timmmm 0:1a3aa2e25db9 76 default:
Timmmm 0:1a3aa2e25db9 77 printf("Recipient: Unknown\n");
Timmmm 0:1a3aa2e25db9 78 break;
Timmmm 0:1a3aa2e25db9 79 }
Timmmm 0:1a3aa2e25db9 80
Timmmm 0:1a3aa2e25db9 81 printf("Length: %d\n", transfer.setup.wLength);
Timmmm 0:1a3aa2e25db9 82
Timmmm 0:1a3aa2e25db9 83 switch (transfer.setup.bmRequestType.Type)
Timmmm 0:1a3aa2e25db9 84 {
Timmmm 0:1a3aa2e25db9 85 case STANDARD_TYPE:
Timmmm 0:1a3aa2e25db9 86 printf("Request type: Standard\nRequest: ");
Timmmm 0:1a3aa2e25db9 87 switch (transfer.setup.bRequest)
Timmmm 0:1a3aa2e25db9 88 {
Timmmm 0:1a3aa2e25db9 89 case GET_STATUS:
Timmmm 0:1a3aa2e25db9 90 printf("GET_STATUS\n");
Timmmm 0:1a3aa2e25db9 91 break;
Timmmm 0:1a3aa2e25db9 92 case CLEAR_FEATURE:
Timmmm 0:1a3aa2e25db9 93 printf("CLEAR_FEATURE\n");
Timmmm 0:1a3aa2e25db9 94 break;
Timmmm 0:1a3aa2e25db9 95 case SET_FEATURE:
Timmmm 0:1a3aa2e25db9 96 printf("SET_FEATURE\n");
Timmmm 0:1a3aa2e25db9 97 break;
Timmmm 0:1a3aa2e25db9 98 case SET_ADDRESS:
Timmmm 0:1a3aa2e25db9 99 printf("SET_ADDRESS\n");
Timmmm 0:1a3aa2e25db9 100 break;
Timmmm 0:1a3aa2e25db9 101 case GET_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 102 printf("GET_DESCRIPTOR\nDescriptor Type: ");
Timmmm 0:1a3aa2e25db9 103 switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
Timmmm 0:1a3aa2e25db9 104 {
Timmmm 0:1a3aa2e25db9 105 case DEVICE_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 106 printf("DEVICE_DESCRIPTOR\n");
Timmmm 0:1a3aa2e25db9 107 break;
Timmmm 0:1a3aa2e25db9 108 case CONFIGURATION_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 109 printf("CONFIGURATION_DESCRIPTOR\n");
Timmmm 0:1a3aa2e25db9 110 break;
Timmmm 0:1a3aa2e25db9 111 case STRING_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 112 printf("STRING_DESCRIPTOR\nDescriptor Index: ");
Timmmm 0:1a3aa2e25db9 113 switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
Timmmm 0:1a3aa2e25db9 114 {
Timmmm 0:1a3aa2e25db9 115 case STRING_OFFSET_LANGID:
Timmmm 0:1a3aa2e25db9 116 printf("STRING_OFFSET_LANGID\n");
Timmmm 0:1a3aa2e25db9 117 break;
Timmmm 0:1a3aa2e25db9 118 case STRING_OFFSET_IMANUFACTURER:
Timmmm 0:1a3aa2e25db9 119 printf("STRING_OFFSET_IMANUFACTURER\n");
Timmmm 0:1a3aa2e25db9 120 break;
Timmmm 0:1a3aa2e25db9 121 case STRING_OFFSET_IPRODUCT:
Timmmm 0:1a3aa2e25db9 122 printf("STRING_OFFSET_IPRODUCT\n");
Timmmm 0:1a3aa2e25db9 123 break;
Timmmm 0:1a3aa2e25db9 124 case STRING_OFFSET_ISERIAL:
Timmmm 0:1a3aa2e25db9 125 printf("STRING_OFFSET_ISERIAL\n");
Timmmm 0:1a3aa2e25db9 126 break;
Timmmm 0:1a3aa2e25db9 127 case STRING_OFFSET_ICONFIGURATION:
Timmmm 0:1a3aa2e25db9 128 printf("STRING_OFFSET_ICONFIGURATION\n");
Timmmm 0:1a3aa2e25db9 129 break;
Timmmm 0:1a3aa2e25db9 130 case STRING_OFFSET_IINTERFACE:
Timmmm 0:1a3aa2e25db9 131 printf("STRING_OFFSET_IINTERFACE\n");
Timmmm 0:1a3aa2e25db9 132 break;
Timmmm 0:1a3aa2e25db9 133 case STRING_OFFSET_MSOS:
Timmmm 0:1a3aa2e25db9 134 // This is a Microsoft extension. I think it's a reasonable one before you get all anti-MS.
Timmmm 0:1a3aa2e25db9 135 printf("STRING_OFFSET_MSOS\n");
Timmmm 0:1a3aa2e25db9 136 break;
Timmmm 0:1a3aa2e25db9 137 default:
Timmmm 0:1a3aa2e25db9 138 printf("Index 0x%02hhx\n", DESCRIPTOR_INDEX(transfer.setup.wValue));
Timmmm 0:1a3aa2e25db9 139 break;
Timmmm 0:1a3aa2e25db9 140 }
Timmmm 0:1a3aa2e25db9 141 break;
Timmmm 0:1a3aa2e25db9 142 case INTERFACE_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 143 printf("INTERFACE_DESCRIPTOR\n");
Timmmm 0:1a3aa2e25db9 144 break;
Timmmm 0:1a3aa2e25db9 145 case ENDPOINT_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 146 printf("ENDPOINT_DESCRIPTOR\n");
Timmmm 0:1a3aa2e25db9 147 break;
Timmmm 0:1a3aa2e25db9 148 case QUALIFIER_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 149 printf("QUALIFIER_DESCRIPTOR\n");
Timmmm 0:1a3aa2e25db9 150 break;
Timmmm 0:1a3aa2e25db9 151 default:
Timmmm 0:1a3aa2e25db9 152 printf("Descriptor 0x%02hhx\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
Timmmm 0:1a3aa2e25db9 153 break;
Timmmm 0:1a3aa2e25db9 154 }
Timmmm 0:1a3aa2e25db9 155 break;
Timmmm 0:1a3aa2e25db9 156 case SET_DESCRIPTOR:
Timmmm 0:1a3aa2e25db9 157 printf("SET_DESCRIPTOR\n");
Timmmm 0:1a3aa2e25db9 158 break;
Timmmm 0:1a3aa2e25db9 159 case GET_CONFIGURATION:
Timmmm 0:1a3aa2e25db9 160 printf("GET_CONFIGURATION\n");
Timmmm 0:1a3aa2e25db9 161 break;
Timmmm 0:1a3aa2e25db9 162 case SET_CONFIGURATION:
Timmmm 0:1a3aa2e25db9 163 printf("SET_CONFIGURATION\n");
Timmmm 0:1a3aa2e25db9 164 break;
Timmmm 0:1a3aa2e25db9 165 case GET_INTERFACE:
Timmmm 0:1a3aa2e25db9 166 printf("GET_INTERFACE\n");
Timmmm 0:1a3aa2e25db9 167 break;
Timmmm 0:1a3aa2e25db9 168 case SET_INTERFACE:
Timmmm 0:1a3aa2e25db9 169 printf("SET_INTERFACE\n");
Timmmm 0:1a3aa2e25db9 170 break;
Timmmm 0:1a3aa2e25db9 171 case 12: //SYNCH_FRAME:
Timmmm 0:1a3aa2e25db9 172 printf("SYNCH_FRAME\n");
Timmmm 0:1a3aa2e25db9 173 break;
Timmmm 0:1a3aa2e25db9 174 default:
Timmmm 0:1a3aa2e25db9 175 printf("Request 0x%02hhx\n", transfer.setup.bRequest);
Timmmm 0:1a3aa2e25db9 176 }
Timmmm 0:1a3aa2e25db9 177 break;
Timmmm 0:1a3aa2e25db9 178 case CLASS_TYPE:
Timmmm 0:1a3aa2e25db9 179 printf("Request type: Class Request 0x%02hhx\n", transfer.setup.bRequest);
Timmmm 0:1a3aa2e25db9 180 break;
Timmmm 0:1a3aa2e25db9 181 case VENDOR_TYPE:
Timmmm 0:1a3aa2e25db9 182 printf("Request type: Vendor\nRequest: ");
Timmmm 0:1a3aa2e25db9 183 switch (transfer.setup.bRequest)
Timmmm 0:1a3aa2e25db9 184 {
Timmmm 0:1a3aa2e25db9 185 // Note that GET_MS_DESCRIPTORS is an arbitrary value, which is returned in the STRING_OFFSET_MSOS string descriptor.
Timmmm 0:1a3aa2e25db9 186 case GET_MS_DESCRIPTORS:
Timmmm 0:1a3aa2e25db9 187 printf("GET_MS_DESCRIPTORS\nIndex: ");
Timmmm 0:1a3aa2e25db9 188 switch (transfer.setup.wIndex)
Timmmm 0:1a3aa2e25db9 189 {
Timmmm 0:1a3aa2e25db9 190 case COMPAT_ID_INDEX:
Timmmm 0:1a3aa2e25db9 191 printf("COMPAT_ID_INDEX\n");
Timmmm 0:1a3aa2e25db9 192 break;
Timmmm 0:1a3aa2e25db9 193 case EXTENDED_PROPERTIES_INDEX:
Timmmm 0:1a3aa2e25db9 194 printf("EXTENDED_PROPERTIES_INDEX\n");
Timmmm 0:1a3aa2e25db9 195 break;
Timmmm 0:1a3aa2e25db9 196 case GENRE_INDEX:
Timmmm 0:1a3aa2e25db9 197 printf("GENRE_INDEX\n");
Timmmm 0:1a3aa2e25db9 198 break;
Timmmm 0:1a3aa2e25db9 199 default:
Timmmm 0:1a3aa2e25db9 200 printf("0x%02hhx\n", transfer.setup.wIndex);
Timmmm 0:1a3aa2e25db9 201 break;
Timmmm 0:1a3aa2e25db9 202 }
Timmmm 0:1a3aa2e25db9 203 break;
Timmmm 0:1a3aa2e25db9 204 default:
Timmmm 0:1a3aa2e25db9 205 printf("Request 0x%02hhx\n", transfer.setup.bRequest);
Timmmm 0:1a3aa2e25db9 206 break;
Timmmm 0:1a3aa2e25db9 207 }
Timmmm 0:1a3aa2e25db9 208 break;
Timmmm 0:1a3aa2e25db9 209 case RESERVED_TYPE:
Timmmm 0:1a3aa2e25db9 210 printf("Request type: Reserved Request 0x%02hhx\n", transfer.setup.bRequest);
Timmmm 0:1a3aa2e25db9 211 break;
Timmmm 0:1a3aa2e25db9 212 default:
Timmmm 0:1a3aa2e25db9 213 printf("Request type: Unknown Request 0x%02hhx\n", transfer.setup.bRequest);
Timmmm 0:1a3aa2e25db9 214 break;
Timmmm 0:1a3aa2e25db9 215 }
Timmmm 0:1a3aa2e25db9 216 }
Timmmm 0:1a3aa2e25db9 217
Timmmm 0:1a3aa2e25db9 218
Timmmm 0:1a3aa2e25db9 219 WinUSBDevice::WinUSBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, const char* guid) : USBDevice(vendor_id, product_id, product_release)
Timmmm 0:1a3aa2e25db9 220 {
Timmmm 0:1a3aa2e25db9 221 // Initialise the descriptors we'll return.
Timmmm 0:1a3aa2e25db9 222 memset(&osStringDesc, 0, sizeof(osStringDesc));
Timmmm 0:1a3aa2e25db9 223
Timmmm 0:1a3aa2e25db9 224 osStringDesc.bLength = sizeof(osStringDesc);
Timmmm 0:1a3aa2e25db9 225 osStringDesc.bDescriptorType = USB_DT_STRING;
Timmmm 0:1a3aa2e25db9 226 copyString16(osStringDesc.qwSignature, sizeof(osStringDesc.qwSignature), "MSFT100");
Timmmm 0:1a3aa2e25db9 227 osStringDesc.bMS_VendorCode = GET_MS_DESCRIPTORS;
Timmmm 0:1a3aa2e25db9 228
Timmmm 0:1a3aa2e25db9 229 memset(&compatIdData, 0, sizeof(compatIdData));
Timmmm 0:1a3aa2e25db9 230
Timmmm 0:1a3aa2e25db9 231 compatIdData.header.dwLength = sizeof(compatIdData); // Length of the complete Extended Compat header (and contents?)
Timmmm 0:1a3aa2e25db9 232 compatIdData.header.bcdVersion = 0x0100;
Timmmm 0:1a3aa2e25db9 233 compatIdData.header.wIndex = COMPAT_ID_INDEX;
Timmmm 0:1a3aa2e25db9 234 compatIdData.header.bCount = 1;
Timmmm 0:1a3aa2e25db9 235
Timmmm 0:1a3aa2e25db9 236 compatIdData.data[0].bFirstInterfaceNumber = 0;
Timmmm 0:1a3aa2e25db9 237 copyString8(compatIdData.data[0].compatibleID, sizeof(compatIdData.data[0].compatibleID), "WINUSB");
Timmmm 0:1a3aa2e25db9 238
Timmmm 0:1a3aa2e25db9 239 memset(&extendedPropertyData, 0, sizeof(extendedPropertyData));
Timmmm 0:1a3aa2e25db9 240
Timmmm 0:1a3aa2e25db9 241 extendedPropertyData.header.dwLength = sizeof(extendedPropertyData); // Length of the complete Extended Compat header (and contents)
Timmmm 0:1a3aa2e25db9 242 extendedPropertyData.header.bcdVersion = 0x0100; // This is little endian apparently.
Timmmm 0:1a3aa2e25db9 243 extendedPropertyData.header.wIndex = EXTENDED_PROPERTIES_INDEX;
Timmmm 0:1a3aa2e25db9 244 extendedPropertyData.header.wCount = 1;
Timmmm 0:1a3aa2e25db9 245
Timmmm 0:1a3aa2e25db9 246 extendedPropertyData.data[0].dwSize = sizeof(extendedPropertyData.data[0]);
Timmmm 0:1a3aa2e25db9 247 extendedPropertyData.data[0].dwPropertyDataType = 7; // 1 means NULL terminated unicode string. 7 means a list of strings (for the GUID*s* variant).
Timmmm 0:1a3aa2e25db9 248 extendedPropertyData.data[0].wPropertyNameLength = sizeof(extendedPropertyData.data[0].bPropertyName);
Timmmm 0:1a3aa2e25db9 249 copyString16(extendedPropertyData.data[0].bPropertyName, sizeof(extendedPropertyData.data[0].bPropertyName), "DeviceInterfaceGUIDs");
Timmmm 0:1a3aa2e25db9 250 extendedPropertyData.data[0].dwPropertyDataLength = sizeof(extendedPropertyData.data[0].bPropertyData);
Timmmm 0:1a3aa2e25db9 251 copyString16(extendedPropertyData.data[0].bPropertyData, sizeof(extendedPropertyData.data[0].bPropertyData), guid);
Timmmm 0:1a3aa2e25db9 252 }
Timmmm 0:1a3aa2e25db9 253
Timmmm 0:1a3aa2e25db9 254 bool WinUSBDevice::USBCallback_request()
Timmmm 0:1a3aa2e25db9 255 {
Timmmm 0:1a3aa2e25db9 256 // This can never be null.
Timmmm 0:1a3aa2e25db9 257 CONTROL_TRANSFER& transfer = *getTransferPtr();
Timmmm 0:1a3aa2e25db9 258
Timmmm 0:1a3aa2e25db9 259 debugUsbSetup(transfer);
Timmmm 0:1a3aa2e25db9 260
Timmmm 0:1a3aa2e25db9 261 // EXTENDED_PROPERTIES_INDEX is sent to the interface, not the device so we can't universally reject non-device requests.
Timmmm 0:1a3aa2e25db9 262 // if (transfer.setup.bmRequestType.Recipient != DEVICE_RECIPIENT)
Timmmm 0:1a3aa2e25db9 263 // return false;
Timmmm 0:1a3aa2e25db9 264
Timmmm 0:1a3aa2e25db9 265 // Intercept the request for string descriptor 0xEE
Timmmm 0:1a3aa2e25db9 266 if (transfer.setup.bmRequestType.Type == STANDARD_TYPE &&
Timmmm 0:1a3aa2e25db9 267 transfer.setup.bRequest == GET_DESCRIPTOR &&
Timmmm 0:1a3aa2e25db9 268 DESCRIPTOR_TYPE(transfer.setup.wValue) == STRING_DESCRIPTOR &&
Timmmm 0:1a3aa2e25db9 269 DESCRIPTOR_INDEX(transfer.setup.wValue) == STRING_OFFSET_MSOS)
Timmmm 0:1a3aa2e25db9 270 {
Timmmm 0:1a3aa2e25db9 271 transfer.ptr = reinterpret_cast<uint8_t*>(&osStringDesc);
Timmmm 0:1a3aa2e25db9 272 transfer.remaining = osStringDesc.bLength;
Timmmm 0:1a3aa2e25db9 273 transfer.direction = DEVICE_TO_HOST;
Timmmm 0:1a3aa2e25db9 274 return true;
Timmmm 0:1a3aa2e25db9 275 }
Timmmm 0:1a3aa2e25db9 276
Timmmm 0:1a3aa2e25db9 277 // Our custom descriptor.
Timmmm 0:1a3aa2e25db9 278 if (transfer.setup.bmRequestType.Type == VENDOR_TYPE &&
Timmmm 0:1a3aa2e25db9 279 transfer.setup.bRequest == GET_MS_DESCRIPTORS)
Timmmm 0:1a3aa2e25db9 280 {
Timmmm 0:1a3aa2e25db9 281 switch (transfer.setup.wIndex)
Timmmm 0:1a3aa2e25db9 282 {
Timmmm 0:1a3aa2e25db9 283 case COMPAT_ID_INDEX: // Extended Compat ID
Timmmm 0:1a3aa2e25db9 284 transfer.ptr = reinterpret_cast<uint8_t*>(&compatIdData);
Timmmm 0:1a3aa2e25db9 285 transfer.remaining = sizeof(compatIdData);
Timmmm 0:1a3aa2e25db9 286 transfer.direction = DEVICE_TO_HOST;
Timmmm 0:1a3aa2e25db9 287 return true;
Timmmm 0:1a3aa2e25db9 288 case EXTENDED_PROPERTIES_INDEX: // Extended Properties.
Timmmm 0:1a3aa2e25db9 289 transfer.ptr = reinterpret_cast<uint8_t*>(&extendedPropertyData);
Timmmm 0:1a3aa2e25db9 290 transfer.remaining = sizeof(extendedPropertyData);
Timmmm 0:1a3aa2e25db9 291 transfer.direction = DEVICE_TO_HOST;
Timmmm 0:1a3aa2e25db9 292 return true;
Timmmm 0:1a3aa2e25db9 293 case GENRE_INDEX: // Genre
Timmmm 0:1a3aa2e25db9 294 default:
Timmmm 0:1a3aa2e25db9 295 return false;
Timmmm 0:1a3aa2e25db9 296 }
Timmmm 0:1a3aa2e25db9 297 }
Timmmm 0:1a3aa2e25db9 298
Timmmm 0:1a3aa2e25db9 299
Timmmm 0:1a3aa2e25db9 300 return false;
Timmmm 0:1a3aa2e25db9 301 }