BLE Mesh DFU Configuration Tool

Configure and validate settings for Distributor, Friend, and LPN nodes

📡

Distributor

Gateway/Client sending firmware

TX_SEG_MAX ? Maximum segments distributor can send in one message. Controls max outgoing message size: (TX_SEG_MAX × 12) - 4 bytes.
1 32
RX_SEG_MAX AUTO Automatically kept equal to LPN TX_SEG_MAX.
1 32
TX_SEG_MSG_COUNT AUTO Automatically scaled to match number of concurrent LPNs.
1 20
RX_SEG_MSG_COUNT ? Number of simultaneous incoming segmented messages. Should match number of targets sending responses.
1 20
🤝

Friend Node

Relay buffering messages for LPNs

DESIRED_CHUNKS_PER_REQUEST ? Target number of chunks LPN should request per Block Report. Lower values = less memory, more round trips. Higher values = more memory, fewer round trips. Recommended: 4-8 chunks.
2 (min memory) 12 (max throughput)
FRIEND_QUEUE_SIZE AUTO Automatically calculated based on chunk size and desired chunks per request. Formula: chunks × segments_per_chunk × 1.15 (15% safety margin).
8 512
TX_SEG_MAX AUTO Automatically kept equal to Distributor TX_SEG_MAX.
1 32
RX_SEG_MAX AUTO Automatically kept equal to Distributor TX_SEG_MAX.
1 32
TX_SEG_MSG_COUNT AUTO Automatically scaled to match number of concurrent LPNs.
1 LPN 10 LPNs
RX_SEG_MSG_COUNT AUTO Automatically scaled to LPN count + 1 (capped at 10).
1 10
🔋

LPN Target

Low Power Node receiving firmware

RX_SEG_MAX AUTO Automatically kept equal to Distributor TX_SEG_MAX.
1 32
TX_SEG_MAX ? For sending responses and Block Reports. Usually smaller than RX since LPN mostly receives.
1 32
BLOB_REPORT_TIMEOUT ? Time (seconds) LPN waits before reporting missing chunks. Balance between quick recovery and battery life.
1s 31s
TX_SEG_MSG_COUNT ? LPNs typically only send to one distributor, so 1 is usually sufficient.
1 5
RX_SEG_MSG_COUNT ? LPNs typically receive from one distributor, so 1 is usually sufficient.
1 5
Number of Concurrent LPNs ? Specify how many Low Power Nodes will be updated concurrently in your network. This automatically scales Friend queue size and MSG_COUNT parameters to handle multiple targets.
LPN_COUNT
1 10
⏱️ DFU Duration Estimator (Unicast Mode)
256.0 KB
Quick presets:
⚠️ Important: These are estimates only

Actual DFU times can vary significantly based on:

  • RF environment: Interference, noise floor, multi-path fading
  • Network topology: Number of hops, relay congestion, mesh density
  • Device capabilities: Processing speed, flash write performance, RTOS scheduling
  • Network conditions: Retransmissions, packet loss rate, collision avoidance delays
  • Concurrent traffic: Other mesh activity during DFU operation
  • Power conditions: Battery voltage affecting TX power and processing speed

For accurate planning, validate estimates with actual measurements in your deployment environment. A 30% overhead factor is included, but real-world variance may be ±20-30%.

🧮 Real-time Calculations
Negotiated Chunk Size
68bytes
Segments Per Chunk
7segments
Max Chunks Per Request
4chunks
Queue Utilization
87%
Max Message Size (TX)
68bytes
Max Message Size (RX)
68bytes
Friend LPN Capacity
2LPNs
Friend Total Memory
3.5KB
Block Size
4096bytes
Chunks Per Block
60chunks
Total Blocks
64blocks
Total Chunks
3840chunks
Effective LPN Poll Rate
28.0seconds
💡 Smart Recommendations
📚 DFU Duration Calculation Methodology

Overview

This tool calculates BLE Mesh DFU duration based on Zephyr RTOS source code analysis. The calculation models the actual LPN polling behavior, Friend queue management, and segment-level data transfer.

Step 1: Calculate Negotiated Chunk Size

Formula: chunkSize = MIN(all RX_SEG_MAX) × 12 - 7

  • Takes the smallest RX_SEG_MAX among Distributor, Friend, and LPN
  • Each BLE Mesh segment carries 12 bytes of application payload
  • Subtracts 7 bytes for BLOB chunk overhead (1-byte opcode + 2-byte chunk index + 4-byte MIC)

Step 2: Calculate Segments Per Chunk

Formula: segmentsPerChunk = ⌈(7 + chunkSize) / 12⌉

  • Includes the 7-byte overhead in the total chunk SDU length
  • Divides by 12 bytes per segment and rounds up

Step 3: Calculate Max Chunks Per Block Report

Formula: maxChunks = MIN(DESIRED_CHUNKS_PER_REQUEST, ⌊Friend Queue Size / segmentsPerChunk⌋)

  • Limited by both user's desired chunks per request AND Friend node's queue capacity
  • LPN cannot request more chunks than Friend can buffer
  • Actual Zephyr implementation also caps at CONFIG_BT_MESH_BLOB_SRV_PULL_REQ_COUNT (default: 4)
  • This tool uses DESIRED_CHUNKS_PER_REQUEST as the effective limit

