Bluetooth: Host: Check max adv data len from ctrl
Send a `READ_MAX_ADV_DATA_LEN` command to the controller at the initialization of the host to fetch the maximum advertising data length the host can accept. This is done because even if the Zephyr controller provide the `CONFIG_BT_CTLR_ADV_DATA_LEN_MAX` Kconfig symbol, other controllers may not have such Kconfig symbol. So this is a way for the host to be more controller-agnostic and provide useful feedback to the users. Signed-off-by: Théo Battrel <theo.battrel@nordicsemi.no>
This commit is contained in:
parent
d590bcb5e0
commit
a0198fe420
3 changed files with 39 additions and 0 deletions
|
@ -661,6 +661,12 @@ static int hci_set_ad_ext(struct bt_le_ext_adv *adv, uint16_t hci_op,
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (total_len_bytes > bt_dev.le.max_adv_data_len) {
|
||||
LOG_WRN("adv or scan rsp data too large (%d > max %d)", total_len_bytes,
|
||||
bt_dev.le.max_adv_data_len);
|
||||
return -EDOM;
|
||||
}
|
||||
|
||||
if (total_len_bytes <= BT_HCI_LE_EXT_ADV_FRAG_MAX_LEN) {
|
||||
/* If possible, set all data at once.
|
||||
* This allows us to update advertising data while advertising.
|
||||
|
|
|
@ -3086,6 +3086,17 @@ static void le_read_supp_states_complete(struct net_buf *buf)
|
|||
bt_dev.le.states = sys_get_le64(rp->le_states);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_BROADCASTER)
|
||||
static void le_read_maximum_adv_data_len_complete(struct net_buf *buf)
|
||||
{
|
||||
struct bt_hci_rp_le_read_max_adv_data_len *rp = (void *)buf->data;
|
||||
|
||||
LOG_DBG("status 0x%02x", rp->status);
|
||||
|
||||
bt_dev.le.max_adv_data_len = sys_le16_to_cpu(rp->max_adv_data_len);
|
||||
}
|
||||
#endif /* CONFIG_BT_BROADCASTER */
|
||||
|
||||
#if defined(CONFIG_BT_SMP)
|
||||
static void le_read_resolving_list_size_complete(struct net_buf *buf)
|
||||
{
|
||||
|
@ -3387,6 +3398,25 @@ static int le_init(void)
|
|||
net_buf_unref(rsp);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_BROADCASTER)
|
||||
if (IS_ENABLED(CONFIG_BT_EXT_ADV) && BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
|
||||
/* Read LE Max Adv Data Len */
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN, NULL, &rsp);
|
||||
if (err == 0) {
|
||||
le_read_maximum_adv_data_len_complete(rsp);
|
||||
net_buf_unref(rsp);
|
||||
} else if (err == -EIO) {
|
||||
LOG_WRN("Controller does not support 'LE_READ_MAX_ADV_DATA_LEN'. "
|
||||
"Assuming maximum length is 31 bytes.");
|
||||
bt_dev.le.max_adv_data_len = 31;
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
bt_dev.le.max_adv_data_len = 31;
|
||||
}
|
||||
#endif /* CONFIG_BT_BROADCASTER */
|
||||
|
||||
if (BT_FEAT_BREDR(bt_dev.features)) {
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP,
|
||||
sizeof(*cp_le));
|
||||
|
|
|
@ -294,6 +294,9 @@ struct bt_dev_le {
|
|||
uint8_t iso_limit;
|
||||
struct k_sem iso_pkts;
|
||||
#endif /* CONFIG_BT_ISO */
|
||||
#if defined(CONFIG_BT_BROADCASTER)
|
||||
uint16_t max_adv_data_len;
|
||||
#endif /* CONFIG_BT_BROADCASTER */
|
||||
|
||||
#if defined(CONFIG_BT_SMP)
|
||||
/* Size of the the controller resolving list */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue