-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Bluetooth: Controller: Initial Frame Space Update support #99473
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
base: main
Are you sure you want to change the base?
Conversation
Initial Frame Space Update support. Signed-off-by: Andries Kruithof <andries.kruithof@nordicsemi.no> Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
|
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.
Pull Request Overview
This PR introduces initial Frame Space Update (FSU) support to the Bluetooth controller. Frame Space Update is a Bluetooth specification feature that allows devices to negotiate inter-frame spacing parameters during a connection, enabling optimization of timing intervals between packets.
Key changes:
- Added FSU procedure handling in LLCP (Link Layer Control Protocol) state machines for both local and remote procedures
- Implemented FSU PDU encoding/decoding functions for request and response messages
- Integrated FSU initialization and updates into connection setup and PHY update procedures
Reviewed Changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| ull_peripheral.c | Added FSU initialization call during peripheral setup |
| ull_central.c | Added FSU initialization call during central connection creation |
| ull_llcp_remote.c | Added FSU procedure handling in remote procedure state machine |
| ull_llcp_local.c | Added FSU procedure handling in local procedure state machine |
| ull_llcp_common.c | Implemented FSU request/response handling and notification logic |
| ull_llcp_phy.c | Added function to update effective TIFS based on FSU parameters during PHY updates |
| ull_llcp_pdu.c | Implemented FSU PDU encoding/decoding functions with debugging printk |
| ull_llcp.c | Added FSU procedure initiation and validation functions |
| ull_conn.c | Implemented FSU initialization, update logic, and per-PHY parameter management |
| ull_llcp_internal.h | Added FSU procedure enum and context data structure |
| ull_llcp_features.h | Added FSU feature check function |
| ull_conn_internal.h | Added FSU function declarations |
| ull_llcp.h | Added FSU public API declarations |
| pdu.h | Added FSU PDU structures and control type definitions |
| lll_conn.h | Added FSU data structures to connection state |
| ll_feat.h | Added FSU feature bit definition (temporarily set to 0) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| p->fsu = sys_cpu_to_le16(conn->lll.fsu.local.fsu_min); | ||
| p->phys = conn->lll.fsu.local.phys; | ||
| p->spacing_type = sys_cpu_to_le16(conn->lll.fsu.local.spacing_type); | ||
| printk("%s: fsu %u\n", __func__, p->fsu); |
Copilot
AI
Nov 17, 2025
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.
Debug printk statement should be removed or replaced with proper logging using LOG_DBG. This printk call is inappropriate for production code and will cause unwanted console output.
| conn->lll.fsu.local.phys = p->phys & 0x07; /* mask out RFU bits */ | ||
| conn->lll.fsu.local.spacing_type = | ||
| sys_le16_to_cpu(p->spacing_type & 0x1F); /* mask out RFU bits */ | ||
| /* nitpic, perphy is confusing, call it phy*/ |
Copilot
AI
Nov 17, 2025
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.
Corrected spelling of 'nitpic' to 'nitpick'.
| /* nitpic, perphy is confusing, call it phy*/ | |
| /* nitpick, perphy is confusing, call it phy*/ |
| conn->lll.phy_tx == 4 ? 2 : conn->lll.phy_tx - 1; /* a bit tricky but should work */ | ||
| phy_index_rx = | ||
| conn->lll.phy_rx == 4 ? 2 : conn->lll.phy_rx - 1; /* a bit tricky but should work */ |
Copilot
AI
Nov 17, 2025
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.
The comment 'a bit tricky but should work' is vague and doesn't explain the PHY index mapping logic. Consider documenting why PHY value 4 maps to index 2 and the general mapping scheme (e.g., PHY_1M=1->index 0, PHY_2M=2->index 1, PHY_CODED=4->index 2).
| conn->lll.phy_tx == 4 ? 2 : conn->lll.phy_tx - 1; /* a bit tricky but should work */ | |
| phy_index_rx = | |
| conn->lll.phy_rx == 4 ? 2 : conn->lll.phy_rx - 1; /* a bit tricky but should work */ | |
| /* Map PHY values to perphy[] indices: | |
| * PHY_1M (1) -> index 0 | |
| * PHY_2M (2) -> index 1 | |
| * PHY_CODED (4) -> index 2 | |
| * This works because PHY_CODED is 4, so (phy == 4 ? 2 : phy - 1) | |
| * yields the correct index for each PHY value. | |
| */ | |
| conn->lll.phy_tx == 4 ? 2 : conn->lll.phy_tx - 1; | |
| phy_index_rx = | |
| /* See mapping above for explanation. */ | |
| conn->lll.phy_rx == 4 ? 2 : conn->lll.phy_rx - 1; |
| phy_index_tx = | ||
| conn->lll.phy_tx == 4 ? 2 : conn->lll.phy_tx - 1; /* a bit tricky but should work */ | ||
| phy_index_rx = | ||
| conn->lll.phy_rx == 4 ? 2 : conn->lll.phy_rx - 1; /* a bit tricky but should work */ |
Copilot
AI
Nov 17, 2025
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.
The comment 'a bit tricky but should work' is vague and doesn't explain the PHY index mapping logic. This duplicates the same unclear pattern from line 326. Consider documenting the mapping scheme clearly.
| phy_index_tx = | |
| conn->lll.phy_tx == 4 ? 2 : conn->lll.phy_tx - 1; /* a bit tricky but should work */ | |
| phy_index_rx = | |
| conn->lll.phy_rx == 4 ? 2 : conn->lll.phy_rx - 1; /* a bit tricky but should work */ | |
| /* Map PHY values to perphy array indices: | |
| * PHY values: 1 = LE 1M, 2 = LE 2M, 3 = LE Coded, 4 = LE Coded S2. | |
| * perphy array indices: 0 = LE 1M, 1 = LE 2M, 2 = LE Coded (S8/S2). | |
| * LE Coded S2 (phy value 4) shares the same index (2) as LE Coded S8 (phy value 3). | |
| * For other PHYs, subtract 1 to get the array index. | |
| */ | |
| phy_index_tx = | |
| conn->lll.phy_tx == 4 ? 2 : conn->lll.phy_tx - 1; | |
| phy_index_rx = | |
| conn->lll.phy_rx == 4 ? 2 : conn->lll.phy_rx - 1; |
| fsu_changed = ull_fsu_update_eff_from_local(conn); | ||
|
|
||
| if (fsu_changed) { | ||
| /* TODO: confirm that we do not need to do something here? */ |
Copilot
AI
Nov 17, 2025
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.
TODO comment is unclear about what needs to be confirmed or what action might be needed. Consider either resolving this TODO before merging or documenting specifically what needs to be investigated (e.g., 'TODO: Verify if timing parameter recalculation is needed when FSU changes').
| /* TODO: confirm that we do not need to do something here? */ | |
| /* TODO: Verify if additional actions (e.g., timing parameter recalculation or event notification) are needed when FSU changes. */ |
| /* llcp_tx_pause_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_FRAME_SPACE); | ||
| */ |
Copilot
AI
Nov 17, 2025
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.
Commented-out code should be removed. If this functionality is planned for future implementation, add a TODO comment explaining when and why it should be uncommented.
| /* llcp_tx_pause_data(conn, LLCP_TX_QUEUE_PAUSE_DATA_FRAME_SPACE); | |
| */ |
| */ | ||
|
|
||
| /* FIXME: Conditional Compilation for FSU feature, and handle feature bits > 64 bits */ | ||
| #define LL_FEAT_BIT_FRAME_SPACE 0U |
Copilot
AI
Nov 17, 2025
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.
LL_FEAT_BIT_FRAME_SPACE is defined as 0U which conflicts with existing feature bit 0. This should be assigned a unique, unused bit position in the feature mask. The comment on line 256 acknowledges this needs fixing for feature bits > 64 bits.
| #define LL_FEAT_BIT_FRAME_SPACE 0U | |
| #define LL_FEAT_BIT_FRAME_SPACE BIT64(BT_LE_FEAT_BIT_FRAME_SPACE) |
| #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ | ||
| struct { | ||
| struct data_pdu_fsu local; | ||
| struct data_pdu_fsu perphy[4]; /* store frame-space for each PHY */ |
Copilot
AI
Nov 17, 2025
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.
Array size hardcoded as 4 but code elsewhere uses size 3 (e.g., ull_conn.c lines 2383, 2427, 2965). This inconsistency could lead to bugs. Consider using a named constant (e.g., FSU_NUM_PHYS) or document why the sizes differ.
| break; | ||
| #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ) | ||
| case PROC_CTE_REQ: | ||
| /* 3rd partam null? */ |
Copilot
AI
Nov 17, 2025
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.
Corrected spelling of 'partam' to 'param'.
| /* 3rd partam null? */ | |
| /* 3rd param null? */ |



Initial Frame Space Update support.
Supercedes #82324.
Thank you @kruithofa for the contribution.
This a rebased PR, and is as-is for now.