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

NRF_ERROR_INVALID_PARAM on ble_advertising_init(), SDK 15.3.0

I'm migrating a project from SDK 14.2.0 to SDK 15.3.0. I use gcc. I have three advertising modes and the first of them is working fine. For the second one, the same 

ble_advertising_init_t that I passed to ble_advertising_init() in SDK 14.2.0 successfully no longer works with SDK 15.3.0. The only change I've made in the course of migrating SDKs is that I noticed the timeouts are now specified in 10ms units, not seconds.
Here's the code up to ble_advertising_init(). BTS_UUID_SERVICE is our custom service.
void ble_advertise_on_motion(void)
{
  ret_code_t err_code = 0;

  ble_advertising_init_t init;
  memset(&init, 0, sizeof(init));

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

  // As above
  init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
  init.advdata.include_appearance = false;
  init.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; // non-discoverable
  init.advdata.uuids_complete.uuid_cnt = 1;
  init.advdata.uuids_complete.p_uuids = adv_uuids;

  // We do NOT want connections from unbonded centrals.
  init.config.ble_adv_whitelist_enabled = true;

  // Diasabled advertising modes.
  init.config.ble_adv_directed_high_duty_enabled = false;
  init.config.ble_adv_directed_enabled = false; // Would only last for 1.28s, so useless with a low power scan.
  init.config.ble_adv_fast_enabled = false;

  // Enabled advertising modes. Directed slow advertising at first looks appropriate here, but in testing, we never get a connection from our Android app. Just use slow (undirected) advertising, which gets us an immediate connection.
  init.config.ble_adv_slow_enabled = true;
  init.config.ble_adv_slow_interval = 32; // 32 * 0.625ms = 20 ms (minimum)
  init.config.ble_adv_slow_timeout = 15 * 100; // 15s, in units of 10ms

  // As above.
  init.evt_handler = on_adv_evt;

  // TODO (P1): Fix. Currently throwing:
  // "E error Code 0x7 (NRF_ERROR_INVALID_PARAM), ../ble_periph.c line 1206"
  err_code = ble_advertising_init(&m_advertising, &init);
  APP_ERROR_CHECK(err_code);
  // ...
}
I was sure there used to be decent SDM migration guides from Nordic, but I don't see one in the SDK's documentation directory. Maybe it was only for SD releases.
Parents
  • Hi Elliot, 

    I sincerely apologize for the very late reply. 

    We do provide a migration guide in the first release of a new major version number, e.g.  SDK v15.0.0. Here is the Migration guide from SDK v14.2.0 to SDK v15.0.0.  As far as I can see the only change is that the directed advertisement modes have been renamed. 

    Did you go deeper into ble_advertising_init()? I guess it was sd_ble_gap_adv_set_configure that returned NRF_ERROR_INVALID_PARAM. 

     

      p_advertising->adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
        p_advertising->adv_params.duration        = p_advertising->adv_modes_config.ble_adv_fast_timeout;
        p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
        p_advertising->adv_params.p_peer_addr     = NULL;
        p_advertising->adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        p_advertising->adv_params.interval        = p_advertising->adv_modes_config.ble_adv_fast_interval;
    
        ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, NULL, &p_advertising->adv_params);
        VERIFY_SUCCESS(ret);

    It could appear that not setting the ble_adv_fast_timeout and/or ble_adv_fast_interval will cause sd_ble_gap_adv_set_configure() to return NRF_ERROR_INVALID_PARAM.

  • No worries. Yes, I went deeper but quickly hit the SD call, beyond which of course I don't have the code. OK, thanks, but why is this invalid? I didn't use to be. It used to be fine to do a bit of slow advertising alone. Now I have to do some fast advertising first. Why? And is my understanding correct?

  • Hi Eliot, 

    just doing slow advertising is not invalid. I believe this is due to how the ble_advertising_init() function is using the parameters in ble_advertising_init_t init.config struct.  As you see in the end of ble_advertising_init, it sets the advertisment interval and timeout to p_advertising->adv_modes_config.ble_adv_fast_interval and p_advertising->adv_modes_config.ble_adv_fast_timeout. 

    So passing the following configuration to ble_advertising_init 

        init.config.ble_adv_slow_enabled = true;
        init.config.ble_adv_slow_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_slow_timeout  = APP_ADV_DURATION;
    /*
        init.config.ble_adv_fast_enabled  = false; //true 
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    */
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);

    will result in p_advertising->adv_params.duration and p_advertising->adv_params.interval being set to zero.  But, if you modify ble_advertising_init to the following, then you should not get any errors. 

    // Configure a initial advertising configuration. The advertising data and and advertising
    // parameters will be changed later when we call @ref ble_advertising_start, but must be set
    // to legal values here to define an advertising handle.
    p_advertising->adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
    p_advertising->adv_params.duration        = p_advertising->adv_modes_config.ble_adv_slow_timeout; // ble_adv_fast_timeout
    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    p_advertising->adv_params.p_peer_addr     = NULL;
    p_advertising->adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    p_advertising->adv_params.interval        = p_advertising->adv_modes_config.ble_adv_slow_interval; // ble_adv_fast_interval
    
    ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, NULL, &p_advertising->adv_params);
    VERIFY_SUCCESS(ret);

    Best regards

    Bjørn

Reply Children
  • No, as the comment in the ble_advertising_init states

    // Configure a initial advertising configuration. The advertising data and and advertising
    // parameters will be changed later when we call @ref ble_advertising_start, but must be set
    // to legal values here to define an advertising handle.

    When you start advertising using ble_advertising_start, then the intervals set in  ble_advertising_init_t init struct will be used, i.e. if you call 

    ble_advertising_start(&m_advertising, BLE_ADV_MODE_SLOW);

    then the following parameters will be used. 

    init.config.ble_adv_slow_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_slow_timeout = APP_ADV_DURATION;

    Best regards

    Bjørn

Related