@nordicsemiconductor/pc-nrfconnect-shared 89.0.0 → 90.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +28 -0
- package/config/tsconfig.json +1 -1
- package/coverage/cobertura-coverage.xml +2216 -1061
- package/ipc/MetaFiles.ts +17 -7
- package/nrfutil/device/__mocks__/device.ts +43 -0
- package/nrfutil/device/batch.ts +219 -0
- package/nrfutil/device/batchTypes.ts +133 -0
- package/nrfutil/device/common.ts +274 -0
- package/nrfutil/device/device.ts +62 -0
- package/nrfutil/device/erase.ts +26 -0
- package/nrfutil/device/eraseBatch.ts +28 -0
- package/nrfutil/device/firmwareRead.ts +34 -0
- package/nrfutil/device/firmwareReadBatch.ts +42 -0
- package/nrfutil/device/getCoreInfo.ts +44 -0
- package/nrfutil/device/getCoreInfoBatch.ts +29 -0
- package/nrfutil/device/getFwInfo.ts +69 -0
- package/nrfutil/device/getFwInfoBatch.ts +29 -0
- package/nrfutil/device/getProtectionStatus.ts +46 -0
- package/nrfutil/device/getProtectionStatusBatch.ts +32 -0
- package/nrfutil/device/list.ts +81 -0
- package/nrfutil/device/program.ts +186 -0
- package/nrfutil/device/programBatch.ts +69 -0
- package/nrfutil/device/recover.ts +26 -0
- package/nrfutil/device/recoverBatch.ts +28 -0
- package/nrfutil/device/reset.ts +41 -0
- package/nrfutil/device/resetBatch.ts +30 -0
- package/nrfutil/device/setMcuState.ts +27 -0
- package/nrfutil/device/setProtectionStatus.ts +27 -0
- package/nrfutil/index.ts +25 -0
- package/nrfutil/moduleVersion.ts +57 -0
- package/nrfutil/nrfutilLogger.ts +15 -0
- package/nrfutil/sandbox.ts +504 -0
- package/nrfutil/sandboxTypes.ts +178 -0
- package/package.json +1 -1
- package/scripts/nordic-publish.js +1 -1
- package/scripts/nordic-publish.ts +11 -2
- package/src/About/SupportCard.tsx +6 -9
- package/src/App/App.test.tsx +4 -0
- package/src/App/App.tsx +13 -2
- package/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.tsx +1 -1
- package/src/Device/DeviceSelector/DeviceSelector.test.tsx +39 -31
- package/src/Device/DeviceSelector/DeviceSelector.tsx +3 -12
- package/src/Device/deviceInfo/deviceInfo.ts +2 -3
- package/src/Device/deviceLibWrapper.ts +0 -66
- package/src/Device/deviceLister.test.ts +1 -2
- package/src/Device/deviceLister.ts +169 -215
- package/src/Device/deviceSlice.ts +2 -16
- package/src/Device/jprogOperations.ts +21 -69
- package/src/Device/sdfuOperations.ts +77 -93
- package/src/ErrorBoundary/ErrorBoundary.tsx +1 -1
- package/src/Log/LogViewer.tsx +0 -4
- package/src/Log/logSlice.ts +4 -7
- package/src/logging/sendInitialLogMessages.ts +7 -8
- package/src/utils/appDirs.ts +6 -11
- package/src/utils/logLibVersions.ts +12 -14
- package/src/utils/systemReport.ts +11 -17
- package/src/utils/usageData.ts +14 -9
- package/tsconfig.json +1 -0
- package/typings/generated/ipc/MetaFiles.d.ts +14 -7
- package/typings/generated/ipc/MetaFiles.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/__mocks__/device.d.ts +23 -0
- package/typings/generated/nrfutil/device/__mocks__/device.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/batch.d.ts +26 -0
- package/typings/generated/nrfutil/device/batch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/batchTypes.d.ts +78 -0
- package/typings/generated/nrfutil/device/batchTypes.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/common.d.ts +125 -0
- package/typings/generated/nrfutil/device/common.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/device.d.ts +30 -0
- package/typings/generated/nrfutil/device/device.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/erase.d.ts +5 -0
- package/typings/generated/nrfutil/device/erase.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/eraseBatch.d.ts +7 -0
- package/typings/generated/nrfutil/device/eraseBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/firmwareRead.d.ts +10 -0
- package/typings/generated/nrfutil/device/firmwareRead.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/firmwareReadBatch.d.ts +9 -0
- package/typings/generated/nrfutil/device/firmwareReadBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/getCoreInfo.d.ts +22 -0
- package/typings/generated/nrfutil/device/getCoreInfo.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/getCoreInfoBatch.d.ts +8 -0
- package/typings/generated/nrfutil/device/getCoreInfoBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/getFwInfo.d.ts +31 -0
- package/typings/generated/nrfutil/device/getFwInfo.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/getFwInfoBatch.d.ts +8 -0
- package/typings/generated/nrfutil/device/getFwInfoBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/getProtectionStatus.d.ts +13 -0
- package/typings/generated/nrfutil/device/getProtectionStatus.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/getProtectionStatusBatch.d.ts +8 -0
- package/typings/generated/nrfutil/device/getProtectionStatusBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/list.d.ts +19 -0
- package/typings/generated/nrfutil/device/list.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/program.d.ts +27 -0
- package/typings/generated/nrfutil/device/program.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/programBatch.d.ts +9 -0
- package/typings/generated/nrfutil/device/programBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/recover.d.ts +5 -0
- package/typings/generated/nrfutil/device/recover.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/recoverBatch.d.ts +7 -0
- package/typings/generated/nrfutil/device/recoverBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/reset.d.ts +5 -0
- package/typings/generated/nrfutil/device/reset.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/resetBatch.d.ts +8 -0
- package/typings/generated/nrfutil/device/resetBatch.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/setMcuState.d.ts +6 -0
- package/typings/generated/nrfutil/device/setMcuState.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/setProtectionStatus.d.ts +5 -0
- package/typings/generated/nrfutil/device/setProtectionStatus.d.ts.map +1 -0
- package/typings/generated/nrfutil/index.d.ts +11 -0
- package/typings/generated/nrfutil/index.d.ts.map +1 -0
- package/typings/generated/nrfutil/moduleVersion.d.ts +6 -0
- package/typings/generated/nrfutil/moduleVersion.d.ts.map +1 -0
- package/typings/generated/nrfutil/nrfutilLogger.d.ts +4 -0
- package/typings/generated/nrfutil/nrfutilLogger.d.ts.map +1 -0
- package/typings/generated/nrfutil/sandbox.d.ts +36 -0
- package/typings/generated/nrfutil/sandbox.d.ts.map +1 -0
- package/typings/generated/nrfutil/sandboxTypes.d.ts +135 -0
- package/typings/generated/nrfutil/sandboxTypes.d.ts.map +1 -0
- package/typings/generated/src/About/SupportCard.d.ts.map +1 -1
- package/typings/generated/src/App/App.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts +2 -6
- package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceInfo/deviceInfo.d.ts +2 -2
- package/typings/generated/src/Device/deviceInfo/deviceInfo.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceLibWrapper.d.ts +1 -4
- package/typings/generated/src/Device/deviceLibWrapper.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceLister.d.ts +11 -16
- package/typings/generated/src/Device/deviceLister.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceLister.test.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceSlice.d.ts +3 -3
- package/typings/generated/src/Device/deviceSlice.d.ts.map +1 -1
- package/typings/generated/src/Device/jprogOperations.d.ts.map +1 -1
- package/typings/generated/src/Device/sdfuOperations.d.ts.map +1 -1
- package/typings/generated/src/ErrorBoundary/ErrorBoundary.d.ts +1 -1
- package/typings/generated/src/ErrorBoundary/ErrorBoundary.d.ts.map +1 -1
- package/typings/generated/src/Log/LogViewer.d.ts.map +1 -1
- package/typings/generated/src/Log/logSlice.d.ts +2 -3
- package/typings/generated/src/Log/logSlice.d.ts.map +1 -1
- package/typings/generated/src/logging/sendInitialLogMessages.d.ts.map +1 -1
- package/typings/generated/src/utils/appDirs.d.ts +4 -4
- package/typings/generated/src/utils/appDirs.d.ts.map +1 -1
- package/typings/generated/src/utils/logLibVersions.d.ts.map +1 -1
- package/typings/generated/src/utils/systemReport.d.ts +1 -1
- package/typings/generated/src/utils/systemReport.d.ts.map +1 -1
- package/typings/generated/src/utils/usageData.d.ts +2 -0
- package/typings/generated/src/utils/usageData.d.ts.map +1 -1
- package/src/utils/describeVersion.ts +0 -21
- package/typings/generated/src/utils/describeVersion.d.ts +0 -4
- package/typings/generated/src/utils/describeVersion.d.ts.map +0 -1
package/ipc/MetaFiles.ts
CHANGED
|
@@ -14,10 +14,13 @@ export interface SourceJson {
|
|
|
14
14
|
export type WithdrawnJson = UrlString[];
|
|
15
15
|
|
|
16
16
|
export type AppVersions = {
|
|
17
|
-
[version: string]:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
[version: string]: AppVersion;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type AppVersion = {
|
|
21
|
+
shasum?: string;
|
|
22
|
+
tarballUrl: UrlString;
|
|
23
|
+
nrfutilModules?: nrfutilModules;
|
|
21
24
|
};
|
|
22
25
|
|
|
23
26
|
export interface AppInfo {
|
|
@@ -39,6 +42,15 @@ interface ObjectContainingOptionalStrings {
|
|
|
39
42
|
[index: string]: string | undefined;
|
|
40
43
|
}
|
|
41
44
|
|
|
45
|
+
interface nrfConnectForDesktop {
|
|
46
|
+
nrfutil?: nrfutilModules;
|
|
47
|
+
html?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface nrfutilModules {
|
|
51
|
+
[index: string]: string[] | undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
export interface PackageJson {
|
|
43
55
|
name: string;
|
|
44
56
|
version: string;
|
|
@@ -52,6 +64,7 @@ export interface PackageJson {
|
|
|
52
64
|
devDependencies?: ObjectContainingOptionalStrings;
|
|
53
65
|
displayName?: string;
|
|
54
66
|
engines?: ObjectContainingOptionalStrings;
|
|
67
|
+
nrfConnectForDesktop?: nrfConnectForDesktop;
|
|
55
68
|
files?: readonly string[];
|
|
56
69
|
license?: string;
|
|
57
70
|
main?: string;
|
|
@@ -61,7 +74,4 @@ export interface PackageJson {
|
|
|
61
74
|
url: UrlString;
|
|
62
75
|
};
|
|
63
76
|
scripts?: ObjectContainingOptionalStrings;
|
|
64
|
-
nrfConnectForDesktop?: {
|
|
65
|
-
html?: string;
|
|
66
|
-
};
|
|
67
77
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const program = jest.fn();
|
|
8
|
+
const programBuffer = jest.fn();
|
|
9
|
+
const erase = jest.fn();
|
|
10
|
+
const recover = jest.fn();
|
|
11
|
+
const reset = jest.fn();
|
|
12
|
+
const getProtectionStatus = jest.fn();
|
|
13
|
+
const setProtectionStatus = jest.fn();
|
|
14
|
+
const getFwInfo = jest.fn();
|
|
15
|
+
const setMcuState = jest.fn();
|
|
16
|
+
const getCoreInfo = jest.fn();
|
|
17
|
+
const list = jest.fn(() => ({
|
|
18
|
+
stop: jest.fn(),
|
|
19
|
+
}));
|
|
20
|
+
const firmwareRead = jest.fn();
|
|
21
|
+
const onLogging = jest.fn();
|
|
22
|
+
const setLogLevel = jest.fn();
|
|
23
|
+
const setVerboseLogging = jest.fn();
|
|
24
|
+
const getModuleVersion = jest.fn();
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
program,
|
|
28
|
+
programBuffer,
|
|
29
|
+
erase,
|
|
30
|
+
recover,
|
|
31
|
+
reset,
|
|
32
|
+
getProtectionStatus,
|
|
33
|
+
setProtectionStatus,
|
|
34
|
+
getFwInfo,
|
|
35
|
+
setMcuState,
|
|
36
|
+
getCoreInfo,
|
|
37
|
+
list,
|
|
38
|
+
firmwareRead,
|
|
39
|
+
onLogging,
|
|
40
|
+
setLogLevel,
|
|
41
|
+
setVerboseLogging,
|
|
42
|
+
getModuleVersion,
|
|
43
|
+
};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { TaskEnd } from '../sandboxTypes';
|
|
8
|
+
import { BatchOperationWrapper, Callbacks } from './batchTypes';
|
|
9
|
+
import {
|
|
10
|
+
DeviceCore,
|
|
11
|
+
getDeviceSandbox,
|
|
12
|
+
NrfutilDeviceWithSerialnumber,
|
|
13
|
+
ResetKind,
|
|
14
|
+
} from './common';
|
|
15
|
+
import eraseBatch from './eraseBatch';
|
|
16
|
+
import firmwareReadBatch from './firmwareReadBatch';
|
|
17
|
+
import { DeviceCoreInfo } from './getCoreInfo';
|
|
18
|
+
import getCoreInfoBatch from './getCoreInfoBatch';
|
|
19
|
+
import { FWInfo } from './getFwInfo';
|
|
20
|
+
import getFwInfoBatch from './getFwInfoBatch';
|
|
21
|
+
import { GetProtectionStatusResult } from './getProtectionStatus';
|
|
22
|
+
import getProtectionStatusBatch from './getProtectionStatusBatch';
|
|
23
|
+
import { FirmwareType, ProgrammingOptions } from './program';
|
|
24
|
+
import programBatch from './programBatch';
|
|
25
|
+
import recoverBatch from './recoverBatch';
|
|
26
|
+
import resetBatch from './resetBatch';
|
|
27
|
+
|
|
28
|
+
type BatchOperationWrapperUnknown = BatchOperationWrapper<unknown, unknown>;
|
|
29
|
+
|
|
30
|
+
export class Batch {
|
|
31
|
+
private operations: BatchOperationWrapperUnknown[];
|
|
32
|
+
|
|
33
|
+
private collectOperations: {
|
|
34
|
+
callback: (completedTasks: TaskEnd<unknown>[]) => void;
|
|
35
|
+
operationId: number;
|
|
36
|
+
count: number;
|
|
37
|
+
}[] = [];
|
|
38
|
+
|
|
39
|
+
constructor(operations?: BatchOperationWrapperUnknown[]) {
|
|
40
|
+
this.operations = operations ?? [];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public erase(core: DeviceCore, callbacks?: Callbacks) {
|
|
44
|
+
this.operations.push(
|
|
45
|
+
eraseBatch(core, { callbacks }) as BatchOperationWrapperUnknown
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public firmwareRead(core: DeviceCore, callbacks?: Callbacks<Buffer>) {
|
|
52
|
+
this.operations.push(
|
|
53
|
+
firmwareReadBatch(core, {
|
|
54
|
+
callbacks,
|
|
55
|
+
}) as BatchOperationWrapperUnknown
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public getCoreInfo(
|
|
62
|
+
core: DeviceCore,
|
|
63
|
+
callbacks?: Callbacks<DeviceCoreInfo>
|
|
64
|
+
) {
|
|
65
|
+
this.operations.push(
|
|
66
|
+
getCoreInfoBatch(core, {
|
|
67
|
+
callbacks,
|
|
68
|
+
}) as BatchOperationWrapperUnknown
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public getFwInfo(core: DeviceCore, callbacks?: Callbacks<FWInfo>) {
|
|
75
|
+
this.operations.push(
|
|
76
|
+
getFwInfoBatch(core, {
|
|
77
|
+
callbacks,
|
|
78
|
+
}) as BatchOperationWrapperUnknown
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public getProtectionStatus(
|
|
85
|
+
core: DeviceCore,
|
|
86
|
+
callbacks?: Callbacks<GetProtectionStatusResult>
|
|
87
|
+
) {
|
|
88
|
+
this.operations.push(
|
|
89
|
+
getProtectionStatusBatch(core, {
|
|
90
|
+
callbacks,
|
|
91
|
+
}) as BatchOperationWrapperUnknown
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public program(
|
|
98
|
+
firmware: FirmwareType,
|
|
99
|
+
core: DeviceCore,
|
|
100
|
+
programmingOptions?: ProgrammingOptions,
|
|
101
|
+
callbacks?: Callbacks
|
|
102
|
+
) {
|
|
103
|
+
this.operations.push(
|
|
104
|
+
programBatch(firmware, core, {
|
|
105
|
+
programmingOptions,
|
|
106
|
+
callbacks,
|
|
107
|
+
}) as BatchOperationWrapperUnknown
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public recover(core: DeviceCore, callbacks?: Callbacks) {
|
|
114
|
+
this.operations.push(
|
|
115
|
+
recoverBatch(core, { callbacks }) as BatchOperationWrapperUnknown
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public reset(core: DeviceCore, reset?: ResetKind, callbacks?: Callbacks) {
|
|
122
|
+
this.operations.push(
|
|
123
|
+
resetBatch(core, {
|
|
124
|
+
reset,
|
|
125
|
+
callbacks,
|
|
126
|
+
}) as BatchOperationWrapperUnknown
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public collect(
|
|
133
|
+
count: number,
|
|
134
|
+
callback: (completedTasks: TaskEnd<unknown>[]) => void
|
|
135
|
+
) {
|
|
136
|
+
this.collectOperations.push({
|
|
137
|
+
callback,
|
|
138
|
+
operationId: this.operations.length - 1,
|
|
139
|
+
count,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public async run(
|
|
146
|
+
device: NrfutilDeviceWithSerialnumber,
|
|
147
|
+
controller?: AbortController | undefined
|
|
148
|
+
): Promise<unknown[]> {
|
|
149
|
+
let beginId = 0;
|
|
150
|
+
let endId = 0;
|
|
151
|
+
const results: TaskEnd<unknown>[] = [];
|
|
152
|
+
|
|
153
|
+
const operations = {
|
|
154
|
+
operations: this.operations.map((operation, index) => ({
|
|
155
|
+
operationId: index.toString(),
|
|
156
|
+
...operation.operation,
|
|
157
|
+
})),
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const sandbox = await getDeviceSandbox();
|
|
161
|
+
try {
|
|
162
|
+
await sandbox.execSubcommand<unknown>(
|
|
163
|
+
'execute-batch',
|
|
164
|
+
[
|
|
165
|
+
'--serial-number',
|
|
166
|
+
device.serialNumber,
|
|
167
|
+
'--batch-json',
|
|
168
|
+
JSON.stringify(operations),
|
|
169
|
+
],
|
|
170
|
+
(progress, task) => {
|
|
171
|
+
if (task) {
|
|
172
|
+
this.operations[endId].onProgress?.(progress, task);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
onTaskBegin => {
|
|
176
|
+
beginId += 1;
|
|
177
|
+
this.operations[endId].onTaskBegin?.(onTaskBegin);
|
|
178
|
+
},
|
|
179
|
+
taskEnd => {
|
|
180
|
+
results.push(taskEnd);
|
|
181
|
+
|
|
182
|
+
this.operations[endId].onTaskEnd?.(taskEnd);
|
|
183
|
+
|
|
184
|
+
this.collectOperations
|
|
185
|
+
.filter(operation => operation.operationId === endId)
|
|
186
|
+
.forEach(operation => {
|
|
187
|
+
operation.callback(
|
|
188
|
+
results.slice(
|
|
189
|
+
results.length - operation.count,
|
|
190
|
+
results.length
|
|
191
|
+
)
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
endId += 1;
|
|
196
|
+
},
|
|
197
|
+
controller
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const errors = results.filter(result => result.result === 'fail');
|
|
201
|
+
if (errors.length > 0) {
|
|
202
|
+
const error = new Error(
|
|
203
|
+
`Batch failed: ${errors
|
|
204
|
+
.map(e => `error: ${e.error}, message: ${e.message}`)
|
|
205
|
+
.join('\n')}`
|
|
206
|
+
);
|
|
207
|
+
this.operations[endId].onException?.(error);
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
} catch (error) {
|
|
211
|
+
if (beginId !== endId) {
|
|
212
|
+
this.operations[beginId].onException?.(error as Error);
|
|
213
|
+
}
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return results.map(result => result.data);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Progress, Task, TaskBegin, TaskEnd } from '../sandboxTypes';
|
|
8
|
+
import { DeviceCore, ResetKind } from './common';
|
|
9
|
+
import {
|
|
10
|
+
isJLinkProgrammingOptions,
|
|
11
|
+
isMcuBootProgrammingOptions,
|
|
12
|
+
isNordicDfuProgrammingOptions,
|
|
13
|
+
ProgrammingOptions,
|
|
14
|
+
} from './program';
|
|
15
|
+
|
|
16
|
+
export interface BatchOperationWrapper<OperationType, T = void> {
|
|
17
|
+
operation: GenericOperation<OperationType>;
|
|
18
|
+
onProgress?: (progress: Progress, task?: Task) => void;
|
|
19
|
+
onTaskBegin?: TaskBeginCallback;
|
|
20
|
+
onTaskEnd?: TaskEndCallback<T>;
|
|
21
|
+
onException?: (error: Error) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type Callbacks<T = void> = {
|
|
25
|
+
onTaskBegin?: TaskBeginCallback;
|
|
26
|
+
onTaskEnd?: TaskEndCallback<T>;
|
|
27
|
+
onProgress?: (progress: Progress, task?: Task) => void;
|
|
28
|
+
onException?: (error: Error) => void;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type DeviceCoreBatch =
|
|
32
|
+
| 'NRFDL_DEVICE_CORE_APPLICATION'
|
|
33
|
+
| 'NRFDL_DEVICE_CORE_NETWORK'
|
|
34
|
+
| 'NRFDL_DEVICE_CORE_MODEM';
|
|
35
|
+
|
|
36
|
+
export const convertDeviceCoreType = (core?: DeviceCore) => {
|
|
37
|
+
switch (core) {
|
|
38
|
+
case 'Application':
|
|
39
|
+
return 'NRFDL_DEVICE_CORE_APPLICATION';
|
|
40
|
+
case 'Network':
|
|
41
|
+
return 'NRFDL_DEVICE_CORE_NETWORK';
|
|
42
|
+
case 'Modem':
|
|
43
|
+
return 'NRFDL_DEVICE_CORE_MODEM';
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const convertProgrammingOptionsType = (
|
|
48
|
+
programmingOptions?: ProgrammingOptions
|
|
49
|
+
) => {
|
|
50
|
+
if (!programmingOptions) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (isJLinkProgrammingOptions(programmingOptions)) {
|
|
55
|
+
return {
|
|
56
|
+
qspi_erase_mode: programmingOptions.chipEraseMode,
|
|
57
|
+
reset: programmingOptions.reset,
|
|
58
|
+
verify: programmingOptions.verify,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (isMcuBootProgrammingOptions(programmingOptions)) {
|
|
63
|
+
return {
|
|
64
|
+
mcu_end_state: programmingOptions.mcuEndState,
|
|
65
|
+
net_core_upload_delay: programmingOptions.netCoreUploadDelay,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (isNordicDfuProgrammingOptions(programmingOptions)) {
|
|
70
|
+
return {
|
|
71
|
+
mcu_end_state: programmingOptions.mcuEndState,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export interface ProgrammingOperation {
|
|
77
|
+
type: 'program';
|
|
78
|
+
firmware: {
|
|
79
|
+
file: string;
|
|
80
|
+
};
|
|
81
|
+
reset?: ResetKind;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ResetOperation {
|
|
85
|
+
type: 'reset';
|
|
86
|
+
option?: ResetKind;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface RecoverOperation {
|
|
90
|
+
type: 'recover';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface ProtectionGetOperation {
|
|
94
|
+
type: 'protection-get';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface FirmwareReadOperation {
|
|
98
|
+
type: 'fw-read';
|
|
99
|
+
firmware: {
|
|
100
|
+
buffer: string;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface EraseOperation {
|
|
105
|
+
type: 'erase';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface GetCoreInfoOperation {
|
|
109
|
+
type: 'core-info';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface GetFwInfoOperation {
|
|
113
|
+
type: 'fw-info';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface GenericOperation<T> {
|
|
117
|
+
core?: DeviceCoreBatch;
|
|
118
|
+
operationId?: string;
|
|
119
|
+
operation: T;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export type BatchOperation =
|
|
123
|
+
| ProgrammingOperation
|
|
124
|
+
| ResetOperation
|
|
125
|
+
| RecoverOperation
|
|
126
|
+
| ProtectionGetOperation
|
|
127
|
+
| FirmwareReadOperation
|
|
128
|
+
| EraseOperation
|
|
129
|
+
| GetCoreInfoOperation
|
|
130
|
+
| GetFwInfoOperation;
|
|
131
|
+
|
|
132
|
+
export type TaskEndCallback<T = void> = (end: TaskEnd<T>) => void;
|
|
133
|
+
export type TaskBeginCallback = (begin: TaskBegin) => void;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { getUserDataDir } from '../../src/utils/appDirs';
|
|
8
|
+
import {
|
|
9
|
+
getIsLoggingVerbose,
|
|
10
|
+
persistIsLoggingVerbose,
|
|
11
|
+
} from '../../src/utils/persistentStore';
|
|
12
|
+
import { getNrfutilLogger } from '../nrfutilLogger';
|
|
13
|
+
import sandbox, { type NrfutilSandbox } from '../sandbox';
|
|
14
|
+
import { Progress } from '../sandboxTypes';
|
|
15
|
+
|
|
16
|
+
export const deviceTraitsToArgs = (traits: DeviceTraits) => {
|
|
17
|
+
const args: string[] = [];
|
|
18
|
+
const traitsString = Object.keys(traits)
|
|
19
|
+
.map(trait => (traits[trait as keyof DeviceTraits] ? trait : null))
|
|
20
|
+
.filter(t => t !== null)
|
|
21
|
+
.join(',');
|
|
22
|
+
|
|
23
|
+
if (traitsString.length > 0) {
|
|
24
|
+
args.push('--traits');
|
|
25
|
+
args.push(traitsString);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return args;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type ResetKind =
|
|
32
|
+
| 'RESET_SYSTEM'
|
|
33
|
+
| 'RESET_HARD'
|
|
34
|
+
| 'RESET_DEBUG'
|
|
35
|
+
| 'RESET_PIN';
|
|
36
|
+
|
|
37
|
+
export interface DeviceArrivedEvent {
|
|
38
|
+
device: NrfutilDevice;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface DeviceLeftEvent {
|
|
42
|
+
id: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface HwInfo {
|
|
46
|
+
romSize: number;
|
|
47
|
+
ramSize: number;
|
|
48
|
+
romPageSize: number;
|
|
49
|
+
deviceFamily: string;
|
|
50
|
+
deviceVersion: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface DfuTriggerInfo {
|
|
54
|
+
wAddress: number;
|
|
55
|
+
wVersionMajor: number;
|
|
56
|
+
wVersionMinor: number;
|
|
57
|
+
wFirmwareId: number;
|
|
58
|
+
wFlashSize: number;
|
|
59
|
+
wFlashPageSize: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface DfuTriggerVersion {
|
|
63
|
+
semVer: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface NrfutilDevice {
|
|
67
|
+
id: number;
|
|
68
|
+
serialNumber?: string; // undefined in case udev is not installed
|
|
69
|
+
traits: DeviceTraits;
|
|
70
|
+
usb?: USB;
|
|
71
|
+
jlink?: JLink;
|
|
72
|
+
// non-Nordic devices may not have serialPorts property at all
|
|
73
|
+
serialPorts?: Array<SerialPort>;
|
|
74
|
+
hwInfo?: HwInfo;
|
|
75
|
+
dfuTriggerInfo?: DfuTriggerInfo;
|
|
76
|
+
dfuTriggerVersion?: DfuTriggerVersion;
|
|
77
|
+
broken?: null | {
|
|
78
|
+
description: string;
|
|
79
|
+
url: string;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface NrfutilDeviceWithSerialnumber extends NrfutilDevice {
|
|
84
|
+
serialNumber: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type DeviceFamily =
|
|
88
|
+
| 'NRF51_FAMILY'
|
|
89
|
+
| 'NRF52_FAMILY'
|
|
90
|
+
| 'NRF53_FAMILY'
|
|
91
|
+
| 'NRF91_FAMILY';
|
|
92
|
+
|
|
93
|
+
export type ProtectionStatus =
|
|
94
|
+
| 'NRFDL_PROTECTION_STATUS_NONE'
|
|
95
|
+
| 'NRFDL_PROTECTION_STATUS_REGION0'
|
|
96
|
+
| 'NRFDL_PROTECTION_STATUS_REGION0_REGION1'
|
|
97
|
+
| 'NRFDL_PROTECTION_STATUS_SECURE_REGIONS'
|
|
98
|
+
| 'NRFDL_PROTECTION_STATUS_ALL';
|
|
99
|
+
|
|
100
|
+
export type VersionType =
|
|
101
|
+
| 'NRFDL_VERSION_TYPE_SEMANTIC'
|
|
102
|
+
| 'NRFDL_VERSION_TYPE_INCREMENTAL'
|
|
103
|
+
| 'NRFDL_VERSION_TYPE_STRING';
|
|
104
|
+
|
|
105
|
+
export type DeviceCore = 'Application' | 'Modem' | 'Network';
|
|
106
|
+
|
|
107
|
+
export interface DeviceTraits {
|
|
108
|
+
usb?: boolean;
|
|
109
|
+
nordicUsb?: boolean;
|
|
110
|
+
nordicDfu?: boolean;
|
|
111
|
+
seggerUsb?: boolean;
|
|
112
|
+
jlink?: boolean;
|
|
113
|
+
serialPorts?: boolean;
|
|
114
|
+
broken?: boolean;
|
|
115
|
+
mcuBoot?: boolean;
|
|
116
|
+
modem?: boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface USB {
|
|
120
|
+
serialNumber: string;
|
|
121
|
+
manufacturer: string | null;
|
|
122
|
+
osDevicePath: string;
|
|
123
|
+
product: string | null;
|
|
124
|
+
device: USBDevice;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface USBDeviceDescriptor {
|
|
128
|
+
bDescriptorType: number;
|
|
129
|
+
idVendor: number;
|
|
130
|
+
idProduct: number;
|
|
131
|
+
bcdDevice: number;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface USBConfigurationDescriptor {
|
|
135
|
+
bDescriptorType: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface USBInterfaceDescriptor {
|
|
139
|
+
bDescriptorType: number;
|
|
140
|
+
bInterfaceClass: number;
|
|
141
|
+
bInterfaceSubClass: number;
|
|
142
|
+
bInterfaceProtocol: number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface USBInterface {
|
|
146
|
+
descriptors: USBInterfaceDescriptor[];
|
|
147
|
+
endpointLists: USBEndpoint[];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface USBEndpointDescriptor {
|
|
151
|
+
bDescriptorType: number;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface USBEndpoint {
|
|
155
|
+
descriptors?: USBEndpointDescriptor[];
|
|
156
|
+
length: number;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface USBConfiguration {
|
|
160
|
+
descriptors: USBConfigurationDescriptor[];
|
|
161
|
+
interfaceLists: USBInterface[];
|
|
162
|
+
length: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface USBDevice {
|
|
166
|
+
busNumber: number;
|
|
167
|
+
address: number;
|
|
168
|
+
descriptor: USBDeviceDescriptor;
|
|
169
|
+
configList: USBConfiguration; // todo: check this prop
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface JLink {
|
|
173
|
+
serialNumber: string;
|
|
174
|
+
boardVersion: string | null; // can be null for external jLink
|
|
175
|
+
jlinkObFirmwareVersion: string | null;
|
|
176
|
+
deviceFamily: string | null;
|
|
177
|
+
deviceVersion: string | null; // will be null if device is protected
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface SerialPort {
|
|
181
|
+
serialNumber: string | null;
|
|
182
|
+
comName: string | null;
|
|
183
|
+
manufacturer: string | null;
|
|
184
|
+
productId: string | null;
|
|
185
|
+
vendorId: string | null;
|
|
186
|
+
vcom: number;
|
|
187
|
+
path: string | null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let deviceSandbox: NrfutilSandbox | undefined;
|
|
191
|
+
let promiseDeviceSandbox: Promise<NrfutilSandbox> | undefined;
|
|
192
|
+
|
|
193
|
+
export const getDeviceSandbox = async () => {
|
|
194
|
+
if (deviceSandbox) {
|
|
195
|
+
return deviceSandbox;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (!promiseDeviceSandbox) {
|
|
199
|
+
promiseDeviceSandbox = sandbox(
|
|
200
|
+
getUserDataDir(),
|
|
201
|
+
'device',
|
|
202
|
+
undefined,
|
|
203
|
+
undefined
|
|
204
|
+
);
|
|
205
|
+
deviceSandbox = await promiseDeviceSandbox;
|
|
206
|
+
|
|
207
|
+
deviceSandbox.onLogging(evt => {
|
|
208
|
+
const deviceLogger = getNrfutilLogger();
|
|
209
|
+
switch (evt.level) {
|
|
210
|
+
case 'TRACE':
|
|
211
|
+
deviceLogger?.verbose(evt.message);
|
|
212
|
+
break;
|
|
213
|
+
case 'DEBUG':
|
|
214
|
+
deviceLogger?.debug(evt.message);
|
|
215
|
+
break;
|
|
216
|
+
case 'INFO':
|
|
217
|
+
deviceLogger?.info(evt.message);
|
|
218
|
+
break;
|
|
219
|
+
case 'WARN':
|
|
220
|
+
deviceLogger?.warn(evt.message);
|
|
221
|
+
break;
|
|
222
|
+
case 'ERROR':
|
|
223
|
+
deviceLogger?.error(evt.message);
|
|
224
|
+
break;
|
|
225
|
+
case 'CRITICAL':
|
|
226
|
+
deviceLogger?.error(evt.message);
|
|
227
|
+
break;
|
|
228
|
+
case 'OFF':
|
|
229
|
+
default:
|
|
230
|
+
// Unreachable
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
deviceSandbox.setLogLevel(getIsLoggingVerbose() ? 'trace' : 'error');
|
|
236
|
+
// Only the first reset after selecting "reset with verbose logging" is relevant
|
|
237
|
+
persistIsLoggingVerbose(false);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const box = await promiseDeviceSandbox;
|
|
241
|
+
return box;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export const deviceSingleTaskEndOperation = async <T = void>(
|
|
245
|
+
device: NrfutilDeviceWithSerialnumber,
|
|
246
|
+
command: string,
|
|
247
|
+
onProgress?: (progress: Progress) => void,
|
|
248
|
+
controller?: AbortController,
|
|
249
|
+
args: string[] = []
|
|
250
|
+
) => {
|
|
251
|
+
const box = await getDeviceSandbox();
|
|
252
|
+
return box.singleTaskEndOperationWithData<T>(
|
|
253
|
+
command,
|
|
254
|
+
onProgress,
|
|
255
|
+
controller,
|
|
256
|
+
[...args, '--serial-number', device.serialNumber]
|
|
257
|
+
);
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
export const deviceSingleTaskEndOperationVoid = async (
|
|
261
|
+
device: NrfutilDeviceWithSerialnumber,
|
|
262
|
+
command: string,
|
|
263
|
+
onProgress?: (progress: Progress) => void,
|
|
264
|
+
controller?: AbortController,
|
|
265
|
+
args: string[] = []
|
|
266
|
+
) => {
|
|
267
|
+
const box = await getDeviceSandbox();
|
|
268
|
+
await box.singleTaskEndOperationOptionalData(
|
|
269
|
+
command,
|
|
270
|
+
onProgress,
|
|
271
|
+
controller,
|
|
272
|
+
[...args, '--serial-number', device.serialNumber]
|
|
273
|
+
);
|
|
274
|
+
};
|