Skip to content

Commit

Permalink
FuriHal,BleGlue: prevent sleep while HCI command executed, proper bt …
Browse files Browse the repository at this point in the history
…api rpc locking. Fixes random system lockups. (flipperdevices#3107)
  • Loading branch information
skotopes authored Sep 25, 2023
1 parent e1030e7 commit 63d7d46
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 16 deletions.
8 changes: 4 additions & 4 deletions applications/services/bt/bt_service/bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,13 +359,13 @@ static void bt_change_profile(Bt* bt, BtMessage* message) {
*message->result = false;
}
}
furi_event_flag_set(bt->api_event, BT_API_UNLOCK_EVENT);
api_lock_unlock(message->lock);
}

static void bt_close_connection(Bt* bt) {
static void bt_close_connection(Bt* bt, BtMessage* message) {
bt_close_rpc_connection(bt);
furi_hal_bt_stop_advertising();
furi_event_flag_set(bt->api_event, BT_API_UNLOCK_EVENT);
api_lock_unlock(message->lock);
}

int32_t bt_srv(void* p) {
Expand Down Expand Up @@ -432,7 +432,7 @@ int32_t bt_srv(void* p) {
} else if(message.type == BtMessageTypeSetProfile) {
bt_change_profile(bt, &message);
} else if(message.type == BtMessageTypeDisconnect) {
bt_close_connection(bt);
bt_close_connection(bt, &message);
} else if(message.type == BtMessageTypeForgetBondedDevices) {
bt_keys_storage_delete(bt->keys_storage);
}
Expand Down
11 changes: 7 additions & 4 deletions applications/services/bt/bt_service/bt_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ bool bt_set_profile(Bt* bt, BtProfile profile) {
// Send message
bool result = false;
BtMessage message = {
.type = BtMessageTypeSetProfile, .data.profile = profile, .result = &result};
.lock = api_lock_alloc_locked(),
.type = BtMessageTypeSetProfile,
.data.profile = profile,
.result = &result};
furi_check(
furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk);
// Wait for unlock
furi_event_flag_wait(bt->api_event, BT_API_UNLOCK_EVENT, FuriFlagWaitAny, FuriWaitForever);
api_lock_wait_unlock_and_free(message.lock);

return result;
}
Expand All @@ -19,11 +22,11 @@ void bt_disconnect(Bt* bt) {
furi_assert(bt);

// Send message
BtMessage message = {.type = BtMessageTypeDisconnect};
BtMessage message = {.lock = api_lock_alloc_locked(), .type = BtMessageTypeDisconnect};
furi_check(
furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk);
// Wait for unlock
furi_event_flag_wait(bt->api_event, BT_API_UNLOCK_EVENT, FuriFlagWaitAny, FuriWaitForever);
api_lock_wait_unlock_and_free(message.lock);
}

void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, void* context) {
Expand Down
4 changes: 2 additions & 2 deletions applications/services/bt/bt_service/bt_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <furi.h>
#include <furi_hal.h>
#include <api_lock.h>

#include <gui/gui.h>
#include <gui/view_port.h>
Expand All @@ -22,8 +23,6 @@

#define BT_KEYS_STORAGE_PATH INT_PATH(BT_KEYS_STORAGE_FILE_NAME)

#define BT_API_UNLOCK_EVENT (1UL << 0)

typedef enum {
BtMessageTypeUpdateStatus,
BtMessageTypeUpdateBatteryLevel,
Expand All @@ -48,6 +47,7 @@ typedef union {
} BtMessageData;

typedef struct {
FuriApiLock lock;
BtMessageType type;
BtMessageData data;
bool* result;
Expand Down
8 changes: 2 additions & 6 deletions applications/system/hid_app/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,9 +422,7 @@ int32_t hid_ble_app(void* p) {

furi_record_close(RECORD_STORAGE);

if(!bt_set_profile(app->bt, BtProfileHidKeyboard)) {
FURI_LOG_E(TAG, "Failed to switch to HID profile");
}
furi_check(bt_set_profile(app->bt, BtProfileHidKeyboard));

furi_hal_bt_start_advertising();
bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
Expand All @@ -442,9 +440,7 @@ int32_t hid_ble_app(void* p) {

bt_keys_storage_set_default_path(app->bt);

if(!bt_set_profile(app->bt, BtProfileSerial)) {
FURI_LOG_E(TAG, "Failed to switch to Serial profile");
}
furi_check(bt_set_profile(app->bt, BtProfileSerial));

hid_free(app);

Expand Down
2 changes: 2 additions & 0 deletions firmware/targets/f7/ble_glue/ble_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,11 @@ static void ble_app_hci_event_handler(void* pPayload) {

static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status) {
if(status == HCI_TL_CmdBusy) {
furi_hal_power_insomnia_enter();
furi_mutex_acquire(ble_app->hci_mtx, FuriWaitForever);
} else if(status == HCI_TL_CmdAvailable) {
furi_mutex_release(ble_app->hci_mtx);
furi_hal_power_insomnia_exit();
}
}

Expand Down
3 changes: 3 additions & 0 deletions firmware/targets/f7/furi_hal/furi_hal_bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <hsem_map.h>

#include <furi_hal_version.h>
#include <furi_hal_power.h>
#include <furi_hal_bt_hid.h>
#include <furi_hal_bt_serial.h>
#include <furi_hal_bus.c>
Expand Down Expand Up @@ -269,6 +270,7 @@ bool furi_hal_bt_start_app(FuriHalBtProfile profile, GapEventCallback event_cb,
}

void furi_hal_bt_reinit() {
furi_hal_power_insomnia_enter();
FURI_LOG_I(TAG, "Disconnect and stop advertising");
furi_hal_bt_stop_advertising();

Expand Down Expand Up @@ -298,6 +300,7 @@ void furi_hal_bt_reinit() {
furi_hal_bt_init();

furi_hal_bt_start_radio_stack();
furi_hal_power_insomnia_exit();
}

bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, void* context) {
Expand Down

0 comments on commit 63d7d46

Please sign in to comment.