When the BleState is PoweredOn, I should be able to startScanDevices() without having BleError: BluetoothLE is in unknown state.
I should be able to scan devices with and without "Remote Debug" enabled.
When I start scanning my devices, I receive the BleError: BluetoothLE is in unknown state even if I waited that the BleManager State was in 'PoweredOn'.
This behavior is only present when I enable the "Remote Debug" on iOS. It's working fine if I'm disable the "Remote Debug".
It's really annoying because everybody is developing with the Remote Debug active I guess... Otherwise it's a bit complicated.
I don't see anything about this issue in the documentation. It's just written that we have to wait that the status is PoweredOnon iOS. And that's done...
I found that it's not working with the "Remote Debug" active in this issue. I don't understand why there is no related issue or documentation about that...
Please provide detailed steps for reproducing the issue.
PoweredOnstartDevicesScan()DeviceScanner.js:17 LIB : Wait until bluetooth ready...
DeviceScanner.js:28 Base state PoweredOn
DeviceScanner.js:57 LIB : Start scan...
DeviceScanner.js:70 Scan error : {"message":"BluetoothLE is in unknown state","errorCode":103,"attErrorCode":null,"iosErrorCode":null,"androidErrorCode":null,"reason":null,"name":"BleError"}
DeviceScanner.js:85 LIB : Scan stopped
DeviceScanner.js:22 State change : PoweredOn
startScan() {
_deviceScanner.startDevicesScan(
error => {
console.error(error);
_deviceScanner.stopDevicesScan();
},
device => {
console.log(device);
}
);
};
/**
* Wait until Bluetooth is ready. On iOS the BLE stack is not immediately ready,
* we need to wait for the "PoweredOn" status.
*/
async waitUntilBluetoothReady() {
let {PoweredOn, PoweredOff, Unauthorized, Unsupported} = State;
console.log('LIB : Wait until bluetooth ready...');
return new Promise(async (resolve, reject) => {
this._bleManager.onStateChange(state => {
console.log('State changed : ', state);
if (state === PoweredOn) {
resolve(true);
}
});
// Verify if the state is already poweredOn before the listener was created
let crtState = await this._bleManager.state();
console.log('Base state', crtState);
if (crtState === PoweredOn) {
resolve(true);
}
else if (
crtState === PoweredOff ||
crtState === Unauthorized ||
crtState === Unsupported
) {
reject(new Error('Bluetooth is not available :', crtState));
}
});
}
/**
* Start device scanning only if the BleManager State is ready
*/
async startDevicesScan(
onError: (error: Error) => void,
onDeviceFound: (device: ConnectHubDevice) => void,
) {
this.waitUntilBluetoothReady()
.then(() => {
console.log('LIB : Start scan...');
const scanOptions = {
allowDuplicates: false,
scanMode: ScanMode.LowLatency,
};
this._bleManager.startDeviceScan(
[SERVICE_UUID],
scanOptions,
(error, device) => {
if (error) {
onError(error);
}
if (device) {
onDeviceFound(device);
}
},
);
})
.catch(error => console.log(JSON.stringify(error));
}
Hi. Could you add logs on when the BleManager is being created? It looks like an issue with different lifecycles of your JS code and native parts.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
We see the same problem, it happens when I change anything outside React code. Only restarting the app fixes this. Do you know when and how different lifecycles of JS code and native parts can cause a problem?
same here
In my case, when the BleManager is being created and its log is
_activePromises: {}
_activeSubscriptions: {}
_errorCodesToMessagesMapping: {0: "Unknown error occurred. This is probably a bug! Check reason property.", 1: "BleManager was destroyed", 2: "Operation was cancelled", 3: "Operation timed out", 4: "Operation was rejected", 5: "Invalid UUIDs or IDs were passed: {internalMessage}", 100: "BluetoothLE is unsupported on this device", 101: "Device is not authorized to use BluetoothLE", 102: "BluetoothLE is powered off", 103: "BluetoothLE is in unknown state", 104: "BluetoothLE is resetting", 105: "Bluetooth state change failed", 200: "Device {deviceID} connection failed", 201: "Device {deviceID} was disconnected", 202: "RSSI read failed for device {deviceID}", 203: "Device {deviceID} is already connected", 204: "Device {deviceID} not found", 205: "Device {deviceID} is not connected", 206: "Device {deviceID} could not change MTU size", 300: "Services discovery failed for device {deviceID}", 301: "Included services discovery failed for device {deviceID} and service: {serviceUUID}", 302: "Service {serviceUUID} for device {deviceID} not found", 303: "Services not discovered for device {deviceID}", 400: "Characteristic discovery failed for device {deviceID} and service {serviceUUID}", 401: "Characteristic {characteristicUUID} write failed for device {deviceID} and service {serviceUUID}", 402: "Characteristic {characteristicUUID} read failed for device {deviceID} and service {serviceUUID}", 403: "Characteristic {characteristicUUID} notify change 鈥 for device {deviceID} and service {serviceUUID}", 404: "Characteristic {characteristicUUID} not found", 405: "Characteristics not discovered for device {deviceID} and service {serviceUUID}", 406: "Cannot write to characteristic {characteristicUUID} with invalid data format: {internalMessage}", 500: "Descriptor {descriptorUUID} discovery failed for d鈥iceUUID} and characteristic {characteristicUUID}", 501: "Descriptor {descriptorUUID} write failed for devic鈥iceUUID} and characteristic {characteristicUUID}", 502: "Descriptor {descriptorUUID} read failed for device鈥iceUUID} and characteristic {characteristicUUID}", 503: "Descriptor {descriptorUUID} not found", 504: "Descriptors not discovered for device {deviceID}, 鈥iceUUID} and characteristic {characteristicUUID}", 505: "Cannot write to descriptor {descriptorUUID} with invalid data format: {internalMessage}", 506: "Cannot write to descriptor {descriptorUUID}. It's 鈥 iOS and therefore forbidden on Android as well.", 600: "Cannot start scanning operation", 601: "Location services are disabled"}
_eventEmitter: NativeEventEmitter {_subscriber: EventSubscriptionVendor, _nativeModule: {鈥}
_uniqueId: 0
and when things went well log is
_activePromises:
9: 茠 (reason)
__proto__: Object
_activeSubscriptions:
8: {remove: 茠}
__proto__: Object
_errorCodesToMessagesMapping: {0: "Unknown error occurred. This is probably a bug! Check reason property.", 1: "BleManager was destroyed", 2: "Operation was cancelled", 3: "Operation timed out", 4: "Operation was rejected", 5: "Invalid UUIDs or IDs were passed: {internalMessage}", 100: "BluetoothLE is unsupported on this device", 101: "Device is not authorized to use BluetoothLE", 102: "BluetoothLE is powered off", 103: "BluetoothLE is in unknown state", 104: "BluetoothLE is resetting", 105: "Bluetooth state change failed", 200: "Device {deviceID} connection failed", 201: "Device {deviceID} was disconnected", 202: "RSSI read failed for device {deviceID}", 203: "Device {deviceID} is already connected", 204: "Device {deviceID} not found", 205: "Device {deviceID} is not connected", 206: "Device {deviceID} could not change MTU size", 300: "Services discovery failed for device {deviceID}", 301: "Included services discovery failed for device {deviceID} and service: {serviceUUID}", 302: "Service {serviceUUID} for device {deviceID} not found", 303: "Services not discovered for device {deviceID}", 400: "Characteristic discovery failed for device {deviceID} and service {serviceUUID}", 401: "Characteristic {characteristicUUID} write failed for device {deviceID} and service {serviceUUID}", 402: "Characteristic {characteristicUUID} read failed for device {deviceID} and service {serviceUUID}", 403: "Characteristic {characteristicUUID} notify change 鈥 for device {deviceID} and service {serviceUUID}", 404: "Characteristic {characteristicUUID} not found", 405: "Characteristics not discovered for device {deviceID} and service {serviceUUID}", 406: "Cannot write to characteristic {characteristicUUID} with invalid data format: {internalMessage}", 500: "Descriptor {descriptorUUID} discovery failed for d鈥iceUUID} and characteristic {characteristicUUID}", 501: "Descriptor {descriptorUUID} write failed for devic鈥iceUUID} and characteristic {characteristicUUID}", 502: "Descriptor {descriptorUUID} read failed for device鈥iceUUID} and characteristic {characteristicUUID}", 503: "Descriptor {descriptorUUID} not found", 504: "Descriptors not discovered for device {deviceID}, 鈥iceUUID} and characteristic {characteristicUUID}", 505: "Cannot write to descriptor {descriptorUUID} with invalid data format: {internalMessage}", 506: "Cannot write to descriptor {descriptorUUID}. It's 鈥 iOS and therefore forbidden on Android as well.", 600: "Cannot start scanning operation", 601: "Location services are disabled"}
_eventEmitter: NativeEventEmitter {_subscriber: EventSubscriptionVendor, _nativeModule: {鈥}
_scanEventSubscription: null
_uniqueId: 9
__proto__: Object
it seems the BleManager's _activePromises and _activeSubscriptions are different. I marked with bold text.
P.S. It occurs very frequently in iOS(higher than 13.3.1) not in Andorid.
Is there any progress??
This also happen when you're using functional components and/or Hooks. Even if you disable the remote debug, still shows the Unknown state Error.
Could you make a repository with reproduction of this issue? Main part missing in code above is how BleManager is created and how it's passed to the component.
I am also having this issue: BluetoothLE is in unknown state
in the Xcode console I can see also this error
2020-12-27 10:00:07.279967+0100 [19145:4875543] [CoreBluetooth] API MISUSE:
2020-12-27 10:00:07.280866+0100 [19145:4874888] [CoreBluetooth] XPC connection invalid
I'm getting exactly the same problem.
This is the log:
2020-12-29 17:43:54.156254+0100 MiPlus[670:31923] [CoreBluetooth] API MISUSE:
2020-12-29 17:43:54.160394+0100 MiPlus[670:33450] [CoreBluetooth] XPC connection invalid
It is important to keep only a single instance of BleManager. Readme was recently updated to stress this out.
Am using only one single instance of BleManager and I still get the error
EDIT:
I was using Hooks, problem solved for me now.
Using Hooks _does not_ mean that you use only a single instance of anything. You need to learn what each hook does and when it reloads its value.
My code was something like this:
constructor() {
this.manager = new BleManager()
}
reset() {
this.manager.destroy()
this.manager = new BleManager()
}
connect() {
this.reset()
this.manager.scan()
}
In Android i need to reset the BLE manager because of some problems on re-connection with a Huawei Tablet.
In IOS I'm getting the error "[CoreBluetooth] XPC connection invalid".
I resolved the bug in release mode with this edit:
// ...
connect() {
if (Platform.os === 'android') this.reset()
this.manager.scan()
}
However I still have the problem in debug mode with active debugger.