esp32-course
esp32-course copied to clipboard
_19_6_Client_GAPP: Timer Stop command never issued
In _19_6_Client_GAPP the timer remains running even when a client unsubscribes.
This behaviour does not match the tutorial.
My solution is to update the ble_gap_event BLE_GAP_EVENT_SUBSRIBE case to:
case BLE_GAP_EVENT_SUBSCRIBE:
ESP_LOGI("GAP", "BLE_GAP_EVENT_SUBSCRIBE");
// Event is on the Battery Characteristic
if(event->subscribe.attr_handle == batt_char_att_hdl){
printf("SUBBED TO BATTERY %u \n", event->subscribe.cur_notify);
if(event->subscribe.cur_notify == 1) { // notifications switched on
xTimerStart(batt_update_timer_handler, 0);
}
else if(event->subscribe.cur_notify == 0){ // notifictions switched off
xTimerStop(batt_update_timer_handler, 0);
}
}
break;
I have encountered the same issue. I implemented the fix in a similar way like yours. The only difference is that I updated config[0]. I don't think that is needed. I did it anyway.
(My code)
case BLE_GAP_EVENT_SUBSCRIBE:
ESP_LOGI("GAP", "BLE_GAP_EVENT_SUBSCRIBE");
if(event->subscribe.attr_handle == batt_char_attr_hdl) // Check if it is the battery level char.
{
ESP_LOGI("GAP", "(ble_gap_event) current notify flag is %d",event->subscribe.cur_notify);
if(event->subscribe.cur_notify)
{
if (config[0] == 0) {
ESP_LOGI("GAP", "(ble_gap_event) Enable notification since it is clear.");
config[0] = 0x01;
}
}
else
{
if (config[0] == 0x01) {
ESP_LOGI("GAP", "(ble_gap_event) Disable notification since it is set.");
config[0] = 0;
}
}
if(config[0] == 0x01) { // only if the notification is enabled.
ESP_LOGI("GAP", "(ble_gap_event) Start the timer.");
xTimerStart(timer_handler, 0); // if it is, start the timer to update the battery level.
}else {
ESP_LOGI("GAP", "(ble_gap_event) Stop the timer.");
xTimerStop(timer_handler, 0);
}
}
break;
I also found another problem. When I switched from notification to read, the battery level is fixed at 50 (not correct). I made a small change to use the global updated variable battry in the battry_level subroutine.
static int battry_level(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
ESP_LOGI("GATT", "(battry_level) BLE Battery level read.");
os_mbuf_append(ctxt->om, &battry, sizeof(battry));
return 0;
}
It is a good example. It needs updated to work with other mobile BLE apps (nRF Connect, Bluefruit, LightBlue) that do not allow me to write directly to the battery client configuration descriptor directly. It seems that the teacher has an app that does.
Best, Michael
Hi Phil,
I checked Espressif's standard Heart Rate measurement BLE peripheral. It follows your approach. I think you did the right way.
https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/nimble/blehr
case BLE_GAP_EVENT_SUBSCRIBE:
MODLOG_DFLT(INFO, "subscribe event; cur_notify=%d\n value handle; "
"val_handle=%d\n",
event->subscribe.cur_notify, hrs_hrm_handle);
if (event->subscribe.attr_handle == hrs_hrm_handle) {
notify_state = event->subscribe.cur_notify;
blehr_tx_hrate_reset();
} else if (event->subscribe.attr_handle != hrs_hrm_handle) {
notify_state = event->subscribe.cur_notify;
blehr_tx_hrate_stop();
}
ESP_LOGI("BLE_GAP_SUBSCRIBE_EVENT", "conn_handle from subscribe=%d", conn_handle);
break;