[ATL-1533] Firmware&Certificate Uploader (#469)

Co-authored-by: Alberto Iannaccone <a.iannaccone@arduino.cc>
This commit is contained in:
Francesco Stasi
2021-08-25 10:36:51 +02:00
committed by GitHub
parent 6233e1fa98
commit 302fb7b6af
37 changed files with 20276 additions and 19 deletions

View File

@@ -0,0 +1,80 @@
import {
ArduinoFirmwareUploader,
FirmwareInfo,
} from '../common/protocol/arduino-firmware-uploader';
import { injectable, inject, named } from 'inversify';
import { ExecutableService } from '../common/protocol';
import { getExecPath, spawnCommand } from './exec-util';
import { ILogger } from '@theia/core/lib/common/logger';
@injectable()
export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
@inject(ExecutableService)
protected executableService: ExecutableService;
protected _execPath: string | undefined;
@inject(ILogger)
@named('fwuploader')
protected readonly logger: ILogger;
protected onError(error: any): void {
this.logger.error(error);
}
async getExecPath(): Promise<string> {
if (this._execPath) {
return this._execPath;
}
this._execPath = await getExecPath('arduino-fwuploader');
return this._execPath;
}
async runCommand(args: string[]): Promise<any> {
const execPath = await this.getExecPath();
return await spawnCommand(`"${execPath}"`, args, this.onError.bind(this));
}
async uploadCertificates(command: string): Promise<any> {
return await this.runCommand(['certificates', 'flash', command]);
}
async list(fqbn?: string): Promise<FirmwareInfo[]> {
const fqbnFlag = fqbn ? ['--fqbn', fqbn] : [];
const firmwares: FirmwareInfo[] =
JSON.parse(
await this.runCommand([
'firmware',
'list',
...fqbnFlag,
'--format',
'json',
])
) || [];
return firmwares.reverse();
}
async updatableBoards(): Promise<string[]> {
return (await this.list()).reduce(
(a, b) => (a.includes(b.board_fqbn) ? a : [...a, b.board_fqbn]),
[] as string[]
);
}
async availableFirmwares(fqbn: string): Promise<FirmwareInfo[]> {
return await this.list(fqbn);
}
async flash(firmware: FirmwareInfo, port: string): Promise<string> {
return await this.runCommand([
'firmware',
'flash',
'--fqbn',
firmware.board_fqbn,
'--address',
port,
'--module',
`${firmware.module}@${firmware.firmware_version}`,
]);
}
}

View File

@@ -1,5 +1,10 @@
import { ContainerModule } from 'inversify';
import { ArduinoDaemonImpl } from './arduino-daemon-impl';
import {
ArduinoFirmwareUploader,
ArduinoFirmwareUploaderPath,
} from '../common/protocol/arduino-firmware-uploader';
import { ILogger } from '@theia/core/lib/common/logger';
import {
BackendApplicationContribution,
@@ -80,6 +85,7 @@ import {
AuthenticationServiceClient,
AuthenticationServicePath,
} from '../common/protocol/authentication-service';
import { ArduinoFirmwareUploaderImpl } from './arduino-firmware-uploader-impl';
export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(BackendApplication).toSelf().inSingletonScope();
@@ -245,6 +251,18 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
)
.inSingletonScope();
bind(ArduinoFirmwareUploaderImpl).toSelf().inSingletonScope();
bind(ArduinoFirmwareUploader).toService(ArduinoFirmwareUploaderImpl);
bind(BackendApplicationContribution).toService(ArduinoFirmwareUploaderImpl);
bind(ConnectionHandler)
.toDynamicValue(
(context) =>
new JsonRpcConnectionHandler(ArduinoFirmwareUploaderPath, () =>
context.container.get(ArduinoFirmwareUploader)
)
)
.inSingletonScope();
// Logger for the Arduino daemon
bind(ILogger)
.toDynamicValue((ctx) => {
@@ -254,6 +272,15 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
.inSingletonScope()
.whenTargetNamed('daemon');
// Logger for the Arduino daemon
bind(ILogger)
.toDynamicValue((ctx) => {
const parentLogger = ctx.container.get<ILogger>(ILogger);
return parentLogger.child('fwuploader');
})
.inSingletonScope()
.whenTargetNamed('fwuploader');
// Logger for the "serial discovery".
bind(ILogger)
.toDynamicValue((ctx) => {