Files
meshcore-sar_android/MESHCORE_QUICK_REFERENCE.md
Janez T 59de627289 feat: Add Packet Log Screen for BLE packet logging and exporting
- 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.
2025-10-14 15:27:18 +02:00

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

  1. Always verify signatures on ADVERT packets
  2. Validate MAC before decrypting encrypted payloads
  3. Check timestamps to prevent replay attacks
  4. Sanitize strings before display (max length, UTF-8 validation)
  5. Rate limit packet processing to prevent DoS
  6. Use constant-time comparison for MAC validation

Flutter Implementation

Main Files:

  • lib/services/meshcore_ble_service.dart - BLE protocol
  • lib/services/buffer_reader.dart - Binary parsing
  • lib/services/buffer_writer.dart - Binary encoding
  • lib/services/cayenne_lpp_parser.dart - Telemetry decoding

Additional Documentation


Document Version: 1.0 Last Updated: 2025-10-14