diff --git a/relay/connection.py b/relay/connection.py index eb9cf41..d268e1d 100644 --- a/relay/connection.py +++ b/relay/connection.py @@ -1,16 +1,41 @@ from crypt_random import secure_random +from lora_handler import LoRaHandler, LoRaMessage - +import time +import uasyncio as asyncio class Connection: - def load_public_constants(self): - with open("public_constants.txt", "r") as f: - self.P = int(f.readline(), 16) - self.G = int(f.readline(), 16) - def __init__(self): self.load_public_constants() - self.private_key = int.from_bytes(secure_random(1024), "big") - self.public_key = pow(self.G, self.private_key) % self.P \ No newline at end of file + # generate diffie-hellman keys + print("Generating keys...") + print(" - Generating private key...") + self.private_key = int.from_bytes(secure_random(32), "big") # 32 bytes = 256 bits + print(" - Generating public key...") + self.public_key = pow(self.G, self.private_key, self.P) + + # start lora handler + self.lora = LoRaHandler() + + async def advertising_loop(self): + while True: + self.lora.advertise() + await asyncio.sleep(5) + + async def start(self): + print("Starting connection...") + asyncio.create_task(self.advertising_loop()) + + while True: + msg: LoRaMessage = await self.lora.message_queue.get() + + print(f"Received message from {msg.sender_id}: {msg.payload}") + print("Sending response...") + self.lora.send(b"Pong!", msg.sender_id) + + def load_public_constants(self): + with open("public_constants.txt", "r") as f: + self.P = int(f.readline(), 16) + self.G = int(f.readline(), 16) \ No newline at end of file diff --git a/relay/lora_handler.py b/relay/lora_handler.py index d055bb9..1d25852 100644 --- a/relay/lora_handler.py +++ b/relay/lora_handler.py @@ -2,9 +2,30 @@ import time import uuid from sx1262 import SX1262 +import uasyncio as asyncio + from machine import Pin led = Pin(25, Pin.OUT) +class Queue: + def __init__(self): + self.items = [] + self.waiters = [] + + async def put(self, item): + self.items.append(item) + if self.waiters: + waiter = self.waiters.pop(0) + waiter.set() + + async def get(self): + while not self.items: + event = asyncio.Event() + self.waiters.append(event) + await event.wait() + + return self.items.pop(0) + class FixedDeque: def __init__(self, maxlen): self.maxlen = maxlen @@ -55,7 +76,7 @@ class LoRaHandler: def __init__(self): print("Initializing LoRa...") - self.sender_id = str(uuid.uuid4()) + self.my_id = str(uuid.uuid4()) # initialize our radio, im using the HAT SX1262 hat for the pico self.radio = SX1262(spi_bus=1, clk=10, mosi=11, miso=12, cs=3, irq=20, rst=15, gpio=2) @@ -64,9 +85,10 @@ class LoRaHandler: self.recent_messages = FixedDeque(32) self.neighbours = set() + self.message_queue = Queue() def send(self, data: bytes, recipient_id: str): - msg_bytes = LoRaMessage(sender_id=self.sender_id, recipient_id=recipient_id, payload=data).encode() + msg_bytes = LoRaMessage(sender_id=self.my_id, recipient_id=recipient_id, payload=data).encode() self.radio.send(msg_bytes) def forward(self, msg: LoRaMessage): @@ -87,12 +109,13 @@ class LoRaHandler: # if we receive a message with lifetime <= 0 we just drop it, # otherwise we decrement the lifetime and forward it to all # neighbors except the sender + msg.lifetime -= 1 if msg.lifetime <= 0: return - msg.lifetime -= 1 # forward messages if they aren't meant for us - if (msg.recipient_id != self.sender_id) and msg.recipient_id != "BROADCAST": + + if (msg.recipient_id != self.my_id) and msg.recipient_id != "BROADCAST": print("Forwarding message...") self.forward(msg) return @@ -101,9 +124,11 @@ 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) + return - print(f"Received message from {msg.sender_id}: {msg.payload}") + asyncio.create_task(self.message_queue.put(msg)) @@ -119,5 +144,5 @@ class LoRaHandler: self.on_receive(LoRaMessage.decode(msg)) elif events & SX1262.TX_DONE: - #print('TX done.') - pass \ No newline at end of file + pass + #print('TX done.') \ No newline at end of file diff --git a/relay/main.py b/relay/main.py index 4f0a06b..0e0e7aa 100644 --- a/relay/main.py +++ b/relay/main.py @@ -1,11 +1,12 @@ from sx1262 import SX1262 from _sx126x import * + +from connection import Connection + import time import crypt_random +import uasyncio as asyncio -from lora_handler import LoRaHandler - -LORA_ENABLED = True BLUETOOTH_ENABLED = False @@ -14,15 +15,9 @@ def main(): if BLUETOOTH_ENABLED: from bluetooth_handler import BluetoothHandler bluetooth_handler = BluetoothHandler() - - lora_handler = None - if LORA_ENABLED: - lora_handler = LoRaHandler() - print("Ready!") - while True: - lora_handler.advertise() - time.sleep(5) + conn = Connection() + asyncio.run(conn.start()) if __name__ == "__main__":