Game Controller Collective Wiki
Advertisement


HID Interface[]

On USB and Dongle the full controller state is provided by Input report ReportIn01USB (0x01).

On Bluetooth the reduced controller state is provided by Input report ReportIn01BT (0x01). On reading Feature Input report ReportFeatureInCalibrateBT (0x05) the former reduced controller state Input report is no longer emitted and instead Input reports ReportIn11 (0x11) through ReportIn19 (0x19) are emitted.

All controller state Input reports on Bluetooth that are not the reduced input report (0x01) must check the EnableHID bit before processing data. If this bit is not set the packet does not contain controller state data and should instead have the EnableAudio bit high as it contains only audio data. All relevant bits should be checked before processing data. For reports larger than ReportIn11 (0x11) both state and audio data may be present. Controller state data is always placed before audio data when both are present.

Most HID reports over Bluetooth end in a CRC32 (0xedb88320) of the report contents. The bytes hashed includes the Bluetooth HID Report Type, Report ID, and report contents up to the CRC.

Bluetooth Report Types:

DATA (0xA0) + INPUT   (0x01) // HID Input
DATA (0xA0) + OUTPUT  (0x02) // HID Output
DATA (0xA0) + FEATURE (0x03) // HID Feature Input
     (0x50) + FEATURE (0x03) // HID Feature Output

Unsorted Commands:

Turn Off Controller:

Dongle Feature Write e2 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Bluetooth Feature Write: 53 08 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 ef a2 23

Debug command dump:

0xA0
0x00 NOP
0x00
0x00
0x00
0x00
0x00


0xA0
0x01 Test Sinwave ALL Audio Devices
0x01 Active, Off/On/invalid
0x00 Unused
0x00
0x00
0x00


0xA0
0x05 Write to audio chip
0x00
0x00 Addr
0x00 Val
0x00
0x00


0xA0
0x04 causes timeout?
0x01
0x00


0xA0
0x03 Flash 4000 Mirror Action
0x03
0x00 Unused
0x00
0x00
0x00


0x08
0xFF Flash 4000 Read
0x01 offset
0x00 Must be <= 0x07FF


0x08
0x20 Test Sinwave ALL Audio Devices
0x01 Active, Off/On/invalid
0x00


0x08
0x10
0x?? value
0x??


0x08
0x01
0x?? 0x10 - calib reset?
0x11 - calib add?
0x12 - calib to mirror?
0xXX - other


0x08
0x02
0x?? 0x40
0x80 (and !0x40)


Report Summaries[]

USB[]

ReportID Size Type Note
0x01 1 63 Input Get Controller State
0x05 5 31 Output Set Controller State
0x02 2 36 Feature Get Calibration
0x04 4 36 Feature ?Possible Set Calibration
0x08 8 3 Feature Write Debug Command (unconfirmed, confirmed for BT)
0x10 16 4 Feature UNKNOWN Read (2 shorts)
0x11 17 2 Feature UNKNOWN Read (1 short) (from FLASH?)
0x12 18 15 Feature Get Controller and Host MAC
0x13 19 22 Feature Set Host MAC and Link Key
0x14 20 16 Feature ?
0x15 21 44 Feature UNKNOWN Read EXT Device Data Buffer
0x80 128 6 Feature Set Controller MAC (temporary)
0x81 129 6 Feature Get Controller MAC
0x82 130 5 Feature ?
0x83 131 1 Feature ?
0x84 132 4 Feature ?
0x85 133 6 Feature ?
0x86 134 6 Feature ?
0x87 135 35 Feature ?
0x88 136 34 Feature set?
0x89 137 2 Feature ?
0x90 144 5 Feature ?
0x91 145 3 Feature ?
0x92 146 3 Feature ?
0x93 147 12 Feature ?
0xA0 160 6 Feature Write Debug Command
0xA1 161 1 Feature ?
0xA2 162 1 Feature Writing 0x01 appears to switch to DFU mode
0xA3 163 48 Feature Get Controller Version/Date
0xA4 164 13 Feature ?
0xA5 165 21 Feature Write data to bank at offset, UNKNOWN purpose
0xA6 166 21 Feature UNKNOWN Read, appears to read 2 data banks, last byte is not cleared from prior report
0xA7 247 1 Feature Write 1 byte, purpose unknown
0xA8 250 1 Feature UNKNOWN Read
0xA9 251 8 Feature UNKNOWN Read
0xAA 252 1 Feature ?
0xAB 253 57 Feature ?
0xAC 254 57 Feature UNKNOWN Read
0xAD 255 11 Feature UNKNOWN Read
0xAE 256 1 Feature Get AC_ON STATE
0xAF 175 2 Feature Get Audio Chip Ident
0xB0 176 63 Feature Debug Telemetry
0xF0 240 63 Feature ?
0xF1 241 63 Feature ?
0xF2 242 15 Feature ?

Bluetooth[]

