Game Controller Collective Wiki
Advertisement

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