I am changing the Tx power successfully with sd_ble_gap_tx_power_set(). I can see the RSSI value change Nordic Connect to confirm that it really is changing. But I also have the TX Power Service enabled and do not see the power level updating in its characteristic. Should that update automatically? It doesn't. So I tried using ble_tps_tx_power_level_set() to get the service characteristic value to match, but that always crashes. Here's my code:
void tx_power_set(int8_t tx_power_level)
ret_code_t err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_advertising.adv_handle, tx_power_level);
err_code = ble_tps_tx_power_level_set(&m_tps, tx_power_level);
I suspect that ble_tps_tx_power_level_set() is returning an error code here, and that the error check by APP_ERROR_CHECK() cause the application to assert to the fault handler. It would be good if you can find the error code from ble_tps_tx_power_level_set(). The ble_tps_tx_power_level_set() is basically a wrapper around sd_ble_gatts_value_set(), so I guess it is one of the listed errors:
You are right. It was returning a BLE_ERROR_INVALID_CONN_HANDLE. This was happening when I changed the power level when unconnected.I see that other services prevent this problem by either setting the conn_handle to BLE_CONN_HANDLE_INVALID in their service init routine, or they call sd_ble_gatts_value_set() with a first parameter of BLE_CONN_HANDLE_INVALID rather than the current service conn_handle.
For example, the Blood Pressure Service init looks like this:
uint32_t ble_bps_init(ble_bps_t * p_bps, ble_bps_init_t const * p_bps_init)
p_bps->conn_handle = BLE_CONN_HANDLE_INVALID;
ret_code_t ble_bas_battery_level_update(ble_bas_t * p_bas,
if (battery_level != p_bas->battery_level_last)
// Update database.
err_code = sd_ble_gatts_value_set(BLE_CONN_HANDLE_INVALID,
The Tx Power Level Service ble_tps.c library code does neither, so an error is thrown when setting without a connection. Should the library code be more like the others? My workaround is to set the conn_handle after calling the library ble_tps_init() function:
err_code = ble_tps_init(&m_tps, &tps_init_obj);
m_tps.conn_handle = BLE_CONN_HANDLE_INVALID;
I was not aware, but this sounds like a reasonable workaround yes, you can also set the m_tps.conn_handle = BLE_CONN_HANDLE_INVALID; on the BLE_GAP_EVT_DISCONNECTED event if you want.