ReportID Size Type Note
0x01 1 9 Input Get Controller State Simple
0x11 17 77 Input Get Controller State or Audio
0x12 18 141 Input Get Controller State and/or Audio
0x13 19 205 Input Get Controller State and/or Audio
0x14 20 269 Input Get Controller State and/or Audio
0x15 21 333 Input Get Controller State and/or Audio
0x16 22 397 Input Get Controller State and/or Audio
0x17 23 461 Input Get Controller State and/or Audio
0x18 24 525 Input Get Controller State and/or Audio
0x19 25 546 Input Get Controller State and/or Audio
0x11 17 77 Output Set Controller State or Audio
0x12 18 141 Output Set Controller State and/or Audio
0x13 19 205 Output Set Controller State and/or Audio
0x14 20 269 Output Set Controller State and/or Audio
0x15 21 333 Output Set Controller State and/or Audio
0x16 22 397 Output Set Controller State and/or Audio
0x17 23 461 Output Set Controller State and/or Audio
0x18 24 525 Output Set Controller State and/or Audio
0x19 25 546 Output Set Controller State and/or Audio
0x02 2 36 Feature ?
0x03 3 38 Feature UNKNOWN Write AUTH related?
0x04 4 46 Feature ?
0x05 5 40 Feature Get Calibration
0x06 6 52 Feature Get Controller Version/Date
0x07 7 48 Feature UNKNOWN Read EXT Device Data Buffer (with CRC32)
0x08 8 47 Feature Write Debug Command
0x09 9 19 Feature Get Controller and Host MAC
0x82 130 63 Feature ?
0x83 131 63 Feature ?
0x84 132 63 Feature ?
0x90 144 63 Feature ?
0x91 145 63 Feature ?
0x92 146 63 Feature ?
0x93 147 63 Feature ?
0x94 148 63 Feature ?
0xA0 160 63 Feature Write Debug Command
0xA3 163 48 Feature Get Controller Version/Date (omits CRC check)
0xA4 164 63 Feature ?
0xA7 167 63 Feature ?
0xA8 168 63 Feature UNKNOWN Read
0xA9 169 63 Feature UNKNOWN Read
0xAA 170 63 Feature ?
0xAB 171 63 Feature ?
0xAC 172 63 Feature UNKNOWN Read
0xAD 173 63 Feature UNKNOWN Read
0xB3 179 63 Feature ?
0xB4 180 63 Feature ?
0xB5 181 63 Feature ?
0xD0 208 63 Feature Set Test Command?
0xD4 212 63 Feature ?
0xF0 240 63 Feature Send challenge data
0xF1 241 63 Feature Read challenge response (after 0xF2)
0xF2 242 15 Feature Read challenge input ready state (after 0xF0)

Dongle[]

ReportID Size Type Note
Normal Mode (0x0BA0)
0x01 1 63 Input Get Controller State
0x05 5 31 Output Set Controller State
0x02 2 36 Feature Get Calibration (Bluetooth Data Order)
0x12 18 15 Feature Get Controller and Host MAC
0x15 21 45 Feature ?
0x80 128 6 Feature ?
0x81 129 6 Feature Get Controller MAC
0x85 133 6 Feature ?
0x86 134 6 Feature ?
0x8A 138 22 Feature ?
0xA0 160 6 Feature ?
0xA1 161 1 Feature ?
0xA2 162 1 Feature Set Enter DFU mode (change to PID 0x0BA1)
0xA3 163 48 Feature ?
0xA4 164 13 Feature ?
0xA5 165 21 Feature ?
0xA6 166 21 Feature ?
0xB0 176 63 Feature ?
0xE0 224 2 Feature Set Audio Output
0xE1 225 48 Feature Get Dongle Version/Date
0xE2 226 16 Feature Shutdown (Unknown Other Uses)
0xE3 227 4 Feature Get Controller VID and PID
0xE4 228 1 Feature ?
0xE5 229 6 Feature Get Dongle Host MAC
DFU Mode (0x0BA1)
0x02 2 63 Feature ?
0xF0 240 62 Feature Set Exit DFU mode (change to PID 0x0BA0)

Descriptor[]

