@onekeyfe/react-native-ble-utils 0.1.7 → 0.1.9
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/android/src/main/java/so/onekey/lib/ble/utils/BleUtilsModule.kt +93 -0
- package/dist/commonjs/index.js +69 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/module/index.js +69 -0
- package/dist/module/index.js.map +1 -1
- package/dist/typescript/commonjs/src/index.d.ts +46 -2
- package/dist/typescript/commonjs/src/index.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/type.d.ts +16 -0
- package/dist/typescript/commonjs/src/type.d.ts.map +1 -1
- package/dist/typescript/module/src/index.d.ts +46 -2
- package/dist/typescript/module/src/index.d.ts.map +1 -1
- package/dist/typescript/module/src/type.d.ts +16 -0
- package/dist/typescript/module/src/type.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +115 -2
- package/src/type.ts +19 -0
|
@@ -29,6 +29,13 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
|
|
|
29
29
|
|
|
30
30
|
override fun getName() = NAME
|
|
31
31
|
|
|
32
|
+
// Lets JS skip waiting for events this OS version never broadcasts.
|
|
33
|
+
override fun getConstants(): MutableMap<String, Any> =
|
|
34
|
+
hashMapOf(
|
|
35
|
+
"supportsKeyMissingEvent" to supportsKeyMissingEvent(),
|
|
36
|
+
"supportsEncryptionChangeEvent" to supportsEncryptionChangeEvent()
|
|
37
|
+
)
|
|
38
|
+
|
|
32
39
|
private fun getBluetoothManager(): BluetoothManager? {
|
|
33
40
|
if (bluetoothManager == null) {
|
|
34
41
|
bluetoothManager =
|
|
@@ -53,6 +60,14 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
|
|
|
53
60
|
|
|
54
61
|
val filter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
|
|
55
62
|
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
|
|
63
|
+
if (supportsKeyMissingEvent()) {
|
|
64
|
+
filter.addAction(ACTION_KEY_MISSING)
|
|
65
|
+
}
|
|
66
|
+
if (supportsEncryptionChangeEvent()) {
|
|
67
|
+
filter.addAction(ACTION_ENCRYPTION_CHANGE)
|
|
68
|
+
// Tells JS when an earlier encryption result stops describing the current link.
|
|
69
|
+
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
|
|
70
|
+
}
|
|
56
71
|
val intentFilter = IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)
|
|
57
72
|
intentFilter.priority = IntentFilter.SYSTEM_HIGH_PRIORITY
|
|
58
73
|
if (Build.VERSION.SDK_INT >= 34) {
|
|
@@ -78,6 +93,24 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
|
|
|
78
93
|
.emit("onDeviceBondState", params)
|
|
79
94
|
}
|
|
80
95
|
|
|
96
|
+
fun emitOnDeviceKeyMissing(params: WritableMap) {
|
|
97
|
+
reactContext
|
|
98
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
99
|
+
.emit("onDeviceKeyMissing", params)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fun emitOnDeviceEncryptionChange(params: WritableMap) {
|
|
103
|
+
reactContext
|
|
104
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
105
|
+
.emit("onDeviceEncryptionChange", params)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
fun emitOnDeviceAclDisconnected(params: WritableMap) {
|
|
109
|
+
reactContext
|
|
110
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
111
|
+
.emit("onDeviceAclDisconnected", params)
|
|
112
|
+
}
|
|
113
|
+
|
|
81
114
|
// 事件监听管理
|
|
82
115
|
@ReactMethod
|
|
83
116
|
fun addListener(eventName: String) {
|
|
@@ -138,6 +171,9 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
|
|
|
138
171
|
|
|
139
172
|
var bonded = false
|
|
140
173
|
var bonding = false
|
|
174
|
+
// False while bonding means the system (or another app) started it, e.g. the
|
|
175
|
+
// re-pairing Android runs by itself after it detects a lost bond.
|
|
176
|
+
var initiated = false
|
|
141
177
|
|
|
142
178
|
when (device.bondState) {
|
|
143
179
|
BluetoothDevice.BOND_BONDED -> {
|
|
@@ -154,12 +190,14 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
|
|
|
154
190
|
val started = device.createBond()
|
|
155
191
|
bonded = false
|
|
156
192
|
bonding = started
|
|
193
|
+
initiated = started
|
|
157
194
|
}
|
|
158
195
|
}
|
|
159
196
|
|
|
160
197
|
val map: WritableMap = Arguments.createMap()
|
|
161
198
|
map.putBoolean("bonded", bonded)
|
|
162
199
|
map.putBoolean("bonding", bonding)
|
|
200
|
+
map.putBoolean("initiated", initiated)
|
|
163
201
|
callback.invoke(null, map)
|
|
164
202
|
} catch (e: Exception) {
|
|
165
203
|
Log.e(LOG_TAG, "pairDevice error: ${e.message}")
|
|
@@ -273,12 +311,67 @@ class BleUtilsModule(private val reactContext: ReactApplicationContext) :
|
|
|
273
311
|
map.putMap("bondState", bond)
|
|
274
312
|
Log.d(LOG_TAG, "onReceive BluetoothDevice BondState Change ${map}")
|
|
275
313
|
module.emitOnDeviceBondState(map)
|
|
314
|
+
} else if (action == ACTION_KEY_MISSING) {
|
|
315
|
+
val device = deviceExtra(intent) ?: return
|
|
316
|
+
|
|
317
|
+
val map = Arguments.createMap()
|
|
318
|
+
map.putString("id", device.address)
|
|
319
|
+
Log.d(LOG_TAG, "onReceive BluetoothDevice KeyMissing")
|
|
320
|
+
module.emitOnDeviceKeyMissing(map)
|
|
321
|
+
} else if (action == ACTION_ENCRYPTION_CHANGE) {
|
|
322
|
+
val device = deviceExtra(intent) ?: return
|
|
323
|
+
if (!isLeTransport(intent)) return
|
|
324
|
+
|
|
325
|
+
val map = Arguments.createMap()
|
|
326
|
+
map.putString("id", device.address)
|
|
327
|
+
// HCI status: 0 on success, 6 (PIN or key missing) when the peer lost the bond.
|
|
328
|
+
map.putInt("status", intent.getIntExtra(EXTRA_ENCRYPTION_STATUS, BluetoothDevice.ERROR))
|
|
329
|
+
map.putBoolean("enabled", intent.getBooleanExtra(EXTRA_ENCRYPTION_ENABLED, false))
|
|
330
|
+
Log.d(LOG_TAG, "onReceive BluetoothDevice EncryptionChange ${map}")
|
|
331
|
+
module.emitOnDeviceEncryptionChange(map)
|
|
332
|
+
} else if (action == BluetoothDevice.ACTION_ACL_DISCONNECTED) {
|
|
333
|
+
val device = deviceExtra(intent) ?: return
|
|
334
|
+
if (!isLeTransport(intent)) return
|
|
335
|
+
|
|
336
|
+
val map = Arguments.createMap()
|
|
337
|
+
map.putString("id", device.address)
|
|
338
|
+
Log.d(LOG_TAG, "onReceive BluetoothDevice AclDisconnected")
|
|
339
|
+
module.emitOnDeviceAclDisconnected(map)
|
|
276
340
|
}
|
|
277
341
|
}
|
|
342
|
+
|
|
343
|
+
private fun deviceExtra(intent: Intent): BluetoothDevice? =
|
|
344
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
345
|
+
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java)
|
|
346
|
+
} else {
|
|
347
|
+
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// A dual-mode peer reports BR/EDR events too; only the LE link carries GATT.
|
|
351
|
+
private fun isLeTransport(intent: Intent): Boolean {
|
|
352
|
+
if (!intent.hasExtra(EXTRA_TRANSPORT)) return true
|
|
353
|
+
return intent.getIntExtra(EXTRA_TRANSPORT, TRANSPORT_LE) == TRANSPORT_LE
|
|
354
|
+
}
|
|
278
355
|
}
|
|
279
356
|
|
|
280
357
|
companion object {
|
|
281
358
|
const val NAME = "BleUtilsModule"
|
|
282
359
|
const val LOG_TAG: String = "RNBleUtils"
|
|
360
|
+
|
|
361
|
+
// These BluetoothDevice constants are public from API 36. The literals keep this
|
|
362
|
+
// module building against older compileSdk versions.
|
|
363
|
+
const val ACTION_KEY_MISSING = "android.bluetooth.device.action.KEY_MISSING"
|
|
364
|
+
const val ACTION_ENCRYPTION_CHANGE = "android.bluetooth.device.action.ENCRYPTION_CHANGE"
|
|
365
|
+
private const val EXTRA_ENCRYPTION_STATUS = "android.bluetooth.device.extra.ENCRYPTION_STATUS"
|
|
366
|
+
private const val EXTRA_ENCRYPTION_ENABLED = "android.bluetooth.device.extra.ENCRYPTION_ENABLED"
|
|
367
|
+
// BluetoothDevice.EXTRA_TRANSPORT and TRANSPORT_LE, public from API 33 and 23.
|
|
368
|
+
private const val EXTRA_TRANSPORT = "android.bluetooth.device.extra.TRANSPORT"
|
|
369
|
+
private const val TRANSPORT_LE = 2
|
|
370
|
+
private const val LINK_SECURITY_EVENTS_MIN_SDK = 36
|
|
371
|
+
|
|
372
|
+
fun supportsKeyMissingEvent(): Boolean = Build.VERSION.SDK_INT >= LINK_SECURITY_EVENTS_MIN_SDK
|
|
373
|
+
|
|
374
|
+
fun supportsEncryptionChangeEvent(): Boolean =
|
|
375
|
+
Build.VERSION.SDK_INT >= LINK_SECURITY_EVENTS_MIN_SDK
|
|
283
376
|
}
|
|
284
377
|
}
|
package/dist/commonjs/index.js
CHANGED
|
@@ -8,6 +8,13 @@ var _reactNative = require("react-native");
|
|
|
8
8
|
const {
|
|
9
9
|
BleUtilsModule
|
|
10
10
|
} = _reactNative.NativeModules;
|
|
11
|
+
const readNativeFlag = name => {
|
|
12
|
+
if (_reactNative.Platform.OS !== 'android' || !BleUtilsModule) return false;
|
|
13
|
+
// Interop exposes legacy constants through getConstants(); the bridge exposes them
|
|
14
|
+
// as plain properties.
|
|
15
|
+
const constants = typeof BleUtilsModule.getConstants === 'function' ? BleUtilsModule.getConstants() : BleUtilsModule;
|
|
16
|
+
return constants?.[name] === true;
|
|
17
|
+
};
|
|
11
18
|
class BleUtils {
|
|
12
19
|
UiEventEmitter = null;
|
|
13
20
|
constructor() {
|
|
@@ -105,6 +112,68 @@ class BleUtils {
|
|
|
105
112
|
this.UiEventEmitter?.removeAllListeners('onDeviceBondState');
|
|
106
113
|
};
|
|
107
114
|
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* [Android only]
|
|
118
|
+
* Whether this OS version and native build report `onDeviceKeyMissing`. When false
|
|
119
|
+
* the event never fires, so callers should not wait for it.
|
|
120
|
+
*/
|
|
121
|
+
supportsDeviceKeyMissing() {
|
|
122
|
+
return readNativeFlag('supportsKeyMissingEvent');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* [Android 16+ only]
|
|
127
|
+
* A bonded device could not provide its keys when the link was encrypted: the device
|
|
128
|
+
* was wiped or removed the bond. Android keeps its side of the bond, so the device
|
|
129
|
+
* stays unusable until the user forgets it in system Bluetooth settings.
|
|
130
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
131
|
+
* @param callback
|
|
132
|
+
*/
|
|
133
|
+
onDeviceKeyMissing(callback) {
|
|
134
|
+
const subscription = this.UiEventEmitter?.addListener('onDeviceKeyMissing', callback);
|
|
135
|
+
return () => {
|
|
136
|
+
subscription?.remove();
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* [Android only]
|
|
142
|
+
* Whether this OS version and native build report `onDeviceEncryptionChange` and
|
|
143
|
+
* `onDeviceAclDisconnected`. When false those events never fire.
|
|
144
|
+
*/
|
|
145
|
+
supportsDeviceEncryptionChange() {
|
|
146
|
+
return readNativeFlag('supportsEncryptionChangeEvent');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* [Android 16+ only]
|
|
151
|
+
* The LE link to a device finished an encryption attempt. Android starts it on its own
|
|
152
|
+
* right after connecting to a bonded device, so this reports whether the stored bond
|
|
153
|
+
* still works before any request that needs encryption is sent.
|
|
154
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
155
|
+
* @param callback
|
|
156
|
+
*/
|
|
157
|
+
onDeviceEncryptionChange(callback) {
|
|
158
|
+
const subscription = this.UiEventEmitter?.addListener('onDeviceEncryptionChange', callback);
|
|
159
|
+
return () => {
|
|
160
|
+
subscription?.remove();
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* [Android 16+ only]
|
|
166
|
+
* The LE link to a device is gone, so earlier encryption results no longer apply.
|
|
167
|
+
* Unlike a GATT disconnect, this does not fire while the system keeps the link alive
|
|
168
|
+
* for another client.
|
|
169
|
+
* @param callback
|
|
170
|
+
*/
|
|
171
|
+
onDeviceAclDisconnected(callback) {
|
|
172
|
+
const subscription = this.UiEventEmitter?.addListener('onDeviceAclDisconnected', callback);
|
|
173
|
+
return () => {
|
|
174
|
+
subscription?.remove();
|
|
175
|
+
};
|
|
176
|
+
}
|
|
108
177
|
}
|
|
109
178
|
var _default = exports.default = new BleUtils();
|
|
110
179
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","BleUtilsModule","NativeModules","
|
|
1
|
+
{"version":3,"names":["_reactNative","require","BleUtilsModule","NativeModules","readNativeFlag","name","Platform","OS","constants","getConstants","BleUtils","UiEventEmitter","constructor","NativeEventEmitter","checkState","Promise","fulfill","_","state","pairDevice","macAddress","resolve","bonded","bonding","reject","error","result","getConnectedPeripherals","serviceUUIDs","getBondedPeripherals","onDeviceBondState","callback","addListener","removeAllListeners","supportsDeviceKeyMissing","onDeviceKeyMissing","subscription","remove","supportsDeviceEncryptionChange","onDeviceEncryptionChange","onDeviceAclDisconnected","_default","exports","default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
|
package/dist/module/index.js
CHANGED
|
@@ -4,6 +4,13 @@ import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
|
|
|
4
4
|
const {
|
|
5
5
|
BleUtilsModule
|
|
6
6
|
} = NativeModules;
|
|
7
|
+
const readNativeFlag = name => {
|
|
8
|
+
if (Platform.OS !== 'android' || !BleUtilsModule) return false;
|
|
9
|
+
// Interop exposes legacy constants through getConstants(); the bridge exposes them
|
|
10
|
+
// as plain properties.
|
|
11
|
+
const constants = typeof BleUtilsModule.getConstants === 'function' ? BleUtilsModule.getConstants() : BleUtilsModule;
|
|
12
|
+
return constants?.[name] === true;
|
|
13
|
+
};
|
|
7
14
|
class BleUtils {
|
|
8
15
|
UiEventEmitter = null;
|
|
9
16
|
constructor() {
|
|
@@ -101,6 +108,68 @@ class BleUtils {
|
|
|
101
108
|
this.UiEventEmitter?.removeAllListeners('onDeviceBondState');
|
|
102
109
|
};
|
|
103
110
|
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* [Android only]
|
|
114
|
+
* Whether this OS version and native build report `onDeviceKeyMissing`. When false
|
|
115
|
+
* the event never fires, so callers should not wait for it.
|
|
116
|
+
*/
|
|
117
|
+
supportsDeviceKeyMissing() {
|
|
118
|
+
return readNativeFlag('supportsKeyMissingEvent');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* [Android 16+ only]
|
|
123
|
+
* A bonded device could not provide its keys when the link was encrypted: the device
|
|
124
|
+
* was wiped or removed the bond. Android keeps its side of the bond, so the device
|
|
125
|
+
* stays unusable until the user forgets it in system Bluetooth settings.
|
|
126
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
127
|
+
* @param callback
|
|
128
|
+
*/
|
|
129
|
+
onDeviceKeyMissing(callback) {
|
|
130
|
+
const subscription = this.UiEventEmitter?.addListener('onDeviceKeyMissing', callback);
|
|
131
|
+
return () => {
|
|
132
|
+
subscription?.remove();
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* [Android only]
|
|
138
|
+
* Whether this OS version and native build report `onDeviceEncryptionChange` and
|
|
139
|
+
* `onDeviceAclDisconnected`. When false those events never fire.
|
|
140
|
+
*/
|
|
141
|
+
supportsDeviceEncryptionChange() {
|
|
142
|
+
return readNativeFlag('supportsEncryptionChangeEvent');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* [Android 16+ only]
|
|
147
|
+
* The LE link to a device finished an encryption attempt. Android starts it on its own
|
|
148
|
+
* right after connecting to a bonded device, so this reports whether the stored bond
|
|
149
|
+
* still works before any request that needs encryption is sent.
|
|
150
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
151
|
+
* @param callback
|
|
152
|
+
*/
|
|
153
|
+
onDeviceEncryptionChange(callback) {
|
|
154
|
+
const subscription = this.UiEventEmitter?.addListener('onDeviceEncryptionChange', callback);
|
|
155
|
+
return () => {
|
|
156
|
+
subscription?.remove();
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* [Android 16+ only]
|
|
162
|
+
* The LE link to a device is gone, so earlier encryption results no longer apply.
|
|
163
|
+
* Unlike a GATT disconnect, this does not fire while the system keeps the link alive
|
|
164
|
+
* for another client.
|
|
165
|
+
* @param callback
|
|
166
|
+
*/
|
|
167
|
+
onDeviceAclDisconnected(callback) {
|
|
168
|
+
const subscription = this.UiEventEmitter?.addListener('onDeviceAclDisconnected', callback);
|
|
169
|
+
return () => {
|
|
170
|
+
subscription?.remove();
|
|
171
|
+
};
|
|
172
|
+
}
|
|
104
173
|
}
|
|
105
174
|
export default new BleUtils();
|
|
106
175
|
//# sourceMappingURL=index.js.map
|
package/dist/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeEventEmitter","NativeModules","Platform","BleUtilsModule","BleUtils","UiEventEmitter","constructor","
|
|
1
|
+
{"version":3,"names":["NativeEventEmitter","NativeModules","Platform","BleUtilsModule","readNativeFlag","name","OS","constants","getConstants","BleUtils","UiEventEmitter","constructor","checkState","Promise","fulfill","_","state","pairDevice","macAddress","resolve","bonded","bonding","reject","error","result","getConnectedPeripherals","serviceUUIDs","getBondedPeripherals","onDeviceBondState","callback","addListener","removeAllListeners","supportsDeviceKeyMissing","onDeviceKeyMissing","subscription","remove","supportsDeviceEncryptionChange","onDeviceEncryptionChange","onDeviceAclDisconnected"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { NativeEventEmitter } from 'react-native';
|
|
2
|
-
import type { BleState, Peripheral, BondState, AdvertisingData } from './type';
|
|
2
|
+
import type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral } from './type';
|
|
3
3
|
type PairDeviceResult = {
|
|
4
4
|
bonded: boolean;
|
|
5
5
|
bonding: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* [Android only] True when this call started the bonding. False while `bonding` is
|
|
8
|
+
* true means the system started it, e.g. its own re-pairing after a lost bond.
|
|
9
|
+
* Undefined on native builds that predate the field.
|
|
10
|
+
*/
|
|
11
|
+
initiated?: boolean;
|
|
6
12
|
};
|
|
7
13
|
declare class BleUtils {
|
|
8
14
|
UiEventEmitter: NativeEventEmitter | null;
|
|
@@ -33,8 +39,46 @@ declare class BleUtils {
|
|
|
33
39
|
* @param callback
|
|
34
40
|
*/
|
|
35
41
|
onDeviceBondState(callback: (peripheral: Peripheral) => void): (() => void) | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* [Android only]
|
|
44
|
+
* Whether this OS version and native build report `onDeviceKeyMissing`. When false
|
|
45
|
+
* the event never fires, so callers should not wait for it.
|
|
46
|
+
*/
|
|
47
|
+
supportsDeviceKeyMissing(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* [Android 16+ only]
|
|
50
|
+
* A bonded device could not provide its keys when the link was encrypted: the device
|
|
51
|
+
* was wiped or removed the bond. Android keeps its side of the bond, so the device
|
|
52
|
+
* stays unusable until the user forgets it in system Bluetooth settings.
|
|
53
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
54
|
+
* @param callback
|
|
55
|
+
*/
|
|
56
|
+
onDeviceKeyMissing(callback: (peripheral: KeyMissingPeripheral) => void): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* [Android only]
|
|
59
|
+
* Whether this OS version and native build report `onDeviceEncryptionChange` and
|
|
60
|
+
* `onDeviceAclDisconnected`. When false those events never fire.
|
|
61
|
+
*/
|
|
62
|
+
supportsDeviceEncryptionChange(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* [Android 16+ only]
|
|
65
|
+
* The LE link to a device finished an encryption attempt. Android starts it on its own
|
|
66
|
+
* right after connecting to a bonded device, so this reports whether the stored bond
|
|
67
|
+
* still works before any request that needs encryption is sent.
|
|
68
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
69
|
+
* @param callback
|
|
70
|
+
*/
|
|
71
|
+
onDeviceEncryptionChange(callback: (peripheral: EncryptionChangePeripheral) => void): () => void;
|
|
72
|
+
/**
|
|
73
|
+
* [Android 16+ only]
|
|
74
|
+
* The LE link to a device is gone, so earlier encryption results no longer apply.
|
|
75
|
+
* Unlike a GATT disconnect, this does not fire while the system keeps the link alive
|
|
76
|
+
* for another client.
|
|
77
|
+
* @param callback
|
|
78
|
+
*/
|
|
79
|
+
onDeviceAclDisconnected(callback: (peripheral: AclDisconnectedPeripheral) => void): () => void;
|
|
36
80
|
}
|
|
37
81
|
declare const _default: BleUtils;
|
|
38
82
|
export default _default;
|
|
39
|
-
export type { BleState, Peripheral, BondState, AdvertisingData };
|
|
83
|
+
export type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral, PairDeviceResult, };
|
|
40
84
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,QAAQ,CAAC;AAGhB,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAiBF,cAAM,QAAQ;IACZ,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAQ;;IAOjD,UAAU;IAQV;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2BzD;;;;OAIG;IACH,uBAAuB,CAAC,YAAY,GAAE,MAAM,EAAO;IAmBnD;;;OAGG;IACH,oBAAoB;IAkBpB;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI;IAQ5D;;;;OAIG;IACH,wBAAwB;IAIxB;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI;IAUvE;;;;OAIG;IACH,8BAA8B;IAI9B;;;;;;;OAOG;IACH,wBAAwB,CACtB,QAAQ,EAAE,CAAC,UAAU,EAAE,0BAA0B,KAAK,IAAI;IAW5D;;;;;;OAMG;IACH,uBAAuB,CACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,yBAAyB,KAAK,IAAI;CAU5D;;AAED,wBAA8B;AAC9B,YAAY,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,GACjB,CAAC"}
|
|
@@ -40,6 +40,22 @@ export interface BondState {
|
|
|
40
40
|
/** Android EXTRA_UNBOND_REASON, when supplied by the system. */
|
|
41
41
|
reason?: number;
|
|
42
42
|
}
|
|
43
|
+
export interface KeyMissingPeripheral {
|
|
44
|
+
/** Device MAC address. */
|
|
45
|
+
id: string;
|
|
46
|
+
}
|
|
47
|
+
export interface EncryptionChangePeripheral {
|
|
48
|
+
/** Device MAC address. */
|
|
49
|
+
id: string;
|
|
50
|
+
/** HCI status of the encryption procedure: 0 on success, 6 when the peer lost the bond. */
|
|
51
|
+
status: number;
|
|
52
|
+
/** Whether the LE link is encrypted after the change. */
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface AclDisconnectedPeripheral {
|
|
56
|
+
/** Device MAC address. */
|
|
57
|
+
id: string;
|
|
58
|
+
}
|
|
43
59
|
export interface AdvertisingData {
|
|
44
60
|
isConnectable?: boolean;
|
|
45
61
|
localName?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,0BAA0B;IACzC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { NativeEventEmitter } from 'react-native';
|
|
2
|
-
import type { BleState, Peripheral, BondState, AdvertisingData } from './type';
|
|
2
|
+
import type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral } from './type';
|
|
3
3
|
type PairDeviceResult = {
|
|
4
4
|
bonded: boolean;
|
|
5
5
|
bonding: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* [Android only] True when this call started the bonding. False while `bonding` is
|
|
8
|
+
* true means the system started it, e.g. its own re-pairing after a lost bond.
|
|
9
|
+
* Undefined on native builds that predate the field.
|
|
10
|
+
*/
|
|
11
|
+
initiated?: boolean;
|
|
6
12
|
};
|
|
7
13
|
declare class BleUtils {
|
|
8
14
|
UiEventEmitter: NativeEventEmitter | null;
|
|
@@ -33,8 +39,46 @@ declare class BleUtils {
|
|
|
33
39
|
* @param callback
|
|
34
40
|
*/
|
|
35
41
|
onDeviceBondState(callback: (peripheral: Peripheral) => void): (() => void) | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* [Android only]
|
|
44
|
+
* Whether this OS version and native build report `onDeviceKeyMissing`. When false
|
|
45
|
+
* the event never fires, so callers should not wait for it.
|
|
46
|
+
*/
|
|
47
|
+
supportsDeviceKeyMissing(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* [Android 16+ only]
|
|
50
|
+
* A bonded device could not provide its keys when the link was encrypted: the device
|
|
51
|
+
* was wiped or removed the bond. Android keeps its side of the bond, so the device
|
|
52
|
+
* stays unusable until the user forgets it in system Bluetooth settings.
|
|
53
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
54
|
+
* @param callback
|
|
55
|
+
*/
|
|
56
|
+
onDeviceKeyMissing(callback: (peripheral: KeyMissingPeripheral) => void): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* [Android only]
|
|
59
|
+
* Whether this OS version and native build report `onDeviceEncryptionChange` and
|
|
60
|
+
* `onDeviceAclDisconnected`. When false those events never fire.
|
|
61
|
+
*/
|
|
62
|
+
supportsDeviceEncryptionChange(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* [Android 16+ only]
|
|
65
|
+
* The LE link to a device finished an encryption attempt. Android starts it on its own
|
|
66
|
+
* right after connecting to a bonded device, so this reports whether the stored bond
|
|
67
|
+
* still works before any request that needs encryption is sent.
|
|
68
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
69
|
+
* @param callback
|
|
70
|
+
*/
|
|
71
|
+
onDeviceEncryptionChange(callback: (peripheral: EncryptionChangePeripheral) => void): () => void;
|
|
72
|
+
/**
|
|
73
|
+
* [Android 16+ only]
|
|
74
|
+
* The LE link to a device is gone, so earlier encryption results no longer apply.
|
|
75
|
+
* Unlike a GATT disconnect, this does not fire while the system keeps the link alive
|
|
76
|
+
* for another client.
|
|
77
|
+
* @param callback
|
|
78
|
+
*/
|
|
79
|
+
onDeviceAclDisconnected(callback: (peripheral: AclDisconnectedPeripheral) => void): () => void;
|
|
36
80
|
}
|
|
37
81
|
declare const _default: BleUtils;
|
|
38
82
|
export default _default;
|
|
39
|
-
export type { BleState, Peripheral, BondState, AdvertisingData };
|
|
83
|
+
export type { BleState, Peripheral, BondState, AdvertisingData, KeyMissingPeripheral, EncryptionChangePeripheral, AclDisconnectedPeripheral, PairDeviceResult, };
|
|
40
84
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,QAAQ,CAAC;AAGhB,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAiBF,cAAM,QAAQ;IACZ,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAQ;;IAOjD,UAAU;IAQV;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2BzD;;;;OAIG;IACH,uBAAuB,CAAC,YAAY,GAAE,MAAM,EAAO;IAmBnD;;;OAGG;IACH,oBAAoB;IAkBpB;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI;IAQ5D;;;;OAIG;IACH,wBAAwB;IAIxB;;;;;;;OAOG;IACH,kBAAkB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,IAAI;IAUvE;;;;OAIG;IACH,8BAA8B;IAI9B;;;;;;;OAOG;IACH,wBAAwB,CACtB,QAAQ,EAAE,CAAC,UAAU,EAAE,0BAA0B,KAAK,IAAI;IAW5D;;;;;;OAMG;IACH,uBAAuB,CACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,yBAAyB,KAAK,IAAI;CAU5D;;AAED,wBAA8B;AAC9B,YAAY,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,gBAAgB,GACjB,CAAC"}
|
|
@@ -40,6 +40,22 @@ export interface BondState {
|
|
|
40
40
|
/** Android EXTRA_UNBOND_REASON, when supplied by the system. */
|
|
41
41
|
reason?: number;
|
|
42
42
|
}
|
|
43
|
+
export interface KeyMissingPeripheral {
|
|
44
|
+
/** Device MAC address. */
|
|
45
|
+
id: string;
|
|
46
|
+
}
|
|
47
|
+
export interface EncryptionChangePeripheral {
|
|
48
|
+
/** Device MAC address. */
|
|
49
|
+
id: string;
|
|
50
|
+
/** HCI status of the encryption procedure: 0 on success, 6 when the peer lost the bond. */
|
|
51
|
+
status: number;
|
|
52
|
+
/** Whether the LE link is encrypted after the change. */
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface AclDisconnectedPeripheral {
|
|
56
|
+
/** Device MAC address. */
|
|
57
|
+
id: string;
|
|
58
|
+
}
|
|
43
59
|
export interface AdvertisingData {
|
|
44
60
|
isConnectable?: boolean;
|
|
45
61
|
localName?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../../src/type.ts"],"names":[],"mappings":"AAAA;;;KAGK;AACL,oBAAY,QAAQ;IAClB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B;;OAEG;IACH,YAAY,iBAAiB;IAC7B,EAAE,OAAO;IACT,GAAG,QAAQ;IACX;;OAEG;IACH,SAAS,eAAe;IACxB;;OAEG;IACH,UAAU,gBAAgB;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,0BAA0B;IACzC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
BleState,
|
|
4
|
+
Peripheral,
|
|
5
|
+
BondState,
|
|
6
|
+
AdvertisingData,
|
|
7
|
+
KeyMissingPeripheral,
|
|
8
|
+
EncryptionChangePeripheral,
|
|
9
|
+
AclDisconnectedPeripheral,
|
|
10
|
+
} from './type';
|
|
3
11
|
|
|
4
12
|
const { BleUtilsModule } = NativeModules;
|
|
5
13
|
type PairDeviceResult = {
|
|
6
14
|
bonded: boolean;
|
|
7
15
|
bonding: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* [Android only] True when this call started the bonding. False while `bonding` is
|
|
18
|
+
* true means the system started it, e.g. its own re-pairing after a lost bond.
|
|
19
|
+
* Undefined on native builds that predate the field.
|
|
20
|
+
*/
|
|
21
|
+
initiated?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type NativeConstantName =
|
|
25
|
+
| 'supportsKeyMissingEvent'
|
|
26
|
+
| 'supportsEncryptionChangeEvent';
|
|
27
|
+
|
|
28
|
+
const readNativeFlag = (name: NativeConstantName): boolean => {
|
|
29
|
+
if (Platform.OS !== 'android' || !BleUtilsModule) return false;
|
|
30
|
+
// Interop exposes legacy constants through getConstants(); the bridge exposes them
|
|
31
|
+
// as plain properties.
|
|
32
|
+
const constants =
|
|
33
|
+
typeof BleUtilsModule.getConstants === 'function'
|
|
34
|
+
? BleUtilsModule.getConstants()
|
|
35
|
+
: BleUtilsModule;
|
|
36
|
+
return constants?.[name] === true;
|
|
8
37
|
};
|
|
9
38
|
|
|
10
39
|
class BleUtils {
|
|
@@ -115,7 +144,91 @@ class BleUtils {
|
|
|
115
144
|
this.UiEventEmitter?.removeAllListeners('onDeviceBondState');
|
|
116
145
|
};
|
|
117
146
|
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* [Android only]
|
|
150
|
+
* Whether this OS version and native build report `onDeviceKeyMissing`. When false
|
|
151
|
+
* the event never fires, so callers should not wait for it.
|
|
152
|
+
*/
|
|
153
|
+
supportsDeviceKeyMissing() {
|
|
154
|
+
return readNativeFlag('supportsKeyMissingEvent');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* [Android 16+ only]
|
|
159
|
+
* A bonded device could not provide its keys when the link was encrypted: the device
|
|
160
|
+
* was wiped or removed the bond. Android keeps its side of the bond, so the device
|
|
161
|
+
* stays unusable until the user forgets it in system Bluetooth settings.
|
|
162
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
163
|
+
* @param callback
|
|
164
|
+
*/
|
|
165
|
+
onDeviceKeyMissing(callback: (peripheral: KeyMissingPeripheral) => void) {
|
|
166
|
+
const subscription = this.UiEventEmitter?.addListener(
|
|
167
|
+
'onDeviceKeyMissing',
|
|
168
|
+
callback
|
|
169
|
+
);
|
|
170
|
+
return () => {
|
|
171
|
+
subscription?.remove();
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* [Android only]
|
|
177
|
+
* Whether this OS version and native build report `onDeviceEncryptionChange` and
|
|
178
|
+
* `onDeviceAclDisconnected`. When false those events never fire.
|
|
179
|
+
*/
|
|
180
|
+
supportsDeviceEncryptionChange() {
|
|
181
|
+
return readNativeFlag('supportsEncryptionChangeEvent');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* [Android 16+ only]
|
|
186
|
+
* The LE link to a device finished an encryption attempt. Android starts it on its own
|
|
187
|
+
* right after connecting to a bonded device, so this reports whether the stored bond
|
|
188
|
+
* still works before any request that needs encryption is sent.
|
|
189
|
+
* Each subscription is removed on its own, so several callers can listen at once.
|
|
190
|
+
* @param callback
|
|
191
|
+
*/
|
|
192
|
+
onDeviceEncryptionChange(
|
|
193
|
+
callback: (peripheral: EncryptionChangePeripheral) => void
|
|
194
|
+
) {
|
|
195
|
+
const subscription = this.UiEventEmitter?.addListener(
|
|
196
|
+
'onDeviceEncryptionChange',
|
|
197
|
+
callback
|
|
198
|
+
);
|
|
199
|
+
return () => {
|
|
200
|
+
subscription?.remove();
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* [Android 16+ only]
|
|
206
|
+
* The LE link to a device is gone, so earlier encryption results no longer apply.
|
|
207
|
+
* Unlike a GATT disconnect, this does not fire while the system keeps the link alive
|
|
208
|
+
* for another client.
|
|
209
|
+
* @param callback
|
|
210
|
+
*/
|
|
211
|
+
onDeviceAclDisconnected(
|
|
212
|
+
callback: (peripheral: AclDisconnectedPeripheral) => void
|
|
213
|
+
) {
|
|
214
|
+
const subscription = this.UiEventEmitter?.addListener(
|
|
215
|
+
'onDeviceAclDisconnected',
|
|
216
|
+
callback
|
|
217
|
+
);
|
|
218
|
+
return () => {
|
|
219
|
+
subscription?.remove();
|
|
220
|
+
};
|
|
221
|
+
}
|
|
118
222
|
}
|
|
119
223
|
|
|
120
224
|
export default new BleUtils();
|
|
121
|
-
export type {
|
|
225
|
+
export type {
|
|
226
|
+
BleState,
|
|
227
|
+
Peripheral,
|
|
228
|
+
BondState,
|
|
229
|
+
AdvertisingData,
|
|
230
|
+
KeyMissingPeripheral,
|
|
231
|
+
EncryptionChangePeripheral,
|
|
232
|
+
AclDisconnectedPeripheral,
|
|
233
|
+
PairDeviceResult,
|
|
234
|
+
};
|
package/src/type.ts
CHANGED
|
@@ -43,6 +43,25 @@ export interface BondState {
|
|
|
43
43
|
reason?: number;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
export interface KeyMissingPeripheral {
|
|
47
|
+
/** Device MAC address. */
|
|
48
|
+
id: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface EncryptionChangePeripheral {
|
|
52
|
+
/** Device MAC address. */
|
|
53
|
+
id: string;
|
|
54
|
+
/** HCI status of the encryption procedure: 0 on success, 6 when the peer lost the bond. */
|
|
55
|
+
status: number;
|
|
56
|
+
/** Whether the LE link is encrypted after the change. */
|
|
57
|
+
enabled: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface AclDisconnectedPeripheral {
|
|
61
|
+
/** Device MAC address. */
|
|
62
|
+
id: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
46
65
|
export interface AdvertisingData {
|
|
47
66
|
isConnectable?: boolean;
|
|
48
67
|
localName?: string;
|