Any idea why sd_ble_gap_rssi_start(handle, 0, 0);
returns NRF_ERROR_INVALID_ADDR
? The documentation doesn't list that as a possible return value and I can't look in the code to see what is causing it.
I'm not doing anything fancy, I basically do this in my connection callback (I'm using mBed):
void onConnectionInterrupt(const Gap::ConnectionCallbackParams_t* params)
{
int rv = sd_ble_gap_rssi_start(params->handle, 0, 0);
if (rv != NRF_SUCCESS)
printf("Failed: %d\n", rv);
}
Which prints Failed: 16
.
Bonus question: Is it necessary to call
sd_ble_gap_rssi_stop()
in the disconnection interrupt, or is it handled cleanly by the softdevice?
My main question though is why the RSSI updates don't work. I'm using an nRF52-DK.
Edit: I tried with an nRF51-DK and this time it prints Failed: 8
which is NRF_ERROR_INVALID_STATE
. There's clearly a bug in the softdevice somewhere, even it if is just returning the wrong error.
Edit 2:: Here is a minimal example that reproduces the problem. Note that this doesn't work in the mBed online compiler. In fact event the BLE_Button example doesn't seem to work at the moment - the board freezes when you connect. You might want to take a look at that!
Anyway, this code 'works' when compiled with the mBed CLI, in that it prints Failed: 8
when you connect.
#include "mbed.h"
#include "ble/BLE.h"
#include "nrf_error.h"
#include "nrf_svc.h"
const int SD_BLE_GAP_RSSI_START = 0x84;
SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count));
const static char DEVICE_NAME[] = "RSSI Test";
Serial pc(USBTX, USBRX);
void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
pc.printf("Connected.\nStarting RSSI updates on: %d\n", params->handle);
int rv = sd_ble_gap_rssi_start(params->handle, 0, 0);
if (rv == NRF_SUCCESS)
{
pc.puts("Success!\n");
}
else
{
pc.printf("Failed: %d\n", rv);
}
}
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
pc.puts("Disconnected.\n");
BLE::Instance().gap().startAdvertising();
}
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
BLE& ble = params->ble;
ble_error_t error = params->error;
if (error != BLE_ERROR_NONE) {
pc.puts("Error initialising BLE.\n");
return;
}
if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
pc.puts("BLE not default instance.\n");
return;
}
ble.gap().onConnection(connectionCallback);
ble.gap().onDisconnection(disconnectionCallback);
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ble.gap().setAdvertisingInterval(100);
ble.gap().startAdvertising();
}
int main()
{
pc.printf("-------\n\n");
BLE &ble = BLE::Instance();
ble.init(bleInitComplete);
while (!ble.hasInitialized())
{
}
for (;;)
{
ble.waitForEvent();
}
}
Edit 3: I tested it with the official nRF5x SDK and it seems to actually work. Using the ble_peripipheral/ble_app_template
example, and adding these lines to the BLE_GAP_EVT_HANDLER
case:
err_code = sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle, 0, 0);
NRF_LOG_INFO("RSSI Start: %d %d\r\n", err_code, p_ble_evt->evt.gap_evt.conn_handle);
It prints RSSI Start: 0 0
. So obviously there is some difference between mBed and the official SDK. Is there a way to pay for someone from Nordic to take a look at this?