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

Interesting sniffer behavior with a custom service

I was playing around with examples and decided to implement a custom service that sends the RSSI as a single-byte characteristic value. Here's the init function:

static uint32_t rssi_char_add(ble_rssis_t * p_rssis, const ble_rssis_init_t * p_rssis_init)
{
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;
	rssi_val_t					dummy_rssi_val = 0xBB;

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

// BLE_GAP_CONN_SEC_MODE_SET_OPEN() Allows the client to read/write this char on demand.
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.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 = p_rssis->uuid_type;
ble_uuid.uuid = SAS_UUID_RSSI_CHAR;

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

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
attr_md.vloc       = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth    = 0;
attr_md.wr_auth    = 0;
attr_md.vlen       = 0;

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(rssi_val_t);
attr_char_value.init_offs    = 0;
attr_char_value.max_len      = sizeof(rssi_val_t);

	p_rssis->rssi_level_last 		 = dummy_rssi_val;
	attr_char_value.p_value      = (void*)&(p_rssis->rssi_level_last);
	
	

return sd_ble_gatts_characteristic_add(p_rssis->service_handle, 
                                       &char_md,
                                       &attr_char_value,
                                       &p_rssis->rssi_level_handles);
}

I noticed that the value was not updating if I had notifications turned off by default... A sniffer trace (attachments) revealed the following:

  • When indications were disabled on init, all read requests of the rssi char value (handle 0x0015) by the master were rejected, with an "Invalid Handle" error
  • Whenever I kept the indications disabled, but also added a SIG service (LLS), reads requests from the master for the RSSI characteristic (handle 0x0015) were honored.

In both cases, the code for my custom service stayed exactly the same. I was using the iOS master control app to read characteristic values and communicate with the EvalKit.

Any insight as to what's going on? it seems as though the SIG service has an additional API call that I need to be able to read the RSSI characteristic value.

traces.zip

BONUS QUESTION!!! Why does the handle to my custom characteristic/service (0x0015) never change even though I add and remove other services? it is somehow computed from the UUID?

Related