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

Static Passkey didn't pop out input passkey window

Dear all,

I have struggled this problem over a week.

I am working on our product, which need to prevent other strangers to connect to our device. After search on the Nordic Q&A, I decided to use static passkey. But when I connected to " nRF Connect " on the PC, the device just connected immediately without popping out any window to input passkey.

What I use:

  • Chip: nRF52832
  • SDK: 15.2.0
  • Board: Custom Board
  • Base example: ble_app_template (Modified a lot. Since I need to add many other functions.)

Here as below are what I done so far:

  1. From this post I knew that  Glucose Application example may helped.
    I set the static in the peer_manager_init()
    #define SEC_PARAM_BOND                  1                                       /**< Perform bonding. */
    #define SEC_PARAM_MITM                  1                                       /**< Man In The Middle protection not required. */
    #define SEC_PARAM_LESC                  0                                       /**< LE Secure Connections not enabled. */
    #define SEC_PARAM_KEYPRESS              0                                       /**< Keypress notifications not enabled. */
    #define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_DISPLAY_ONLY                    /**< No I/O capabilities. */
    #define SEC_PARAM_OOB                   0                                       /**< Out Of Band data not available. */
    #define SEC_PARAM_MIN_KEY_SIZE          7                                       /**< Minimum encryption key size. */
    #define SEC_PARAM_MAX_KEY_SIZE          16                                      /**< Maximum encryption key size. */
    
    /**@brief Function for the Peer Manager initialization.
     */
    static void peer_manager_init(void)
    {
        ble_gap_sec_params_t sec_param;
        ret_code_t           err_code;
    
        err_code = pm_init();
        APP_ERROR_CHECK(err_code);
    
        memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
    
        // Security parameters to be used for all security procedures.
        sec_param.bond           = SEC_PARAM_BOND;
        sec_param.mitm           = SEC_PARAM_MITM;
        sec_param.lesc           = SEC_PARAM_LESC;
        sec_param.keypress       = SEC_PARAM_KEYPRESS;
        sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
        sec_param.oob            = SEC_PARAM_OOB;
        sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
        sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
        sec_param.kdist_own.enc  = 1;
        sec_param.kdist_own.id   = 1;
        sec_param.kdist_peer.enc = 1;
        sec_param.kdist_peer.id  = 1;
    
        err_code = pm_sec_params_set(&sec_param);
        APP_ERROR_CHECK(err_code);
    
        err_code = pm_register(pm_evt_handler);
        APP_ERROR_CHECK(err_code);
        
    		///////// what I change ////////////
    		uint8_t passkey[] = "123456";
    		ble_opt_t ble_opt;
    		ble_opt.gap_opt.passkey.p_passkey = &passkey[0];
    		err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &ble_opt);
    		APP_ERROR_CHECK(err_code); 
    		////////////////////////////////////
    }


  2. Reference to Glucose example, I also do some changes in advertising_init()
    /**@brief Function for initializing the Advertising functionality.
     */
    static void advertising_init(void)
    {
        ret_code_t             err_code;
        
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance      = true;
        ///////// what I change ////////////
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;		// BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE
        ////////////////////////////////////
        init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        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);
    		
    		err_code = app_timer_create(&m_advertising_timer,
    												        APP_TIMER_MODE_REPEATED,
    												        advertising_timer_handler);
    		APP_ERROR_CHECK(err_code);
    		
    }


  3. Above steps didn't work. So I found this post, modified the gap_params_init()
    /**@brief Function for the GAP initialization.
     *
     * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
     *          device including the device name, appearance, and the preferred connection parameters.
     */
    static void gap_params_init(void)
    {
        ret_code_t              err_code;
        ble_gap_conn_params_t   gap_conn_params;
        ble_gap_conn_sec_mode_t sec_mode;
    		
    		///////// what I change //////////////
        BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&sec_mode);	  //BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    		///////////////////////////////////////
    	
    	
    		// custom device name
    		if(record_read(CUSTOM_NAME_FILE_ID, CUSTOM_NAME_LENGTH_RECORD_ID, &custom_name_length)){
    				//nrf_gpio_pin_clear(LED_RED_PIN);
    				char devname_with_addr[custom_name_length];
    
    				record_read(CUSTOM_NAME_FILE_ID, CUSTOM_NAME_RECORD_ID, custom_name_from_fds);
    				
    				memcpy(devname_with_addr, custom_name_from_fds, custom_name_length);
    				
    				err_code = sd_ble_gap_device_name_set(&sec_mode,
    																							(const uint8_t *)devname_with_addr,
    																							strlen(devname_with_addr));
    				APP_ERROR_CHECK(err_code);
    		}
    		else{
    				err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *)DEFAULT_DEVICE_NAME,
                                              strlen(DEFAULT_DEVICE_NAME));
    				APP_ERROR_CHECK(err_code);
    		}    
    
    
        memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
        gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
        gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
        gap_conn_params.slave_latency     = SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    }
     