USB[]

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x05,        // Usage (Game Pad)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x30,        //   Usage (X)
0x09, 0x31,        //   Usage (Y)
0x09, 0x32,        //   Usage (Z)
0x09, 0x35,        //   Usage (Rz)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x39,        //   Usage (Hat switch)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x07,        //   Logical Maximum (7)
0x35, 0x00,        //   Physical Minimum (0)
0x46, 0x3B, 0x01,  //   Physical Maximum (315)
0x65, 0x14,        //   Unit (System: English Rotation, Length: Centimeter)
0x75, 0x04,        //   Report Size (4)
0x95, 0x01,        //   Report Count (1)
0x81, 0x42,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x65, 0x00,        //   Unit (None)
0x05, 0x09,        //   Usage Page (Button)
0x19, 0x01,        //   Usage Minimum (0x01)
0x29, 0x0E,        //   Usage Maximum (0x0E)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x0E,        //   Report Count (14)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x09, 0x20,        //   Usage (0x20)
0x75, 0x06,        //   Report Size (6)
0x95, 0x01,        //   Report Count (1)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x7F,        //   Logical Maximum (127)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x33,        //   Usage (Rx)
0x09, 0x34,        //   Usage (Ry)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x02,        //   Report Count (2)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x36,        //   Report Count (54)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x05,        //   Report ID (5)
0x09, 0x22,        //   Usage (0x22)
0x95, 0x1F,        //   Report Count (31)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x04,        //   Report ID (4)
0x09, 0x23,        //   Usage (0x23)
0x95, 0x24,        //   Report Count (36)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x02,        //   Report ID (2)
0x09, 0x24,        //   Usage (0x24)
0x95, 0x24,        //   Report Count (36)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x08,        //   Report ID (8)
0x09, 0x25,        //   Usage (0x25)
0x95, 0x03,        //   Report Count (3)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x10,        //   Report ID (16)
0x09, 0x26,        //   Usage (0x26)
0x95, 0x04,        //   Report Count (4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x11,        //   Report ID (17)
0x09, 0x27,        //   Usage (0x27)
0x95, 0x02,        //   Report Count (2)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x12,        //   Report ID (18)
0x06, 0x02, 0xFF,  //   Usage Page (Vendor Defined 0xFF02)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x0F,        //   Report Count (15)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x13,        //   Report ID (19)
0x09, 0x22,        //   Usage (0x22)
0x95, 0x16,        //   Report Count (22)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x14,        //   Report ID (20)
0x06, 0x05, 0xFF,  //   Usage Page (Vendor Defined 0xFF05)
0x09, 0x20,        //   Usage (0x20)
0x95, 0x10,        //   Report Count (16)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x15,        //   Report ID (21)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x2C,        //   Report Count (44)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x80, 0xFF,  //   Usage Page (Vendor Defined 0xFF80)
0x85, 0x80,        //   Report ID (128)
0x09, 0x20,        //   Usage (0x20)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x81,        //   Report ID (129)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x82,        //   Report ID (130)
0x09, 0x22,        //   Usage (0x22)
0x95, 0x05,        //   Report Count (5)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x83,        //   Report ID (131)
0x09, 0x23,        //   Usage (0x23)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x84,        //   Report ID (132)
0x09, 0x24,        //   Usage (0x24)
0x95, 0x04,        //   Report Count (4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x85,        //   Report ID (133)
0x09, 0x25,        //   Usage (0x25)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x86,        //   Report ID (134)
0x09, 0x26,        //   Usage (0x26)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x87,        //   Report ID (135)
0x09, 0x27,        //   Usage (0x27)
0x95, 0x23,        //   Report Count (35)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x88,        //   Report ID (136)
0x09, 0x28,        //   Usage (0x28)
0x95, 0x22,        //   Report Count (34)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x89,        //   Report ID (137)
0x09, 0x29,        //   Usage (0x29)
0x95, 0x02,        //   Report Count (2)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x90,        //   Report ID (144)
0x09, 0x30,        //   Usage (0x30)
0x95, 0x05,        //   Report Count (5)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x91,        //   Report ID (145)
0x09, 0x31,        //   Usage (0x31)
0x95, 0x03,        //   Report Count (3)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x92,        //   Report ID (146)
0x09, 0x32,        //   Usage (0x32)
0x95, 0x03,        //   Report Count (3)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x93,        //   Report ID (147)
0x09, 0x33,        //   Usage (0x33)
0x95, 0x0C,        //   Report Count (12)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA0,        //   Report ID (160)
0x09, 0x40,        //   Usage (0x40)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA1,        //   Report ID (161)
0x09, 0x41,        //   Usage (0x41)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA2,        //   Report ID (162)
0x09, 0x42,        //   Usage (0x42)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA3,        //   Report ID (163)
0x09, 0x43,        //   Usage (0x43)
0x95, 0x30,        //   Report Count (48)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA4,        //   Report ID (164)
0x09, 0x44,        //   Usage (0x44)
0x95, 0x0D,        //   Report Count (13)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA5,        //   Report ID (165)
0x09, 0x45,        //   Usage (0x45)
0x95, 0x15,        //   Report Count (21)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA6,        //   Report ID (166)
0x09, 0x46,        //   Usage (0x46)
0x95, 0x15,        //   Report Count (21)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF0,        //   Report ID (240)
0x09, 0x47,        //   Usage (0x47)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF1,        //   Report ID (241)
0x09, 0x48,        //   Usage (0x48)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF2,        //   Report ID (242)
0x09, 0x49,        //   Usage (0x49)
0x95, 0x0F,        //   Report Count (15)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA7,        //   Report ID (247)
0x09, 0x4A,        //   Usage (0x4A)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA8,        //   Report ID (250)
0x09, 0x4B,        //   Usage (0x4B)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA9,        //   Report ID (251)
0x09, 0x4C,        //   Usage (0x4C)
0x95, 0x08,        //   Report Count (8)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAA,        //   Report ID (252)
0x09, 0x4E,        //   Usage (0x4E)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAB,        //   Report ID (253)
0x09, 0x4F,        //   Usage (0x4F)
0x95, 0x39,        //   Report Count (57)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAC,        //   Report ID (254)
0x09, 0x50,        //   Usage (0x50)
0x95, 0x39,        //   Report Count (57)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAD,        //   Report ID (255)
0x09, 0x51,        //   Usage (0x51)
0x95, 0x0B,        //   Report Count (11)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAE,        //   Report ID (256)
0x09, 0x52,        //   Usage (0x52)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAF,        //   Report ID (175)
0x09, 0x53,        //   Usage (0x53)
0x95, 0x02,        //   Report Count (2)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB0,        //   Report ID (176)
0x09, 0x54,        //   Usage (0x54)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 467 bytes

