Closed Yodio-Jeff closed 1 year ago
Hi @Yodio-Jeff ... it's unlikely to be anything in the plugin, as we report these values exactly as we receive them from iOS itself... there's no additional parsing or transformations going on within this plugin at all.
Having said that, are you able to grab a screenshot of how nrf Connect renders this advertising packet? Ideally one showing the bad packet and one showing the good packet would be great, as we might be able to figure things out from there.
Out of interest, is this device connectable?
This has been a baffling issue. My app shows the scanned devices as they come in, and it's only these new devices that are causing the headaches.
let subscription = this.bleService.startScan(options).subscribe(candidate => {
// many devices report back an ID but no name field
candidate.hasProperName = !(candidate.name == null) && candidate.name.length > 0;
if (!candidate.hasProperName) {
candidate.name = unknownDeviceName;
}
this.messageHandler(`${this.devices.length} :: "${candidate.name}", ${candidate.id}, ${candidate.rssi}`);
Immediately after that it puts out the advertising data, either everything iOS provides, or a simple decode of the Android raw data.
Here's the nrfConnect screenshot I have showing the bad output:
The two entries NJGPM and NJGPW should be named serial number "SN:00000xxxxx", and the service UUID is FFF0.
From our iOS app, you can see the advertising data for an older device that works, and the oddball device:
The Android app shows the partially decoded advertising buffer for two of the weird locks:
So both apps agree the names are weird, but nrfConnect usually shows the expected data. The manufacturer insists they didn't do anything with the name fields. With the scan filter "FFF0" active the oddballs were excluded. Scanning with no filter reveals them, and we can connect, except writing to the normal service causes a long delay and the error "peripheral with UUID FFF0 can't be found on device ....". They certainly act - to the app - as if those odd values are real.
Any ideas? Could changes to the iBeacon setup or the header bits drastically change the way the broadcast payload is interpreted? Why do scanning tools - including the OS's own Bluetooth devices scanner - show the expected values? This makes no sense and we need it fixed.
I recently discovered that the name shown by iOS via the plugin appears to update after connecting to the device, based on the GAP service (service 0x1800, char ID 0x2A00). See Bluetooth name caching - https://developer.apple.com/forums/thread/19381?answerId=61155022#61155022 for a bit more detail about this.
Is this possibly what's happening for you there? Have you connected to any of the good/bad devices before?
As an experiment, I chopped in the @capacitor-community/bluetooth-le plugin, just the scan functions. While it's ability to find devices was seriously underwhelming, on about 1 in 20 tries it does show the correct serial number name. With two of the devices in range, it never shows both correctly in the same scan.
Name caching may be happening on iOS. The weird names are popping up on Android, too. In the screenshot above you can see where the name NJGPM returned by the OS was encoded in the raw advertising buffer, field type 09.
The manufacturer insists they're now sending one fixed advertising packet. However, we're seeing the unusable data show up regularly in nrfConnect scans. I'm beginning to suspect a bug in their firmware that we'll have to work around.
One of the biggest issues we've had is devices not showing up in scans, even within arm's reach. Is there some way to increase the sensitivity, particularly on iOS? Advertisements are broadcast every half second, yet it can take a full 3 second scan to get one detection. It's frustratingly erratic, worse than the OS device detector.
@Yodio-Jeff .5s is an extremely slow advertisment interval! Apple recommends a 20ms interval for the first 20s or so...
I'd highly suggest reading through section 41.5 (page187) in Apple's Accesory Design Guidelines: https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf
@peitschie nrfConnect shows the interval jumping around between 1/4 and 1/2 a second. The specs we have are sparse on the finer details.
The Apple guide looks more readable than the official Bluetooth docs, thanks for the pointer. Basic question: Does the central broadcast a "who's out there?" message that prompts the peripherals to advertise their presence? If so, all the devices in range should be found quickly.
@Yodio-Jeff it is a broadcast but....
Bluetooth advertisments are scattered across multiple radio channels. In order for a phone to "hear" the broadcast, it has to be listening on the right channel at the right time to hear the packet. Most phones can't listen to multiple channels at a time, and will switch between channels in rapid succession. Additionally, in order for the broadcast to be understood, it has to occur at a time when nothing else is talking at the same time (as colliding broadcasts on the same frequency effectively destroy your carefully crafted packet).
The BLE consortium has a reasonable intro on this at https://www.bluetooth.com/blog/advertising-works-part-1/ (see Of Transmitters and Receivers) but I find https://www.argenox.com/library/bluetooth-low-energy/ble-advertising-primer/ a better visual representation.
3 seconds when using a 250 => 500ms interval sounds about right to me 🙂 . If you want much faster than that, then the advertising interval definitely needs to be far closer to the 20ms range!
Closing this issue, as it seems like there's no fixes or problems in the plugin itself. Feel free to continue the discussion here however, or raise a new issue if problems are encountered.
We're connecting to a custom BLE device from an iPhone. The manufacturer changed their advertising data and the new devices no longer work. The engineers insist they only changed the manufacturer-specific field (0xFF), removed the iBeacon setting, and went to a single fixed advertisement. When scanning, we should see a name like "SN:0000096267". Instead, scanning produces "NJGPW", and while our app connects, the custom service fails to respond.
nrfConnect usually shows the correct information for these devices, but we've seen it produce the same nonsense.
In the screenshot from our app you can see what looks like complete device information, except the name and service UUID are bad.
The scan() call is basic (using the Ionic @ionic-native/ble wrapper):
Has anyone seen situations where nrfConnect and this plugin don't return the same info?