Hope someone can give me some advice (ಥ﹏ಥ)

Below is my whole ble connection code

#include "System.h"
#include "m_coms_btle.h"
#include "m_coms_btle_cfg.h"
#include "m_button.h"
/* m_coms_btle.c */

#include "ADS1231_spi.h"
#include "m_bat_meas.h"
#include "m_fds.h"
#include "m_pwr_mgmt.h"

/*  BLE  */
#include "ble.h"
#include "ble_hci.h"
#include "ble_srv_common.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "peer_manager.h"
#include "peer_manager_handler.h"
#include "sensorsim.h"
#include "ble_conn_state.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_qwr.h"
#include "nrf_pwr_mgmt.h"

/*  Service  */
#include "ble_bas.h"
//#include "ble_nus.h"

#define ADVERTISING_LED_INTERVAL 1000

static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;                        /**< Handle of the current connection. */

// NUS Service
BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT);                               /**< BLE NUS service instance. */

BLE_BAS_DEF(m_bas);		
NRF_BLE_GATT_DEF(m_gatt);                                                       /**< GATT module instance. */
BLE_ADVERTISING_DEF(m_advertising);                                             /**< Advertising module instance. */
NRF_BLE_QWR_DEF(m_qwr);                                                         /**< Context for the Queued Write module.*/

APP_TIMER_DEF(m_advertising_timer);

uint32_t custom_name_length;
uint32_t custom_name_from_fds[3];	

static ble_advertising_init_t init;


static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;                   /**< Advertising handle used to identify an advertising set. */
static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];                    /**< Buffer for storing an encoded advertising set. */
static uint8_t m_enc_scan_response_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX];         /**< Buffer for storing an encoded scan data. */

/**@brief Struct that contains pointers to the encoded advertising data. */
static ble_gap_adv_data_t m_adv_data =
{
    .adv_data =
    {
        .p_data = m_enc_advdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = m_enc_scan_response_data,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX

    }
};

/* YOUR_JOB: Declare all services structure your application is using
 *  BLE_XYZ_DEF(m_xyz);
 */

// YOUR_JOB: Use UUIDs for service(s) used in your application.
static ble_uuid_t m_adv_uuids[] =                                               /**< Universally unique service identifiers. */
{
    {BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}
};



/***************************************************************************
 *@brief GAP initialization.
 *@details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
 *         device including the device name, appearance, and the preferred connection parameters.
 ***************************************************************************/
void gap_devname_default(void)
{
	if(record_read(CUSTOM_NAME_FILE_ID, CUSTOM_NAME_LENGTH_RECORD_ID, &custom_name_length))
	{	
		file_delete(CUSTOM_NAME_FILE_ID);
		
		system_suspend_mode_enter(true);	
	}		
}


extern struct TrxEvt send_temp;

void gap_custom_device_name_set(uint8_t * name_char, uint8_t name_length){
		ret_code_t err_code;
		ble_advdata_t advdata;
		ble_gap_adv_params_t adv_params;
		ble_gap_conn_sec_mode_t sec_mode;
    BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&sec_mode);
	
		
    sd_ble_gap_adv_stop(m_adv_handle);
	
		custom_name_length = name_length;
		memcpy(custom_name_from_fds, name_char, name_length);
	
		uint16_t size;
		uint8_t dataArray[10];	
	
		sprintf((char *)dataArray, "%d", name_length);
		size = sizeof(name_length);
		send_temp.data = dataArray;
		send_temp.len = &size;
		ble_nus_send(send_temp);
		
		record_write(CUSTOM_NAME_FILE_ID, CUSTOM_NAME_LENGTH_RECORD_ID, &custom_name_length,  1);
		record_write(CUSTOM_NAME_FILE_ID, CUSTOM_NAME_RECORD_ID, custom_name_from_fds, custom_name_length);
	
		system_suspend_mode_enter(true);
}


void advertising_stop(void)
{
			ret_code_t err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle);
			APP_ERROR_CHECK(err_code);
}


/**@brief Function for the GAP initialization.
 *
 * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
 *          device including the device name, appearance, and the preferred connection parameters.
 */
