diff --git a/applications/bt/bt_service/bt.c b/applications/bt/bt_service/bt.c index 64966570..296f5593 100755 --- a/applications/bt/bt_service/bt.c +++ b/applications/bt/bt_service/bt.c @@ -4,6 +4,10 @@ #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) { furi_assert(context); @@ -75,7 +79,7 @@ Bt* bt_alloc() { // RPC bt->rpc = furi_record_open("rpc"); - bt->rpc_sem = osSemaphoreNew(1, 0, NULL); + bt->rpc_event = osEventFlagsNew(NULL); return bt; } @@ -97,7 +101,7 @@ static void bt_on_data_sent_callback(void* context) { furi_assert(context); Bt* bt = context; - osSemaphoreRelease(bt->rpc_sem); + osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); } // 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); Bt* bt = context; + osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL); size_t bytes_sent = 0; while(bytes_sent < bytes_len) { 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); 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; furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); } else if(event.type == BleEventTypeDisconnected) { - FURI_LOG_I(TAG, "Close RPC connection"); 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); + furi_hal_bt_set_data_event_callbacks(0, NULL, NULL, NULL); bt->rpc_session = NULL; } } else if(event.type == BleEventTypeStartAdvertising) { diff --git a/applications/bt/bt_service/bt_i.h b/applications/bt/bt_service/bt_i.h index 3921a4c5..698dee1e 100644 --- a/applications/bt/bt_service/bt_i.h +++ b/applications/bt/bt_service/bt_i.h @@ -51,5 +51,5 @@ struct Bt { Power* power; Rpc* rpc; RpcSession* rpc_session; - osSemaphoreId_t rpc_sem; + osEventFlagsId_t rpc_event; }; diff --git a/applications/rpc/rpc.c b/applications/rpc/rpc.c index 450daaee..fa39699f 100644 --- a/applications/rpc/rpc.c +++ b/applications/rpc/rpc.c @@ -354,6 +354,7 @@ void rpc_session_close(RpcSession* session) { rpc_session_set_send_bytes_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); } @@ -409,7 +410,6 @@ void rpc_session_set_buffer_is_empty_callback( RpcSession* session, RpcBufferIsEmptyCallback callback) { furi_assert(session); - furi_assert(callback); furi_assert(session->rpc->busy); osMutexAcquire(session->callbacks_mutex, osWaitForever);