@onekeyfe/hd-core 1.2.0-alpha.48 → 1.2.0-alpha.49
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/__tests__/check-all-firmware-release-protocol-v2.test.ts +4 -4
- package/__tests__/device-lifecycle-events.test.ts +105 -3
- package/__tests__/method-protocol-support.test.ts +19 -0
- package/__tests__/protocol-binding.test.ts +89 -0
- package/__tests__/protocol-v2.test.ts +274 -6
- package/__tests__/search-devices.test.ts +12 -3
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +1 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/device/Device.d.ts +5 -1
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/index.d.ts +19 -2
- package/dist/index.js +238 -105
- package/dist/inject.d.ts +6 -1
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +4 -0
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/params.d.ts +1 -0
- package/dist/types/params.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +5 -3
- package/src/api/DetectDeviceConnectProtocol.ts +18 -0
- package/src/api/FirmwareUpdate.ts +6 -2
- package/src/api/FirmwareUpdateV2.ts +5 -2
- package/src/api/FirmwareUpdateV3.ts +6 -2
- package/src/api/FirmwareUpdateV4.ts +68 -40
- package/src/api/SearchDevices.ts +3 -1
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +15 -4
- package/src/api/firmware/uploadFirmware.ts +17 -4
- package/src/api/index.ts +1 -0
- package/src/core/index.ts +11 -2
- package/src/device/Device.ts +53 -15
- package/src/device/DevicePool.ts +7 -2
- package/src/inject.ts +57 -2
- package/src/lowLevelInject.ts +6 -3
- package/src/topLevelInject.ts +6 -3
- package/src/types/api/detectDeviceConnectProtocol.ts +7 -0
- package/src/types/api/index.ts +11 -0
- package/src/types/params.ts +7 -1
|
@@ -291,7 +291,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
291
291
|
expect(result.targetsToUpdate).toEqual(['app_v1', 'app_v2']);
|
|
292
292
|
});
|
|
293
293
|
|
|
294
|
-
test('
|
|
294
|
+
test('does not read vol0 resource inventory while Protocol V2 is in Application mode', async () => {
|
|
295
295
|
const method = new CheckAllFirmwareRelease({
|
|
296
296
|
id: 1,
|
|
297
297
|
payload: {
|
|
@@ -325,13 +325,13 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
325
325
|
protocol: 'V2',
|
|
326
326
|
deviceType: 'pro2',
|
|
327
327
|
status: 'required',
|
|
328
|
-
resourceStatus: '
|
|
329
|
-
targetsToUpdate: ['boot', 'app_v1'
|
|
328
|
+
resourceStatus: 'unknown',
|
|
329
|
+
targetsToUpdate: ['boot', 'app_v1'],
|
|
330
330
|
firmware: {
|
|
331
331
|
status: 'required',
|
|
332
332
|
},
|
|
333
333
|
});
|
|
334
|
-
expect(typedCall.
|
|
334
|
+
expect(typedCall).not.toHaveBeenCalled();
|
|
335
335
|
expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
336
336
|
});
|
|
337
337
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
1
2
|
import { TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
|
|
2
3
|
|
|
3
4
|
import { initConnector, initCore } from '../src/core';
|
|
@@ -95,7 +96,7 @@ describe('public device lifecycle events', () => {
|
|
|
95
96
|
expect(messages.filter(message => message.type === DEVICE.DISCONNECT)).toHaveLength(1);
|
|
96
97
|
});
|
|
97
98
|
|
|
98
|
-
test('uses a cached protocol as a
|
|
99
|
+
test('uses a verified cached protocol as a strict expected protocol', async () => {
|
|
99
100
|
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
100
101
|
const device = Device.fromDescriptor({
|
|
101
102
|
id: 'ble-id',
|
|
@@ -103,16 +104,117 @@ describe('public device lifecycle events', () => {
|
|
|
103
104
|
commType: 'ble',
|
|
104
105
|
protocolType: 'V1',
|
|
105
106
|
} as never);
|
|
106
|
-
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: '
|
|
107
|
+
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V1' });
|
|
107
108
|
device.deviceConnector = { acquire } as never;
|
|
108
109
|
|
|
109
110
|
await device.acquire();
|
|
110
111
|
|
|
111
|
-
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true,
|
|
112
|
+
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, 'V1', undefined);
|
|
113
|
+
expect(device.getProtocol()).toBe('V1');
|
|
114
|
+
expect(device.originalDescriptor.protocolType).toBe('V1');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('bypasses a cached protocol only for explicit active detection', async () => {
|
|
118
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
119
|
+
const device = Device.fromDescriptor({
|
|
120
|
+
id: 'ble-id',
|
|
121
|
+
path: 'ble-id',
|
|
122
|
+
commType: 'ble',
|
|
123
|
+
protocolType: 'V1',
|
|
124
|
+
} as never);
|
|
125
|
+
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V2' });
|
|
126
|
+
device.deviceConnector = { acquire } as never;
|
|
127
|
+
|
|
128
|
+
await device.acquire(undefined, { forceProtocolDetection: true });
|
|
129
|
+
|
|
130
|
+
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, undefined, undefined);
|
|
112
131
|
expect(device.getProtocol()).toBe('V2');
|
|
113
132
|
expect(device.originalDescriptor.protocolType).toBe('V2');
|
|
114
133
|
});
|
|
115
134
|
|
|
135
|
+
test('does not reuse a stale protocol when active detection returns no protocol', async () => {
|
|
136
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
137
|
+
const device = Device.fromDescriptor({
|
|
138
|
+
id: 'ble-id',
|
|
139
|
+
path: 'ble-id',
|
|
140
|
+
commType: 'ble',
|
|
141
|
+
protocolType: 'V1',
|
|
142
|
+
} as never);
|
|
143
|
+
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id' });
|
|
144
|
+
const release = jest.fn().mockResolvedValue(undefined);
|
|
145
|
+
device.deviceConnector = { acquire, release } as never;
|
|
146
|
+
await expect(
|
|
147
|
+
device.acquire(undefined, {
|
|
148
|
+
forceProtocolDetection: true,
|
|
149
|
+
throwOnRunPromiseError: true,
|
|
150
|
+
})
|
|
151
|
+
).rejects.toMatchObject({ errorCode: HardwareErrorCode.RuntimeError });
|
|
152
|
+
expect(device.originalDescriptor.protocolType).toBe('V1');
|
|
153
|
+
expect(device.hasDeviceAcquire()).toBe(false);
|
|
154
|
+
expect(release).toHaveBeenCalledWith('ble-id', false);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test('actively reacquires an already connected device without initializing it', async () => {
|
|
158
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('webusb' as never);
|
|
159
|
+
const device = Device.fromDescriptor({
|
|
160
|
+
id: 'usb-device',
|
|
161
|
+
path: 'usb-device',
|
|
162
|
+
session: 'old-session',
|
|
163
|
+
protocolType: 'V1',
|
|
164
|
+
} as never);
|
|
165
|
+
device.mainId = 'old-session';
|
|
166
|
+
device.commands = { disposed: false } as never;
|
|
167
|
+
const release = jest.spyOn(device, 'release').mockImplementation(() => {
|
|
168
|
+
device.mainId = null;
|
|
169
|
+
device.originalDescriptor.session = null;
|
|
170
|
+
device.commands.disposed = true;
|
|
171
|
+
return Promise.resolve();
|
|
172
|
+
});
|
|
173
|
+
const acquire = jest.spyOn(device, 'acquire').mockImplementation(() => {
|
|
174
|
+
device.mainId = 'new-session';
|
|
175
|
+
device.originalDescriptor.session = 'new-session';
|
|
176
|
+
device.originalDescriptor.protocolType = 'V2';
|
|
177
|
+
device.commands.disposed = false;
|
|
178
|
+
return Promise.resolve();
|
|
179
|
+
});
|
|
180
|
+
const initialize = jest.spyOn(device, 'initialize').mockResolvedValue(undefined);
|
|
181
|
+
|
|
182
|
+
await device.run(() => Promise.resolve(undefined), {
|
|
183
|
+
forceProtocolDetection: true,
|
|
184
|
+
skipInitialize: true,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
expect(release).toHaveBeenCalled();
|
|
188
|
+
expect(acquire).toHaveBeenCalledWith(undefined, {
|
|
189
|
+
forceProtocolDetection: true,
|
|
190
|
+
});
|
|
191
|
+
expect(initialize).not.toHaveBeenCalled();
|
|
192
|
+
expect(device.getProtocol()).toBe('V2');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('keeps the freshly probed React Native BLE session until the call completes', async () => {
|
|
196
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
197
|
+
const device = Device.fromDescriptor({
|
|
198
|
+
id: 'ble-device',
|
|
199
|
+
path: 'ble-device',
|
|
200
|
+
commType: 'ble',
|
|
201
|
+
protocolType: 'V1',
|
|
202
|
+
} as never);
|
|
203
|
+
device.mainId = 'ble-device';
|
|
204
|
+
device.commands = { disposed: false } as never;
|
|
205
|
+
(device as unknown as { deviceAcquired: boolean }).deviceAcquired = true;
|
|
206
|
+
const release = jest.spyOn(device, 'release').mockResolvedValue(undefined);
|
|
207
|
+
const run = jest.fn().mockResolvedValue(undefined);
|
|
208
|
+
|
|
209
|
+
await device.run(run, {
|
|
210
|
+
forceProtocolDetection: true,
|
|
211
|
+
skipInitialize: true,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(run).toHaveBeenCalledTimes(1);
|
|
215
|
+
expect(release).toHaveBeenCalledTimes(1);
|
|
216
|
+
});
|
|
217
|
+
|
|
116
218
|
test('keeps an explicit connectProtocol as a strict expected protocol', async () => {
|
|
117
219
|
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
118
220
|
const device = Device.fromDescriptor({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EFirmwareType, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
3
|
import { BaseMethod } from '../src/api/BaseMethod';
|
|
4
|
+
import { findMethod } from '../src/api/utils';
|
|
4
5
|
import BTCGetAddress from '../src/api/btc/BTCGetAddress';
|
|
5
6
|
import DeviceReboot from '../src/api/protocol-v2/DeviceReboot';
|
|
6
7
|
import SolGetAddress from '../src/api/solana/SolGetAddress';
|
|
@@ -20,6 +21,24 @@ class DefaultMethod extends BaseMethod {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
describe('method protocol support', () => {
|
|
24
|
+
test('creates a protocol detection method that returns only the current protocol', async () => {
|
|
25
|
+
const method = findMethod({
|
|
26
|
+
id: 6,
|
|
27
|
+
payload: {
|
|
28
|
+
method: 'detectDeviceConnectProtocol',
|
|
29
|
+
connectId: 'ble-device',
|
|
30
|
+
},
|
|
31
|
+
} as never);
|
|
32
|
+
|
|
33
|
+
method.init();
|
|
34
|
+
(method as unknown as { device: unknown }).device = {
|
|
35
|
+
getProtocol: () => 'V2',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
39
|
+
await expect(method.run()).resolves.toBe('V2');
|
|
40
|
+
});
|
|
41
|
+
|
|
23
42
|
test('defaults existing methods to Protocol V1 only', () => {
|
|
24
43
|
const method = new DefaultMethod({
|
|
25
44
|
id: 1,
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createCoreApi, createProtocolAwareCall } from '../src/inject';
|
|
2
|
+
|
|
3
|
+
import type { CoreApi } from '../src/types/api';
|
|
4
|
+
|
|
5
|
+
describe('SDK protocol binding', () => {
|
|
6
|
+
test('exposes a minimal API that returns the actively detected protocol', async () => {
|
|
7
|
+
const response = { success: true as const, payload: 'V2' as const };
|
|
8
|
+
const rawCall = jest.fn().mockResolvedValue(response);
|
|
9
|
+
const api = createCoreApi(rawCall as CoreApi['call']);
|
|
10
|
+
|
|
11
|
+
await expect(api.detectDeviceConnectProtocol('USB_DEVICE_A')).resolves.toBe(response);
|
|
12
|
+
expect(rawCall).toHaveBeenCalledWith({
|
|
13
|
+
connectId: 'USB_DEVICE_A',
|
|
14
|
+
forceProtocolDetection: true,
|
|
15
|
+
method: 'detectDeviceConnectProtocol',
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('injects a strict protocol into every later call and isolates devices', async () => {
|
|
20
|
+
const rawCall = jest.fn(params => Promise.resolve({ success: true, payload: params }));
|
|
21
|
+
const protocolAwareCall = createProtocolAwareCall(rawCall as CoreApi['call']);
|
|
22
|
+
const api = createCoreApi(protocolAwareCall.call);
|
|
23
|
+
|
|
24
|
+
protocolAwareCall.setDeviceConnectProtocol('USB_DEVICE_A', 'V2');
|
|
25
|
+
protocolAwareCall.setDeviceConnectProtocol('ble-device-b', 'V1');
|
|
26
|
+
|
|
27
|
+
await api.deviceWipe('usb_device_a');
|
|
28
|
+
await api.deviceSupportFeatures('BLE-DEVICE-B');
|
|
29
|
+
await api.getFeatures('USB_DEVICE_A', { connectProtocol: 'V1' });
|
|
30
|
+
await api.getDeviceState('USB_DEVICE_A', { forceProtocolDetection: true });
|
|
31
|
+
await protocolAwareCall.call({
|
|
32
|
+
connectId: 'USB_DEVICE_A',
|
|
33
|
+
method: 'deviceUpdateReboot',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
expect(rawCall).toHaveBeenNthCalledWith(1, {
|
|
37
|
+
connectId: 'usb_device_a',
|
|
38
|
+
method: 'deviceWipe',
|
|
39
|
+
connectProtocol: 'V2',
|
|
40
|
+
});
|
|
41
|
+
expect(rawCall).toHaveBeenNthCalledWith(2, {
|
|
42
|
+
connectId: 'BLE-DEVICE-B',
|
|
43
|
+
method: 'deviceSupportFeatures',
|
|
44
|
+
connectProtocol: 'V1',
|
|
45
|
+
});
|
|
46
|
+
expect(rawCall).toHaveBeenNthCalledWith(3, {
|
|
47
|
+
connectId: 'USB_DEVICE_A',
|
|
48
|
+
method: 'getFeatures',
|
|
49
|
+
connectProtocol: 'V1',
|
|
50
|
+
});
|
|
51
|
+
expect(rawCall).toHaveBeenNthCalledWith(4, {
|
|
52
|
+
connectId: 'USB_DEVICE_A',
|
|
53
|
+
method: 'getDeviceState',
|
|
54
|
+
forceProtocolDetection: true,
|
|
55
|
+
});
|
|
56
|
+
expect(rawCall).toHaveBeenNthCalledWith(5, {
|
|
57
|
+
connectId: 'USB_DEVICE_A',
|
|
58
|
+
method: 'deviceUpdateReboot',
|
|
59
|
+
connectProtocol: 'V2',
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('keeps bindings local to one SDK instance and supports clearing them', async () => {
|
|
64
|
+
const firstRawCall = jest.fn(() => Promise.resolve({ success: true, payload: {} }));
|
|
65
|
+
const secondRawCall = jest.fn(() => Promise.resolve({ success: true, payload: {} }));
|
|
66
|
+
const first = createProtocolAwareCall(firstRawCall as CoreApi['call']);
|
|
67
|
+
const second = createProtocolAwareCall(secondRawCall as CoreApi['call']);
|
|
68
|
+
|
|
69
|
+
first.setDeviceConnectProtocol('same-device', 'V2');
|
|
70
|
+
await first.call({ connectId: 'same-device', method: 'deviceWipe' });
|
|
71
|
+
await second.call({ connectId: 'same-device', method: 'deviceWipe' });
|
|
72
|
+
first.setDeviceConnectProtocol('same-device', undefined);
|
|
73
|
+
await first.call({ connectId: 'same-device', method: 'deviceWipe' });
|
|
74
|
+
|
|
75
|
+
expect(firstRawCall).toHaveBeenNthCalledWith(1, {
|
|
76
|
+
connectId: 'same-device',
|
|
77
|
+
method: 'deviceWipe',
|
|
78
|
+
connectProtocol: 'V2',
|
|
79
|
+
});
|
|
80
|
+
expect(secondRawCall).toHaveBeenCalledWith({
|
|
81
|
+
connectId: 'same-device',
|
|
82
|
+
method: 'deviceWipe',
|
|
83
|
+
});
|
|
84
|
+
expect(firstRawCall).toHaveBeenNthCalledWith(2, {
|
|
85
|
+
connectId: 'same-device',
|
|
86
|
+
method: 'deviceWipe',
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -3923,6 +3923,68 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3923
3923
|
});
|
|
3924
3924
|
});
|
|
3925
3925
|
|
|
3926
|
+
test('enters Protocol V2 bootloader before reading and downloading remote resources', async () => {
|
|
3927
|
+
const method = new FirmwareUpdateV4({
|
|
3928
|
+
id: 1,
|
|
3929
|
+
payload: {
|
|
3930
|
+
method: 'firmwareUpdateV4',
|
|
3931
|
+
platform: 'web',
|
|
3932
|
+
targetsToUpdate: ['resource'],
|
|
3933
|
+
},
|
|
3934
|
+
});
|
|
3935
|
+
method.init();
|
|
3936
|
+
|
|
3937
|
+
(method as any).device = stubDevice({
|
|
3938
|
+
originalDescriptor: { id: 'usb-id', path: 'app-path', protocolType: 'V2' },
|
|
3939
|
+
features: {
|
|
3940
|
+
deviceType: 'pro2',
|
|
3941
|
+
firmwareVersion: '1.0.0',
|
|
3942
|
+
mode: 'normal',
|
|
3943
|
+
bootloaderMode: false,
|
|
3944
|
+
capabilities: [],
|
|
3945
|
+
},
|
|
3946
|
+
isBootloader: () => false,
|
|
3947
|
+
isRomloader: () => false,
|
|
3948
|
+
});
|
|
3949
|
+
(method as any).captureProtocolV2PhysicalIdentity = jest.fn().mockResolvedValue(undefined);
|
|
3950
|
+
(method as any).prepareRemoteProtocolV2Binaries = jest.fn().mockResolvedValue({
|
|
3951
|
+
bootloaderBinary: null,
|
|
3952
|
+
fwBinaryMap: [],
|
|
3953
|
+
installItems: [],
|
|
3954
|
+
});
|
|
3955
|
+
|
|
3956
|
+
const order: string[] = [];
|
|
3957
|
+
(method as any).enterProtocolV2BootloaderMode = jest.fn().mockImplementation(() => {
|
|
3958
|
+
order.push('enter-bootloader');
|
|
3959
|
+
return Promise.resolve(true);
|
|
3960
|
+
});
|
|
3961
|
+
(method as any).prepareProtocolV2ResourceBundles = jest.fn().mockImplementation(() => {
|
|
3962
|
+
order.push('prepare-resources');
|
|
3963
|
+
return Promise.resolve([
|
|
3964
|
+
{
|
|
3965
|
+
name: 'images.okpkg',
|
|
3966
|
+
binary: new Uint8Array([1]).buffer,
|
|
3967
|
+
devicePath: 'vol0:/bundles/images/images.okpkg',
|
|
3968
|
+
},
|
|
3969
|
+
]);
|
|
3970
|
+
});
|
|
3971
|
+
(method as any).executeProtocolV2Update = jest.fn().mockImplementation(() => {
|
|
3972
|
+
order.push('execute-update');
|
|
3973
|
+
return Promise.resolve();
|
|
3974
|
+
});
|
|
3975
|
+
(method as any).exitProtocolV2BootloaderToNormal = jest.fn().mockResolvedValue(undefined);
|
|
3976
|
+
(method as any).waitForProtocolV2FinalFeatures = jest.fn().mockResolvedValue({
|
|
3977
|
+
bootloaderVersion: '1.0.0',
|
|
3978
|
+
bleVersion: '1.0.0',
|
|
3979
|
+
firmwareVersion: '1.0.0',
|
|
3980
|
+
});
|
|
3981
|
+
method.postTipMessage = jest.fn();
|
|
3982
|
+
|
|
3983
|
+
await method.run();
|
|
3984
|
+
|
|
3985
|
+
expect(order).toEqual(['enter-bootloader', 'prepare-resources', 'execute-update']);
|
|
3986
|
+
});
|
|
3987
|
+
|
|
3926
3988
|
test('reboots Protocol V2 normal-mode device to bootloader before transfer', async () => {
|
|
3927
3989
|
const method = new FirmwareUpdateV4({
|
|
3928
3990
|
id: 1,
|
|
@@ -3972,6 +4034,33 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
3972
4034
|
expect(reconnectProtocolV2Device).toHaveBeenCalledTimes(1);
|
|
3973
4035
|
});
|
|
3974
4036
|
|
|
4037
|
+
test('keeps Protocol V2 bootloader active before firmware transfer', async () => {
|
|
4038
|
+
const method = new FirmwareUpdateV4({
|
|
4039
|
+
id: 1,
|
|
4040
|
+
payload: {
|
|
4041
|
+
method: 'firmwareUpdateV4',
|
|
4042
|
+
},
|
|
4043
|
+
});
|
|
4044
|
+
(method as any).device = stubDevice({
|
|
4045
|
+
originalDescriptor: { id: 'usb-id', path: 'bootloader-path', protocolType: 'V2' },
|
|
4046
|
+
features: {
|
|
4047
|
+
deviceType: 'pro2',
|
|
4048
|
+
mode: 'bootloader',
|
|
4049
|
+
bootloaderMode: true,
|
|
4050
|
+
capabilities: [],
|
|
4051
|
+
},
|
|
4052
|
+
isBootloader: () => true,
|
|
4053
|
+
isRomloader: () => false,
|
|
4054
|
+
});
|
|
4055
|
+
(method as any).protocolV2Reboot = jest.fn();
|
|
4056
|
+
method.postTipMessage = jest.fn();
|
|
4057
|
+
|
|
4058
|
+
await expect((method as any).enterProtocolV2BootloaderMode()).resolves.toBe(false);
|
|
4059
|
+
|
|
4060
|
+
expect((method as any).protocolV2Reboot).not.toHaveBeenCalled();
|
|
4061
|
+
expect(method.postTipMessage).not.toHaveBeenCalledWith('AutoRebootToBootloader');
|
|
4062
|
+
});
|
|
4063
|
+
|
|
3975
4064
|
test('keeps Protocol V2 romloader active before firmware transfer', async () => {
|
|
3976
4065
|
const method = new FirmwareUpdateV4({
|
|
3977
4066
|
id: 1,
|
|
@@ -4039,7 +4128,7 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4039
4128
|
|
|
4040
4129
|
await method.run();
|
|
4041
4130
|
|
|
4042
|
-
expect(prepareResourceBundles).
|
|
4131
|
+
expect(prepareResourceBundles).not.toHaveBeenCalled();
|
|
4043
4132
|
expect((method as any).protocolV2Reboot).not.toHaveBeenCalled();
|
|
4044
4133
|
expect((method as any).executeProtocolV2Update).toHaveBeenCalledWith({
|
|
4045
4134
|
bootloaderBinary: null,
|
|
@@ -4122,7 +4211,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4122
4211
|
getCommands: () => commands,
|
|
4123
4212
|
mainId: 'usb-path',
|
|
4124
4213
|
});
|
|
4125
|
-
const cachedDevice = {
|
|
4214
|
+
const cachedDevice = {
|
|
4215
|
+
getConnectId: () => 'usb-path',
|
|
4216
|
+
getCurrentSerialNo: () => '',
|
|
4217
|
+
};
|
|
4126
4218
|
const getDevices = jest.spyOn(DevicePool, 'getDevices').mockResolvedValue({
|
|
4127
4219
|
devices: {},
|
|
4128
4220
|
deviceList: [cachedDevice],
|
|
@@ -4139,6 +4231,182 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
4139
4231
|
expect(initialize).not.toHaveBeenCalled();
|
|
4140
4232
|
});
|
|
4141
4233
|
|
|
4234
|
+
test('selects the matching physical device from multiple Protocol V2 USB reconnect candidates', async () => {
|
|
4235
|
+
const method = new FirmwareUpdateV4({
|
|
4236
|
+
id: 1,
|
|
4237
|
+
payload: {
|
|
4238
|
+
method: 'firmwareUpdateV4',
|
|
4239
|
+
},
|
|
4240
|
+
});
|
|
4241
|
+
const commands = { disposed: true, mainId: '' };
|
|
4242
|
+
const updateFromCache = jest.fn();
|
|
4243
|
+
const device = stubDevice({
|
|
4244
|
+
originalDescriptor: { id: 'old-usb-id', path: 'old-usb-path', protocolType: 'V2' },
|
|
4245
|
+
deviceConnector: {
|
|
4246
|
+
enumerate: jest.fn().mockResolvedValue({
|
|
4247
|
+
descriptors: [
|
|
4248
|
+
{ id: 'usb-a', path: 'usb-a', protocolType: 'V2' },
|
|
4249
|
+
{ id: 'usb-b', path: 'usb-b', protocolType: 'V2' },
|
|
4250
|
+
],
|
|
4251
|
+
}),
|
|
4252
|
+
},
|
|
4253
|
+
updateFromCache,
|
|
4254
|
+
hasDeviceAcquire: jest.fn(() => false),
|
|
4255
|
+
acquire: jest.fn().mockResolvedValue(undefined),
|
|
4256
|
+
commands,
|
|
4257
|
+
getCommands: () => commands,
|
|
4258
|
+
mainId: 'old-usb-path',
|
|
4259
|
+
});
|
|
4260
|
+
const otherDevice = {
|
|
4261
|
+
getConnectId: () => 'usb-a',
|
|
4262
|
+
getCurrentSerialNo: () => 'PRO2-PHYSICAL-A',
|
|
4263
|
+
};
|
|
4264
|
+
const expectedDevice = {
|
|
4265
|
+
getConnectId: () => 'usb-b',
|
|
4266
|
+
getCurrentSerialNo: () => 'PRO2-PHYSICAL-B',
|
|
4267
|
+
};
|
|
4268
|
+
const getDevices = jest.spyOn(DevicePool, 'getDevices').mockResolvedValue({
|
|
4269
|
+
devices: {},
|
|
4270
|
+
deviceList: [otherDevice, expectedDevice],
|
|
4271
|
+
} as any);
|
|
4272
|
+
(method as any).device = device;
|
|
4273
|
+
(method as any).protocolV2ExpectedSerialNumber = 'PRO2-PHYSICAL-B';
|
|
4274
|
+
|
|
4275
|
+
try {
|
|
4276
|
+
await (method as any).reconnectProtocolV2Device();
|
|
4277
|
+
} finally {
|
|
4278
|
+
getDevices.mockRestore();
|
|
4279
|
+
}
|
|
4280
|
+
|
|
4281
|
+
expect(updateFromCache).toHaveBeenCalledWith(expectedDevice);
|
|
4282
|
+
});
|
|
4283
|
+
|
|
4284
|
+
test('rejects ambiguous Protocol V2 USB reconnect candidates without an identity match', async () => {
|
|
4285
|
+
const method = new FirmwareUpdateV4({
|
|
4286
|
+
id: 1,
|
|
4287
|
+
payload: {
|
|
4288
|
+
method: 'firmwareUpdateV4',
|
|
4289
|
+
},
|
|
4290
|
+
});
|
|
4291
|
+
const updateFromCache = jest.fn();
|
|
4292
|
+
const device = stubDevice({
|
|
4293
|
+
originalDescriptor: { id: 'old-usb-id', path: 'old-usb-path', protocolType: 'V2' },
|
|
4294
|
+
deviceConnector: {
|
|
4295
|
+
enumerate: jest.fn().mockResolvedValue({
|
|
4296
|
+
descriptors: [
|
|
4297
|
+
{ id: 'usb-a', path: 'usb-a', protocolType: 'V2' },
|
|
4298
|
+
{ id: 'usb-b', path: 'usb-b', protocolType: 'V2' },
|
|
4299
|
+
],
|
|
4300
|
+
}),
|
|
4301
|
+
},
|
|
4302
|
+
updateFromCache,
|
|
4303
|
+
});
|
|
4304
|
+
const getDevices = jest.spyOn(DevicePool, 'getDevices').mockResolvedValue({
|
|
4305
|
+
devices: {},
|
|
4306
|
+
deviceList: [
|
|
4307
|
+
{
|
|
4308
|
+
getConnectId: () => 'usb-a',
|
|
4309
|
+
getCurrentSerialNo: () => 'PRO2-PHYSICAL-A',
|
|
4310
|
+
},
|
|
4311
|
+
{
|
|
4312
|
+
getConnectId: () => 'usb-b',
|
|
4313
|
+
getCurrentSerialNo: () => 'PRO2-PHYSICAL-B',
|
|
4314
|
+
},
|
|
4315
|
+
],
|
|
4316
|
+
} as any);
|
|
4317
|
+
(method as any).device = device;
|
|
4318
|
+
(method as any).protocolV2ExpectedSerialNumber = 'PRO2-PHYSICAL-C';
|
|
4319
|
+
|
|
4320
|
+
try {
|
|
4321
|
+
await expect((method as any).reconnectProtocolV2Device()).rejects.toBeDefined();
|
|
4322
|
+
} finally {
|
|
4323
|
+
getDevices.mockRestore();
|
|
4324
|
+
}
|
|
4325
|
+
|
|
4326
|
+
expect(updateFromCache).not.toHaveBeenCalled();
|
|
4327
|
+
});
|
|
4328
|
+
|
|
4329
|
+
test('allows a single Protocol V2 USB reconnect candidate when its physical serial is unavailable', async () => {
|
|
4330
|
+
const method = new FirmwareUpdateV4({
|
|
4331
|
+
id: 1,
|
|
4332
|
+
payload: {
|
|
4333
|
+
method: 'firmwareUpdateV4',
|
|
4334
|
+
},
|
|
4335
|
+
});
|
|
4336
|
+
const commands = { disposed: true, mainId: '' };
|
|
4337
|
+
const updateFromCache = jest.fn();
|
|
4338
|
+
const device = stubDevice({
|
|
4339
|
+
originalDescriptor: { id: 'old-usb-id', path: 'old-usb-path', protocolType: 'V2' },
|
|
4340
|
+
deviceConnector: {
|
|
4341
|
+
enumerate: jest.fn().mockResolvedValue({
|
|
4342
|
+
descriptors: [{ id: 'usb-a', path: 'usb-a', protocolType: 'V2' }],
|
|
4343
|
+
}),
|
|
4344
|
+
},
|
|
4345
|
+
updateFromCache,
|
|
4346
|
+
hasDeviceAcquire: jest.fn(() => false),
|
|
4347
|
+
acquire: jest.fn().mockResolvedValue(undefined),
|
|
4348
|
+
commands,
|
|
4349
|
+
getCommands: () => commands,
|
|
4350
|
+
mainId: 'old-usb-path',
|
|
4351
|
+
});
|
|
4352
|
+
const candidate = {
|
|
4353
|
+
getConnectId: () => 'usb-a',
|
|
4354
|
+
getCurrentSerialNo: () => '',
|
|
4355
|
+
};
|
|
4356
|
+
const getDevices = jest.spyOn(DevicePool, 'getDevices').mockResolvedValue({
|
|
4357
|
+
devices: {},
|
|
4358
|
+
deviceList: [candidate],
|
|
4359
|
+
} as any);
|
|
4360
|
+
(method as any).device = device;
|
|
4361
|
+
(method as any).protocolV2ExpectedSerialNumber = 'PRO2-PHYSICAL-A';
|
|
4362
|
+
|
|
4363
|
+
try {
|
|
4364
|
+
await (method as any).reconnectProtocolV2Device();
|
|
4365
|
+
} finally {
|
|
4366
|
+
getDevices.mockRestore();
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4369
|
+
expect(updateFromCache).toHaveBeenCalledWith(candidate);
|
|
4370
|
+
});
|
|
4371
|
+
|
|
4372
|
+
test('rejects a single Protocol V2 USB reconnect candidate with a different physical serial', async () => {
|
|
4373
|
+
const method = new FirmwareUpdateV4({
|
|
4374
|
+
id: 1,
|
|
4375
|
+
payload: {
|
|
4376
|
+
method: 'firmwareUpdateV4',
|
|
4377
|
+
},
|
|
4378
|
+
});
|
|
4379
|
+
const updateFromCache = jest.fn();
|
|
4380
|
+
const device = stubDevice({
|
|
4381
|
+
originalDescriptor: { id: 'old-usb-id', path: 'old-usb-path', protocolType: 'V2' },
|
|
4382
|
+
deviceConnector: {
|
|
4383
|
+
enumerate: jest.fn().mockResolvedValue({
|
|
4384
|
+
descriptors: [{ id: 'usb-a', path: 'usb-a', protocolType: 'V2' }],
|
|
4385
|
+
}),
|
|
4386
|
+
},
|
|
4387
|
+
updateFromCache,
|
|
4388
|
+
});
|
|
4389
|
+
const getDevices = jest.spyOn(DevicePool, 'getDevices').mockResolvedValue({
|
|
4390
|
+
devices: {},
|
|
4391
|
+
deviceList: [
|
|
4392
|
+
{
|
|
4393
|
+
getConnectId: () => 'usb-a',
|
|
4394
|
+
getCurrentSerialNo: () => 'PRO2-PHYSICAL-A',
|
|
4395
|
+
},
|
|
4396
|
+
],
|
|
4397
|
+
} as any);
|
|
4398
|
+
(method as any).device = device;
|
|
4399
|
+
(method as any).protocolV2ExpectedSerialNumber = 'PRO2-PHYSICAL-B';
|
|
4400
|
+
|
|
4401
|
+
try {
|
|
4402
|
+
await expect((method as any).reconnectProtocolV2Device()).rejects.toBeDefined();
|
|
4403
|
+
} finally {
|
|
4404
|
+
getDevices.mockRestore();
|
|
4405
|
+
}
|
|
4406
|
+
|
|
4407
|
+
expect(updateFromCache).not.toHaveBeenCalled();
|
|
4408
|
+
});
|
|
4409
|
+
|
|
4142
4410
|
test('reuses an acquired Protocol V2 USB session while polling reconnect readiness', async () => {
|
|
4143
4411
|
const method = new FirmwareUpdateV4({
|
|
4144
4412
|
id: 1,
|
|
@@ -5938,14 +6206,14 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
5938
6206
|
.mockReturnValue(stable as any);
|
|
5939
6207
|
(method as any).downloadProtocolV2Resource = jest.fn();
|
|
5940
6208
|
|
|
5941
|
-
await expect((method as any).prepareProtocolV2ResourceBundles(
|
|
6209
|
+
await expect((method as any).prepareProtocolV2ResourceBundles()).resolves.toEqual([]);
|
|
5942
6210
|
expect(typedCall.mock.calls.some(call => call[0] === 'ResourceInventoryGet')).toBe(false);
|
|
5943
6211
|
expect(typedCall.mock.calls.some(call => call[0] === 'FilesystemFileRead')).toBe(true);
|
|
5944
6212
|
expect((method as any).downloadProtocolV2Resource).not.toHaveBeenCalled();
|
|
5945
6213
|
resourcesSpy.mockRestore();
|
|
5946
6214
|
});
|
|
5947
6215
|
|
|
5948
|
-
test('downloads only changed resources
|
|
6216
|
+
test('downloads only changed resources from loader inventory', async () => {
|
|
5949
6217
|
const method = new FirmwareUpdateV4({
|
|
5950
6218
|
id: 1,
|
|
5951
6219
|
payload: { method: 'firmwareUpdateV4', platform: 'web', targetsToUpdate: ['resource'] },
|
|
@@ -5973,7 +6241,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
5973
6241
|
})
|
|
5974
6242
|
);
|
|
5975
6243
|
|
|
5976
|
-
const bundles = await (method as any).prepareProtocolV2ResourceBundles(
|
|
6244
|
+
const bundles = await (method as any).prepareProtocolV2ResourceBundles();
|
|
5977
6245
|
|
|
5978
6246
|
expect(bundles).toHaveLength(1);
|
|
5979
6247
|
expect((method as any).downloadProtocolV2Resource).toHaveBeenCalledWith(stable[0]);
|
|
@@ -6008,7 +6276,7 @@ describe('Protocol V2 firmware reconnect identity', () => {
|
|
|
6008
6276
|
})
|
|
6009
6277
|
);
|
|
6010
6278
|
|
|
6011
|
-
const bundles = await (method as any).prepareProtocolV2ResourceBundles(
|
|
6279
|
+
const bundles = await (method as any).prepareProtocolV2ResourceBundles();
|
|
6012
6280
|
|
|
6013
6281
|
expect(bundles).toHaveLength(1);
|
|
6014
6282
|
expect(typedCall.mock.calls.some(call => call[0] === 'ResourceInventoryGet')).toBe(false);
|
|
@@ -42,7 +42,7 @@ describe('SearchDevices', () => {
|
|
|
42
42
|
mockIsBleConnect.mockReturnValue(false);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
test('
|
|
45
|
+
test('搜索忽略调用方协议并主动探测,单个无响应设备不阻断后续结果', async () => {
|
|
46
46
|
const unresponsiveDescriptor = {
|
|
47
47
|
path: 'stale-usb-device',
|
|
48
48
|
id: 'stale-usb-device',
|
|
@@ -74,6 +74,7 @@ describe('SearchDevices', () => {
|
|
|
74
74
|
id: 1,
|
|
75
75
|
payload: {
|
|
76
76
|
method: 'searchDevices',
|
|
77
|
+
connectProtocol: 'V2',
|
|
77
78
|
},
|
|
78
79
|
} as any);
|
|
79
80
|
method.init();
|
|
@@ -89,13 +90,21 @@ describe('SearchDevices', () => {
|
|
|
89
90
|
1,
|
|
90
91
|
[unresponsiveDescriptor],
|
|
91
92
|
unresponsiveDescriptor.path,
|
|
92
|
-
{
|
|
93
|
+
{
|
|
94
|
+
connectProtocol: undefined,
|
|
95
|
+
forceProtocolDetection: true,
|
|
96
|
+
refreshRuntimeState: true,
|
|
97
|
+
}
|
|
93
98
|
);
|
|
94
99
|
expect(mockGetDevices).toHaveBeenNthCalledWith(
|
|
95
100
|
2,
|
|
96
101
|
[availableDescriptor],
|
|
97
102
|
availableDescriptor.path,
|
|
98
|
-
{
|
|
103
|
+
{
|
|
104
|
+
connectProtocol: undefined,
|
|
105
|
+
forceProtocolDetection: true,
|
|
106
|
+
refreshRuntimeState: true,
|
|
107
|
+
}
|
|
99
108
|
);
|
|
100
109
|
});
|
|
101
110
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAY/E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM1C,OAAO,KAAK,EACV,kBAAkB,EAElB,kCAAkC,EAClC,+BAA+B,EAChC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,UAAU,CAAC;AA6HlB,KAAK,6BAA6B,GAAG;IACnC,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,+BAA+B,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,mBAAmB,CAAC;IACrC,UAAU,EAAE,kCAAkC,EAAE,CAAC;IACjD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,mBAAwB,EACxB,mBAAwB,EACxB,YAAY,EACZ,OAAO,GACR,EAAE;IACD,eAAe,EAAE,mBAAmB,CAAC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpD,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,YAAY,EAAE,aAAa,CAAC;IAC5B,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,GAAG,6BAA6B,CAoEhC;AAED,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,qBAAqB;IAIrB,IAAI;IAME,GAAG;YAuDK,aAAa;
|
|
1
|
+
{"version":3,"file":"CheckAllFirmwareRelease.d.ts","sourceRoot":"","sources":["../../src/api/CheckAllFirmwareRelease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAY/E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM1C,OAAO,KAAK,EACV,kBAAkB,EAElB,kCAAkC,EAClC,+BAA+B,EAChC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,UAAU,CAAC;AA6HlB,KAAK,6BAA6B,GAAG;IACnC,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,+BAA+B,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,mBAAmB,CAAC;IACrC,UAAU,EAAE,kCAAkC,EAAE,CAAC;IACjD,eAAe,EAAE,sBAAsB,EAAE,CAAC;IAC1C,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,EAC7C,eAAe,EACf,mBAAwB,EACxB,mBAAwB,EACxB,YAAY,EACZ,OAAO,GACR,EAAE;IACD,eAAe,EAAE,mBAAmB,CAAC;IACrC,mBAAmB,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACpD,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9D,YAAY,EAAE,aAAa,CAAC;IAC5B,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC3C,GAAG,6BAA6B,CAoEhC;AAED,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,qBAAqB;IAIrB,IAAI;IAME,GAAG;YAuDK,aAAa;CAqF5B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
export default class DetectDeviceConnectProtocol extends BaseMethod {
|
|
3
|
+
init(): void;
|
|
4
|
+
getSupportedProtocols(): readonly ["V1", "V2"];
|
|
5
|
+
run(): Promise<"V1" | "V2">;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=DetectDeviceConnectProtocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DetectDeviceConnectProtocol.d.ts","sourceRoot":"","sources":["../../src/api/DetectDeviceConnectProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,CAAC,OAAO,OAAO,2BAA4B,SAAQ,UAAU;IACjE,IAAI;IAOJ,qBAAqB;IAIrB,GAAG;CAGJ"}
|