Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: compare checksum of UHK80 and dongle devices #2510

Merged
merged 1 commit into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions packages/uhk-agent/src/services/device.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
UHK_80_DEVICE_LEFT,
UHK_DEVICE_IDS,
UHK_DONGLE,
UHK_MODULE_IDS,
UHK_MODULES,
UpdateFirmwareData,
UploadFileData,
Expand Down Expand Up @@ -342,9 +343,9 @@ export class DeviceService {
if (isFirmwareChecksumSupported) {
for (const moduleInfo of hardwareModules.moduleInfos) {
const moduleId = moduleInfo.module.id;
const md5 = readUhkResponseAs0EndString(await this.operations.getRightModuleProperty(DevicePropertyIds.FirmwareChecksum, [moduleId]));
const builtFirmwareChecksum = readUhkResponseAs0EndString(await this.operations.getRightModuleProperty(DevicePropertyIds.BuiltFirmwareChecksumByModuleId, [moduleId]));
hardwareModules.rightModuleInfo.modules[moduleId] = {
md5
builtFirmwareChecksum
};
}
}
Expand Down Expand Up @@ -420,16 +421,16 @@ export class DeviceService {
try {
dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid);
let dongleOperations = new UhkOperations(this.logService, dongleUhkDevice);
let versionInfo = await dongleOperations.getDeviceVersionInfo();
this.logService.misc('[DeviceService] Current Dongle firmware checksum:',
versionInfo.firmwareChecksum);
let versionInfo = await dongleOperations.getDeviceVersionInfo(UHK_MODULE_IDS.DONGLE);
this.logService.misc('[DeviceService] Current Dongle built firmware checksum:',
versionInfo.builtFirmwareChecksum);

const deviceConfig = findDeviceConfigInFirmwareJson(UHK_DONGLE, packageJson);

this.logService.misc('[DeviceService] New Dongle firmware checksum:',
deviceConfig.md5);

if (data.forceUpgrade || versionInfo.firmwareChecksum !== deviceConfig.md5) {
if (data.forceUpgrade || versionInfo.builtFirmwareChecksum !== deviceConfig.md5) {
event.sender.send(IpcEvents.device.moduleFirmwareUpgrading, UHK_DONGLE.name);
await dongleOperations.updateDeviceFirmware(dongleFirmwarePath, UHK_DONGLE);
this.logService.misc('[DeviceService] Waiting for keyboard');
Expand All @@ -440,7 +441,7 @@ export class DeviceService {
if (dongleHid) {
dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid);
dongleOperations = new UhkOperations(this.logService, dongleUhkDevice);
versionInfo = await dongleOperations.getDeviceVersionInfo();
versionInfo = await dongleOperations.getDeviceVersionInfo(UHK_MODULE_IDS.DONGLE);
event.sender.send(IpcEvents.device.dongleVersionInfoLoaded, versionInfo);
}
}
Expand All @@ -462,14 +463,14 @@ export class DeviceService {
JSON.stringify(uhkDeviceProduct, usbDeviceJsonFormatter));
const deviceFirmwarePath = getDeviceFirmwarePath(uhkDeviceProduct, packageJson);

this.logService.misc('[DeviceService] Current Device right firmware checksum:',
hardwareModules.rightModuleInfo.firmwareChecksum);
this.logService.misc('[DeviceService] Current Device right built firmware checksum:',
hardwareModules.rightModuleInfo.builtFirmwareChecksum);

const deviceConfig = findDeviceConfigInFirmwareJson(uhkDeviceProduct, packageJson);
this.logService.misc('[DeviceService] New Device right firmware checksum:',
deviceConfig.md5);

if (data.forceUpgrade || hardwareModules.rightModuleInfo.firmwareChecksum !== deviceConfig.md5) {
if (data.forceUpgrade || hardwareModules.rightModuleInfo.builtFirmwareChecksum !== deviceConfig.md5) {
event.sender.send(IpcEvents.device.moduleFirmwareUpgrading, RIGHT_HALF_FIRMWARE_UPGRADE_MODULE_NAME);
await this.operations.updateDeviceFirmware(deviceFirmwarePath, uhkDeviceProduct);
this.logService.misc('[DeviceService] Waiting for keyboard');
Expand Down Expand Up @@ -497,15 +498,18 @@ export class DeviceService {
const leftModuleFirmwareInfo = hardwareModules.rightModuleInfo.modules[leftModuleInfo.module.id];

this.logService.misc('[DeviceService] Left module firmware version: ', leftModuleInfo.info.firmwareVersion);
this.logService.misc('[DeviceService] Current left module firmware checksum: ', leftModuleInfo.info.firmwareChecksum);
this.logService.misc('[DeviceService] Left module remote firmware checksum: ', leftModuleInfo.info.remoteFirmwareChecksum);
if (leftModuleFirmwareInfo) {
this.logService.misc('[DeviceService] New left module firmware checksum: ', leftModuleFirmwareInfo.md5);
this.logService.misc('[DeviceService] Left module built firmware checksum: ', leftModuleFirmwareInfo.builtFirmwareChecksum);
}

const isLeftModuleFirmwareSame = isSameFirmware(
leftModuleInfo.info,
{
firmwareChecksum: leftModuleFirmwareInfo?.md5,
firmwareChecksum: leftModuleInfo.info.remoteFirmwareChecksum,
firmwareVersion: leftModuleInfo.info.firmwareVersion
},
{
firmwareChecksum: leftModuleFirmwareInfo?.builtFirmwareChecksum,
firmwareVersion: packageJson.firmwareVersion
}
);
Expand Down Expand Up @@ -549,17 +553,20 @@ export class DeviceService {
// Left half upgrade mandatory, it is running before the other modules upgrade.
} else if (moduleInfo.module.firmwareUpgradeSupported) {
this.logService.misc(`[DeviceService] "${moduleInfo.module.name}" firmware version:`, moduleInfo.info.firmwareVersion);
this.logService.misc(`[DeviceService] "${moduleInfo.module.name}" current firmware checksum:`, moduleInfo.info.firmwareChecksum);
this.logService.misc(`[DeviceService] "${moduleInfo.module.name}" current remote firmware checksum:`, moduleInfo.info.remoteFirmwareChecksum);

const moduleFirmwareInfo = hardwareModules.rightModuleInfo.modules[moduleInfo.module.id];
if (moduleFirmwareInfo) {
this.logService.misc(`[DeviceService] "${moduleInfo.module.name}" new firmware checksum:`, moduleFirmwareInfo.md5);
this.logService.misc(`[DeviceService] "${moduleInfo.module.name}" new built firmware checksum:`, moduleFirmwareInfo.builtFirmwareChecksum);
}

const isModuleFirmwareSame = isSameFirmware(
moduleInfo.info,
{
firmwareChecksum: moduleFirmwareInfo?.md5,
firmwareChecksum: moduleInfo.info.remoteFirmwareChecksum,
firmwareVersion: moduleInfo.info.firmwareVersion
},
{
firmwareChecksum: moduleFirmwareInfo?.builtFirmwareChecksum,
firmwareVersion: packageJson.firmwareVersion
}
);
Expand Down Expand Up @@ -942,8 +949,7 @@ export class DeviceService {
if (isDeviceSupportWirelessUSBCommands
&& !state.dongle.multiDevice
&& !state.dongle.bootloaderActive
&& state.dongle.serialNumber
&& state.dongle.serialNumber !== this.savedState?.dongle?.serialNumber) {
&& state.dongle.serialNumber) {

const dongle = await getCurrentUhkDongleHID();
let dongleUhkDevice: UhkHidDevice;
Expand Down
2 changes: 1 addition & 1 deletion packages/uhk-common/src/models/device-module-record.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface DeviceModule {
md5: string;
builtFirmwareChecksum: string;
}

export interface DeviceModuleRecord extends Record<number, DeviceModule>{
Expand Down
5 changes: 3 additions & 2 deletions packages/uhk-common/src/models/device-version-information.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FirmwareRepoInfo } from './firmware-repo-info.js';
import { FirmwareVersionInfo } from './firmware-version-info.js';
import { FirmwareVersion } from './firmware-version.js';
import { ProtocolVersions } from './protocol-versions.js';

export interface DeviceVersionInformation extends FirmwareRepoInfo, FirmwareVersionInfo, ProtocolVersions {
export interface DeviceVersionInformation extends FirmwareRepoInfo, FirmwareVersion, ProtocolVersions {
builtFirmwareChecksum?: string;
}
2 changes: 1 addition & 1 deletion packages/uhk-common/src/models/firmware-version-info.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FirmwareVersion } from './firmware-version.js';

export interface FirmwareVersionInfo extends FirmwareVersion {
firmwareChecksum?: string;
firmwareChecksum: string;
}
5 changes: 3 additions & 2 deletions packages/uhk-common/src/models/module-version-info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FirmwareRepoInfo } from './firmware-repo-info.js';
import { FirmwareVersionInfo } from './firmware-version-info.js';
import { FirmwareVersion } from './firmware-version.js';

export interface ModuleVersionInfo extends FirmwareRepoInfo, FirmwareVersionInfo {
export interface ModuleVersionInfo extends FirmwareRepoInfo, FirmwareVersion {
moduleProtocolVersion?: string;
remoteFirmwareChecksum?: string;
}
2 changes: 2 additions & 0 deletions packages/uhk-common/src/models/uhk-module-ids.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
export const UHK_MODULE_IDS = Object.freeze({
RIGHT_HALF: 0,
LEFT_HALF: 1,
LEFT_KEY_CLUSTER: 2,
RIGHT_TRACKBALL: 3,
RIGHT_TRACKPOINT: 4,
RIGHT_TOUCHPAD: 5,
DONGLE: 254
});

export type UHK_MODULE_IDS_KEY_TYPE = keyof typeof UHK_MODULE_IDS;
Expand Down
4 changes: 2 additions & 2 deletions packages/uhk-usb/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export enum DevicePropertyIds {
Uptime = 5,
GitTag = 6,
GitRepo = 7,
FirmwareChecksum = 8,
BuiltFirmwareChecksumByModuleId = 8,
BleAddress = 9,
PairedRightPeerBleAddress = 10,
PairingStatus = 11,
Expand All @@ -79,7 +79,7 @@ export enum ModulePropertyId {
protocolVersions = 0,
GitTag = 1,
GitRepo = 2,
FirmwareChecksum = 3
RemoteFirmwareChecksumBySlotId = 3
}

export enum PairIds {
Expand Down
2 changes: 1 addition & 1 deletion packages/uhk-usb/src/uhk-hid-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ export class UhkHidDevice {
smartMacrosVersion: `${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}`
};

this.logService.misc('[UhkHidDevice] protocol versions: ' + JSON.stringify(this._protocolVersions));
this.logService.misc(`[UhkHidDevice] productId: ${this._deviceInfo.productId} protocol versions: ${JSON.stringify(this._protocolVersions)}`);

return this._protocolVersions;
}
Expand Down
17 changes: 12 additions & 5 deletions packages/uhk-usb/src/uhk-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ import {
UhkBuffer,
UhkDeviceProduct,
UhkModule,
UHK_MODULE_IDS_TYPE,
UHK_MODULE_IDS,
UNKNOWN_DEVICE,
} from 'uhk-common';
import { promisify } from 'util';
import semver from 'semver';
import {
ConfigBufferId,
DevicePropertyIds,
Expand Down Expand Up @@ -448,11 +451,11 @@ export class UhkOperations {
return this.getModuleProperty(arg).then(readUhkResponseAs0EndString);
}

public async getModuleFirmwareChecksum(module: ModuleSlotToId): Promise<string> {
public async getModuleRemoteFirmwareChecksum(module: ModuleSlotToId): Promise<string> {
const moduleSlotName = getSlotIdName(module);
this.logService.misc(`[DeviceOperation] Read "${moduleSlotName}" firmware checksum`);

return this.getModulePropertyAsString({ module, property: ModulePropertyId.FirmwareChecksum });
return this.getModulePropertyAsString({ module, property: ModulePropertyId.RemoteFirmwareChecksumBySlotId });
}

public async getModuleFirmwareRepoInfo(module: ModuleSlotToId): Promise<FirmwareRepoInfo> {
Expand Down Expand Up @@ -490,7 +493,7 @@ export class UhkOperations {
if (includeFirmwareChecksum) {
moduleVersionInfo = {
...moduleVersionInfo,
firmwareChecksum: await this.getModuleFirmwareChecksum(module),
remoteFirmwareChecksum: await this.getModuleRemoteFirmwareChecksum(module),
};
}

Expand Down Expand Up @@ -522,7 +525,7 @@ export class UhkOperations {
};
}

public async getDeviceVersionInfo(): Promise<DeviceVersionInformation> {
public async getDeviceVersionInfo(moduleId: UHK_MODULE_IDS_TYPE = UHK_MODULE_IDS.RIGHT_HALF): Promise<DeviceVersionInformation> {
// TODO: read device name from UHK Device
this.logService.usbOps('[DeviceOperation] USB[T]: Device information');

Expand All @@ -539,9 +542,13 @@ export class UhkOperations {
};

if (isDeviceProtocolSupportFirmwareChecksum(deviceVersionInformation.deviceProtocolVersion)) {
if (semver.lt(deviceVersionInformation.deviceProtocolVersion, '4.14.1')) {
moduleId = UHK_MODULE_IDS.RIGHT_HALF;
}

deviceVersionInformation = {
...deviceVersionInformation,
firmwareChecksum: readUhkResponseAs0EndString(await this.getRightModuleProperty(DevicePropertyIds.FirmwareChecksum, [0])),
builtFirmwareChecksum: readUhkResponseAs0EndString(await this.getRightModuleProperty(DevicePropertyIds.BuiltFirmwareChecksumByModuleId, [moduleId])),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ function mapModules(firmwareJson: FirmwareJson, hardwareModules: HardwareModules
const firmwareModuleInfo = hardwareModules.rightModuleInfo.modules[moduleInfo.module.id];
const stateModule = findStateModule(moduleInfo.module.name);

if (!firmwareModuleInfo || moduleInfo.info.firmwareVersion === hardwareModules.rightModuleInfo?.firmwareVersion || firmwareModuleInfo.md5 !== moduleInfo.info.firmwareChecksum) {
if (!firmwareModuleInfo || moduleInfo.info.firmwareVersion === hardwareModules.rightModuleInfo?.firmwareVersion || firmwareModuleInfo.builtFirmwareChecksum !== moduleInfo.info.remoteFirmwareChecksum) {
modules.push({
moduleName: moduleInfo.module.name,
firmwareUpgradeSupported: moduleInfo.module.firmwareUpgradeSupported,
Expand Down