Meshcore-sensor-net

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

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 almost universally in the Netherlands now is the EU/UK setting:

869.618 / SF8 / BW62.5 / CR8 header enabled sync word XXXX Description of the on-the-air message: https://gist.github.com/recrof/ca7ccff28c43d1b6bf7e55ce5159100b Dissection code: https://github.com/folkertvanheusden/meshcore-store/blob/master/utils/dissect.py

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.

Investigation

Design

The plan is to use payload type "PAYLOAD_TYPE_GRP_DATA". Initially flood mode, normally direct mode.

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)
  • 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. '#meshcore-sensor-net')

Citizen science payload structure:

  • 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, but we do add a cryptographic checksum to recognize authentic messages
  • 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
  • The hash key itself also calculated as follows:
    • Blake2s hash with key, where key = application secret
    • Fields included in hash: application name, deviceid
  • 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). The resulting key is written to non-volatile storage of the sensor.

Software

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