Skip to content

Base Interoperability Profile

This page defines the minimum default profile that two LowMesh devices SHOULD support to interoperate on the same RF network. Product-specific extensions MAY add payloads and policies beyond this baseline.

See also: Packet layout, Channels & security, Routing, Payloads, Compatibility matrix, Golden test vectors.

Wire status labels

Use these tags consistently across payload and feature pages:

LabelMeaning
Base Profile RequiredMUST be implemented for Base Interoperability Profile interop
Normative OptionalStable wire format; optional for the Base Profile but defined for cross-vendor use when enabled
Design TargetProposed format; not stable for interop — use vendor payloads or promoted alternatives until promoted
Vendor/PrivateAllowed private extension; not cross-vendor interop
InformativeExplanatory or companion integration only; not a mesh wire requirement

See the compatibility matrix for a feature-level summary.

Profile identifier

FieldValue
NameLowMesh Base Interoperability Profile
Header VERSION0b10 in verFlags bits 15–14 — identifies the current mesh header layout (not a separate public API release)

Note: The Base Profile is the wire/interop baseline. Client profiles (Standard, Sensor) are behavior presets on top of the same wire format — not separate protocol versions. See Device roles and profiles.

Roles and client profiles (behavior)

ItemBase profile
RolesClient, Repeater, Gateway
Default Client behaviorStandard Client Profile — Dynamic Repeater Mode ON by default
Optional Client behaviorIoT Client Profile / Sensor ProfileTELEMETRY_BASIC + ACK_BASIC; Dynamic Repeater Mode OFF by default

Identity and addresses

ItemBase profile
Stable identitynodeIdentity64 (8 bytes in NVM; EUI-64-like or provisioning-random) — see Node identity
On-air addressnodeId324-byte LE srcId / dstId in the mesh header
DerivationCanonical: nodeId32 = read_u32_le(SHA256(pkEd)[0..3]). Collisions MUST be detected via NODE_ADVERT; resolve by regenerating the Ed25519 identity, not by picking an arbitrary nodeId32. Provisioned overrides are a separate mode — see Node identity

Cryptography

ItemBase profile
Required MICMIC_MODE = 00AES-256-CCM-4 (4-byte MIC) on the application tail for all channelHash values, including 0x0000
Optional MICMIC_MODE = 01AES-256-CCM-8 (8-byte MIC). Devices that support CCM-8 SHOULD advertise SEC_CAP_CCM8 in NODE_ADVERT / NODE_INFO. Devices that do not support CCM-8 MUST drop MIC_MODE = 01 frames cleanly
Default communitychannelHash == 0x0000 → ROM defaultCommunityPsk32 — encrypted on-air, but not private against other LowMesh devices (globally shared key); use named channels, DMs, or admin for private traffic
Nonce12-byte Base Profile layout — **`srcId
Replay / dupRAM cache keyed by (channelHash, srcId, sessionId, messageId, fragmentWord) — see Routing and Packet layout

There is no cleartext inner payload on 0x0000 in the current specification.

CCM-8 note: CCM-8 is an optional stronger MIC mode for admin, high-security, or product-specific deployments. Normal mesh traffic remains CCM-4 by default for airtime efficiency. CCM-4-only peers cannot decrypt CCM-8; they reject by safe drop.

Routing (hopControl / ttlRaw)

ItemBase profile
Repeater modelStateless dumb-pipe — flood + optional strict on-wire path in the routing block
NoDistance-vector tables, predictive nextHop RAM, or learned mesh routing state
FloodFLOOD flag. Originators MAY omit the routing block. The first relay that forwards such a flood MUST insert the routing block before retransmission
RolesClient, Repeater, Gateway — see Device roles and profiles
Recommended hashSize2 bytes (HASH_SIZE = 01); parsers MUST accept 1–4 bytes per Packet layout
Hop limitPolicy-capped by HASH_SIZE — see Routing
Maximum Mesh PDU255 bytes (SX126x LoRa PHY payload)

Originators MAY omit the routing block when originating a flood. If a relay actually forwards a flood with no routing block, that first forwarding relay MUST insert one (pathCount=1 + local fingerprint, set HAS_ROUTE_BLOCK, decrement hops, verify ≤ 255 bytes) — see Routing on wire.

Required payload types

payloadTypeName
0x01TEXT_UTF8
0x02POSITION_CORE
0x03TELEMETRY_BASIC
0x06ACK_BASIC
0x0ANODE_ADVERT (Base Profile Required); NODE_INFO_* (Normative Optional)

Optional (base profile MAY implement)

payloadTypeName
0x04PAYLOAD_BODY_V2 (chunked files / long blobs)
0x07FRAG_NACK
0x710x75Bulletin board family
0x91 / 0x92Admin command / response
Firmware update envelopesProduct-defined

Security capability bits (capabilities LE)

The capabilities field in NODE_ADVERT / NODE_INFO_* (2 bytes, LE) includes security-related bits:

BitMaskNameMeaning
80x0100SEC_CAP_CCM8Supports MIC_MODE = 01 / AES-256-CCM-8
90x0200SEC_CAP_ADMIN_SIGSupports signed ADMIN_CMD command chains (Ed25519)

Other bits remain as documented per payload (bulletin, IoT ACK, GPS, voice, etc.). Bits 8–9 are normative when set.

Regional / RF

ItemBase profile
USAUS915 FCC-oriented behavior per FCC — USAnot a generic 10% duty-cycle cap
EU / duty-cycle regionsConfigurable regionalDutyCycle* counters — see LoRa parameters

Interop checklist (implementers)

  • [ ] Parse dynamic 16/20-byte base header + optional 5-byte region + 2-byte fragment + variable routing block
  • [ ] Decode MIC_MODE; require CCM-4; optionally CCM-8 when SEC_CAP_CCM8 advertised
  • [ ] AES-CCM decrypt/verify on 0x0000 with defaultCommunityPsk32
  • [ ] Unique CCM nonces per (psk32, nonce); persist sessionId in NVM and change after reboot before messageId reuse
  • [ ] Flood forward with randomized backoff + duplicate cache
  • [ ] Emit ACK_BASIC when ACK_REQ is set (product policy)
  • [ ] Advertise NODE_ADVERT with shortName / longName, nodeId32, and security capability bits when supported

LowMeshOS — always open-source mesh protocol documentation