bt: Fix race condition when disconnect during TX (#1260)
* bt: Fix race condition when disconnect during TX * bt: Move flag clear to not be in middle of other logic * bt: Bail out of send bytes a little bit earlier Co-authored-by: gornekich <n.gorbadey@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
eb83b0f02a
commit
f90c9320d9
16
applications/bt/bt_service/bt.c
Executable file → Normal file
16
applications/bt/bt_service/bt.c
Executable file → Normal file
@ -167,7 +167,11 @@ 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);
|
if(osEventFlagsGet(bt->rpc_event) & BT_RPC_EVENT_DISCONNECTED) {
|
||||||
|
// Early stop from sending if we're already disconnected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED));
|
||||||
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;
|
||||||
@ -178,10 +182,14 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt
|
|||||||
furi_hal_bt_serial_tx(&bytes[bytes_sent], bytes_remain);
|
furi_hal_bt_serial_tx(&bytes[bytes_sent], bytes_remain);
|
||||||
bytes_sent += bytes_remain;
|
bytes_sent += bytes_remain;
|
||||||
}
|
}
|
||||||
uint32_t event_flag =
|
// We want BT_RPC_EVENT_DISCONNECTED to stick, so don't clear
|
||||||
osEventFlagsWait(bt->rpc_event, BT_RPC_EVENT_ALL, osFlagsWaitAny, osWaitForever);
|
uint32_t event_flag = osEventFlagsWait(
|
||||||
|
bt->rpc_event, BT_RPC_EVENT_ALL, osFlagsWaitAny | osFlagsNoClear, osWaitForever);
|
||||||
if(event_flag & BT_RPC_EVENT_DISCONNECTED) {
|
if(event_flag & BT_RPC_EVENT_DISCONNECTED) {
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
// If we didn't get BT_RPC_EVENT_DISCONNECTED, then clear everything else
|
||||||
|
osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,6 +205,8 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) {
|
|||||||
bt->status = BtStatusConnected;
|
bt->status = BtStatusConnected;
|
||||||
BtMessage message = {.type = BtMessageTypeUpdateStatus};
|
BtMessage message = {.type = BtMessageTypeUpdateStatus};
|
||||||
furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK);
|
furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK);
|
||||||
|
// Clear BT_RPC_EVENT_DISCONNECTED because it might be set from previous session
|
||||||
|
osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED);
|
||||||
if(bt->profile == BtProfileSerial) {
|
if(bt->profile == BtProfileSerial) {
|
||||||
// Open RPC session
|
// Open RPC session
|
||||||
bt->rpc_session = rpc_session_open(bt->rpc);
|
bt->rpc_session = rpc_session_open(bt->rpc);
|
||||||
|
Loading…
Reference in New Issue
Block a user