@ledgerhq/react-native-hw-transport-ble 6.28.5 → 6.28.6-nightly.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +11 -0
  3. package/lib/BleTransport.d.ts.map +1 -1
  4. package/lib/BleTransport.js +424 -623
  5. package/lib/BleTransport.js.map +1 -1
  6. package/lib/BleTransport.test.js +146 -248
  7. package/lib/BleTransport.test.js.map +1 -1
  8. package/lib/awaitsBleOn.js +25 -28
  9. package/lib/awaitsBleOn.js.map +1 -1
  10. package/lib/monitorCharacteristic.js +26 -28
  11. package/lib/monitorCharacteristic.js.map +1 -1
  12. package/lib/remapErrors.d.ts +3 -1
  13. package/lib/remapErrors.d.ts.map +1 -1
  14. package/lib/remapErrors.js +22 -13
  15. package/lib/remapErrors.js.map +1 -1
  16. package/lib/timer.js +12 -12
  17. package/lib/timer.js.map +1 -1
  18. package/lib/types.d.ts +3 -3
  19. package/lib/types.d.ts.map +1 -1
  20. package/lib/types.js +1 -1
  21. package/lib-es/BleTransport.d.ts.map +1 -1
  22. package/lib-es/BleTransport.js +412 -612
  23. package/lib-es/BleTransport.js.map +1 -1
  24. package/lib-es/BleTransport.test.js +143 -245
  25. package/lib-es/BleTransport.test.js.map +1 -1
  26. package/lib-es/awaitsBleOn.js +21 -24
  27. package/lib-es/awaitsBleOn.js.map +1 -1
  28. package/lib-es/monitorCharacteristic.js +22 -24
  29. package/lib-es/monitorCharacteristic.js.map +1 -1
  30. package/lib-es/remapErrors.d.ts +3 -1
  31. package/lib-es/remapErrors.d.ts.map +1 -1
  32. package/lib-es/remapErrors.js +22 -13
  33. package/lib-es/remapErrors.js.map +1 -1
  34. package/lib-es/timer.js +10 -10
  35. package/lib-es/timer.js.map +1 -1
  36. package/lib-es/types.d.ts +3 -3
  37. package/lib-es/types.d.ts.map +1 -1
  38. package/package.json +6 -7
  39. package/src/BleTransport.test.ts +22 -2
  40. package/src/BleTransport.ts +27 -8
  41. package/src/remapErrors.ts +17 -3
@@ -1,18 +1,3 @@
1
- var __extends = (this && this.__extends) || (function () {
2
- var extendStatics = function (d, b) {
3
- extendStatics = Object.setPrototypeOf ||
4
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6
- return extendStatics(d, b);
7
- };
8
- return function (d, b) {
9
- if (typeof b !== "function" && b !== null)
10
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11
- extendStatics(d, b);
12
- function __() { this.constructor = d; }
13
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
- };
15
- })();
16
1
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
2
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
3
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -22,60 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
22
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
23
8
  });
24
9
  };
