Meshcore-sensor-net: Difference between revisions

From RevSpace

No edit summary
 
Line 29: Line 29:
At some point the discovery packets reaches a special internet-connected gateway that forwards it to the backend software.
At some point the discovery packets reaches a special internet-connected gateway that forwards it to the backend software.
The backend software processes the data payload and sends back an acknowledgement packet back over the (best) path that it received the message on. When this reaches the sensor node, the sensor node knows the most efficient way to reach the gateway node and uses a "direct" packet. Every now and then it expects a kind of acknowledgement packet back from the server, to know that messages are still coming through. This is actually a bit similar to how LoRaWAN works.
The backend software processes the data payload and sends back an acknowledgement packet back over the (best) path that it received the message on. When this reaches the sensor node, the sensor node knows the most efficient way to reach the gateway node and uses a "direct" packet. Every now and then it expects a kind of acknowledgement packet back from the server, to know that messages are still coming through. This is actually a bit similar to how LoRaWAN works.
== Progress ==
Done so far:
* I understand the meshcore packet structure
* Using an stm32wle5 board (has an sx1262-like built in), we can send a valid group-data packet which is understood by repeaters and repeated
Todo:
* Implement the gateway part, the plan is to use a S3/SX1262 seeed board.
* Write the backend part: listen to MQTT and respond with a valid packet
* Process the backend packet on the sensor node


== Investigation ==
== Investigation ==

Latest revision as of 12:23, 19 March 2026

Project meshcore-sensor-net
File:Yunopicture.png
Status In progress
Contact bertrik
Last Update 2026-03-19

Introduction

This project is an investigation for using meshcore as a transport layer for citizen science data.

Meshcore is basically a network of radio repeaters for lora messages with a specific radio setting. The idea is to use a citizen science sensor with a LoRa radio to uplink citizen science data through this repeater network, get the data repeated, then pick it up using a special kind of node is connected to the internet (e.g. MQTT) that forwards the data to a collection server for further processing.

The LoRa setting used for meshcore almost universally in the Netherlands now is the EU/UK setting:

  • 869.618 / SF8 / BW62.5 / CR8
  • explicit header, CRC enabled
  • sync word 0x12

Description of the on-the-air message:

Meshcore repeaters a relatively "dumb", they just forward anything that resembles a packet (they can't inspect the encrypted part).

The idea is basically:

Sensor first starts up, sends a kind of discovery packet in "flood" mode. This kind of packet is flooded over the entire network. At some point the discovery packets reaches a special internet-connected gateway that forwards it to the backend software. The backend software processes the data payload and sends back an acknowledgement packet back over the (best) path that it received the message on. When this reaches the sensor node, the sensor node knows the most efficient way to reach the gateway node and uses a "direct" packet. Every now and then it expects a kind of acknowledgement packet back from the server, to know that messages are still coming through. This is actually a bit similar to how LoRaWAN works.

Progress

Done so far:

  • I understand the meshcore packet structure
  • Using an stm32wle5 board (has an sx1262-like built in), we can send a valid group-data packet which is understood by repeaters and repeated

Todo:

  • Implement the gateway part, the plan is to use a S3/SX1262 seeed board.
  • Write the backend part: listen to MQTT and respond with a valid packet
  • Process the backend packet on the sensor node

Investigation

Meshcore security

The 16-byte channel key is derived from the channel name, as follows:

 key = hashlib.sha256(name.encode('utf-8')).digest()[0:16]

where 'name' is the channel name, including the '#'

The 1-byte channel hash is derived from the channel key, as follows:

 hash = hashlib.sha256(key).digest()[0]

where 'key' is the byte array containing the key

Encryption of the payload is done using the key:

  • Payload is padded with 0 to multiple of 16
  • Encrypted using AES-128 ECB (!) mode, initialised with the key

The 2-byte MAC is calculated over the *encrypted* payload, using the key:

 mac = sha256-hmac(payload)[0:2]

Design

Communication scheme

The sensor sends measurements. The backend returns ACKs, with preferred path information to reach a gateway. Not every measurement is ACKed, to keep traffic down (like LoRaWAN does), but only every x messages (say 16).

Escalation ladder when the sensor misses ACKs (or when the path to the gateway is lost):

  • When expecting ACKs, just send couple more (re)tries along the last known path, e.g. enable a kind of 'ACK wanted' flag
  • On start-up, try a quick-start with a zero-hop direct message, to probe if the gateway is perhaps within range of the sensor
  • On start-up, if the quick-start did not work, send a flood message (with larger network impact)

To be worked out further.

Packet structure

The plan is to use payload type "PAYLOAD_TYPE_GRP_DATA".

Meshcore packet structure from sensor:

  • Header: 1 byte = payload type PAYLOAD_TYPE_GRP_DATA + (flood or direct)
  • Path: length + path bytes (0 in case of flood)
  • Channel hash: 1 byte
  • MAC: 2 bytes, according to PAYLOAD_TYPE_GRP_DATA format
  • Encrypted payload: citizen science payload structure, encrypted with key derived from "channel name" (e.g. '#sensornet')

Citizen science payload structure (big endian):

  • 4 bytes deviceid
  • 4 bytes counter
  • x bytes citizen science data
  • 4 bytes MAC

Security:

  • The PAYLOAD_TYPE_GRP_DATA payload follows the meshcore structure: 2-byte MAC + encrypted payload
  • The citizen science data is not secret, it is encrypted with a key derived from the channel name (e.g. '#sensornet'), but we do add a cryptographic checksum to recognize authentic messages belonging to a specific application and device
  • The checksum is calculated using the blake2s algorithm, calculated as follows:
    • Blake2s hash with key (32-bytes)
    • Fields included in hash: deviceid, counter, citizen science data
    • We retain 4 bytes of the hash to use as the MAC
  • The hash key itself calculated, as follows:
    • Blake2s hash with key, where key = application secret
    • Fields included in hash: application name, deviceid (big endian)
  • The application name is part of the program image, the deviceid is derived from a unique hardware id, the application secret is entered only during key generation (never stored on device). Only the generated hash key is written to non-volatile storage of the sensor.

Software

See https://github.com/bertrik/meshcore-sensor-net