cordova-plugin-ble-central
cordova-plugin-ble-central copied to clipboard
BLE startScan([service]) is not returning any devices
I'm using Android and "cordova-plugin-ble-central": "^1.4.4" The method startScan([]) with empty service is returning devices. but when I add a service no device is discovered. I tried to connect to one of the devices, so that I can be sure that I'm using the right service. These are the services: 0: "1800" 1: "1801" 2: "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
When I try to call the startScan method with one of the services nothing is discovered
@gse-mmobile there's a difference between a device having a service and the device advertising support for the service. While it's encouraging that you can connect and interact with the services, the device also needs to put this data in the advertising packet in order for the filtering to work.
I'd suggest looking at the advertising packet using nrf Connect and confirming which services are being advertised.
For example, the advertising payload for a Powerpal BLE device advertises a single 128-bit service in it's advertising packet:
Hello,
I am having a similar issue. On iOS I am able to call startScanWithOptions with a service list without a problem. Devices are discovered and returned. On Android, no devices are ever returned. If I call startScanWithOptions with an empty service list [], it works just fine on Android.
Does not work on Android v12, does work on iOS 15:
ble.startScanWithOptions(["4149524c-03b7-0014-0004-000000000000", "4149524c-03b7-0014-0000-000000000000", "4149524c-03b7-0066-0003-000000000000"]
Does work on Android v12:
ble.startScanWithOptions([]
Using a Pixel 4a with Android v12. I have not tested this on any other Android devices. If I find a combination that works I will let you know.
I have tested this issue on:
- Android v10 (Samsung Galaxy), SDK 29, 30 or 31
- Android v11 (Google Pixel). SDK 29, 30 or 31
None of those combinations appear to work. Android will not return devices if a service list is provided when the scan is started.
@airbly I suspect you've bumped into an interesting platform difference between Android and iOS there.
What happens if you scan by just one of the services instead of all 3 on Android?
@peitschie , You are correct. Putting only a single service UUID in the array works properly on Android.
I believe the difference here is that Android requires all the listed service UUIDs to be in a single advertising packet, which is impossible because the advertising packet can only be around 32 bytes long. iOS must gather together multiple advertising packets and combine them into a "super" packet, allowing that filter to work.
My suggestion there @airbly is to only filter by one of the services when scanning. Note, you can use any service the peripheral has... you don't necessarily need to scan for them in order to use them.
In all the systems I've designed, I'm only ever searching for either a single 128-bit service UUID, or 1 sometimes 2 16-bit service UUIDs.
I should note, the only way a peripheral could advertise support of all those services is if it "rolls" the advertising packet every few seconds.
E.g., 1 sec advertising "4149524c-03b7-0014-0004-000000000000" 1 sec advertising "4149524c-03b7-0014-0000-000000000000" 1 sec advertising "4149524c-03b7-0066-0003-000000000000" repeat
Those UUIDs represent three different models of peripherals we are trying to monitor for. Right now the first one is the only important one so I can work with the single service UUID limitation.
@airbly that's interesting.
I'm actually a bit surprised it works on iOS. I wonder if this is the underlying cause noted in #816. It seems from your description like iOS will return a device that matches one of the specified services, while Android will only return a device that matches ALL of the specified services.
Is this the behaviour you're seeing?
Putting only a single service UUID in the array works properly on Android
This does NOT work for me, sadly.
Sorry, I have to be more precise. It works by scanning for a UUID I found by accident after looking at the advertised packet, based on the suggestions above.
It is still unclear how nRF Connect can identify all of the services which are really important, if they are not advertised.
@Lazza Bluetooth treats the advertising packet as a completely separate thing from the service discovery that occurs after connecting to a peripheral.
For scanning purposes, the peripheral designers decides which service uuids to include in the advertising packet. You can only scan for service uuids present in the advertising packet.
@peitschie Now I understand better how it works.
Thank you for taking the time and explaining it! 👍 Much appreciated.