Step 4: Calculate Effective Poll Timeout

Important: During active DFU operations, Zephyr caps the LPN poll timeout at 1 second regardless of CONFIG_BT_MESH_LPN_POLL_TIMEOUT.

Formula: effectivePollTimeout = min(POLL_TIMEOUT_MAX, 1000ms)

  • For DFU duration estimation, this tool uses fixed default values:
    • LPN_POLL_TIMEOUT = 80 (8 seconds)
    • LPN_RECV_DELAY = 100ms
  • These defaults result in POLL_TIMEOUT_MAX ≈ 5.9 seconds
  • During active DFU, the effective poll timeout is capped at 1000ms
  • Source: zephyr/subsys/bluetooth/mesh/lpn.c:122 - if (bt_mesh_tx_in_progress()) return MIN(POLL_TIMEOUT_MAX, 1000)

Step 5: Calculate Time Per Block Report Cycle

Formula: 100ms + effectivePollTimeout + (totalSegments × 200ms) + BLOB_TIMEOUT

Based on packet capture analysis, each Block Report cycle consists of these phases:

Phase 1: Immediate Poll After Block Report

Time: ~100ms

  • LPN sends unsegmented Block Report (9 bytes for 4 chunks)
  • LPN immediately polls Friend via bt_mesh_lpn_poll()
  • Friend responds with "no data" (chunks not ready yet)
  • Source: zephyr/subsys/bluetooth/mesh/blob_srv.c:205

Phase 2: Wait for Chunks

Time: 1000ms (capped during active DFU)

  • LPN waits 1 second before next poll (Zephyr caps poll timeout during active transmission)
  • During this wait: Distributor sends chunks to Friend (5-6 seconds for 4 chunks)
  • Friend receives all segments and queues them
  • When LPN polls again, Friend has data ready

Phase 3: Segment Reception (Friend → LPN)

Time: totalSegments × 200ms

  • Total Segments: maxChunks × segmentsPerChunk
  • Friend sends ONE segment per poll with md=1 flag
  • Each segment delivery cycle: poll → segment → next poll = ~200ms (measured)
  • NOT 100ms as initially modeled - packet capture shows actual timing is 200ms
  • Continues until all segments delivered (md=0)

Phase 4: BLOB Report Timeout

Time: BLOB_REPORT_TIMEOUT (default: 10s)

  • After receiving last segment, LPN waits before sending next Block Report
  • Timer is reset on every completed chunk
  • If timeout expires with missing chunks, LPN sends report listing missing chunks
  • Source: zephyr/subsys/bluetooth/mesh/blob_srv.c:802

Step 6: Calculate Total DFU Time

Formula:

  • Block Reports Needed: ⌈totalChunks / maxChunks⌉
  • Single LPN Time: blockReportsNeeded × blockReportCycleMs × 1.15
  • Multiple LPNs: singleLpnTime × numTargets (sequential unicast)
  • 15% Overhead: Accounts for retransmissions, network collisions, timing variations, and protocol overhead

Example Calculation (Default Values)

Configuration:
- Firmware: 262144 bytes (256 KB)
- Queue Size: 46 segments
- RX_SEG_MAX: 10 (all nodes)
- DESIRED_CHUNKS_PER_REQUEST: 4
- BLOB_REPORT_TIMEOUT: 10s

Fixed Defaults (not user-configurable in UI):
- LPN_POLL_TIMEOUT: 300 (30 seconds)
- LPN_RECV_DELAY: 100ms
- FRIEND_RECV_WIN: 255ms

Calculated:
- Chunk size: 113 bytes
- Segments per chunk: 10
- Max chunks (from queue): 4 (46 / 10 = 4.6)
- Max chunks (actual): MIN(4 desired, 4 from queue) = 4
- Total segments per report: 40
- POLL_TIMEOUT_MAX: ~5.9s (from defaults)
- Effective poll timeout during DFU: 1.0s (capped)
- Total chunks needed: 2320
- Block reports needed: 580

Time per Block Report (packet capture based):
- Immediate poll: 0.1s
- Wait for chunks: 1.0s (Zephyr DFU cap)
- Segment reception: 8.0s (40 × 0.2s)
- BLOB timeout: 10.0s
- Total: 19.1s

Total DFU Time (1 LPN):
580 × 19.1s × 1.30 = 14,393s = 03:59:53

Important Notes

  • Calculation is based on Zephyr RTOS 3.x implementation and validated against packet capture analysis
  • LPN poll timeout during DFU: Zephyr automatically caps poll timeout at 1 second during active transmissions, regardless of CONFIG_BT_MESH_LPN_POLL_TIMEOUT setting
  • Segment delivery timing (200ms): Measured from actual packet captures, not theoretical estimates
  • Assumes unicast DFU mode (targets updated sequentially)
  • Actual times may vary based on RF environment, interference, network topology, and retransmissions
  • The 30% overhead is an engineering estimate - real-world overhead may differ
  • For best accuracy, validate with actual DFU measurements in your deployment environment
  • Non-configurable parameters: LPN_POLL_TIMEOUT and LPN_RECV_DELAY use fixed defaults (80/100ms) for DFU estimation as they have minimal impact on actual DFU duration