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?