Bluetooth Mesh programming : Addressing & Network PDU

Bluetooth Mesh programming : Addressing & Network PDU

How nodes find each other and what a mesh packet actually looks like under the hood

4
Address Types
9
PDU Fields
127
Max TTL Hops
64b
Max NetMIC

Why Does Addressing Matter in a Mesh Network?

In a Bluetooth Mesh network, a single light switch might need to control one specific bulb, every bulb on a floor, or every bulb in the whole building — all using the same radio protocol. To support all these scenarios cleanly, Bluetooth Mesh defines a flexible addressing model with four distinct address types.

Once a message is addressed, it gets wrapped in a Network PDU — a carefully structured packet that carries the payload, routing info, and cryptographic protection all in one. This tutorial walks through both topics step by step.

Topics Covered

Virtual Address Label UUID Group Address Fixed Group Addresses Address Validity Rules Network PDU IVI / NID / CTL / TTL NetMIC Sequence Number

1. Virtual Addresses — The “PO Box” of Bluetooth Mesh

The Problem Virtual Addresses Solve

Imagine two devices that want to exchange private messages without registering anything in a central provisioning database. They agree on a shared secret label (a 128-bit UUID) out-of-band, but broadcasting that full 128-bit UUID as a destination address every time would be wasteful and expose too much information.

Virtual addresses solve this elegantly: a compact 14-bit hash is derived from the 128-bit Label UUID and packed into a 16-bit virtual address. Any device that knows the Label UUID can derive the same hash and recognise messages meant for it.

SALT  = s1(“vtad”)
hash  = AES-CMACSALT(Label UUID) mod 214

The result is a 14-bit value embedded into the lower 14 bits of the virtual address. Because the hash is only 14 bits, multiple different Label UUIDs can produce the same hash — a deliberate design that provides privacy. On receiving a matching virtual address, the upper transport layer checks each candidate Label UUID in full until a genuine match is confirmed via cryptographic authentication.

Virtual Address — 16-bit Bit Layout

The bit pattern is always 1 0 in the two most significant bits, followed by the 14-bit hash. This pattern uniquely distinguishes virtual addresses from all other address types.

1 0 Hash (14 bits)
bit 15 bit 14 bits 13 → 0
Valid range: 0x8000 – 0xBFFF
⚠️ Remember: Only Access messages can use virtual addresses. Control messages must use unicast or group addresses.

2. Group Addresses — Send One, Reach Many

How Group Addressing Works

A group address is a destination that zero or more elements can subscribe to. When a message is sent to a group address, every element in the mesh that has registered a subscription to that group receives and processes it — just like joining a mailing list.

Group addresses are identified by having both bit 15 and bit 14 set to 1. There are two flavours: dynamically assigned addresses (configured by a provisioner, range 0xC000–0xFEFF) and fixed addresses (pre-defined in the spec, range 0xFF00–0xFFFF).

Group Address — 16-bit Bit Layout

1 1 Group Address (14 bits)
bit 15 bit 14 bits 13 → 0
Dynamic range: 0xC000 – 0xFEFF  |  Fixed range: 0xFF00 – 0xFFFF
Fixed Group Addresses — Built-in Network-Wide Destinations

The top of the group address space holds four special fixed addresses. They let a provisioner or controller reach every node of a specific feature type without knowing individual unicast addresses — extremely handy for large deployments.

Address Name Who processes the message?
0xFF00–0xFFFB RFU Reserved — not yet defined
0xFFFC all-proxies Primary element of every node with Proxy feature enabled
0xFFFD all-friends Primary element of every node with Friend feature enabled
0xFFFE all-relays Primary element of every node with Relay feature enabled
0xFFFF all-nodes Primary element of every node in the network, unconditionally

A real-world use case: if you want to broadcast a new TTL default to every relay node in a building, send a configuration message to 0xFFFE. No address book needed.

3. Address Validity — Which Address Works Where?

Source vs Destination Rules

Not every address type is allowed in every field of a Network PDU. The key rule is simple: a node always identifies itself with a unicast address — there’s no anonymous or multi-cast source. Destinations are more flexible depending on message type.

Address Type Source (SRC) Dest: Control Msg Dest: Access Msg
Unassigned
Unicast
Virtual
Group

There is also a separate rule about which address types can be used with which key type:

  • Device key — only unicast destinations. Used for direct node-to-node configuration traffic.
  • Application key — unicast, virtual, or group. Used for all normal application-level messaging.

This makes security sense: device keys are for provisioning and per-node configuration — there’s no reason to multicast those with a device key.

4. The Network PDU — Anatomy of a Mesh Packet

Every message traveling through a Bluetooth Mesh network is carried inside a Network PDU. This is the packet format at the network layer — it wraps the transport payload with routing info, a sequence number, and a cryptographic integrity check. The whole PDU is protected by keys derived from the network key, identified by the NID field.

Two things are worth understanding before diving into individual fields: some bytes are obfuscated (scrambled for privacy but not fully encrypted), while others are fully encrypted. The diagram below shows this split.

Network PDU — Visual Field Map

←————— Obfuscated (Privacy Protected) —————→

