Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

How to switch from connectable mode to beacon mode after disconnection

Currently I have been able to advertise and connect through debug app using nRF52 DK. My target is:

1. After the link is lost the bluetooth gets disconnected and at this time I want the DK to advertise in the beacon mode.

2. My purpose is that when some one with the app comes near I can send him the advertisement and the lost user can track the item.

How to implement this switch from connectable mode to beacon mode after disconnection

Parents Reply Children
  • void advertising_beacon_start(bool erase_bonds)
    {
    
       if (erase_bonds == true)
        {
            delete_bonds();
            // Advertising is started by PM_EVT_PEERS_DELETED_SUCEEDED event
        }
        else
        {
            ret_code_t err_code;
    
          err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
          APP_ERROR_CHECK(err_code);
    
          err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
          APP_ERROR_CHECK(err_code); 
    
        }
        
    }

    This is the advertising_beacon_start function and this is called in BLE_GAP_EVT_DISCONNECTED as follows

     
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
                
                 advertising_beacon_start(erase_bonds);
                 
                // LED indication will be changed when advertising starts.
                break;
    

    Please can you give a light on what is wrong here. If possible can you give a similiar example on how to tackle this problem. 

    Please get familiar with how you can stop and re-start advertising.

    can you give an example or link on how to familiarize with the same

  • Hi ,

    Please find the example attached. See how I added the advertising_init_beacon() with 

        adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED;

    and calling it inside BLE_GAP_EVT_DISCONNECTED  event. 

    When you see something doesn't work please try to debug it. You can use the UART log to see if there is any assert. And you can add DEBUG into the project's preprocessor symbols to have more information about the assert. 

  • Please find the example attached.

    I can't see the attached example. Can you attach the example once again!!

  • static void advertising_beacon_init(void)
    {
        uint32_t      err_code;
    
        ble_advdata_t advdata1;
        ble_advdata_t srdata1;
    
    
        memset(&advdata1, 0, sizeof(advdata1));
    
        advdata1.name_type          = BLE_ADVDATA_NO_NAME;
        advdata1.include_appearance = true;
        advdata1.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        memset(&srdata1, 0, sizeof(srdata1));
        srdata1.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        srdata1.uuids_complete.p_uuids  = m_adv_uuids;
    
        err_code = ble_advdata_encode(&advdata1, m_adv_data1.adv_data1.p_data1, &m_adv_data1.adv_data1.len1);
        APP_ERROR_CHECK(err_code);
    
        err_code = ble_advdata_encode(&srdata1, m_adv_data1.scan_rsp_data1.p_data1, &m_adv_data1.scan_rsp_data1.len1);
        APP_ERROR_CHECK(err_code);
        ble_gap_adv_params_t adv_params1;
    
        // Set advertising parameters.
        memset(&adv_params1, 0, sizeof(adv_params1));
    
        adv_params1.primary_phy     = BLE_GAP_PHY_1MBPS;
        adv_params1.duration        = APP_ADV_DURATION;
        adv_params1.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED;
        adv_params1.p_peer_addr     = NULL;
        adv_params1.filter_policy   = BLE_GAP_ADV_FP_ANY;
        adv_params1.interval        = APP_ADV_INTERVAL;
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle1, &m_adv_data1, &adv_params1);
        //APP_ERROR_CHECK(err_code);
       
        }
    
    
    /**@brief Function for initializing the Advertising functionality.
     */
    static void advertising_init(void)
    {
        ret_code_t             err_code;
        ble_advertising_init_t init;
    
       
        
       // ble_advdata_manuf_data_t manuf_specific_data;
        //manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
       
        memset(&init, 0, sizeof(init));
        
        ble_advdata_manuf_data_t                  manuf_data; //Variable to hold manufacturer specific data
        uint8_t data[]                            = {0x30,0x5F,0x1E,0xAe,0xEC,0x5E,0xE9}; //Our data to advertise
        manuf_data.company_identifier             =  0x4D4B; //Nordics company ID
        //manuf_data.hardware_type                  =  0x3;
        //manuf_data.bind_tag                       =  0x0;
        manuf_data.data.p_data                    = data;
        manuf_data.data.size                      = sizeof(data);
        init.advdata.p_manuf_specific_data        = &manuf_data;
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance      = true;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
        init.advdata.uuids_more_available.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_more_available.p_uuids  = m_adv_uuids;
        
        //init.advdata.p_manuf_specific_data   = &manuf_specific_data;
    
        init.config.ble_adv_on_disconnect_disabled = true;
        init.config.ble_adv_fast_enabled  = 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);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    
    
    
        
    }
    

    The code above is for advertising_init and advertising_beacon_init.

    static void advertising_beacon_start(void)
    {
        ret_code_t           err_code;
    
        
    
        err_code = sd_ble_gap_adv_start(m_adv_handle1, APP_BLE_CONN_CFG_TAG);
        NRF_LOG_INFO("BEACON_STARTED");
        APP_ERROR_CHECK(err_code);
        
    
    }
    
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(bool erase_bonds)
    {
        if (erase_bonds == true)
        {
            delete_bonds();
            // Advertising is started by PM_EVT_PEERS_DELETED_SUCEEDED event
        }
        else
        {
            ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    
            APP_ERROR_CHECK(err_code);
        }
    }

    this code is for advertising_start and advertising_beacon_start.

    ble_app_blinky_beacon.zip

    this example was really helpful in understanding the fundamentals, but still I am not able switch from connectable to beacon mode in my project. When I disconnect the advertisement goes back to connectable rather than going into beacon mode.

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t err_code = NRF_SUCCESS;
        bool erase_bonds;
        //pm_handler_secure_on_connection(p_ble_evt);
       
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
                sd_ble_gap_adv_stop(&m_advertising);
                app_timer_stop(m_adv_data_update_timer);
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                advertising_beacon_init();
                advertising_beacon_start();
                NRF_LOG_INFO("beacon_started");
                 

    Please see the code and give some light!!!

Related