asdasdasd i hate bluetooth with a PASSION

This commit is contained in:
2026-05-15 18:43:03 +10:00
parent 46ae344c0c
commit dfc9cd820d
4 changed files with 54 additions and 6 deletions

View File

@@ -112,6 +112,16 @@ class BluetoothHandler:
print("Advertising Bluetooth...")
self.ble.gap_advertise(100_000, self.advertising_payload(name="MeshNode", services=[SERVICE_UUID]))
def send_packet(self, packet_type: int, data: dict):
if not self.connections:
print("No connected devices to send to.")
return
payload = struct.pack("<B", packet_type) + str(data).encode()
for conn_handle in self.connections:
self.ble.gatts_notify(conn_handle, self.tx_handle, payload)
def irq(self, event, data):
print(f"BLUETOOTH IRQ | EVENT: {event}, DATA: {data}")
if event == IRQ_CONNECT:

View File

@@ -3,10 +3,26 @@ from lora_handler import LoRaHandler, LoRaMessage
import time
import uasyncio as asyncio
import json
from machine import Pin
led = Pin("LED", Pin.OUT)
class Connection:
def __init__(self, bluetooth_handler=None):
# ensure led is off during initialization to indicate we're not ready yet
led.value(0)
try:
with open("settings.json", "r") as f:
self.settings = json.load(f)
except FileNotFoundError:
print("No settings file found. Using defaults...")
self.settings = {
"display_name": "Unnamed Node"
}
self.bluetooth_handler = bluetooth_handler
self.load_public_constants()
@@ -20,6 +36,9 @@ class Connection:
# start lora handler
self.lora = LoRaHandler()
# turn on status LED to indicate we're ready
led.value(1)
async def bluetooth_listener(self):
while True:
msg_type, payload = await self.bluetooth_handler.packets.get()
@@ -27,6 +46,10 @@ class Connection:
if msg_type == 3: # advertise self
self.lora.advertise()
def bluetooth_send(self, msg_type: int, payload: dict):
if self.bluetooth_handler:
self.bluetooth_handler.send_packet(msg_type, payload)
async def start(self):
print("Starting connection...")
@@ -35,9 +58,12 @@ class Connection:
while True:
msg: LoRaMessage = await self.lora.message_queue.get()
print(f"Received message from {msg.sender_id}: {msg.payload}")
if msg.payload == b"Ping!":
self.bluetooth_send(4, {"id": msg.sender_id, "name": self.settings["display_name"]})
def load_public_constants(self):
with open("public_constants.txt", "r") as f:
self.P = int(f.readline(), 16)

View File

@@ -5,8 +5,6 @@ from sx1262 import SX1262
import uasyncio as asyncio
from queue import Queue
from machine import Pin
led = Pin(25, Pin.OUT)
class FixedDeque:
def __init__(self, maxlen):
@@ -73,7 +71,17 @@ class LoRaHandler:
msg_bytes = LoRaMessage(sender_id=self.my_id, recipient_id=recipient_id, payload=data).encode()
self.radio.send(msg_bytes)
def has_seen_message(self, msg: LoRaMessage) -> bool:
if msg.message_id in self.recent_messages:
return True
self.recent_messages.append(msg.message_id)
return False
def forward(self, msg: LoRaMessage):
# ensure we don't process a message twice
if self.has_seen_message(msg):
return
msg_bytes = msg.encode()
self.radio.send(msg_bytes)
@@ -83,9 +91,8 @@ class LoRaHandler:
def on_receive(self, msg: LoRaMessage):
# ensure we don't process a message twice
if msg.message_id in self.recent_messages:
if self.has_seen_message(msg):
return
self.recent_messages.append(msg.message_id)
# messages has a lifetime to prevent infinite loops.
# if we receive a message with lifetime <= 0 we just drop it,
@@ -106,8 +113,10 @@ class LoRaHandler:
if not msg.sender_id in self.neighbours:
print(f"Neighbour discovered: {msg.sender_id}")
self.neighbours.add(msg.sender_id)
self.send(b"Ping!", msg.sender_id)
# tell the sender we heard them by sending a ping back
self.send(b"Ping!", msg.sender_id)
self.forward(msg)
return
asyncio.create_task(self.message_queue.put(msg))

3
relay/settings.json Normal file
View File

@@ -0,0 +1,3 @@
{
"display_name": "Cool Guy"
}