static void gap_params_init(void)
{
    ret_code_t              err_code;
    ble_gap_conn_params_t   gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;
		
		///////// what I change //////////////
    BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&sec_mode);	  //BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
		///////////////////////////////////////
	
	
		// custom device name
		if(record_read(CUSTOM_NAME_FILE_ID, CUSTOM_NAME_LENGTH_RECORD_ID, &custom_name_length)){
				//nrf_gpio_pin_clear(LED_RED_PIN);
				char devname_with_addr[custom_name_length];

				record_read(CUSTOM_NAME_FILE_ID, CUSTOM_NAME_RECORD_ID, custom_name_from_fds);
				
				memcpy(devname_with_addr, custom_name_from_fds, custom_name_length);
				
				err_code = sd_ble_gap_device_name_set(&sec_mode,
																							(const uint8_t *)devname_with_addr,
																							strlen(devname_with_addr));
				APP_ERROR_CHECK(err_code);
		}
		else{
				err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *)DEFAULT_DEVICE_NAME,
                                          strlen(DEFAULT_DEVICE_NAME));
				APP_ERROR_CHECK(err_code);
		}    


    memset(&gap_conn_params, 0, sizeof(gap_conn_params));

    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency     = SLAVE_LATENCY;
    gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;

    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the GATT module.
 */
static void gatt_init(void)
{
    ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
    APP_ERROR_CHECK(err_code);
	
		err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
    APP_ERROR_CHECK(err_code);
}



/**@brief Function for putting the chip into sleep mode.
 *
 * @note This function will not return.
 */
static void sleep_mode_enter(void)
{
    ret_code_t err_code;

    //err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    //APP_ERROR_CHECK(err_code);

    // Prepare wakeup buttons.
    //err_code = bsp_btn_ble_sleep_mode_prepare();
    //APP_ERROR_CHECK(err_code);

    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
}



/**@brief Function for handling advertising events.
 *
 * @details This function will be called for advertising events which are passed to the application.
 *
 * @param[in] ble_adv_evt  Advertising event.
 */
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{

    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            NRF_LOG_INFO("Fast advertising.");
            break;

        case BLE_ADV_EVT_IDLE:
            sleep_mode_enter();
            break;

        default:
            break;
    }
}


static void advertising_timer_handler(void * p_context)
{
		nrf_gpio_pin_toggle(LED_BLUE_PIN);
}



/**@brief Function for initializing the Advertising functionality.
 */
static void advertising_init(void)
{
    ret_code_t             err_code;
    

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

    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;		// BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE
    init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.advdata.uuids_complete.p_uuids  = m_adv_uuids;

    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);
		
		err_code = app_timer_create(&m_advertising_timer,
												        APP_TIMER_MODE_REPEATED,
												        advertising_timer_handler);
		APP_ERROR_CHECK(err_code);
		
}





/***************************************************************************
 *@brief Initialize Queued Write Module.
 *@details
 ***************************************************************************/
#if  NRF_MODULE_ENABLED(NRF_BLE_QWR)

/**@brief Function for handling Queued Write Module errors.
 *
 * @details A pointer to this function will be passed to each service which may need to inform the
 *          application about an error.
 *
 * @param[in]   nrf_error   Error code containing information about what went wrong.
 */
static void nrf_qwr_error_handler(uint32_t nrf_error)
{
    APP_ERROR_HANDLER(nrf_error);
}

static void qwr_init(void)
{
		uint32_t       err_code;
    nrf_ble_qwr_init_t qwr_init;

    // Initialize Queued Write Module.
		memset(&qwr_init, 0, sizeof(qwr_init));
    
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);
}
#endif

/***************************************************************************
 *@brief Initialize Battery services.
 *@details
 ***************************************************************************/
#if NRF_MODULE_ENABLED(BLE_BAS)
void ble_battery_level_update(uint8_t battery_level)
{
		ble_bas_battery_level_update(&m_bas,battery_level,m_conn_handle);			
}

static void bas_init(void)
{
		uint32_t       err_code;
    ble_bas_init_t bas_init;
	
    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    bas_init.bl_rd_sec        = SEC_OPEN;
    bas_init.bl_cccd_wr_sec   = SEC_OPEN;
    bas_init.bl_report_rd_sec = SEC_OPEN;

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);
}
#endif




/***************************************************************************
 *@brief Initialize NUS services.
 *@details
 ***************************************************************************/

void ble_nus_send(const struct TrxEvt evt){
		uint32_t err_code;
		err_code = ble_nus_data_send(&m_nus, evt.data, evt.len, m_conn_handle);
		if ((err_code != NRF_ERROR_INVALID_STATE) &&
        (err_code != NRF_ERROR_RESOURCES) &&
        (err_code != NRF_ERROR_NOT_FOUND))
    {
        APP_ERROR_CHECK(err_code);
    }
}


