@onekeyfe/hd-transport-react-native 1.2.0-alpha.70 → 1.2.0-alpha.72
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/dist/BleTransport.d.ts +1 -1
- package/dist/BleTransport.d.ts.map +1 -1
- package/dist/bleStrategy.d.ts +7 -0
- package/dist/bleStrategy.d.ts.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +188 -46
- package/package.json +5 -5
- package/src/BleTransport.ts +1 -1
- package/src/__tests__/bleStrategy.test.ts +93 -5
- package/src/__tests__/protocolV2Link.test.ts +195 -15
- package/src/bleStrategy.ts +26 -11
- package/src/constants.ts +2 -1
- package/src/index.ts +212 -41
|
@@ -7,6 +7,7 @@ import transportPackage, {
|
|
|
7
7
|
import { HardwareErrorCode, createDeferred } from '@onekeyfe/hd-shared';
|
|
8
8
|
|
|
9
9
|
import ReactNativeBleTransport, {
|
|
10
|
+
BLE_WRITE_PACKET_TIMEOUT_MS,
|
|
10
11
|
configureProtocolV2BleTuning,
|
|
11
12
|
getFirmwareUploadWriteRetryType,
|
|
12
13
|
resetProtocolV2BleTuning,
|
|
@@ -32,6 +33,7 @@ jest.mock('react-native-ble-plx', () => ({
|
|
|
32
33
|
CharacteristicNotFound: 404,
|
|
33
34
|
},
|
|
34
35
|
BleManager: jest.fn(),
|
|
36
|
+
ConnectionPriority: { Balanced: 0, High: 1, LowPower: 2 },
|
|
35
37
|
ScanMode: { LowLatency: 2 },
|
|
36
38
|
}));
|
|
37
39
|
|
|
@@ -157,6 +159,7 @@ const createHarness = ({
|
|
|
157
159
|
id: uuid,
|
|
158
160
|
name: deviceName,
|
|
159
161
|
localName: deviceName,
|
|
162
|
+
mtu: 247,
|
|
160
163
|
serviceUUIDs: ['00000001-0000-1000-8000-00805f9b34fb'],
|
|
161
164
|
isConnected: jest.fn(() => Promise.resolve(true)),
|
|
162
165
|
cancelConnection: jest.fn(() => Promise.resolve()),
|
|
@@ -164,7 +167,9 @@ const createHarness = ({
|
|
|
164
167
|
disconnectCallback = callback;
|
|
165
168
|
return { remove: jest.fn() };
|
|
166
169
|
}),
|
|
167
|
-
};
|
|
170
|
+
} as any;
|
|
171
|
+
device.requestMTU = jest.fn(() => Promise.resolve(device));
|
|
172
|
+
device.requestConnectionPriority = jest.fn(() => Promise.resolve(device));
|
|
168
173
|
const bleManager = {
|
|
169
174
|
devices: jest.fn(() => Promise.resolve([device])),
|
|
170
175
|
connectedDevices: jest.fn(() => Promise.resolve([])),
|
|
@@ -172,18 +177,21 @@ const createHarness = ({
|
|
|
172
177
|
};
|
|
173
178
|
const transport = new ReactNativeBleTransport({ scanTimeout: 1 });
|
|
174
179
|
const emitter = new EventEmitter();
|
|
180
|
+
const logger = { debug: jest.fn(), error: jest.fn() };
|
|
175
181
|
transport.blePlxManager = bleManager;
|
|
176
182
|
transport.resolveCharacteristics = jest.fn(() =>
|
|
177
183
|
Promise.resolve({ writeCharacteristic, notifyCharacteristic })
|
|
178
184
|
);
|
|
179
|
-
transport.init(
|
|
185
|
+
transport.init(logger, emitter);
|
|
180
186
|
transport.configure(protocolV1Schema);
|
|
181
187
|
transport.configureProtocolV2(protocolV2Schema);
|
|
182
188
|
|
|
183
189
|
return {
|
|
184
190
|
transport,
|
|
185
191
|
emitter,
|
|
192
|
+
logger,
|
|
186
193
|
uuid,
|
|
194
|
+
device,
|
|
187
195
|
sentSeqs,
|
|
188
196
|
writeCharacteristic,
|
|
189
197
|
setShouldRespond(value: boolean) {
|
|
@@ -247,6 +255,7 @@ const createV1Harness = ({
|
|
|
247
255
|
id: uuid,
|
|
248
256
|
name: 'OneKey Classic',
|
|
249
257
|
localName: 'OneKey Classic',
|
|
258
|
+
mtu: 247,
|
|
250
259
|
serviceUUIDs: ['00000001-0000-1000-8000-00805f9b34fb'],
|
|
251
260
|
isConnected: jest.fn(() => Promise.resolve(true)),
|
|
252
261
|
cancelConnection: jest.fn(() => Promise.resolve()),
|
|
@@ -255,7 +264,8 @@ const createV1Harness = ({
|
|
|
255
264
|
disconnectSubscriptionRemovers.push(remove);
|
|
256
265
|
return { remove };
|
|
257
266
|
}),
|
|
258
|
-
};
|
|
267
|
+
} as any;
|
|
268
|
+
device.requestMTU = jest.fn(() => Promise.resolve(device));
|
|
259
269
|
const transport = new ReactNativeBleTransport({ scanTimeout: 1 });
|
|
260
270
|
const bleManager = {
|
|
261
271
|
devices: jest.fn(() => Promise.resolve([device])),
|
|
@@ -392,7 +402,7 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
392
402
|
});
|
|
393
403
|
|
|
394
404
|
test('actively probes Protocol V2 on iOS when only a name-derived hint is available', async () => {
|
|
395
|
-
const { transport, uuid, sentSeqs, writeCharacteristic } = createHarness({
|
|
405
|
+
const { transport, uuid, device, sentSeqs, writeCharacteristic } = createHarness({
|
|
396
406
|
deviceName: 'Pro2 6E9E',
|
|
397
407
|
});
|
|
398
408
|
|
|
@@ -400,6 +410,7 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
400
410
|
uuid,
|
|
401
411
|
protocolType: 'V2',
|
|
402
412
|
});
|
|
413
|
+
expect(device.requestMTU).toHaveBeenCalledWith(247);
|
|
403
414
|
expect(writeCharacteristic.writeWithResponse).toHaveBeenCalledTimes(1);
|
|
404
415
|
|
|
405
416
|
await expect(
|
|
@@ -429,6 +440,114 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
429
440
|
await transport.release(uuid, true);
|
|
430
441
|
});
|
|
431
442
|
|
|
443
|
+
test('continues with the current MTU when the connected snapshot refresh fails', async () => {
|
|
444
|
+
const { transport, uuid, device } = createHarness();
|
|
445
|
+
const mtuError = new Error('MTU refresh failed');
|
|
446
|
+
device.requestMTU.mockRejectedValueOnce(mtuError);
|
|
447
|
+
|
|
448
|
+
await expect(transport.acquire({ uuid })).resolves.toEqual({
|
|
449
|
+
uuid,
|
|
450
|
+
protocolType: 'V2',
|
|
451
|
+
});
|
|
452
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(1);
|
|
453
|
+
expect((transport as any).getCachedTransport(uuid).mtuSize).toBe(247);
|
|
454
|
+
await transport.release(uuid, true);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test('refreshes a transient bootloader MTU after notifications are ready', async () => {
|
|
458
|
+
const { transport, uuid, device } = createHarness();
|
|
459
|
+
device.mtu = 23;
|
|
460
|
+
device.requestMTU
|
|
461
|
+
.mockResolvedValueOnce(device)
|
|
462
|
+
.mockResolvedValueOnce(device)
|
|
463
|
+
.mockImplementationOnce(() => {
|
|
464
|
+
device.mtu = 247;
|
|
465
|
+
return Promise.resolve(device);
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
await expect(transport.acquire({ uuid })).resolves.toEqual({
|
|
469
|
+
uuid,
|
|
470
|
+
protocolType: 'V2',
|
|
471
|
+
});
|
|
472
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(3);
|
|
473
|
+
expect((transport as any).getCachedTransport(uuid).mtuSize).toBe(247);
|
|
474
|
+
await transport.release(uuid, true);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
test('continues with a low bootloader MTU when the bounded retry fails', async () => {
|
|
478
|
+
const { transport, uuid, device } = createHarness();
|
|
479
|
+
device.mtu = 23;
|
|
480
|
+
device.requestMTU
|
|
481
|
+
.mockResolvedValueOnce(device)
|
|
482
|
+
.mockResolvedValueOnce(device)
|
|
483
|
+
.mockRejectedValueOnce(new Error('bootloader MTU retry failed'));
|
|
484
|
+
|
|
485
|
+
await expect(transport.acquire({ uuid })).resolves.toEqual({
|
|
486
|
+
uuid,
|
|
487
|
+
protocolType: 'V2',
|
|
488
|
+
});
|
|
489
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(3);
|
|
490
|
+
expect((transport as any).getCachedTransport(uuid).mtuSize).toBe(23);
|
|
491
|
+
await transport.release(uuid, true);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
test('accepts a stable low MTU without the delayed refresh loop', async () => {
|
|
495
|
+
const { transport, uuid, device } = createHarness();
|
|
496
|
+
device.mtu = 185;
|
|
497
|
+
|
|
498
|
+
await expect(transport.acquire({ uuid })).resolves.toEqual({
|
|
499
|
+
uuid,
|
|
500
|
+
protocolType: 'V2',
|
|
501
|
+
});
|
|
502
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(1);
|
|
503
|
+
expect((transport as any).getCachedTransport(uuid).mtuSize).toBe(185);
|
|
504
|
+
await transport.release(uuid, true);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test('continues Protocol V2 probing with a conservative packet size when MTU is unavailable', async () => {
|
|
508
|
+
const { transport, uuid, device, writeCharacteristic } = createHarness();
|
|
509
|
+
device.mtu = undefined;
|
|
510
|
+
|
|
511
|
+
await expect(transport.acquire({ uuid })).resolves.toEqual({
|
|
512
|
+
uuid,
|
|
513
|
+
protocolType: 'V2',
|
|
514
|
+
});
|
|
515
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(3);
|
|
516
|
+
expect((transport as any).getCachedTransport(uuid).mtuSize).toBeUndefined();
|
|
517
|
+
expect(writeCharacteristic.writeWithResponse).toHaveBeenCalled();
|
|
518
|
+
await transport.release(uuid, true);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
test('refreshes an unavailable MTU before a Protocol V2 high-volume write', async () => {
|
|
522
|
+
const { transport, uuid, device, writeCharacteristic } = createHarness();
|
|
523
|
+
device.mtu = undefined;
|
|
524
|
+
|
|
525
|
+
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
|
526
|
+
device.requestMTU.mockImplementationOnce(() => {
|
|
527
|
+
device.mtu = 247;
|
|
528
|
+
return Promise.resolve(device);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
await expect(transport.call(uuid, 'FileWrite', {})).resolves.toBeDefined();
|
|
532
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(4);
|
|
533
|
+
expect(writeCharacteristic.writeWithoutResponse).toHaveBeenCalledTimes(1);
|
|
534
|
+
await transport.release(uuid, true);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
test('rejects a Protocol V2 high-volume write when MTU remains unavailable', async () => {
|
|
538
|
+
const { transport, uuid, device, writeCharacteristic } = createHarness();
|
|
539
|
+
device.mtu = undefined;
|
|
540
|
+
|
|
541
|
+
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
|
542
|
+
|
|
543
|
+
await expect(transport.call(uuid, 'FileWrite', {})).rejects.toMatchObject({
|
|
544
|
+
errorCode: HardwareErrorCode.BleConnectedError,
|
|
545
|
+
});
|
|
546
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(4);
|
|
547
|
+
expect(writeCharacteristic.writeWithoutResponse).not.toHaveBeenCalled();
|
|
548
|
+
await transport.release(uuid, true);
|
|
549
|
+
});
|
|
550
|
+
|
|
432
551
|
test('reconnects before falling back to Protocol V1 after a fatal V2 probe failure', async () => {
|
|
433
552
|
setPlatformOS('android');
|
|
434
553
|
const { transport, uuid, device, notifySubscriptionRemovers, disconnectSubscriptionRemovers } =
|
|
@@ -564,16 +683,40 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
564
683
|
});
|
|
565
684
|
|
|
566
685
|
test('keeps iOS Protocol V2 high-volume calls on withoutResponse', async () => {
|
|
567
|
-
const { transport, uuid, writeCharacteristic } = createHarness();
|
|
686
|
+
const { transport, uuid, logger, writeCharacteristic } = createHarness();
|
|
568
687
|
|
|
569
688
|
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
|
570
689
|
|
|
571
690
|
await transport.call(uuid, 'FileWrite', {});
|
|
572
|
-
|
|
691
|
+
await transport.call(uuid, 'FileWrite', {});
|
|
692
|
+
expect(writeCharacteristic.writeWithoutResponse).toHaveBeenCalledTimes(2);
|
|
573
693
|
expect(writeCharacteristic.writeWithResponse).not.toHaveBeenCalled();
|
|
694
|
+
expect(
|
|
695
|
+
logger.debug.mock.calls.filter(
|
|
696
|
+
([message]) =>
|
|
697
|
+
message === '[ReactNativeBleTransport] Protocol V2 high-volume write configured'
|
|
698
|
+
)
|
|
699
|
+
).toHaveLength(1);
|
|
574
700
|
await transport.release(uuid, true);
|
|
575
701
|
});
|
|
576
702
|
|
|
703
|
+
test('uses Android 517 MTU and high connection priority during Protocol V2 high-volume calls', async () => {
|
|
704
|
+
setPlatformOS('android');
|
|
705
|
+
const { transport, uuid, device } = createHarness();
|
|
706
|
+
|
|
707
|
+
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
|
708
|
+
expect(device.requestMTU).toHaveBeenCalledWith(517);
|
|
709
|
+
|
|
710
|
+
await transport.call(uuid, 'FileWrite', {});
|
|
711
|
+
await transport.call(uuid, 'FileWrite', {});
|
|
712
|
+
|
|
713
|
+
expect(device.requestConnectionPriority).toHaveBeenCalledTimes(1);
|
|
714
|
+
expect(device.requestConnectionPriority).toHaveBeenCalledWith(1);
|
|
715
|
+
|
|
716
|
+
await transport.release(uuid, true);
|
|
717
|
+
expect(device.requestConnectionPriority).toHaveBeenLastCalledWith(0);
|
|
718
|
+
});
|
|
719
|
+
|
|
577
720
|
test('uses withResponse for an iOS Protocol V2 firmware file write when requested', async () => {
|
|
578
721
|
const { transport, uuid, writeCharacteristic } = createHarness();
|
|
579
722
|
|
|
@@ -606,7 +749,7 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
606
749
|
const context = {
|
|
607
750
|
messageName: 'ProtocolInfoRequest',
|
|
608
751
|
timeoutMs: 1000,
|
|
609
|
-
|
|
752
|
+
highThroughput: false,
|
|
610
753
|
generation: 1,
|
|
611
754
|
signal: new AbortController().signal,
|
|
612
755
|
};
|
|
@@ -630,7 +773,7 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
630
773
|
expect(writeWithoutResponse).not.toHaveBeenCalled();
|
|
631
774
|
});
|
|
632
775
|
|
|
633
|
-
test('
|
|
776
|
+
test('does not pace a one-packet Protocol V2 control write on iOS', async () => {
|
|
634
777
|
const transport = new ReactNativeBleTransport({ scanTimeout: 1 }) as any;
|
|
635
778
|
const writeWithoutResponse = jest.fn().mockResolvedValue(undefined);
|
|
636
779
|
const bleTransport = {
|
|
@@ -640,7 +783,7 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
640
783
|
const context = {
|
|
641
784
|
messageName: 'ProtocolInfoRequest',
|
|
642
785
|
timeoutMs: 1000,
|
|
643
|
-
|
|
786
|
+
highThroughput: false,
|
|
644
787
|
generation: 1,
|
|
645
788
|
signal: new AbortController().signal,
|
|
646
789
|
};
|
|
@@ -656,11 +799,11 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
656
799
|
jest.fn()
|
|
657
800
|
);
|
|
658
801
|
|
|
659
|
-
await Promise.resolve();
|
|
660
|
-
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 5);
|
|
661
|
-
expect(writeWithoutResponse).not.toHaveBeenCalled();
|
|
662
|
-
|
|
663
802
|
await call;
|
|
803
|
+
// The only scheduled timer is the per-packet BLE write watchdog: no pacing delay.
|
|
804
|
+
expect(setTimeoutSpy.mock.calls.map(([, timeout]) => timeout)).toEqual([
|
|
805
|
+
BLE_WRITE_PACKET_TIMEOUT_MS,
|
|
806
|
+
]);
|
|
664
807
|
expect(writeWithoutResponse).toHaveBeenCalledTimes(1);
|
|
665
808
|
} finally {
|
|
666
809
|
setTimeoutSpy.mockRestore();
|
|
@@ -716,7 +859,7 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
716
859
|
const context = {
|
|
717
860
|
messageName: 'Ping',
|
|
718
861
|
timeoutMs: 1000,
|
|
719
|
-
|
|
862
|
+
highThroughput: false,
|
|
720
863
|
generation: 1,
|
|
721
864
|
signal: new AbortController().signal,
|
|
722
865
|
};
|
|
@@ -749,7 +892,7 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
749
892
|
const context = {
|
|
750
893
|
messageName: 'FileWrite',
|
|
751
894
|
timeoutMs: 1000,
|
|
752
|
-
|
|
895
|
+
highThroughput: true,
|
|
753
896
|
generation: 1,
|
|
754
897
|
signal: new AbortController().signal,
|
|
755
898
|
};
|
|
@@ -766,4 +909,41 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
766
909
|
).rejects.toMatchObject({ errorCode: 205 });
|
|
767
910
|
expect(writeWithoutResponse).toHaveBeenCalledTimes(1);
|
|
768
911
|
});
|
|
912
|
+
|
|
913
|
+
test('does not apply fixed burst or flush pauses to high-volume Protocol V2 writes', async () => {
|
|
914
|
+
const transport = new ReactNativeBleTransport({ scanTimeout: 1 }) as any;
|
|
915
|
+
const writeWithoutResponse = jest.fn().mockResolvedValue(undefined);
|
|
916
|
+
const bleTransport = {
|
|
917
|
+
mtuSize: 247,
|
|
918
|
+
writeCharacteristic: { writeWithoutResponse },
|
|
919
|
+
};
|
|
920
|
+
const context = {
|
|
921
|
+
messageName: 'FileWrite',
|
|
922
|
+
timeoutMs: 1000,
|
|
923
|
+
highThroughput: true,
|
|
924
|
+
generation: 1,
|
|
925
|
+
signal: new AbortController().signal,
|
|
926
|
+
};
|
|
927
|
+
const setTimeoutSpy = jest.spyOn(global, 'setTimeout');
|
|
928
|
+
|
|
929
|
+
try {
|
|
930
|
+
await transport.writeProtocolV2Frame(
|
|
931
|
+
'test-device',
|
|
932
|
+
bleTransport,
|
|
933
|
+
new Uint8Array(600),
|
|
934
|
+
context,
|
|
935
|
+
jest.fn()
|
|
936
|
+
);
|
|
937
|
+
|
|
938
|
+
expect(writeWithoutResponse).toHaveBeenCalledTimes(3);
|
|
939
|
+
// One BLE write watchdog per packet and nothing else: no burst or flush pauses.
|
|
940
|
+
expect(setTimeoutSpy.mock.calls.map(([, timeout]) => timeout)).toEqual([
|
|
941
|
+
BLE_WRITE_PACKET_TIMEOUT_MS,
|
|
942
|
+
BLE_WRITE_PACKET_TIMEOUT_MS,
|
|
943
|
+
BLE_WRITE_PACKET_TIMEOUT_MS,
|
|
944
|
+
]);
|
|
945
|
+
} finally {
|
|
946
|
+
setTimeoutSpy.mockRestore();
|
|
947
|
+
}
|
|
948
|
+
});
|
|
769
949
|
});
|
package/src/bleStrategy.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ANDROID_PROTOCOL_V2_PACKET_LENGTH, IOS_PROTOCOL_V2_PACKET_LENGTH } from './constants';
|
|
2
2
|
|
|
3
3
|
export type BlePlatform = 'ios' | 'android' | string;
|
|
4
4
|
|
|
@@ -13,8 +13,8 @@ export function hasWritableCapability(characteristic: BleWriteCapability) {
|
|
|
13
13
|
|
|
14
14
|
export function resolveProtocolV2PacketCapacity({
|
|
15
15
|
platform,
|
|
16
|
-
iosPacketLength =
|
|
17
|
-
androidPacketLength =
|
|
16
|
+
iosPacketLength = IOS_PROTOCOL_V2_PACKET_LENGTH,
|
|
17
|
+
androidPacketLength = ANDROID_PROTOCOL_V2_PACKET_LENGTH,
|
|
18
18
|
mtu,
|
|
19
19
|
}: {
|
|
20
20
|
platform: BlePlatform;
|
|
@@ -22,14 +22,29 @@ export function resolveProtocolV2PacketCapacity({
|
|
|
22
22
|
androidPacketLength?: number;
|
|
23
23
|
mtu?: number | null;
|
|
24
24
|
}) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const negotiatedMtu =
|
|
26
|
+
typeof mtu === 'number' && Number.isFinite(mtu) && mtu > 3 ? Math.floor(mtu) : 23;
|
|
27
|
+
const payloadLength = negotiatedMtu - 3;
|
|
28
|
+
const configuredPacketLength = platform === 'ios' ? iosPacketLength : androidPacketLength;
|
|
29
|
+
return Math.min(configuredPacketLength, payloadLength);
|
|
30
|
+
}
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
32
|
+
export function shouldRefreshNegotiatedMtu(mtu?: number | null) {
|
|
33
|
+
return typeof mtu !== 'number' || !Number.isFinite(mtu) || mtu <= 23;
|
|
34
|
+
}
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
export function shouldWriteProtocolV2WithResponse({
|
|
37
|
+
platform,
|
|
38
|
+
highThroughput,
|
|
39
|
+
requestedWithResponse,
|
|
40
|
+
characteristic,
|
|
41
|
+
}: {
|
|
42
|
+
platform: BlePlatform;
|
|
43
|
+
highThroughput: boolean;
|
|
44
|
+
requestedWithResponse?: boolean;
|
|
45
|
+
characteristic: BleWriteCapability;
|
|
46
|
+
}) {
|
|
47
|
+
if (!characteristic.isWritableWithResponse) return false;
|
|
48
|
+
if (!characteristic.isWritableWithoutResponse) return true;
|
|
49
|
+
return requestedWithResponse === true || (platform === 'ios' && !highThroughput);
|
|
35
50
|
}
|
package/src/constants.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { createKnownBleUuidAliases, matchesKnownBleUuid } from '@onekeyfe/hd-sha
|
|
|
2
2
|
|
|
3
3
|
export const IOS_PACKET_LENGTH = 128;
|
|
4
4
|
export const ANDROID_PACKET_LENGTH = 192;
|
|
5
|
-
export const
|
|
5
|
+
export const IOS_PROTOCOL_V2_PACKET_LENGTH = 244;
|
|
6
|
+
export const ANDROID_PROTOCOL_V2_PACKET_LENGTH = 244;
|
|
6
7
|
|
|
7
8
|
type BluetoothServices = Record<
|
|
8
9
|
string,
|