mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
- Implemented PacketLogScreen to display and filter BLE packet logs. - Added functionality to export logs as CSV and text files. - Introduced clipboard copy feature for hex data. - Implemented clear logs functionality with confirmation dialog. - Enhanced MeshCoreBleService to log TX and RX packets with descriptions. - Added BufferReader methods for reading unsigned and signed 16-bit integers (big-endian). - Updated CayenneLppParser to read values as big-endian. - Created MessageStorageService for persisting messages to local storage. - Enhanced map markers to display telemetry data including voltage, humidity, and pressure.
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