IVI
1 bit
NID
7 bits
CTL
1 bit
TTL
7 bits
SEQ
24 bits
SRC
16 bits

←——————————— Encrypted ———————————→

DST
16 bits
TransportPDU
8 – 128 bits
NetMIC
32 or 64 bits

IVI / NID — obfuscated header CTL / TTL — obfuscated routing SEQ / SRC — obfuscated identity DST / Transport — encrypted payload NetMIC — integrity tag

Field-by-Field Explanation

IVI — IV Index Bit (1 bit)

The IV Index is a 32-bit security counter that the entire mesh network increments periodically to prevent sequence number exhaustion. Embedding the full 32 bits in every packet would be wasteful, so only the least significant bit travels in this field. The receiver uses this bit to quickly determine which IV Index the sender used during encryption, then verifies with the full value during decryption.

NID — Network Identifier (7 bits)

Think of the NID as a compact key-ring index. A receiving node may have multiple network keys for different subnets. Instead of trying every key, it uses the 7-bit NID to quickly narrow down which Encryption Key and Privacy Key to apply. Importantly, the NID is derived differently for standard mesh traffic versus Friend-to-LPN (Low Power Node) private messages, keeping those conversations isolated even on the same network.

CTL — Control Flag (1 bit)

A single bit that answers the question: “Is this packet carrying application data or network management instructions?” It also directly controls the size of the NetMIC integrity check.

CTL Message Type NetMIC Size
0 Access Message (sensor readings, light commands, etc.) 32 bits
1 Control Message (relay/friend/heartbeat operations) 64 bits

Control messages get a larger 64-bit MIC because tampering with network management traffic (like friend subscriptions or IV index updates) could destabilise the whole network. The extra 32 bits of MIC make forgery exponentially harder.

TTL — Time To Live (7 bits)

TTL limits how far a message propagates through the mesh by counting relay hops. Each relay node decrements TTL by 1 before re-transmitting. When the count hits 1, the message is delivered but not forwarded further.

Value What it means in practice
0 No relay, ever. The receiver knows the sender is exactly one radio hop away — great for proximity-aware logic.
1 Delivered at next hop but not relayed onward. The message has reached its final relay step.
2–126 Normal operational range — message may have already been relayed and can still be relayed further. Most applications start here.
127 Maximum TTL — packet is fresh off the originator and can travel up to 126 relay hops before stopping.
💡 Practical tip: Setting TTL = 0 on transmitted messages is a simple way to implement single-hop-range detection. If a node receives your message with TTL still at 0, you’re neighbours.

SEQ — Sequence Number (24 bits)

Every element in a mesh network maintains a monotonically increasing 24-bit counter. Each message it originates gets the next value. The SEQ is critical for two things: it feeds into the encryption nonce (making each encrypted packet unique), and it defends against replay attacks — a node that has already processed SEQ 1000 from a given source will reject any later packet with SEQ ≤ 1000 from that same source.

SRC — Source Address (16 bits)

Always the unicast address of the element that originated the message. Combined with SEQ and IVI, it forms the complete nonce used to encrypt the payload. There is no anonymous transmission at the mesh network layer.

DST — Destination Address (16 bits)

The intended recipient — unicast, virtual, or group. Because DST is part of the encrypted payload, relay nodes cannot read it without the network key. This provides a meaningful level of destination privacy against passive listeners who don’t have the key.

TransportPDU (8–128 bits)

The payload handed down from the Transport layer. This could be a segmented or unsegmented access message (sensor data, a light command) or a control message (a heartbeat, a friend request acknowledgment). It is fully encrypted alongside DST.

NetMIC — Network Message Integrity Check (32 or 64 bits)

The cryptographic authentication tag appended to the encrypted portion of the PDU. Any tampering with DST or TransportPDU will cause the MIC verification to fail, and the packet will be silently discarded. Size is determined by CTL: 32 bits for access messages, 64 bits for control messages.

Quick Reference Summary

Address Type Cheat Sheet
Type Bit Pattern Range Use Case
Unassigned 0x0000 0x0000 Not yet configured — invalid in messages
Unicast 0b0xxxxxxx xxxxxxxx 0x0001–0x7FFF One specific element; source & destination
Virtual 0b10xxxxxx xxxxxxxx 0x8000–0xBFFF Private group via Label UUID hash; access messages only
Group 0b11xxxxxx xxxxxxxx 0xC000–0xFFFF Subscription-based multicast; fixed all-* aliases at top

Key Takeaways

Virtual addr = 14-bit hash of Label UUID Group addr = subscription-based multicast all-nodes = 0xFFFF all-relays = 0xFFFE Source must always be unicast Virtual addr → Access messages only CTL=0 → Access | CTL=1 → Control TTL=0 means single radio hop DST + TransportPDU are fully encrypted NetMIC: 32b access, 64b control SEQ prevents replay attacks NID = key-ring lookup index

Continue Your Bluetooth Mesh Journey

This post covered the mesh addressing system and the Network PDU format. Next up: how the Transport layer handles segmentation, reassembly, and friend queuing for Low Power Nodes.

Leave a Reply

Your email address will not be published. Required fields are marked *