📡 Bluetooth Mesh — Part 2
ble mesh tutorial – Publish-Subscribe Message Exchange & Replay Attack Protection
Pub-Sub & Messaging
~10 minutes
Beginner–Intermediate
Key Terms in This Post
The Big Picture
In Part 1, we saw how a device is organised internally (nodes → elements → models). Now let us look at how devices communicate in a mesh network. Bluetooth Mesh uses a publish-subscribe model — the same pattern used in MQTT and many IoT systems. Understanding this makes it easy to see why Mesh is so flexible and scalable.
📬 What is Publish-Subscribe?
Imagine a radio station. The station broadcasts (publishes) music on a frequency. Anyone who tunes in (subscribes) to that frequency can hear it. The station does not need to know who is listening.
Bluetooth Mesh works exactly the same way. A node publishes messages to an address. Any node that has subscribed to that address receives and acts on the message.
(Generic OnOff
Client)
group 0xC001
0xC001
subscribers
0x0011
0x0012
0x0013
The switch publishes once → all three subscribed devices receive it
📍 Address Types in Bluetooth Mesh
Bluetooth Mesh has three types of destination addresses. Choosing the right one determines who receives a message.
↩️ Two Kinds of Messages
When a model sends a message, it falls into one of two categories:
🏠 Multiple Subscriptions — The Bedroom Light Example
A node can subscribe to more than one group address. This is very useful for smart home scenarios where one device belongs to multiple logical groups.
all 4 groups
Now the bedside light will respond to any of these commands:
- “Turn off bedside light” → targets 0xC001 → only bedside light responds
- “Turn off bedroom” → targets 0xC002 → all bedroom lights respond
- “Good night” → targets 0xC004 → ALL lights in the house turn off
🔢 Sequence Numbers & Replay Attack Protection
Every message in Bluetooth Mesh is sent from a single unicast address (element address) and includes a unique sequence number. This sequence number increases with every message sent.
| 🚨 Without Sequence Numbers — Replay Attack | What Happens |
|---|---|
| Attacker records: “Unlock door” message | Later replays the same message |
| Door receives the replayed message | 🔓 Door unlocks — security breach! |
| ✅ With Sequence Numbers — Protected | What Happens |
|---|---|
| “Unlock door” message has SEQ = 1042 | Door processes it, stores SEQ = 1042 |
| Attacker replays same message (SEQ = 1042) | 🛡 Door discards it — SEQ already seen! |
💻 BlueZ in Action — Setting Up Publish & Subscribe
Using mesh-cfgclient, you can configure a node to publish and subscribe. Here is how to set up our power strip sockets:
Step 1: Subscribe Socket 1 to a group address
# Subscribe element 0x0001 (Socket 1) to group 0xC001 ("All Sockets")
# Command: sub-add <node_addr> <element_addr> <group_addr> <model_id>
[mesh-cfgclient]# sub-add 0x0001 0x0001 0xC001 0x1306
# Output: Subscription added for model 0x1306 on element 0x0001
Step 2: Configure Socket 1 to publish its status
# Set publish address so Socket 1 reports its state to group 0xC002
# Command: pub-set <node_addr> <element_addr> <pub_addr> <app_key_idx> <ttl> <period> <count> <model_id>
[mesh-cfgclient]# pub-set 0x0001 0x0001 0xC002 1 5 0 0 0x1306
# Now element 0x0001 will publish power level status to 0xC002
Step 3: Also subscribe Socket 1 to the “Whole House” group
# A node can have multiple subscriptions on the same element/model
[mesh-cfgclient]# sub-add 0x0001 0x0001 0xC010 0x1306
# Socket 1 now responds to messages sent to 0xC001 OR 0xC010
Step 4: Send a power level message to all sockets (group 0xC001)
# Set destination to group address
[mesh-cfgclient]# dst 0xC001
# Send Generic OnOff Set — turn all sockets OFF
# Both Socket 1 (0x0001) and Socket 2 (0x0002) will respond
# because both are subscribed to 0xC001
[mesh-cfgclient]# onoff-set 0 0x01
# Output:
# Generic OnOff Set sent to 0xC001
# Received OnOff Status from 0x0001: state=OFF
# Received OnOff Status from 0x0002: state=OFF
📝 Quick Summary
| Concept | Description |
|---|---|
| Publish Address | Where a model sends its unsolicited messages. One per model instance. |
| Subscription List | Group addresses a model listens to. Can have multiple entries. |
| Group Address | One message → many devices. Like a WhatsApp broadcast. |
| Sequence Number | Unique counter per message. Prevents replay attacks. |
| Reply Message | Response to a request. Sent to the requester’s unicast address. |
| Unsolicited Message | Sent on model’s own initiative. Sent to model’s publish address. |
Continue Learning Bluetooth Mesh
Next: How every message in the mesh is encrypted and authenticated using three types of keys
