-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bluetooth: scan: Implement non-blocking ext-adv report reassembly #78982
base: main
Are you sure you want to change the base?
Changes from all commits
e83a24b
b53a010
2d9357b
93e6e13
90d264b
a0a3d57
db675f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,6 +161,8 @@ static inline enum bt_buf_type bt_buf_get_type(struct net_buf *buf) | |
->type; | ||
} | ||
|
||
struct net_buf *bt_buf_get_evt_but_better(uint8_t evt, uint8_t meta, k_timeout_t timeout); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose we'd want to deprecate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes. I made this to allow a soft-migration. Now that I think of it, I should update There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed. Found (and fixed) a bug in the process, yay. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I assume that it's planned that @alwa-nordic will take over and finalize this? If not, we should create a GH issue for it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alwa-nordic will take over, that is the plan. |
||
|
||
/** | ||
* @} | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -431,6 +431,29 @@ static void prio_recv_thread(void *p1, void *p2, void *p3) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
static bool node_to_evt(struct node_rx_pdu *node_rx, uint8_t *evt, uint8_t *meta) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if defined(CONFIG_BT_OBSERVER) && defined(CONFIG_BT_EXT_ADV) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
switch (node_rx->hdr.type) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case NODE_RX_TYPE_EXT_1M_REPORT: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case NODE_RX_TYPE_EXT_2M_REPORT: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case NODE_RX_TYPE_EXT_CODED_REPORT: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*evt = BT_HCI_EVT_LE_META_EVENT; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*meta = BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case NODE_RX_TYPE_EXT_SCAN_TERMINATE: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*evt = BT_HCI_EVT_LE_META_EVENT; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*meta = BT_HCI_EVT_LE_SCAN_TIMEOUT; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
default: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+436
to
+454
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
static inline struct net_buf *encode_node(struct node_rx_pdu *node_rx, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int8_t class) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -443,10 +466,17 @@ static inline struct net_buf *encode_node(struct node_rx_pdu *node_rx, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case HCI_CLASS_EVT_CONNECTION: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case HCI_CLASS_EVT_LLCP: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (class == HCI_CLASS_EVT_DISCARDABLE) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buf = bt_buf_get_evt(BT_HCI_EVT_UNKNOWN, true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
K_NO_WAIT); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buf = bt_buf_get_evt(BT_HCI_EVT_UNKNOWN, true, K_NO_WAIT); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint8_t evt = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint8_t meta = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bool recognized = node_to_evt(node_rx, &evt, &meta); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (recognized) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buf = bt_buf_get_evt_but_better(evt, meta, K_FOREVER); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (buf) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hci_evt_encode(node_rx, buf); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -779,6 +779,19 @@ config BT_EXT_SCAN_BUF_SIZE | |
provided by the controller is larger than this buffer size, | ||
the remaining data will be discarded. | ||
|
||
config BT_EXT_SCAN_BUF_NUM | ||
int "Maximum number of report reassembly buffers" | ||
range 1 65535 | ||
default 2 | ||
help | ||
Advertising reports can be fragmented when transmitted over HCI to the | ||
Host. They are re-assembled into a dedicated buffer pool and the | ||
application is notified asynchronously. This number governs the amount | ||
of pending reassembled advertising reports. | ||
|
||
Note that this option only uses up resources if extended advertising | ||
is enabled. | ||
Comment on lines
+792
to
+793
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should it then not depend on |
||
|
||
endif # BT_OBSERVER | ||
|
||
config BT_SCAN_WITH_IDENTITY | ||
|
@@ -1035,6 +1048,12 @@ config BT_TESTING | |
This option enables custom Bluetooth testing interface. | ||
Shall only be used for testing purposes. | ||
|
||
config BT_HTOP | ||
bool "Bluetooth Statistics" | ||
help | ||
Enable printing of Bluetooth performance statistics. | ||
Sort of like THREAD_ANALYZER. | ||
Comment on lines
+1051
to
+1055
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
config BT_CONN_DISABLE_SECURITY | ||
bool "Disable security" | ||
depends on BT_TESTING | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -82,6 +82,101 @@ struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout) | |||||||||||||||||||||||||||||||||||||||||||
return buf; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
static bool is_hci_event_discardable(const uint8_t evt_type, const uint8_t subevt_type) | ||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||
switch (evt_type) { | ||||||||||||||||||||||||||||||||||||||||||||
#if defined(CONFIG_BT_CLASSIC) | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: | ||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_LE_META_EVENT: { | ||||||||||||||||||||||||||||||||||||||||||||
switch (subevt_type) { | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_LE_ADVERTISING_REPORT: | ||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||
default: | ||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
default: | ||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
NET_BUF_POOL_FIXED_DEFINE(sync_adv_pool, 2, SYNC_EVT_SIZE, sizeof(struct bt_buf_data), NULL); | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is |
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/* This is a host-private function */ | ||||||||||||||||||||||||||||||||||||||||||||
bool bt_buf_can_steal_ext_adv_report_buf(struct net_buf *buf) | ||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||
if (net_buf_pool_get(buf->pool_id) != &sync_adv_pool) { | ||||||||||||||||||||||||||||||||||||||||||||
/* The driver did not use `bt_buf_get_evt_but_better` */ | ||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/* Host can steal the buffer if we have at least one available. | ||||||||||||||||||||||||||||||||||||||||||||
* This is the case when: | ||||||||||||||||||||||||||||||||||||||||||||
* - There are buffers in the `free` LIFO | ||||||||||||||||||||||||||||||||||||||||||||
* - There are un-initialized buffers | ||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||
return (!k_fifo_is_empty(&sync_adv_pool.free)) || (sync_adv_pool.uninit_count != 0); | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This almost begs for a proper net_buf_pool API to test for "is it empty?". That said, it's inherently racy in premptible contexts, so we might not want to give people such a foot gun. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep. Ideally There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, though that's a bit of a separate issue. Even with everything in the LIFO it's still racy to first check and then try to allocate (or make any other decisions based on the pool status) |
||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
struct net_buf *bt_buf_get_evt_but_better(uint8_t evt, uint8_t meta, k_timeout_t timeout) | ||||||||||||||||||||||||||||||||||||||||||||
Thalley marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||
/* Always allocs so-called "discardable" events with K_NO_WAIT. Most of | ||||||||||||||||||||||||||||||||||||||||||||
* the drivers will call from ISR so they should not block at all. | ||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||
* For non-meta events, the `meta` param is just the next byte. | ||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||
struct net_buf *buf = NULL; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
switch (evt) { | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_NUM_COMPLETED_PACKETS: | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_CMD_STATUS: | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_CMD_COMPLETE: | ||||||||||||||||||||||||||||||||||||||||||||
case BT_HCI_EVT_LE_META_EVENT: { | ||||||||||||||||||||||||||||||||||||||||||||
bool is_ext_adv = meta == BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT; | ||||||||||||||||||||||||||||||||||||||||||||
bool is_meta = evt == BT_HCI_EVT_LE_META_EVENT; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if (is_ext_adv) { | ||||||||||||||||||||||||||||||||||||||||||||
buf = net_buf_alloc(&sync_adv_pool, timeout); | ||||||||||||||||||||||||||||||||||||||||||||
/* 60% of the time we get a buffer every time */ | ||||||||||||||||||||||||||||||||||||||||||||
__ASSERT_NO_MSG(buf); | ||||||||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if (is_meta && !is_ext_adv) { | ||||||||||||||||||||||||||||||||||||||||||||
/* For now we use the sync pool only for ext adv | ||||||||||||||||||||||||||||||||||||||||||||
* reports. They cannot be marked as discardable thanks | ||||||||||||||||||||||||||||||||||||||||||||
* to the geniuses in SIG that decided to save space and | ||||||||||||||||||||||||||||||||||||||||||||
* only use two bits for reassembly status. | ||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+146
to
+155
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Minor optimization; we don't need the |
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
buf = net_buf_alloc(&sync_evt_pool, timeout); | ||||||||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
default: | ||||||||||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if (!buf) { | ||||||||||||||||||||||||||||||||||||||||||||
if (is_hci_event_discardable(evt, meta)) { | ||||||||||||||||||||||||||||||||||||||||||||
buf = net_buf_alloc(&discardable_pool, K_NO_WAIT); | ||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||
return bt_buf_get_rx(BT_BUF_EVT, timeout); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if (buf) { | ||||||||||||||||||||||||||||||||||||||||||||
net_buf_reserve(buf, BT_BUF_RESERVE); | ||||||||||||||||||||||||||||||||||||||||||||
bt_buf_set_type(buf, BT_BUF_EVT); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
return buf; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, | ||||||||||||||||||||||||||||||||||||||||||||
k_timeout_t timeout) | ||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any define for the offset instead of the magic number
3
?