Our BLE peripheral uses a custom GATT service similar to the NUS (Nordic UART service) used in the SDK example app_ble_uart. The peripheral receives data on the UART peripheral (not UARTE) from an external device at 115200 baud with full hardware handshaking.
Our PDU data length is configured as 251 and our MTU size as 247.
The peripheral repeatedly calls sd_ble_gatts_hvx with a 244 byte ATT data packet but we only receive 4 BLE_GATTS_EVT_HVN_TX_COMPLETE events.
You can see on the oscilloscope screenshot below that we have called sd_ble_gatts_hvx 11 times (SD_SEND) but have only received TX_COMPLETE 4 times. We keep track of the number of notifications available to us so we no longer try to send after calling sd_ble_gatts_hvx 7 times since the last TX_COMPLETE event.
We are outputting any errors returned by the sd_ble_gatts_hvx call using a spare GPIO line (SD_SEND_ERR) and you can see that there are none.
We have tried keeping the PDU data length configured as 251 and our MTU size as 247, but calling sd_ble_gatts_hvx with 200 byte data payload instead and this has resolved the issue.
So the main question is why do we stop receiving the BLE_GATTS_EVT_HVN_TX_COMPLETE event when we use the maximum payload size?
More detailed setup information:
BLE peripheral = nrf52 dev kit (PCA10040).
BLE central = custom hardware using nrf52832.
We are using the S132 SoftDevice v 7.0.1.
We are not using the nRF SDK driver or HAL layers – we’re interfacing with the peripherals directly, but the chip header files we’re using are taken from SDK version 15.2.
BLE connection parameters:
Connection interval 7.5ms
Event length 7.5ms
Slave latency 0.
Connection supervisory timeout 1s.
Extended event length enabled.
MTU size 247
PDU data length 251
BLE notifications queue size (hvn_tx_queue_size) 7
Happy to provide more information if needed.