feat: kboot package (#894)
* feat: kboot package * feat: kboot package * fix: wait 1 sec after device is available * test: fix unit test * refactor: clean unused codes * doc: improve readme.md * doc: improve readme.md * test: fix unit test * chore: fix lint settings * style: fix linting issues
This commit is contained in:
committed by
László Monda
parent
bfc08edfce
commit
3964698cf7
6
packages/kboot/src/util/encode-string-to-parameters.ts
Normal file
6
packages/kboot/src/util/encode-string-to-parameters.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export const encodeStringToParams = (data: string): Int8Array => {
|
||||
// const buffer = Buffer.from(data);
|
||||
|
||||
// return new Int8Array(buffer, 0);
|
||||
return new Int8Array(0);
|
||||
};
|
||||
22
packages/kboot/src/util/index.ts
Normal file
22
packages/kboot/src/util/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
export * from './encode-string-to-parameters';
|
||||
export * from './response-parser';
|
||||
export * from './usb';
|
||||
|
||||
export const convertToHexString = (arr: number[] | Buffer): string => {
|
||||
let str = '';
|
||||
|
||||
for (const n of arr) {
|
||||
let hex = n.toString(16);
|
||||
if (hex.length < 2) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
|
||||
if (str.length > 0) {
|
||||
str += ' ';
|
||||
}
|
||||
|
||||
str += hex;
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
21
packages/kboot/src/util/response-parser.ts
Normal file
21
packages/kboot/src/util/response-parser.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ResponseCodes, ResponseTags } from '../enums';
|
||||
|
||||
export const convertLittleEndianNumber = (data: Buffer): number => {
|
||||
let value = 0;
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
value += data[i] << (8 * i);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
export const getResponseCode = (response: Buffer): ResponseCodes => {
|
||||
const data = response.slice(8, 11);
|
||||
|
||||
return convertLittleEndianNumber(data);
|
||||
};
|
||||
|
||||
export const getResponseTag = (response: Buffer): ResponseTags => {
|
||||
return response[4];
|
||||
};
|
||||
1
packages/kboot/src/util/snooze.ts
Normal file
1
packages/kboot/src/util/snooze.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const snooze = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
18
packages/kboot/src/util/usb/decode-command-response.ts
Normal file
18
packages/kboot/src/util/usb/decode-command-response.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { CommandResponse } from '../../models';
|
||||
import { getResponseCode, getResponseTag } from '../response-parser';
|
||||
|
||||
export const decodeCommandResponse = (response: Buffer): CommandResponse => {
|
||||
if (response.length < 8) {
|
||||
throw new Error('Invalid response length!');
|
||||
}
|
||||
|
||||
if (response[0] !== 3) {
|
||||
throw new Error(`Invalid response command channel!`);
|
||||
}
|
||||
|
||||
return {
|
||||
code: getResponseCode(response),
|
||||
tag: getResponseTag(response),
|
||||
raw: response
|
||||
};
|
||||
};
|
||||
22
packages/kboot/src/util/usb/device-finder.ts
Normal file
22
packages/kboot/src/util/usb/device-finder.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { isNullOrUndefined } from 'util';
|
||||
import { Device } from 'node-hid';
|
||||
|
||||
import { USB } from '../../models';
|
||||
|
||||
export const deviceFinder = (usb: USB) => {
|
||||
return (device: Device): boolean => {
|
||||
if (device.productId !== usb.productId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (device.vendorId !== usb.vendorId) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Add interface, usage and usePage filtering
|
||||
// if (!isNullOrUndefined(usb.interface) && device.interface !== -1 && device.interface === usb.interface) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
46
packages/kboot/src/util/usb/encode-command-option.ts
Normal file
46
packages/kboot/src/util/usb/encode-command-option.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { isNullOrUndefined } from 'util';
|
||||
import { pack } from 'byte-data';
|
||||
|
||||
import { CommandOption } from '../../models';
|
||||
|
||||
/**
|
||||
* Encode the USB Command.
|
||||
* @param option
|
||||
*/
|
||||
export const encodeCommandOption = (option: CommandOption): number[] => {
|
||||
const payload = [
|
||||
option.command,
|
||||
option.hasDataPhase ? 1 : 0,
|
||||
0, // Reserved. Should be 0
|
||||
option.params ? option.params.length / 4 >> 0 : 0 // number of parameters
|
||||
];
|
||||
|
||||
if (option.params) {
|
||||
payload.push(...option.params);
|
||||
}
|
||||
|
||||
const header = [
|
||||
1, // Communication channel
|
||||
0, // TODO: What is it?
|
||||
...pack(payload.length, { bits: 16 }) // payload length in 2 byte
|
||||
];
|
||||
|
||||
const placeholders = new Array(32 - payload.length)
|
||||
.fill(0);
|
||||
|
||||
return [...header, ...payload, ...placeholders];
|
||||
};
|
||||
|
||||
export const validateCommandParams = (params: any[]): void => {
|
||||
if (isNullOrUndefined(params)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(params)) {
|
||||
throw new Error('Command parameters must be an array!');
|
||||
}
|
||||
|
||||
if (params.length > 28) {
|
||||
throw new Error('Maximum 7 (28 bytes) command parameters allowed!');
|
||||
}
|
||||
};
|
||||
2
packages/kboot/src/util/usb/index.ts
Normal file
2
packages/kboot/src/util/usb/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { deviceFinder } from './device-finder';
|
||||
export { encodeCommandOption } from './encode-command-option';
|
||||
Reference in New Issue
Block a user