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

BLE_ERROR_GATTS_INVALID_ATTR_TYPE when sending notification with sd_ble_gatts_hvx()

Hello,

I've been all over the forum trying to solve my problem but I just couldn't find enough information.

I'm trying to set up notifications in my application, but I cannot get rid of the BLE_ERROR_GATTS_INVALID_ATTR_TYPE error. According to the documentation, this error is returned when an invalid attribute type(s) is supplied, only characteristic values may be notified and indicated.

I have a function that looks like this:

uint32_t ble_abstraction_chara_notify(ble_service_t *p_custom_service, ble_gatts_char_handles_t * char_handle, uint8_t length, uint8_t * val)
{
    if (p_custom_service->conn_handle != BLE_CONN_HANDLE_INVALID)
    {
    	uint16_t len = length;
        ble_gatts_hvx_params_t hvx_params;
        memset(&hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = char_handle->value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = 0;
        hvx_params.p_len  = &len;
        hvx_params.p_data = val;

        return sd_ble_gatts_hvx(p_custom_service->conn_handle, &hvx_params);
    }
    NRF_LOG_ERROR("Invalid connection handle\r\n");
    return BLE_ERROR_INVALID_CONN_HANDLE;
}

Then I call it passing a pointer to the characteristic that I want to update.

The thing is: I have a service with 18 characteristics, and I store the characteristic handles in an array as follows: ble_gatts_char_handles_t characteristics[18]. Then I pass the pointer to that array to the service initialization routine, which assigns it to the char_handles member of the ble_service_t struct. I have set the vloc flag to BLE_GATTS_VLOC_USER to indicate that I will store the characteristics myself.

In the end, I just call the function by passing a pointer to the characteristic I want, but sd_ble_gatts_hvx returns invalid attribute type. I don't understand why.

I already tried to pass the pointer to the characteristic like this:

ble_gatts_char_handles_t * characteristic = &characteristics[index];

and like this:

ble_gatts_char_handles_t * characteristic = &(service->char_handles[index]);

To my understanding, those two calls should be equivalent, but I just tried for the sake of trying and it still fails.

Any pointers to where I might have the problem will be really appreciated!

EDIT: Typo

Update: I put some more debug output to check the value handles I'm getting each time I add a characteristic with sd_ble_gatts_characteristic_add. Now, for example, I know for a fact that the call to sd_ble_gatts_characteristic_add returned a 0x003D for the value handle of a particular characteristic. If I pass 0x003D to hvx_params.handle shouldn't I be able to send a notification? I mean, maybe I would get another kind of error, but why am I getting "invalid attribute"?

Related