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

How do I know that characteristic has been subscribed to?

I've tried getting a notification of subscription from a bluetooth event handler like so:

  1. ble_evt_dispatch() is being called from main:

     static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
     {
         on_ble_evt(p_ble_evt);
         ble_conn_params_on_ble_evt(p_ble_evt);
         ble_MY_SERVICE_on_ble_evt(&MY_SERVICE_handle, p_ble_evt); // <- My service's event handler
     }
    
  2. My service's event handler does some crude event matching:

     void ble_MY_SERVICE_on_ble_evt(MY_SERVICE_handle_t *MY_SERVICE_handle, ble_evt_t *p_ble_evt)
     {
         switch (p_ble_evt->header.evt_id)
         {
             case BLE_GAP_EVT_CONNECTED:
             case BLE_GAP_EVT_DISCONNECTED:
             ....
             case ???: {
                 ???
             } break;
         }
     }
    

At this point I'm stuck. When subscribing to a characteristic, p_ble_evt->header.evt_id equals to 0x0050, but since enums don't have explicit values in the code, I don't know which event this corresponds to and how to handle it.

And if I try and bruteforce it by hardcoding 0x0050 event handling, p_ble_evt->evt.gattc_evt.params.hvx.type always equals to 0xF1, which doesn't make sense since this parameter is of 'type' BLE_GATT_HVX_TYPES which can only be 0x00, 0x01 or 0x02, so I must be doing something wrong since I think its just garbage data.

  • I agree that it is a bit difficult to find out which event an ID corresponds to, but you can find out like this:

    • Open ble_ranges.h and scroll down to #define BLE_EVT_BASE
    • Look at your event id (0x0050) and find out which range this lies in. Scrolling a bit down in ble_ranges.h we see that BLE_GATTS_EVT_BASE starts at 0x50 and stops at 0x6F, so the id is a GATTS event.
    • Open ble_gatts.h and find out where BLE_GATTS_EVT_BASE is used
    • We see that BLE_GATTS_EVT_WRITE is defined as BLE_GATTS_EVT_BASE (0x50) and the succeeding events are increments of this. (if your code was 0x53 you would have to count down along the enum declarations, and would arrive at BLE_GATTS_EVT_HVC).

    So, what you are looking for in your switch-case is BLE_GATTS_EVT_WRITE. What happens when a device subscribes to a characteristic, it writes 1 to the characteristic CCCD handle. There are examples of catching this in most of the projects in the SDK. If you look in ble_app_hrs for example, you can see the following in the ble_hrs_on_ble_evt function:

     case BLE_GATTS_EVT_WRITE:
            on_write(p_hrs, p_ble_evt);
            break;
    

    Then the on_write function checks if it is a write to the cccd handle:

     static void on_write(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt){
    
          ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
          if (p_evt_write->handle == p_hrs->hrm_handles.cccd_handle){
             on_hrm_cccd_write(p_hrs, p_evt_write);
          }
     }
    

    and lastly the on_hrm_cccd_write function checks if notification has been enabled or disabled, and you can handle this acccordingly, in that function

  • Why won't SES ide follow the event definitions back to their base. If I right click on BLE_GATTS_EVT_WRITE and select go to definition I get to BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, from this point I put the cursor over the BLE_GATTS_EVT_BASE and do the same right click, go to definition, but the ide won't take me to the definition of BLE_GATTS_EVT_BASE, Why?? Even more confusing is that I can search the entire project/solution and BLE_GATTS_EVT_BASE doesn't show up!! Even though the ble_gap.h and ble_gatt.h files show up as Dependencies in the project tree.

Related