yanshouwang / bluetooth_low_energy

A Flutter plugin for controlling the bluetooth low energy.
https://pub.dev/packages/bluetooth_low_energy
MIT License
48 stars 15 forks source link

Advertising Data appears incomplete #46

Open martin-robert-fink opened 7 months ago

martin-robert-fink commented 7 months ago

I'm trying to get device name during the scan process. For many devices I scan, the name field is null. I should then be able to get the Type = 0x09 = complete local name or the Type = 0x08 = Shortened local name from the advertising data. I have checked the serviceData and serviceUUIDs field and no data. Is there raw AD data missing that I can get somewhere? Simple device scans with no data are iPhone and Apple Watch. Some devices have data in serviceData and serviceUUIDs but not the raw AD data.

Am I missing something?

Thanks, Martin

yanshouwang commented 7 months ago

You can get the raw advertie data on the Android platform, but the iOS doesn't have a raw data API, look at this document: https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerdelegate/advertisement_data_retrieval_keys

So I use the iOS API in this plugin to unify the interface, you can't get raw data with this plugin.

But I think you can get the device name if the advertise data contains 0x08 or 0x09 TLV structure.

martin-robert-fink commented 7 months ago

Right now, I'm trying to duplicate the functionality of LightBlue: LightBlue.

It sounds like you're saying that's not possible?

Not sure what you mean by TLV structure? Where is that structure. All the data I look at in the advertising data is empty right now.

Thanks, Martin

yanshouwang commented 7 months ago

The CoreBluetooth framework doesn't provide a raw data API.

I don't konw how the LightBlue app get the raw data, maybe it convert back raw data by the advertisement key? But the device name key could be 0x09 or 0x08, so there may be errors when get raw data with this way.

The TLV is the advertisement base structure(Length,Type,Value)

See: https://stackoverflow.com/questions/22833198/get-advertisement-data-for-ble-in-ios

ekuleshov commented 7 months ago

@martin-robert-fink @yanshouwang I noticed that the advertised local name is being truncated or omitted when the advertising messages is too large. E.g. when implementing peripheral in the app, I had to remove service uuids from the message in order to get the local name visible.

I wonder if it has something to do with the Bluetooth 5 advertising extension and 2M PHY support. https://source.android.com/docs/core/connect/bluetooth/ble_advertising

martin-robert-fink commented 7 months ago

It does appear as though the iOS bluetooth API does not allow raw advertisement data. I installed LightBlue on iOS (I was using it on Mac before) and the somehow, it still gets some data, but it's different. For example, it's still getting iPhone/iPad/Airpods names during the scan. But, while the Mac also gets the name of AirTags, the iOS version does not. So, this is all very interesting. I'm not quite sure what to do (if I can do anything at all :)).

martin-robert-fink commented 7 months ago

BTW... My end goal in all of this is to read data from my scuba diving computer. It does provide a name during the scan. So, for now, I should be able to start experimenting with downloading dive data from my dive computer. I was learning how to use the plug in, and when I couldn't get advertisement data, I thought I was doing something wrong.

ekuleshov commented 7 months ago

@martin-robert-fink some devices don't advertise local name. You can deal with that by filtering scan results using name patterns matching your device and can also match on the advertised services uuids.

There is an app called nRF Connect you can use (on Android and iOS) to see what is being advertised by BLE devices and to test/debug communication with these devices.

martin-robert-fink commented 7 months ago

Ok, cool. Thanks!

yanshouwang commented 7 months ago

@martin-robert-fink @yanshouwang I noticed that the advertised local name is being truncated or omitted when the advertising messages is too large. E.g. when implementing peripheral in the app, I had to remove service uuids from the message in order to get the local name visible.

I wonder if it has something to do with the Bluetooth 5 advertising extension and 2M PHY support. https://source.android.com/docs/core/connect/bluetooth/ble_advertising

Current this plugin doesn't support extension advertisement when act as a peripheral, that means the advertisement data can not exceed 31 bytes, I need to investigate how to do this on every platform, after that I will decide how to implement this feature in this plugin.

@martin-robert-fink Beside device name in the advertisement, there is another device name in the peripheral class, maybe I should expose this property: https://developer.apple.com/documentation/corebluetooth/cbperipheral/1519029-name

martin-robert-fink commented 7 months ago

That would be great if you can do that!

yanshouwang commented 7 months ago

That would be great if you can do that!

I will check this issue when I have spare time

Does the lightBlue or nRF connect can get your target device's name or something in advertisement which this plugin can't get?

martin-robert-fink commented 7 months ago

LightBlue is definitely getting more data than I can get from this plug in. There is a difference between MacOS and iOS. iOS has a bit less. I don't know about nRF.

Thanks for working on this. Martin

github-actions[bot] commented 6 months ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 6 months ago

This issue was closed because it has been inactive for 14 days since being marked as stale.