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:
Théo Battrel 2024-04-17 16:23:15 +02:00 committed by Carles Cufí
commit a0198fe420
3 changed files with 39 additions and 0 deletions

View file

@ -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.

View file

@ -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));

View file

@ -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 */