From 98f9e370619d179a4257a5fae5c6412754e5ef81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20R=C3=B3bert?= Date: Sat, 9 Nov 2024 17:40:18 +0100 Subject: [PATCH 1/5] fix: allow to delete host connection when dongle is not connected --- packages/uhk-agent/src/services/device.service.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/uhk-agent/src/services/device.service.ts b/packages/uhk-agent/src/services/device.service.ts index 3108fa46..c9f31845 100644 --- a/packages/uhk-agent/src/services/device.service.ts +++ b/packages/uhk-agent/src/services/device.service.ts @@ -713,11 +713,14 @@ export class DeviceService { try { await this.stopPollUhkDevice(); - const dongleHid = await getCurrentUhkDongleHID(); let dongleUhkDevice: UhkHidDevice; try { - dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid); - await dongleUhkDevice.deleteAllBonds(); + if (isConnectedDongleAddress) { + const dongleHid = await getCurrentUhkDongleHID(); + dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid); + await dongleUhkDevice.deleteAllBonds(); + } + await this.device.deleteBond(convertBleStringToNumberArray(address)); this.logService.misc('[DeviceService] delete host connection success', { address }); await snooze(1000); From 95c2bedfaf344b879a3533bdaf74b1b0f0a9fc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20R=C3=B3bert?= Date: Thu, 14 Nov 2024 19:02:24 +0100 Subject: [PATCH 2/5] fix: check dongle device existence --- packages/uhk-agent/src/services/device.service.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/uhk-agent/src/services/device.service.ts b/packages/uhk-agent/src/services/device.service.ts index c9f31845..fd874a7a 100644 --- a/packages/uhk-agent/src/services/device.service.ts +++ b/packages/uhk-agent/src/services/device.service.ts @@ -717,8 +717,10 @@ export class DeviceService { try { if (isConnectedDongleAddress) { const dongleHid = await getCurrentUhkDongleHID(); - dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid); - await dongleUhkDevice.deleteAllBonds(); + if (dongleHid) { + dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid); + await dongleUhkDevice.deleteAllBonds(); + } } await this.device.deleteBond(convertBleStringToNumberArray(address)); From 419a4c23d029cb0662d92e2712045167fb696b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20R=C3=B3bert?= Date: Thu, 14 Nov 2024 19:13:20 +0100 Subject: [PATCH 3/5] fix: ensure dongle is connected --- packages/uhk-agent/src/services/device.service.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/uhk-agent/src/services/device.service.ts b/packages/uhk-agent/src/services/device.service.ts index fd874a7a..49f2fb19 100644 --- a/packages/uhk-agent/src/services/device.service.ts +++ b/packages/uhk-agent/src/services/device.service.ts @@ -752,6 +752,10 @@ export class DeviceService { try { await this.stopPollUhkDevice(); const dongleHid = await getCurrentUhkDongleHID(); + if (!dongleHid) { + throw new Error('Cannot find dongle!'); + } + let dongleUhkDevice: UhkHidDevice; try { dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid); @@ -1063,6 +1067,12 @@ export class DeviceService { try { await snooze(1000); const uhkDeviceProduct = await getCurrentUhkDongleHID(); + + if (uhkDeviceProduct) { + this.logService.misc('[DeviceService] Dongle not found, skip reenumeration'); + return; + } + uhkHidDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, uhkDeviceProduct); await uhkHidDevice.reenumerate({ device: UHK_DONGLE, From 686efc316ccfe1e1a6bc03d50d183da94dad791a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20R=C3=B3bert?= Date: Tue, 19 Nov 2024 20:56:49 +0100 Subject: [PATCH 4/5] fix: don't delete bonds of the dongle when un-pairing --- .../uhk-agent/src/services/device.service.ts | 31 ++++--------------- .../app/services/device-renderer.service.ts | 3 +- .../store/effects/dongle-pairing.effect.ts | 12 ++----- 3 files changed, 10 insertions(+), 36 deletions(-) diff --git a/packages/uhk-agent/src/services/device.service.ts b/packages/uhk-agent/src/services/device.service.ts index 49f2fb19..fbb00370 100644 --- a/packages/uhk-agent/src/services/device.service.ts +++ b/packages/uhk-agent/src/services/device.service.ts @@ -708,35 +708,16 @@ export class DeviceService { } public async deleteHostConnection(event: Electron.IpcMainEvent, args: Array): Promise { - const {isConnectedDongleAddress, index, address} = args[0]; - this.logService.misc('[DeviceService] delete host connection', { isConnectedDongleAddress, index, address }); + const {index, address} = args[0]; + this.logService.misc('[DeviceService] delete host connection', { index, address }); try { await this.stopPollUhkDevice(); - let dongleUhkDevice: UhkHidDevice; - try { - if (isConnectedDongleAddress) { - const dongleHid = await getCurrentUhkDongleHID(); - if (dongleHid) { - dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid); - await dongleUhkDevice.deleteAllBonds(); - } - } - - await this.device.deleteBond(convertBleStringToNumberArray(address)); - this.logService.misc('[DeviceService] delete host connection success', { address }); - await snooze(1000); - event.sender.send(IpcEvents.device.deleteHostConnectionSuccess, {index, address}); - } - finally { - if (dongleUhkDevice) { - dongleUhkDevice.close(); - } - } + await this.device.deleteBond(convertBleStringToNumberArray(address)); + this.logService.misc('[DeviceService] delete host connection success', { address }); + await snooze(1000); + event.sender.send(IpcEvents.device.deleteHostConnectionSuccess, {index, address}); } catch (error) { - if (isConnectedDongleAddress) { - await this.forceReenumerateDongle(); - } await this.forceReenumerateDevice(); this.logService.misc('[DeviceService] delete host connection failed', { address, error }); event.sender.send(IpcEvents.device.deleteHostConnectionFailed, error.message); 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 c5d836b1..72707a3e 100644 --- a/packages/uhk-web/src/app/services/device-renderer.service.ts +++ b/packages/uhk-web/src/app/services/device-renderer.service.ts @@ -69,9 +69,8 @@ export class DeviceRendererService { this.ipcRenderer.send(IpcEvents.device.changeKeyboardLayout, layout, hardwareConfiguration.toJsonObject()); } - deleteHostConnection(data: DeleteHostConnectionPayload, isConnectedDongleAddress: boolean): void { + deleteHostConnection(data: DeleteHostConnectionPayload): void { this.ipcRenderer.send(IpcEvents.device.deleteHostConnection, { - isConnectedDongleAddress, index: data.index, address: data.hostConnection.address, }); diff --git a/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts b/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts index 6f764c25..30b6e6c8 100644 --- a/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts +++ b/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts @@ -1,8 +1,6 @@ import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType} from '@ngrx/effects'; -import { Store } from '@ngrx/store'; -import { map, tap, withLatestFrom } from 'rxjs/operators'; -import { HostConnections } from 'uhk-common'; +import { map, tap } from 'rxjs/operators'; import { NotificationType, runInElectron } from 'uhk-common'; import { DeviceRendererService } from '../../services/device-renderer.service'; @@ -16,7 +14,6 @@ import { DonglePairingFailedAction, DonglePairingSuccessAction, } from '../actions/dongle-pairing.action'; -import { AppState, getDongle } from '../index'; @Injectable() export class DonglePairingEffect { @@ -24,11 +21,9 @@ export class DonglePairingEffect { deleteHostConnection$ = createEffect(() => this.actions$ .pipe( ofType(ActionTypes.DeleteHostConnection), - withLatestFrom(this.store.select(getDongle)), - map(([action, dongle ]) => { + map((action ) => { if (runInElectron()) { - const isConnectedDongleAddress = action.payload.hostConnection.type === HostConnections.Dongle && dongle?.bleAddress === action.payload.hostConnection.address; - this.deviceRendererService.deleteHostConnection(action.payload, isConnectedDongleAddress); + this.deviceRendererService.deleteHostConnection(action.payload); return new EmptyAction(); } else { return new DeleteHostConnectionSuccessAction({ @@ -87,6 +82,5 @@ export class DonglePairingEffect { constructor(private actions$: Actions, private deviceRendererService: DeviceRendererService, - private store: Store, ){} } From d28cba007168bd5be2041b79eac499da1a1ad64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20R=C3=B3bert?= Date: Thu, 21 Nov 2024 20:41:00 +0100 Subject: [PATCH 5/5] Revert "fix: don't delete bonds of the dongle when un-pairing" This reverts commit 686efc316ccfe1e1a6bc03d50d183da94dad791a. --- .../uhk-agent/src/services/device.service.ts | 31 +++++++++++++++---- .../app/services/device-renderer.service.ts | 3 +- .../store/effects/dongle-pairing.effect.ts | 12 +++++-- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/uhk-agent/src/services/device.service.ts b/packages/uhk-agent/src/services/device.service.ts index fbb00370..49f2fb19 100644 --- a/packages/uhk-agent/src/services/device.service.ts +++ b/packages/uhk-agent/src/services/device.service.ts @@ -708,16 +708,35 @@ export class DeviceService { } public async deleteHostConnection(event: Electron.IpcMainEvent, args: Array): Promise { - const {index, address} = args[0]; - this.logService.misc('[DeviceService] delete host connection', { index, address }); + const {isConnectedDongleAddress, index, address} = args[0]; + this.logService.misc('[DeviceService] delete host connection', { isConnectedDongleAddress, index, address }); try { await this.stopPollUhkDevice(); - await this.device.deleteBond(convertBleStringToNumberArray(address)); - this.logService.misc('[DeviceService] delete host connection success', { address }); - await snooze(1000); - event.sender.send(IpcEvents.device.deleteHostConnectionSuccess, {index, address}); + let dongleUhkDevice: UhkHidDevice; + try { + if (isConnectedDongleAddress) { + const dongleHid = await getCurrentUhkDongleHID(); + if (dongleHid) { + dongleUhkDevice = new UhkHidDevice(this.logService, this.options, this.rootDir, dongleHid); + await dongleUhkDevice.deleteAllBonds(); + } + } + + await this.device.deleteBond(convertBleStringToNumberArray(address)); + this.logService.misc('[DeviceService] delete host connection success', { address }); + await snooze(1000); + event.sender.send(IpcEvents.device.deleteHostConnectionSuccess, {index, address}); + } + finally { + if (dongleUhkDevice) { + dongleUhkDevice.close(); + } + } } catch (error) { + if (isConnectedDongleAddress) { + await this.forceReenumerateDongle(); + } await this.forceReenumerateDevice(); this.logService.misc('[DeviceService] delete host connection failed', { address, error }); event.sender.send(IpcEvents.device.deleteHostConnectionFailed, error.message); 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 72707a3e..c5d836b1 100644 --- a/packages/uhk-web/src/app/services/device-renderer.service.ts +++ b/packages/uhk-web/src/app/services/device-renderer.service.ts @@ -69,8 +69,9 @@ export class DeviceRendererService { this.ipcRenderer.send(IpcEvents.device.changeKeyboardLayout, layout, hardwareConfiguration.toJsonObject()); } - deleteHostConnection(data: DeleteHostConnectionPayload): void { + deleteHostConnection(data: DeleteHostConnectionPayload, isConnectedDongleAddress: boolean): void { this.ipcRenderer.send(IpcEvents.device.deleteHostConnection, { + isConnectedDongleAddress, index: data.index, address: data.hostConnection.address, }); diff --git a/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts b/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts index 30b6e6c8..6f764c25 100644 --- a/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts +++ b/packages/uhk-web/src/app/store/effects/dongle-pairing.effect.ts @@ -1,6 +1,8 @@ import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType} from '@ngrx/effects'; -import { map, tap } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { map, tap, withLatestFrom } from 'rxjs/operators'; +import { HostConnections } from 'uhk-common'; import { NotificationType, runInElectron } from 'uhk-common'; import { DeviceRendererService } from '../../services/device-renderer.service'; @@ -14,6 +16,7 @@ import { DonglePairingFailedAction, DonglePairingSuccessAction, } from '../actions/dongle-pairing.action'; +import { AppState, getDongle } from '../index'; @Injectable() export class DonglePairingEffect { @@ -21,9 +24,11 @@ export class DonglePairingEffect { deleteHostConnection$ = createEffect(() => this.actions$ .pipe( ofType(ActionTypes.DeleteHostConnection), - map((action ) => { + withLatestFrom(this.store.select(getDongle)), + map(([action, dongle ]) => { if (runInElectron()) { - this.deviceRendererService.deleteHostConnection(action.payload); + const isConnectedDongleAddress = action.payload.hostConnection.type === HostConnections.Dongle && dongle?.bleAddress === action.payload.hostConnection.address; + this.deviceRendererService.deleteHostConnection(action.payload, isConnectedDongleAddress); return new EmptyAction(); } else { return new DeleteHostConnectionSuccessAction({ @@ -82,5 +87,6 @@ export class DonglePairingEffect { constructor(private actions$: Actions, private deviceRendererService: DeviceRendererService, + private store: Store, ){} }