I've based my application on ble_peripheral ble_app_blinky example.
So I used the following Code as model:
NRF_LOG_INFO("Send button state change.");
err_code = ble_lbs_on_button_change(m_conn_handle, &m_lbs, button_action);
if (err_code != NRF_SUCCESS &&
err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
err_code != NRF_ERROR_INVALID_STATE &&
err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
{
APP_ERROR_CHECK(err_code);
}
break;
with:
uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state)
{
ble_gatts_hvx_params_t params;
uint16_t len = sizeof(button_state);
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_lbs->button_char_handles.value_handle;
params.p_data = &button_state;
params.p_len = &len;
return sd_ble_gatts_hvx(conn_handle, ¶ms);
}
for update and notification of a charachteristic value.
This and the documentation under https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.0.0%2Flib_ble_advertising.html (function sd_ble_gatts_hvx) suggest that the sd_ble_gatts_value_set function is not needed.
With this approach, the value at the client remains 0 when the notification is switched on and the correct value only appears after the first update. This can take a very long time. This is unsatisfactory.
Therefore I tried to set the value before with sd_ble_gatts_value_set.
void ble_temp_char_update(uint16_t conn_handle, ble_mein_service_t *p_mein_service, int16_t data)
{
ret_code_t rc;
ble_gatts_hvx_params_t params;
uint16_t len = sizeof(data);
ble_gatts_value_t gv;
memset(&gv, 0, sizeof(gv));
gv.len = sizeof(data);
gv.offset = 0;
gv.p_value = (uint8_t *)&data;
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_mein_service->temp_char_handles.value_handle;
params.p_data = (uint8_t *)&data;
params.p_len = &len;
rc = sd_ble_gatts_hvx(conn_handle, ¶ms);
switch (rc) {
case NRF_SUCCESS:
break;
case BLE_ERROR_INVALID_CONN_HANDLE:
//keine Connection vorhanden
case NRF_ERROR_INVALID_STATE:
//Notification nicht eingeschaltet
//...dann setze den Wert, falls mit Read gelesen wird
rc = sd_ble_gatts_value_set(conn_handle, p_mein_service->temp_char_handles.value_handle, &gv);
APP_ERROR_CHECK(rc); // <=== Error 0x3002
break;
case BLE_ERROR_GATTS_SYS_ATTR_MISSING:
//bei einem bekannten Peer muss wohl hier sd_ble_gatts_sys_attr_set() aufgerufen werden
break;
default:
APP_ERROR_CHECK(rc);
}
}
This works so far. But after disconnecting the connection an error 0x3002 occurs when the update function is called again (Line 29 in the last Codebox).
What can I do?