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
  • By indications, I'll assume you mean notifications, since that is the characteristic property you have enabled.

    It seems you are only discovering attribute handles 0x0000 to 0x0008.

    Are you able to see your RSSI characteristic with handle 0x0015 in LightBlue on the iOS device?

    Can you test this in Master Control Panel for Windows as well?

    Please edit your question to include the information.

  • As I understood it, the difference between notifications and Indications was that notifications have an ACK, while indications do not. I was hoping to use indications for data that asynchronously changes, but I don't care if the master receives every single update. Hence I wanted to not have an ACK to reduce traffic & power usage.

    However, this thread: devzone.nordicsemi.com/.../ seems to have a different explanation for the distinction between the two.

    Since the stock master control panel app is likely not sending an application level ACK, am I correct in assuming that it cannot work with only indications enabled?

Reply
  • As I understood it, the difference between notifications and Indications was that notifications have an ACK, while indications do not. I was hoping to use indications for data that asynchronously changes, but I don't care if the master receives every single update. Hence I wanted to not have an ACK to reduce traffic & power usage.

    However, this thread: devzone.nordicsemi.com/.../ seems to have a different explanation for the distinction between the two.

    Since the stock master control panel app is likely not sending an application level ACK, am I correct in assuming that it cannot work with only indications enabled?

Children
No Data
Related