@nordicsemiconductor/pc-nrfconnect-shared 121.0.0 → 123.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 +85 -0
- package/coverage/cobertura-coverage.xml +2276 -1778
- package/ipc/launcherConfig.ts +25 -0
- package/ipc/openWindow.ts +17 -1
- package/ipc/schema/packageJson.ts +26 -22
- package/main/index.ts +11 -5
- package/mocks/packageJsonMock.ts +1 -1
- package/nrfutil/device/__mocks__/device.ts +2 -0
- package/nrfutil/device/batch.ts +19 -9
- package/nrfutil/device/common.ts +32 -46
- package/nrfutil/device/device.ts +2 -0
- package/nrfutil/device/deviceInfo.ts +70 -0
- package/nrfutil/device/erase.ts +2 -2
- package/nrfutil/device/firmwareRead.ts +2 -2
- package/nrfutil/device/getCoreInfo.ts +2 -2
- package/nrfutil/device/getFwInfo.ts +2 -2
- package/nrfutil/device/getProtectionStatus.ts +2 -2
- package/nrfutil/device/list.ts +5 -31
- package/nrfutil/device/program.ts +4 -4
- package/nrfutil/device/recover.ts +2 -2
- package/nrfutil/device/reset.ts +2 -2
- package/nrfutil/device/setMcuState.ts +2 -5
- package/nrfutil/device/setProtectionStatus.ts +2 -2
- package/nrfutil/index.ts +1 -1
- package/nrfutil/moduleVersion.ts +22 -2
- package/nrfutil/sandbox.ts +52 -32
- package/nrfutil/sandboxTypes.ts +15 -1
- package/package.json +3 -2
- package/scripts/check-app-properties.ts +6 -6
- package/scripts/esbuild.ts +3 -3
- package/scripts/nordic-publish.js +23 -23
- package/scripts/nordic-publish.ts +3 -3
- package/scripts/release-shared.ts +2 -2
- package/src/About/ApplicationCard.tsx +3 -5
- package/src/About/DeviceCard.tsx +6 -5
- package/src/About/SupportCard.tsx +2 -2
- package/src/App/App.test.tsx +7 -0
- package/src/App/App.tsx +14 -27
- package/src/Device/DeviceSelector/BasicDeviceInfo.tsx +12 -6
- package/src/Device/DeviceSelector/DeviceList/AnimatedList.tsx +1 -1
- package/src/Device/DeviceSelector/DeviceList/Device.tsx +7 -5
- package/src/Device/DeviceSelector/DeviceList/DeviceList.tsx +23 -5
- package/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.tsx +7 -6
- package/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.tsx +26 -30
- package/src/Device/DeviceSelector/DeviceList/edit-device-buttons.scss +1 -2
- package/src/Device/DeviceSelector/DeviceSelector.test.tsx +17 -37
- package/src/Device/DeviceSelector/DeviceSelector.tsx +64 -21
- package/src/Device/DeviceSelector/Favorite.tsx +10 -10
- package/src/Device/DeviceSelector/basic-device-info.scss +0 -12
- package/src/Device/deviceInfo/deviceInfo.ts +2 -2
- package/src/Device/deviceLister.ts +111 -59
- package/src/Device/deviceSetup.ts +30 -13
- package/src/Device/deviceSlice.ts +157 -84
- package/src/Device/jprogOperations.ts +56 -27
- package/src/Device/sdfuOperations.ts +25 -31
- package/src/ErrorBoundary/ErrorBoundary.tsx +7 -13
- package/src/Feedback/sendFeedback.ts +2 -4
- package/src/InlineInput/NumberInlineInput.tsx +1 -1
- package/src/InlineInput/NumberInputWithDropdown.tsx +1 -2
- package/src/index.ts +4 -0
- package/src/logging/sendInitialLogMessages.ts +15 -13
- package/src/utils/appDetails.ts +22 -0
- package/src/utils/appDirs.ts +4 -4
- package/src/utils/launcherConfig.ts +17 -0
- package/src/utils/logLibVersions.ts +1 -1
- package/src/utils/packageJson.ts +52 -10
- package/src/utils/persistentStore.ts +21 -14
- package/src/utils/systemReport.ts +4 -6
- package/src/utils/usageData.ts +75 -167
- package/src/utils/usageDataCommon.ts +59 -0
- package/src/utils/usageDataMain.ts +117 -0
- package/src/utils/usageDataRenderer.ts +126 -0
- package/src/utils/useHotKey.ts +2 -2
- package/typings/generated/ipc/launcherConfig.d.ts +14 -0
- package/typings/generated/ipc/launcherConfig.d.ts.map +1 -0
- package/typings/generated/ipc/openWindow.d.ts +10 -4
- package/typings/generated/ipc/openWindow.d.ts.map +1 -1
- package/typings/generated/ipc/schema/packageJson.d.ts +34 -52
- package/typings/generated/ipc/schema/packageJson.d.ts.map +1 -1
- package/typings/generated/main/index.d.ts +8 -2
- package/typings/generated/main/index.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/__mocks__/device.d.ts +1 -0
- package/typings/generated/nrfutil/device/__mocks__/device.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/batch.d.ts +3 -2
- package/typings/generated/nrfutil/device/batch.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/common.d.ts +7 -34
- package/typings/generated/nrfutil/device/common.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/device.d.ts +14 -13
- package/typings/generated/nrfutil/device/device.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/deviceInfo.d.ts +40 -0
- package/typings/generated/nrfutil/device/deviceInfo.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/erase.d.ts +2 -2
- package/typings/generated/nrfutil/device/erase.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/firmwareRead.d.ts +2 -2
- package/typings/generated/nrfutil/device/firmwareRead.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/getCoreInfo.d.ts +2 -2
- package/typings/generated/nrfutil/device/getCoreInfo.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/getFwInfo.d.ts +2 -2
- package/typings/generated/nrfutil/device/getFwInfo.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/getProtectionStatus.d.ts +2 -2
- package/typings/generated/nrfutil/device/getProtectionStatus.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/list.d.ts +3 -3
- package/typings/generated/nrfutil/device/list.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/program.d.ts +2 -2
- package/typings/generated/nrfutil/device/program.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/recover.d.ts +2 -2
- package/typings/generated/nrfutil/device/recover.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/reset.d.ts +2 -2
- package/typings/generated/nrfutil/device/reset.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/setMcuState.d.ts +2 -2
- package/typings/generated/nrfutil/device/setMcuState.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/setProtectionStatus.d.ts +2 -2
- package/typings/generated/nrfutil/device/setProtectionStatus.d.ts.map +1 -1
- package/typings/generated/nrfutil/index.d.ts +2 -1
- package/typings/generated/nrfutil/index.d.ts.map +1 -1
- package/typings/generated/nrfutil/moduleVersion.d.ts +4 -0
- package/typings/generated/nrfutil/moduleVersion.d.ts.map +1 -1
- package/typings/generated/nrfutil/sandbox.d.ts +2 -2
- package/typings/generated/nrfutil/sandbox.d.ts.map +1 -1
- package/typings/generated/nrfutil/sandboxTypes.d.ts +10 -1
- package/typings/generated/nrfutil/sandboxTypes.d.ts.map +1 -1
- package/typings/generated/src/About/ApplicationCard.d.ts.map +1 -1
- package/typings/generated/src/About/DeviceCard.d.ts.map +1 -1
- package/typings/generated/src/App/App.d.ts +0 -1
- package/typings/generated/src/App/App.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/BasicDeviceInfo.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/Device.d.ts +0 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/Device.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/DeviceList.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.d.ts +0 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/Favorite.d.ts +0 -1
- package/typings/generated/src/Device/DeviceSelector/Favorite.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceLister.d.ts +1 -15
- package/typings/generated/src/Device/deviceLister.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceSetup.d.ts +7 -6
- package/typings/generated/src/Device/deviceSetup.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceSlice.d.ts +16 -15
- 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.map +1 -1
- package/typings/generated/src/Feedback/sendFeedback.d.ts.map +1 -1
- package/typings/generated/src/InlineInput/NumberInlineInput.d.ts +1 -1
- package/typings/generated/src/InlineInput/NumberInlineInput.d.ts.map +1 -1
- package/typings/generated/src/InlineInput/NumberInputWithDropdown.d.ts.map +1 -1
- package/typings/generated/src/index.d.ts +3 -1
- package/typings/generated/src/index.d.ts.map +1 -1
- package/typings/generated/src/logging/sendInitialLogMessages.d.ts.map +1 -1
- package/typings/generated/src/utils/appDetails.d.ts +4 -0
- package/typings/generated/src/utils/appDetails.d.ts.map +1 -0
- package/typings/generated/src/utils/appDirs.d.ts +1 -1
- package/typings/generated/src/utils/appDirs.d.ts.map +1 -1
- package/typings/generated/src/utils/launcherConfig.d.ts +4 -0
- package/typings/generated/src/utils/launcherConfig.d.ts.map +1 -0
- package/typings/generated/src/utils/packageJson.d.ts +30 -7
- package/typings/generated/src/utils/packageJson.d.ts.map +1 -1
- package/typings/generated/src/utils/persistentStore.d.ts +3 -2
- package/typings/generated/src/utils/persistentStore.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 +8 -65
- package/typings/generated/src/utils/usageData.d.ts.map +1 -1
- package/typings/generated/src/utils/usageDataCommon.d.ts +27 -0
- package/typings/generated/src/utils/usageDataCommon.d.ts.map +1 -0
- package/typings/generated/src/utils/usageDataMain.d.ts +10 -0
- package/typings/generated/src/utils/usageDataMain.d.ts.map +1 -0
- package/typings/generated/src/utils/usageDataRenderer.d.ts +10 -0
- package/typings/generated/src/utils/usageDataRenderer.d.ts.map +1 -0
- package/src/Device/DeviceSelector/DeviceList/device.scss +0 -28
- package/src/Device/DeviceSelector/DeviceList/more-device-info.scss +0 -33
- package/src/Device/DeviceSelector/favorite.scss +0 -17
|
@@ -8,7 +8,8 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
|
8
8
|
import type { AutoDetectTypes } from '@serialport/bindings-cpp';
|
|
9
9
|
import { SerialPortOpenOptions } from 'serialport';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { DeviceInfo } from '../../nrfutil';
|
|
12
|
+
import { NrfutilDevice } from '../../nrfutil/device/common';
|
|
12
13
|
import type { RootState } from '../store';
|
|
13
14
|
import {
|
|
14
15
|
getPersistedIsFavorite,
|
|
@@ -20,65 +21,83 @@ import {
|
|
|
20
21
|
} from '../utils/persistentStore';
|
|
21
22
|
|
|
22
23
|
export interface Device extends NrfutilDevice {
|
|
23
|
-
serialNumber: string;
|
|
24
|
-
boardVersion?: string;
|
|
25
24
|
nickname?: string;
|
|
26
|
-
serialport?: SerialPort;
|
|
27
25
|
favorite?: boolean;
|
|
28
|
-
id: number;
|
|
29
26
|
persistedSerialPortOptions?: SerialPortOpenOptions<AutoDetectTypes>;
|
|
30
27
|
}
|
|
31
28
|
|
|
29
|
+
export interface DeviceWithSerialNumber extends Device {
|
|
30
|
+
serialNumber: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const isDeviceWithSerialNumber = (
|
|
34
|
+
device: Device
|
|
35
|
+
): device is DeviceWithSerialNumber =>
|
|
36
|
+
!!(device as DeviceWithSerialNumber).serialNumber;
|
|
37
|
+
|
|
38
|
+
const findDeviceItem = (
|
|
39
|
+
devices: Device[],
|
|
40
|
+
id: number,
|
|
41
|
+
serialNumber?: string | null
|
|
42
|
+
) => {
|
|
43
|
+
const index = devices.findIndex(
|
|
44
|
+
d => d.id === id || d.serialNumber === serialNumber
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return { index, device: devices[index] };
|
|
48
|
+
};
|
|
49
|
+
|
|
32
50
|
const updateDevice = (
|
|
33
51
|
state: DeviceState,
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
updateToMergeIn: Partial<Device>,
|
|
53
|
+
id: number,
|
|
54
|
+
serialNumber?: string | null
|
|
36
55
|
) => {
|
|
37
|
-
const device = state.devices
|
|
56
|
+
const device = findDeviceItem(state.devices, id, serialNumber).device;
|
|
38
57
|
if (device) {
|
|
39
58
|
Object.assign(device, updateToMergeIn);
|
|
40
59
|
}
|
|
41
60
|
};
|
|
42
61
|
|
|
43
62
|
export interface DeviceState {
|
|
44
|
-
devices:
|
|
45
|
-
deviceInfo: Device | null;
|
|
46
|
-
selectedSerialNumber: string | null;
|
|
63
|
+
devices: Device[];
|
|
47
64
|
readbackProtection: 'unknown' | 'protected' | 'unprotected';
|
|
65
|
+
selectedDevice?: Device;
|
|
66
|
+
selectedDeviceInfo?: DeviceInfo;
|
|
48
67
|
}
|
|
49
68
|
|
|
50
69
|
const initialState: DeviceState = {
|
|
51
|
-
devices:
|
|
52
|
-
selectedSerialNumber: null,
|
|
53
|
-
deviceInfo: null,
|
|
70
|
+
devices: [],
|
|
54
71
|
readbackProtection: 'unknown',
|
|
55
72
|
};
|
|
56
73
|
|
|
57
74
|
const setPersistedData = (device: Device) => {
|
|
58
|
-
|
|
59
|
-
...device
|
|
60
|
-
favorite
|
|
61
|
-
nickname
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
75
|
+
if (device.serialNumber) {
|
|
76
|
+
const newDevice = { ...device };
|
|
77
|
+
newDevice.favorite = getPersistedIsFavorite(device.serialNumber);
|
|
78
|
+
newDevice.nickname = getPersistedNickname(device.serialNumber);
|
|
79
|
+
|
|
80
|
+
const persistedSerialPortSettings = getPersistedSerialPortSettings(
|
|
81
|
+
device.serialNumber
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (persistedSerialPortSettings) {
|
|
85
|
+
const path =
|
|
86
|
+
newDevice.serialPorts?.[persistedSerialPortSettings.vComIndex]
|
|
87
|
+
?.comName;
|
|
88
|
+
|
|
89
|
+
if (path) {
|
|
90
|
+
newDevice.persistedSerialPortOptions = {
|
|
91
|
+
...persistedSerialPortSettings.serialPortOptions,
|
|
92
|
+
path,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
78
95
|
}
|
|
96
|
+
|
|
97
|
+
return newDevice;
|
|
79
98
|
}
|
|
80
99
|
|
|
81
|
-
return
|
|
100
|
+
return device;
|
|
82
101
|
};
|
|
83
102
|
|
|
84
103
|
const slice = createSlice({
|
|
@@ -89,104 +108,158 @@ const slice = createSlice({
|
|
|
89
108
|
* Indicates that a device has been selected.
|
|
90
109
|
*/
|
|
91
110
|
selectDevice: (state, action: PayloadAction<Device>) => {
|
|
92
|
-
state.
|
|
111
|
+
state.selectedDevice = action.payload;
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
setSelectedDeviceInfo: (
|
|
115
|
+
state,
|
|
116
|
+
action: PayloadAction<DeviceInfo | undefined>
|
|
117
|
+
) => {
|
|
118
|
+
state.selectedDeviceInfo = action.payload;
|
|
93
119
|
},
|
|
94
120
|
|
|
95
121
|
/*
|
|
96
122
|
* Indicates that the currently selected device has been deselected.
|
|
97
123
|
*/
|
|
98
124
|
deselectDevice: state => {
|
|
99
|
-
state.
|
|
100
|
-
state.
|
|
125
|
+
state.selectedDevice = undefined;
|
|
126
|
+
state.selectedDeviceInfo = undefined;
|
|
101
127
|
state.readbackProtection = 'unknown';
|
|
102
128
|
},
|
|
103
129
|
|
|
104
130
|
addDevice: (state, action: PayloadAction<Device>) => {
|
|
105
|
-
state.devices.
|
|
106
|
-
|
|
107
|
-
|
|
131
|
+
const index = state.devices.findIndex(
|
|
132
|
+
item =>
|
|
133
|
+
item.serialNumber === action.payload.serialNumber ||
|
|
134
|
+
item.id === action.payload.id
|
|
108
135
|
);
|
|
136
|
+
|
|
137
|
+
const device = setPersistedData(action.payload);
|
|
138
|
+
if (index !== -1) {
|
|
139
|
+
state.devices[index] = device;
|
|
140
|
+
} else {
|
|
141
|
+
state.devices.push(device);
|
|
142
|
+
}
|
|
109
143
|
},
|
|
110
144
|
|
|
111
145
|
persistSerialPortOptions: (
|
|
112
146
|
state,
|
|
113
147
|
action: PayloadAction<SerialPortOpenOptions<AutoDetectTypes>>
|
|
114
148
|
) => {
|
|
115
|
-
if (state.
|
|
149
|
+
if (!state.selectedDevice) return;
|
|
116
150
|
|
|
117
|
-
const selectedDevice = state.
|
|
118
|
-
state.selectedSerialNumber
|
|
119
|
-
);
|
|
151
|
+
const selectedDevice = state.selectedDevice;
|
|
120
152
|
|
|
121
153
|
if (selectedDevice) {
|
|
122
154
|
const vComIndex = selectedDevice.serialPorts?.findIndex(
|
|
123
155
|
e => e.comName === action.payload.path
|
|
124
156
|
);
|
|
125
157
|
|
|
126
|
-
if (
|
|
158
|
+
if (
|
|
159
|
+
selectedDevice.serialNumber && // we want to disregard comparing devices with no sn
|
|
160
|
+
vComIndex !== undefined &&
|
|
161
|
+
vComIndex !== -1
|
|
162
|
+
) {
|
|
127
163
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- used to filter out the path property
|
|
128
164
|
const { path: _, ...serialPortOptions } = action.payload;
|
|
129
165
|
|
|
130
166
|
persistSerialPortSettingsToStore(
|
|
131
|
-
|
|
167
|
+
selectedDevice.serialNumber,
|
|
132
168
|
{
|
|
133
169
|
serialPortOptions,
|
|
134
170
|
vComIndex,
|
|
135
171
|
}
|
|
136
172
|
);
|
|
137
173
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
174
|
+
updateDevice(
|
|
175
|
+
state,
|
|
176
|
+
{
|
|
177
|
+
...selectedDevice,
|
|
178
|
+
persistedSerialPortOptions: action.payload,
|
|
179
|
+
},
|
|
180
|
+
selectedDevice.id,
|
|
181
|
+
selectedDevice.serialNumber
|
|
182
|
+
);
|
|
142
183
|
}
|
|
143
184
|
}
|
|
144
185
|
},
|
|
145
186
|
|
|
146
187
|
removeDevice: (state, action: PayloadAction<Device>) => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
188
|
+
const index = findDeviceItem(
|
|
189
|
+
state.devices,
|
|
190
|
+
action.payload.id,
|
|
191
|
+
action.payload.serialNumber
|
|
192
|
+
).index;
|
|
193
|
+
state.devices.splice(index, 1);
|
|
194
|
+
|
|
195
|
+
if (action.payload.id === state.selectedDevice?.id) {
|
|
196
|
+
state.selectedDevice = undefined;
|
|
197
|
+
state.selectedDeviceInfo = undefined;
|
|
152
198
|
}
|
|
153
199
|
},
|
|
154
200
|
|
|
155
|
-
toggleDeviceFavorited: (state, action: PayloadAction<
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
201
|
+
toggleDeviceFavorited: (state, action: PayloadAction<Device>) => {
|
|
202
|
+
const device = findDeviceItem(
|
|
203
|
+
state.devices,
|
|
204
|
+
action.payload.id,
|
|
205
|
+
action.payload.serialNumber
|
|
206
|
+
).device;
|
|
207
|
+
|
|
208
|
+
if (!device.serialNumber) return;
|
|
209
|
+
|
|
210
|
+
const newFavoriteState = !device.favorite;
|
|
211
|
+
|
|
212
|
+
persistIsFavorite(device.serialNumber, newFavoriteState);
|
|
213
|
+
updateDevice(
|
|
214
|
+
state,
|
|
215
|
+
{
|
|
216
|
+
favorite: newFavoriteState,
|
|
217
|
+
},
|
|
218
|
+
action.payload.id,
|
|
219
|
+
action.payload.serialNumber
|
|
220
|
+
);
|
|
162
221
|
},
|
|
163
222
|
|
|
164
223
|
setDeviceNickname: {
|
|
165
|
-
prepare: (
|
|
166
|
-
payload: {
|
|
224
|
+
prepare: (device: Device, nickname: string) => ({
|
|
225
|
+
payload: { device, nickname },
|
|
167
226
|
}),
|
|
168
227
|
reducer: (
|
|
169
228
|
state,
|
|
170
229
|
action: PayloadAction<{
|
|
171
|
-
|
|
230
|
+
device: Device;
|
|
172
231
|
nickname: string;
|
|
173
232
|
}>
|
|
174
233
|
) => {
|
|
234
|
+
if (!action.payload.device.serialNumber) return;
|
|
235
|
+
|
|
175
236
|
persistNickname(
|
|
176
|
-
action.payload.serialNumber,
|
|
237
|
+
action.payload.device.serialNumber,
|
|
177
238
|
action.payload.nickname
|
|
178
239
|
);
|
|
179
|
-
updateDevice(
|
|
180
|
-
|
|
181
|
-
|
|
240
|
+
updateDevice(
|
|
241
|
+
state,
|
|
242
|
+
{
|
|
243
|
+
nickname: action.payload.nickname,
|
|
244
|
+
},
|
|
245
|
+
action.payload.device.id,
|
|
246
|
+
action.payload.device.serialNumber
|
|
247
|
+
);
|
|
182
248
|
},
|
|
183
249
|
},
|
|
184
250
|
|
|
185
|
-
resetDeviceNickname: (state, action: PayloadAction<
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
251
|
+
resetDeviceNickname: (state, action: PayloadAction<Device>) => {
|
|
252
|
+
if (!action.payload.serialNumber) return;
|
|
253
|
+
|
|
254
|
+
persistNickname(action.payload.serialNumber, '');
|
|
255
|
+
updateDevice(
|
|
256
|
+
state,
|
|
257
|
+
{
|
|
258
|
+
nickname: '',
|
|
259
|
+
},
|
|
260
|
+
action.payload.id,
|
|
261
|
+
action.payload.serialNumber
|
|
262
|
+
);
|
|
190
263
|
},
|
|
191
264
|
|
|
192
265
|
setReadbackProtected: (
|
|
@@ -204,6 +277,7 @@ export const {
|
|
|
204
277
|
deselectDevice,
|
|
205
278
|
resetDeviceNickname,
|
|
206
279
|
selectDevice,
|
|
280
|
+
setSelectedDeviceInfo,
|
|
207
281
|
addDevice,
|
|
208
282
|
removeDevice,
|
|
209
283
|
setDeviceNickname,
|
|
@@ -213,22 +287,21 @@ export const {
|
|
|
213
287
|
},
|
|
214
288
|
} = slice;
|
|
215
289
|
|
|
216
|
-
export const getDevice = (
|
|
217
|
-
state.device.devices.
|
|
290
|
+
export const getDevice = (state: RootState, serialNumber: string) =>
|
|
291
|
+
state.device.devices.find(d => d.serialNumber === serialNumber);
|
|
218
292
|
|
|
219
293
|
export const getDevices = (state: RootState) => state.device.devices;
|
|
220
294
|
|
|
221
295
|
export const deviceIsSelected = (state: RootState) =>
|
|
222
|
-
state.device.
|
|
296
|
+
!!state.device.selectedDevice;
|
|
297
|
+
|
|
298
|
+
export const selectedDevice = (state: RootState) => state.device.selectedDevice;
|
|
223
299
|
|
|
224
|
-
export const
|
|
225
|
-
state.device.
|
|
226
|
-
? state.device.devices.get(state.device.selectedSerialNumber)
|
|
227
|
-
: undefined;
|
|
300
|
+
export const selectedDeviceInfo = (state: RootState) =>
|
|
301
|
+
state.device.selectedDevice ? state.device.selectedDeviceInfo : undefined;
|
|
228
302
|
|
|
229
|
-
export const deviceInfo = (state: RootState) => state.device.deviceInfo;
|
|
230
303
|
export const selectedSerialNumber = (state: RootState) =>
|
|
231
|
-
state.device.
|
|
304
|
+
state.device.selectedDevice?.serialNumber;
|
|
232
305
|
|
|
233
306
|
export const getReadbackProtection = (state: RootState) =>
|
|
234
307
|
state.device.readbackProtection;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import NrfutilDeviceLib from '../../nrfutil/device/device';
|
|
8
|
+
import { DeviceInfo } from '../../nrfutil/device/deviceInfo';
|
|
8
9
|
import { FWInfo } from '../../nrfutil/device/getFwInfo';
|
|
9
10
|
import logger from '../logging';
|
|
10
11
|
import type { AppThunk, RootState } from '../store';
|
|
@@ -18,14 +19,15 @@ const getDeviceReadProtection = async (
|
|
|
18
19
|
readbackProtection: 'unknown' | 'protected' | 'unprotected';
|
|
19
20
|
}> => {
|
|
20
21
|
try {
|
|
22
|
+
logger.info('Checking readback protection on device');
|
|
21
23
|
const info = await NrfutilDeviceLib.getFwInfo(device);
|
|
22
24
|
return {
|
|
23
25
|
fwInfo: info,
|
|
24
26
|
readbackProtection: 'unprotected',
|
|
25
27
|
};
|
|
26
|
-
} catch (
|
|
27
|
-
|
|
28
|
-
if (error.
|
|
28
|
+
} catch (e) {
|
|
29
|
+
const error = e as Error;
|
|
30
|
+
if (error.message.includes('NotAvailableBecauseProtection')) {
|
|
29
31
|
logger.warn(
|
|
30
32
|
'Readback protection on device enabled. Unable to verify that the firmware version is correct.'
|
|
31
33
|
);
|
|
@@ -49,29 +51,50 @@ const programDeviceWithFw =
|
|
|
49
51
|
): AppThunk<RootState, Promise<Device>> =>
|
|
50
52
|
async (dispatch, getState) => {
|
|
51
53
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
const batch = NrfutilDeviceLib.batch();
|
|
55
|
+
if (getState().device.readbackProtection !== 'unprotected') {
|
|
56
|
+
batch.recover('Application', {
|
|
57
|
+
onTaskBegin: () =>
|
|
58
|
+
logger.info(`Device protected, recovering device`),
|
|
59
|
+
onTaskEnd: () => logger.info(`Finished recovering device.`),
|
|
60
|
+
onException: () =>
|
|
61
|
+
logger.error(`Failed to recover device.`),
|
|
62
|
+
onProgress: progress => {
|
|
63
|
+
onProgress(
|
|
64
|
+
progress.totalProgressPercentage,
|
|
65
|
+
'Recovering device'
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
});
|
|
56
69
|
}
|
|
57
70
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
selectedFw.fw,
|
|
64
|
-
progress => {
|
|
71
|
+
batch.program(selectedFw.fw, 'Application', undefined, undefined, {
|
|
72
|
+
onTaskBegin: () => logger.info(`Programming device`),
|
|
73
|
+
onTaskEnd: () => logger.info(`Finished programming device.`),
|
|
74
|
+
onException: () => logger.error(`Failed to program device.`),
|
|
75
|
+
onProgress: progress => {
|
|
65
76
|
onProgress(
|
|
66
77
|
progress.totalProgressPercentage,
|
|
67
78
|
progress.message ?? 'programming'
|
|
68
79
|
);
|
|
69
80
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
batch.reset('Application', undefined, {
|
|
84
|
+
onTaskBegin: () => logger.info(`Resting device`),
|
|
85
|
+
onTaskEnd: () => logger.info(`Finished resting device.`),
|
|
86
|
+
onException: () => logger.error(`Failed to reset device.`),
|
|
87
|
+
onProgress: progress => {
|
|
88
|
+
onProgress(
|
|
89
|
+
progress.totalProgressPercentage,
|
|
90
|
+
'Resetting device'
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await batch.run(device);
|
|
74
96
|
await NrfutilDeviceLib.reset(device);
|
|
97
|
+
onProgress(0, 'Updating readback protection');
|
|
75
98
|
const { readbackProtection } = await getDeviceReadProtection(
|
|
76
99
|
device
|
|
77
100
|
);
|
|
@@ -88,12 +111,18 @@ const programDeviceWithFw =
|
|
|
88
111
|
return device;
|
|
89
112
|
};
|
|
90
113
|
|
|
91
|
-
const firmwareOptions = (
|
|
114
|
+
const firmwareOptions = (
|
|
115
|
+
device: Device,
|
|
116
|
+
firmware: JprogEntry[],
|
|
117
|
+
deviceInfo?: DeviceInfo
|
|
118
|
+
) =>
|
|
92
119
|
firmware.filter(fw => {
|
|
93
|
-
const family = (device.
|
|
94
|
-
const deviceType = (
|
|
120
|
+
const family = (device.devkit?.deviceFamily || '').toLowerCase();
|
|
121
|
+
const deviceType = (
|
|
122
|
+
deviceInfo?.jlink?.deviceVersion || ''
|
|
123
|
+
).toLowerCase();
|
|
95
124
|
const shortDeviceType = deviceType.split('_').shift();
|
|
96
|
-
const boardVersion = (device.
|
|
125
|
+
const boardVersion = (device.devkit?.boardVersion || '').toLowerCase();
|
|
97
126
|
|
|
98
127
|
const key = fw.key.toLowerCase();
|
|
99
128
|
return (
|
|
@@ -108,11 +137,11 @@ export const jprogDeviceSetup = (
|
|
|
108
137
|
firmware: JprogEntry[],
|
|
109
138
|
needSerialport = false
|
|
110
139
|
): DeviceSetup => ({
|
|
111
|
-
supportsProgrammingMode:
|
|
140
|
+
supportsProgrammingMode: device =>
|
|
112
141
|
(needSerialport === !!device.traits.serialPorts || !needSerialport) &&
|
|
113
142
|
!!device.traits.jlink,
|
|
114
|
-
getFirmwareOptions: device =>
|
|
115
|
-
firmwareOptions(device, firmware).map(firmwareOption => ({
|
|
143
|
+
getFirmwareOptions: (device, deviceInfo) =>
|
|
144
|
+
firmwareOptions(device, firmware, deviceInfo).map(firmwareOption => ({
|
|
116
145
|
key: firmwareOption.key,
|
|
117
146
|
description: firmwareOption.description,
|
|
118
147
|
programDevice: onProgress => dispatch =>
|
|
@@ -120,8 +149,8 @@ export const jprogDeviceSetup = (
|
|
|
120
149
|
programDeviceWithFw(device, firmwareOption, onProgress)
|
|
121
150
|
),
|
|
122
151
|
})),
|
|
123
|
-
isExpectedFirmware: (device
|
|
124
|
-
const fwVersions = firmwareOptions(device, firmware);
|
|
152
|
+
isExpectedFirmware: (device, deviceInfo) => dispatch => {
|
|
153
|
+
const fwVersions = firmwareOptions(device, firmware, deviceInfo);
|
|
125
154
|
if (fwVersions.length === 0) {
|
|
126
155
|
return Promise.resolve({
|
|
127
156
|
device,
|
|
@@ -46,8 +46,9 @@ export const isDeviceInDFUBootloader = (device: Device) => {
|
|
|
46
46
|
d.idProduct === NORDIC_DFU_PRODUCT_ID
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
|
|
50
|
+
if (device.serialPorts && device.serialPorts[0]) {
|
|
51
|
+
const { vendorId, productId } = device.serialPorts[0];
|
|
51
52
|
return vendorId === '1915' && productId?.toUpperCase() === '521F';
|
|
52
53
|
}
|
|
53
54
|
return false;
|
|
@@ -410,9 +411,7 @@ const programInDFUBootloader =
|
|
|
410
411
|
onFail: (reason?: unknown) => void
|
|
411
412
|
): AppThunk<RootState, Promise<void>> =>
|
|
412
413
|
async dispatch => {
|
|
413
|
-
logger.debug(
|
|
414
|
-
`${device.serialNumber} on ${device.serialport?.comName} is now in DFU-Bootloader...`
|
|
415
|
-
);
|
|
414
|
+
logger.debug(`${device.serialNumber} on is now in DFU-Bootloader...`);
|
|
416
415
|
const { application, softdevice } = dfu;
|
|
417
416
|
const params: Partial<InitPacket> = dfu.params || {};
|
|
418
417
|
|
|
@@ -545,9 +544,9 @@ export const sdfuDeviceSetup = (
|
|
|
545
544
|
dfuFirmware: DfuEntry[],
|
|
546
545
|
needSerialport = false
|
|
547
546
|
): DeviceSetup => ({
|
|
548
|
-
supportsProgrammingMode: (device
|
|
549
|
-
((!!
|
|
550
|
-
|
|
547
|
+
supportsProgrammingMode: (device, deviceInfo) =>
|
|
548
|
+
((!!deviceInfo?.dfuTriggerVersion &&
|
|
549
|
+
deviceInfo.dfuTriggerVersion.semVer.length > 0) ||
|
|
551
550
|
isDeviceInDFUBootloader(device)) &&
|
|
552
551
|
(needSerialport === device.traits.serialPorts || !needSerialport),
|
|
553
552
|
getFirmwareOptions: device =>
|
|
@@ -559,31 +558,26 @@ export const sdfuDeviceSetup = (
|
|
|
559
558
|
programDeviceWithFw(device, firmwareOption, onProgress)
|
|
560
559
|
),
|
|
561
560
|
})),
|
|
562
|
-
isExpectedFirmware: (device
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
if (device.dfuTriggerVersion) {
|
|
568
|
-
logger.debug(
|
|
569
|
-
'Device has DFU trigger interface, the device is in Application mode'
|
|
570
|
-
);
|
|
561
|
+
isExpectedFirmware: (device, deviceInfo) => () => {
|
|
562
|
+
if (deviceInfo?.dfuTriggerVersion) {
|
|
563
|
+
logger.debug(
|
|
564
|
+
'Device has DFU trigger interface, the device is in Application mode'
|
|
565
|
+
);
|
|
571
566
|
|
|
572
|
-
|
|
567
|
+
const { semVer } = deviceInfo.dfuTriggerVersion;
|
|
573
568
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
}),
|
|
569
|
+
return Promise.resolve({
|
|
570
|
+
device,
|
|
571
|
+
validFirmware:
|
|
572
|
+
dfuFirmware.filter(fw => fw.semver === semVer).length > 0,
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return Promise.resolve({
|
|
577
|
+
device,
|
|
578
|
+
validFirmware: false,
|
|
579
|
+
});
|
|
580
|
+
},
|
|
587
581
|
tryToSwitchToApplicationMode: device => dispatch =>
|
|
588
582
|
new Promise<Device>((resolve, reject) => {
|
|
589
583
|
dispatch(switchToApplicationMode(device, resolve, reject));
|
|
@@ -13,27 +13,20 @@ import FactoryResetButton from '../FactoryReset/FactoryResetButton';
|
|
|
13
13
|
import { CollapsibleGroup } from '../SidePanel/Group';
|
|
14
14
|
import Spinner from '../Spinner/Spinner';
|
|
15
15
|
import { openUrl } from '../utils/open';
|
|
16
|
-
import packageJson from '../utils/packageJson';
|
|
16
|
+
import { packageJson } from '../utils/packageJson';
|
|
17
17
|
import { getAppSpecificStore as store } from '../utils/persistentStore';
|
|
18
18
|
import { generateSystemReport } from '../utils/systemReport';
|
|
19
|
-
import
|
|
20
|
-
init as initGA,
|
|
21
|
-
isEnabled,
|
|
22
|
-
isInitialized as isGAInitialized,
|
|
23
|
-
sendErrorReport,
|
|
24
|
-
} from '../utils/usageData';
|
|
19
|
+
import usageData from '../utils/usageData';
|
|
25
20
|
import bugIcon from './bug.svg';
|
|
26
21
|
|
|
27
22
|
import './error-boundary.scss';
|
|
28
23
|
|
|
29
24
|
const sendGAEvent = (error: string) => {
|
|
30
|
-
if (!isEnabled()) {
|
|
25
|
+
if (!usageData.isEnabled()) {
|
|
31
26
|
return;
|
|
32
27
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
sendErrorReport(error);
|
|
28
|
+
|
|
29
|
+
usageData.sendErrorReport(error);
|
|
37
30
|
};
|
|
38
31
|
|
|
39
32
|
interface Props {
|
|
@@ -97,7 +90,8 @@ class ErrorBoundary extends React.Component<
|
|
|
97
90
|
return children;
|
|
98
91
|
}
|
|
99
92
|
|
|
100
|
-
const appDisplayName =
|
|
93
|
+
const appDisplayName =
|
|
94
|
+
appName || packageJson().displayName || packageJson().name;
|
|
101
95
|
|
|
102
96
|
return (
|
|
103
97
|
<div className="error-boundary__container">
|
|
@@ -5,18 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { isDevelopment } from '../utils/environment';
|
|
8
|
-
import packageJson from '../utils/packageJson';
|
|
8
|
+
import { packageJson } from '../utils/packageJson';
|
|
9
9
|
|
|
10
10
|
const formURL =
|
|
11
11
|
isDevelopment === true
|
|
12
12
|
? 'https://formkeep.com/f/87deb409a565'
|
|
13
13
|
: 'https://formkeep.com/f/36b394b92851';
|
|
14
14
|
|
|
15
|
-
const getAppName = () => packageJson().name;
|
|
16
|
-
|
|
17
15
|
export default async (feedback: string, category?: string) => {
|
|
18
16
|
const data: Record<string, unknown> = {
|
|
19
|
-
name:
|
|
17
|
+
name: packageJson().name,
|
|
20
18
|
feedback,
|
|
21
19
|
platform: process.platform,
|
|
22
20
|
};
|