dualsense-ts
Version:
The natural interface for your DualSense and DualSense Access controllers, with Typescript
109 lines • 3.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultFirmwareInfo = void 0;
exports.formatFirmwareVersion = formatFirmwareVersion;
exports.readFirmwareInfo = readFirmwareInfo;
/** A zeroed firmware version */
const UnknownVersion = { major: 0, minor: 0, patch: 0 };
/** Default FirmwareInfo used when Feature Report 0x20 could not be read */
exports.DefaultFirmwareInfo = {
buildDate: "unknown",
buildTime: "unknown",
firmwareType: 0,
softwareSeries: 0,
hardwareInfo: 0,
mainFirmwareVersion: UnknownVersion,
mainFirmwareVersionRaw: 0,
deviceInfo: "unknown",
updateVersion: "00.00",
updateImageInfo: 0,
sblFirmwareVersion: UnknownVersion,
dspFirmwareVersion: "0000_0000",
spiderDspFirmwareVersion: UnknownVersion,
};
/** Format a FirmwareVersion as "major.minor.patch" */
function formatFirmwareVersion(v) {
return `${v.major}.${v.minor}.${v.patch}`;
}
/** Feature report ID for firmware information */
const REPORT_ID = 0x20;
/** Expected report length (report ID + 63 bytes of data) */
const REPORT_LENGTH = 64;
/** Parse a uint32 version into major.minor.patch */
function parseVersion(ver) {
return {
major: (ver >>> 24) & 0xff,
minor: (ver >>> 16) & 0xff,
patch: ver & 0xffff,
};
}
/** Format a uint16 as HH.LL hex */
function formatUpdateVersion(ver) {
const hi = ((ver >>> 8) & 0xff).toString(16).padStart(2, "0");
const lo = (ver & 0xff).toString(16).padStart(2, "0");
return `${hi}.${lo}`;
}
/** Format a uint32 as HHHH_LLLL hex */
function formatDspVersion(ver) {
const hi = ((ver >>> 16) & 0xffff).toString(16).padStart(4, "0");
const lo = (ver & 0xffff).toString(16).padStart(4, "0");
return `${hi}_${lo}`;
}
/** Read a null-terminated ASCII string from a buffer */
function readString(data, offset, length) {
let str = "";
for (let i = 0; i < length; i++) {
const byte = data[offset + i];
if (byte === 0)
break;
str += String.fromCharCode(byte);
}
return str;
}
/** Read a little-endian uint16 from a buffer */
function readUint16LE(data, offset) {
return data[offset] | (data[offset + 1] << 8);
}
/** Read a little-endian uint32 from a buffer */
function readUint32LE(data, offset) {
return (data[offset] |
(data[offset + 1] << 8) |
(data[offset + 2] << 16) |
((data[offset + 3] << 24) >>> 0));
}
/** Convert bytes to a hex string */
function toHex(data, offset, length) {
return Array.from(data.slice(offset, offset + length))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
/**
* Read and parse Feature Report 0x20 from a connected controller.
* Returns undefined if the report cannot be read.
*/
async function readFirmwareInfo(provider) {
try {
const data = await provider.readFeatureReport(REPORT_ID, REPORT_LENGTH);
// Offsets are from byte 1 (after the report ID byte)
const base = 1;
return {
buildDate: readString(data, base, 11),
buildTime: readString(data, base + 11, 8),
firmwareType: readUint16LE(data, base + 19),
softwareSeries: readUint16LE(data, base + 21),
hardwareInfo: readUint32LE(data, base + 23),
mainFirmwareVersion: parseVersion(readUint32LE(data, base + 27)),
mainFirmwareVersionRaw: readUint32LE(data, base + 27),
deviceInfo: toHex(data, base + 31, 12),
updateVersion: formatUpdateVersion(readUint16LE(data, base + 43)),
updateImageInfo: data[base + 45],
sblFirmwareVersion: parseVersion(readUint32LE(data, base + 47)),
dspFirmwareVersion: formatDspVersion(readUint32LE(data, base + 51)),
spiderDspFirmwareVersion: parseVersion(readUint32LE(data, base + 55)),
};
}
catch {
return undefined;
}
}
//# sourceMappingURL=firmware_info.js.map