Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

ble_advertising_init returning NRF_ERROR_INVALID_PARAM for parameters set by the function itself

Hello,

i'm trying to use ble_advertising_init to initialize my advertising data, but when i use this function like it is used in the examples i get NRF_ERROR_INVALID_PARAM.

i located the error in the following code part of the function:

    // 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_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);

Since all parameters given to the function are the default params defined by the function itself, there should be no error.

Also the comment is kind of irritating, since you can't set any advertising parameters in ble_advertising_start. Although it seems, that ble_advertising_start overwrites your set paramters with default values again. But since these parameters can only be set when advertising is stopped, this would make setting them pointless.

Am i missing something here?

If someone could provide some inside on this, i would appreciate it.

Best regards,

Niclas

Parents
  • For anyone having problems with the ble_advertising_init() function, I would recommend using the combination of ble_advdata_encode() and sd_ble_gap_adv_set_configure() instead. Instead of the ble_advertising_init_t struct you can use the ble_advertising_t struct directly:

      ble_advertising_init_t init;
      ble_advertising_t advertising;
    
      advertising.adv_data.adv_data = init.advdata;
      advertising.adv_data.scan_rsp_data = init.srdata;
      advertising.adv_modes_config = init.config;
      advertising.evt_handler = init.evt_handler;
      advertising.error_handler = init.error_handler;

    To initialize your advertsing data and parameters You can use the following function:

    BLE_ADVERTISING_DEF(m_advModuleInstance);
    
    extern void advertising_init (void)
    {
      uint32_t      err_code = NRF_SUCCESS;
      ble_advdata_t advInitData;
      ble_advdata_t srInitData;
    
      /* Initialize structs. */
      memset(&advInitData, 0, sizeof(ble_advdata_t));
      memset(&srInitData, 0, sizeof(ble_advdata_t));
    
      /* Prepare advertising data. */
      advInitData.xxx = xxx; // configure the data you want here
    
      /* Prepare scan response data. */
      srInitData.xxx = xxx; // configure the data you want here
    
      /* Set advertising and scan response data. */
      m_advModuleInstance.adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
      m_advModuleInstance.adv_mode_current = BLE_ADV_MODE_IDLE;
    
      m_advModuleInstance.adv_data.adv_data.p_data = m_advModuleInstance.enc_advdata;
      m_advModuleInstance.adv_data.adv_data.len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    
      err_code = ble_advdata_encode(&advInitData, m_advModuleInstance.adv_data.adv_data.p_data, &m_advModuleInstance.adv_data.adv_data.len);
      APP_ERROR_CHECK(err_code);
      BLEPE_LOG_PRINTF_WARNING("adv_data.len 0x%X",m_advModuleInstance.adv_data.adv_data.len);
    
      m_advModuleInstance.adv_data.scan_rsp_data.p_data = m_advModuleInstance.enc_scan_rsp_data;
      m_advModuleInstance.adv_data.scan_rsp_data.len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    
      err_code = ble_advdata_encode(&srInitData, m_advModuleInstance.adv_data.scan_rsp_data.p_data, &m_advModuleInstance.adv_data.scan_rsp_data.len);
      APP_ERROR_CHECK(err_code);
      BLEPE_LOG_PRINTF_WARNING("scan_rsp_data.len 0x%X",m_advModuleInstance.adv_data.scan_rsp_data.len);
    
      /*
       *  Configure a initial advertising configuration. The advertising data and advertising parameters
       *  can be changed later, but must be set to legal values here to define an advertising handle.
       */
      m_advModuleInstance.adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
      m_advModuleInstance.adv_params.duration        = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
      m_advModuleInstance.adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
      m_advModuleInstance.adv_params.p_peer_addr     = NULL;
      m_advModuleInstance.adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
      m_advModuleInstance.adv_params.interval        = BLE_GAP_ADV_INTERVAL_MIN;
    
      err_code = sd_ble_gap_adv_set_configure(&m_advModuleInstance.adv_handle, &m_advModuleInstance.adv_data, &m_advModuleInstance.adv_params);
      APP_ERROR_CHECK(err_code);
    
      m_advModuleInstance.initialized = true;
    }

    In my opinion, it has the following advantages over the ble_advertising_init() function:

    • All adv_params are set to default values (no need to set fast advertising params even if you don't use them)
    • The sd_ble_gap_adv_set_configure() function actually sets your configured advertising data

    Two paramters get set during ble_advertising_init, that I don't use, but you can just add them to the init function if you need them.

    p_advertising->conn_cfg_tag                   = BLE_CONN_CFG_TAG_DEFAULT;
    p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;

    I also would advise not to use the ble_advertising_start() function from the same module, because it overwrites all your advertising paramters with the following code:

        // Initialize advertising parameters with default values.
        memset(&p_advertising->adv_params, 0, sizeof(p_advertising->adv_params));
    
        p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    
        // Use 1MBIT as primary phy if no phy was selected.
        if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
        {
            p_advertising->adv_params.primary_phy = p_advertising->adv_modes_config.ble_adv_primary_phy;
        }
        else
        {
            p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
        }
    
        if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
        {
            // Use 1MBIT as secondary phy if no phy was selected.
            if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
            {
                p_advertising->adv_params.secondary_phy = p_advertising->adv_modes_config.ble_adv_secondary_phy;
            }
            else
            {
                p_advertising->adv_params.secondary_phy = BLE_GAP_PHY_1MBPS;
            }
        }
        p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;

    I hope this helps people, who are having problems with the advertising module of the SDK15.

    Best regards,

    Niclas

Reply
  • For anyone having problems with the ble_advertising_init() function, I would recommend using the combination of ble_advdata_encode() and sd_ble_gap_adv_set_configure() instead. Instead of the ble_advertising_init_t struct you can use the ble_advertising_t struct directly:

      ble_advertising_init_t init;
      ble_advertising_t advertising;
    
      advertising.adv_data.adv_data = init.advdata;
      advertising.adv_data.scan_rsp_data = init.srdata;
      advertising.adv_modes_config = init.config;
      advertising.evt_handler = init.evt_handler;
      advertising.error_handler = init.error_handler;

    To initialize your advertsing data and parameters You can use the following function:

    BLE_ADVERTISING_DEF(m_advModuleInstance);
    
    extern void advertising_init (void)
    {
      uint32_t      err_code = NRF_SUCCESS;
      ble_advdata_t advInitData;
      ble_advdata_t srInitData;
    
      /* Initialize structs. */
      memset(&advInitData, 0, sizeof(ble_advdata_t));
      memset(&srInitData, 0, sizeof(ble_advdata_t));
    
      /* Prepare advertising data. */
      advInitData.xxx = xxx; // configure the data you want here
    
      /* Prepare scan response data. */
      srInitData.xxx = xxx; // configure the data you want here
    
      /* Set advertising and scan response data. */
      m_advModuleInstance.adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
      m_advModuleInstance.adv_mode_current = BLE_ADV_MODE_IDLE;
    
      m_advModuleInstance.adv_data.adv_data.p_data = m_advModuleInstance.enc_advdata;
      m_advModuleInstance.adv_data.adv_data.len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    
      err_code = ble_advdata_encode(&advInitData, m_advModuleInstance.adv_data.adv_data.p_data, &m_advModuleInstance.adv_data.adv_data.len);
      APP_ERROR_CHECK(err_code);
      BLEPE_LOG_PRINTF_WARNING("adv_data.len 0x%X",m_advModuleInstance.adv_data.adv_data.len);
    
      m_advModuleInstance.adv_data.scan_rsp_data.p_data = m_advModuleInstance.enc_scan_rsp_data;
      m_advModuleInstance.adv_data.scan_rsp_data.len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    
      err_code = ble_advdata_encode(&srInitData, m_advModuleInstance.adv_data.scan_rsp_data.p_data, &m_advModuleInstance.adv_data.scan_rsp_data.len);
      APP_ERROR_CHECK(err_code);
      BLEPE_LOG_PRINTF_WARNING("scan_rsp_data.len 0x%X",m_advModuleInstance.adv_data.scan_rsp_data.len);
    
      /*
       *  Configure a initial advertising configuration. The advertising data and advertising parameters
       *  can be changed later, but must be set to legal values here to define an advertising handle.
       */
      m_advModuleInstance.adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
      m_advModuleInstance.adv_params.duration        = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
      m_advModuleInstance.adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
      m_advModuleInstance.adv_params.p_peer_addr     = NULL;
      m_advModuleInstance.adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
      m_advModuleInstance.adv_params.interval        = BLE_GAP_ADV_INTERVAL_MIN;
    
      err_code = sd_ble_gap_adv_set_configure(&m_advModuleInstance.adv_handle, &m_advModuleInstance.adv_data, &m_advModuleInstance.adv_params);
      APP_ERROR_CHECK(err_code);
    
      m_advModuleInstance.initialized = true;
    }

    In my opinion, it has the following advantages over the ble_advertising_init() function:

    • All adv_params are set to default values (no need to set fast advertising params even if you don't use them)
    • The sd_ble_gap_adv_set_configure() function actually sets your configured advertising data

    Two paramters get set during ble_advertising_init, that I don't use, but you can just add them to the init function if you need them.

    p_advertising->conn_cfg_tag                   = BLE_CONN_CFG_TAG_DEFAULT;
    p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;

    I also would advise not to use the ble_advertising_start() function from the same module, because it overwrites all your advertising paramters with the following code:

        // Initialize advertising parameters with default values.
        memset(&p_advertising->adv_params, 0, sizeof(p_advertising->adv_params));
    
        p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    
        // Use 1MBIT as primary phy if no phy was selected.
        if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
        {
            p_advertising->adv_params.primary_phy = p_advertising->adv_modes_config.ble_adv_primary_phy;
        }
        else
        {
            p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
        }
    
        if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
        {
            // Use 1MBIT as secondary phy if no phy was selected.
            if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
            {
                p_advertising->adv_params.secondary_phy = p_advertising->adv_modes_config.ble_adv_secondary_phy;
            }
            else
            {
                p_advertising->adv_params.secondary_phy = BLE_GAP_PHY_1MBPS;
            }
        }
        p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;

    I hope this helps people, who are having problems with the advertising module of the SDK15.

    Best regards,

    Niclas

Children
Related