Bluetooth Mesh Segmentation: Bound Retransmission Cost for Large Access Messages

Budget a large Mesh Access message in segments, retransmission opportunities and retained buffers before increasing the payload limit. One missing segment can keep a transaction alive while other traffic competes for the same transport resources.

Applicability: historical Bluetooth Mesh Protocol 1.1 lower-transport segmentation and Zephyr 4.2.0 transport/Kconfig sources. The worked case is an Access message to a unicast destination, without a Friend acting on behalf of the receiver. Multicast and friendship differences are identified separately. All counts and loss cases are hypothetical; no radio or transport test was run.

A 34-octet Upper Transport PDU splits into 12, 12 and 10 octets; bitmap five identifies the missing middle segment and bitmap seven completes it.
Original hypothetical unicast loss fixture. Four source segment submissions exclude acknowledgments, network repetitions and relay copies; no transport or RF test was run.

1. Count the Upper Transport bytes correctly

The segmented Access format divides the Upper Transport Access PDU into twelve-octet segments, except that the last can be shorter. The Upper Transport PDU includes encrypted Access content and its TransMIC. Do not count only the application’s parameter bytes.

For a hypothetical Access PDU of 30 octets, including opcode and parameters, plus a four-octet TransMIC, the Upper Transport length is 34 octets. It needs three segments: 12, 12 and 10 octets. SegO values are zero, one and two; SegN is two, not three.

With an eight-octet TransMIC, the same Access length becomes 38 octets and needs four segments: 12, 12, 12 and 2. This boundary change is arithmetic, not a reason to weaken the required authentication format.

Control messages use a different segment payload size. Keep this Access calculation scoped rather than applying twelve octets to every lower-transport message.

2. Use partial acknowledgments instead of whole-message guessing

For unicast segmented delivery, the lower transport tracks acknowledged segments and retransmits missing ones under its configured retry rules. Segments belong to the same transaction through SeqAuth-related state; a fresh application resend is a separate operation, not automatically another segment retry.

In the three-segment example, suppose segments zero and two arrive while segment one is lost. A matching acknowledgment bitmap of 0x00000005 marks bits zero and two. With retry budget available, the sender needs segment one; after complete reception, the bitmap is 0x00000007.

This particular path uses four source segment submissions: three initial segments and one missing-segment resend. It excludes acknowledgments, Network Transmit repetitions, relay copies and application retries. It is not a count of captured advertising packets or an airtime estimate.

A matching zero acknowledgment bitmap has cancellation semantics. It must not be interpreted as an ordinary request to retry every segment forever. The Zephyr trans_ack implementation completes that matching transmission with a cancellation result.

3. Bound retry policy at each layer

Mesh 1.1 has SAR unicast retransmission and no-progress budgets, with separate timing controls. A new acknowledgment can advance progress; repeated absence of progress cannot consume unlimited retries. Capture the effective configuration rather than assuming defaults from another release.

Keep SAR repetition separate from the originating node’s Network Transmit state and relays’ Relay Retransmit state. Each retransmitted segment can create additional lower-layer traffic. Multiplying an assumed loss percentage by payload bytes does not model that layered cost.

For group and virtual destinations, receivers do not send Segment Acknowledgment messages. The sender follows multicast retransmission behavior. Completion after the configured transmissions does not prove that every group member reassembled the message.

The exact Zephyr transmit path returns timeout when a unicast retry budget is exhausted, while completing multicast transmission after its attempts is expected behavior. Label those results differently in product telemetry.

Do not launch an unlimited application retry on every transport failure. Use a bounded application policy with a stable operation identity where duplicate execution matters, and preserve whether the previous outcome is known or uncertain.

4. Budget contexts and buffers independently

Zephyr 4.2.0 Kconfig exposes TX/RX segment-message counts, TX/RX maximum segment counts and BT_MESH_SEG_BUFS. These limit different things: simultaneous contexts, size of one message and the shared segment-buffer pool.

Raising the maximum message size does not create more contexts or enlarge every competing buffer pool. Two incomplete receives and one outgoing message can contend even if each message individually fits its configured maximum.

The tagged Kconfig help says incoming transactions allocate all segments at the start. The exact transport.c receive path instead allocates rx->seg[seg_o] as each accepted segment is processed. Use that implementation behavior when diagnosing allocation timing; do not treat the help text as a reservation guarantee.

Plan enough shared capacity for the qualified overlapping workload, including incomplete transactions and outgoing data. Account separately for context structures, timers, advertising buffers and application storage. Twelve-byte segment blocks are not the entire RAM cost.

Inspect the precise failure reason. The tagged receive path distinguishes a too-large SDU, no free receive context and inability to allocate a segment buffer. Collapsing them all into “poor RF” hides a local resource fault.

5. Keep reassembly completion below application completion

Only a complete reassembled Upper Transport PDU progresses to the upper transport layer. Authentication, access dispatch and application acceptance remain later boundaries. A successful segment acknowledgment does not certify a durable setting change or completed actuator command.

If a Friend acknowledges on behalf of a low-power destination, it establishes reception by the Friend, not delivery to the sleeping application. Use the separate friendship queue contract when that topology applies; the direct-receiver fixture here deliberately excludes it.

Keep operation timing from submission through transport result and application response. A long reassembly lifetime can consume resources without ever producing useful work. Expired or canceled contexts must release their retained buffers through the stack’s cleanup path.

6. Test missing segments and competing transactions

  • Replay the three-segment fixture with only segment one missing: verify partial acknowledgment and targeted retry.
  • Deliver duplicate and out-of-order segments: verify one reconstructed message, without treating arrival order as payload order.
  • Lose the final acknowledgment: verify bounded retry and no duplicate application action.
  • Inject a matching cancellation acknowledgment: verify a distinct canceled result.
  • Start enough incomplete receives to exhaust contexts, then separately exhaust the shared buffer pool: preserve different diagnostics.
  • Use a payload just beyond the receiver’s configured segment limit: verify explicit rejection and cleanup.
  • Run the same logical payload to a group: verify that send completion is not reported as per-member delivery.

Acceptance requires bounded outstanding work, correct bitmap handling, reclaimed resources and an application-level result where needed. Publish the supported payload/concurrency envelope with actual configuration and later measurements, rather than turning a protocol maximum into a delivery promise.

Similar Posts