#if NRF_MODULE_ENABLED(BLE_NUS)

void Jmex_nus_init(void (*nus_handler)(ble_nus_evt_t * p_evt)){
		uint32_t       err_code;
    ble_nus_init_t nus_init;
	
    // Initialize NUS Service.
    memset(&nus_init, 0, sizeof(nus_init));

    nus_init.data_handler = nus_handler;

    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
}

#endif

/**@brief Function for initializing services that will be used by the application.
 */
static void services_init(void)
{
#if NRF_MODULE_ENABLED(NRF_BLE_QWR)
		qwr_init();
#endif
    	
#if NRF_MODULE_ENABLED(BLE_BAS)
		bas_init();
#endif
		
}




/**@brief Function for handling the Connection Parameters Module.
 *
 * @details This function will be called for all events in the Connection Parameters Module which
 *          are passed to the application.
 *          @note All this function does is to disconnect. This could have been done by simply
 *                setting the disconnect_on_fail config parameter, but instead we use the event
 *                handler mechanism to demonstrate its use.
 *
 * @param[in] p_evt  Event received from the Connection Parameters Module.
 */
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
{
    ret_code_t err_code;

    if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
        err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
        APP_ERROR_CHECK(err_code);
    }
}


/**@brief Function for handling a Connection Parameters error.
 *
 * @param[in] nrf_error  Error code containing information about what went wrong.
 */
static void conn_params_error_handler(uint32_t nrf_error)
{
    APP_ERROR_HANDLER(nrf_error);
}


/**@brief Function for initializing the Connection Parameters module.
 */
static void conn_params_init(void)
{
    ret_code_t             err_code;
    ble_conn_params_init_t cp_init;

    memset(&cp_init, 0, sizeof(cp_init));

    cp_init.p_conn_params                  = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail             = false;
    cp_init.evt_handler                    = on_conn_params_evt;
    cp_init.error_handler                  = conn_params_error_handler;

    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for handling Peer Manager events.
 *
 * @param[in] p_evt  Peer Manager event.
 */
static void pm_evt_handler(pm_evt_t const * p_evt)
{
    pm_handler_on_pm_evt(p_evt);
    pm_handler_flash_clean(p_evt);

    switch (p_evt->evt_id)
    {
        case PM_EVT_PEERS_DELETE_SUCCEEDED:
            advertising_start(false);
            break;

        default:
            break;
    }
}



/**@brief Function for the Peer Manager initialization.
 */
static void peer_manager_init(void)
{
    ble_gap_sec_params_t sec_param;
    ret_code_t           err_code;

    err_code = pm_init();
    APP_ERROR_CHECK(err_code);

    memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));

    // Security parameters to be used for all security procedures.
    sec_param.bond           = SEC_PARAM_BOND;
    sec_param.mitm           = SEC_PARAM_MITM;
    sec_param.lesc           = SEC_PARAM_LESC;
    sec_param.keypress       = SEC_PARAM_KEYPRESS;
    sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
    sec_param.oob            = SEC_PARAM_OOB;
    sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
    sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
    sec_param.kdist_own.enc  = 1;
    sec_param.kdist_own.id   = 1;
    sec_param.kdist_peer.enc = 1;
    sec_param.kdist_peer.id  = 1;

    err_code = pm_sec_params_set(&sec_param);
    APP_ERROR_CHECK(err_code);

    err_code = pm_register(pm_evt_handler);
    APP_ERROR_CHECK(err_code);
		
		uint8_t passkey[] = "123456";
		ble_opt_t ble_opt;
		ble_opt.gap_opt.passkey.p_passkey = &passkey[0];
		err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &ble_opt);
		APP_ERROR_CHECK(err_code); 
}


/**@brief Clear bond information from persistent storage.
 */
static void delete_bonds(void)
{
    ret_code_t err_code;

    NRF_LOG_INFO("Erase bonds!");

    err_code = pm_peers_delete();
    APP_ERROR_CHECK(err_code);
}



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

        APP_ERROR_CHECK(err_code);
    }
		err_code = app_timer_start(m_advertising_timer, APP_TIMER_TICKS(ADVERTISING_LED_INTERVAL), NULL);
		APP_ERROR_CHECK(err_code);
}



