This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

pm_conn_secure does NOT timeout when Central does not initiate bonding

Hello:

I have been at this problem for days now and not getting anywhere to a solution. My app is using  a static passkey for encryption and does timeout after 30 seconds if no key is received from the central when using the nRFconnect app as it should. Our central app uses BlueGiga dongle and BlueGiga has their own GUI app that can be used for testing. when using Bluegiga app and not enabling bonding, my app still connects and still transmits data and does NOT timeout and therefore bypassing the whole security feature. I know that the passkey is passed through the boding process but how can I force my app to disconnect if the central does not wanna bond? I am using SDK 15 and softdevice 6.00. any help would be greatly appreciated. 

Here is my peer manger init function

#define SEC_PARAM_BOND                  1                                           /**< Perform bonding. */
#define SEC_PARAM_MITM                  1                                           /**< Man In The Middle protection required (applicable when display module is detected). */
#define SEC_PARAM_LESC                  0                                           /**< LE Secure Connections enabled. */
#define SEC_PARAM_KEYPRESS              0                                           /**< Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_DISPLAY_ONLY                /**< Display 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. */

I did try with SEC_PARAM_LESC set to 1 and made no difference.

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;

		static uint8_t passkey[] = "000000";
		
    static ble_opt_t m_ble_opt;
    m_ble_opt.gap_opt.passkey.p_passkey = &passkey[0];   
		
		err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY,&m_ble_opt);
    APP_ERROR_CHECK(err_code);
		
    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);
}

static uint32_t standard_acquisition_char_add(ble_acq_mode_service_t * p_acq_mode_service, ble_acq_mode_service_init_t const * p_acq_mode_service_init)
{
    /**@snippet [Adding proprietary characteristic to the SoftDevice] */
		uint32_t            err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;
	
		
		memset(&cccd_md, 0, sizeof(cccd_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);

    cccd_md.vloc = BLE_GATTS_VLOC_STACK;
	
		memset(&char_md, 0, sizeof(char_md));
		
		char_md.char_props.read 	= 1;
		char_md.char_props.write 	= 1;
    char_md.char_props.notify = 1;
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
		char_md.p_cccd_md         = &cccd_md;
    char_md.p_sccd_md         = NULL;
	
		memset(&attr_md, 0, sizeof(attr_md));
		
//		attr_md.read_perm  = p_acq_mode_service_init->acq_mode_service_value_char_attr_md.read_perm; 
//    attr_md.write_perm = p_acq_mode_service_init->acq_mode_service_value_char_attr_md.write_perm;

//    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
//    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    
    BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(&attr_md.write_perm);

		attr_md.vloc    = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth = 0;
    attr_md.wr_auth = 0;
    attr_md.vlen    = 1;
		
		ble_uuid.type = p_acq_mode_service->uuid_type;
    ble_uuid.uuid = BLE_UUID_STANDARD_FUNCTION_CHARACTERISTIC_UUID;
		
		memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = sizeof(uint8_t);
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = 20;
		
		err_code =  sd_ble_gatts_characteristic_add(p_acq_mode_service->service_handle,
                                           &char_md,
                                           &attr_char_value,
                                           &p_acq_mode_service->standard_char_handle );
		
		if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    return NRF_SUCCESS;

    /**@snippet [Adding proprietary characteristic to the SoftDevice] */
}

static void services_init(void)
{
    uint32_t           							err_code;
    nrf_ble_qwr_init_t 							qwr_init = {0};
		
		ble_acq_mode_service_init_t     acq_mode_service_init;
		ble_dfu_init_t 									dfus_init = {0};
		
		ble_dis_init_t     							dis_init;
    
		// Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);
    
		memset(&acq_mode_service_init, 0, sizeof(acq_mode_service_init));

		acq_mode_service_init.evt_handler = on_acq_mode_service_evt;

//		BLE_GAP_CONN_SEC_MODE_SET_OPEN(&acq_mode_service_init.acq_mode_service_value_char_attr_md.read_perm);
//		BLE_GAP_CONN_SEC_MODE_SET_OPEN(&acq_mode_service_init.acq_mode_service_value_char_attr_md.write_perm);
    
    BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM (&acq_mode_service_init.acq_mode_service_value_char_attr_md.read_perm);
		BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM (&acq_mode_service_init.acq_mode_service_value_char_attr_md.write_perm);
		
		err_code = ble_acq_mode_service_init(&m_acq_mode_service, &acq_mode_service_init);
    APP_ERROR_CHECK(err_code);
		
#ifndef DEBUG
    // Initialize the async SVCI interface to bootloader.
    err_code = ble_dfu_async_svci_init();
    APP_ERROR_CHECK(err_code);
#endif

    dfus_init.evt_handler = ble_dfu_evt_handler;

    err_code = ble_dfu_init(&dfus_init);
    APP_ERROR_CHECK(err_code);
		
		// Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME);

    ble_srv_ascii_to_utf8(&dis_init.serial_num_str, MODEL_NUMBER);

    ble_dis_sys_id_t system_id;
    system_id.manufacturer_id            = MANUFACTURER_ID;
    system_id.organizationally_unique_id = ORG_UNIQUE_ID;
    dis_init.p_sys_id                    = &system_id;

//    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
//    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);
    
    BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);

}

