This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Connecting to only one central. How to? detailed

Hi, i know this question has been ask before but, i was reading and readind and i could find a way to do it. I got the theory but when i'm going to implement it in my code i get confused.

Starting by symple, i have 2 devices, one of this as central and one of this as peripheral.

I need the peripheral only get connected to this specific central and avoide connection to another.

1-. How i can setup an static address to my central? which part of the code i do that?

2-.I know that it is possible to create a whitelist to save bond info about the connection that has been made but i think i don't need it because i only have 1 central and just want to connect to him. wich part of the code i have to writte to set the address of my central in order to only connect to him? What would be this address, the peer addres or another one?

3-. I have read about directed advertising, what i got was that, you use direct adv when you want to connect to a specific central, but again, where do you specify that?

4-. My peripheral could be scannable but i just want my central could connect not any other device.

Maybe these are newbie question, but how i wrote above, i have read and read and i don't find a good explanation to do that.

Sorry and thanks in advance.

  • Hi Antonio,

    1. You set the address of the device using sd_ble_gap_address_set() function.

    2. You need to use whitelist, you can have a look at the demo code here if you want to use the API directly. If you don't you can think of using the device manager or peer manager and limit the maximum number of peer device to 1.

    3. You need to feed the address and the flag when calling sd_ble_gap_adv_start() as explained in the API documentation and in the blog above.

    4. Whitelisting with only one central will do the tast.

    Here is an example of using directed advertising. The address of the central device is {ba:2d:f2:f5:ed:5c} address type is Public. SDK v11, S132v2.

    ble_app_proximity - Directed.zip

  • Hi thanks for answer.. No i get this in my peripheral..

    MAIN.C

    int main(void){
    
     Uint32_t err_code;
     bool erase_bonds;
    // Initialize.
     le
    
    ds_init();
         nrf_gpio_cfg_output(8);
        nrf_gpio_pin_write(8,1);
        timers_init();
         buttons_init();
         ble_stack_init();
         device_manager_init(erase_bonds);
         gap_params_init();
         services_init();
         advertising_init();
         conn_params_init();
    
    // Start execution.
    err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED);
    APP_ERROR_CHECK(err_code);
    
    // Enter main loop.
    for (;;)
    {
        power_manage();
    }}
    

    BLE_ADVERTISING.C

                 uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode)
            {
              uint32_t             err_code;
           ble_gap_adv_params_t adv_params;
    
         m_adv_mode_current = advertising_mode;
    
    // Verify if there are any pending flash operations. If so, delay starting advertising until
    // the flash operations are complete.
    if(flash_access_in_progress())
    {
        m_advertising_start_pending = true;
        return NRF_SUCCESS;
    }
    
    ADV_LOG("[ADV]: no flash operations in progress, prepare advertising.\r\n");
    // Fetch the peer address.
    ble_advertising_peer_address_clear();
    
    if (  ((m_adv_modes_config.ble_adv_directed_enabled)      && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED))
        ||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED))
        ||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW))
       )
    {
        if (m_evt_handler != NULL)
        {
            m_peer_addr_reply_expected = true;
            m_evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
        }
        else
        {
            m_peer_addr_reply_expected = false;
        }
    }
    
    // If a mode is disabled, continue to the next mode. I.e fast instead of direct, slow instead of fast, idle instead of slow.
    if (  (m_adv_mode_current == BLE_ADV_MODE_DIRECTED)
        &&(!m_adv_modes_config.ble_adv_directed_enabled || !peer_address_exists(m_peer_address.addr)))
    {
        m_adv_mode_current = BLE_ADV_MODE_DIRECTED_SLOW;
    }
    if (  (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW)
        &&(!m_adv_modes_config.ble_adv_directed_slow_enabled || !peer_address_exists(m_peer_address.addr)))
    {
        m_adv_mode_current = BLE_ADV_MODE_FAST;
    }
    if (!m_adv_modes_config.ble_adv_fast_enabled && m_adv_mode_current == BLE_ADV_MODE_FAST)
    {
        m_adv_mode_current = BLE_ADV_MODE_SLOW;
    }
    if (!m_adv_modes_config.ble_adv_slow_enabled && m_adv_mode_current == BLE_ADV_MODE_SLOW)
    {
        m_adv_mode_current = BLE_ADV_MODE_IDLE;
        m_adv_evt          = BLE_ADV_EVT_IDLE;
    }
    
    // Fetch the whitelist.
    if (   (m_evt_handler != NULL)
        && (m_adv_mode_current == BLE_ADV_MODE_FAST || m_adv_mode_current == BLE_ADV_MODE_SLOW)
        && (m_adv_modes_config.ble_adv_whitelist_enabled)
        && (!m_whitelist_temporarily_disabled))
    {
        m_whitelist_reply_expected = true;
        m_evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
    }
    else
    {
        m_whitelist_reply_expected = false;
    }
    
    // Initialize advertising parameters with default values.
    memset(&adv_params, 0, sizeof(adv_params));
    
    adv_params.type        = BLE_GAP_ADV_TYPE_ADV_IND;
    adv_params.p_peer_addr = NULL;
    adv_params.fp          = BLE_GAP_ADV_FP_ANY;
    adv_params.p_whitelist = NULL;
    
    // Set advertising parameters and events according to selected advertising mode.
    switch (m_adv_mode_current)
    {
        case BLE_ADV_MODE_DIRECTED:
            ADV_LOG("[ADV]: Starting direct advertisement.\r\n");
            adv_params.p_peer_addr = &m_peer_address; // Directed advertising.
            adv_params.type        = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
            adv_params.timeout     = 0;
            adv_params.interval    = 0;
            m_adv_evt              = BLE_ADV_EVT_DIRECTED;
            break;
    
        case BLE_ADV_MODE_DIRECTED_SLOW:
            ADV_LOG("[ADV]: Starting direct advertisement.\r\n");
            adv_params.p_peer_addr = &m_peer_address; // Directed advertising.
            adv_params.type        = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
            adv_params.timeout     = m_adv_modes_config.ble_adv_directed_slow_timeout;
            adv_params.interval    = m_adv_modes_config.ble_adv_directed_slow_interval;
            m_adv_evt              = BLE_ADV_EVT_DIRECTED_SLOW;
            break;
    
        case BLE_ADV_MODE_FAST:
            adv_params.timeout  = m_adv_modes_config.ble_adv_fast_timeout;
            adv_params.interval = m_adv_modes_config.ble_adv_fast_interval;
    
            if (   whitelist_has_entries(&m_whitelist)
                && m_adv_modes_config.ble_adv_whitelist_enabled
                && !m_whitelist_temporarily_disabled)
            {
                adv_params.fp          = BLE_GAP_ADV_FP_FILTER_CONNREQ;
                adv_params.p_whitelist = &m_whitelist;
                m_advdata.flags        = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
                err_code               = ble_advdata_set(&m_advdata, NULL);
                VERIFY_SUCCESS(err_code);
    
                m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST;
                ADV_LOG("[ADV]: Starting fast advertisement with whitelist.\r\n");
            }
            else
            {
                m_adv_evt = BLE_ADV_EVT_FAST;
                ADV_LOG("[ADV]: Starting fast advertisement.\r\n");
            }
            break;
    
        case BLE_ADV_MODE_SLOW:
            adv_params.interval = m_adv_modes_config.ble_adv_slow_interval;
            adv_params.timeout  = m_adv_modes_config.ble_adv_slow_timeout;
    
            if (   whitelist_has_entries(&m_whitelist)
                && m_adv_modes_config.ble_adv_whitelist_enabled
                && !m_whitelist_temporarily_disabled)
            {
                adv_params.fp          = BLE_GAP_ADV_FP_FILTER_CONNREQ;
                adv_params.p_whitelist = &m_whitelist;
                m_advdata.flags        = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
                err_code               = ble_advdata_set(&m_advdata, NULL);
                VERIFY_SUCCESS(err_code);
    
                m_adv_evt = BLE_ADV_EVT_SLOW_WHITELIST;
                ADV_LOG("[ADV]: Starting slow advertisement with whitelist.\r\n");
            }
            else
            {
                m_adv_evt = BLE_ADV_EVT_SLOW;
                ADV_LOG("[ADV]: Starting slow advertisement.\r\n");
            }
            break;
    
        default:
            break;
    }
    if (m_adv_mode_current != BLE_ADV_MODE_IDLE)
    {
        err_code = sd_ble_gap_adv_start(&adv_params);
        VERIFY_SUCCESS(err_code);
    }
    if (m_evt_handler != NULL)
    {
        m_evt_handler(m_adv_evt);
    }
    
             return NRF_SUCCESS;
             }
    

    1-. I set BLE_ADV_MODE_DIRECTED as my advertising mode.

    2-. So if i look in the switch-case on ble_advertising.c, i can find this line --->

    adv_params.p_peer_addr = &m_peer_address;

    I supposed that this peer address is the one that i hav to populate with de ID of my central, isn't it? If it does, how do i do it??

  • Yes you are correct. Have you managed to confirm that only the central you allowed can connect ?

  • Yes i did.. but, when i load this code in the peripheral, it doesn't start to advertising.

    You said i'm correct, so, how do i populate the peer address in the central and in the peripheral?

  • @Antonio: You may need to check and make sure there is no error code return when you call the APIs. I suspect that there could be a incorrect configuration. You may want to add a breakpoint in the app_error_handler to see what cause assertion.

Related