From 832fd9af372f16fafcdce0458873f625ebd8f12b Mon Sep 17 00:00:00 2001 From: fangzhenwei Date: Wed, 15 Jan 2025 12:44:42 +0800 Subject: [PATCH] Bluetooth: Classic: GAP: Write EIR support bug: v/47556 add read and write EIR API, and write EIR only implement local name EIR. optimize the process of set name, update the EIR with local name if EIR feature is support. Signed-off-by: fangzhenwei --- include/zephyr/bluetooth/classic/classic.h | 24 +++++++ include/zephyr/bluetooth/hci_types.h | 14 +++++ subsys/bluetooth/host/classic/br.c | 73 ++++++++++++++++++++++ subsys/bluetooth/host/hci_core.c | 8 ++- subsys/bluetooth/host/settings.c | 1 + 5 files changed, 119 insertions(+), 1 deletion(-) diff --git a/include/zephyr/bluetooth/classic/classic.h b/include/zephyr/bluetooth/classic/classic.h index b8f01d3471c..cdf2045e5b8 100644 --- a/include/zephyr/bluetooth/classic/classic.h +++ b/include/zephyr/bluetooth/classic/classic.h @@ -273,6 +273,30 @@ int bt_br_set_class_of_device(uint32_t local_cod); */ int bt_br_write_local_name(const char *name); +/** + * @brief Read the Extended Inquiry Response configuration parameter of the + * local BR/EDR Controller. + * + * @param status Status of the command. + * @param fec_required FEC required for EIR. + * @param eir Extended Inquiry Response data. + * + * @return Zero on success or error code otherwise, positive in case + * of protocol error or negative (POSIX) in case of stack internal error. + */ +int bt_br_read_ext_inq_response(uint8_t *status, uint8_t *fec_required, uint8_t *eir); + +/** + * @brief Write the Extended Inquiry Response configuration parameter of the + * local BR/EDR Controller. + * + * @param fec_required FEC required for EIR. + * + * @return Zero on success or error code otherwise, positive in case + * of protocol error or negative (POSIX) in case of stack internal error. + */ +int bt_br_write_ext_inq_response(uint8_t fec_required); + /** Information about a br/edr bond with a remote device. */ struct bt_bond_info_br { bt_addr_t addr; diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 34dd3c36ffc..dcb5a75d38a 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -156,6 +156,7 @@ struct bt_hci_cmd_hdr { #define BT_FEAT_2EV3_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 5) #define BT_FEAT_3EV3_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 6) #define BT_FEAT_3SLOT_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 7) +#define BT_FEAT_EIR(feat) BT_FEAT_TEST(feat, 0, 6, 0) #define BT_FEAT_SSP(feat) BT_FEAT_TEST(feat, 0, 6, 3) /* LE features */ @@ -722,6 +723,19 @@ struct bt_hci_rp_read_tx_power_level { int8_t tx_power_level; } __packed; +#define BT_HCI_OP_READ_EXTENDED_INQUIRY_RESPONSE BT_OP(BT_OGF_BASEBAND, 0x0051) /* 0x0c51 */ +struct bt_hci_rp_read_extended_inquiry_response { + uint8_t status; + uint8_t fec_required; + uint8_t extended_inquiry_response[240]; +} __packed; + +#define BT_HCI_OP_WRITE_EXTENDED_INQUIRY_RESPONSE BT_OP(BT_OGF_BASEBAND, 0x0052) /* 0x0c52 */ +struct bt_hci_cp_write_extended_inquiry_response { + uint8_t fec; + uint8_t extended_inquiry_response[240]; +} __packed; + #define BT_HCI_LE_TX_POWER_PHY_1M 0x01 #define BT_HCI_LE_TX_POWER_PHY_2M 0x02 #define BT_HCI_LE_TX_POWER_PHY_CODED_S8 0x03 diff --git a/subsys/bluetooth/host/classic/br.c b/subsys/bluetooth/host/classic/br.c index a5c80660893..c0d366f2bdc 100644 --- a/subsys/bluetooth/host/classic/br.c +++ b/subsys/bluetooth/host/classic/br.c @@ -1270,6 +1270,79 @@ int bt_br_write_local_name(const char *name) return bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_LOCAL_NAME, buf, NULL); } +int bt_br_read_ext_inq_response(uint8_t *status, uint8_t *fec_required, uint8_t *eir) +{ + struct bt_hci_rp_read_extended_inquiry_response *rp; + struct net_buf *rsp; + int err; + + if (!BT_FEAT_EIR(bt_dev.features)) { + return -ENOTSUP; + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_EXTENDED_INQUIRY_RESPONSE, NULL, &rsp); + if (err) { + return err; + } + + rp = (void *)rsp->data; + *status = rp->status; + *fec_required = rp->fec_required; + + if (eir) { + memcpy(eir, rp->extended_inquiry_response, sizeof(rp->extended_inquiry_response)); + } + + net_buf_unref(rsp); + + return 0; +} + +int bt_br_write_ext_inq_response(uint8_t fec_required) +{ + struct net_buf *buf; + struct bt_hci_cp_write_extended_inquiry_response *cp; + size_t name_len, eir_len = 240; + uint8_t type; + + if (!BT_FEAT_EIR(bt_dev.features)) { + return -ENOTSUP; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_EXTENDED_INQUIRY_RESPONSE, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + net_buf_add_u8(buf, fec_required); + + /* Fill in EIR data (Name) */ + eir_len -= 2; + name_len = strlen(bt_dev.name); + if (name_len > eir_len) { + name_len = eir_len; + type = EIR_SHORT_NAME; + eir_len = 0; + } else { + type = EIR_COMPLETE_NAME; + eir_len -= name_len; + } + + net_buf_add_u8(buf, name_len + 1); + net_buf_add_u8(buf, type); + net_buf_add_mem(buf, bt_dev.name, name_len); + + /* TODO: Fill in EIR data (COD) */ + /* TODO: Fill in EIR data (UUID) */ + /* TODO: Fill in EIR data (Flags) */ + /* TODO: Fill in EIR data (Manufacturer Specific Data) */ + /* TODO: Fill in EIR data (TX Power) */ + + net_buf_add(buf, eir_len); + + return bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_EXTENDED_INQUIRY_RESPONSE, buf, NULL); +} + int bt_br_remote_name_request(const bt_addr_t *bdaddr, bt_br_remote_name_req_cb_t cb) { struct bt_br_discovery_result *result; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index a7fecafc321..0a53f201282 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -4558,7 +4558,13 @@ int bt_set_name(const char *name) } if (IS_ENABLED(CONFIG_BT_CLASSIC)) { - return bt_br_write_local_name(name); + err = bt_br_write_local_name(name); + if (err) { + LOG_WRN("Unable to set BR/EDR name"); + return err; + } + + return bt_br_write_ext_inq_response(true); } return 0; diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 06b3526c852..12750aeb06b 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -250,6 +250,7 @@ static int commit_settings(void) } else { if (IS_ENABLED(CONFIG_BT_CLASSIC)) { bt_br_write_local_name(bt_dev.name); + bt_br_write_ext_inq_response(true); } } #endif