@@ -18,9 +18,11 @@ import { UhkHidDeviceService } from './uhk-hid-device.service';
1818 * UHK USB Communications command. All communication package should have start with a command code.
1919 */
2020enum Command {
21+ GetProperty = 0 ,
2122 UploadConfig = 8 ,
2223 ApplyConfig = 9 ,
2324 LaunchEepromTransfer = 12 ,
25+ ReadUserConfig = 15 ,
2426 GetKeyboardState = 16
2527}
2628
@@ -31,13 +33,23 @@ enum EepromTransfer {
3133 WriteUserConfig = 3
3234}
3335
36+ enum SystemPropertyIds {
37+ UsbProtocolVersion = 0 ,
38+ BridgeProtocolVersion = 1 ,
39+ DataModelVersion = 2 ,
40+ FirmwareVersion = 3 ,
41+ HardwareConfigSize = 4 ,
42+ UserConfigSize = 5
43+ }
44+
3445const snooze = ms => new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
3546
3647/**
3748 * IpcMain pair of the UHK Communication
3849 * Functionality:
3950 * - Detect device is connected or not
4051 * - Send UserConfiguration to the UHK Device
52+ * - Read UserConfiguration from the UHK Device
4153 */
4254export class DeviceService {
4355 private pollTimer$ : Subscription ;
@@ -48,6 +60,7 @@ export class DeviceService {
4860 private device : UhkHidDeviceService ) {
4961 this . pollUhkDevice ( ) ;
5062 ipcMain . on ( IpcEvents . device . saveUserConfiguration , this . saveUserConfiguration . bind ( this ) ) ;
63+ ipcMain . on ( IpcEvents . device . loadUserConfiguration , this . loadUserConfiguration . bind ( this ) ) ;
5164 logService . debug ( '[DeviceService] init success' ) ;
5265 }
5366
@@ -59,6 +72,38 @@ export class DeviceService {
5972 return this . connected ;
6073 }
6174
75+ /**
76+ * Return with the actual UserConfiguration from UHK Device
77+ * @returns {Promise<Buffer> }
78+ */
79+ public async loadUserConfiguration ( event : Electron . Event ) : Promise < void > {
80+ let response = [ ] ;
81+
82+ try {
83+ this . logService . debug ( '[DeviceService] USB[T]: Read user configuration size from keyboard' ) ;
84+ const configSize = await this . getUserConfigSizeFromKeyboard ( ) ;
85+ const chunkSize = 63 ;
86+ let offset = 0 ;
87+ let configBuffer = new Buffer ( 0 ) ;
88+
89+ this . logService . debug ( '[DeviceService] USB[T]: Read user configuration from keyboard' ) ;
90+ while ( offset < configSize ) {
91+ const chunkSizeToRead = Math . min ( chunkSize , configSize - offset ) ;
92+ const writeBuffer = Buffer . from ( [ Command . ReadUserConfig , chunkSizeToRead , offset & 0xff , offset >> 8 ] ) ;
93+ const readBuffer = await this . device . write ( writeBuffer ) ;
94+ configBuffer = Buffer . concat ( [ configBuffer , new Buffer ( readBuffer . slice ( 1 , chunkSizeToRead + 1 ) ) ] ) ;
95+ offset += chunkSizeToRead ;
96+ }
97+ response = UhkHidDeviceService . convertBufferToIntArray ( configBuffer ) ;
98+ } catch ( error ) {
99+ this . logService . error ( '[DeviceService] getUserConfigFromEeprom error' , error ) ;
100+ } finally {
101+ this . device . close ( ) ;
102+ }
103+
104+ event . sender . send ( IpcEvents . device . loadUserConfigurationReply , JSON . stringify ( response ) ) ;
105+ }
106+
62107 /**
63108 * HID API not support device attached and detached event.
64109 * This method check the keyboard is attached to the computer or not.
@@ -76,25 +121,38 @@ export class DeviceService {
76121 . do ( ( connected : boolean ) => {
77122 this . connected = connected ;
78123 this . win . webContents . send ( IpcEvents . device . deviceConnectionStateChanged , connected ) ;
79- this . logService . info ( `Device connection state changed to: ${ connected } ` ) ;
124+ this . logService . info ( `[DeviceService] Device connection state changed to: ${ connected } ` ) ;
80125 } )
81126 . subscribe ( ) ;
82127 }
83128
129+ /**
130+ * Return the UserConfiguration size from the UHK Device
131+ * @returns {Promise<number> }
132+ */
133+ private async getUserConfigSizeFromKeyboard ( ) : Promise < number > {
134+ const buffer = await this . device . write ( new Buffer ( [ Command . GetProperty , SystemPropertyIds . UserConfigSize ] ) ) ;
135+ const configSize = buffer [ 1 ] + ( buffer [ 2 ] << 8 ) ;
136+ this . logService . debug ( '[DeviceService] User config size:' , configSize ) ;
137+ return configSize ;
138+ }
139+
84140 private async saveUserConfiguration ( event : Electron . Event , json : string ) : Promise < void > {
85141 const response = new IpcResponse ( ) ;
86142
87143 try {
88- this . sendUserConfigToKeyboard ( json ) ;
144+ this . logService . debug ( '[DeviceService] USB[T]: Write user configuration to keyboard' ) ;
145+ await this . sendUserConfigToKeyboard ( json ) ;
146+ this . logService . debug ( '[DeviceService] USB[T]: Write user configuration to EEPROM' ) ;
89147 await this . writeUserConfigToEeprom ( ) ;
90- this . device . close ( ) ;
91148
92149 response . success = true ;
93- this . logService . info ( 'transferring finished' ) ;
94150 }
95151 catch ( error ) {
96152 this . logService . error ( '[DeviceService] Transferring error' , error ) ;
97153 response . error = { message : error . message } ;
154+ } finally {
155+ this . device . close ( ) ;
98156 }
99157
100158 event . sender . send ( IpcEvents . device . saveUserConfigurationReply , response ) ;
@@ -114,19 +172,14 @@ export class DeviceService {
114172 for ( const fragment of fragments ) {
115173 await this . device . write ( fragment ) ;
116174 }
117-
175+ this . logService . debug ( '[DeviceService] USB[T]: Apply user configuration to keyboard' ) ;
118176 const applyBuffer = new Buffer ( [ Command . ApplyConfig ] ) ;
119177 await this . device . write ( applyBuffer ) ;
120- this . logService . info ( '[DeviceService] Transferring finished' ) ;
121178 }
122179
123180 private async writeUserConfigToEeprom ( ) : Promise < void > {
124- this . logService . info ( '[DeviceService] Start write user configuration to eeprom' ) ;
125-
126- const buffer = await this . device . write ( new Buffer ( [ Command . LaunchEepromTransfer , EepromTransfer . WriteUserConfig ] ) ) ;
181+ await this . device . write ( new Buffer ( [ Command . LaunchEepromTransfer , EepromTransfer . WriteUserConfig ] ) ) ;
127182 await this . waitUntilKeyboardBusy ( ) ;
128-
129- this . logService . info ( '[DeviceService] End write user configuration to eeprom' ) ;
130183 }
131184
132185 private async waitUntilKeyboardBusy ( ) : Promise < void > {
0 commit comments