Parents
  • Hi Wael, 

    In Bluetooth spec, there isn't a requirement of the link have to be encrypted after certain amount of time. What defined in the spec is that certain characteristics/services would requires the link to be encrypted at certain level so that the value of the attributes can be read/write. 

    In your case I assume you do have characteristics that require encryption ? And what you want to do is that on top of that requirement you also want to disconnect the central if the central doesn't do bonding at a certain time ? 

    If you want to do that, you would need to start a timer after the Connected event. And if after a certain time (30s for example) there isn't an event telling that the link is encrypted (BLE_GAP_EVT_CONN_SEC_UPDATE) the timer will timeout and disconnect the link. This should be done in the application. 

  • Hi Hung:

    I have implemented the timer and it seems to work as expected. But how do i prevent the central from reading my service characteristics during the 30 sec timer?  I am using BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM macro and it isn't working as expected. Again, Thanks for all your help!!

  • No. Please post the code where you this macro: BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM

    The whole function, where you configure and add the characteristic in. 

  • that is in standard_acquisition_char_add and services_init I already posted

  • Hi Wael, 

    Thanks for pointing me to the function. Could you double check that the central can read the value of the characteristic when the link is not encrypted ? 

    In our example we have the ble_app_proximity example that has characteristics require encryption for reading. Please try to test reading the TX power value or writing to the  alert level without bonding to check if you see the same issue ? 

  • Hung:

    I have checked multiple times and the central app is able to view, read, write all characteristics. I also wait well over the 30 seconds to see if the app would disconnect. The central informs that the bonding has failed but yet I can read/write the characteristics. we are using our own in house build board and it would take some considerable amount of work to try and test the example. Is there any other suggestions you may have? Again, Thanks for your help

    Regards,

  • Hi Wael, 


    It's very strange. Could you please record a sniffer trace

    Please test with the ble_app_proximity. It doesn't require you to have any special board, it should run on any board. You may need to configure the LFCLK source if you don't have  a 32kHz crystal. 

    You can also send your code here so we can test. Please make sure you disable any external requirements so it can run on a DK. You can convert this case to private case if there is any confidential information you don't want to be in the public. 

     

Reply
  • Hi Wael, 


    It's very strange. Could you please record a sniffer trace

    Please test with the ble_app_proximity. It doesn't require you to have any special board, it should run on any board. You may need to configure the LFCLK source if you don't have  a 32kHz crystal. 

    You can also send your code here so we can test. Please make sure you disable any external requirements so it can run on a DK. You can convert this case to private case if there is any confidential information you don't want to be in the public. 

     

Children
No Data
Related