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

sd_ble_gatts_characteristic_add Error (Encryption)

Hello all, I have found closed topics here with similar names (devzone.nordicsemi.com/.../ etc.) but my question is about adding the characteristic with encryption. My device is nrf51822 s130. I want to create encrypted link with the central by NUS (Nordic Uart Service).

I added service and want to add TX characteristic with:

	char_md.char_props.write            = 1;
	char_md.char_props.write_wo_resp    = 1;
...
	BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);

and call sd_ble_gatts_characteristic_add that successfully finished. I've tested encryption by sending packets from central with and without bonding, without being bonded my device didn't receive the packets. So I think encryption works on this direction.

The different situation is with RX characteristic (full code). I want to notify to peer central.

   memset(&cccd_md, 0, sizeof(cccd_md));
    	/*BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM*/
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); //**But why???**
     	BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
    	cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    	memset(&char_md, 0, sizeof(char_md));
    	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;
    
    	ble_uuid.type             = gs_central.uuid_type;
    	ble_uuid.uuid             = BLE_UUID_NUS_RX_CHARACTERISTIC;
    	memset(&attr_md, 0, sizeof(attr_md));
    	BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
    	BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_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;
    	
    	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   = BLE_MAX_DATA_LEN;
    	
    	if ((err_code=sd_ble_gatts_characteristic_add(gs_central.service_handle, &char_md, &attr_char_value, &gs_central.rx_handles)) != NRF_SUCCESS){
    		DBG("sd_ble_gatts_characteristic_add RX: %d\n",err_code);
    		return;
    	}

The error NRF_ERROR_INVALID_PARAM occured during sd_ble_gatts_characteristic_add wthen cccd_md.read_perm set to be encrypted.

BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.read_perm); 

when no encryption chosen ( BLE_GAP_CONN_SEC_MODE_SET_OPEN ) there are no error.

The question #1 is why the error occured?

The question #2 : Could RX direction of link be considered encrypted with BLE_GAP_CONN_SEC_MODE_SET_OPEN on cccd_md.read_perm?

Best regards,

  • In your characteristic you have a characteristic value and a CCCD descriptor.

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); // The CCCD can be read BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm); // The CCCD can only be written if the link is encrypted

    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm); // The characteristic value can only be read if the link is encrypted BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm); // The characteristic value can only be written if the link is encrypted

    It is the characteristic values that contain your information you want to encrypt, the CCCD doesn't include any secret information. It just determines if the characteristic value can be notified(0x0001), indicated(0x0002), if not it is 0x0000

    I'm not sure why can't require encryption to read the CCCD, but my best guess is that it is defined in the Bluetooth Core specification. I can look into it if you want, let me know.

  • Finding things in the Bluetooth spec can be really hard sometimes. However i finally tracked it down to

    Specification V4.2, volume 3, part G, section 3.3.3.3 where it does indeed state about the CCCD

    Attribute Permissions
    
    Readable with no authentication or authorisation.
    Writable with authentication and authorization defined by a higher layer specification or is implementation specific.
    
  • Many thanks, now it's clear. Also the quote from "3.3.3.3 Client Characteristic Configuration" could be usefull for others:

    "Authentication and authorization may be required by the server to write the configuration descriptor. The Client Characteristic Configuration declaration shall be readable and writable."

Related