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

Old BLE devices not found after Android upgrade #223

Open
RJPoelstra opened this issue Sep 30, 2024 · 12 comments
Open

Old BLE devices not found after Android upgrade #223

RJPoelstra opened this issue Sep 30, 2024 · 12 comments
Labels

Comments

@RJPoelstra
Copy link

Describe the bug
I've a BLE product that uses Bluetooth 4.3. After updating the Android OS to 13 the nRF Connect app no longer discovers this product. A newer product based on Bluetooth 5.0 is found just fine.
The iOS version of nRF Connect finds both the new and old product, so it seems there is no issue with the product itself.

To Reproduce
Steps to reproduce the behavior:

  1. Make sure a Bluetooth 4.3 BLE product is advertising
  2. Start scanning in nRF Connect
  3. Notice that the product does not show up in the list

Expected behavior
The product shows up in the list of scan results

Screenshots
I've added screenshots of both the Android and iOS version of nRF Connect scanning at the same time. Notice that the iOS version finds two devices, while the Android version finds one. The filters are configured the same.
Screenshot_20240930_103859_nRF Connect
Schermafbeelding 2024-09-30 om 10 38 05

Versions (please complete the following information):

  • Android version: 13
  • Phone model: Galaxy XCover Pro
  • App Version: 4.28.1
@philips77
Copy link
Member

Hello,
Could you try scanning on an older Android version, or a different phone?
I think it's not that nRF Connect doesn't show it, as it displays everything the system reports, but the Android system fails to deliver it. At some point Android started verifying packets while parsing the advertising data and in case of a failure it ignores that packet. Older phones should pass it through.

Could you check the exact bytes of the packet, or use a sniffer?

@RJPoelstra
Copy link
Author

RJPoelstra commented Oct 1, 2024

Hi,

Thank you for your reply.

I've used a sniffer to capture a packet. Wireshark does not indicate a problem and it's looking fine to me. But I'm not entirely sure what constitutes a valid packet.

I noticed that when I start scanning on the iPhone the ADV_IND packets are interspersed with SCAN_REQ/SCAN_RSP packets. But if I start scanning on the Android phone, no such scan packets appear. So it seems that Android already ignores the initial ADV_IND packets.

I've attached the dissection and bytes from Wireshark. Do you know whether there is any problem with it?
dissect.txt

@philips77
Copy link
Member

I don't know if that matters, but I noticed an interesting thing. The MAC address that the device advertises with is public (34:15:13:d0:39:f9):

Packet Header: 0x2400 (PDU Type: ADV_IND, ChSel: #1, TxAdd: Public)
        .... 0000 = PDU Type: 0x0 ADV_IND
        ...0 .... = Reserved: 0
        ..0. .... = Channel Selection Algorithm: #1
        .0.. .... = Tx Address: Public
        0... .... = Reserved: 0
        Length: 36
    Advertising Address: TexasInstrum_d0:39:f9 (34:15:13:d0:39:f9)

but in the advertising packet it says random and the MAC is inverted:

        LE Bluetooth Device Address
            Length: 8
            Type: LE Bluetooth Device Address (0x1b)
            0000 000. = Reserved: 0x00
            .... ...1 = Type: Random (0x1)
            BD_ADDR: f9:39:d0:13:15:34 (f9:39:d0:13:15:34)

@philips77
Copy link
Member

Also, the packet does not have a Complete Local name, so your filter in nRF Connect excludes it.

@RJPoelstra
Copy link
Author

Also, the packet does not have a Complete Local name, so your filter in nRF Connect excludes it.

The name is in the scan response, so it's properly found by at least the iOS version of nRF Connect. It also used to be found by the Android version.

@RJPoelstra
Copy link
Author

I also noticed that the address configuration seems contradictory. Do you know a tool that can 'fake' advertisement packets based on these bytes. I can then try to broadcast the captured bytes and slightly modify them to see whether I can get Android to accept them.

@philips77
Copy link
Member

You may use nRF Connect for Desktop with the Bluetooth LE app if you have a nRF52832 or nRF52840 DK.
You can set any packet in adv packet and scan response, but I don't think you can modify the MAC address there.
From nRF Connect on Android you can't set the LE Bluetooth Device Address field, but you can the Service UUID. Flags are set automatically.

@RJPoelstra
Copy link
Author

I used nRF Connect for Desktop and tried to mimic the packet as close as possible.
The main differences are:

  • the channel selection algorithm that I've no control over
  • The TX address that is different and set to random
  • But I've adapted the address in the adv data to be public and inverted the address in the header.

This packet is accepted directly by Android (resulting in SCAN_REQ/RSP packets) and discovered in nRF Connect for Android (and iOS).

So it remains a bit a mystery why the original advertisement packet is ignored while a very similar packet is accepted.

@philips77
Copy link
Member

If you may modify the advertising packet on your device, try removing AD fields and check if any change makes it discoverable. Try changing the address type to random or changing it.

@RJPoelstra
Copy link
Author

Unfortunately, I can't modify the firmware of the device.

But I did manage to recreate the exact advertising packet based on an nRF52832 and NCS.
I compared the advertising packets in Wireshark and (apart from timestamps etc) there are no differences in the transmitted bytes. Even the CRC at the end is identical.

Yet, the original device does not show up on Android, while the nRF52832 device does show up. Scanning the nRF52832 results in SCAN_REQ/RSP packets in the air. Scanning the original device does not result in such packets. If some kind of communication issue would be the problem I would expect at least the SCAN_REQ packets from the Android device.

So it seems the mystery is even bigger now.

@philips77
Copy link
Member

Did you compare all the bytes of the adv packet, including header and CRC?

@RJPoelstra
Copy link
Author

Yes, I did. Using the dissect from Wireshark as well as manually comparing the bytes. Only fields such as the timestamps and packet counter differ.

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

No branches or pull requests

2 participants