Calling sd_ble_gap_tx_power_set() errors out with 0x3004, NRF_ERROR_NO_MEM


I've been trying to figure why calling sd_ble_gap_tx_power_set() continues to return the error NRF_ERROR_NO_MEM. I'm using SDK 17.0.2 with S113, v7.2.0 on the NRF52840.

I've seen previous posted regarding other Softdevice function calls failing with NRF_ERROR_NO_MEM, but all attempts to limit MTU and GAP_LENGTH in sdk_config.h failed.

I even tried rebuilding the project with S140, but still, my application code errors out with NRF_ERROR_NO_MEM.

  ret_code_t err_code = NRF_SUCCESS;
    ble_advertising_init_t bleAdvInitData;

    // Initialize to zero.
    memset( &bleAdvInitData, 0, sizeof( bleAdvInitData ) );

    // Set the Tx power before we begin advertisement. Radio transmit power in
    // dBm (accepted values are ONLY -40, -20, -16, -12, -8, -4, 0, and 4 dBm).
    // Note: Testing with the base station found that TX_POWER_HIGH_SECURITY set
    // the transmit strength too low for consistent log transfers.
    txPower_t calaTxPower = TX_POWER_MEDIUM_SECURITY;

    ble_uuid_t adv_uuids[] = { { BTS_UUID_SERVICE, m_bts.uuid_type } }; // BTS

    // Build advertising data struct to pass into @ref ble_advertising_init.
    bleAdvInitData.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    bleAdvInitData.advdata.include_appearance = true;
    bleAdvInitData.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    memset( &bleAdvInitData.srdata, 0, sizeof( bleAdvInitData.srdata ) );
    bleAdvInitData.srdata.uuids_complete.uuid_cnt = sizeof( adv_uuids ) / sizeof( adv_uuids[0] );
    bleAdvInitData.srdata.uuids_complete.p_uuids = adv_uuids;

    bleAdvInitData.config.ble_adv_fast_enabled  = true;
    bleAdvInitData.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    bleAdvInitData.config.ble_adv_fast_timeout  = APP_ADV_NEVER_TIMEOUT;
    bleAdvInitData.evt_handler                  = on_adv_evt;

    // Set the Tx power (rely on compiler type promotion to int8_t here):
    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_connHandle, calaTxPower);
    if ( err_code != NRF_SUCCESS )
        NRF_LOG_INFO( "sd_ble_gap_tx_power_set() failed, err_code: 0x%X\n", err_code );

Top Replies

  • Hi,

    The error code 0x3004 is BLE_ERROR_INVALID_ADV_HANDLE (not NRF_ERROR_NO_MEM). Looking at the API documentation for sd_ble_gap_tx_power_set() you see that it is returned if you provided an invalid connection handle. I do not see from your code snippet what the value of m_connHandle is, but it is clearly not valid. You get this value from when you initialize advertising (see for instance <SDK 17.x.x>\examples\ble_peripheral\ble_app_proximity\main.c).

    For future reference, I highly recommend making use of the APP_ERROR_CHECK() function in combination with having DEBUG defined in your preprocessor defines, like shown in the included image:

    This will make your logger output a detailed error message whenever a non-NRF_SUCCESS error code is passed to an APP_ERROR_CHECK, which makes debugging much easier. It would be very useful to see the error message output by the logger in this case, if you insert an APP_ERROR_CHECK on the error code returned by sd_ble_gap_tx_power_set.

  • Looks like a misread interpreted the error code. Thank you for clarifying. Ok, so I can now successfully call sd_ble_gap_tx_power_set() with the following code:

    BLE_ADVERTISING_DEF(m_advertising);                                                 /**< Advertising module instance. */
    static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;                            /**< Handle of the current connection. */
    //err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_connHandle, calaTxPower); // this does not work!
    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_advertising.adv_handle, calaTxPower); // this works

    The way that doesn't work is the way we used to call sd_ble_gap_tx_power_set() from SDK 11.0.0~!

    The method that you suggested, which doesn't use the connection handle but rather, the advertising instance m_advertising, does work. Is my attempt to use m_conn_handle simply deprecated? 

    I turned on the DEBUG preprocessor as you suggested, however, I got no further information (only the old error code 0x3004).

  • 0
    22825 pts.
    in reply to Sami


    The API of sd_ble_gap_tx_power_set() changed in SoftDevice version 6.0.0. Since then, you can set TX power separately for different roles, connections, etc. See API documentation for details.