/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t err_code = NRF_SUCCESS;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected.");
						ADS1231_stop();
						err_code = app_timer_start(m_advertising_timer, APP_TIMER_TICKS(ADVERTISING_LED_INTERVAL), NULL);
						APP_ERROR_CHECK(err_code);
						
            break;

        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("Connected.");
				
						// check calibration status
						check_calibrated(0);
						// battery test
						app_timer_stop(m_advertising_timer);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
            APP_ERROR_CHECK(err_code);
						nrf_gpio_pin_set(LED_BLUE_PIN);
            break;

        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            NRF_LOG_DEBUG("PHY update request.");
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;

        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            NRF_LOG_DEBUG("GATT Client Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            NRF_LOG_DEBUG("GATT Server Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        default:
            // No implementation needed.
            break;
    }
}



/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupt.
 */
void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);

    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}

void ble_stack_params_init(void){
		// Initialize GAP parameters.
    gap_params_init();
	  // Initialize GATT parameters.	
    gatt_init();
		// Default advertising setting.
		advertising_init();	
		// Initialize BLE services.
    services_init();
		// Initialize connection parameters.	
    conn_params_init();	
		// Initialize peer manager.		
	  peer_manager_init();
		
}

Parents
  • Hello,

    You might be mixing that security is made up of two configurations:

    - The security capabilities of the device, which is typically handled during peer_manager_init().
    - The security requirements for the services and chacteristics in your GATT database, which is typically handled during services_init().

    If all services and characteristics are configured with BLE_GAP_CONN_SEC_MODE_SET_OPEN/SEC_OPEN, then the peer may not see any need to elevate the security of the link when established. In your case you can for instance (for test) elevate the security requirements for bas_init(). The GAP params I believe must always be OPEN by spec.

    Best regards,
    Kenneth

  • Thanks for quick reply!

    Did you mean the peer would elevate the security only if there are some characteristics(no need to be all) configured with higher security ?

    Btw I modified the bas_init(), but nothing change.

    static void bas_init(void)
    {
    	uint32_t       err_code;
        ble_bas_init_t bas_init;
    	
        // Initialize Battery Service.
        memset(&bas_init, 0, sizeof(bas_init));
    
        // Here the sec level for the Battery Service can be changed/increased.
        bas_init.bl_rd_sec        = SEC_MITM;
        bas_init.bl_cccd_wr_sec   = SEC_MITM;
        bas_init.bl_report_rd_sec = SEC_MITM;
    
        bas_init.evt_handler          = NULL;
        bas_init.support_notification = true;
        bas_init.p_report_ref         = NULL;
        bas_init.initial_batt_level   = 100;
    
        err_code = ble_bas_init(&m_bas, &bas_init);
        APP_ERROR_CHECK(err_code);
    }

  • Since said:
    Did you mean the peer would elevate the security only if there are some characteristics(no need to be all) configured with higher security ?

    It's only required to elevate the security in that case (, some may do it anyways).

    I believe if you are using the nRF Connect for Desktop BLE app, you need to trigger the security manually:
    https://infocenter.nordicsemi.com/topic/ug_nrfconnect_ble/UG/nRF_Connect_BLE/nRF_Connect_Pairing_devices.html 

  • Hi Kenneth,

    I try to manual pairing, here are something I found.

    1. When I run  Glucose Application example on the pca10040, nRF connect will auto pop out the passkey window. So I guess maybe it's possible that I won't need to manual pairing ?

    2. In my case, before I manual paired on nRF Connect, the nus service will work(it isn't supposed happened. I want users able to use the device only after they input the right passkey.) And after I paired and entered the passkey, the program was stuck. I couldn't control my device.
  • 1. It's possible to make the application to trigger security by adding in ble_evt_handler() a call to pm_handler_secure_on_connection(). The "manual" pairing you experience without it is a result of nRF Connect for Desktop is not really a product meant for end customers, it is a tool for debugging and development. So it does not give the same UX as when used with for instance iOS, Android or Windows native BT.

    2.

    Since said:
    In my case, before I manual paired on nRF Connect, the nus service will work(it isn't supposed happened. I want users able to use the device only after they input the right passkey.)

    That is likely because you have not set any security requirements on the characteristics in services_init().

Reply
  • 1. It's possible to make the application to trigger security by adding in ble_evt_handler() a call to pm_handler_secure_on_connection(). The "manual" pairing you experience without it is a result of nRF Connect for Desktop is not really a product meant for end customers, it is a tool for debugging and development. So it does not give the same UX as when used with for instance iOS, Android or Windows native BT.

    2.

    Since said:
    In my case, before I manual paired on nRF Connect, the nus service will work(it isn't supposed happened. I want users able to use the device only after they input the right passkey.)

    That is likely because you have not set any security requirements on the characteristics in services_init().

Children
No Data
Related