From ac7d66e338453989629795a51c322466a5fc88b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Monda?= Date: Thu, 26 Jul 2018 05:34:48 +0200 Subject: [PATCH] Add keyboard shortcut for enabling the USB stack test mode of the firmware. Resolves #735. --- packages/uhk-agent/src/services/device.service.ts | 13 +++++++++++++ packages/uhk-common/src/util/ipcEvents.ts | 1 + packages/uhk-usb/src/constants.ts | 14 +++++++++++++- packages/uhk-usb/src/uhk-hid-device.ts | 8 +++++++- packages/uhk-web/src/app/app.component.ts | 15 +++++++++++++++ .../src/app/services/device-renderer.service.ts | 4 ++++ packages/uhk-web/src/app/store/actions/device.ts | 8 +++++++- packages/uhk-web/src/app/store/effects/device.ts | 5 +++++ 8 files changed, 65 insertions(+), 3 deletions(-) diff --git a/packages/uhk-agent/src/services/device.service.ts b/packages/uhk-agent/src/services/device.service.ts index 87ad3935..2d4e4c60 100644 --- a/packages/uhk-agent/src/services/device.service.ts +++ b/packages/uhk-agent/src/services/device.service.ts @@ -87,6 +87,15 @@ export class DeviceService { }); }); + ipcMain.on(IpcEvents.device.enableUsbStackTest, (...args: any[]) => { + this.queueManager.add({ + method: this.enableUsbStackTest, + bind: this, + params: args, + asynchronous: true + }); + }); + logService.debug('[DeviceService] init success'); } @@ -224,6 +233,10 @@ export class DeviceService { event.sender.send(IpcEvents.device.updateFirmwareReply, response); } + public async enableUsbStackTest(event: Electron.Event) { + await this.device.enableUsbStackTest(); + } + /** * HID API not support device attached and detached event. * This method check the keyboard is attached to the computer or not. diff --git a/packages/uhk-common/src/util/ipcEvents.ts b/packages/uhk-common/src/util/ipcEvents.ts index e62cc92d..3d9ab45c 100644 --- a/packages/uhk-common/src/util/ipcEvents.ts +++ b/packages/uhk-common/src/util/ipcEvents.ts @@ -30,6 +30,7 @@ export class Device { public static readonly updateFirmwareReply = 'device-update-firmware-reply'; public static readonly startConnectionPoller = 'device-start-connection-poller'; public static readonly recoveryDevice = 'device-recovery'; + public static readonly enableUsbStackTest = 'enable-usb-stack-test'; } export class IpcEvents { diff --git a/packages/uhk-usb/src/constants.ts b/packages/uhk-usb/src/constants.ts index a09c0a35..d2bdbbef 100644 --- a/packages/uhk-usb/src/constants.ts +++ b/packages/uhk-usb/src/constants.ts @@ -23,7 +23,12 @@ export enum UsbCommand { GetDebugBuffer = 0x0b, GetAdcValue = 0x0c, SetLedPwmBrightness = 0x0d, - GetModuleProperty = 0x0e + GetModuleProperty = 0x0e, + GetSlaveI2cErrors = 0x0f, + SetI2cBaudRate = 0x10, + SwitchKeymap = 0x11, + GetVariable = 0x12, + SetVariable = 0x13 } export enum EepromOperation { @@ -86,3 +91,10 @@ export enum KbootCommands { export enum ModulePropertyId { protocolVersions = 0 } + +export enum UsbVariables { + testSwitches = 0, + testUsbStack = 1, + debounceTimePress = 2, + debounceTimeRelease = 3 +} diff --git a/packages/uhk-usb/src/uhk-hid-device.ts b/packages/uhk-usb/src/uhk-hid-device.ts index c7e148ec..158ad38b 100644 --- a/packages/uhk-usb/src/uhk-hid-device.ts +++ b/packages/uhk-usb/src/uhk-hid-device.ts @@ -10,7 +10,8 @@ import { KbootCommands, ModuleSlotToI2cAddress, ModuleSlotToId, - UsbCommand + UsbCommand, + UsbVariables } from './constants'; import { bufferToString, getTransferData, isUhkDevice, retry, snooze } from './util'; @@ -133,6 +134,11 @@ export class UhkHidDevice { await this.waitUntilKeyboardBusy(); } + public async enableUsbStackTest(): Promise { + await this.write(new Buffer([UsbCommand.SetVariable, UsbVariables.testUsbStack, 1])); + await this.waitUntilKeyboardBusy(); + } + /** * Close the communication chanel with UHK Device */ diff --git a/packages/uhk-web/src/app/app.component.ts b/packages/uhk-web/src/app/app.component.ts index 564cedae..530a0223 100644 --- a/packages/uhk-web/src/app/app.component.ts +++ b/packages/uhk-web/src/app/app.component.ts @@ -7,6 +7,7 @@ import { Action, Store } from '@ngrx/store'; import 'rxjs/add/operator/last'; import { DoNotUpdateAppAction, UpdateAppAction } from './store/actions/app-update.action'; +import { EnableUsbStackTestAction } from './store/actions/device'; import { AppState, getShowAppUpdateAvailable, @@ -64,6 +65,16 @@ export class MainAppComponent implements OnDestroy { this.clickedOnProgressButton(this.saveToKeyboardState.action); event.preventDefault(); } + + if (event.shiftKey && + event.ctrlKey && + event.altKey && + event.metaKey && + event.key === '|' && + !event.defaultPrevented) { + this.enableUsbStackTest(); + event.preventDefault(); + } } updateApp() { @@ -77,4 +88,8 @@ export class MainAppComponent implements OnDestroy { clickedOnProgressButton(action: Action) { return this.store.dispatch(action); } + + enableUsbStackTest() { + this.store.dispatch(new EnableUsbStackTestAction()); + } } diff --git a/packages/uhk-web/src/app/services/device-renderer.service.ts b/packages/uhk-web/src/app/services/device-renderer.service.ts index 7c191c44..f0cf9549 100644 --- a/packages/uhk-web/src/app/services/device-renderer.service.ts +++ b/packages/uhk-web/src/app/services/device-renderer.service.ts @@ -50,6 +50,10 @@ export class DeviceRendererService { this.ipcRenderer.send(IpcEvents.device.recoveryDevice); } + enableUsbStackTest(): void { + this.ipcRenderer.send(IpcEvents.device.enableUsbStackTest); + } + private registerEvents(): void { this.ipcRenderer.on(IpcEvents.device.deviceConnectionStateChanged, (event: string, arg: DeviceConnectionState) => { this.dispachStoreAction(new ConnectionStateChangedAction(arg)); diff --git a/packages/uhk-web/src/app/store/actions/device.ts b/packages/uhk-web/src/app/store/actions/device.ts index f7fd638c..6c025e0f 100644 --- a/packages/uhk-web/src/app/store/actions/device.ts +++ b/packages/uhk-web/src/app/store/actions/device.ts @@ -28,7 +28,8 @@ export const ActionTypes = { HAS_BACKUP_USER_CONFIGURATION: type(PREFIX + 'Store backup user configuration'), RESTORE_CONFIGURATION_FROM_BACKUP: type(PREFIX + 'Restore configuration from backup'), RESTORE_CONFIGURATION_FROM_BACKUP_SUCCESS: type(PREFIX + 'Restore configuration from backup success'), - RECOVERY_DEVICE: type(PREFIX + 'Recovery device') + RECOVERY_DEVICE: type(PREFIX + 'Recovery device'), + ENABLE_USB_STACK_TEST: type(PREFIX + 'USB stack test') }; export class SetPrivilegeOnLinuxAction implements Action { @@ -144,6 +145,10 @@ export class RecoveryDeviceAction implements Action { type = ActionTypes.RECOVERY_DEVICE; } +export class EnableUsbStackTestAction implements Action { + type = ActionTypes.ENABLE_USB_STACK_TEST; +} + export type Actions = SetPrivilegeOnLinuxAction | SetPrivilegeOnLinuxReplyAction @@ -166,4 +171,5 @@ export type Actions | HasBackupUserConfigurationAction | RestoreUserConfigurationFromBackupSuccessAction | RecoveryDeviceAction + | EnableUsbStackTestAction ; diff --git a/packages/uhk-web/src/app/store/effects/device.ts b/packages/uhk-web/src/app/store/effects/device.ts index d65ca45b..8933611f 100644 --- a/packages/uhk-web/src/app/store/effects/device.ts +++ b/packages/uhk-web/src/app/store/effects/device.ts @@ -23,6 +23,7 @@ import { import { ActionTypes, ConnectionStateChangedAction, + EnableUsbStackTestAction, HideSaveToKeyboardButton, RecoveryDeviceAction, ResetUserConfigurationAction, @@ -230,6 +231,10 @@ export class DeviceEffects { .ofType(ActionTypes.RECOVERY_DEVICE) .do(() => this.deviceRendererService.recoveryDevice()); + @Effect({dispatch: false}) enableUsbStackTest$ = this.actions$ + .ofType(ActionTypes.ENABLE_USB_STACK_TEST) + .do(() => this.deviceRendererService.enableUsbStackTest()); + constructor(private actions$: Actions, private router: Router, private deviceRendererService: DeviceRendererService,