Android-nRF-Mesh-Library: Sequence number is not properly updated when broadcasting segmented VendorModelMessageAcked messages.

Describe 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:

  1. Create a firmware that contains a vendor model that expects some data. The NCS chat example can easily be modified for this.
  2. Send a VendorModelMessageAcked message to the firmware using the broadcast (0xffff) address. Ensure the message’s payload is big enough to be sent in segments.
  3. Send the same message a second time - create a new instance though!.
  4. When the firmware receives the second VendorModelMessageAcked message, it will log a warnings like: <wrn> bt_mesh_transport: Replay: src 0x0001 dst 0xffff seq 0x00000b Roughly 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.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks for your help!

could you test against the sample app as well?

Sure, but the network layer is quite far down the stack, and the library nicely hides it behind a comfortable high level interface - great work btw - so I’d be very surprised if it behaves different at the sample app. Anyway, please give me a few days…

Works well. Thank you for the fast fix!

I have already merged this to develop so you can check it there!

@roshanrajaratnam Thank you for the fast fix. I’ll have a look at it in the next few days.