Skip to content

Protocol

sputlab edited this page Nov 13, 2026 · 1 revision

Protocol

The authoritative definitions are in app/src/main/java/com/nodewave/mesh/protocol/Packet.kt and the neighbouring files. This page summarises them (wire format v4).

Packet header (24 bytes, big-endian)

[version u8][type u8][ttl u8][hops u8][senderId 8B][destId 8B][messageId i32][payload ...]
  • senderId is the original author and never changes while relayed.
  • ttl (default 5) is decremented and hops incremented by each relay, so they are not authenticated.
  • (senderId, messageId) identifies a packet network-wide (dedupe key).
  • Every other header field is bound into the AES-GCM tag as AAD.

Packet types

Code Type Content
1 MESSAGE sealed chat text (max 180 bytes of text)
2 PING sealed ping text
3 ACK sealed message id being acknowledged
4 HELLO one-hop neighbour announcement, sealed, never forwarded
5 KEY signed ephemeral key exchange (handshake), routed like a message
6 GROUP group message, invitation, member update or leave, sealed
7 POSITION sealed position (lat, lon, accuracy, time: 14 bytes)
8 DATA one sealed chunk of a bulk transfer (voice clip, photo)
9 DATA_ACK receiver's sealed bitmap of chunks held
10 DATA_REFUSE relay tells the author it cannot forward a transfer (unauthenticated)
11 LINK sealed fast-link (Wi-Fi Direct) negotiation

Sealed payload

payload = sid(4) | nonce(12) | ciphertext | tag(16), with a fresh random nonce per message. AAD: version, type, senderId, destId, messageId plus the session id. See Security.

Node identity

Node ID = first 8 bytes of SHA-256 of the P-256 identity public key, shown as 16 lowercase hex characters (the UI groups them by four).

Routing and HELLO

  • Each node announces its neighbours in a sealed HELLO (every ~60 s plus jitter, and shortly after a change). HELLOs carry an increasing sequence number against replay.
  • RoutingTable learns routes from neighbours' HELLOs; a route expires after 150 s.
  • Router chooses: direct link, else known route, else flood. A node already seen is not forwarded again (seen-cache, 1024 entries).

Reliability

  • A message awaiting an ACK is resent after 10 s, at most 2 times.
  • ACKs are sent twice with a short delay.
  • A handshake KEY is attempted 3 times with a 5 s timeout, rate limited in the background.
  • A reply is sent back on the link the request arrived on when possible.

Bulk transfers (voice, photos)

  • A transfer is cut into DATA chunks sized for the slowest link class on the path: SLOW 240 B, MEDIUM (BLE) 244 B, FAST (Wi-Fi Direct) 1400 B.
  • The receiver periodically returns a sealed DATA_ACK bitmap; the sender resends the missing chunks. A chunk whose send fails is retried at once (3 times, growing pause); the transfer gives up after six passes without progress.
  • The link class byte is sealed with the chunk. A relay refuses a transfer its next link cannot carry (DATA_REFUSE).
  • The receiver caps the number, size and age of transfers it assembles (TransferAssembler).

Fast link negotiation

  1. Bluetooth finds the peer; a big transfer asks for a fast link.
  2. One phone creates a Wi-Fi Direct group (random name DIRECT-NW-xxxx and passphrase) and sends the sealed offer (name, passphrase, port) in a LINK packet.
  3. The receiver, if its who may start a link setting allows the sender, joins and connects over TCP.
  4. The TCP stream carries the same sealed packets as any radio. The link class becomes FAST.
  5. It closes after 40 s without traffic.

Contact QR

nodewave://c/1/<public key>/<name>: the full P-256 public key and the display name.

Clone this wiki locally