@onekeyfe/hd-transport-react-native 1.1.27-alpha.31 → 1.1.27-alpha.33
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/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +151 -56
- package/package.json +5 -5
- package/src/index.ts +157 -48
package/dist/index.d.ts
CHANGED
|
@@ -43,9 +43,12 @@ declare class ReactNativeBleTransport {
|
|
|
43
43
|
runPromise: Deferred<any> | null;
|
|
44
44
|
emitter?: EventEmitter;
|
|
45
45
|
private deviceProtocol;
|
|
46
|
+
private deviceProtocolHints;
|
|
46
47
|
private protocolV2Assemblers;
|
|
47
|
-
private
|
|
48
|
-
private
|
|
48
|
+
private protocolV2FrameQueues;
|
|
49
|
+
private protocolV2FramePromises;
|
|
50
|
+
private activeProtocolV2Call;
|
|
51
|
+
private nextProtocolV2CallToken;
|
|
49
52
|
private monitorTokens;
|
|
50
53
|
private nextMonitorToken;
|
|
51
54
|
constructor(options: TransportOptions);
|
|
@@ -70,12 +73,15 @@ declare class ReactNativeBleTransport {
|
|
|
70
73
|
private getCachedTransport;
|
|
71
74
|
private createProtocolMismatchError;
|
|
72
75
|
private detectProtocol;
|
|
76
|
+
private resetProbeStateAfterProtocolProbe;
|
|
73
77
|
private probeProtocolV1;
|
|
74
78
|
private probeProtocolV2;
|
|
75
79
|
private handleProtocolV2Notification;
|
|
80
|
+
private getProtocolV2FrameQueue;
|
|
76
81
|
private resolveProtocolV2Frame;
|
|
77
|
-
private
|
|
82
|
+
private rejectAllProtocolV2Frames;
|
|
78
83
|
private resetProtocolV2Frames;
|
|
84
|
+
private isActiveProtocolV2Call;
|
|
79
85
|
private readProtocolV2Frame;
|
|
80
86
|
private writeProtocolV2Frame;
|
|
81
87
|
private callProtocolV2;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAIL,UAAU,IAAI,aAAa,EAE5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,SAAS,EAAE,EAEhB,KAAK,oBAAoB,EAGzB,KAAK,YAAY,EAGjB,KAAK,oBAAoB,EAE1B,MAAM,wBAAwB,CAAC;AAkBhC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAqBjE,MAAM,MAAM,mBAAmB,GAAG;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC,CAAC;AAqBF,wBAAgB,4BAA4B,CAAC,MAAM,GAAE,mBAAwB,QA0B5E;AAED,wBAAgB,wBAAwB,SAGvC;AAED,wBAAgB,sBAAsB;;;;;;;EAErC;AA0BD,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,MAAM,CAAC;AA2C1D,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC1C,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IAEzC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,WAAW,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAErE,IAAI,SAA6B;IAEjC,UAAU,UAAS;IAEnB,OAAO,UAAS;IAEhB,WAAW,SAA0B;IAErC,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAExC,OAAO,CAAC,EAAE,YAAY,CAAC;IAGvB,OAAO,CAAC,cAAc,CAAwC;IAE9D,OAAO,CAAC,oBAAoB,CAAoD;IAEhF,OAAO,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -283,7 +283,7 @@ function resetProtocolV2BleTuning() {
|
|
|
283
283
|
function getProtocolV2BleTuning() {
|
|
284
284
|
return Object.assign({}, protocolV2BleTuning);
|
|
285
285
|
}
|
|
286
|
-
function
|
|
286
|
+
function inferProtocolHintFromDeviceName(name) {
|
|
287
287
|
return /\bpro\s*2\b/i.test(name !== null && name !== void 0 ? name : '') ? 'V2' : undefined;
|
|
288
288
|
}
|
|
289
289
|
function getDeviceDisplayName(device) {
|
|
@@ -339,9 +339,12 @@ class ReactNativeBleTransport {
|
|
|
339
339
|
this.scanTimeout = DEVICE_SCAN_TIMEOUT_MS;
|
|
340
340
|
this.runPromise = null;
|
|
341
341
|
this.deviceProtocol = new Map();
|
|
342
|
+
this.deviceProtocolHints = new Map();
|
|
342
343
|
this.protocolV2Assemblers = new Map();
|
|
343
|
-
this.
|
|
344
|
-
this.
|
|
344
|
+
this.protocolV2FrameQueues = new Map();
|
|
345
|
+
this.protocolV2FramePromises = new Map();
|
|
346
|
+
this.activeProtocolV2Call = null;
|
|
347
|
+
this.nextProtocolV2CallToken = 1;
|
|
345
348
|
this.monitorTokens = new Map();
|
|
346
349
|
this.nextMonitorToken = 1;
|
|
347
350
|
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
|
|
@@ -458,8 +461,11 @@ class ReactNativeBleTransport {
|
|
|
458
461
|
var _a;
|
|
459
462
|
if (deviceList.every(d => d.id !== device.id)) {
|
|
460
463
|
const displayName = (_a = getDeviceDisplayName(device)) !== null && _a !== void 0 ? _a : 'Unknown BLE Device';
|
|
461
|
-
const
|
|
462
|
-
|
|
464
|
+
const protocolHint = inferProtocolHintFromDeviceName(displayName);
|
|
465
|
+
if (protocolHint) {
|
|
466
|
+
this.deviceProtocolHints.set(device.id, protocolHint);
|
|
467
|
+
}
|
|
468
|
+
deviceList.push(Object.assign(Object.assign({}, device), { name: displayName, commType: 'ble' }));
|
|
463
469
|
}
|
|
464
470
|
};
|
|
465
471
|
timer.timeout(() => {
|
|
@@ -470,7 +476,7 @@ class ReactNativeBleTransport {
|
|
|
470
476
|
});
|
|
471
477
|
}
|
|
472
478
|
acquire(input) {
|
|
473
|
-
var _a, _b, _c, _d, _e;
|
|
479
|
+
var _a, _b, _c, _d, _e, _f;
|
|
474
480
|
return __awaiter(this, void 0, void 0, function* () {
|
|
475
481
|
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
476
482
|
if (!uuid) {
|
|
@@ -484,8 +490,9 @@ class ReactNativeBleTransport {
|
|
|
484
490
|
if (forceCleanRunPromise && this.runPromise) {
|
|
485
491
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
486
492
|
this.runPromise.reject(error);
|
|
487
|
-
this.
|
|
493
|
+
this.rejectAllProtocolV2Frames(error);
|
|
488
494
|
this.runPromise = null;
|
|
495
|
+
this.activeProtocolV2Call = null;
|
|
489
496
|
Log === null || Log === void 0 ? void 0 : Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
|
|
490
497
|
}
|
|
491
498
|
const blePlxManager = yield this.getPlxManager();
|
|
@@ -638,7 +645,13 @@ class ReactNativeBleTransport {
|
|
|
638
645
|
if (!notifyCharacteristic.isNotifiable) {
|
|
639
646
|
throw hdShared.ERRORS.TypedError('BLECharacteristicNotNotifiable: notify characteristic not notifiable');
|
|
640
647
|
}
|
|
648
|
+
const protocolHint = expectedProtocol
|
|
649
|
+
? undefined
|
|
650
|
+
: (_e = this.deviceProtocolHints.get(uuid)) !== null && _e !== void 0 ? _e : inferProtocolHintFromDeviceName(getDeviceDisplayName(device));
|
|
641
651
|
yield this.release(uuid);
|
|
652
|
+
if (protocolHint) {
|
|
653
|
+
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
654
|
+
}
|
|
642
655
|
const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
643
656
|
const monitorToken = this.nextMonitorToken;
|
|
644
657
|
this.nextMonitorToken += 1;
|
|
@@ -654,8 +667,8 @@ class ReactNativeBleTransport {
|
|
|
654
667
|
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
655
668
|
});
|
|
656
669
|
}
|
|
657
|
-
const protocolType = yield this.detectProtocol(uuid, expectedProtocol);
|
|
658
|
-
(
|
|
670
|
+
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
671
|
+
(_f = this.emitter) === null || _f === void 0 ? void 0 : _f.emit('device-connect', {
|
|
659
672
|
name: device.name,
|
|
660
673
|
id: device.id,
|
|
661
674
|
connectId: device.id,
|
|
@@ -676,7 +689,7 @@ class ReactNativeBleTransport {
|
|
|
676
689
|
if (this.runPromise) {
|
|
677
690
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError);
|
|
678
691
|
this.runPromise.reject(error);
|
|
679
|
-
this.
|
|
692
|
+
this.rejectAllProtocolV2Frames(error);
|
|
680
693
|
}
|
|
681
694
|
}
|
|
682
695
|
catch (e) {
|
|
@@ -716,13 +729,13 @@ class ReactNativeBleTransport {
|
|
|
716
729
|
((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('notify change failed for device'))) {
|
|
717
730
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure);
|
|
718
731
|
this.runPromise.reject(notifyError);
|
|
719
|
-
this.
|
|
732
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
720
733
|
Log === null || Log === void 0 ? void 0 : Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
|
|
721
734
|
return;
|
|
722
735
|
}
|
|
723
736
|
const notifyError = hdShared.ERRORS.TypedError(ERROR);
|
|
724
737
|
this.runPromise.reject(notifyError);
|
|
725
|
-
this.
|
|
738
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
726
739
|
Log === null || Log === void 0 ? void 0 : Log.debug(': monitor notify error, and has unreleased Promise', Error);
|
|
727
740
|
}
|
|
728
741
|
return;
|
|
@@ -758,7 +771,7 @@ class ReactNativeBleTransport {
|
|
|
758
771
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
|
|
759
772
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
760
773
|
(_j = this.runPromise) === null || _j === void 0 ? void 0 : _j.reject(notifyError);
|
|
761
|
-
this.
|
|
774
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
762
775
|
}
|
|
763
776
|
}, notifyTransactionId);
|
|
764
777
|
return subscription;
|
|
@@ -771,10 +784,11 @@ class ReactNativeBleTransport {
|
|
|
771
784
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
772
785
|
this.runPromise.reject(error);
|
|
773
786
|
this.runPromise = null;
|
|
774
|
-
this.
|
|
787
|
+
this.rejectAllProtocolV2Frames(error);
|
|
788
|
+
this.activeProtocolV2Call = null;
|
|
775
789
|
}
|
|
776
790
|
else {
|
|
777
|
-
this.resetProtocolV2Frames();
|
|
791
|
+
this.resetProtocolV2Frames(uuid);
|
|
778
792
|
}
|
|
779
793
|
if (transport) {
|
|
780
794
|
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
@@ -795,10 +809,12 @@ class ReactNativeBleTransport {
|
|
|
795
809
|
}
|
|
796
810
|
}
|
|
797
811
|
delete transportCache[uuid];
|
|
798
|
-
this.deviceProtocol.delete(uuid);
|
|
799
812
|
}
|
|
813
|
+
this.deviceProtocol.delete(uuid);
|
|
814
|
+
this.deviceProtocolHints.delete(uuid);
|
|
800
815
|
(_e = this.protocolV2Assemblers.get(uuid)) === null || _e === void 0 ? void 0 : _e.reset();
|
|
801
816
|
this.protocolV2Assemblers.delete(uuid);
|
|
817
|
+
this.resetProtocolV2Frames(uuid);
|
|
802
818
|
try {
|
|
803
819
|
yield ((_f = this.blePlxManager) === null || _f === void 0 ? void 0 : _f.cancelTransaction(uuid));
|
|
804
820
|
}
|
|
@@ -957,7 +973,7 @@ class ReactNativeBleTransport {
|
|
|
957
973
|
this.stopped = true;
|
|
958
974
|
}
|
|
959
975
|
disconnect(session) {
|
|
960
|
-
var _a, _b, _c, _d, _e;
|
|
976
|
+
var _a, _b, _c, _d, _e, _f;
|
|
961
977
|
return __awaiter(this, void 0, void 0, function* () {
|
|
962
978
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport resetSession: ', session);
|
|
963
979
|
const transport = transportCache[session];
|
|
@@ -1007,10 +1023,15 @@ class ReactNativeBleTransport {
|
|
|
1007
1023
|
delete transportCache[session];
|
|
1008
1024
|
}
|
|
1009
1025
|
this.deviceProtocol.delete(session);
|
|
1026
|
+
this.deviceProtocolHints.delete(session);
|
|
1010
1027
|
this.protocolV2Assemblers.delete(session);
|
|
1028
|
+
this.resetProtocolV2Frames(session);
|
|
1029
|
+
if (((_d = this.activeProtocolV2Call) === null || _d === void 0 ? void 0 : _d.uuid) === session) {
|
|
1030
|
+
this.activeProtocolV2Call = null;
|
|
1031
|
+
}
|
|
1011
1032
|
try {
|
|
1012
|
-
(
|
|
1013
|
-
name: (
|
|
1033
|
+
(_e = this.emitter) === null || _e === void 0 ? void 0 : _e.emit('device-disconnect', {
|
|
1034
|
+
name: (_f = transport === null || transport === void 0 ? void 0 : transport.device) === null || _f === void 0 ? void 0 : _f.name,
|
|
1014
1035
|
id: session,
|
|
1015
1036
|
connectId: session,
|
|
1016
1037
|
});
|
|
@@ -1036,7 +1057,7 @@ class ReactNativeBleTransport {
|
|
|
1036
1057
|
createProtocolMismatchError(expected) {
|
|
1037
1058
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1038
1059
|
}
|
|
1039
|
-
detectProtocol(uuid, expectedProtocol) {
|
|
1060
|
+
detectProtocol(uuid, expectedProtocol, protocolHint) {
|
|
1040
1061
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1041
1062
|
if (expectedProtocol === 'V1') {
|
|
1042
1063
|
if (yield this.probeProtocolV1(uuid)) {
|
|
@@ -1054,20 +1075,73 @@ class ReactNativeBleTransport {
|
|
|
1054
1075
|
}
|
|
1055
1076
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1056
1077
|
}
|
|
1078
|
+
if (protocolHint === 'V2' && (yield this.probeProtocolV2(uuid))) {
|
|
1079
|
+
this.deviceProtocol.set(uuid, 'V2');
|
|
1080
|
+
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (hint)`);
|
|
1081
|
+
return 'V2';
|
|
1082
|
+
}
|
|
1057
1083
|
if (this.deviceProtocol.get(uuid) === 'V2' && (yield this.probeProtocolV2(uuid))) {
|
|
1058
1084
|
this.deviceProtocol.set(uuid, 'V2');
|
|
1059
1085
|
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (cached)`);
|
|
1060
1086
|
return 'V2';
|
|
1061
1087
|
}
|
|
1062
1088
|
let protocol = 'V1';
|
|
1063
|
-
|
|
1064
|
-
|
|
1089
|
+
const protocolV1Detected = yield this.probeProtocolV1(uuid);
|
|
1090
|
+
if (!protocolV1Detected) {
|
|
1091
|
+
yield this.resetProbeStateAfterProtocolProbe(uuid, 'V1');
|
|
1092
|
+
if (yield this.probeProtocolV2(uuid)) {
|
|
1093
|
+
protocol = 'V2';
|
|
1094
|
+
}
|
|
1065
1095
|
}
|
|
1066
1096
|
this.deviceProtocol.set(uuid, protocol);
|
|
1067
1097
|
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> ${protocol}`);
|
|
1068
1098
|
return protocol;
|
|
1069
1099
|
});
|
|
1070
1100
|
}
|
|
1101
|
+
resetProbeStateAfterProtocolProbe(uuid, protocol) {
|
|
1102
|
+
var _a, _b, _c, _d;
|
|
1103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1104
|
+
const transport = transportCache[uuid];
|
|
1105
|
+
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1106
|
+
this.resetProtocolV2Frames(uuid);
|
|
1107
|
+
if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
|
|
1108
|
+
this.activeProtocolV2Call = null;
|
|
1109
|
+
}
|
|
1110
|
+
if (this.runPromise) {
|
|
1111
|
+
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1112
|
+
this.runPromise.reject(error);
|
|
1113
|
+
this.runPromise = null;
|
|
1114
|
+
}
|
|
1115
|
+
if (!transport)
|
|
1116
|
+
return;
|
|
1117
|
+
const previousNotifyTransactionId = transport.notifyTransactionId;
|
|
1118
|
+
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
1119
|
+
this.monitorTokens.delete(uuid);
|
|
1120
|
+
}
|
|
1121
|
+
(_c = transport.notifySubscription) === null || _c === void 0 ? void 0 : _c.remove();
|
|
1122
|
+
transport.notifySubscription = undefined;
|
|
1123
|
+
if (previousNotifyTransactionId) {
|
|
1124
|
+
try {
|
|
1125
|
+
yield ((_d = this.blePlxManager) === null || _d === void 0 ? void 0 : _d.cancelTransaction(previousNotifyTransactionId));
|
|
1126
|
+
}
|
|
1127
|
+
catch (error) {
|
|
1128
|
+
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] cancel notify after Protocol ${protocol} probe failed:`, (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
const monitorToken = this.nextMonitorToken;
|
|
1132
|
+
this.nextMonitorToken += 1;
|
|
1133
|
+
const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
|
|
1134
|
+
transport.monitorToken = monitorToken;
|
|
1135
|
+
transport.notifyTransactionId = notifyTransactionId;
|
|
1136
|
+
this.monitorTokens.set(uuid, monitorToken);
|
|
1137
|
+
transport.notifySubscription = this._monitorCharacteristic(transport.notifyCharacteristic, uuid, monitorToken, notifyTransactionId);
|
|
1138
|
+
if (reactNative.Platform.OS === 'ios') {
|
|
1139
|
+
yield new Promise(resolve => {
|
|
1140
|
+
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1071
1145
|
probeProtocolV1(uuid) {
|
|
1072
1146
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1073
1147
|
if (!this._messages) {
|
|
@@ -1100,17 +1174,17 @@ class ReactNativeBleTransport {
|
|
|
1100
1174
|
onProbeFailed: () => {
|
|
1101
1175
|
var _a;
|
|
1102
1176
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1103
|
-
this.resetProtocolV2Frames();
|
|
1177
|
+
this.resetProtocolV2Frames(uuid);
|
|
1104
1178
|
},
|
|
1105
1179
|
});
|
|
1106
1180
|
});
|
|
1107
1181
|
}
|
|
1108
1182
|
handleProtocolV2Notification(uuid, data) {
|
|
1109
|
-
var _a, _b;
|
|
1183
|
+
var _a, _b, _c;
|
|
1110
1184
|
try {
|
|
1111
|
-
if (!this.runPromise) {
|
|
1112
|
-
(
|
|
1113
|
-
this.resetProtocolV2Frames();
|
|
1185
|
+
if (!this.runPromise || ((_a = this.activeProtocolV2Call) === null || _a === void 0 ? void 0 : _a.uuid) !== uuid) {
|
|
1186
|
+
(_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
|
|
1187
|
+
this.resetProtocolV2Frames(uuid);
|
|
1114
1188
|
return;
|
|
1115
1189
|
}
|
|
1116
1190
|
if (data.length === 0)
|
|
@@ -1120,50 +1194,63 @@ class ReactNativeBleTransport {
|
|
|
1120
1194
|
return;
|
|
1121
1195
|
let frameData = assembler.push(data);
|
|
1122
1196
|
while (frameData) {
|
|
1123
|
-
this.resolveProtocolV2Frame(frameData);
|
|
1197
|
+
this.resolveProtocolV2Frame(uuid, frameData);
|
|
1124
1198
|
frameData = assembler.push(new Uint8Array(0));
|
|
1125
1199
|
}
|
|
1126
1200
|
}
|
|
1127
1201
|
catch (error) {
|
|
1128
1202
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notification error:', error);
|
|
1129
1203
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1130
|
-
(
|
|
1131
|
-
this.
|
|
1204
|
+
(_c = this.runPromise) === null || _c === void 0 ? void 0 : _c.reject(notifyError);
|
|
1205
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
1132
1206
|
}
|
|
1133
1207
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1208
|
+
getProtocolV2FrameQueue(uuid) {
|
|
1209
|
+
let queue = this.protocolV2FrameQueues.get(uuid);
|
|
1210
|
+
if (!queue) {
|
|
1211
|
+
queue = [];
|
|
1212
|
+
this.protocolV2FrameQueues.set(uuid, queue);
|
|
1213
|
+
}
|
|
1214
|
+
return queue;
|
|
1215
|
+
}
|
|
1216
|
+
resolveProtocolV2Frame(uuid, frame) {
|
|
1217
|
+
const framePromise = this.protocolV2FramePromises.get(uuid);
|
|
1218
|
+
if (framePromise) {
|
|
1219
|
+
framePromise.resolve(frame);
|
|
1220
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1138
1221
|
return;
|
|
1139
1222
|
}
|
|
1140
|
-
this.
|
|
1223
|
+
this.getProtocolV2FrameQueue(uuid).push(frame);
|
|
1141
1224
|
}
|
|
1142
|
-
|
|
1143
|
-
this.
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
this.protocolV2FramePromise = null;
|
|
1225
|
+
rejectAllProtocolV2Frames(error) {
|
|
1226
|
+
this.protocolV2FrameQueues.clear();
|
|
1227
|
+
for (const framePromise of this.protocolV2FramePromises.values()) {
|
|
1228
|
+
framePromise.reject(error);
|
|
1147
1229
|
}
|
|
1230
|
+
this.protocolV2FramePromises.clear();
|
|
1231
|
+
}
|
|
1232
|
+
resetProtocolV2Frames(uuid) {
|
|
1233
|
+
this.protocolV2FrameQueues.delete(uuid);
|
|
1234
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1148
1235
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
this.
|
|
1236
|
+
isActiveProtocolV2Call(uuid, token) {
|
|
1237
|
+
var _a;
|
|
1238
|
+
return ((_a = this.activeProtocolV2Call) === null || _a === void 0 ? void 0 : _a.uuid) === uuid && this.activeProtocolV2Call.token === token;
|
|
1152
1239
|
}
|
|
1153
|
-
readProtocolV2Frame() {
|
|
1240
|
+
readProtocolV2Frame(uuid) {
|
|
1154
1241
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1155
|
-
const queuedFrame = this.
|
|
1242
|
+
const queuedFrame = this.getProtocolV2FrameQueue(uuid).shift();
|
|
1156
1243
|
if (queuedFrame) {
|
|
1157
1244
|
return queuedFrame;
|
|
1158
1245
|
}
|
|
1159
1246
|
const framePromise = hdShared.createDeferred();
|
|
1160
|
-
this.
|
|
1247
|
+
this.protocolV2FramePromises.set(uuid, framePromise);
|
|
1161
1248
|
try {
|
|
1162
1249
|
return yield framePromise.promise;
|
|
1163
1250
|
}
|
|
1164
1251
|
finally {
|
|
1165
|
-
if (this.
|
|
1166
|
-
this.
|
|
1252
|
+
if (this.protocolV2FramePromises.get(uuid) === framePromise) {
|
|
1253
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1167
1254
|
}
|
|
1168
1255
|
}
|
|
1169
1256
|
});
|
|
@@ -1222,15 +1309,18 @@ class ReactNativeBleTransport {
|
|
|
1222
1309
|
}
|
|
1223
1310
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1224
1311
|
this.runPromise.reject(error);
|
|
1225
|
-
this.
|
|
1312
|
+
this.rejectAllProtocolV2Frames(error);
|
|
1226
1313
|
this.runPromise = null;
|
|
1314
|
+
this.activeProtocolV2Call = null;
|
|
1227
1315
|
}
|
|
1228
1316
|
const transport$1 = this.getCachedTransport(uuid);
|
|
1229
1317
|
const runPromise = hdShared.createDeferred();
|
|
1230
1318
|
runPromise.promise.catch(() => undefined);
|
|
1231
1319
|
this.runPromise = runPromise;
|
|
1320
|
+
const callToken = this.nextProtocolV2CallToken++;
|
|
1321
|
+
this.activeProtocolV2Call = { uuid, token: callToken };
|
|
1232
1322
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1233
|
-
this.resetProtocolV2Frames();
|
|
1323
|
+
this.resetProtocolV2Frames(uuid);
|
|
1234
1324
|
let completed = false;
|
|
1235
1325
|
const callOptions = Object.assign(Object.assign({}, options), { timeoutMs: (_b = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _b !== void 0 ? _b : BLE_RESPONSE_TIMEOUT_MS });
|
|
1236
1326
|
const highVolumeWrite = transport.LogBlockCommand.has(name);
|
|
@@ -1253,7 +1343,7 @@ class ReactNativeBleTransport {
|
|
|
1253
1343
|
router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
|
|
1254
1344
|
writeFrame: (frame) => this.writeProtocolV2Frame(transport$1, frame, { highVolume: highVolumeWrite }),
|
|
1255
1345
|
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1256
|
-
const rxFrame = yield this.readProtocolV2Frame();
|
|
1346
|
+
const rxFrame = yield this.readProtocolV2Frame(uuid);
|
|
1257
1347
|
if (!(rxFrame instanceof Uint8Array)) {
|
|
1258
1348
|
throw new Error('Protocol V2 response is not Uint8Array');
|
|
1259
1349
|
}
|
|
@@ -1268,16 +1358,21 @@ class ReactNativeBleTransport {
|
|
|
1268
1358
|
return result;
|
|
1269
1359
|
}
|
|
1270
1360
|
catch (e) {
|
|
1271
|
-
(
|
|
1272
|
-
|
|
1361
|
+
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1362
|
+
(_c = this.protocolV2Assemblers.get(uuid)) === null || _c === void 0 ? void 0 : _c.reset();
|
|
1363
|
+
this.resetProtocolV2Frames(uuid);
|
|
1364
|
+
}
|
|
1273
1365
|
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
|
|
1274
1366
|
throw e;
|
|
1275
1367
|
}
|
|
1276
1368
|
finally {
|
|
1277
|
-
if (
|
|
1278
|
-
|
|
1369
|
+
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1370
|
+
if (!completed) {
|
|
1371
|
+
(_d = this.protocolV2Assemblers.get(uuid)) === null || _d === void 0 ? void 0 : _d.reset();
|
|
1372
|
+
}
|
|
1373
|
+
this.resetProtocolV2Frames(uuid);
|
|
1374
|
+
this.activeProtocolV2Call = null;
|
|
1279
1375
|
}
|
|
1280
|
-
this.resetProtocolV2Frames();
|
|
1281
1376
|
if (this.runPromise === runPromise) {
|
|
1282
1377
|
this.runPromise = null;
|
|
1283
1378
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-react-native",
|
|
3
|
-
"version": "1.1.27-alpha.
|
|
3
|
+
"version": "1.1.27-alpha.33",
|
|
4
4
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"lint:fix": "eslint . --fix"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@onekeyfe/hd-core": "1.1.27-alpha.
|
|
23
|
-
"@onekeyfe/hd-shared": "1.1.27-alpha.
|
|
24
|
-
"@onekeyfe/hd-transport": "1.1.27-alpha.
|
|
22
|
+
"@onekeyfe/hd-core": "1.1.27-alpha.33",
|
|
23
|
+
"@onekeyfe/hd-shared": "1.1.27-alpha.33",
|
|
24
|
+
"@onekeyfe/hd-transport": "1.1.27-alpha.33",
|
|
25
25
|
"@onekeyfe/react-native-ble-utils": "^0.1.4",
|
|
26
26
|
"react-native-ble-plx": "3.5.1"
|
|
27
27
|
},
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "c589e498b522a447b538d6dd61bf8d820ff86d79"
|
|
29
29
|
}
|
package/src/index.ts
CHANGED
|
@@ -125,7 +125,7 @@ export function getProtocolV2BleTuning() {
|
|
|
125
125
|
return { ...protocolV2BleTuning };
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
function
|
|
128
|
+
function inferProtocolHintFromDeviceName(name?: string | null): ProtocolType | undefined {
|
|
129
129
|
return /\bpro\s*2\b/i.test(name ?? '') ? 'V2' : undefined;
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -214,11 +214,17 @@ export default class ReactNativeBleTransport {
|
|
|
214
214
|
/** Per-device protocol type detected by active wire-level probe after connect. */
|
|
215
215
|
private deviceProtocol: Map<string, ProtocolType> = new Map();
|
|
216
216
|
|
|
217
|
+
private deviceProtocolHints: Map<string, ProtocolType> = new Map();
|
|
218
|
+
|
|
217
219
|
private protocolV2Assemblers: Map<string, ProtocolV2FrameAssembler> = new Map();
|
|
218
220
|
|
|
219
|
-
private
|
|
221
|
+
private protocolV2FrameQueues: Map<string, Uint8Array[]> = new Map();
|
|
222
|
+
|
|
223
|
+
private protocolV2FramePromises: Map<string, Deferred<Uint8Array>> = new Map();
|
|
220
224
|
|
|
221
|
-
private
|
|
225
|
+
private activeProtocolV2Call: { uuid: string; token: number } | null = null;
|
|
226
|
+
|
|
227
|
+
private nextProtocolV2CallToken = 1;
|
|
222
228
|
|
|
223
229
|
private monitorTokens: Map<string, number> = new Map();
|
|
224
230
|
|
|
@@ -370,12 +376,14 @@ export default class ReactNativeBleTransport {
|
|
|
370
376
|
const addDevice = (device: Device) => {
|
|
371
377
|
if (deviceList.every(d => d.id !== device.id)) {
|
|
372
378
|
const displayName = getDeviceDisplayName(device) ?? 'Unknown BLE Device';
|
|
373
|
-
const
|
|
379
|
+
const protocolHint = inferProtocolHintFromDeviceName(displayName);
|
|
380
|
+
if (protocolHint) {
|
|
381
|
+
this.deviceProtocolHints.set(device.id, protocolHint);
|
|
382
|
+
}
|
|
374
383
|
deviceList.push({
|
|
375
384
|
...device,
|
|
376
385
|
name: displayName,
|
|
377
386
|
commType: 'ble',
|
|
378
|
-
...(protocolType ? { protocolType } : {}),
|
|
379
387
|
} as IOneKeyDevice);
|
|
380
388
|
}
|
|
381
389
|
};
|
|
@@ -408,8 +416,9 @@ export default class ReactNativeBleTransport {
|
|
|
408
416
|
if (forceCleanRunPromise && this.runPromise) {
|
|
409
417
|
const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
|
|
410
418
|
this.runPromise.reject(error);
|
|
411
|
-
this.
|
|
419
|
+
this.rejectAllProtocolV2Frames(error);
|
|
412
420
|
this.runPromise = null;
|
|
421
|
+
this.activeProtocolV2Call = null;
|
|
413
422
|
Log?.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
|
|
414
423
|
}
|
|
415
424
|
|
|
@@ -591,8 +600,16 @@ export default class ReactNativeBleTransport {
|
|
|
591
600
|
);
|
|
592
601
|
}
|
|
593
602
|
|
|
603
|
+
const protocolHint = expectedProtocol
|
|
604
|
+
? undefined
|
|
605
|
+
: this.deviceProtocolHints.get(uuid) ??
|
|
606
|
+
inferProtocolHintFromDeviceName(getDeviceDisplayName(device));
|
|
607
|
+
|
|
594
608
|
// release transport before new transport instance
|
|
595
609
|
await this.release(uuid);
|
|
610
|
+
if (protocolHint) {
|
|
611
|
+
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
612
|
+
}
|
|
596
613
|
|
|
597
614
|
const transport = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
598
615
|
const monitorToken = this.nextMonitorToken;
|
|
@@ -617,7 +634,7 @@ export default class ReactNativeBleTransport {
|
|
|
617
634
|
});
|
|
618
635
|
}
|
|
619
636
|
|
|
620
|
-
const protocolType = await this.detectProtocol(uuid, expectedProtocol);
|
|
637
|
+
const protocolType = await this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
621
638
|
|
|
622
639
|
this.emitter?.emit('device-connect', {
|
|
623
640
|
name: device.name,
|
|
@@ -641,7 +658,7 @@ export default class ReactNativeBleTransport {
|
|
|
641
658
|
if (this.runPromise) {
|
|
642
659
|
const error = ERRORS.TypedError(HardwareErrorCode.BleConnectedError);
|
|
643
660
|
this.runPromise.reject(error);
|
|
644
|
-
this.
|
|
661
|
+
this.rejectAllProtocolV2Frames(error);
|
|
645
662
|
}
|
|
646
663
|
} catch (e) {
|
|
647
664
|
Log?.debug('device disconnect error: ', e);
|
|
@@ -696,7 +713,7 @@ export default class ReactNativeBleTransport {
|
|
|
696
713
|
HardwareErrorCode.BleCharacteristicNotifyChangeFailure
|
|
697
714
|
);
|
|
698
715
|
this.runPromise.reject(notifyError);
|
|
699
|
-
this.
|
|
716
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
700
717
|
Log?.debug(
|
|
701
718
|
`${HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`
|
|
702
719
|
);
|
|
@@ -704,7 +721,7 @@ export default class ReactNativeBleTransport {
|
|
|
704
721
|
}
|
|
705
722
|
const notifyError = ERRORS.TypedError(ERROR);
|
|
706
723
|
this.runPromise.reject(notifyError);
|
|
707
|
-
this.
|
|
724
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
708
725
|
Log?.debug(': monitor notify error, and has unreleased Promise', Error);
|
|
709
726
|
}
|
|
710
727
|
|
|
@@ -750,7 +767,7 @@ export default class ReactNativeBleTransport {
|
|
|
750
767
|
Log?.debug('monitor data error: ', error);
|
|
751
768
|
const notifyError = ERRORS.TypedError(HardwareErrorCode.BleWriteCharacteristicError);
|
|
752
769
|
this.runPromise?.reject(notifyError);
|
|
753
|
-
this.
|
|
770
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
754
771
|
}
|
|
755
772
|
}, notifyTransactionId);
|
|
756
773
|
|
|
@@ -763,9 +780,10 @@ export default class ReactNativeBleTransport {
|
|
|
763
780
|
const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
|
|
764
781
|
this.runPromise.reject(error);
|
|
765
782
|
this.runPromise = null;
|
|
766
|
-
this.
|
|
783
|
+
this.rejectAllProtocolV2Frames(error);
|
|
784
|
+
this.activeProtocolV2Call = null;
|
|
767
785
|
} else {
|
|
768
|
-
this.resetProtocolV2Frames();
|
|
786
|
+
this.resetProtocolV2Frames(uuid);
|
|
769
787
|
}
|
|
770
788
|
|
|
771
789
|
if (transport) {
|
|
@@ -795,11 +813,13 @@ export default class ReactNativeBleTransport {
|
|
|
795
813
|
}
|
|
796
814
|
|
|
797
815
|
delete transportCache[uuid];
|
|
798
|
-
this.deviceProtocol.delete(uuid);
|
|
799
816
|
}
|
|
800
817
|
|
|
818
|
+
this.deviceProtocol.delete(uuid);
|
|
819
|
+
this.deviceProtocolHints.delete(uuid);
|
|
801
820
|
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
802
821
|
this.protocolV2Assemblers.delete(uuid);
|
|
822
|
+
this.resetProtocolV2Frames(uuid);
|
|
803
823
|
|
|
804
824
|
try {
|
|
805
825
|
await this.blePlxManager?.cancelTransaction(uuid);
|
|
@@ -1053,7 +1073,12 @@ export default class ReactNativeBleTransport {
|
|
|
1053
1073
|
delete transportCache[session];
|
|
1054
1074
|
}
|
|
1055
1075
|
this.deviceProtocol.delete(session);
|
|
1076
|
+
this.deviceProtocolHints.delete(session);
|
|
1056
1077
|
this.protocolV2Assemblers.delete(session);
|
|
1078
|
+
this.resetProtocolV2Frames(session);
|
|
1079
|
+
if (this.activeProtocolV2Call?.uuid === session) {
|
|
1080
|
+
this.activeProtocolV2Call = null;
|
|
1081
|
+
}
|
|
1057
1082
|
|
|
1058
1083
|
// emit the disconnect event
|
|
1059
1084
|
try {
|
|
@@ -1094,7 +1119,8 @@ export default class ReactNativeBleTransport {
|
|
|
1094
1119
|
|
|
1095
1120
|
private async detectProtocol(
|
|
1096
1121
|
uuid: string,
|
|
1097
|
-
expectedProtocol?: ProtocolType
|
|
1122
|
+
expectedProtocol?: ProtocolType,
|
|
1123
|
+
protocolHint?: ProtocolType
|
|
1098
1124
|
): Promise<ProtocolType> {
|
|
1099
1125
|
if (expectedProtocol === 'V1') {
|
|
1100
1126
|
if (await this.probeProtocolV1(uuid)) {
|
|
@@ -1114,6 +1140,12 @@ export default class ReactNativeBleTransport {
|
|
|
1114
1140
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1115
1141
|
}
|
|
1116
1142
|
|
|
1143
|
+
if (protocolHint === 'V2' && (await this.probeProtocolV2(uuid))) {
|
|
1144
|
+
this.deviceProtocol.set(uuid, 'V2');
|
|
1145
|
+
Log?.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (hint)`);
|
|
1146
|
+
return 'V2';
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1117
1149
|
if (this.deviceProtocol.get(uuid) === 'V2' && (await this.probeProtocolV2(uuid))) {
|
|
1118
1150
|
this.deviceProtocol.set(uuid, 'V2');
|
|
1119
1151
|
Log?.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (cached)`);
|
|
@@ -1121,14 +1153,69 @@ export default class ReactNativeBleTransport {
|
|
|
1121
1153
|
}
|
|
1122
1154
|
|
|
1123
1155
|
let protocol: ProtocolType = 'V1';
|
|
1124
|
-
|
|
1125
|
-
|
|
1156
|
+
const protocolV1Detected = await this.probeProtocolV1(uuid);
|
|
1157
|
+
if (!protocolV1Detected) {
|
|
1158
|
+
await this.resetProbeStateAfterProtocolProbe(uuid, 'V1');
|
|
1159
|
+
if (await this.probeProtocolV2(uuid)) {
|
|
1160
|
+
protocol = 'V2';
|
|
1161
|
+
}
|
|
1126
1162
|
}
|
|
1127
1163
|
this.deviceProtocol.set(uuid, protocol);
|
|
1128
1164
|
Log?.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> ${protocol}`);
|
|
1129
1165
|
return protocol;
|
|
1130
1166
|
}
|
|
1131
1167
|
|
|
1168
|
+
private async resetProbeStateAfterProtocolProbe(uuid: string, protocol: ProtocolType) {
|
|
1169
|
+
const transport = transportCache[uuid];
|
|
1170
|
+
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
1171
|
+
this.resetProtocolV2Frames(uuid);
|
|
1172
|
+
if (this.activeProtocolV2Call?.uuid === uuid) {
|
|
1173
|
+
this.activeProtocolV2Call = null;
|
|
1174
|
+
}
|
|
1175
|
+
if (this.runPromise) {
|
|
1176
|
+
const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
|
|
1177
|
+
this.runPromise.reject(error);
|
|
1178
|
+
this.runPromise = null;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
if (!transport) return;
|
|
1182
|
+
|
|
1183
|
+
const previousNotifyTransactionId = transport.notifyTransactionId;
|
|
1184
|
+
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
1185
|
+
this.monitorTokens.delete(uuid);
|
|
1186
|
+
}
|
|
1187
|
+
transport.notifySubscription?.remove();
|
|
1188
|
+
transport.notifySubscription = undefined;
|
|
1189
|
+
if (previousNotifyTransactionId) {
|
|
1190
|
+
try {
|
|
1191
|
+
await this.blePlxManager?.cancelTransaction(previousNotifyTransactionId);
|
|
1192
|
+
} catch (error) {
|
|
1193
|
+
Log?.debug(
|
|
1194
|
+
`[ReactNativeBleTransport] cancel notify after Protocol ${protocol} probe failed:`,
|
|
1195
|
+
error?.message || error
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
const monitorToken = this.nextMonitorToken;
|
|
1201
|
+
this.nextMonitorToken += 1;
|
|
1202
|
+
const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
|
|
1203
|
+
transport.monitorToken = monitorToken;
|
|
1204
|
+
transport.notifyTransactionId = notifyTransactionId;
|
|
1205
|
+
this.monitorTokens.set(uuid, monitorToken);
|
|
1206
|
+
transport.notifySubscription = this._monitorCharacteristic(
|
|
1207
|
+
transport.notifyCharacteristic,
|
|
1208
|
+
uuid,
|
|
1209
|
+
monitorToken,
|
|
1210
|
+
notifyTransactionId
|
|
1211
|
+
);
|
|
1212
|
+
if (Platform.OS === 'ios') {
|
|
1213
|
+
await new Promise<void>(resolve => {
|
|
1214
|
+
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1132
1219
|
private async probeProtocolV1(uuid: string) {
|
|
1133
1220
|
if (!this._messages) {
|
|
1134
1221
|
return false;
|
|
@@ -1159,16 +1246,16 @@ export default class ReactNativeBleTransport {
|
|
|
1159
1246
|
logPrefix: 'ProtocolV2 RN-BLE',
|
|
1160
1247
|
onProbeFailed: () => {
|
|
1161
1248
|
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
1162
|
-
this.resetProtocolV2Frames();
|
|
1249
|
+
this.resetProtocolV2Frames(uuid);
|
|
1163
1250
|
},
|
|
1164
1251
|
});
|
|
1165
1252
|
}
|
|
1166
1253
|
|
|
1167
1254
|
private handleProtocolV2Notification(uuid: string, data: Uint8Array) {
|
|
1168
1255
|
try {
|
|
1169
|
-
if (!this.runPromise) {
|
|
1256
|
+
if (!this.runPromise || this.activeProtocolV2Call?.uuid !== uuid) {
|
|
1170
1257
|
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
1171
|
-
this.resetProtocolV2Frames();
|
|
1258
|
+
this.resetProtocolV2Frames(uuid);
|
|
1172
1259
|
return;
|
|
1173
1260
|
}
|
|
1174
1261
|
|
|
@@ -1179,52 +1266,66 @@ export default class ReactNativeBleTransport {
|
|
|
1179
1266
|
|
|
1180
1267
|
let frameData = assembler.push(data);
|
|
1181
1268
|
while (frameData) {
|
|
1182
|
-
this.resolveProtocolV2Frame(frameData);
|
|
1269
|
+
this.resolveProtocolV2Frame(uuid, frameData);
|
|
1183
1270
|
frameData = assembler.push(new Uint8Array(0));
|
|
1184
1271
|
}
|
|
1185
1272
|
} catch (error) {
|
|
1186
1273
|
Log?.debug('[ReactNativeBleTransport] Protocol V2 notification error:', error);
|
|
1187
1274
|
const notifyError = ERRORS.TypedError(HardwareErrorCode.BleWriteCharacteristicError);
|
|
1188
1275
|
this.runPromise?.reject(notifyError);
|
|
1189
|
-
this.
|
|
1276
|
+
this.rejectAllProtocolV2Frames(notifyError);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
private getProtocolV2FrameQueue(uuid: string) {
|
|
1281
|
+
let queue = this.protocolV2FrameQueues.get(uuid);
|
|
1282
|
+
if (!queue) {
|
|
1283
|
+
queue = [];
|
|
1284
|
+
this.protocolV2FrameQueues.set(uuid, queue);
|
|
1190
1285
|
}
|
|
1286
|
+
return queue;
|
|
1191
1287
|
}
|
|
1192
1288
|
|
|
1193
|
-
private resolveProtocolV2Frame(frame: Uint8Array) {
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1289
|
+
private resolveProtocolV2Frame(uuid: string, frame: Uint8Array) {
|
|
1290
|
+
const framePromise = this.protocolV2FramePromises.get(uuid);
|
|
1291
|
+
if (framePromise) {
|
|
1292
|
+
framePromise.resolve(frame);
|
|
1293
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1197
1294
|
return;
|
|
1198
1295
|
}
|
|
1199
|
-
this.
|
|
1296
|
+
this.getProtocolV2FrameQueue(uuid).push(frame);
|
|
1200
1297
|
}
|
|
1201
1298
|
|
|
1202
|
-
private
|
|
1203
|
-
this.
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
this.protocolV2FramePromise = null;
|
|
1299
|
+
private rejectAllProtocolV2Frames(error: Error) {
|
|
1300
|
+
this.protocolV2FrameQueues.clear();
|
|
1301
|
+
for (const framePromise of this.protocolV2FramePromises.values()) {
|
|
1302
|
+
framePromise.reject(error);
|
|
1207
1303
|
}
|
|
1304
|
+
this.protocolV2FramePromises.clear();
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
private resetProtocolV2Frames(uuid: string) {
|
|
1308
|
+
this.protocolV2FrameQueues.delete(uuid);
|
|
1309
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1208
1310
|
}
|
|
1209
1311
|
|
|
1210
|
-
private
|
|
1211
|
-
this.
|
|
1212
|
-
this.protocolV2FramePromise = null;
|
|
1312
|
+
private isActiveProtocolV2Call(uuid: string, token: number) {
|
|
1313
|
+
return this.activeProtocolV2Call?.uuid === uuid && this.activeProtocolV2Call.token === token;
|
|
1213
1314
|
}
|
|
1214
1315
|
|
|
1215
|
-
private async readProtocolV2Frame() {
|
|
1216
|
-
const queuedFrame = this.
|
|
1316
|
+
private async readProtocolV2Frame(uuid: string) {
|
|
1317
|
+
const queuedFrame = this.getProtocolV2FrameQueue(uuid).shift();
|
|
1217
1318
|
if (queuedFrame) {
|
|
1218
1319
|
return queuedFrame;
|
|
1219
1320
|
}
|
|
1220
1321
|
|
|
1221
1322
|
const framePromise = createDeferred<Uint8Array>();
|
|
1222
|
-
this.
|
|
1323
|
+
this.protocolV2FramePromises.set(uuid, framePromise);
|
|
1223
1324
|
try {
|
|
1224
1325
|
return await framePromise.promise;
|
|
1225
1326
|
} finally {
|
|
1226
|
-
if (this.
|
|
1227
|
-
this.
|
|
1327
|
+
if (this.protocolV2FramePromises.get(uuid) === framePromise) {
|
|
1328
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1228
1329
|
}
|
|
1229
1330
|
}
|
|
1230
1331
|
}
|
|
@@ -1298,16 +1399,19 @@ export default class ReactNativeBleTransport {
|
|
|
1298
1399
|
}
|
|
1299
1400
|
const error = ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise);
|
|
1300
1401
|
this.runPromise.reject(error);
|
|
1301
|
-
this.
|
|
1402
|
+
this.rejectAllProtocolV2Frames(error);
|
|
1302
1403
|
this.runPromise = null;
|
|
1404
|
+
this.activeProtocolV2Call = null;
|
|
1303
1405
|
}
|
|
1304
1406
|
|
|
1305
1407
|
const transport = this.getCachedTransport(uuid);
|
|
1306
1408
|
const runPromise = createDeferred<Uint8Array>();
|
|
1307
1409
|
runPromise.promise.catch(() => undefined);
|
|
1308
1410
|
this.runPromise = runPromise;
|
|
1411
|
+
const callToken = this.nextProtocolV2CallToken++;
|
|
1412
|
+
this.activeProtocolV2Call = { uuid, token: callToken };
|
|
1309
1413
|
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
1310
|
-
this.resetProtocolV2Frames();
|
|
1414
|
+
this.resetProtocolV2Frames(uuid);
|
|
1311
1415
|
let completed = false;
|
|
1312
1416
|
const callOptions = {
|
|
1313
1417
|
...options,
|
|
@@ -1341,7 +1445,7 @@ export default class ReactNativeBleTransport {
|
|
|
1341
1445
|
writeFrame: (frame: Uint8Array) =>
|
|
1342
1446
|
this.writeProtocolV2Frame(transport, frame, { highVolume: highVolumeWrite }),
|
|
1343
1447
|
readFrame: async () => {
|
|
1344
|
-
const rxFrame = await this.readProtocolV2Frame();
|
|
1448
|
+
const rxFrame = await this.readProtocolV2Frame(uuid);
|
|
1345
1449
|
if (!(rxFrame instanceof Uint8Array)) {
|
|
1346
1450
|
throw new Error('Protocol V2 response is not Uint8Array');
|
|
1347
1451
|
}
|
|
@@ -1360,15 +1464,20 @@ export default class ReactNativeBleTransport {
|
|
|
1360
1464
|
completed = true;
|
|
1361
1465
|
return result;
|
|
1362
1466
|
} catch (e) {
|
|
1363
|
-
this.
|
|
1364
|
-
|
|
1467
|
+
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1468
|
+
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
1469
|
+
this.resetProtocolV2Frames(uuid);
|
|
1470
|
+
}
|
|
1365
1471
|
Log?.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
|
|
1366
1472
|
throw e;
|
|
1367
1473
|
} finally {
|
|
1368
|
-
if (
|
|
1369
|
-
|
|
1474
|
+
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1475
|
+
if (!completed) {
|
|
1476
|
+
this.protocolV2Assemblers.get(uuid)?.reset();
|
|
1477
|
+
}
|
|
1478
|
+
this.resetProtocolV2Frames(uuid);
|
|
1479
|
+
this.activeProtocolV2Call = null;
|
|
1370
1480
|
}
|
|
1371
|
-
this.resetProtocolV2Frames();
|
|
1372
1481
|
if (this.runPromise === runPromise) {
|
|
1373
1482
|
this.runPromise = null;
|
|
1374
1483
|
}
|