Bluetooth: Add support for setting LE advertising data
This patch adds support for setting basing LE advertising data. The three elements supported for now are the advertising flags, the TX power and the friendly name. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This commit is contained in:
committed by
Gustavo Padovan
parent
bbaf444a89
commit
3f0f524baf
@@ -594,6 +594,99 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
|
||||
{
|
||||
u8 ad_len = 0, flags = 0;
|
||||
size_t name_len;
|
||||
|
||||
if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
|
||||
flags |= LE_AD_GENERAL;
|
||||
|
||||
if (!lmp_bredr_capable(hdev))
|
||||
flags |= LE_AD_NO_BREDR;
|
||||
|
||||
if (lmp_le_br_capable(hdev))
|
||||
flags |= LE_AD_SIM_LE_BREDR_CTRL;
|
||||
|
||||
if (lmp_host_le_br_capable(hdev))
|
||||
flags |= LE_AD_SIM_LE_BREDR_HOST;
|
||||
|
||||
if (flags) {
|
||||
BT_DBG("adv flags 0x%02x", flags);
|
||||
|
||||
ptr[0] = 2;
|
||||
ptr[1] = EIR_FLAGS;
|
||||
ptr[2] = flags;
|
||||
|
||||
ad_len += 3;
|
||||
ptr += 3;
|
||||
}
|
||||
|
||||
if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) {
|
||||
ptr[0] = 2;
|
||||
ptr[1] = EIR_TX_POWER;
|
||||
ptr[2] = (u8) hdev->adv_tx_power;
|
||||
|
||||
ad_len += 3;
|
||||
ptr += 3;
|
||||
}
|
||||
|
||||
name_len = strlen(hdev->dev_name);
|
||||
if (name_len > 0) {
|
||||
size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
|
||||
|
||||
if (name_len > max_len) {
|
||||
name_len = max_len;
|
||||
ptr[1] = EIR_NAME_SHORT;
|
||||
} else
|
||||
ptr[1] = EIR_NAME_COMPLETE;
|
||||
|
||||
ptr[0] = name_len + 1;
|
||||
|
||||
memcpy(ptr + 2, hdev->dev_name, name_len);
|
||||
|
||||
ad_len += (name_len + 2);
|
||||
ptr += (name_len + 2);
|
||||
}
|
||||
|
||||
return ad_len;
|
||||
}
|
||||
|
||||
int hci_update_ad(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_cp_le_set_adv_data cp;
|
||||
u8 len;
|
||||
int err;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (!lmp_le_capable(hdev)) {
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
len = create_ad(hdev, cp.data);
|
||||
|
||||
if (hdev->adv_data_len == len &&
|
||||
memcmp(cp.data, hdev->adv_data, len) == 0) {
|
||||
err = 0;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
|
||||
hdev->adv_data_len = len;
|
||||
|
||||
cp.length = len;
|
||||
err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---- HCI ioctl helpers ---- */
|
||||
|
||||
int hci_dev_open(__u16 dev)
|
||||
@@ -651,6 +744,7 @@ int hci_dev_open(__u16 dev)
|
||||
hci_dev_hold(hdev);
|
||||
set_bit(HCI_UP, &hdev->flags);
|
||||
hci_notify(hdev, HCI_DEV_UP);
|
||||
hci_update_ad(hdev);
|
||||
if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
|
||||
mgmt_valid_hdev(hdev)) {
|
||||
hci_dev_lock(hdev);
|
||||
|
Reference in New Issue
Block a user