@nordicsemiconductor/pc-nrfconnect-shared 88.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.
Files changed (149) hide show
  1. package/Changelog.md +34 -0
  2. package/config/tsconfig.json +1 -1
  3. package/coverage/cobertura-coverage.xml +2216 -1061
  4. package/ipc/MetaFiles.ts +17 -7
  5. package/nrfutil/device/__mocks__/device.ts +43 -0
  6. package/nrfutil/device/batch.ts +219 -0
  7. package/nrfutil/device/batchTypes.ts +133 -0
  8. package/nrfutil/device/common.ts +274 -0
  9. package/nrfutil/device/device.ts +62 -0
  10. package/nrfutil/device/erase.ts +26 -0
  11. package/nrfutil/device/eraseBatch.ts +28 -0
  12. package/nrfutil/device/firmwareRead.ts +34 -0
  13. package/nrfutil/device/firmwareReadBatch.ts +42 -0
  14. package/nrfutil/device/getCoreInfo.ts +44 -0
  15. package/nrfutil/device/getCoreInfoBatch.ts +29 -0
  16. package/nrfutil/device/getFwInfo.ts +69 -0
  17. package/nrfutil/device/getFwInfoBatch.ts +29 -0
  18. package/nrfutil/device/getProtectionStatus.ts +46 -0
  19. package/nrfutil/device/getProtectionStatusBatch.ts +32 -0
  20. package/nrfutil/device/list.ts +81 -0
  21. package/nrfutil/device/program.ts +186 -0
  22. package/nrfutil/device/programBatch.ts +69 -0
  23. package/nrfutil/device/recover.ts +26 -0
  24. package/nrfutil/device/recoverBatch.ts +28 -0
  25. package/nrfutil/device/reset.ts +41 -0
  26. package/nrfutil/device/resetBatch.ts +30 -0
  27. package/nrfutil/device/setMcuState.ts +27 -0
  28. package/nrfutil/device/setProtectionStatus.ts +27 -0
  29. package/nrfutil/index.ts +25 -0
  30. package/nrfutil/moduleVersion.ts +57 -0
  31. package/nrfutil/nrfutilLogger.ts +15 -0
  32. package/nrfutil/sandbox.ts +504 -0
  33. package/nrfutil/sandboxTypes.ts +178 -0
  34. package/package.json +2 -2
  35. package/scripts/nordic-publish.js +1 -1
  36. package/scripts/nordic-publish.ts +11 -2
  37. package/src/About/SupportCard.tsx +6 -9
  38. package/src/App/App.test.tsx +4 -0
  39. package/src/App/App.tsx +13 -2
  40. package/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.tsx +1 -1
  41. package/src/Device/DeviceSelector/DeviceSelector.test.tsx +39 -31
  42. package/src/Device/DeviceSelector/DeviceSelector.tsx +3 -12
  43. package/src/Device/deviceInfo/deviceInfo.ts +2 -3
  44. package/src/Device/deviceLibWrapper.ts +0 -66
  45. package/src/Device/deviceLister.test.ts +1 -2
  46. package/src/Device/deviceLister.ts +169 -215
  47. package/src/Device/deviceSlice.ts +2 -16
  48. package/src/Device/jprogOperations.ts +21 -69
  49. package/src/Device/sdfuOperations.ts +77 -93
  50. package/src/ErrorBoundary/ErrorBoundary.tsx +1 -1
  51. package/src/Log/LogViewer.tsx +0 -4
  52. package/src/Log/logSlice.ts +4 -7
  53. package/src/logging/sendInitialLogMessages.ts +7 -8
  54. package/src/utils/appDirs.ts +6 -11
  55. package/src/utils/logLibVersions.ts +12 -14
  56. package/src/utils/systemReport.ts +11 -17
  57. package/src/utils/usageData.ts +14 -9
  58. package/tsconfig.json +1 -0
  59. package/typings/generated/ipc/MetaFiles.d.ts +14 -7
  60. package/typings/generated/ipc/MetaFiles.d.ts.map +1 -1
  61. package/typings/generated/nrfutil/device/__mocks__/device.d.ts +23 -0
  62. package/typings/generated/nrfutil/device/__mocks__/device.d.ts.map +1 -0
  63. package/typings/generated/nrfutil/device/batch.d.ts +26 -0
  64. package/typings/generated/nrfutil/device/batch.d.ts.map +1 -0
  65. package/typings/generated/nrfutil/device/batchTypes.d.ts +78 -0
  66. package/typings/generated/nrfutil/device/batchTypes.d.ts.map +1 -0
  67. package/typings/generated/nrfutil/device/common.d.ts +125 -0
  68. package/typings/generated/nrfutil/device/common.d.ts.map +1 -0
  69. package/typings/generated/nrfutil/device/device.d.ts +30 -0
  70. package/typings/generated/nrfutil/device/device.d.ts.map +1 -0
  71. package/typings/generated/nrfutil/device/erase.d.ts +5 -0
  72. package/typings/generated/nrfutil/device/erase.d.ts.map +1 -0
  73. package/typings/generated/nrfutil/device/eraseBatch.d.ts +7 -0
  74. package/typings/generated/nrfutil/device/eraseBatch.d.ts.map +1 -0
  75. package/typings/generated/nrfutil/device/firmwareRead.d.ts +10 -0
  76. package/typings/generated/nrfutil/device/firmwareRead.d.ts.map +1 -0
  77. package/typings/generated/nrfutil/device/firmwareReadBatch.d.ts +9 -0
  78. package/typings/generated/nrfutil/device/firmwareReadBatch.d.ts.map +1 -0
  79. package/typings/generated/nrfutil/device/getCoreInfo.d.ts +22 -0
  80. package/typings/generated/nrfutil/device/getCoreInfo.d.ts.map +1 -0
  81. package/typings/generated/nrfutil/device/getCoreInfoBatch.d.ts +8 -0
  82. package/typings/generated/nrfutil/device/getCoreInfoBatch.d.ts.map +1 -0
  83. package/typings/generated/nrfutil/device/getFwInfo.d.ts +31 -0
  84. package/typings/generated/nrfutil/device/getFwInfo.d.ts.map +1 -0
  85. package/typings/generated/nrfutil/device/getFwInfoBatch.d.ts +8 -0
  86. package/typings/generated/nrfutil/device/getFwInfoBatch.d.ts.map +1 -0
  87. package/typings/generated/nrfutil/device/getProtectionStatus.d.ts +13 -0
  88. package/typings/generated/nrfutil/device/getProtectionStatus.d.ts.map +1 -0
  89. package/typings/generated/nrfutil/device/getProtectionStatusBatch.d.ts +8 -0
  90. package/typings/generated/nrfutil/device/getProtectionStatusBatch.d.ts.map +1 -0
  91. package/typings/generated/nrfutil/device/list.d.ts +19 -0
  92. package/typings/generated/nrfutil/device/list.d.ts.map +1 -0
  93. package/typings/generated/nrfutil/device/program.d.ts +27 -0
  94. package/typings/generated/nrfutil/device/program.d.ts.map +1 -0
  95. package/typings/generated/nrfutil/device/programBatch.d.ts +9 -0
  96. package/typings/generated/nrfutil/device/programBatch.d.ts.map +1 -0
  97. package/typings/generated/nrfutil/device/recover.d.ts +5 -0
  98. package/typings/generated/nrfutil/device/recover.d.ts.map +1 -0
  99. package/typings/generated/nrfutil/device/recoverBatch.d.ts +7 -0
  100. package/typings/generated/nrfutil/device/recoverBatch.d.ts.map +1 -0
  101. package/typings/generated/nrfutil/device/reset.d.ts +5 -0
  102. package/typings/generated/nrfutil/device/reset.d.ts.map +1 -0
  103. package/typings/generated/nrfutil/device/resetBatch.d.ts +8 -0
  104. package/typings/generated/nrfutil/device/resetBatch.d.ts.map +1 -0
  105. package/typings/generated/nrfutil/device/setMcuState.d.ts +6 -0
  106. package/typings/generated/nrfutil/device/setMcuState.d.ts.map +1 -0
  107. package/typings/generated/nrfutil/device/setProtectionStatus.d.ts +5 -0
  108. package/typings/generated/nrfutil/device/setProtectionStatus.d.ts.map +1 -0
  109. package/typings/generated/nrfutil/index.d.ts +11 -0
  110. package/typings/generated/nrfutil/index.d.ts.map +1 -0
  111. package/typings/generated/nrfutil/moduleVersion.d.ts +6 -0
  112. package/typings/generated/nrfutil/moduleVersion.d.ts.map +1 -0
  113. package/typings/generated/nrfutil/nrfutilLogger.d.ts +4 -0
  114. package/typings/generated/nrfutil/nrfutilLogger.d.ts.map +1 -0
  115. package/typings/generated/nrfutil/sandbox.d.ts +36 -0
  116. package/typings/generated/nrfutil/sandbox.d.ts.map +1 -0
  117. package/typings/generated/nrfutil/sandboxTypes.d.ts +135 -0
  118. package/typings/generated/nrfutil/sandboxTypes.d.ts.map +1 -0
  119. package/typings/generated/src/About/SupportCard.d.ts.map +1 -1
  120. package/typings/generated/src/App/App.d.ts.map +1 -1
  121. package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts +2 -6
  122. package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts.map +1 -1
  123. package/typings/generated/src/Device/deviceInfo/deviceInfo.d.ts +2 -2
  124. package/typings/generated/src/Device/deviceInfo/deviceInfo.d.ts.map +1 -1
  125. package/typings/generated/src/Device/deviceLibWrapper.d.ts +1 -4
  126. package/typings/generated/src/Device/deviceLibWrapper.d.ts.map +1 -1
  127. package/typings/generated/src/Device/deviceLister.d.ts +11 -16
  128. package/typings/generated/src/Device/deviceLister.d.ts.map +1 -1
  129. package/typings/generated/src/Device/deviceLister.test.d.ts.map +1 -1
  130. package/typings/generated/src/Device/deviceSlice.d.ts +3 -3
  131. package/typings/generated/src/Device/deviceSlice.d.ts.map +1 -1
  132. package/typings/generated/src/Device/jprogOperations.d.ts.map +1 -1
  133. package/typings/generated/src/Device/sdfuOperations.d.ts.map +1 -1
  134. package/typings/generated/src/ErrorBoundary/ErrorBoundary.d.ts +1 -1
  135. package/typings/generated/src/ErrorBoundary/ErrorBoundary.d.ts.map +1 -1
  136. package/typings/generated/src/Log/LogViewer.d.ts.map +1 -1
  137. package/typings/generated/src/Log/logSlice.d.ts +2 -3
  138. package/typings/generated/src/Log/logSlice.d.ts.map +1 -1
  139. package/typings/generated/src/logging/sendInitialLogMessages.d.ts.map +1 -1
  140. package/typings/generated/src/utils/appDirs.d.ts +4 -4
  141. package/typings/generated/src/utils/appDirs.d.ts.map +1 -1
  142. package/typings/generated/src/utils/logLibVersions.d.ts.map +1 -1
  143. package/typings/generated/src/utils/systemReport.d.ts +1 -1
  144. package/typings/generated/src/utils/systemReport.d.ts.map +1 -1
  145. package/typings/generated/src/utils/usageData.d.ts +2 -0
  146. package/typings/generated/src/utils/usageData.d.ts.map +1 -1
  147. package/src/utils/describeVersion.ts +0 -21
  148. package/typings/generated/src/utils/describeVersion.d.ts +0 -4
  149. 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
- shasum?: string;
19
- tarballUrl: UrlString;
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
+ };