This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

S132 v4.0.5 Notification packet corruption

Hello,

I have an application where an nRF52832 peripheral (S132 v3.1.0) transmits a 5-to-10 MB file to an nRF52832 central (S132 v4.0.5). The peripheral sends the file in segments using a custom notify characteristic (similar to the ble_app_uart examples). With an MTU size of 247 and connection event length extension, I'm able to achieve around 700 kbps transfer.

However, I've noticed that occasionally the file gets corrupted. When this occurs, three consecutive bytes of the file contain garbage data. After extensive testing, I believe the data is being corrupted on L2CAP reassembly by the central.

I changed the file to be a repeating chain of 0x00 through 0xC0 and added some additional wrappers to the packet for diagnostics:

  • Byte 0: 0xFE (Start)
  • Byte 1-4: File offset (in big endian)
  • Byte 5: Number of bytes in this packet
  • Byte 6 through N-2: File content
  • Byte N-1: 0xFF (End)

I used the NXP USB-KW41Z for sniffing as it is capable of Bluetooth 4.2 (Nordic's sniffer is not). I was able to catch 8 transfers where the BLE_GATTC_EVT_HVX event on the central contained incorrect data. In all instances, the packet where the file was sent was fragmented by the peripheral and the 3 bytes that were corrupted were the last 3 bytes of the first fragment.

Here is one such example. The 244 byte notification was partitioned into two fragments by the peripheral's soft device.

Fragment 1:

FE 00 8A A0 E6 F4 3D 3E 3F 40 41 42 43 44 45 46
47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56
57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66
67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76
77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86
87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96
97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6

Fragment 2:

A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6
B7 B8 B9 BA BB BC BD BE BF C0 00 01 02 03 04 05
06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15
16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25
26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35
36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45
46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55
56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65
66 67 68 FF

Fragment start packet: Fragment start

Fragment start (re-transmission): Fragment start (re-transmission)

Fragment end: Fragment end

The event data I received on the central for the BLE_GATTC_EVT_HVX event:

FE 00 8A A0 E6 F4 3D 3E 3F 40 41 42 43 44 45 46
47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56
57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66
67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76
77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86
87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96
97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 1A 77 00 //Note A4 A5 A6 has been replaced with 1A 77 00
A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6
B7 B8 B9 BA BB BC BD BE BF C0 00 01 02 03 04 05
06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15
16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25
26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35
36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45
46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55
56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65
66 67 68 FF

In all instances I've seen, the first fragment is transmitted twice. There are multiple instances where the notification is fragmented and data is not corrupted. The corrupted bytes appear to only occur when the first fragment is re-transmitted.

So my questions are:

  • What causes the Soft Device (S132 v3.1.0) to decide to fragment the notification into two packets?
  • Is there a way to prevent fragmentation?
  • Is the packet re-assembly a bug in S132 v4.0.5 or some underlying Bluetooth problem?

Edit: Added wireshark capture 11-21-2017__03-43-00 PM.pcapng

  • Strange. The SoftDevice will fragment if the attribute data length is to big to fit inside one LL packet. What LL payload size are you using?

    It is prevented by setting an ATT MTU that can fit inside one LL packet.

    I'm not aware of any such bug, but I will look into this. Could you edit your question and upload the complete sniffer trace?

  • I've added the attachment per your request.

    The payload is always 244 bytes or less. From the capture, most of the notifications are transmitted as a single packet.

    I should also point out that I have some additional control messages that are being transmit concurrent with the file transfer. I needed to implement some flow control because the UART output of my central could occasionally stall (e.g. the PC is too busy to read the virtual COM).

    Now that I have the verbosity of the sniffer, I've realized that the current flow control is not very efficient. The central writes (write with response) a command to the peripheral: Send me another N bytes. The peripheral responds with the LL acknowledgement, as well as an application level acknowledgement (notification on a different characteristic). This slows down my throughput, so I may change to a write without response based scheme.

  • I re-wrote my application code to just perform a generic BLE transfer.

    When additional writes/notifications (simulating my flow control) are interspersed with the file transfer packets, about 5-10% of the LL packets are fragmented by the Soft Device. When the file transfer packets are the only packets the peripheral sends (i.e. flow control is off), there does not appear to be any fragmentation.

    Even with fragmentation, I am unable to reproduce the corrupted data issue on the test platform. For the time being, I'm going to assume the issue is limited to my firmware.

  • Thanks. For some reason I'm not able do decode your trace. Do I need to do anything special?

    I believe the nRF Sniffer v2 supports data length extension. Maybe you can try to do a sniff with it?

  • I believe there is some parsing setting that NXP sets up with Wireshark when you install their Kinetis Protocol Analyzer Software. I ran into the same problem when updating Wireshark.

    I've installed the nRF Sniffer v2 and it doesn't seem to support data length extension yet. The payload is truncated after 33 bytes.

Related