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

sd_ble_gap_rssi_start() returns NRF_ERROR_INVALID_ADDR

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?

Related