From 7deb752a97394d9e13937c09a4d0b57407ce9a28 Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Sat, 7 Mar 2026 10:18:47 +1100 Subject: [PATCH] WE DID IT I FIXED THE STUPID BLE HEADER AND IT WORKED --- relay/bluetooth_handler.py | 61 +++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/relay/bluetooth_handler.py b/relay/bluetooth_handler.py index e5d2f04..9193b91 100644 --- a/relay/bluetooth_handler.py +++ b/relay/bluetooth_handler.py @@ -1,4 +1,5 @@ import bluetooth +import struct from micropython import const @@ -16,17 +17,36 @@ IRQ_CONNECT = const(1) IRQ_DISCONNECT = const(2) IRQ_GATTS_WRITE = const(3) +# Advertising payloads are repeated packets of the following form: +# 1 byte data length (N + 1) +# 1 byte type (see constants below) +# N bytes type-specific data + +_ADV_TYPE_FLAGS = const(0x01) +_ADV_TYPE_NAME = const(0x09) +_ADV_TYPE_UUID16_COMPLETE = const(0x3) +_ADV_TYPE_UUID32_COMPLETE = const(0x5) +_ADV_TYPE_UUID128_COMPLETE = const(0x7) +_ADV_TYPE_UUID16_MORE = const(0x2) +_ADV_TYPE_UUID32_MORE = const(0x4) +_ADV_TYPE_UUID128_MORE = const(0x6) +_ADV_TYPE_APPEARANCE = const(0x19) + +_ADV_MAX_PAYLOAD = const(31) + class BluetoothHandler: def __init__(self): print("Initializing Bluetooth...") self.ble = bluetooth.BLE() + print("Activating...") self.ble.active(True) + print("Setting IRQ callback...") self.ble.irq(self.irq) - + print("Getting MAC address...") self.mac_address = self._get_mac_address() - print(f"Mac Address: {self.mac_address}") + print(f"MAC address: {self.mac_address}") self.ble.config(gap_name="NODE-" + self.mac_address) ((self.tx_handle, self.rx_handle),) = self.ble.gatts_register_services((SERVICE,)) @@ -38,11 +58,44 @@ class BluetoothHandler: def _get_mac_address(self): mac = self.ble.config("mac")[1] return ':'.join('{:02X}'.format(b) for b in mac) + + def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0): + payload = bytearray() + + def _append(adv_type, value): + nonlocal payload + payload += struct.pack("BB", len(value) + 1, adv_type) + value + + _append( + _ADV_TYPE_FLAGS, + struct.pack("B", (0x01 if limited_disc else 0x02) + (0x18 if br_edr else 0x04)), + ) + + if name: + _append(_ADV_TYPE_NAME, name) + + if services: + for uuid in services: + b = bytes(uuid) + if len(b) == 2: + _append(_ADV_TYPE_UUID16_COMPLETE, b) + elif len(b) == 4: + _append(_ADV_TYPE_UUID32_COMPLETE, b) + elif len(b) == 16: + _append(_ADV_TYPE_UUID128_COMPLETE, b) + + # See org.bluetooth.characteristic.gap.appearance.xml + if appearance: + _append(_ADV_TYPE_APPEARANCE, struct.pack(" _ADV_MAX_PAYLOAD: + raise ValueError("advertising payload too large") + + return payload def advertise(self): print("Advertising Bluetooth...") - # note: \x02\x01\x06\x0C\x09 is the BLE header that tells other devices we're BLE only and discoverable - self.ble.gap_advertise(100_000, b"\x02\x01\x06\x0C\x09NODE-" + self.mac_address.encode()) + self.ble.gap_advertise(100_000, self.advertising_payload(name="MeshNode", services=[SERVICE_UUID])) def irq(self, event, data): print(f"BLUETOOTH IRQ | EVENT: {event}, DATA: {data}")