Fix incorrect RPC session termination on BLE disconnect #828

This commit is contained in:
gornekich 2021-11-17 21:15:58 +03:00 committed by GitHub
parent 6792e24b6e
commit cc044c5033
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 6 deletions

View File

@ -4,6 +4,10 @@
#define TAG "BtSrv" #define TAG "BtSrv"
#define BT_RPC_EVENT_BUFF_SENT (1UL << 0)
#define BT_RPC_EVENT_DISCONNECTED (1UL << 1)
#define BT_RPC_EVENT_ALL (BT_RPC_EVENT_BUFF_SENT | BT_RPC_EVENT_DISCONNECTED)
static void bt_draw_statusbar_callback(Canvas* canvas, void* context) { static void bt_draw_statusbar_callback(Canvas* canvas, void* context) {
furi_assert(context); furi_assert(context);
@ -75,7 +79,7 @@ Bt* bt_alloc() {
// RPC // RPC
bt->rpc = furi_record_open("rpc"); bt->rpc = furi_record_open("rpc");
bt->rpc_sem = osSemaphoreNew(1, 0, NULL); bt->rpc_event = osEventFlagsNew(NULL);
return bt; return bt;
} }
@ -97,7 +101,7 @@ static void bt_on_data_sent_callback(void* context) {
furi_assert(context); furi_assert(context);
Bt* bt = context; Bt* bt = context;
osSemaphoreRelease(bt->rpc_sem); osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT);
} }
// Called from RPC thread // Called from RPC thread
@ -105,6 +109,7 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt
furi_assert(context); furi_assert(context);
Bt* bt = context; Bt* bt = context;
osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL);
size_t bytes_sent = 0; size_t bytes_sent = 0;
while(bytes_sent < bytes_len) { while(bytes_sent < bytes_len) {
size_t bytes_remain = bytes_len - bytes_sent; size_t bytes_remain = bytes_len - bytes_sent;
@ -115,7 +120,11 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt
furi_hal_bt_tx(&bytes[bytes_sent], bytes_remain); furi_hal_bt_tx(&bytes[bytes_sent], bytes_remain);
bytes_sent += bytes_remain; bytes_sent += bytes_remain;
} }
osSemaphoreAcquire(bt->rpc_sem, osWaitForever); uint32_t event_flag =
osEventFlagsWait(bt->rpc_event, BT_RPC_EVENT_ALL, osFlagsWaitAny, osWaitForever);
if(event_flag & BT_RPC_EVENT_DISCONNECTED) {
break;
}
} }
} }
@ -149,9 +158,11 @@ static void bt_on_gap_event_callback(BleEvent event, void* context) {
message.data.battery_level = info.charge; message.data.battery_level = info.charge;
furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK);
} else if(event.type == BleEventTypeDisconnected) { } else if(event.type == BleEventTypeDisconnected) {
FURI_LOG_I(TAG, "Close RPC connection");
if(bt->rpc_session) { if(bt->rpc_session) {
FURI_LOG_I(TAG, "Close RPC connection");
osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED);
rpc_session_close(bt->rpc_session); rpc_session_close(bt->rpc_session);
furi_hal_bt_set_data_event_callbacks(0, NULL, NULL, NULL);
bt->rpc_session = NULL; bt->rpc_session = NULL;
} }
} else if(event.type == BleEventTypeStartAdvertising) { } else if(event.type == BleEventTypeStartAdvertising) {

View File

@ -51,5 +51,5 @@ struct Bt {
Power* power; Power* power;
Rpc* rpc; Rpc* rpc;
RpcSession* rpc_session; RpcSession* rpc_session;
osSemaphoreId_t rpc_sem; osEventFlagsId_t rpc_event;
}; };

View File

@ -354,6 +354,7 @@ void rpc_session_close(RpcSession* session) {
rpc_session_set_send_bytes_callback(session, NULL); rpc_session_set_send_bytes_callback(session, NULL);
rpc_session_set_close_callback(session, NULL); rpc_session_set_close_callback(session, NULL);
rpc_session_set_buffer_is_empty_callback(session, NULL);
osEventFlagsSet(session->rpc->events, RPC_EVENT_DISCONNECT); osEventFlagsSet(session->rpc->events, RPC_EVENT_DISCONNECT);
} }
@ -409,7 +410,6 @@ void rpc_session_set_buffer_is_empty_callback(
RpcSession* session, RpcSession* session,
RpcBufferIsEmptyCallback callback) { RpcBufferIsEmptyCallback callback) {
furi_assert(session); furi_assert(session);
furi_assert(callback);
furi_assert(session->rpc->busy); furi_assert(session->rpc->busy);
osMutexAcquire(session->callbacks_mutex, osWaitForever); osMutexAcquire(session->callbacks_mutex, osWaitForever);