Skip to content

Commit 48a6094

Browse files
zhongzhijie1PavelVPV
authored andcommitted
[nrf fromtree] Bluetooth: Host: Fix handling of adv reports when scanning for connection
In some cases, the host starts scanning internally for establishing connections (BT_LE_SCAN_USER_CONN), such as host-based resolving or auto-connection. In this situation, even if the application does not start explicit scan, the host still needs to handle the advertising reports to continue the connection process. Previously, both bt_hci_le_adv_report() and bt_hci_le_adv_ext_report() will break or discard all reports when explicit scan is not active. This causes the connection to stay in SCAN_BEFORE_INITIATING and never move forward. This patch adds checking of BT_LE_SCAN_USER_CONN to allow advertising reports to be processed during connection-purpose scanning. When the scan is started explicitly by application, the behavior remains the same, only small comments are updated to describe this behavior and keep the original code style unchanged. Signed-off-by: Zhijie Zhong <[email protected]> (cherry picked from commit 87e351f) Signed-off-by: Pavel Vasilyev <[email protected]>
1 parent b3575ba commit 48a6094

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

subsys/bluetooth/host/scan.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -632,13 +632,14 @@ static void le_adv_recv(bt_addr_le_t *addr, struct bt_le_scan_recv_info *info,
632632
struct bt_le_scan_cb *listener, *next;
633633
struct net_buf_simple_state state;
634634
bt_addr_le_t id_addr;
635+
bool explicit_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN);
636+
bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN);
635637

636638
LOG_DBG("%s event %u, len %u, rssi %d dBm", bt_addr_le_str(addr), info->adv_type, len,
637639
info->rssi);
638640

639641
if (!IS_ENABLED(CONFIG_BT_PRIVACY) && !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
640-
atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN) &&
641-
(info->adv_props & BT_HCI_LE_ADV_PROP_DIRECT)) {
642+
explicit_scan && (info->adv_props & BT_HCI_LE_ADV_PROP_DIRECT)) {
642643
LOG_DBG("Dropped direct adv report");
643644
return;
644645
}
@@ -652,6 +653,13 @@ static void le_adv_recv(bt_addr_le_t *addr, struct bt_le_scan_recv_info *info,
652653
bt_lookup_id_addr(BT_ID_DEFAULT, addr));
653654
}
654655

656+
/* For connection-purpose scanning,
657+
* skip app callbacks but allow pending-conn check logic.
658+
*/
659+
if (!explicit_scan && conn_scan) {
660+
goto check_pending_conn;
661+
}
662+
655663
if (scan_dev_found_cb) {
656664
net_buf_simple_save(buf, &state);
657665

@@ -677,6 +685,7 @@ static void le_adv_recv(bt_addr_le_t *addr, struct bt_le_scan_recv_info *info,
677685
/* Clear pointer to this stack frame before returning to calling function */
678686
info->addr = NULL;
679687

688+
check_pending_conn:
680689
#if defined(CONFIG_BT_CENTRAL)
681690
check_pending_conn(&id_addr, addr, info->adv_props);
682691
#endif /* CONFIG_BT_CENTRAL */
@@ -805,6 +814,8 @@ static void create_ext_adv_info(struct bt_hci_evt_le_ext_advertising_info const
805814
void bt_hci_le_adv_ext_report(struct net_buf *buf)
806815
{
807816
uint8_t num_reports = net_buf_pull_u8(buf);
817+
bool explicit_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN);
818+
bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN);
808819

809820
LOG_DBG("Adv number of reports %u", num_reports);
810821

@@ -817,19 +828,23 @@ void bt_hci_le_adv_ext_report(struct net_buf *buf)
817828
bool more_to_come;
818829
bool is_new_advertiser;
819830

820-
if (!atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN)) {
831+
if (!explicit_scan) {
821832
/* The application has not requested explicit scan, so it is not expecting
822833
* advertising reports. Discard, and reset the reassembler if not inactive
823834
* This is done in the loop as this flag can change between each iteration,
824835
* and it is not uncommon that scanning is disabled in the callback called
825-
* from le_adv_recv
836+
* from le_adv_recv.
837+
*
838+
* However, if scanning is running for connection purposes,
839+
* the report shall still be processed to allow pending connections.
826840
*/
827-
828841
if (reassembling_advertiser.state != FRAG_ADV_INACTIVE) {
829842
reset_reassembling_advertiser();
830843
}
831844

832-
break;
845+
if (!conn_scan) {
846+
break;
847+
}
833848
}
834849

835850
if (buf->len < sizeof(*evt)) {
@@ -1669,18 +1684,23 @@ void bt_hci_le_adv_report(struct net_buf *buf)
16691684
{
16701685
uint8_t num_reports = net_buf_pull_u8(buf);
16711686
struct bt_hci_evt_le_advertising_info *evt;
1687+
bool explicit_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN);
1688+
bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN);
16721689

16731690
LOG_DBG("Adv number of reports %u", num_reports);
16741691

16751692
while (num_reports--) {
16761693
struct bt_le_scan_recv_info adv_info;
16771694

1678-
if (!atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN)) {
1695+
if (!explicit_scan && !conn_scan) {
16791696
/* The application has not requested explicit scan, so it is not expecting
16801697
* advertising reports. Discard.
16811698
* This is done in the loop as this flag can change between each iteration,
16821699
* and it is not uncommon that scanning is disabled in the callback called
1683-
* from le_adv_recv
1700+
* from le_adv_recv.
1701+
*
1702+
* However, if scanning is running for connection purposes,
1703+
* the report shall still be processed to allow pending connections.
16841704
*/
16851705

16861706
break;

0 commit comments

Comments
 (0)