BT[]

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x05,        // Usage (Game Pad)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x30,        //   Usage (X)
0x09, 0x31,        //   Usage (Y)
0x09, 0x32,        //   Usage (Z)
0x09, 0x35,        //   Usage (Rz)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x39,        //   Usage (Hat switch)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x07,        //   Logical Maximum (7)
0x75, 0x04,        //   Report Size (4)
0x95, 0x01,        //   Report Count (1)
0x81, 0x42,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x05, 0x09,        //   Usage Page (Button)
0x19, 0x01,        //   Usage Minimum (0x01)
0x29, 0x0E,        //   Usage Maximum (0x0E)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x0E,        //   Report Count (14)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x06,        //   Report Size (6)
0x95, 0x01,        //   Report Count (1)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x33,        //   Usage (Rx)
0x09, 0x34,        //   Usage (Ry)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x02,        //   Report Count (2)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x04, 0xFF,  //   Usage Page (Vendor Defined 0xFF04)
0x85, 0x02,        //   Report ID (2)
0x09, 0x24,        //   Usage (0x24)
0x95, 0x24,        //   Report Count (36)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA3,        //   Report ID (163)
0x09, 0x25,        //   Usage (0x25)
0x95, 0x30,        //   Report Count (48)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x05,        //   Report ID (5)
0x09, 0x26,        //   Usage (0x26)
0x95, 0x28,        //   Report Count (40)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x06,        //   Report ID (6)
0x09, 0x27,        //   Usage (0x27)
0x95, 0x34,        //   Report Count (52)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x07,        //   Report ID (7)
0x09, 0x28,        //   Usage (0x28)
0x95, 0x30,        //   Report Count (48)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x08,        //   Report ID (8)
0x09, 0x29,        //   Usage (0x29)
0x95, 0x2F,        //   Report Count (47)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x09,        //   Report ID (9)
0x09, 0x2A,        //   Usage (0x2A)
0x95, 0x13,        //   Report Count (19)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x03, 0xFF,  //   Usage Page (Vendor Defined 0xFF03)
0x85, 0x03,        //   Report ID (3)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x26,        //   Report Count (38)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x04,        //   Report ID (4)
0x09, 0x22,        //   Usage (0x22)
0x95, 0x2E,        //   Report Count (46)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF0,        //   Report ID (240)
0x09, 0x47,        //   Usage (0x47)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF1,        //   Report ID (241)
0x09, 0x48,        //   Usage (0x48)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF2,        //   Report ID (242)
0x09, 0x49,        //   Usage (0x49)
0x95, 0x0F,        //   Report Count (15)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x85, 0x11,        //   Report ID (17)
0x09, 0x20,        //   Usage (0x20)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x4D,        //   Report Count (77)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x21,        //   Usage (0x21)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x12,        //   Report ID (18)
0x09, 0x22,        //   Usage (0x22)
0x95, 0x8D,        //   Report Count (141)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x23,        //   Usage (0x23)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x13,        //   Report ID (19)
0x09, 0x24,        //   Usage (0x24)
0x95, 0xCD,        //   Report Count (205)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x25,        //   Usage (0x25)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x14,        //   Report ID (20)
0x09, 0x26,        //   Usage (0x26)
0x96, 0x0D, 0x01,  //   Report Count (269)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x27,        //   Usage (0x27)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x15,        //   Report ID (21)
0x09, 0x28,        //   Usage (0x28)
0x96, 0x4D, 0x01,  //   Report Count (333)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x29,        //   Usage (0x29)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x16,        //   Report ID (22)
0x09, 0x2A,        //   Usage (0x2A)
0x96, 0x8D, 0x01,  //   Report Count (397)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x2B,        //   Usage (0x2B)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x17,        //   Report ID (23)
0x09, 0x2C,        //   Usage (0x2C)
0x96, 0xCD, 0x01,  //   Report Count (461)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x2D,        //   Usage (0x2D)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x18,        //   Report ID (24)
0x09, 0x2E,        //   Usage (0x2E)
0x96, 0x0D, 0x02,  //   Report Count (525)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x2F,        //   Usage (0x2F)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x19,        //   Report ID (25)
0x09, 0x30,        //   Usage (0x30)
0x96, 0x22, 0x02,  //   Report Count (546)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x31,        //   Usage (0x31)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x80, 0xFF,  //   Usage Page (Vendor Defined 0xFF80)
0x85, 0x82,        //   Report ID (130)
0x09, 0x22,        //   Usage (0x22)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x83,        //   Report ID (131)
0x09, 0x23,        //   Usage (0x23)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x84,        //   Report ID (132)
0x09, 0x24,        //   Usage (0x24)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x90,        //   Report ID (144)
0x09, 0x30,        //   Usage (0x30)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x91,        //   Report ID (145)
0x09, 0x31,        //   Usage (0x31)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x92,        //   Report ID (146)
0x09, 0x32,        //   Usage (0x32)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x93,        //   Report ID (147)
0x09, 0x33,        //   Usage (0x33)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x94,        //   Report ID (148)
0x09, 0x34,        //   Usage (0x34)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA0,        //   Report ID (160)
0x09, 0x40,        //   Usage (0x40)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA4,        //   Report ID (164)
0x09, 0x44,        //   Usage (0x44)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA7,        //   Report ID (167)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA8,        //   Report ID (168)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA9,        //   Report ID (169)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAA,        //   Report ID (170)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAB,        //   Report ID (171)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAC,        //   Report ID (172)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAD,        //   Report ID (173)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB3,        //   Report ID (179)
0x09, 0x45,        //   Usage (0x45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB4,        //   Report ID (180)
0x09, 0x46,        //   Usage (0x46)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB5,        //   Report ID (181)
0x09, 0x47,        //   Usage (0x47)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xD0,        //   Report ID (208)
0x09, 0x40,        //   Usage (0x40)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xD4,        //   Report ID (212)
0x09, 0x44,        //   Usage (0x44)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 442 bytes

Dongle[]

0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x30,        //   Usage (0x30)
0x09, 0x31,        //   Usage (0x31)
0x09, 0x32,        //   Usage (0x32)
0x09, 0x35,        //   Usage (0x35)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x39,        //   Usage (0x39)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x07,        //   Logical Maximum (7)
0x35, 0x00,        //   Physical Minimum (0)
0x46, 0x3B, 0x01,  //   Physical Maximum (315)
0x65, 0x14,        //   Unit (System: English Rotation, Length: Centimeter)
0x75, 0x04,        //   Report Size (4)
0x95, 0x01,        //   Report Count (1)
0x81, 0x42,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x65, 0x00,        //   Unit (None)
0x05, 0x09,        //   Usage Page (Button)
0x19, 0x01,        //   Usage Minimum (0x01)
0x29, 0x0E,        //   Usage Maximum (0x0E)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x0E,        //   Report Count (14)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x09, 0x20,        //   Usage (0x20)
0x75, 0x06,        //   Report Size (6)
0x95, 0x01,        //   Report Count (1)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x7F,        //   Logical Maximum (127)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x33,        //   Usage (Rx)
0x09, 0x34,        //   Usage (Ry)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x02,        //   Report Count (2)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x36,        //   Report Count (54)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x05,        //   Report ID (5)
0x09, 0x22,        //   Usage (0x22)
0x95, 0x1F,        //   Report Count (31)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x02,        //   Report ID (2)
0x09, 0x24,        //   Usage (0x24)
0x95, 0x24,        //   Report Count (36)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x02, 0xFF,  //   Usage Page (Vendor Defined 0xFF02)
0x85, 0x12,        //   Report ID (18)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x0F,        //   Report Count (15)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x05, 0xFF,  //   Usage Page (Vendor Defined 0xFF05)
0x85, 0x15,        //   Report ID (21)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x2D,        //   Report Count (45)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x80, 0xFF,  //   Usage Page (Vendor Defined 0xFF80)
0x85, 0x80,        //   Report ID (128)
0x09, 0x20,        //   Usage (0x20)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x81,        //   Report ID (129)
0x09, 0x21,        //   Usage (0x21)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x85,        //   Report ID (133)
0x09, 0x25,        //   Usage (0x25)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x86,        //   Report ID (134)
0x09, 0x26,        //   Usage (0x26)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x8A,        //   Report ID (138)
0x09, 0x27,        //   Usage (0x27)
0x95, 0x16,        //   Report Count (22)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA0,        //   Report ID (160)
0x09, 0x40,        //   Usage (0x40)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA1,        //   Report ID (161)
0x09, 0x41,        //   Usage (0x41)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA2,        //   Report ID (162)
0x09, 0x42,        //   Usage (0x42)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA3,        //   Report ID (163)
0x09, 0x43,        //   Usage (0x43)
0x95, 0x30,        //   Report Count (48)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA4,        //   Report ID (164)
0x09, 0x44,        //   Usage (0x44)
0x95, 0x0D,        //   Report Count (13)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA5,        //   Report ID (165)
0x09, 0x45,        //   Usage (0x45)
0x95, 0x15,        //   Report Count (21)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA6,        //   Report ID (166)
0x09, 0x46,        //   Usage (0x46)
0x95, 0x15,        //   Report Count (21)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB0,        //   Report ID (176)
0x09, 0x54,        //   Usage (0x54)
0x95, 0x3F,        //   Report Count (63)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE0,        //   Report ID (224)
0x09, 0x56,        //   Usage (0x56)
0x95, 0x02,        //   Report Count (2)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE1,        //   Report ID (225)
0x09, 0x57,        //   Usage (0x57)
0x95, 0x30,        //   Report Count (48)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE2,        //   Report ID (226)
0x09, 0x57,        //   Usage (0x57)
0x95, 0x10,        //   Report Count (16)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE3,        //   Report ID (227)
0x09, 0x57,        //   Usage (0x57)
0x95, 0x04,        //   Report Count (4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE4,        //   Report ID (228)
0x09, 0x57,        //   Usage (0x57)
0x95, 0x01,        //   Report Count (1)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xE5,        //   Report ID (229)
0x09, 0x57,        //   Usage (0x57)
0x95, 0x06,        //   Report Count (6)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 295 bytes

