mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 08:20:36 +00:00
5.5 KiB
5.5 KiB
MeshCore Quick Reference Card
Quick lookup for MeshCore protocol constants and structures.
BLE Service (App ↔ Device)
Service UUID: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
- RX:
6E400002-B5A3-F393-E0A9-E50E24DCCA9E(Write - Commands) - TX:
6E400003-B5A3-F393-E0A9-E50E24DCCA9E(Notify - Responses)
BLE Commands (RX)
| Code | Command | Format |
|---|---|---|
0x04 |
Get Contacts | [0x04] |
0x02 |
Send Message | [0x02][32B pubkey][2B len][text] |
0x27 |
Get Telemetry | [0x27][32B pubkey] |
BLE Responses (TX)
| Code | Response | Format |
|---|---|---|
0x03 |
Contact Info | [0x03][32B pubkey][1B type][64B name][4B lat][4B lon] |
0x07 |
Message | [0x07][1B type][4B src][4B dest][2B len][text] |
0x8B |
Telemetry | [0x8B][4B pubkey][Cayenne LPP data] |
Mesh Packet Structure (LoRa Network)
[Header: 1B] [Path Len: 1B] [Path: 0-64B] [Payload: 0-184B]
Header Encoding
Bits: [Ver:2][Type:4][Route:2]
Route = header & 0x03
Type = (header >> 2) & 0x0F
Ver = (header >> 6) & 0x03
Route Types
| Code | Name | Description |
|---|---|---|
0x01 |
FLOOD | Broadcast to all nodes |
0x02 |
DIRECT | Point-to-point via path |
Payload Types
| Code | Name | Encrypted | Structure |
|---|---|---|---|
0x00 |
REQ | ✓ | [1B dest][1B src][2B MAC][encrypted] |
0x01 |
RESPONSE | ✓ | [1B dest][1B src][2B MAC][encrypted] |
0x02 |
TXT_MSG | ✓ | [1B dest][1B src][2B MAC][encrypted] |
0x03 |
ACK | ✗ | [ack data] |
0x04 |
ADVERT | ✗ | [32B pubkey][4B ts][app][64B sig] |
0x05 |
GRP_TXT | ✓ | [1B chan][2B MAC][encrypted] |
0x06 |
GRP_DATA | ✓ | [1B chan][2B MAC][encrypted] |
0x07 |
ANON_REQ | ✓ | [1B dest][32B ephemeral][2B MAC][enc] |
0x08 |
PATH | ✓ | [1B dest][1B src][2B MAC][encrypted] |
0x09 |
TRACE | ✗ | [trace data] |
0x0F |
RAW_CUSTOM | ? | Application-defined |
Advertisement App Data
Format: [Flags:1B][Lat:4B?][Lon:4B?][Battery:1B?][Temp:1B?][Name:NB?]
Flags Byte
Bits: [Name:1][Temp:1][Batt:1][LatLon:1][Type:4]
Type = flags & 0x0F
Has GPS = flags & 0x10
Has Batt = flags & 0x20
Has Temp = flags & 0x40
Has Name = flags & 0x80
Contact Types
| Code | Name | Description |
|---|---|---|
0x00 |
NONE | Unknown |
0x01 |
CHAT | Team member (shown on map) |
0x02 |
REPEATER | Network node |
0x03 |
ROOM | Group channel |
Cayenne LPP (Telemetry)
Format: [Channel:1B][Type:1B][Data]
| Type | Code | Data | Decoding |
|---|---|---|---|
| GPS | 0x88 |
12B | lat/lon ÷ 10000, alt ÷ 100 |
| Temp | 0x67 |
2B | int16 ÷ 10 for °C |
| Analog | 0x02 |
2B | uint16 ÷ 100 for volts |
Example:
[01][88][A0C20600][30670200][2C010000]
^ch ^gps ^-lat-^ ^-lon-^ ^-alt-^
GPS: 44.304°N, 15.7488°E, 3.00m
Constants
Size Limits
- Max Packet Payload: 184 bytes
- Max Path Size: 64 bytes
- Max Advert Data: 32 bytes
- Public Key: 32 bytes
- Private Key: 64 bytes
- Signature: 64 bytes
- MAC: 2 bytes
- Cipher Block: 16 bytes
Coordinate Encoding
// Encode
int32 encoded = (double degrees * 10000).toInt();
// Decode
double degrees = encoded / 10000.0;
// Precision: 4 decimal places (~11m accuracy)
Common Operations
Parse BLE Contact Response
final pubkey = data.sublist(1, 33); // 32 bytes
final type = data[33]; // 0-3
final name = data.sublist(34, 98); // 64 bytes
final lat = ByteData.view(data.buffer)
.getInt32(98, Endian.little) / 10000.0;
final lon = ByteData.view(data.buffer)
.getInt32(102, Endian.little) / 10000.0;
Parse Mesh Packet Header
final header = packet[0];
final routeType = header & 0x03;
final payloadType = (header >> 2) & 0x0F;
final version = (header >> 6) & 0x03;
final isFlood = routeType == 0x01;
final isTxtMsg = payloadType == 0x02;
Parse Advertisement Flags
final flags = appData[0];
final contactType = flags & 0x0F;
final hasGPS = (flags & 0x10) != 0;
final hasBattery = (flags & 0x20) != 0;
final hasTemp = (flags & 0x40) != 0;
final hasName = (flags & 0x80) != 0;
Parse Cayenne LPP GPS
if (data[1] == 0x88) { // GPS type
final lat = ByteData.view(data.buffer)
.getInt32(2, Endian.little) / 10000.0;
final lon = ByteData.view(data.buffer)
.getInt32(6, Endian.little) / 10000.0;
final alt = ByteData.view(data.buffer)
.getInt32(10, Endian.little) / 100.0;
}
Security Notes
- Always verify signatures on ADVERT packets
- Validate MAC before decrypting encrypted payloads
- Check timestamps to prevent replay attacks
- Sanitize strings before display (max length, UTF-8 validation)
- Rate limit packet processing to prevent DoS
- Use constant-time comparison for MAC validation
Flutter Implementation
Main Files:
lib/services/meshcore_ble_service.dart- BLE protocollib/services/buffer_reader.dart- Binary parsinglib/services/buffer_writer.dart- Binary encodinglib/services/cayenne_lpp_parser.dart- Telemetry decoding
Additional Documentation
- MESHCORE_PROTOCOL.md - Complete mesh packet protocol specification
- MESHCORE_BLE_PROTOCOL.md - Complete BLE command/response protocol
- CLAUDE.md - Project overview and development guide
Document Version: 1.0 Last Updated: 2025-10-14