-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Bluetooth: Controller: Adds path loss monitoring functionality #92450
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?
Changes from all commits
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 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2793,6 +2793,55 @@ static void le_set_phy(struct net_buf *buf, struct net_buf **evt) | |||||||||
*evt = cmd_status(status); | ||||||||||
} | ||||||||||
#endif /* CONFIG_BT_CTLR_PHY */ | ||||||||||
|
||||||||||
|
||||||||||
#if defined(CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING) | ||||||||||
|
||||||||||
#define PATH_LOSS_FACTOR_INVALID 0xFF | ||||||||||
static void le_path_loss_set_parameters(struct net_buf *buf, struct net_buf **evt) | ||||||||||
{ | ||||||||||
struct bt_hci_cp_le_set_path_loss_reporting_parameters *cmd = (void *)buf->data; | ||||||||||
struct bt_hci_rp_le_set_path_loss_reporting_parameters *rp; | ||||||||||
|
||||||||||
uint16_t handle = sys_le16_to_cpu(cmd->handle); | ||||||||||
uint16_t min_time_spent = sys_le16_to_cpu(cmd->min_time_spent); | ||||||||||
|
||||||||||
rp = hci_cmd_complete(evt, sizeof(*rp)); | ||||||||||
rp->handle = handle; | ||||||||||
|
||||||||||
if (cmd->high_threshold + cmd->high_hysteresis > PATH_LOSS_FACTOR_INVALID || | ||||||||||
cmd->low_threshold < cmd->low_hysteresis || | ||||||||||
cmd->low_threshold > cmd->high_threshold || | ||||||||||
cmd->low_threshold + cmd->low_hysteresis > cmd->high_threshold - cmd->high_hysteresis) { | ||||||||||
rp->status = BT_HCI_ERR_INVALID_PARAM; | ||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
rp->status = ll_conn_set_path_loss_parameters(handle, cmd->high_threshold, | ||||||||||
cmd->high_hysteresis, cmd->low_threshold, | ||||||||||
cmd->low_hysteresis, min_time_spent); | ||||||||||
} | ||||||||||
|
||||||||||
#define PATH_LOSS_ENABLED 0x01 | ||||||||||
#define PATH_LOSS_DISABLED 0x00 | ||||||||||
static void le_path_loss_enable(struct net_buf *buf, struct net_buf **evt) | ||||||||||
{ | ||||||||||
struct bt_hci_cp_le_set_path_loss_reporting_enable *cmd = (void *)buf->data; | ||||||||||
struct bt_hci_rp_le_set_path_loss_reporting_enable *rp; | ||||||||||
|
||||||||||
uint16_t handle = sys_le16_to_cpu(cmd->handle); | ||||||||||
|
||||||||||
rp = hci_cmd_complete(evt, sizeof(*rp)); | ||||||||||
rp->handle = handle; | ||||||||||
|
||||||||||
if (cmd->enable != PATH_LOSS_ENABLED && | ||||||||||
cmd->enable != PATH_LOSS_DISABLED) { | ||||||||||
rp->status = BT_HCI_ERR_INVALID_PARAM; | ||||||||||
} | ||||||||||
|
||||||||||
rp->status = ll_conn_set_path_loss_reporting(handle, cmd->enable); | ||||||||||
} | ||||||||||
#endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ | ||||||||||
#endif /* CONFIG_BT_CONN */ | ||||||||||
|
||||||||||
#if defined(CONFIG_BT_CTLR_PRIVACY) | ||||||||||
|
@@ -4767,6 +4816,17 @@ static int controller_cmd_handle(uint16_t ocf, struct net_buf *cmd, | |||||||||
le_set_phy(cmd, evt); | ||||||||||
break; | ||||||||||
#endif /* CONFIG_BT_CTLR_PHY */ | ||||||||||
|
||||||||||
#if defined(CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING) | ||||||||||
case BT_OCF(BT_HCI_OP_LE_SET_PATH_LOSS_REPORTING_PARAMETERS): | ||||||||||
le_path_loss_set_parameters(cmd, evt); | ||||||||||
break; | ||||||||||
|
||||||||||
case BT_OCF(BT_HCI_OP_LE_SET_PATH_LOSS_REPORTING_ENABLE): | ||||||||||
le_path_loss_enable(cmd, evt); | ||||||||||
break; | ||||||||||
|
||||||||||
#endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ | ||||||||||
#endif /* CONFIG_BT_CONN */ | ||||||||||
|
||||||||||
#if defined(CONFIG_BT_CTLR_ADV_EXT) | ||||||||||
|
@@ -8645,6 +8705,28 @@ static void le_req_peer_sca_complete(struct pdu_data *pdu, uint16_t handle, | |||||||||
sep->sca = scau->sca; | ||||||||||
} | ||||||||||
#endif /* CONFIG_BT_CTLR_SCA_UPDATE */ | ||||||||||
#if defined(CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING) | ||||||||||
static void le_path_loss_threshold(struct pdu_data *pdu, | ||||||||||
uint16_t handle, | ||||||||||
struct net_buf *buf) | ||||||||||
{ | ||||||||||
struct bt_hci_evt_le_path_loss_threshold *sep; | ||||||||||
struct node_rx_path_loss *pl_pdu; | ||||||||||
|
||||||||||
pl_pdu = (void *)pdu; | ||||||||||
|
||||||||||
if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) || | ||||||||||
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
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'd prefer to leave it as is, since it's similar to how it's done in the other functions above. Examples: zephyr/subsys/bluetooth/controller/hci/hci.c Line 8633 in fdd02c5
zephyr/subsys/bluetooth/controller/hci/hci.c Line 8608 in fdd02c5
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'll defer that to the maintainer of the controller. The reason why I mentioned here is that it's in violation of rule 85 of the Zephyr coding guidelines that does not allow using integers as controlling expression https://docs.zephyrproject.org/latest/contribute/coding_guidelines/index.html : https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_14_04.c 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. @cvinayak Perhaps we could make a Github issue and fix up this file to be compliant after this PR? Then we can get all the changes done at once. 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. Fixing it for a single file won't do much :D It's pretty much in every file and everywhere, since it has been the coding standard for many years before we adaptoed the aforementioned rule. I'm personally slowly going through some of the coding style violations in the LE Audio code, but there are thousands of cases for each rule :) |
||||||||||
!(le_event_mask & BT_EVT_MASK_LE_PATH_LOSS_THRESHOLD)) { | ||||||||||
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
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. Same suggestion as above, since this would stick out from the other, similar functions. 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. See #92450 (comment) |
||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
sep = meta_evt(buf, BT_HCI_EVT_LE_PATH_LOSS_THRESHOLD, sizeof(*sep)); | ||||||||||
|
||||||||||
sep->handle = sys_cpu_to_le16(handle); | ||||||||||
sep->current_path_loss = pl_pdu->current_path_loss; | ||||||||||
sep->zone_entered = pl_pdu->zone_entered; | ||||||||||
} | ||||||||||
#endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ | ||||||||||
#endif /* CONFIG_BT_CONN */ | ||||||||||
|
||||||||||
#if defined(CONFIG_BT_HCI_MESH_EXT) | ||||||||||
|
@@ -8847,6 +8929,12 @@ static void encode_control(struct node_rx_pdu *node_rx, | |||||||||
#endif /* CONFIG_BT_CTLR_DF_VS_CONN_IQ_REPORT_16_BITS_IQ_SAMPLES */ | ||||||||||
return; | ||||||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */ | ||||||||||
|
||||||||||
#if defined(CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING) | ||||||||||
case NODE_RX_TYPE_PATH_LOSS: | ||||||||||
le_path_loss_threshold(pdu_data, handle, buf); | ||||||||||
return; | ||||||||||
#endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ | ||||||||||
#endif /* CONFIG_BT_CONN */ | ||||||||||
|
||||||||||
#if defined(CONFIG_BT_CTLR_ADV_INDICATION) | ||||||||||
|
@@ -9332,6 +9420,10 @@ uint8_t hci_get_class(struct node_rx_pdu *node_rx) | |||||||||
#endif /* CONFIG_BT_CTLR_PHY */ | ||||||||||
|
||||||||||
return HCI_CLASS_EVT_CONNECTION; | ||||||||||
#if defined(CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING) | ||||||||||
case NODE_RX_TYPE_PATH_LOSS: | ||||||||||
return HCI_CLASS_EVT_REQUIRED; | ||||||||||
#endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ | ||||||||||
#endif /* CONFIG_BT_CONN */ | ||||||||||
|
||||||||||
#if defined(CONFIG_BT_CTLR_SYNC_ISO) || defined(CONFIG_BT_CTLR_CONN_ISO) | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,22 @@ | |
#define LLL_CONN_MIC_PASS 1 | ||
#define LLL_CONN_MIC_FAIL 2 | ||
|
||
|
||
struct path_loss_params { | ||
uint16_t min_time_spent; | ||
uint8_t enabled; | ||
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. Some values like 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. In practice, I think they can be optimized (like |
||
uint8_t high_threshold; | ||
uint8_t high_hysteresis; | ||
uint8_t low_threshold; | ||
uint8_t low_hysteresis; | ||
} __packed; | ||
|
||
struct path_loss_state { | ||
uint16_t conn_handle; | ||
uint16_t min_time_counter; | ||
uint8_t new_zone; | ||
} __packed; | ||
|
||
struct lll_tx { | ||
uint16_t handle; | ||
void *node; | ||
|
@@ -157,6 +173,11 @@ struct lll_conn { | |
uint8_t rssi_sample_count; | ||
#endif /* CONFIG_BT_CTLR_CONN_RSSI_EVENT */ | ||
#endif /* CONFIG_BT_CTLR_CONN_RSSI */ | ||
#if defined(CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING) | ||
struct path_loss_params pl_params; | ||
struct path_loss_state pl_state; | ||
uint8_t pl_current_zone; | ||
#endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ | ||
|
||
#if defined(CONFIG_BT_CTLR_CONN_META) | ||
struct lll_conn_meta conn_meta; | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2910,6 +2910,56 @@ uint8_t ull_conn_lll_phy_active(struct ll_conn *conn, uint8_t phys) | |||||
return 1; | ||||||
} | ||||||
|
||||||
#if defined(CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING) | ||||||
uint8_t ll_conn_set_path_loss_parameters(uint16_t handle, | ||||||
uint8_t high_threshold, | ||||||
uint8_t high_hysteresis, | ||||||
uint8_t low_threshold, | ||||||
uint8_t low_hysteresis, | ||||||
uint16_t min_time_spent) | ||||||
{ | ||||||
struct ll_conn *conn; | ||||||
|
||||||
conn = ll_connected_get(handle); | ||||||
|
||||||
if (!conn) { | ||||||
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
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 would prefer to leave this as is, since this file has many cases of being done this way. 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. See #92450 (comment) |
||||||
return BT_HCI_ERR_UNKNOWN_CONN_ID; | ||||||
} | ||||||
|
||||||
conn->lll.pl_params.high_threshold = high_threshold; | ||||||
conn->lll.pl_params.high_hysteresis = high_hysteresis; | ||||||
conn->lll.pl_params.low_threshold = low_threshold; | ||||||
conn->lll.pl_params.low_hysteresis = low_hysteresis; | ||||||
conn->lll.pl_params.min_time_spent = min_time_spent; | ||||||
|
||||||
/* Reset the counter and zone after any update from the host */ | ||||||
conn->lll.pl_state.min_time_counter = 0; | ||||||
conn->lll.pl_current_zone = BT_HCI_LE_ZONE_ENTERED_LOW; | ||||||
|
||||||
return BT_HCI_ERR_SUCCESS; | ||||||
} | ||||||
|
||||||
uint8_t ll_conn_set_path_loss_reporting(uint16_t handle, uint8_t enable) | ||||||
{ | ||||||
struct ll_conn *conn; | ||||||
|
||||||
conn = ll_connected_get(handle); | ||||||
|
||||||
if (!conn) { | ||||||
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
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 would prefer to leave this as is, since this file has many cases of being done this way. 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. See #92450 (comment) |
||||||
return BT_HCI_ERR_UNKNOWN_CONN_ID; | ||||||
} | ||||||
|
||||||
conn->lll.pl_params.enabled = enable; | ||||||
|
||||||
/* Reset the counter and zone after any update from the host */ | ||||||
conn->lll.pl_state.min_time_counter = 0; | ||||||
conn->lll.pl_current_zone = BT_HCI_LE_ZONE_ENTERED_LOW; | ||||||
|
||||||
return BT_HCI_ERR_SUCCESS; | ||||||
|
||||||
} | ||||||
#endif /* CONFIG_BT_CTLR_LE_PATH_LOSS_MONITORING */ | ||||||
|
||||||
uint8_t ull_is_lll_tx_queue_empty(struct ll_conn *conn) | ||||||
{ | ||||||
return (memq_peek(conn->lll.memq_tx.head, conn->lll.memq_tx.tail, NULL) == NULL); | ||||||
|
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.
Not particularly related to this PR, as it's basically done nowhere in the controller, but
cmd->handle
is only 12 bits. If we receive a a handle of0xFFFF
we should returnBT_HCI_ERR_INVALID_PARAM
, right?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.
Very good point. Maybe it's worth making a Github issue and fixing this file up? 👍
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.
Sure, could be a nice first-time issue as it's just fixing a missing check several places :) Chances are that it's being handled somewhere else that I'm not aware of @cvinayak ?