BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED, when trying a Write Characterisitc?

Part: nrf52833

Soft Device: SD140 (recently switched from SD 122 because SD140 supports more BLE 5.x features)

Application: Replace legacy Central host device with nrf53833.

Problem: One of our production peripherals will make a connection, but the Characteristic writes  fail after to switching from SD 122 to SD 140.

The gstt_status fault code is 0x106.  BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED

One of our peripherals gets an error when a Write Characteristic is requested, type_2 passes the request.

This is a high priority to get working?  Is there any way to tell why SD122 did not have this issue?

Thanks,

Dan

Customer Sensor Peripheral type 1:  gets a gatt_status failure

00> <warning> ble_nus_c: WRITING TO THE AUTH CHAR
00> <debug> app: GATT STATUS FAULT CODE 0x106

Customer sensor Peripheral type 2: no failure, is it possible that sensor 1 does not support the MTU exchange below that sensor 2 shows?

00> <debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 247 bytes.
00> <debug> nrf_ble_gatt: Updating ATT MTU to 23 bytes (desired: 23) on connection 0x0.
00> <info> app: Ble NUS max data length set to 0x14(20)

  • Hello,

    It looks like you central project is not configured to support long ATT MTUs, which means your payload is effectively limited to 20 bytes for each write without response packet (GATTC Characteristic Value Write Without Response). I suggest you try to increase the MTU in your project to allow for longer packets.

    Increasing the max. ATT MTU Size

    In gatt_init():

    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_central_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }

    and in sdk_config.h:

    // <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
    #ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247
    #endif

    One of our peripherals gets an error when a Write Characteristic is requested, type_2 passes the request.

    I guess you were trying to do a "long write" (GATTC Characteristic or Descriptor Value Long Write) when you got the error? Either way,  BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED is indicating that you tried to issue an request that is not supported by the peripheral.

    Best regards,

    Vidar

  • Vidar,

    Thanks for getting back with this.  It appears that the MTU_SIZE is not directly related to the problem.  The write request still fails when the gatt_central is initialized to NRF_SDH_BLE_GATT_MAX_MTU_SIZE.  

    here are some additinal details.

    1.  the Central makes a connection.

     2. A write request to a characteristic is made.

      NRF_LOG_WARNING("WRITING TO THE AUTH CHAR");

            return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);

    /* code */

     

    3.  The response from the write request is a fault 0x106.  (This worked when using SD122?)

    00> <debug> app: GATT WRITE FAILED.

    00> <debug> app: GATT STATUS FAULT CODE 0x106

     

      case BLE_GATTC_EVT_WRITE_RSP:

            {

               const ble_gattc_evt_write_rsp_t * p_val = &p_ble_evt->evt.gattc_evt.params.write_rsp;

             

               if ((BLE_GATT_STATUS_SUCCESS != p_ble_evt->evt.gattc_evt.gatt_status))

                {

                  // Handle retry of the write depending upon the error

                  NRF_LOG_DEBUG("GATT WRITE FAILED.");

                  NRF_LOG_DEBUG("GATT STATUS FAULT CODE 0x%X", p_ble_evt->evt.gattc_evt.gatt_status);

                  // handle write failure 

                  cble_nus_c_handleFaultWriteChar(p_val);

                }else{

                  // handles moving to the next step when the write has completed.

                  cble_nus_c_handleWriteChar(p_val);

               }

     Thanks,

    Dan

  • Dan,

    There shouldn't be any difference between the s122 and s140 if you are passing the same write parameters to sd_ble_gattc_write(). Can you post the parameters you have in 'write_params' here?

    Best regards,

    Vidar

  • Here is the Write request code:

    uint32_t ble_nus_c_auth_char_write(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length)
    {
    VERIFY_PARAM_NOT_NULL(p_ble_nus_c);

    if (length > BLE_NUS_MAX_DATA_LEN)
    {
    NRF_LOG_WARNING("Content too long.");
    return NRF_ERROR_INVALID_PARAM;
    }
    if (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
    {
    NRF_LOG_WARNING("Connection handle invalid.");
    return NRF_ERROR_INVALID_STATE;
    }

    ble_gattc_write_params_t const write_params =
    {
    .write_op = BLE_GATT_OP_EXEC_WRITE_REQ,
    .flags = 0, //BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
    .handle = p_ble_nus_c->handles.cble_auth_pw_handle,
    .offset = 0,
    .len = length,
    .p_value = p_string
    };

    NRF_LOG_WARNING("WRITING TO THE AUTH CHAR");
    return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);
    }

  • Vidar,

    I tried many different Write parameter combinations, and still getting an error 0x106 with the one periperal and success on the other.

    Note: We do not run the Discovery() step after connecting to the sensor.

    ble_gattc_write_params_t const write_params =
    {
    .write_op = BLE_GATT_OP_EXEC_WRITE_REQ,//BLE_GATT_OP_WRITE_CMD, //BLE_GATT_OP_SIGN_WRITE_CMD,//BLE_GATT_OP_WRITE_REQ, //BLE_GATT_OP_EXEC_WRITE_REQ, //BLE_GATT_OP_WRITE_CMD,
    .flags = 0, //BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,

    // .write_op = BLE_GATT_OP_WRITE_CMD,
    // .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,

    .handle = p_ble_nus_c->handles.cble_auth_pw_handle,
    .offset = 0,
    .len = 4, // length,
    .p_value = p_string
    };

    NRF_LOG_WARNING("WRITING TO THE AUTH CHAR");
    return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);
    }

Related