Sequence number is not properly updated when broadcasting segmented VendorModelMessageAcked messages.
See original GitHub issueDescribe the bug
When broadcasting a segmented VendorModelMessageAcked, NetworkLayer’s sequence number seems to be incremented only once per message, rather than once per segment, causing the firmware to discard subsequent messages.
Let’s start with the OK case:
Here’s an example of a VendorModelMessageAcked that’s transmitted in three segments. The message was sent to a single node twice in a row, and the following was logged:
V/MeshTransport: Src address: 0001
V/MeshTransport: Dst address: 0002
...
V/MeshTransport: Sequence number: 10
V/MeshTransport: Access message opcode: 3
V/MeshTransport: Access message parameters: 04110101220202330303440404414243444546474800
V/AccessLayer: Created Access PDU C3123404110101220202330303440404414243444546474800
V/UpperTransportLayer: Application nonce: 010000000A0001000200000000
V/UpperTransportLayer: Encrypted upper transport pdu: 09FFF90E242966A8FE2544C976E15A5AEB765BBFA1313BC79D0BF607CD
V/LowerTransportLayer: Segmented Lower transport access PDU: D900280209FFF90E242966A8FE2544C9 0 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: D900282276E15A5AEB765BBFA1313BC7 1 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: D90028429D0BF607CD 2 of 3
...
V/NetworkLayer: Sequence Number: 00000A
V/NetworkLayer: Encrypted Network payload: 17EFFF4AD3E23CE2FDF98B1CAAAB2FB29D26E09E0AF6
V/NetworkLayer: Sequence Number: 00000B
V/NetworkLayer: Encrypted Network payload: 82FF850037EA33E3B0E908B10FD243C75AB69133F62A
V/NetworkLayer: Sequence Number: 00000C
V/NetworkLayer: Encrypted Network payload: 83210847FB2EACEF08029906E3A76A
V/VendorModelMessageAckedState: Sending acknowledged vendor model message
/*
* Message is sent a second time:
*/
V/MeshTransport: Src address: 0001
V/MeshTransport: Dst address: 0002
...
V/MeshTransport: Sequence number: 13
V/MeshTransport: Access message opcode: 3
V/MeshTransport: Access message parameters: 04110101220202330303440404414243444546474800
V/AccessLayer: Created Access PDU C3123404110101220202330303440404414243444546474800
V/UpperTransportLayer: Application nonce: 010000000D0001000200000000
V/UpperTransportLayer: Encrypted upper transport pdu: 5C17C41C7E50D80BEAB0DC93E45F1B0F9BCA8365028C7110FC92F92460
V/LowerTransportLayer: Segmented Lower transport access PDU: D90034025C17C41C7E50D80BEAB0DC93 0 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: D9003422E45F1B0F9BCA8365028C7110 1 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: D9003442FC92F92460 2 of 3
...
V/NetworkLayer: Sequence Number: 00000D
V/NetworkLayer: Encrypted Network payload: C3CD33738C97E1FD8A5DB555C145012FAFC197BCA2D3
V/NetworkLayer: Sequence Number: 00000E
V/NetworkLayer: Encrypted Network payload: E4D0A55B45E85DBD68BAC9DB758E680DE97CBAD1D191
V/NetworkLayer: Sequence Number: 00000F
V/NetworkLayer: Encrypted Network payload: 9739202BD93CD1A8FBA57D79A5D1F7
V/VendorModelMessageAckedState: Sending acknowledged vendor model message
Please note that the NetworkLayer’s sequence number was incremented as expected from 0x0a to 0x0c and from 0x0d to 0x0f. So far, everything is all right.
When broadcasting the same message twice in a row, it’s getting interesting:
V/MeshTransport: Src address: 0001
V/MeshTransport: Dst address: FFFF
...
V/MeshTransport: Sequence number: 10
V/MeshTransport: Access message opcode: 3
V/MeshTransport: Access message parameters: 04110101220202330303440404414243444546474800
V/AccessLayer: Created Access PDU C3123404110101220202330303440404414243444546474800
V/UpperTransportLayer: Application nonce: 010000000A0001FFFF00000000
V/UpperTransportLayer: Encrypted upper transport pdu: 000ECE8DFE0500E5030002787274D7D049AB314CEBA274B9B95D127AC4
V/LowerTransportLayer: Segmented Lower transport access PDU: E9002802000ECE8DFE0500E503000278 0 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: E90028227274D7D049AB314CEBA274B9 1 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: E9002842B95D127AC4 2 of 3
...
V/NetworkLayer: Sequence Number: 00000A
V/NetworkLayer: Encrypted Network payload: CC930017BC1E28A454CA2BAE679F8E9BC0F9719DF2C1
V/NetworkLayer: Sequence Number: 00000B
V/NetworkLayer: Encrypted Network payload: B7617BFD317347A4AB38E1B1DBE535EDFD01245135FE
V/NetworkLayer: Sequence Number: 00000C
V/NetworkLayer: Encrypted Network payload: E960C6C08463A3EFD7C1EB5E25547F
V/VendorModelMessageAckedState: Sending acknowledged vendor model message
/*
* Message is sent a second time:
*/
V/MeshTransport: Src address: 0001
V/MeshTransport: Dst address: FFFF
...
V/MeshTransport: Sequence number: 11
V/MeshTransport: Access message opcode: 3
V/MeshTransport: Access message parameters: 04110101220202330303440404414243444546474800
V/AccessLayer: Created Access PDU C3123404110101220202330303440404414243444546474800
V/UpperTransportLayer: Application nonce: 010000000B0001FFFF00000000
V/UpperTransportLayer: Encrypted upper transport pdu: 7962F8A29FA7928C8B734B8FE7693169231E3CB198965D2540CEB9FA48
V/LowerTransportLayer: Segmented Lower transport access PDU: E9002C027962F8A29FA7928C8B734B8F 0 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: E9002C22E7693169231E3CB198965D25 1 of 3
V/LowerTransportLayer: Segmented Lower transport access PDU: E9002C4240CEB9FA48 2 of 3
...
V/NetworkLayer: Sequence Number: 00000B
V/NetworkLayer: Encrypted Network payload: B7617BFD35534CB2844A37BD7825553CC2378A087E65
V/NetworkLayer: Sequence Number: 00000C
V/NetworkLayer: Encrypted Network payload: E960C6C08003FDDBF4D20C86AB76D27D0EDD96A6026D
V/NetworkLayer: Sequence Number: 00000D
V/NetworkLayer: Encrypted Network payload: 617082EE3F663FD9261BD2268F2671
V/VendorModelMessageAckedState: Sending acknowledged vendor model message
What’s interesting when broadcasting is that the sequence numbers of the first and second VendorModelMessageAcked messages overlap (0x0a to 0x0c, and 0x0b to 0x0d), causing the firmware to happily discard any segments whose sequence number has already been used (0x0b and 0x0c of the second VendorModelMessageAcked message).
To Reproduce Steps to reproduce the behavior:
- Create a firmware that contains a vendor model that expects some data. The NCS chat example can easily be modified for this.
- Send a
VendorModelMessageAckedmessage to the firmware using the broadcast (0xffff) address. Ensure the message’s payload is big enough to be sent in segments. - Send the same message a second time - create a new instance though!.
- When the firmware receives the second
VendorModelMessageAckedmessage, it will log a warnings like:<wrn> bt_mesh_transport: Replay: src 0x0001 dst 0xffff seq 0x00000bRoughly around the same time, the library will log already used NetworkLayer sequence numbers similar to the (second) logs above.
Expected behavior
Broadcasting a VendorModelMessageAcked should properly update the sequence number - i.e. sequence numbers must not be re-used.
Platform details:
- Device: Any.
- OS: Any (most likely). Android 10 for sure.
- Library Version: 3.1.6
Note: Edited for clarity.
Issue Analytics
- State:
- Created 2 years ago
- Comments:16 (9 by maintainers)

Top Related StackOverflow Question
Works well. Thank you for the fast fix!
I have already merged this to develop so you can check it there!