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)

Parents
  • 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

Reply Children
  • 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);
    }

  • Don,

    BLE_GATT_OP_EXEC_WRITE_REQ is used to end a long write procedure and can't be used to start a new write. What error did you get in return when you used BLE_GATT_OP_WRITE_CMD?

  • Vidar,

    Ok, it is operating differently when using this, but I do not get a Event write response event to know whether the Write passed?  My connection with the sensor times out because I was waiting on the event.

    .write_op = BLE_GATT_OP_WRITE_CMD,
    .flags = 0,
    .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);

    case BLE_GATTC_EVT_WRITE_RSP:
    {
    no event received?
    }
    break;

  • Don,

    This is actually correct behavior for this command. BLE_GATT_OP_WRITE_CMD is a write without response meaning that the packet is only acknowledged at the link layer. You will however get the TX complete event when the packets has been received by the gatt server as the message sequence chart here shows: GATTC Characteristic Value Write Without Response.

    You can use BLE_GATT_OP_WRITE_REQ if you need a write response: GATTC Characteristic or Descriptor Value Write

Related