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
  • 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!!!

  • Hi Vishnu, 

    You are mixing ble_advertising and the calling sd_ble_gap_adv directly.
    I would suggest to follow exactly what I did in the example. Only use sd_ble_gap_adv API and not the ble_advertising  module. 
    Note that I only used one advertising_start() function.

Related