Dongle (DFU Mode)[]

0xA1, 0x01,        // Collection (Application)
0x85, 0x02,        //   Report ID (2)
0x06, 0x01, 0xFF,  //   Usage Page (Vendor Defined 0xFF01)
0x09, 0x22,        //   Usage (0x22)
0x75, 0x08,        //   Report Size (8)
0x95, 0x3F,        //   Report Count (63)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0xF0,        //   Report ID (240)
0x09, 0x23,        //   Usage (0x23)
0x95, 0x3E,        //   Report Count (62)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 24 bytes

Data Structures[]

Common Structures[]

enum Direction : uint8_t {
    North = 0,
    NorthEast,
    East,
    SouthEast,
    South,
    SouthWest,
    West,
    NorthWest,
    None = 8
};

template<int N> struct BTCRC {
    uint8_t Buff[N-4];
    uint32_t CRC;
};

template<int N> struct BTAudio {
    uint16_t FrameNumber;
    uint8_t AudioTarget; // 0x02 speaker?, 0x24 headset?, 0x03 mic?
    uint8_t SBCData[N-3];
};

Input Reports[]

template<int N> struct BTGetStateDataAndAudio {
    BTGetStateData State;
    BTAudio<N-75> Audio;
};

struct TouchFingerData {
    uint8_t Index : 7;
    uint8_t NotTouching : 1;
    uint16_t FingerX : 12;
    uint16_t FingerY : 12;
};

struct TouchData {
    uint8_t Timestamp;
    TouchFingerData Finger[2];
};

struct BasicGetStateData {
/*0  */ uint8_t LeftStickX;
/*1  */ uint8_t LeftStickY;
/*2  */ uint8_t RightStickX;
/*3  */ uint8_t RightStickY;
/*4.0*/ Direction DPad : 4;
/*4.4*/ uint8_t ButtonSquare : 1;
/*4.5*/ uint8_t ButtonCross : 1;
/*4.6*/ uint8_t ButtonCircle : 1;
/*4.7*/ uint8_t ButtonTriangle : 1;
/*5.0*/ uint8_t ButtonL1 : 1;
/*5.1*/ uint8_t ButtonR1 : 1;
/*5.2*/ uint8_t ButtonL2 : 1;
/*5.3*/ uint8_t ButtonR2 : 1;
/*5.4*/ uint8_t ButtonShare : 1;
/*5.5*/ uint8_t ButtonOptions : 1;
/*5.6*/ uint8_t ButtonL3 : 1;
/*5.7*/ uint8_t ButtonR3 : 1;
/*6.0*/ uint8_t ButtonHome : 1;
/*6.1*/ uint8_t ButtonPad : 1;
/*6.2*/ uint8_t Counter : 6; // always 0 on USB, counts up with some skips on BT
/*7  */ uint8_t TriggerLeft;
/*8  */ uint8_t TriggerRight;
};

struct GetStateData : BasicGetStateData {
/* 9  */ uint16_t Timestamp; // in 5.33us units?
/*11  */ uint8_t Temperture;
/*12  */ int16_t AngularVelocityX;
/*14  */ int16_t AngularVelocityZ;
/*16  */ int16_t AngularVelocityY;
/*18  */ int16_t AccelerometerX;
/*20  */ int16_t AccelerometerY;
/*22  */ int16_t AccelerometerZ;
/*24  */ uint8_t[5] ExtData; // range can be set by EXT device
/*29  */ uint8_t PowerPercent : 4; // 0x00-0x0A or 0x01-0x0B if plugged int
/*29.4*/ uint8_t PluggedPowerCable : 1;
/*29.5*/ uint8_t PluggedHeadphones : 1;
/*29.6*/ uint8_t PluggedMic : 1;
/*29,7*/ uint8_t PluggedExt : 1;
/*30.0*/ uint8_t UnkExt1 : 1; // ExtCapableOfExtraData?
/*30.1*/ uint8_t UnkExt2 : 1; // ExtHasExtraData?
/*30.2*/ uint8_t NotConnected : 1; // Used by dongle to indicate no controller
/*30.3*/ uint8_t Unk1 : 5;
/*31  */ uint8_t Unk2; // unused?
/*32  */ uint8_t TouchCount;
};

struct USBGetStateData : GetStateData {
    TouchData TouchData[3];
    uint8_t Pad[3];
};

struct BTGetStateData : GetStateData {
    TouchData TouchData[4];
    uint8_t Pad[6];
};

HID Report 0x01 Input USB/Dongle[]

struct ReportIn01USB {
    uint8_t ReportID; // 0x01
    USBGetStateData State;
};

HID Report 0x01 Input BT[]

struct ReportIn01BT {
    uint8_t ReportID; // 0x01
    BasicGetStateData State;
};

