From a02781b93687086f546df1a48f7f0ca3f7724c5a Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:18:14 +0900 Subject: [PATCH] [FL-3920] Fix lost BadBLE keystrokes (#3993) * WIP: fix lost BadBLE keystrokes * Switch to semaphores for synchronization * Move checking to the gap level * Remove leftovers from hid_service * Remove more leftovers from hid_service * De-allocate the semaphore after use * Change the timeout to account for unforeseen situation * Update F18 API * Fix naming and unbump api version * Move away from semaphores * Remove the left over include * Ble: cleanup error handling in ble_gatt_characteristic_update * Fix PVS warning Co-authored-by: Aleksandr Kutuzov --- lib/ble_profile/extra_services/hid_service.c | 14 ++++---- lib/nfc/protocols/mf_plus/mf_plus_poller.c | 4 +-- lib/subghz/protocols/bin_raw.c | 2 +- targets/f7/ble_glue/furi_ble/gatt.c | 34 +++++++++++++++++--- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lib/ble_profile/extra_services/hid_service.c b/lib/ble_profile/extra_services/hid_service.c index e46d2010c52..9f9a0f7520e 100644 --- a/lib/ble_profile/extra_services/hid_service.c +++ b/lib/ble_profile/extra_services/hid_service.c @@ -10,13 +10,13 @@ #define TAG "BleHid" #define BLE_SVC_HID_REPORT_MAP_MAX_LEN (255) -#define BLE_SVC_HID_REPORT_MAX_LEN (255) -#define BLE_SVC_HID_REPORT_REF_LEN (2) -#define BLE_SVC_HID_INFO_LEN (4) -#define BLE_SVC_HID_CONTROL_POINT_LEN (1) +#define BLE_SVC_HID_REPORT_MAX_LEN (255) +#define BLE_SVC_HID_REPORT_REF_LEN (2) +#define BLE_SVC_HID_INFO_LEN (4) +#define BLE_SVC_HID_CONTROL_POINT_LEN (1) -#define BLE_SVC_HID_INPUT_REPORT_COUNT (3) -#define BLE_SVC_HID_OUTPUT_REPORT_COUNT (0) +#define BLE_SVC_HID_INPUT_REPORT_COUNT (3) +#define BLE_SVC_HID_OUTPUT_REPORT_COUNT (0) #define BLE_SVC_HID_FEATURE_REPORT_COUNT (0) #define BLE_SVC_HID_REPORT_COUNT \ (BLE_SVC_HID_INPUT_REPORT_COUNT + BLE_SVC_HID_OUTPUT_REPORT_COUNT + \ @@ -157,6 +157,7 @@ static BleEventAckStatus ble_svc_hid_event_handler(void* event, void* context) { hci_event_pckt* event_pckt = (hci_event_pckt*)(((hci_uart_pckt*)event)->data); evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data; // aci_gatt_attribute_modified_event_rp0* attribute_modified; + if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) { if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { // Process modification events @@ -274,6 +275,7 @@ bool ble_svc_hid_update_input_report( .data_ptr = data, .data_len = len, }; + return ble_gatt_characteristic_update( hid_svc->svc_handle, &hid_svc->input_report_chars[input_report_num], &report_data); } diff --git a/lib/nfc/protocols/mf_plus/mf_plus_poller.c b/lib/nfc/protocols/mf_plus/mf_plus_poller.c index 8d1cc1c99a2..57a26a9cf7b 100644 --- a/lib/nfc/protocols/mf_plus/mf_plus_poller.c +++ b/lib/nfc/protocols/mf_plus/mf_plus_poller.c @@ -146,7 +146,7 @@ static void mf_plus_poller_set_callback( static NfcCommand mf_plus_poller_run(NfcGenericEvent event, void* context) { furi_assert(context); - furi_assert(event.protocol = NfcProtocolIso14443_4a); + furi_assert(event.protocol == NfcProtocolIso14443_4a); furi_assert(event.event_data); MfPlusPoller* instance = context; @@ -178,7 +178,7 @@ void mf_plus_poller_free(MfPlusPoller* instance) { static bool mf_plus_poller_detect(NfcGenericEvent event, void* context) { furi_assert(context); - furi_assert(event.protocol = NfcProtocolIso14443_4a); + furi_assert(event.protocol == NfcProtocolIso14443_4a); furi_assert(event.event_data); MfPlusPoller* instance = context; diff --git a/lib/subghz/protocols/bin_raw.c b/lib/subghz/protocols/bin_raw.c index 8298bce6b06..c2aebb6aba5 100644 --- a/lib/subghz/protocols/bin_raw.c +++ b/lib/subghz/protocols/bin_raw.c @@ -314,8 +314,8 @@ SubGhzProtocolStatus flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); if(!subghz_protocol_encoder_bin_raw_get_upload(instance)) { - break; res = SubGhzProtocolStatusErrorEncoderGetUpload; + break; } instance->encoder.is_running = true; diff --git a/targets/f7/ble_glue/furi_ble/gatt.c b/targets/f7/ble_glue/furi_ble/gatt.c index e407865833c..b8ab094f96c 100644 --- a/targets/f7/ble_glue/furi_ble/gatt.c +++ b/targets/f7/ble_glue/furi_ble/gatt.c @@ -7,6 +7,12 @@ #define GATT_MIN_READ_KEY_SIZE (10) +#ifdef BLE_GATT_STRICT +#define ble_gatt_strict_crash(message) furi_crash(message) +#else +#define ble_gatt_strict_crash(message) +#endif + void ble_gatt_characteristic_init( uint16_t svc_handle, const BleGattCharacteristicParams* char_descriptor, @@ -42,6 +48,7 @@ void ble_gatt_characteristic_init( &char_instance->handle); if(status) { FURI_LOG_E(TAG, "Failed to add %s char: %d", char_descriptor->name, status); + ble_gatt_strict_crash("Failed to add characteristic"); } char_instance->descriptor_handle = 0; @@ -68,6 +75,7 @@ void ble_gatt_characteristic_init( &char_instance->descriptor_handle); if(status) { FURI_LOG_E(TAG, "Failed to add %s char descriptor: %d", char_descriptor->name, status); + ble_gatt_strict_crash("Failed to add characteristic descriptor"); } if(release_data) { free((void*)char_data); @@ -82,6 +90,7 @@ void ble_gatt_characteristic_delete( if(status) { FURI_LOG_E( TAG, "Failed to delete %s char: %d", char_instance->characteristic->name, status); + ble_gatt_strict_crash("Failed to delete characteristic"); } free((void*)char_instance->characteristic); } @@ -111,14 +120,27 @@ bool ble_gatt_characteristic_update( release_data = char_descriptor->data.callback.fn(context, &char_data, &char_data_size); } - tBleStatus result = aci_gatt_update_char_value( - svc_handle, char_instance->handle, 0, char_data_size, char_data); - if(result) { - FURI_LOG_E(TAG, "Failed updating %s characteristic: %d", char_descriptor->name, result); - } + tBleStatus result; + size_t retries_left = 1000; + do { + retries_left--; + result = aci_gatt_update_char_value( + svc_handle, char_instance->handle, 0, char_data_size, char_data); + if(result == BLE_STATUS_INSUFFICIENT_RESOURCES) { + FURI_LOG_W(TAG, "Insufficient resources for %s characteristic", char_descriptor->name); + furi_delay_ms(1); + } + } while(result == BLE_STATUS_INSUFFICIENT_RESOURCES && retries_left); + if(release_data) { free((void*)char_data); } + + if(result != BLE_STATUS_SUCCESS) { + FURI_LOG_E(TAG, "Failed updating %s characteristic: %d", char_descriptor->name, result); + ble_gatt_strict_crash("Failed to update characteristic"); + } + return result != BLE_STATUS_SUCCESS; } @@ -132,6 +154,7 @@ bool ble_gatt_service_add( Service_UUID_Type, Service_UUID, Service_Type, Max_Attribute_Records, Service_Handle); if(result) { FURI_LOG_E(TAG, "Failed to add service: %x", result); + ble_gatt_strict_crash("Failed to add service"); } return result == BLE_STATUS_SUCCESS; @@ -141,6 +164,7 @@ bool ble_gatt_service_delete(uint16_t svc_handle) { tBleStatus result = aci_gatt_del_service(svc_handle); if(result) { FURI_LOG_E(TAG, "Failed to delete service: %x", result); + ble_gatt_strict_crash("Failed to delete service"); } return result == BLE_STATUS_SUCCESS;