Skip to content

Commit 3c4bb27

Browse files
committed
Fix the packet prefix
Also changes to manually getting the message so packets are only as long as needed.
1 parent 4894d64 commit 3c4bb27

File tree

1 file changed

+41
-13
lines changed

1 file changed

+41
-13
lines changed

adafruit_radio.py

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@
4242
import time
4343
import struct
4444
import random
45+
from micropython import const
4546
from adafruit_ble import BLERadio
46-
from adafruit_ble.advertising.adafruit import AdafruitRadio
47+
from adafruit_ble.advertising import Advertisement, LazyObjectField
48+
from adafruit_ble.advertising.standard import ManufacturerData, ManufacturerDataField
4749

4850

4951
__version__ = "0.0.0-auto.0"
@@ -56,6 +58,39 @@
5658
#: Amount of time to advertise a message (in seconds).
5759
AD_DURATION = 0.5
5860

61+
_MANUFACTURING_DATA_ADT = const(0xff)
62+
_ADAFRUIT_COMPANY_ID = const(0x0822)
63+
_RADIO_DATA_ID = const(0x0001) # TODO: check this isn't already taken.
64+
65+
class _RadioAdvertisement(Advertisement):
66+
"""Broadcast arbitrary bytes as a radio message."""
67+
prefix = struct.pack("<BBH",
68+
0x3,
69+
0xff,
70+
_ADAFRUIT_COMPANY_ID)
71+
manufacturer_data = LazyObjectField(ManufacturerData,
72+
"manufacturer_data",
73+
advertising_data_type=_MANUFACTURING_DATA_ADT,
74+
company_id=_ADAFRUIT_COMPANY_ID,
75+
key_encoding="<H")
76+
77+
@classmethod
78+
def matches(cls, entry):
79+
if len(entry.advertisement_bytes) < 6:
80+
return False
81+
# Check the key position within the manufacturer data. We already know
82+
# prefix matches so we don't need to check it twice.
83+
return struct.unpack_from("<H", entry.advertisement_bytes, 5)[0] == _RADIO_DATA_ID
84+
85+
@property
86+
def msg(self):
87+
if _RADIO_DATA_ID not in self.manufacturer_data.data:
88+
return b""
89+
return self.manufacturer_data.data[_RADIO_DATA_ID]
90+
91+
@msg.setter
92+
def msg(self, value):
93+
self.manufacturer_data.data[_RADIO_DATA_ID] = value
5994

6095
class Radio:
6196
"""
@@ -111,18 +146,11 @@ def send_bytes(self, message):
111146
raise ValueError(
112147
"Message too long (max length = {})".format(MAX_LENGTH)
113148
)
114-
advertisement = AdafruitRadio()
115-
# Channel byte.
116-
chan = struct.pack("<B", self._channel)
117-
# "Unique" id byte (to avoid duplication when receiving messages in
118-
# an AD_DURATION timeframe).
119-
uid = struct.pack("<B", self.uid)
120-
# Increment (and reset if needed) the uid.
121-
self.uid += 1
122-
if self.uid > 255:
123-
self.uid = 0
149+
advertisement = _RadioAdvertisement()
124150
# Concatenate the bytes that make up the advertised message.
125-
advertisement.msg = chan + uid + message
151+
advertisement.msg = struct.pack("<BB", self._channel, self.uid) + message
152+
153+
self.uid = (self.uid + 1) % 255
126154
# Advertise (block) for AD_DURATION period of time.
127155
self.ble.start_advertising(advertisement)
128156
time.sleep(AD_DURATION)
@@ -158,7 +186,7 @@ def receive_full(self):
158186
"""
159187
try:
160188
for entry in self.ble.start_scan(
161-
AdafruitRadio, minimum_rssi=-255, timeout=1, extended=True
189+
_RadioAdvertisement, minimum_rssi=-255, timeout=1, extended=True
162190
):
163191
# Extract channel and unique message ID bytes.
164192
chan, uid = struct.unpack("<BB", entry.msg[:2])

0 commit comments

Comments
 (0)