25
- var __generator = (this && this.__generator) || function (thisArg, body) {
26
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
27
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28
- function verb(n) { return function (v) { return step([n, v]); }; }
29
- function step(op) {
30
- if (f) throw new TypeError("Generator is already executing.");
31
- while (_) try {
32
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33
- if (y = 0, t) op = [op[0] & 2, t.value];
34
- switch (op[0]) {
35
- case 0: case 1: t = op; break;
36
- case 4: _.label++; return { value: op[1], done: false };
37
- case 5: _.label++; y = op[1]; op = [0]; continue;
38
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
39
- default:
40
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44
- if (t[2]) _.ops.pop();
45
- _.trys.pop(); continue;
46
- }
47
- op = body.call(thisArg, _);
48
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
- }
51
- };
52
- var __read = (this && this.__read) || function (o, n) {
53
- var m = typeof Symbol === "function" && o[Symbol.iterator];
54
- if (!m) return o;
55
- var i = m.call(o), r, ar = [], e;
56
- try {
57
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
58
- }
59
- catch (error) { e = { error: error }; }
60
- finally {
61
- try {
62
- if (r && !r.done && (m = i["return"])) m.call(i);
63
- }
64
- finally { if (e) throw e.error; }
65
- }
66
- return ar;
67
- };
68
- var __values = (this && this.__values) || function(o) {
69
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
70
- if (m) return m.call(o);
71
- if (o && typeof o.length === "number") return {
72
- next: function () {
73
- if (o && i >= o.length) o = void 0;
74
- return { value: o && o[i++], done: !o };
75
- }
76
- };
77
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
78
- };
10
+ var _a;
79
11
  import Transport from "@ledgerhq/hw-transport";
80
12
  // ---------------------------------------------------------------------------------------------
81
13
  // Since this is a react-native library and metro bundler does not support
@@ -92,48 +24,49 @@ import { getBluetoothServiceUuids, getInfosForServiceUuid, } from "@ledgerhq/dev
92
24
  import { log } from "@ledgerhq/logs";
93
25
  import { defer, merge, from, of, throwError } from "rxjs";
94
26
  import { share, ignoreElements, first, map, tap, catchError, } from "rxjs/operators";
95
- import { CantOpenDevice, TransportError, DisconnectedDeviceDuringOperation, PairingFailed, } from "@ledgerhq/errors";
27
+ import { CantOpenDevice, TransportError, DisconnectedDeviceDuringOperation, PairingFailed, PeerRemovedPairing, } from "@ledgerhq/errors";
96
28
  import { monitorCharacteristic } from "./monitorCharacteristic";
97
29
  import { awaitsBleOn } from "./awaitsBleOn";
98
- import { decoratePromiseErrors, mapBleErrorToHwTransportError, remapError, } from "./remapErrors";
30
+ import { decoratePromiseErrors, remapError, mapBleErrorToHwTransportError, } from "./remapErrors";
99
31
  /**
100
32
  * This is potentially not needed anymore, to be checked if the bug is still
101
33
  * happening.
102
34
  */
103
- var reconnectionConfig = {
35
+ let reconnectionConfig = {
104
36
  pairingThreshold: 1000,
105
- delayAfterFirstPairing: 4000
37
+ delayAfterFirstPairing: 4000,
106
38
  };
107
- export var setReconnectionConfig = function (config) {
39
+ export const setReconnectionConfig = (config) => {
108
40
  reconnectionConfig = config;
109
41
  };
110
- var retrieveInfos = function (device) {
42
+ const retrieveInfos = (device) => {
111
43
  if (!device || !device.serviceUUIDs)
112
44
  return;
113
- var _a = __read(device.serviceUUIDs, 1), serviceUUID = _a[0];
45
+ const [serviceUUID] = device.serviceUUIDs;
114
46
  if (!serviceUUID)
115
47
  return;
116
- var infos = getInfosForServiceUuid(serviceUUID);
48
+ const infos = getInfosForServiceUuid(serviceUUID);
117
49
  if (!infos)
118
50
  return;
51
+ // If we retrieved information, update the cache
52
+ bluetoothInfoCache[device.id] = infos;
119
53
  return infos;
120
54
  };
121
- var delay = function (ms) {
122
- return new Promise(function (success) { return setTimeout(success, ms); });
123
- };
55
+ const delay = (ms) => new Promise((success) => setTimeout(success, ms));
124
56
  /**
125
57
  * A cache of Bluetooth transport instances associated with device IDs.
126
58
  * Allows efficient storage and retrieval of previously initialized transports.
127
59
  * @type {Object.<string, BluetoothTransport>}
128
60
  */
129
- var transportsCache = {};
61
+ const transportsCache = {};
62
+ const bluetoothInfoCache = {}; // Allows us to give more granulary error messages.
130
63
  // connectOptions is actually used by react-native-ble-plx even if comment above ConnectionOptions says it's not used
131
- var connectOptions = {
64
+ let connectOptions = {
132
65
  // 156 bytes to max the iOS < 10 limit (158 bytes)
133
66
  // (185 bytes for iOS >= 10)(up to 512 bytes for Android, but could be blocked at 23 bytes)
134
67
  requestMTU: 156,
135
68
  // Priority 1 = high. TODO: Check firmware update over BLE PR before merging
136
- connectionPriority: 1
69
+ connectionPriority: 1,
137
70
  };
138
71
  /**
139
72
  * Returns the instance of the Bluetooth Low Energy Manager. It initializes it only
@@ -142,265 +75,219 @@ var connectOptions = {
142
75
  * Use this function instead.
143
76
  * @returns {BleManager} - The instance of the BleManager.
144
77
  */
145
- var _bleManager = null;
146
- var bleManagerInstance = function () {
78
+ let _bleManager = null;
79
+ const bleManagerInstance = () => {
147
80
  if (!_bleManager) {
148
81
  _bleManager = new BleManager();
149
82
  }
150
83
  return _bleManager;
151
84
  };
152
- var clearDisconnectTimeout = function (deviceId) {
153
- var cachedTransport = transportsCache[deviceId];
85
+ const clearDisconnectTimeout = (deviceId) => {
86
+ const cachedTransport = transportsCache[deviceId];
154
87
  if (cachedTransport && cachedTransport.disconnectTimeout) {
155
88
  log(TAG, "Clearing queued disconnect");
156
89
  clearTimeout(cachedTransport.disconnectTimeout);
157
90
  }
158
91
  };
159
92
  function open(deviceOrId, needsReconnect) {
160
- return __awaiter(this, void 0, void 0, function () {
161
- var device, devices, connectedDevices, connectedDevicesFiltered, e_1, e_2, res, characteristics, _a, _b, uuid, e_3, e_4_1, deviceModel, serviceUuid, writeUuid, writeCmdUuid, notifyUuid, writeC, writeCmdC, notifyC, characteristics_1, characteristics_1_1, c, notifyObservable, notif, transport, disconnectedSub, onDisconnect, beforeMTUTime, afterMTUTime;
162
- var _c, _d, e_4, _e, e_5, _f;
163
- return __generator(this, function (_g) {
164
- switch (_g.label) {
165
- case 0:
166
- log(TAG, "open with ".concat(deviceOrId));
167
- if (!(typeof deviceOrId === "string")) return [3 /*break*/, 12];
168
- if (transportsCache[deviceOrId]) {
169
- log(TAG, "Transport in cache, using that.");
170
- clearDisconnectTimeout(deviceOrId);
171
- return [2 /*return*/, transportsCache[deviceOrId]];
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ let device;
95
+ log(TAG, `open with ${deviceOrId}`);
96
+ if (typeof deviceOrId === "string") {
97
+ if (transportsCache[deviceOrId]) {
98
+ log(TAG, "Transport in cache, using that.");
99
+ clearDisconnectTimeout(deviceOrId);
100
+ return transportsCache[deviceOrId];
101
+ }
102
+ log(TAG, `Tries to open device: ${deviceOrId}`);
103
+ yield awaitsBleOn(bleManagerInstance());
104
+ // Returns a list of known devices by their identifiers
105
+ const devices = yield bleManagerInstance().devices([deviceOrId]);
106
+ log(TAG, `found ${devices.length} devices`);
107
+ [device] = devices;
108
+ if (!device) {
109
+ // Returns a list of the peripherals currently connected to the system
110
+ // which have discovered services, connected to system doesn't mean
111
+ // connected to our app, we check that below.
112
+ const connectedDevices = yield bleManagerInstance().connectedDevices(getBluetoothServiceUuids());
113
+ const connectedDevicesFiltered = connectedDevices.filter((d) => d.id === deviceOrId);
114
+ log(TAG, `found ${connectedDevicesFiltered.length} connected devices`);
115
+ [device] = connectedDevicesFiltered;
116
+ }
117
+ if (!device) {
118
+ // We still don't have a device, so we attempt to connect to it.
119
+ log(TAG, `connectToDevice(${deviceOrId})`);
120
+ // Nb ConnectionOptions dropped since it's not used internally by ble-plx.
121
+ try {
122
+ device = yield bleManagerInstance().connectToDevice(deviceOrId, connectOptions);
123
+ }
124
+ catch (e) {
125
+ log(TAG, `error code ${e.errorCode}`);
126
+ if (e.errorCode === BleErrorCode.DeviceMTUChangeFailed) {
127
+ // If the MTU update did not work, we try to connect without requesting for a specific MTU
128
+ connectOptions = {};
129
+ device = yield bleManagerInstance().connectToDevice(deviceOrId);
172
130
  }
173
- log(TAG, "Tries to open device: ".concat(deviceOrId));
174
- return [4 /*yield*/, awaitsBleOn(bleManagerInstance())];
175
- case 1:
176
- _g.sent();
177
- return [4 /*yield*/, bleManagerInstance().devices([deviceOrId])];
178
- case 2:
179
- devices = _g.sent();
180
- log(TAG, "found ".concat(devices.length, " devices"));
181
- _c = __read(devices, 1), device = _c[0];
182
- if (!!device) return [3 /*break*/, 4];
183
- return [4 /*yield*/, bleManagerInstance().connectedDevices(getBluetoothServiceUuids())];
184
- case 3:
185
- connectedDevices = _g.sent();
186
- connectedDevicesFiltered = connectedDevices.filter(function (d) { return d.id === deviceOrId; });
187
- log(TAG, "found ".concat(connectedDevicesFiltered.length, " connected devices"));
188
- _d = __read(connectedDevicesFiltered, 1), device = _d[0];
189
- _g.label = 4;
190
- case 4:
191
- if (!!device) return [3 /*break*/, 11];
192
- // We still don't have a device, so we attempt to connect to it.
193
- log(TAG, "connectToDevice(".concat(deviceOrId, ")"));
194
- _g.label = 5;
195
- case 5:
196
- _g.trys.push([5, 7, , 11]);
197
- return [4 /*yield*/, bleManagerInstance().connectToDevice(deviceOrId, connectOptions)];
198
- case 6:
199
- device = _g.sent();
200
- return [3 /*break*/, 11];
201
- case 7:
202
- e_1 = _g.sent();
203
- log(TAG, "error code ".concat(e_1.errorCode));
204
- if (!(e_1.errorCode === BleErrorCode.DeviceMTUChangeFailed)) return [3 /*break*/, 9];
205
- // If the MTU update did not work, we try to connect without requesting for a specific MTU
206
- connectOptions = {};
207
- return [4 /*yield*/, bleManagerInstance().connectToDevice(deviceOrId)];
208
- case 8:
209
- device = _g.sent();
210
- return [3 /*break*/, 10];
211
- case 9: throw e_1;
212
- case 10: return [3 /*break*/, 11];
213
- case 11:
214
- if (!device) {
215
- throw new CantOpenDevice();
131
+ else {
132
+ throw e;
216
133
  }
217
- return [3 /*break*/, 13];
218
- case 12:
219
- // It was already a Device
220
- device = deviceOrId;
221
- _g.label = 13;
222
- case 13: return [4 /*yield*/, device.isConnected()];
223
- case 14:
224
- if (!!(_g.sent())) return [3 /*break*/, 21];
225
- log(TAG, "not connected. connecting...");
226
- _g.label = 15;
227
- case 15:
228
- _g.trys.push([15, 17, , 21]);
229
- return [4 /*yield*/, device.connect(connectOptions)];
230
- case 16:
231
- _g.sent();
232
- return [3 /*break*/, 21];
233
- case 17:
234
- e_2 = _g.sent();
235
- if (!(e_2.errorCode === BleErrorCode.DeviceMTUChangeFailed)) return [3 /*break*/, 19];
236
- // If the MTU update did not work, we try to connect without requesting for a specific MTU
134
+ }
135
+ }
136
+ if (!device) {
137
+ throw new CantOpenDevice();
138
+ }
139
+ }
140
+ else {
141
+ // It was already a Device
142
+ device = deviceOrId;
143
+ }
144
+ if (!(yield device.isConnected())) {
145
+ log(TAG, "not connected. connecting...");
146
+ try {
147
+ yield device.connect(connectOptions);
148
+ }
149
+ catch (e) {
150
+ log("ble-verbose", `connect error - ${JSON.stringify(e)}`);
151
+ if (e.errorCode === BleErrorCode.DeviceMTUChangeFailed) {
152
+ log("ble-verbose", `device.mtu=${device.mtu}, reconnecting`);
237
153
  connectOptions = {};
238
- return [4 /*yield*/, device.connect()];
239
- case 18:
240
- _g.sent();
241
- return [3 /*break*/, 20];
242
- case 19: throw e_2;
243
- case 20: return [3 /*break*/, 21];
244
- case 21: return [4 /*yield*/, device.discoverAllServicesAndCharacteristics()];
245
- case 22:
246
- _g.sent();
247
- res = retrieveInfos(device);
248
- if (!!res) return [3 /*break*/, 32];
249
- _g.label = 23;
250
- case 23:
251
- _g.trys.push([23, 30, 31, 32]);
252
- _a = __values(getBluetoothServiceUuids()), _b = _a.next();
253
- _g.label = 24;
254
- case 24:
255
- if (!!_b.done) return [3 /*break*/, 29];
256
- uuid = _b.value;
257
- _g.label = 25;
258
- case 25:
259
- _g.trys.push([25, 27, , 28]);
260
- return [4 /*yield*/, device.characteristicsForService(uuid)];
261
- case 26:
262
- characteristics = _g.sent();
263
- res = getInfosForServiceUuid(uuid);
264
- return [3 /*break*/, 29];
265
- case 27:
266
- e_3 = _g.sent();
267
- return [3 /*break*/, 28];
268
- case 28:
269
- _b = _a.next();
270
- return [3 /*break*/, 24];
271
- case 29: return [3 /*break*/, 32];
272
- case 30:
273
- e_4_1 = _g.sent();
274
- e_4 = { error: e_4_1 };
275
- return [3 /*break*/, 32];
276
- case 31:
277
- try {
278
- if (_b && !_b.done && (_e = _a["return"])) _e.call(_a);
279
- }
280
- finally { if (e_4) throw e_4.error; }
281
- return [7 /*endfinally*/];
282
- case 32:
283
- if (!res) {
284
- throw new TransportError("service not found", "BLEServiceNotFound");
285
- }
286
- deviceModel = res.deviceModel, serviceUuid = res.serviceUuid, writeUuid = res.writeUuid, writeCmdUuid = res.writeCmdUuid, notifyUuid = res.notifyUuid;
287
- if (!!characteristics) return [3 /*break*/, 34];
288
- return [4 /*yield*/, device.characteristicsForService(serviceUuid)];
289
- case 33:
290
- characteristics = _g.sent();
291
- _g.label = 34;
292
- case 34:
293
- if (!characteristics) {
294
- throw new TransportError("service not found", "BLEServiceNotFound");
295
- }
296
- try {
297
- for (characteristics_1 = __values(characteristics), characteristics_1_1 = characteristics_1.next(); !characteristics_1_1.done; characteristics_1_1 = characteristics_1.next()) {
298
- c = characteristics_1_1.value;
299
- if (c.uuid === writeUuid) {
300
- writeC = c;
301
- }
302
- else if (c.uuid === writeCmdUuid) {
303
- writeCmdC = c;
304
- }
305
- else if (c.uuid === notifyUuid) {
306
- notifyC = c;
307
- }
308
- }
309
- }
310
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
311
- finally {
312
- try {
313
- if (characteristics_1_1 && !characteristics_1_1.done && (_f = characteristics_1["return"])) _f.call(characteristics_1);
314
- }
315
- finally { if (e_5) throw e_5.error; }
316
- }
317
- if (!writeC) {
318
- throw new TransportError("write characteristic not found", "BLECharacteristicNotFound");
319
- }
320
- if (!notifyC) {
321
- throw new TransportError("notify characteristic not found", "BLECharacteristicNotFound");
322
- }
323
- if (!writeC.isWritableWithResponse) {
324
- throw new TransportError("write characteristic not writableWithResponse", "BLECharacteristicInvalid");
325
- }
326
- if (!notifyC.isNotifiable) {
327
- throw new TransportError("notify characteristic not notifiable", "BLECharacteristicInvalid");
328
- }
329
- if (writeCmdC) {
330
- if (!writeCmdC.isWritableWithoutResponse) {
331
- throw new TransportError("write cmd characteristic not writableWithoutResponse", "BLECharacteristicInvalid");
332
- }
333
- }
334
- log(TAG, "device.mtu=".concat(device.mtu));
335
- notifyObservable = monitorCharacteristic(notifyC).pipe(catchError(function (e) {
336
- // LL-9033 fw 2.0.2 introduced this case, we silence the inner unhandled error.
337
- var msg = String(e);
338
- return msg.includes("notify change failed")
339
- ? of(new PairingFailed(msg))
340
- : throwError(e);
341
- }), tap(function (value) {
342
- if (value instanceof PairingFailed)
343
- return;
344
- log("ble-frame", "<= " + value.toString("hex"));
345
- }), share());
346
- notif = notifyObservable.subscribe();
347
- transport = new BleTransport(device, writeC, writeCmdC, notifyObservable, deviceModel);
348
- onDisconnect = function (e) {
349
- transport.isConnected = false;
350
- transport.notYetDisconnected = false;
351
- notif.unsubscribe();
352
- disconnectedSub === null || disconnectedSub === void 0 ? void 0 : disconnectedSub.remove();
353
- clearDisconnectTimeout(transport.id);
354
- delete transportsCache[transport.id];
355
- log(TAG, "BleTransport(".concat(transport.id, ") disconnected"));
356
- transport.emit("disconnect", e);
357
- };
358
- // eslint-disable-next-line require-atomic-updates
359
- transportsCache[transport.id] = transport;
360
- beforeMTUTime = Date.now();
361
- disconnectedSub = device.onDisconnected(function (e) {
362
- if (!transport.notYetDisconnected)
363
- return;
364
- onDisconnect(e);
154
+ yield device.connect();
155
+ }
156
+ else if (e.iosErrorCode === 14 ||
157
+ e.reason === "Peer removed pairing information") {
158
+ log("ble-verbose", "iOS broken pairing");
159
+ log("ble-verbose", JSON.stringify(device));
160
+ log("ble-verbose", JSON.stringify(bluetoothInfoCache[device.id]));
161
+ const { deviceModel } = bluetoothInfoCache[device.id] || {};
162
+ const { productName } = deviceModel || {};
163
+ throw new PeerRemovedPairing(undefined, {
164
+ deviceName: device.name,
165
+ productName,
365
166
  });
366
- _g.label = 35;
367
- case 35:
368
- _g.trys.push([35, , 37, 43]);
369
- return [4 /*yield*/, transport.inferMTU()];
370
- case 36:
371
- _g.sent();
372
- return [3 /*break*/, 43];
373
- case 37:
374
- afterMTUTime = Date.now();
375
- if (!reconnectionConfig) return [3 /*break*/, 41];
376
- // workaround for #279: we need to open() again if we come the first time here,
377
- // to make sure we do a disconnect() after the first pairing time
378
- // because of a firmware bug
379
- if (afterMTUTime - beforeMTUTime < reconnectionConfig.pairingThreshold) {
380
- needsReconnect = false; // (optim) there is likely no new pairing done because mtu answer was fast.
381
- }
382
- if (!needsReconnect) return [3 /*break*/, 40];
383
- // necessary time for the bonding workaround
384
- return [4 /*yield*/, BleTransport.disconnect(transport.id)["catch"](function () { })];
385
- case 38:
386
- // necessary time for the bonding workaround
387
- _g.sent();
388
- return [4 /*yield*/, delay(reconnectionConfig.delayAfterFirstPairing)];
389
- case 39:
390
- _g.sent();
391
- _g.label = 40;
392
- case 40: return [3 /*break*/, 42];
393
- case 41:
394
- needsReconnect = false;
395
- _g.label = 42;
396
- case 42: return [7 /*endfinally*/];
397
- case 43:
398
- if (needsReconnect) {
399
- return [2 /*return*/, open(device, false)];
400
- }
401
- return [2 /*return*/, transport];
167
+ }
168
+ else {
169
+ throw remapError(e);
170
+ }
402
171
  }
172
+ }
173
+ yield device.discoverAllServicesAndCharacteristics();
174
+ let res = retrieveInfos(device);
175
+ let characteristics;
176
+ if (!res) {
177
+ for (const uuid of getBluetoothServiceUuids()) {
178
+ try {
179
+ characteristics = yield device.characteristicsForService(uuid);
180
+ res = getInfosForServiceUuid(uuid);
181
+ break;
182
+ }
183
+ catch (e) {
184
+ // we attempt to connect to service
185
+ }
186
+ }
187
+ }
188
+ if (!res) {
189
+ throw new TransportError("service not found", "BLEServiceNotFound");
190
+ }
191
+ const { deviceModel, serviceUuid, writeUuid, writeCmdUuid, notifyUuid } = res;
192
+ if (!characteristics) {
193
+ characteristics = yield device.characteristicsForService(serviceUuid);
194
+ }
195
+ if (!characteristics) {
196
+ throw new TransportError("service not found", "BLEServiceNotFound");
197
+ }
198
+ let writeC;
199
+ let writeCmdC;
200
+ let notifyC;
201
+ for (const c of characteristics) {
202
+ if (c.uuid === writeUuid) {
203
+ writeC = c;
204
+ }
205
+ else if (c.uuid === writeCmdUuid) {
206
+ writeCmdC = c;
207
+ }
208
+ else if (c.uuid === notifyUuid) {
209
+ notifyC = c;
210
+ }
211
+ }
212
+ if (!writeC) {
213
+ throw new TransportError("write characteristic not found", "BLECharacteristicNotFound");
214
+ }
215
+ if (!notifyC) {
216
+ throw new TransportError("notify characteristic not found", "BLECharacteristicNotFound");
217
+ }
218
+ if (!writeC.isWritableWithResponse) {
219
+ throw new TransportError("write characteristic not writableWithResponse", "BLECharacteristicInvalid");
220
+ }
221
+ if (!notifyC.isNotifiable) {
222
+ throw new TransportError("notify characteristic not notifiable", "BLECharacteristicInvalid");
223
+ }
224
+ if (writeCmdC) {
225
+ if (!writeCmdC.isWritableWithoutResponse) {
226
+ throw new TransportError("write cmd characteristic not writableWithoutResponse", "BLECharacteristicInvalid");
227
+ }
228
+ }
229
+ log(TAG, `device.mtu=${device.mtu}`);
230
+ const notifyObservable = monitorCharacteristic(notifyC).pipe(catchError((e) => {
231
+ // LL-9033 fw 2.0.2 introduced this case, we silence the inner unhandled error.
232
+ const msg = String(e);
233
+ return msg.includes("notify change failed")
234
+ ? of(new PairingFailed(msg))
235
+ : throwError(e);
236
+ }), tap((value) => {
237
+ if (value instanceof PairingFailed)
238
+ return;
239
+ log("ble-frame", "<= " + value.toString("hex"));
240
+ }), share());
241
+ const notif = notifyObservable.subscribe();
242
+ const transport = new BleTransport(device, writeC, writeCmdC, notifyObservable, deviceModel);
243
+ // Keeping it as a comment for now but if no new bluetooth issues occur, we will be able to remove it
244
+ // await transport.requestConnectionPriority("High");
245
+ // eslint-disable-next-line prefer-const
246
+ let disconnectedSub;
247
+ const onDisconnect = (e) => {
248
+ transport.isConnected = false;
249
+ transport.notYetDisconnected = false;
250
+ notif.unsubscribe();
251
+ disconnectedSub === null || disconnectedSub === void 0 ? void 0 : disconnectedSub.remove();
252
+ clearDisconnectTimeout(transport.id);
253
+ delete transportsCache[transport.id];
254
+ log(TAG, `BleTransport(${transport.id}) disconnected`);
255
+ transport.emit("disconnect", e);
256
+ };
257
+ // eslint-disable-next-line require-atomic-updates
258
+ transportsCache[transport.id] = transport;
259
+ const beforeMTUTime = Date.now();
260
+ disconnectedSub = device.onDisconnected((e) => {
261
+ if (!transport.notYetDisconnected)
262
+ return;
263
+ onDisconnect(e);
403
264
  });
265
+ try {
266
+ yield transport.inferMTU();
267
+ }
268
+ finally {
269
+ const afterMTUTime = Date.now();
270
+ if (reconnectionConfig) {
271
+ // workaround for #279: we need to open() again if we come the first time here,
272
+ // to make sure we do a disconnect() after the first pairing time
273
+ // because of a firmware bug
274
+ if (afterMTUTime - beforeMTUTime < reconnectionConfig.pairingThreshold) {
275
+ needsReconnect = false; // (optim) there is likely no new pairing done because mtu answer was fast.
276
+ }
277
+ if (needsReconnect) {
278
+ // necessary time for the bonding workaround
279
+ yield BleTransport.disconnect(transport.id).catch(() => { });
280
+ yield delay(reconnectionConfig.delayAfterFirstPairing);
281
+ }
282
+ }
283
+ else {
284
+ needsReconnect = false;
285
+ }
286
+ }
287
+ if (needsReconnect) {
288
+ return open(device, false);
289
+ }
290
+ return transport;
404
291
  });
405
292
  }
406
293
  /**
@@ -408,255 +295,189 @@ function open(deviceOrId, needsReconnect) {
408
295
  * @example
409
296
  * import BleTransport from "@ledgerhq/react-native-hw-transport-ble";
410
297
  */
411
- var TAG = "ble-verbose";
412
- var BleTransport = /** @class */ (function (_super) {
413
- __extends(BleTransport, _super);
414
- function BleTransport(device, writeCharacteristic, writeCmdCharacteristic, notifyObservable, deviceModel) {
415
- var _this = _super.call(this) || this;
416
- _this.disconnectTimeout = null;
417
- _this.isConnected = true;
418
- _this.mtuSize = 20;
419
- _this.notYetDisconnected = true;
420
- /**
421
- * Send data to the device using a low level API.
422
- * It's recommended to use the "send" method for a higher level API.
423
- * @param {Buffer} apdu - The data to send.
424
- * @returns {Promise<Buffer>} A promise that resolves with the response data from the device.
425
- */
426
- _this.exchange = function (apdu) {
427
- return _this.exchangeAtomicImpl(function () { return __awaiter(_this, void 0, void 0, function () {
428
- var msgIn, data, msgOut, e_6;
429
- return __generator(this, function (_b) {
430
- switch (_b.label) {
431
- case 0:
432
- _b.trys.push([0, 2, , 5]);
433
- msgIn = apdu.toString("hex");
434
- log("apdu", "=> ".concat(msgIn));
435
- return [4 /*yield*/, merge(this.notifyObservable.pipe(receiveAPDU), sendAPDU(this.write, apdu, this.mtuSize)).toPromise()];
436
- case 1:
437
- data = _b.sent();
438
- msgOut = data.toString("hex");
439
- log("apdu", "<= ".concat(msgOut));
440
- return [2 /*return*/, data];
441
- case 2:
442
- e_6 = _b.sent();
443
- log("ble-error", "exchange got " + String(e_6));
444
- if (!this.notYetDisconnected) return [3 /*break*/, 4];
445
- // in such case we will always disconnect because something is bad.
446
- return [4 /*yield*/, bleManagerInstance()
447
- .cancelDeviceConnection(this.id)["catch"](function () { })];
448
- case 3:
449
- // in such case we will always disconnect because something is bad.
450
- _b.sent(); // but we ignore if disconnect worked.
451
- _b.label = 4;
452
- case 4: throw remapError(e_6);
453
- case 5: return [2 /*return*/];
454
- }
455
- });
456
- }); });
457
- };
458
- /**
459
- * Do not call this directly unless you know what you're doing. Communication
460
- * with a Ledger device should be through the {@link exchange} method.
461
- * @param buffer
462
- * @param txid
463
- */
464
- _this.write = function (buffer, txid) { return __awaiter(_this, void 0, void 0, function () {
465
- var e_7, e_8;
466
- return __generator(this, function (_b) {
467
- switch (_b.label) {
468
- case 0:
469
- log("ble-frame", "=> " + buffer.toString("hex"));
470
- if (!!this.writeCmdCharacteristic) return [3 /*break*/, 5];
471
- _b.label = 1;
472
- case 1:
473
- _b.trys.push([1, 3, , 4]);
474
- return [4 /*yield*/, this.writeCharacteristic.writeWithResponse(buffer.toString("base64"), txid)];
475
- case 2:
476
- _b.sent();
477
- return [3 /*break*/, 4];
478
- case 3:
479
- e_7 = _b.sent();
480
- throw new DisconnectedDeviceDuringOperation(e_7.message);
481
- case 4: return [3 /*break*/, 8];
482
- case 5:
483
- _b.trys.push([5, 7, , 8]);
484
- return [4 /*yield*/, this.writeCmdCharacteristic.writeWithoutResponse(buffer.toString("base64"), txid)];
485
- case 6:
486
- _b.sent();
487
- return [3 /*break*/, 8];
488
- case 7:
489
- e_8 = _b.sent();
490
- throw new DisconnectedDeviceDuringOperation(e_8.message);
491
- case 8: return [2 /*return*/];
492
- }
493
- });
494
- }); };
495
- _this.id = device.id;
496
- _this.device = device;
497
- _this.writeCharacteristic = writeCharacteristic;
498
- _this.writeCmdCharacteristic = writeCmdCharacteristic;
499
- _this.notifyObservable = notifyObservable;
500
- _this.deviceModel = deviceModel;
501
- log(TAG, "BleTransport(".concat(String(_this.id), ") new instance"));
502
- clearDisconnectTimeout(_this.id);
503
- return _this;
504
- }
298
+ const TAG = "ble-verbose";
299
+ export default class BleTransport extends Transport {
505
300
  /**
506
301
  * Listen to state changes on the bleManagerInstance and notify the
507
302
  * specified observer.
508
303
  * @param observer
509
304
  * @returns TransportSubscription
510
305
  */
511
- BleTransport.observeState = function (observer) {
512
- var emitFromState = function (type) {
306
+ static observeState(observer) {
307
+ const emitFromState = (type) => {
513
308
  observer.next({
514
- type: type,
515
- available: type === "PoweredOn"
309
+ type,
310
+ available: type === "PoweredOn",
516
311
  });
517
312
  };
518
313
  bleManagerInstance().onStateChange(emitFromState, true);
519
314
  return {
520
- unsubscribe: function () { }
315
+ unsubscribe: () => { },
521
316
  };
522
- };
317
+ }
523
318
  /**
524
319
  * Scan for bluetooth Ledger devices
525
320
  * @param observer Device is partial in order to avoid the live-common/this dep
526
321
  * @returns TransportSubscription
527
322
  */
528
- BleTransport.listen = function (observer) {
529
- var _this = this;
323
+ static listen(observer) {
530
324
  log(TAG, "listening for devices");
531
- var unsubscribed;
532
- var stateSub = bleManagerInstance().onStateChange(function (state) { return __awaiter(_this, void 0, void 0, function () {
533
- var devices;
534
- return __generator(this, function (_b) {
535
- switch (_b.label) {
536
- case 0:
537
- if (!(state === "PoweredOn")) return [3 /*break*/, 4];
538
- stateSub.remove();
539
- return [4 /*yield*/, bleManagerInstance().connectedDevices(getBluetoothServiceUuids())];
540
- case 1:
541
- devices = _b.sent();
542
- if (unsubscribed)
543
- return [2 /*return*/];
544
- if (!devices.length) return [3 /*break*/, 3];
545
- log(TAG, "disconnecting from devices");
546
- return [4 /*yield*/, Promise.all(devices.map(function (d) { return BleTransport.disconnect(d.id)["catch"](function () { }); }))];
547
- case 2:
548
- _b.sent();
549
- _b.label = 3;
550
- case 3:
551
- if (unsubscribed)
552
- return [2 /*return*/];
553
- bleManagerInstance().startDeviceScan(getBluetoothServiceUuids(), null, function (bleError, scannedDevice) {
554
- if (bleError) {
555
- observer.error(mapBleErrorToHwTransportError(bleError));
556
- unsubscribe();
557
- return;
558
- }
559
- var res = retrieveInfos(scannedDevice);
560
- var deviceModel = res && res.deviceModel;
561
- if (scannedDevice) {
562
- observer.next({
563
- type: "add",
564
- descriptor: scannedDevice,
565
- deviceModel: deviceModel
566
- });
567
- }
568
- });
569
- _b.label = 4;
570
- case 4: return [2 /*return*/];
325
+ let unsubscribed;
326
+ const stateSub = bleManagerInstance().onStateChange((state) => __awaiter(this, void 0, void 0, function* () {
327
+ if (state === "PoweredOn") {
328
+ stateSub.remove();
329
+ const devices = yield bleManagerInstance().connectedDevices(getBluetoothServiceUuids());
330
+ if (unsubscribed)
331
+ return;
332
+ if (devices.length) {
333
+ log(TAG, "disconnecting from devices");
334
+ yield Promise.all(devices.map((d) => BleTransport.disconnect(d.id).catch(() => { })));
571
335
  }
572
- });
573
- }); }, true);
574
- var unsubscribe = function () {
336
+ if (unsubscribed)
337
+ return;
338
+ bleManagerInstance().startDeviceScan(getBluetoothServiceUuids(), null, (bleError, scannedDevice) => {
339
+ if (bleError) {
340
+ observer.error(mapBleErrorToHwTransportError(bleError));
341
+ unsubscribe();
342
+ return;
343
+ }
344
+ const res = retrieveInfos(scannedDevice);
345
+ const deviceModel = res && res.deviceModel;
346
+ if (scannedDevice) {
347
+ observer.next({
348
+ type: "add",
349
+ descriptor: scannedDevice,
350
+ deviceModel,
351
+ });
352
+ }
353
+ });
354
+ }
355
+ }), true);
356
+ const unsubscribe = () => {
575
357
  unsubscribed = true;
576
358
  bleManagerInstance().stopDeviceScan();
577
359
  stateSub.remove();
578
360
  log(TAG, "done listening.");
579
361
  };
580
362
  return {
581
- unsubscribe: unsubscribe
363
+ unsubscribe,
582
364
  };
583
- };
365
+ }
584
366
  /**
585
367
  * Open a BLE transport
586
368
  * @param {Device | string} deviceOrId
587
369
  */
588
- BleTransport.open = function (deviceOrId) {
589
- return __awaiter(this, void 0, void 0, function () {
590
- return __generator(this, function (_b) {
591
- return [2 /*return*/, open(deviceOrId, true)];
592
- });
370
+ static open(deviceOrId) {
371
+ return __awaiter(this, void 0, void 0, function* () {
372
+ return open(deviceOrId, true);
373
+ });
374
+ }
375
+ constructor(device, writeCharacteristic, writeCmdCharacteristic, notifyObservable, deviceModel) {
376
+ super();
377
+ this.disconnectTimeout = null;
378
+ this.isConnected = true;
379
+ this.mtuSize = 20;
380
+ this.notYetDisconnected = true;
381
+ /**
382
+ * Send data to the device using a low level API.
383
+ * It's recommended to use the "send" method for a higher level API.
384
+ * @param {Buffer} apdu - The data to send.
385
+ * @returns {Promise<Buffer>} A promise that resolves with the response data from the device.
386
+ */
387
+ this.exchange = (apdu) => this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
388
+ try {
389
+ const msgIn = apdu.toString("hex");
390
+ log("apdu", `=> ${msgIn}`);
391
+ const data = yield merge(this.notifyObservable.pipe(receiveAPDU), sendAPDU(this.write, apdu, this.mtuSize)).toPromise();
392
+ const msgOut = data.toString("hex");
393
+ log("apdu", `<= ${msgOut}`);
394
+ return data;
395
+ }
396
+ catch (e) {
397
+ log("ble-error", "exchange got " + String(e));
398
+ if (this.notYetDisconnected) {
399
+ // in such case we will always disconnect because something is bad.
400
+ yield bleManagerInstance()
401
+ .cancelDeviceConnection(this.id)
402
+ .catch(() => { }); // but we ignore if disconnect worked.
403
+ }
404
+ throw remapError(e);
405
+ }
406
+ }));
407
+ /**
408
+ * Do not call this directly unless you know what you're doing. Communication
409
+ * with a Ledger device should be through the {@link exchange} method.
410
+ * @param buffer
411
+ * @param txid
412
+ */
413
+ this.write = (buffer, txid) => __awaiter(this, void 0, void 0, function* () {
414
+ log("ble-frame", "=> " + buffer.toString("hex"));
415
+ if (!this.writeCmdCharacteristic) {
416
+ try {
417
+ yield this.writeCharacteristic.writeWithResponse(buffer.toString("base64"), txid);
418
+ }
419
+ catch (e) {
420
+ throw new DisconnectedDeviceDuringOperation(e.message);
421
+ }
422
+ }
423
+ else {
424
+ try {
425
+ yield this.writeCmdCharacteristic.writeWithoutResponse(buffer.toString("base64"), txid);
426
+ }
427
+ catch (e) {
428
+ throw new DisconnectedDeviceDuringOperation(e.message);
429
+ }
430
+ }
593
431
  });
594
- };
432
+ this.id = device.id;
433
+ this.device = device;
434
+ this.writeCharacteristic = writeCharacteristic;
435
+ this.writeCmdCharacteristic = writeCmdCharacteristic;
436
+ this.notifyObservable = notifyObservable;
437
+ this.deviceModel = deviceModel;
438
+ log(TAG, `BleTransport(${String(this.id)}) new instance`);
439
+ clearDisconnectTimeout(this.id);
440
+ }
595
441
  /**
596
442
  * Negotiate with the device the maximum transfer unit for the ble frames
597
443
  * @returns Promise<number>
598
444
  */
599
- BleTransport.prototype.inferMTU = function () {
600
- return __awaiter(this, void 0, void 0, function () {
601
- var mtu;
602
- var _this = this;
603
- return __generator(this, function (_b) {
604
- switch (_b.label) {
605
- case 0:
606
- mtu = this.device.mtu;
607
- return [4 /*yield*/, this.exchangeAtomicImpl(function () { return __awaiter(_this, void 0, void 0, function () {
608
- var e_9;
609
- var _this = this;
610
- return __generator(this, function (_b) {
611
- switch (_b.label) {
612
- case 0:
613
- _b.trys.push([0, 2, , 4]);
614
- return [4 /*yield*/, merge(this.notifyObservable.pipe(tap(function (maybeError) {
615
- if (maybeError instanceof Error)
616
- throw maybeError;
617
- }), first(function (buffer) { return buffer.readUInt8(0) === 0x08; }), map(function (buffer) { return buffer.readUInt8(5); })), defer(function () { return from(_this.write(Buffer.from([0x08, 0, 0, 0, 0]))); }).pipe(ignoreElements())).toPromise()];
618
- case 1:
619
- mtu = _b.sent();
620
- return [3 /*break*/, 4];
621
- case 2:
622
- e_9 = _b.sent();
623
- log("ble-error", "inferMTU got " + JSON.stringify(e_9));
624
- return [4 /*yield*/, bleManagerInstance()
625
- .cancelDeviceConnection(this.id)["catch"](function () { })];
626
- case 3:
627
- _b.sent(); // but we ignore if disconnect worked.
628
- throw remapError(e_9);
629
- case 4: return [2 /*return*/];
630
- }
631
- });
632
- }); })];
633
- case 1:
634
- _b.sent();
635
- if (mtu > 20) {
636
- this.mtuSize = mtu;
637
- log(TAG, "BleTransport(".concat(this.id, ") mtu set to ").concat(this.mtuSize));
638
- }
639
- return [2 /*return*/, this.mtuSize];
445
+ inferMTU() {
446
+ return __awaiter(this, void 0, void 0, function* () {
447
+ let { mtu } = this.device;
448
+ yield this.exchangeAtomicImpl(() => __awaiter(this, void 0, void 0, function* () {
449
+ try {
450
+ mtu = yield merge(this.notifyObservable.pipe(tap((maybeError) => {
451
+ if (maybeError instanceof Error)
452
+ throw maybeError;
453
+ }), first((buffer) => buffer.readUInt8(0) === 0x08), map((buffer) => buffer.readUInt8(5))), defer(() => from(this.write(Buffer.from([0x08, 0, 0, 0, 0])))).pipe(ignoreElements())).toPromise();
640
454
  }
641
- });
455
+ catch (e) {
456
+ log("ble-error", "inferMTU got " + JSON.stringify(e));
457
+ yield bleManagerInstance()
458
+ .cancelDeviceConnection(this.id)
459
+ .catch(() => { }); // but we ignore if disconnect worked.
460
+ throw remapError(e);
461
+ }
462
+ }));
463
+ if (mtu > 20) {
464
+ this.mtuSize = mtu;
465
+ log(TAG, `BleTransport(${this.id}) mtu set to ${this.mtuSize}`);
466
+ }
467
+ return this.mtuSize;
642
468
  });
643
- };
469
+ }
644
470
  /**
645
471
  * Exposed method from the ble-plx library
646
472
  * Request the connection priority for the given device.
647
473
  * @param {"Balanced" | "High" | "LowPower"} connectionPriority: Connection priority.
648
474
  * @returns {Promise<Device>} Connected device.
649
475
  */
650
- BleTransport.prototype.requestConnectionPriority = function (connectionPriority) {
651
- return __awaiter(this, void 0, void 0, function () {
652
- return __generator(this, function (_b) {
653
- switch (_b.label) {
654
- case 0: return [4 /*yield*/, decoratePromiseErrors(this.device.requestConnectionPriority(ConnectionPriority[connectionPriority]))];
655
- case 1: return [2 /*return*/, _b.sent()];
656
- }
657
- });
476
+ requestConnectionPriority(connectionPriority) {
477
+ return __awaiter(this, void 0, void 0, function* () {
478
+ return yield decoratePromiseErrors(this.device.requestConnectionPriority(ConnectionPriority[connectionPriority]));
658
479
  });
659
- };
480
+ }
660
481
  /**
661
482
  * We intentionally do not immediately close a transport connection.
662
483
  * Instead, we queue the disconnect and wait for a future connection to dismiss the event.
@@ -665,88 +486,67 @@ var BleTransport = /** @class */ (function (_super) {
665
486
  * already been disconnected.
666
487
  * @returns {Promise<void>}
667
488
  */
668
- BleTransport.prototype.close = function () {
669
- return __awaiter(this, void 0, void 0, function () {
670
- var resolve, disconnectPromise;
671
- var _this = this;
672
- return __generator(this, function (_b) {
673
- switch (_b.label) {
674
- case 0:
675
- disconnectPromise = new Promise(function (innerResolve) {
676
- resolve = innerResolve;
677
- });
678
- clearDisconnectTimeout(this.id);
679
- log(TAG, "Queuing a disconnect");
680
- this.disconnectTimeout = setTimeout(function () {
681
- log(TAG, "Triggering a disconnect from ".concat(_this.id));
682
- if (_this.isConnected) {
683
- BleTransport.disconnect(_this.id)["catch"](function () { })["finally"](resolve);
684
- }
685
- else {
686
- resolve();
687
- }
688
- }, BleTransport.disconnectTimeoutMs);
689
- // The closure will occur no later than 5s, triggered either by disconnection
690
- // or the actual response of the apdu.
691
- return [4 /*yield*/, Promise.race([
692
- this.exchangeBusyPromise || Promise.resolve(),
693
- disconnectPromise,
694
- ])];
695
- case 1:
696
- // The closure will occur no later than 5s, triggered either by disconnection
697
- // or the actual response of the apdu.
698
- _b.sent();
699
- return [2 /*return*/];
700
- }
489
+ close() {
490
+ return __awaiter(this, void 0, void 0, function* () {
491
+ let resolve;
492
+ const disconnectPromise = new Promise((innerResolve) => {
493
+ resolve = innerResolve;
701
494
  });
495
+ clearDisconnectTimeout(this.id);
496
+ log(TAG, "Queuing a disconnect");
497
+ this.disconnectTimeout = setTimeout(() => {
498
+ log(TAG, `Triggering a disconnect from ${this.id}`);
499
+ if (this.isConnected) {
500
+ BleTransport.disconnect(this.id)
501
+ .catch(() => { })
502
+ .finally(resolve);
503
+ }
504
+ else {
505
+ resolve();
506
+ }
507
+ }, BleTransport.disconnectTimeoutMs);
508
+ // The closure will occur no later than 5s, triggered either by disconnection
509
+ // or the actual response of the apdu.
510
+ yield Promise.race([
511
+ this.exchangeBusyPromise || Promise.resolve(),
512
+ disconnectPromise,
513
+ ]);
514
+ return;
702
515
  });
703
- };
704
- var _a;
705
- _a = BleTransport;
706
- BleTransport.disconnectTimeoutMs = 5000;
707
- /**
708
- *
709
- */
710
- BleTransport.isSupported = function () {
711
- return Promise.resolve(typeof BleManager === "function");
712
- };
713
- /**
714
- *
715
- */
716
- BleTransport.list = function () {
717
- throw new Error("not implemented");
718
- };
719
- /**
720
- * Exposed method from the ble-plx library
721
- * Sets new log level for native module's logging mechanism.
722
- * @param string logLevel New log level to be set.
723
- */
724
- BleTransport.setLogLevel = function (logLevel) {
725
- if (Object.values(LogLevel).includes(logLevel)) {
726
- bleManagerInstance().setLogLevel(logLevel);
727
- }
728
- else {
729
- throw new Error("".concat(logLevel, " is not a valid LogLevel"));
730
- }
731
- };
732
- /**
733
- * Exposed method from the ble-plx library
734
- * Disconnects from {@link Device} if it's connected or cancels pending connection.
735
- */
736
- BleTransport.disconnect = function (id) { return __awaiter(void 0, void 0, void 0, function () {
737
- return __generator(_a, function (_b) {
738
- switch (_b.label) {
739
- case 0:
740
- log(TAG, "user disconnect(".concat(id, ")"));
741
- return [4 /*yield*/, bleManagerInstance().cancelDeviceConnection(id)];
742
- case 1:
743
- _b.sent();
744
- log(TAG, "disconnected");
745
- return [2 /*return*/];
746
- }
747
- });
748
- }); };
749
- return BleTransport;
750
- }(Transport));
751
- export default BleTransport;
516
+ }
517
+ }
518
+ _a = BleTransport;
519
+ BleTransport.disconnectTimeoutMs = 5000;
520
+ /**
521
+ *
522
+ */
523
+ BleTransport.isSupported = () => Promise.resolve(typeof BleManager === "function");
524
+ /**
525
+ *
526
+ */
527
+ BleTransport.list = () => {
528
+ throw new Error("not implemented");
529
+ };
530
+ /**
531
+ * Exposed method from the ble-plx library
532
+ * Sets new log level for native module's logging mechanism.
533
+ * @param string logLevel New log level to be set.
534
+ */
535
+ BleTransport.setLogLevel = (logLevel) => {
536
+ if (Object.values(LogLevel).includes(logLevel)) {
537
+ bleManagerInstance().setLogLevel(logLevel);
538
+ }
539
+ else {
540
+ throw new Error(`${logLevel} is not a valid LogLevel`);
541
+ }
542
+ };
543
+ /**
544
+ * Exposed method from the ble-plx library
545
+ * Disconnects from {@link Device} if it's connected or cancels pending connection.
546
+ */
547
+ BleTransport.disconnect = (id) => __awaiter(void 0, void 0, void 0, function* () {
548
+ log(TAG, `user disconnect(${id})`);
549
+ yield bleManagerInstance().cancelDeviceConnection(id);
550
+ log(TAG, "disconnected");
551
+ });
752
552
  //# sourceMappingURL=BleTransport.js.map