HID Report 0x11 Input BT[]

struct ReportIn11 {
    union {
        BTCRC<78> CRC;
        struct {
            uint8_t ReportID; // 0x11
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateData State;
                BTAudio<75> Audio;
            };
        } Data;
    };
};

HID Report 0x12 Input BT[]

struct ReportIn12 {
    union {
        BTCRC<142> CRC;
        struct {
            uint8_t ReportID; // 0x12
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<139> State;
                BTAudio<139> Audio;
            };
        } Data;
    };
};

HID Report 0x13 Input BT[]

struct ReportIn13 {
    union {
        BTCRC<206> CRC;
        struct {
            uint8_t ReportID; // 0x13
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<203> State;
                BTAudio<203> Audio;
            };
        } Data;
    };
};

HID Report 0x14 Input BT[]

struct ReportIn14 {
    union {
        BTCRC<270> CRC;
        struct {
            uint8_t ReportID; // 0x14
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<267> State;
                BTAudio<267> Audio;
            };
        } Data;
    };
};

HID Report 0x15 Input BT[]

struct ReportIn15 {
    union {
        BTCRC<334> CRC;
        struct {
            uint8_t ReportID; // 0x15
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<331> State;
                BTAudio<331> Audio;
            };
        } Data;
    };
};

HID Report 0x16 Input BT[]

struct ReportIn16 {
    union {
        BTCRC<398> CRC;
        struct {
            uint8_t ReportID; // 0x16
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<395> State;
                BTAudio<395> Audio;
            };
        } Data;
    };
};

HID Report 0x17 Input BT[]

struct ReportIn17 {
    union {
        BTCRC<462> CRC;
        struct {
            uint8_t ReportID; // 0x17
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<459> State;
                BTAudio<459> Audio;
            };
        } Data;
    };
};

HID Report 0x18 Input BT[]

struct ReportIn18 {
    union {
        BTCRC<526> CRC;
        struct {
            uint8_t ReportID; // 0x18
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<523> State;
                BTAudio<523> Audio;
            };
        } Data;
    };
};

HID Report 0x19 Input BT[]

struct ReportIn19 {
    union {
        BTCRC<547> CRC;
        struct {
            uint8_t ReportID; // 0x19
            uint8_t Unk1 : 6;
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t Unk2 : 7;
            uint8_t EnableAudio : 1;
            union {
                BTGetStateDataAndAudio<544> State;
                BTAudio<544> Audio;
            };
        } Data;
    };
};

Output Reports[]

template<int N> struct BTSetStateDataAndAudio {
    BTSetStateData State;
    BTAudio<N-75> Audio;
};

struct USBSetStateData {
    uint8_t EnableRumbleUpdate : 1;
    uint8_t EnableLedUpdate : 1;
    uint8_t EnableLedBlink : 1;
    uint8_t EnableExtWrite : 1;
    uint8_t EnableVolumeLeftUpdate : 1;
    uint8_t EnableVolumeRightUpdate : 1;
    uint8_t EnableVolumeMicUpdate : 1;
    uint8_t EnableVolumeSpeakerUpdate : 1;
    uint8_t UNK_RESET1: 1; // unknown reset, both set high by Remote Play
    uint8_t UNK_RESET2: 1; // unknown reset, both set high by Remote Play
    uint8_t UNK1: 1;
    uint8_t UNK2: 1;
    uint8_t UNK3: 1;
    uint8_t UNKPad: 3;
    uint8_t Empty1;
    uint8_t RumbleRight; // weak
    uint8_t RumbleLeft; // strong
    uint8_t LedRed;
    uint8_t LedGreen;
    uint8_t LedBlue;
    uint8_t LedFlashOnPeriod;
    uint8_t LedFlashOffPeriod;
    uint8_t ExtDataSend[8]; // sent to I2C EXT port, stored in 8x8 byte block
    uint8_t VolumeLeft; // 0x00 - 0x4F inclusive
    uint8_t VolumeRight; // 0x00 - 0x4F inclusive
    uint8_t VolumeMic; // 0x00, 0x01 - 0x40 inclusive (0x00 is special behavior)
    uint8_t VolumeSpeaker; // 0x00 - 0x4F
    uint8_t UNK_AUDIO1 : 7; // clamped to 1-64 inclusive, appears to be set to 5 for audio
    uint8_t UNK_AUDIO2: 1; // unknown, appears to be set to 1 for audio
    uint8_t Pad[8];
};

struct BTSetStateData {
    uint8_t EnableRumbleUpdate : 1;
    uint8_t EnableLedUpdate : 1;
    uint8_t EnableLedBlink : 1;
    uint8_t EnableExtWrite : 1;
    uint8_t EnableVolumeLeftUpdate : 1;
    uint8_t EnableVolumeRightUpdate : 1;
    uint8_t EnableVolumeMicUpdate : 1;
    uint8_t EnableVolumeSpeakerUpdate : 1;
    uint8_t UNK_RESET1: 1; // unknown reset, both set high by Remote Play
    uint8_t UNK_RESET2: 1; // unknown reset, both set high by Remote Play
    uint8_t UNK1: 1;
    uint8_t UNK2: 1;
    uint8_t UNK3: 1;
    uint8_t UNKPad: 3;
    uint8_t Empty1;
    uint8_t RumbleRight; // weak
    uint8_t RumbleLeft; // strong
    uint8_t LedRed;
    uint8_t LedGreen
    uint8_t LedBlue;
    uint8_t LedFlashOnPeriod;
    uint8_t LedFlashOffPeriod;
    uint8_t ExtDataSend[8]; // sent to I2C EXT port, stored in 8x8 byte block
    uint8_t VolumeLeft; // 0x00 - 0x4F inclusive
    uint8_t VolumeRight; // 0x00 - 0x4F inclusive
    uint8_t VolumeMic; // 0x00, 0x01 - 0x40 inclusive (0x00 is special behavior)
    uint8_t VolumeSpeaker; // 0x00 - 0x4F
    uint8_t UNK_AUDIO1 : 7; // clamped to 1-64 inclusive, appears to be set to 5 for audio
    uint8_t UNK_AUDIO2: 1; // unknown, appears to be set to 1 for audio
    uint8_t Pad[52];
};

