bluerange-io / bluerange-mesh

BlueRange Mesh (formerly FruityMesh) - The first completely connection-based open source mesh on top of Bluetooth Low Energy (4.1/5.0 or higher)
https://bluerange.io/
Other
288 stars 109 forks source link

Adding custom data fields to the advertising packets #177

Closed jjduhamel closed 3 years ago

jjduhamel commented 3 years ago

Hello,

I'd like to add a version number to the advertising data so that my app can detect which nodes are running an outdated firmware and prompt the user to update those nodes. My first thought was to include this in the manufacturerData. However, when I scan for devices, it seems that none of the nodes are including any manufacturerData in the advertisement packets. After some digging, I see in the specification that Fruitymesh has two types of advertising packets: one with manufacturer data, and another with service data. Further, the documentation states with regard to service data packets:

This is important when dealing with mobile devices since some have hardware filtering with no support for manufacturer specific data.

Some devices such as iOS devices have a better reception rate when using the serviceData structure.

This is consistent with what I'm observing. My BLE framework is including a string for service data for each of the devices, but no manufacturer data. The string is 16 bytes long, which look similar, but slightly different. A few example are: AwALAAnPEykAAAAA, AwALAAktzSgAAAAA, AwALAAlYCCkAAAAA. I'm hazarding a guess that what I'm seeing is the legacy version of this data structure. However, I can't seem to make any sense of these strings. For instance, when I look at the hex representation of these strings I can't find TYPE_SERVICE_DATA (0x16) or the networkId (0x0B) anywhere.

I have a few questions:

1) Is it expected that iOS should not receive any packets with manufacturerData when scanning to BLE devices? 2) Which data structure do the strings I pasted above represent? How do I decode these values? 3) Is the serviceData an appropriate place to include a firmware version number, or should I go about this somewhere else?

Please let me know if you need any additional information to help debug this.

mariusheil commented 3 years ago

Hi,

1) iOS devices will receive packets with manufacturer specific data if your app is in the foreground. From our tests, the reception rate might sometimes be slower than receiving packets that advertise a service and service data. In the background, you will have to rely mostly on packets with a service as other packets are filtered out and you cannot easily toggle your app functionality with them. 2) I am guessing that the aboce Strings are Base64 encoded (https://cryptii.com/pipes/base64-to-hex), so the first one would be: 03 00 0b 00 09 cf 13 29 00 00 00 00 I am also guessing that they are broadcasted using our 16 bit service UUID (0xFE12). Then, according to the specification, this would be message type 3: https://www.bluerange.io/docs/fruitymesh/Specification.html#_list_of_messagetypes_for_service_data_advertisements So it should be a MeshAccessBroadcast with the following data: https://www.bluerange.io/docs/fruitymesh/MeshAccessModule.html#MeshAccessBroadcast

type: 0x0003 => 3
networkId: 0x000b => 11
bitfield flags: 0x09 => 9
serial number index: 0x002913cf => FM1G7
.....

3) Yes, service data would be fine. However you should not modify one of the existing packets and you should not use the M-Mway Service UUID (0xFE12) for your data, as this might clash with our definitions that we add in the future. If you have a company identifier, you can use that one. You can also use the M-Mway identifier and use 200 (0xC8) as the first byte of the manufacturer specific data. I have created an internal ticket so that we will reserve this messageId for everyone to use. We are not currently using it. This is helpful as you will not have to register your company with the BLE SIG.

For debugging, try the nRF Connect app and make sure to try out the nRF Sniffer which is a very helpful tool to get more insights.

One other thing: You could also use the scan Response Data that is sent out once a device, such as an iOS App does active scanning and asks for this data. This would be the best way to handle this kind of information. You would need to include a full message containing manufacturer id and the manufacturer specific data. So it would represent the exact same data but only would be sent once being asked for it.

Marius

siretty commented 3 years ago

Hello, I'll close this as there has not been any more feedback. Feel free to reopen it.