6.7 KiB
MeshCore Protocol Reference
Protocol documentation derived from meshcore-cli v1.5.0 (MIT).
This is the canonical reference for MESHTANIC's protocol implementation.
Packet Types
All values from meshcore.packets.PacketType enum.
Identity
| Type | Value | Direction | Description |
|---|---|---|---|
| SELF_INFO | -- | Node->App | Device identity info |
| CONTACT | -- | Node->App | Contact record |
| CONTACT_START | -- | Node->App | Begin contact list sync |
| CONTACT_END | -- | Node->App | End contact list sync |
| CONTACT_URI | -- | App->Node | Import contact by URI |
Messaging
| Type | Value | Direction | Description |
|---|---|---|---|
| CONTACT_MSG_RECV | -- | Node->App | Received direct message (v3) |
| CHANNEL_MSG_RECV | -- | Node->App | Received channel message (v3) |
| MSG_SENT | -- | Node->App | Message send confirmation |
| SEND_TXT_MSG | -- | App->Node | Send text to contact |
| SEND_CHANNEL_MSG | -- | App->Node | Send text to channel |
Network
| Type | Value | Direction | Description |
|---|---|---|---|
| ADVERTISEMENT | 0x80 | Over-air | Peer discovery broadcast |
| PATH_UPDATE | 0x81 | Over-air | Routing path update |
| ACK | 0x82 | Over-air | Packet acknowledgment |
| PATH_DISCOVERY | -- | Over-air | Route discovery request |
Binary / Telemetry
| Type | Value | Direction | Description |
|---|---|---|---|
| STATUS | -- | Node->App | Device status struct |
| KEEP_ALIVE | -- | Bidirectional | Connection keepalive |
| TELEMETRY | -- | Over-air | Cayenne LPP sensor data |
| MMA | -- | Over-air | Mesh management |
| ACL | -- | Node->App | Access control list |
| NEIGHBOURS | -- | Node->App | Neighbor table |
Control
| Type | Value | Direction | Description |
|---|---|---|---|
| NODE_DISCOVER_REQ | -- | App->Node | Request node discovery |
| NODE_DISCOVER_RESP | -- | Node->App | Node discovery result |
| SEND_CONTROL_DATA | -- | App->Node | Send control command |
| SET_FLOOD_SCOPE | -- | App->Node | Configure flood scope |
Session
| Type | Value | Direction | Description |
|---|---|---|---|
| LOGIN_SUCCESS | -- | Node->App | Authentication success |
| LOGIN_FAILED | -- | Node->App | Authentication failure |
| MESSAGES_WAITING | -- | Node->App | Pending message count |
Contact Model
Contacts are identified by public key (hex string). Each contact has:
- Public key: Primary identity, hex-encoded
- Display name: User-chosen name
- Type: Node type (0=standard, 3=room server, etc.)
- Last seen: Timestamp of last advertisement/message
- Path info: SNR, RSSI, hop count from last path update
- ACL flags: Per-contact permissions
Contact Discovery
- Node broadcasts ADVERTISEMENT packets periodically
- Receiving nodes add/update contact in database
- PATH_UPDATE packets refine routing information
- SNR/RSSI tracked for link quality assessment
Contact Types
| Type | Value | Description |
|---|---|---|
| Standard | 0 | Regular mesh node |
| Repeater | 1 | Relay-only node |
| Client | 2 | Companion-connected client |
| Room Server | 3 | Store-and-forward server |
Channel Model
Channels are named groups prefixed with #.
Key Derivation
Channel encryption keys are derived deterministically from the channel name:
channel_key = derive_key("#channel_name")
All nodes with the same channel name automatically share the encryption key. No key exchange needed.
Channel Properties
- Name:
#-prefixed string (e.g.,#public,#emergency) - Index: 0-39 capacity per node
- Encryption: AES-256-GCM with name-derived key
- Persistence: Channels survive reboot (stored in NVS)
Routing
Hybrid Flood + Path Hash
MeshCore uses a hybrid routing strategy:
- Flood routing: Broadcast to all neighbors within flood scope. Used for discovery and broadcast messages.
- Path hash routing: Directed routing using cached path information. Used for unicast messages to known contacts.
Flood Scope
Configurable per-node. Limits how many hops a flooded packet will travel:
- Scope 0: Direct neighbors only
- Scope 1-N: N-hop radius
- Higher scope = more network coverage, more airtime used
Path Tracking
Each contact entry maintains:
- Last known path hash
- SNR at each hop
- RSSI at each hop
- Hop count
- Age of path information
Encryption
Channel Encryption (AES-256-GCM)
- Key derived from channel name
- Nonce: per-packet, incrementing
- All nodes on same channel can decrypt
Contact Encryption (ECDH + AES-256-GCM)
- Contact pairing establishes shared secret via ECDH
- Per-message encryption with AES-256-GCM
- Forward secrecy through key rotation (if implemented)
Companion Protocol
The companion protocol connects a host application (meshcore-cli, coremebot, meshcore-open) to a MeshCore radio node.
Transport
| Transport | Config |
|---|---|
| Serial | 115200 baud, 8N1 |
| BLE | Nordic UART Service (NUS) |
| TCP | Port varies |
Flow
- Host connects via serial/BLE/TCP
- Node sends LOGIN_SUCCESS or LOGIN_FAILED
- Node streams events (contacts, messages, status)
- Host sends commands (send message, discover nodes, etc.)
- Bidirectional KEEP_ALIVE maintains connection
Event System
Events from meshcore.events.EventType:
- Contact events (add, update, remove)
- Message events (received, sent, failed)
- Status events (battery, telemetry, neighbors)
- Network events (path update, advertisement)
Telemetry (Cayenne LPP)
Sensor data encoded in Cayenne Low Power Payload format.
Status Struct
Periodically reported device status:
| Field | Type | Description |
|---|---|---|
| battery | uint8 | Battery percentage (0-100) |
| tx_queue | uint8 | Pending TX packet count |
| noise_floor | int16 | Channel noise floor (dBm) |
| rssi | int16 | Last received RSSI (dBm) |
| snr | int8 | Last received SNR (dB) |
| direct_count | uint32 | Direct packets sent |
| flood_count | uint32 | Flooded packets sent |
| airtime | uint32 | Total TX airtime (ms) |
| uptime | uint32 | Device uptime (seconds) |
Implementation Notes for MESHTANIC
- Packet codec: Mirror
meshcore.packetsexactly. Byte-for-byte compatibility required. - Companion protocol: Must be wire-compatible with existing nodes so meshcore-cli works unmodified.
- Channel keys: Derivation must match meshcore-cli's algorithm exactly, or channel messages won't decrypt.
- Advertisement format: Must match existing MeshCore nodes or MESHTANIC won't be discoverable.
- Test strategy: Use coremebot as integration test -- if it works with MESHTANIC as it works with Heltec V3, protocol compat is proven.