Skip to content

Commit 891e457

Browse files
MarkWangChinesekartben
authored andcommitted
bluetooth: classic: Fix remote name resolving with multiple devices
The error occur when discoverying br devices and need to send request_name for many found devices. In system work queue task, bt_hci_inquiry_complete-> report_discovery_results is called, then request_name is called for all the found devices. The controller gives HCI_Remote_Name_Request_Complete event for every name request result and one buf is allocated from hci_rx_pool to save HCI_Remote_Name_Request_Complete. When system work queue task is blocked to call request_name for every device, many HCI_Remote_Name_Request_Complete are received for the already sent request_name, it uses up all the buf of hci_rx_pool, then the bt_rx_thread task is blocked to get buf from hci_rx_pool when next HCI_Remote_Name_Request_Complete is received, meanwhile the next request_name send hci cmd and wait the result, but the hci status/complete event can't be received because the bt_rx_thread is blocked and bt_uart_isr is kept in the state to receive last HCI_Remote_Name_Request_Complete, then bt_dev.ncmd_sem is not released, then the next request_name send hci cmd again, but the bt_dev.ncmd_sem is invalid, then bt_hci_cmd_send_sync fail and assert. resolve it by requesting name one by one. Signed-off-by: Mark Wang <yichang.wang@nxp.com>
1 parent 48de4ab commit 891e457

File tree

2 files changed

+37
-18
lines changed
  • include/zephyr/bluetooth/classic
  • subsys/bluetooth/host/classic

2 files changed

+37
-18
lines changed

include/zephyr/bluetooth/classic/classic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct bt_br_discovery_priv {
4848
/** Page scan repetition mode */
4949
uint8_t pscan_rep_mode;
5050
/** Resolving remote name*/
51-
bool resolving;
51+
uint8_t resolve_state;
5252
};
5353

5454
/** @brief BR/EDR discovery result structure */

subsys/bluetooth/host/classic/br.c

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ LOG_MODULE_REGISTER(bt_br);
2424

2525
#define RSSI_INVALID 127
2626

27+
enum __packed resolve_name_state {
28+
RESOLVE_REMOTE_NAME_PENDING,
29+
RESOLVE_REMOTE_NAME_RESOLVING,
30+
RESOLVE_REMOTE_NAME_RESOLVED,
31+
};
32+
2733
struct bt_br_discovery_result *discovery_results;
2834
static size_t discovery_results_size;
2935
static size_t discovery_results_count;
@@ -327,11 +333,10 @@ void bt_br_discovery_reset(void)
327333
discovery_results_count = 0;
328334
}
329335

330-
static void report_discovery_results(void)
336+
static bool check_request_name(void)
331337
{
332-
bool resolving_names = false;
333338
int i;
334-
struct bt_br_discovery_cb *listener, *next;
339+
bool resolving_names = false;
335340

336341
for (i = 0; i < discovery_results_count; i++) {
337342
struct bt_br_discovery_priv *priv;
@@ -342,16 +347,37 @@ static void report_discovery_results(void)
342347
continue;
343348
}
344349

350+
if (priv->resolve_state != RESOLVE_REMOTE_NAME_PENDING) {
351+
continue;
352+
}
353+
345354
if (request_name(&discovery_results[i].addr, priv->pscan_rep_mode,
346355
priv->clock_offset)) {
356+
priv->resolve_state = RESOLVE_REMOTE_NAME_RESOLVED;
347357
continue;
348358
}
349359

350-
priv->resolving = true;
360+
priv->resolve_state = RESOLVE_REMOTE_NAME_RESOLVING;
351361
resolving_names = true;
362+
break;
363+
}
364+
365+
return resolving_names;
366+
}
367+
368+
static void report_discovery_results(void)
369+
{
370+
int i;
371+
struct bt_br_discovery_cb *listener, *next;
372+
373+
for (i = 0; i < discovery_results_count; i++) {
374+
struct bt_br_discovery_priv *priv;
375+
376+
priv = &discovery_results[i]._priv;
377+
priv->resolve_state = RESOLVE_REMOTE_NAME_PENDING;
352378
}
353379

354-
if (resolving_names) {
380+
if (check_request_name()) {
355381
return;
356382
}
357383

@@ -511,7 +537,6 @@ void bt_hci_remote_name_request_complete(struct net_buf *buf)
511537
struct bt_br_discovery_priv *priv;
512538
int eir_len = 240;
513539
uint8_t *eir;
514-
int i;
515540
struct bt_br_discovery_cb *listener, *next;
516541

517542
result = get_result_slot(&evt->bdaddr, RSSI_INVALID);
@@ -520,7 +545,7 @@ void bt_hci_remote_name_request_complete(struct net_buf *buf)
520545
}
521546

522547
priv = &result->_priv;
523-
priv->resolving = false;
548+
priv->resolve_state = RESOLVE_REMOTE_NAME_RESOLVED;
524549

525550
if (evt->status) {
526551
goto check_names;
@@ -572,15 +597,9 @@ void bt_hci_remote_name_request_complete(struct net_buf *buf)
572597
}
573598

574599
check_names:
575-
/* if still waiting for names */
576-
for (i = 0; i < discovery_results_count; i++) {
577-
struct bt_br_discovery_priv *dpriv;
578-
579-
dpriv = &discovery_results[i]._priv;
580-
581-
if (dpriv->resolving) {
582-
return;
583-
}
600+
/* if still need to request name */
601+
if (check_request_name()) {
602+
return;
584603
}
585604

586605
/* all names resolved, report discovery results */
@@ -982,7 +1001,7 @@ int bt_br_discovery_stop(void)
9821001

9831002
priv = &discovery_results[i]._priv;
9841003

985-
if (!priv->resolving) {
1004+
if (priv->resolve_state != RESOLVE_REMOTE_NAME_RESOLVING) {
9861005
continue;
9871006
}
9881007

0 commit comments

Comments
 (0)