HID Report 0x05 Output USB/Dongle[]

struct ReportIn05 {
    uint8_t ReportID; // 0x05
    USBSetStateData State;
};

HID Report 0x11 Output BT[]

struct ReportOut11 {
    union {
        BTCRC<78> CRC;
        struct {
            uint8_t ReportID; // 0x11
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateData State;
                BTAudio<75> Audio;
            };
        } Data;
    };
};

HID Report 0x12 Output BT[]

struct ReportOut12 {
    union {
        BTCRC<142> CRC;
        struct {
            uint8_t ReportID; // 0x12
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<139> State;
                BTAudio<139> Audio;
            };
        } Data;
    };
};

HID Report 0x13 Output BT[]

struct ReportOut13 {
    union {
        BTCRC<206> CRC;
        struct {
            uint8_t ReportID; // 0x13
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<203> State;
                BTAudio<203> Audio;
            };
        } Data;
    };
};

HID Report 0x14 Output BT[]

struct ReportOut14 {
    union {
        BTCRC<270> CRC;
        struct {
            uint8_t ReportID; // 0x14
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<267> State;
                BTAudio<267> Audio;
            };
        } Data;
    };
};

HID Report 0x15 Output BT[]

struct ReportOut15 {
    union {
        BTCRC<334> CRC;
        struct {
            uint8_t ReportID; // 0x15
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<331> State;
                BTAudio<331> Audio;
            };
        } Data;
    };
};

HID Report 0x16 Output BT[]

struct ReportOut16 {
    union {
        BTCRC<398> CRC;
        struct {
            uint8_t ReportID; // 0x16
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<395> State;
                BTAudio<395> Audio;
            };
        } Data;
    };
};

HID Report 0x17 Output BT[]

struct ReportOut17 {
    union {
        BTCRC<462> CRC;
        struct {
            uint8_t ReportID; // 0x17
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<459> State;
                BTAudio<459> Audio;
            };
        } Data;
    };
};

HID Report 0x18 Output BT[]

struct ReportOut18 {
    union {
        BTCRC<526> CRC;
        struct {
            uint8_t ReportID; // 0x18
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<523> State;
                BTAudio<523> Audio;
            };
        } Data;
    };
};

HID Report 0x19 Output BT[]

struct ReportOut19 {
    union {
        BTCRC<547> CRC;
        struct {
            uint8_t ReportID; // 0x19
            uint8_t PollingRate: 6; // note 0 appears to be clamped to 1
            uint8_t EnableCRC : 1;
            uint8_t EnableHID : 1;
            uint8_t EnableMic : 3; // somehow enables mic, appears to be 3 bit flags
            uint8_t UnkA4 : 1;
            uint8_t UnkB1 : 1;
            uint8_t UnkB2 : 1; // seems to always be 1
            uint8_t UnkB3 : 1;
            uint8_t EnableAudio : 1;
            union {
                BTSetStateDataAndAudio<544> State;
                BTAudio<544> Audio;
            };
        } Data;
    };
};

Feature Reports[]

Calibration[]

Reading calibration is required to switch input reports from the truncated 0x01 report to the expanded 0x11-0x19 reports.

Linux hid-sony.c

/* Set gyroscope calibration and normalization parameters.
 * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s.
 */
speed_2x = (gyro_speed_plus + gyro_speed_minus);
sc->ds4_calib_data[0].abs_code = ABS_RX;
sc->ds4_calib_data[0].bias = gyro_pitch_bias;
sc->ds4_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
sc->ds4_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus;

sc->ds4_calib_data[1].abs_code = ABS_RY;
sc->ds4_calib_data[1].bias = gyro_yaw_bias;
sc->ds4_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
sc->ds4_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus;

sc->ds4_calib_data[2].abs_code = ABS_RZ;
sc->ds4_calib_data[2].bias = gyro_roll_bias;
sc->ds4_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
sc->ds4_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus;

/* Set accelerometer calibration and normalization parameters.
 * Data values will be normalized to 1/DS4_ACC_RES_PER_G G.
 */
range_2g = acc_x_plus - acc_x_minus;
sc->ds4_calib_data[3].abs_code = ABS_X;
sc->ds4_calib_data[3].bias = acc_x_plus - range_2g / 2;
sc->ds4_calib_data[3].sens_numer = 2*DS4_ACC_RES_PER_G;
sc->ds4_calib_data[3].sens_denom = range_2g;

range_2g = acc_y_plus - acc_y_minus;
sc->ds4_calib_data[4].abs_code = ABS_Y;
sc->ds4_calib_data[4].bias = acc_y_plus - range_2g / 2;
sc->ds4_calib_data[4].sens_numer = 2*DS4_ACC_RES_PER_G;
sc->ds4_calib_data[4].sens_denom = range_2g;

range_2g = acc_z_plus - acc_z_minus;
sc->ds4_calib_data[5].abs_code = ABS_Z;
sc->ds4_calib_data[5].bias = acc_z_plus - range_2g / 2;
sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G;
sc->ds4_calib_data[5].sens_denom = range_2g;

In Remote Play, version 17 controllers lock GyroSpeedPlus and GyroSpeedMinus to 540

In Remote Play, a version of 18 or lower sets MotionDataTimestampUnits to 7.0999999

In Remote Play, a version over 18 sets MotionDataTimestampUnits to 5.3299999

What this value is used for is unclear.

Version comes from the device's revision number and is bashed from hex to decimal. (0x1F93 -> 1993)

