Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLE startScan([service]) is not returning any devices #910

Open
gse-mmobile opened this issue Mar 30, 2022 · 13 comments
Open

BLE startScan([service]) is not returning any devices #910

gse-mmobile opened this issue Mar 30, 2022 · 13 comments

Comments

@gse-mmobile
Copy link

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 gse-mmobile changed the title BLE startScan([filter]) is not returning any devices BLE startScan([service]) is not returning any devices Mar 30, 2022
@peitschie
Copy link
Collaborator

@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:
image

@airbly
Copy link

airbly commented Jun 13, 2022

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.

@airbly
Copy link

airbly commented Jun 13, 2022

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.

@peitschie
Copy link
Collaborator

@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?

@airbly
Copy link

airbly commented Jun 14, 2022

@peitschie , You are correct. Putting only a single service UUID in the array works properly on Android.

@peitschie
Copy link
Collaborator

peitschie commented Jun 14, 2022

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.

@peitschie
Copy link
Collaborator

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

@airbly
Copy link

airbly commented Jun 14, 2022

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.

@peitschie
Copy link
Collaborator

@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?

@Lazza
Copy link

Lazza commented Jan 12, 2023

Putting only a single service UUID in the array works properly on Android

This does NOT work for me, sadly.

@Lazza
Copy link

Lazza commented Jan 12, 2023

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.

@peitschie
Copy link
Collaborator

@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.

@Lazza
Copy link

Lazza commented Jan 13, 2023

@peitschie Now I understand better how it works.

Thank you for taking the time and explaining it! 👍 Much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants