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

hard fault in examples/peripheral/usbd_ble_uart when MTU is exceeded

I'm using the example examples/peripheral/usbd_ble_uart on a nRF42840 USB dongle (pca10059).

As client (central) I'm using nrfconnect on an Android phone.

Connecting to the peripheral and sending data onto the UART RX channel works fine, as long as data length doesn't exceed the maximum MTU (hardcoded to 64bytes in the example).

Example output:

<info> nrf_ble_gatt: Requesting to update ATT MTU to 64 bytes on connection 0x0.
<info> app: BLE NUS connected
<info> app: Data len is set to 0x3D(61)
<info> app: CDC ACM unavailable, data received: 123456789012345678901234567890123456789012345678901234567890

If I exceed that 64bytes limit, though, the device hard faults with:

<error> app: ERROR 7 [NRF_ERROR_INVALID_PARAM] at ../../../main.c:481
PC at: 0x00031F33
<error> app: End of error report

While this is probably to be expected(?), I'm missing a hint how to do it right.

By right I mean:

best case) how to still be able to receive that data (e.g. as multiple packets each not exceeding the MTU)

worst case) discard data and/or disconnect from the central or alike, but stay operational for the next connection request

..but not hard fault.

Thanks!

  • Please try with the code posted below. I changed the implementation so it replies with BLE_GATT_STATUS_SUCCESS when it gets a BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL request. Same as we do in the Queued Writes module.

            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                ble_gatts_evt_rw_authorize_request_t  req;
                ble_gatts_rw_authorize_reply_params_t auth_reply = {0};
    
                req = p_ble_evt->evt.gatts_evt.params.authorize_request;
    
                if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
                {
                    if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                    {
                        if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                        }
                        else
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                        }
    
                        auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
    
                        if (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
                        {
                            auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
                        }
    
                        err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                                   &auth_reply);
                        APP_ERROR_CHECK(err_code);
                    }
                }
            } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST

Related