USB 0x02[]
struct ReportFeatureInCalibrateUSB {
    uint8_t ReportID; // 0x02
    int16_t GyroPitchBias;
    int16_t GyroYawBias;
    int16_t GyroRollBias;
    int16_t GyroPitchPlus;
    int16_t GyroPitchMinus;
    int16_t GyroYawPlus;
    int16_t GyroYawMinus;
    int16_t GyroRollPlus;
    int16_t GyroRollMinus;
    int16_t GyroSpeedPlus;
    int16_t GyroSpeedMinus;
    int16_t AccelXPlus;
    int16_t AccelXMinus;
    int16_t AccelYPlus;
    int16_t AccelYMinus;
    int16_t AccelZPlus;
    int16_t AccelZMinus;
    int16_t Unknown;
};
Bluetooth 0x05[]
struct ReportFeatureInCalibrateBT {
    union {
        BTCRC<41> CRC;
        struct {
            uint8_t ReportID; // 0x05
            int16_t GyroPitchBias;
            int16_t GyroYawBias;
            int16_t GyroRollBias;
            int16_t GyroPitchPlus;
            int16_t GyroYawPlus;
            int16_t GyroRollPlus;
            int16_t GyroPitchMinus;
            int16_t GyroYawMinus;
            int16_t GyroRollMinus;
            int16_t GyroSpeedPlus;
            int16_t GyroSpeedMinus;
            int16_t AccelXPlus;
            int16_t AccelXMinus;
            int16_t AccelYPlus;
            int16_t AccelYMinus;
            int16_t AccelZPlus;
            int16_t AccelZMinus;
            int16_t Unknown;
        } Data;
    }
};
Dongle 0x02[]
struct ReportFeatureInCalibrateDongle {
    uint8_t ReportID; // 0x02
    int16_t GyroPitchBias;
    int16_t GyroYawBias;
    int16_t GyroRollBias;
    int16_t GyroPitchPlus;
    int16_t GyroYawPlus;
    int16_t GyroRollPlus;
    int16_t GyroPitchMinus;
    int16_t GyroYawMinus;
    int16_t GyroRollMinus;
    int16_t GyroSpeedPlus;
    int16_t GyroSpeedMinus;
    int16_t AccelXPlus;
    int16_t AccelXMinus;
    int16_t AccelYPlus;
    int16_t AccelYMinus;
    int16_t AccelZPlus;
    int16_t AccelZMinus;
    int16_t Unknown;
};

MAC[]

Need to confirm these on BT

Get All MAC USB/Dongle 0x12[]
struct ReportFeatureInMacAll {
    uint8_t ReportID; // 0x12 (0x09 for BT)
    uint8_t[6] ClientMac; // Right to Left
    uint8_t Hard08;
    uint8_t Hard25;
    uint8_t Hard00;
    uint8_t[6] HostMac; // Right to Left
};
Get All MAC BT 0x09[]
struct ReportFeatureInMacAllBT {
    union {
        BTCRC<53> CRC;
        ReportFeatureInControllerVersion Data; // with ReportID 0x09
    }
};
Get Client MAC USB/Dongle 0x81[]
struct ReportFeatureInMacClient {
    uint8_t ReportID; // 0x81
    uint8_t[6] ClientMac; // Right to Left
};
Get Host Dongle 0xE5[]
struct ReportFeatureInMacHost {
    uint8_t ReportID; // 0xE5
    uint8_t[6] HostMac; // Right to Left
};
Set Host MAC and Linkkey USB 0x13[]
struct ReportFeatureOutMacHost {
    uint8_t ReportID; // 0x13
    uint8_t[6] ClientMac; // Right to Left
    uint8_t[16] Linkkey;
};
Set Client MAC USB 0x80[]
struct ReportFeatureOutMacClient {
    uint8_t ReportID; // 0x80
    uint8_t[6] ClientMac; // Right to Left
};

Date and Version[]

Controller Date/Version Dongle/USB 0xA3[]
struct ReportFeatureInControllerVersion {
    uint8_t ReportID; // 0xA3 (0x06 for BT)
    char[16] Date; // string
    char[16] Time; // string
    uint16_t HardwareVersionMajor; // %04x.%04x AKA DevRel
    uint16_t HardwareVersionMinor; // Must be >= 0x3100u for Remote Play
                                   // might be bitwise anded with 0xFFC0
    uint32_t SoftwareVersionMajor; // firmware ignores this for debug terminal output a hardcode of 3
    uint16_t SoftwareVersionMinor; // written %08x.%04x, 3, sw_ver_minor
    uint16_t SoftwareSeries; // %04x
    uint32_t CodeSize;
};
Controller Date/Version Bluetooth 0x06[]
struct ReportFeatureInControllerVersionBT {
    union {
        BTCRC<53> CRC;
        ReportFeatureInControllerVersion Data; // with ReportID 0x06
    }
};
Dongle Date/Version Dongle 0xE1[]
struct ReportFeatureInDongleVersion {
    uint8_t ReportID; // 0xE1
    char[16] Date; // string
    char[16] Time; // string
    uint16_t HardwareVersionMajor;
    uint16_t HardwareVersionMinor;
    uint32_t SoftwareVersionMajor;
    uint16_t SoftwareVersionMinor;
    uint16_t SoftwareSeries;
    uint32_t CodeSize;
};

Other[]

Controller VID/PID Dongle 0xE3[]

Access controller's VID/PID to determine what controller is connected to dongle. Note: Dongle's revision number is used.

struct ReportFeatureInControllerVidPidDongle {
    uint8_t ReportID; // 0xE3
    uint16_t VID; // Ex: 0x054C
    uint16_t PID; // Ex: 0x09CC
};
Get Audio Chip Ident 0xAF[]

Confirm if this is USB only

struct ReportFeatureInMacClient {
    uint8_t ReportID; // 0xAF
    uint16_t Ident; // 0x1801 for WM1801
};
Get AC_ON_STATE 0xAE[]

Confirm if this is USB only, this is of unknown purpose

struct ReportFeatureInMacClient {
    uint8_t ReportID; // 0xAE
    uint8_t Value; // 0x00 - L, 0x01 - H
};
Dongle Set Audio Output Dongle 0xE0[]
// Note that the headset output does not downmix, so mono only comes from the left
enum AudioOutput : uint8_t {
    HeadsetStereo = 0,  // Left and Right to headphones
    HeadsetMono,        // Left to headphones
    HeadsetMonoSpeaker, // Left to headphones, Right to speaker
    Speaker,            // Right to speaker
    Disabled = 4
};
struct ReportFeatureInDongleSetAudio {
    uint8_t ReportID; // 0xE0
    uint8_t Unknown; // 0x00
    AudioOutput Output;
};
Advertisement