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?

Parents
  • Just wanted to add, do you do a service_change and hence update the service list in the iOS app? The concern is that you've possibly already have bonded with the iOS app and the iOS app buffers this information and reads a characteristics that's not there or it's changed from what it originally was. The sniffer traces that seems to be ok, doesn't read 0xBB as value either. Try to remove the bond between phone and EK.

Reply
  • Just wanted to add, do you do a service_change and hence update the service list in the iOS app? The concern is that you've possibly already have bonded with the iOS app and the iOS app buffers this information and reads a characteristics that's not there or it's changed from what it originally was. The sniffer traces that seems to be ok, doesn't read 0xBB as value either. Try to remove the bond between phone and EK.

Children
Related