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

pc-ble-driver: Indication fails with error 0x0C (wrong data size) on the third indication of same size

I have a long PDU which I need to send fragmented by indications.

So in a while loop I populate a ble_gatts_hvx_params_t  hvx_params struct and call 

error_code = sd_ble_gatts_hvx(m_adapter, m_connection_handle, &hvx_params);

The code sequence is

hvx_params.handle = global_indicate_handle;
        hvx_params.type = BLE_GATT_HVX_INDICATION;
        hvx_params.offset = global_indicate_offset;
        hvx_params.p_len = &hvx_length;
        hvx_params.p_data = global_indicate_data;

        printf("hvx_params.handle 0x%04X\nhvx_params.offset %u bytes\nhvx_params.p_len %u\nhvx_params.p_data 0x%X\n",
            hvx_params.handle, hvx_params.offset, *hvx_params.p_len, hvx_params.p_data);

        error_code = sd_ble_gatts_hvx(m_adapter, m_connection_handle, &hvx_params);

The PDU is 61 bytes

send 1 is 20 bytes from offset 0

send 2 is 20 bytes from offset 20

send 3 is 20 bytes from offset 40 - fails with error 0x0C (incorrect size). What?

Here is the log


Send # 1: Sending 20 bytes of 61 total from offset 0 at time 5391 on attribute handle 0x0013
hvx_params.handle 0x0013
hvx_params.offset 0 bytes
hvx_params.p_len 20
hvx_params.p_data 0xBEAF52F0
Confirmation of indication on handle 19 received at time 5469

(wait on sem)
Send # 2: Sending 20 bytes of 61 total from offset 20 at time 5469 on attribute handle 0x0013
hvx_params.handle 0x0013
hvx_params.offset 20 bytes
hvx_params.p_len 20
hvx_params.p_data 0xBEAF52F0
Confirmation of indication on handle 19 received at time 5578

(wiat on sem)
Send # 3: Sending 20 bytes of 61 total from offset 40 at time 5578 on attribute handle 0x0013
hvx_params.handle 0x0013
hvx_params.offset 40 bytes
hvx_params.p_len 20
hvx_params.p_data 0xBEAF52F0
Failed doing the indication. Error code: 0x0C

I know the length field is a pointer so I print the contents of the pointer.

On the Android i receive 20 bytes on the two successful indications, but the same 20 bytes. What am I doing wrong? 

WOULD YOU PLEASE ADD A PC_BLE_DRIVER tag!!!

Parents
  • It may be a case of poor documentation.

    If I ignore the offset and always set it to 0 and increase the pointer to the data instead, I do not get the 0x0C error and the same 20 bytes are not sent every time. I do not know what purpose the offset serves.

    Here is the only documentation for this method

    * @param[in] conn_handle Connection handle.
    * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data
    * contains a non-NULL pointer the attribute value will be updated with the contents
    * pointed by it before sending the notification or indication. If the attribute value
    * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to
    * contain the number of actual bytes written, else it will be set to 0.
    *
    * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
    * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
    * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
    * - Invalid Connection State
    * - Notifications and/or indications not enabled in the CCCD
    * - An ATT_MTU exchange is ongoing
    * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
    * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
    * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
    * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
    * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
    * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
    * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
    * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
    * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
    * @retval ::NRF_ERROR_RESOURCES Too many notifications queued.
    * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
    * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
    */
    SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(adapter_t *adapter, uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));

    and the core struct

    typedef struct
    {
    uint16_t handle; /**< Characteristic Value Handle. */
    uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
    uint16_t offset; /**< Offset within the attribute value. */
    uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */
    uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */
    } ble_gatts_hvx_params_t;

    which is clearly incorrect.

Reply
  • It may be a case of poor documentation.

    If I ignore the offset and always set it to 0 and increase the pointer to the data instead, I do not get the 0x0C error and the same 20 bytes are not sent every time. I do not know what purpose the offset serves.

    Here is the only documentation for this method

    * @param[in] conn_handle Connection handle.
    * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data
    * contains a non-NULL pointer the attribute value will be updated with the contents
    * pointed by it before sending the notification or indication. If the attribute value
    * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to
    * contain the number of actual bytes written, else it will be set to 0.
    *
    * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
    * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
    * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
    * - Invalid Connection State
    * - Notifications and/or indications not enabled in the CCCD
    * - An ATT_MTU exchange is ongoing
    * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
    * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
    * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
    * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
    * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
    * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
    * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
    * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
    * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
    * @retval ::NRF_ERROR_RESOURCES Too many notifications queued.
    * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
    * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
    */
    SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(adapter_t *adapter, uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));

    and the core struct

    typedef struct
    {
    uint16_t handle; /**< Characteristic Value Handle. */
    uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
    uint16_t offset; /**< Offset within the attribute value. */
    uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */
    uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */
    } ble_gatts_hvx_params_t;

    which is clearly incorrect.

Children
Related