Skip to content

Commit 72f5cce

Browse files
committed
[nrf fromtree] mgmt: mcumgr: transport: smp_bt: Fix deadlock on disconnect with data
This fixes an issue with the bluetooth transport whereby if a device drops the connection prior to receiving all the output data it could cause a deadlock. Signed-off-by: Jamie McCrae <[email protected]> (cherry picked from commit 7bab5c1)
1 parent c5340c1 commit 72f5cce

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

subsys/mgmt/mcumgr/transport/smp_bt.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,13 +387,30 @@ static int smp_bt_tx_pkt(struct net_buf *nb)
387387
.data = nb->data,
388388
};
389389
bool sent = false;
390+
struct bt_conn_info info;
390391

391392
conn = smp_bt_conn_from_pkt(nb);
392393
if (conn == NULL) {
393394
rc = MGMT_ERR_ENOENT;
394395
goto cleanup;
395396
}
396397

398+
/* Verify that the device is connected, the necessity for this check is that the remote
399+
* device might have sent a command and disconnected before the command has been processed
400+
* completely, if this happens then the the connection details will still be valid due to
401+
* the incremented connection reference count, but the connection has actually been
402+
* dropped, this avoids waiting for a semaphore that will never be given which would
403+
* otherwise cause a deadlock.
404+
*/
405+
rc = bt_conn_get_info(conn, &info);
406+
407+
if (rc != 0 || info.state != BT_CONN_STATE_CONNECTED) {
408+
/* Remote device has disconnected */
409+
bt_conn_unref(conn);
410+
rc = MGMT_ERR_ENOENT;
411+
goto cleanup;
412+
}
413+
397414
/* Send data in chunks of the MTU size */
398415
mtu_size = smp_bt_get_mtu(nb);
399416

@@ -414,7 +431,6 @@ static int smp_bt_tx_pkt(struct net_buf *nb)
414431
notify_param.len = mtu_size;
415432

416433
rc = bt_gatt_notify_cb(conn, &notify_param);
417-
k_sem_take(&smp_notify_sem, K_FOREVER);
418434

419435
if (rc == -ENOMEM) {
420436
if (sent == false) {
@@ -443,7 +459,10 @@ static int smp_bt_tx_pkt(struct net_buf *nb)
443459
off += mtu_size;
444460
notify_param.data = &nb->data[off];
445461
sent = true;
462+
463+
k_sem_take(&smp_notify_sem, K_FOREVER);
446464
} else {
465+
/* No connection, cannot continue */
447466
rc = MGMT_ERR_EUNKNOWN;
448467
break;
449468
}

0 commit comments

Comments
 (0)