adafruit / Adafruit_CircuitPython_BLE

Bluetooth Low Energy (BLE) library for CircuitPython
MIT License
124 stars 57 forks source link

ManufacturerData tweak to offer control over ordering of its data fields #97

Closed kevinjwalters closed 4 years ago

kevinjwalters commented 4 years ago

This changes self.data from an {} to an OrderedDict() to offer more control over the data field ordering for the benefit of the prefix matching.

On a side note, my understanding is that big python (CPython) has used an insertion ordered implementation for normal dict since 3.6 and this has become part of the language spec now in 3.7

kevinjwalters commented 4 years ago

I added a single but long line to the inline ManufacturerData docs, let me know if that needs further polishing.

kevinjwalters commented 4 years ago

@tannewt Is that comment for me or @dhalbert ? I'm not comfortable with making that particular global change due to lack of experience with the internals and limited testing resources.

tannewt commented 4 years ago

@kevinjwalters It was for you but it's fine if we do it later. I've opened https://github.com/adafruit/circuitpython/issues/3278 to track it.

What prefix matching are you doing where this is important? Ordering of entries in the advertisement seems outside of the BLE spec.

kevinjwalters commented 4 years ago

It's not the ordering of entries in an advertising packet, it's the ordering of entries within manufacturer data field that interests me and that is what this PR affects.

In an application I am using the same approach as AdafruitColor where the prefix looks into the first part of the manufacturer data to spot an ID which identifies the type and therefore class for the data.

https://github.com/adafruit/Adafruit_CircuitPython_BLE/blob/73a840061b17d09c315b0f03bcadb2a2580be5a7/adafruit_ble/advertising/adafruit.py#L51-L60

I have multiple manufacturer fields so for prefix matching to work for an id number I need to ensure that one appears first. Multiple fields are attractive as I have an optional field and those are supported well by ManufacturerDataField.

https://github.com/adafruit/Adafruit_Learning_System_Guides/pull/1185/files#diff-9cfa0c5482e43d21a6ed0e9c4ba6e599R71-R79

kevinjwalters commented 4 years ago

Is the adafruit_ble library used by any SAMD21 (M0) boards or are parts of it useful or usable for those? I've used the https://github.com/adafruit/Adafruit_CircuitPython_BluefruitSPI library before on a Feather M0 Bluefruit.

dhalbert commented 4 years ago

Is the adafruit_ble library used by any SAMD21 (M0) boards or are parts of it useful or usable for those? I've used the https://github.com/adafruit/Adafruit_CircuitPython_BluefruitSPI library before on a Feather M0 Bluefruit.

Are you thinking about whether OrderedCollection might not be present?

Right now the library is only usable on nRF boards and via Blinka. However, I'm finishing up an implementation of _bleio for the ESP32 co-processor, used on Metro M4 Airlift, PyPortal, etc., and it's also available as a breakout.

I'm not sure there's enough RAM on SAMD21 boards. You could try importing some of adafruit_ble on a SAMD21 and see whether it fits at all.

kevinjwalters commented 4 years ago

Yes, the other ticket shows it AWOL on some SAMD board and inevitably it is the SAMD21 but I wasn't sure what the plan was for adafruit_ble. Gemma M0 example below:

Adafruit CircuitPython 5.3.0 on 2020-04-29; Adafruit Gemma M0 with samd21e18
>>> from collections import OrderedDict
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name OrderedDict
>>> import collections
>>> dir(collections)
['__name__', 'namedtuple']