Bluetooth: Allow use of ScanData with BT_LE_ADV_OPT_USE_NAME
This enables the user to provide a ScanData, as long as it contain names, and set BT_LE_ADV_OPT_USE_NAME. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
acc3e5129e
commit
18df11646f
1 changed files with 50 additions and 25 deletions
|
@ -4698,11 +4698,16 @@ int bt_enable(bt_ready_cb_t cb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int set_ad(u16_t hci_op, const struct bt_data *ad, size_t ad_len)
|
||||
struct bt_ad {
|
||||
const struct bt_data *data;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static int set_ad(u16_t hci_op, const struct bt_ad *ad, size_t ad_len)
|
||||
{
|
||||
struct bt_hci_cp_le_set_adv_data *set_data;
|
||||
struct net_buf *buf;
|
||||
int i;
|
||||
int c, i;
|
||||
|
||||
buf = bt_hci_cmd_create(hci_op, sizeof(*set_data));
|
||||
if (!buf) {
|
||||
|
@ -4713,19 +4718,23 @@ static int set_ad(u16_t hci_op, const struct bt_data *ad, size_t ad_len)
|
|||
|
||||
memset(set_data, 0, sizeof(*set_data));
|
||||
|
||||
for (i = 0; i < ad_len; i++) {
|
||||
/* Check if ad fit in the remaining buffer */
|
||||
if (set_data->len + ad[i].data_len + 2 > 31) {
|
||||
net_buf_unref(buf);
|
||||
return -EINVAL;
|
||||
for (c = 0; c < ad_len; c++) {
|
||||
const struct bt_data *data = ad[c].data;
|
||||
|
||||
for (i = 0; i < ad[c].len; i++) {
|
||||
/* Check if ad fit in the remaining buffer */
|
||||
if (set_data->len + data[i].data_len + 2 > 31) {
|
||||
net_buf_unref(buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
set_data->data[set_data->len++] = data[i].data_len + 1;
|
||||
set_data->data[set_data->len++] = data[i].type;
|
||||
|
||||
memcpy(&set_data->data[set_data->len], data[i].data,
|
||||
data[i].data_len);
|
||||
set_data->len += data[i].data_len;
|
||||
}
|
||||
|
||||
set_data->data[set_data->len++] = ad[i].data_len + 1;
|
||||
set_data->data[set_data->len++] = ad[i].type;
|
||||
|
||||
memcpy(&set_data->data[set_data->len], ad[i].data,
|
||||
ad[i].data_len);
|
||||
set_data->len += ad[i].data_len;
|
||||
}
|
||||
|
||||
return bt_hci_cmd_send_sync(hci_op, buf, NULL);
|
||||
|
@ -4756,10 +4765,11 @@ int bt_set_name(const char *name)
|
|||
|
||||
/* Update advertising name if in use */
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING_NAME)) {
|
||||
struct bt_data sd[] = { BT_DATA(BT_DATA_NAME_COMPLETE, name,
|
||||
struct bt_data data[] = { BT_DATA(BT_DATA_NAME_COMPLETE, name,
|
||||
strlen(name)) };
|
||||
struct bt_ad sd = { data, ARRAY_SIZE(data) };
|
||||
|
||||
set_ad(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, sd, ARRAY_SIZE(sd));
|
||||
set_ad(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, &sd, 1);
|
||||
|
||||
/* Make sure the new name is set */
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
||||
|
@ -4843,6 +4853,7 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,
|
|||
{
|
||||
struct bt_hci_cp_le_set_adv_param set_param;
|
||||
struct net_buf *buf;
|
||||
struct bt_ad d[2] = {};
|
||||
int err;
|
||||
|
||||
if (!valid_adv_param(param)) {
|
||||
|
@ -4853,37 +4864,51 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,
|
|||
return -EALREADY;
|
||||
}
|
||||
|
||||
err = set_ad(BT_HCI_OP_LE_SET_ADV_DATA, ad, ad_len);
|
||||
d[0].data = ad;
|
||||
d[0].len = ad_len;
|
||||
|
||||
err = set_ad(BT_HCI_OP_LE_SET_ADV_DATA, d, 1);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
d[0].data = sd;
|
||||
d[0].len = sd_len;
|
||||
|
||||
if (param->options & BT_LE_ADV_OPT_USE_NAME) {
|
||||
const char *name;
|
||||
|
||||
/* Cannot use name if sd is set */
|
||||
if (sd) {
|
||||
return -EINVAL;
|
||||
int i;
|
||||
|
||||
/* Cannot use name if name is already set */
|
||||
for (i = 0; i < sd_len; i++) {
|
||||
if (sd[i].type == BT_DATA_NAME_COMPLETE ||
|
||||
sd[i].type == BT_DATA_NAME_SHORTENED) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
name = bt_get_name();
|
||||
|
||||
sd = (&(struct bt_data)BT_DATA(BT_DATA_NAME_COMPLETE, name,
|
||||
strlen(name)));
|
||||
sd_len = 1;
|
||||
d[1].data = (&(struct bt_data)BT_DATA(BT_DATA_NAME_COMPLETE,
|
||||
name, strlen(name)));
|
||||
d[1].len = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to set SCAN_RSP when enabling advertising type that allows
|
||||
* for Scan Requests.
|
||||
*
|
||||
* If sd was not provided but we enable connectable undirected
|
||||
* If any data was not provided but we enable connectable undirected
|
||||
* advertising sd needs to be cleared from values set by previous calls.
|
||||
* Clearing sd is done by calling set_ad() with NULL data and zero len.
|
||||
* So following condition check is unusual but correct.
|
||||
*/
|
||||
if (sd || (param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
|
||||
err = set_ad(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, sd, sd_len);
|
||||
if (d[0].data || d[1].data ||
|
||||
(param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
|
||||
err = set_ad(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, d, 2);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue