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

write only characteristic?

Hi, how to create a write only characteristic?

I have tried: ble_char_md.char_props.read = 0;

This does not work.

  • typedef struct
    {
      /* Standard properties */
      uint8_t broadcast       :1; /**< Broadcasting of the value permitted. */
      uint8_t read            :1; /**< Reading the value permitted. */
      uint8_t write_wo_resp   :1; /**< Writing the value with Write Command permitted. */
      uint8_t write           :1; /**< Writing the value with Write Request permitted. */
      uint8_t notify          :1; /**< Notications of the value permitted. */
      uint8_t indicate        :1; /**< Indications of the value permitted. */
      uint8_t auth_signed_wr  :1; /**< Writing the value with Signed Write Command permitted. */
    } ble_gatt_char_props_t;
    

    You need to add ble_char_md.char_props.write = 1;

  • My complete code for creating the characteristic:

    	{
    	/* ATT metadata */
    	ble_gatts_attr_md_t ble_attr_md;
    
    	memset(&ble_attr_md, 0, sizeof(ble_attr_md));
    
    	/* No security is required whatsoever, needs to be changed when encryption
    		        is added */
    	ble_attr_md.read_perm.lv = 1;
    	ble_attr_md.read_perm.sm = 1;
    	ble_attr_md.write_perm.lv = 1;
    	ble_attr_md.write_perm.sm = 1;
    
    	ble_attr_md.vloc = BLE_GATTS_VLOC_STACK;
    	ble_attr_md.rd_auth = 0;
    	ble_attr_md.wr_auth = 0;
    	ble_attr_md.vlen = 0;
    
    	/* BLE GATT metadata */
    	ble_gatts_char_md_t ble_char_md;
    
    	memset(&ble_char_md, 0, sizeof(ble_char_md));
    
    	ble_char_md.p_char_pf = NULL;
    	ble_char_md.char_props.read = 0;
    	ble_char_md.char_props.write = 1;
    	ble_char_md.char_props.write_wo_resp = 1;
    	ble_char_md.char_props.notify = 0;
    
    	ble_char_md.p_cccd_md = NULL;
    	ble_char_md.p_sccd_md = NULL;
    	ble_char_md.p_char_user_desc = NULL;
    	ble_char_md.p_user_desc_md = NULL;
    	uint8_t name[]="Crypto key";
    	ble_char_md.p_char_user_desc = name;
    	ble_char_md.char_user_desc_size=strlen((const char*)name);
    	ble_char_md.char_user_desc_max_size=strlen((const char*)name);
    
    	/* ble characteristic UUID */
    	ble_uuid_t ble_uuid;
    
    	ble_uuid.type = mesh_base_uuid_type;
    	ble_uuid.uuid = MESH_AES_KEY_UUID;
    
    	/* ble attribute */
    	ble_gatts_attr_t ble_attr;
    
    	memset(&ble_attr, 0, sizeof(ble_attr));
    
    	uint8_t key[16]={0};
    
    	ble_attr.init_offs = 0;
    	ble_attr.init_len = 16;
    	ble_attr.max_len = 16;
    	ble_attr.p_attr_md = &ble_attr_md;
    	ble_attr.p_uuid = &ble_uuid;
    	ble_attr.p_value = (uint8_t*)&key;
    
    	/* add to service */
    	ble_gatts_char_handles_t ble_value_char_handles;
    
    	error_code = sd_ble_gatts_characteristic_add(
    			g_mesh_service.service_handle,
    			&ble_char_md,
    			&ble_attr,
    			&ble_value_char_handles);
    

    }

    When connecting with master control I can write some data and then read the data. I do not want to be able to read the data.

  • @victor: Next time, please edit your question to add more information instead of posting it as an answer :)

    There are 2 sets of a characteristic attribute: permissions and properties. set char_props.read = 0 only set the property of the characteristic. You should also set the permission : read_perm.lv and read_perm.sm to zero. Please have a look at the macro BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS() in ble_gap.h

Related