1 // SPDX-License-Identifier: GPL-2.0
3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2021 Intel Corporation
8 #include <net/bluetooth/bluetooth.h>
9 #include <net/bluetooth/hci_core.h>
10 #include <net/bluetooth/mgmt.h>
14 #define PNP_INFO_SVCLASS_ID 0x1200
16 u8
eir_append_local_name(struct hci_dev
*hdev
, u8
*ptr
, u8 ad_len
)
21 /* no space left for name (+ type + len) */
22 if ((max_adv_len(hdev
) - ad_len
) < HCI_MAX_SHORT_NAME_LENGTH
+ 2)
25 /* use complete name if present and fits */
26 complete_len
= strnlen(hdev
->dev_name
, sizeof(hdev
->dev_name
));
27 if (complete_len
&& complete_len
<= HCI_MAX_SHORT_NAME_LENGTH
)
28 return eir_append_data(ptr
, ad_len
, EIR_NAME_COMPLETE
,
29 hdev
->dev_name
, complete_len
);
31 /* use short name if present */
32 short_len
= strnlen(hdev
->short_name
, sizeof(hdev
->short_name
));
34 return eir_append_data(ptr
, ad_len
, EIR_NAME_SHORT
,
38 /* use shortened full name if present, we already know that name
39 * is longer then HCI_MAX_SHORT_NAME_LENGTH
42 return eir_append_data(ptr
, ad_len
, EIR_NAME_SHORT
,
44 HCI_MAX_SHORT_NAME_LENGTH
);
49 u8
eir_append_appearance(struct hci_dev
*hdev
, u8
*ptr
, u8 ad_len
)
51 return eir_append_le16(ptr
, ad_len
, EIR_APPEARANCE
, hdev
->appearance
);
54 u8
eir_append_service_data(u8
*eir
, u16 eir_len
, u16 uuid
, u8
*data
,
57 eir
[eir_len
++] = sizeof(u8
) + sizeof(uuid
) + data_len
;
58 eir
[eir_len
++] = EIR_SERVICE_DATA
;
59 put_unaligned_le16(uuid
, &eir
[eir_len
]);
60 eir_len
+= sizeof(uuid
);
61 memcpy(&eir
[eir_len
], data
, data_len
);
67 static u8
*create_uuid16_list(struct hci_dev
*hdev
, u8
*data
, ptrdiff_t len
)
69 u8
*ptr
= data
, *uuids_start
= NULL
;
75 list_for_each_entry(uuid
, &hdev
->uuids
, list
) {
81 uuid16
= get_unaligned_le16(&uuid
->uuid
[12]);
85 if (uuid16
== PNP_INFO_SVCLASS_ID
)
91 uuids_start
[1] = EIR_UUID16_ALL
;
95 /* Stop if not enough space to put next UUID */
96 if ((ptr
- data
) + sizeof(u16
) > len
) {
97 uuids_start
[1] = EIR_UUID16_SOME
;
101 *ptr
++ = (uuid16
& 0x00ff);
102 *ptr
++ = (uuid16
& 0xff00) >> 8;
103 uuids_start
[0] += sizeof(uuid16
);
109 static u8
*create_uuid32_list(struct hci_dev
*hdev
, u8
*data
, ptrdiff_t len
)
111 u8
*ptr
= data
, *uuids_start
= NULL
;
112 struct bt_uuid
*uuid
;
117 list_for_each_entry(uuid
, &hdev
->uuids
, list
) {
118 if (uuid
->size
!= 32)
124 uuids_start
[1] = EIR_UUID32_ALL
;
128 /* Stop if not enough space to put next UUID */
129 if ((ptr
- data
) + sizeof(u32
) > len
) {
130 uuids_start
[1] = EIR_UUID32_SOME
;
134 memcpy(ptr
, &uuid
->uuid
[12], sizeof(u32
));
136 uuids_start
[0] += sizeof(u32
);
142 static u8
*create_uuid128_list(struct hci_dev
*hdev
, u8
*data
, ptrdiff_t len
)
144 u8
*ptr
= data
, *uuids_start
= NULL
;
145 struct bt_uuid
*uuid
;
150 list_for_each_entry(uuid
, &hdev
->uuids
, list
) {
151 if (uuid
->size
!= 128)
157 uuids_start
[1] = EIR_UUID128_ALL
;
161 /* Stop if not enough space to put next UUID */
162 if ((ptr
- data
) + 16 > len
) {
163 uuids_start
[1] = EIR_UUID128_SOME
;
167 memcpy(ptr
, uuid
->uuid
, 16);
169 uuids_start
[0] += 16;
175 void eir_create(struct hci_dev
*hdev
, u8
*data
)
180 name_len
= strnlen(hdev
->dev_name
, sizeof(hdev
->dev_name
));
186 ptr
[1] = EIR_NAME_SHORT
;
188 ptr
[1] = EIR_NAME_COMPLETE
;
191 /* EIR Data length */
192 ptr
[0] = name_len
+ 1;
194 memcpy(ptr
+ 2, hdev
->dev_name
, name_len
);
196 ptr
+= (name_len
+ 2);
199 if (hdev
->inq_tx_power
!= HCI_TX_POWER_INVALID
) {
201 ptr
[1] = EIR_TX_POWER
;
202 ptr
[2] = (u8
)hdev
->inq_tx_power
;
207 if (hdev
->devid_source
> 0) {
209 ptr
[1] = EIR_DEVICE_ID
;
211 put_unaligned_le16(hdev
->devid_source
, ptr
+ 2);
212 put_unaligned_le16(hdev
->devid_vendor
, ptr
+ 4);
213 put_unaligned_le16(hdev
->devid_product
, ptr
+ 6);
214 put_unaligned_le16(hdev
->devid_version
, ptr
+ 8);
219 ptr
= create_uuid16_list(hdev
, ptr
, HCI_MAX_EIR_LENGTH
- (ptr
- data
));
220 ptr
= create_uuid32_list(hdev
, ptr
, HCI_MAX_EIR_LENGTH
- (ptr
- data
));
221 ptr
= create_uuid128_list(hdev
, ptr
, HCI_MAX_EIR_LENGTH
- (ptr
- data
));
224 u8
eir_create_per_adv_data(struct hci_dev
*hdev
, u8 instance
, u8
*ptr
)
226 struct adv_info
*adv
= NULL
;
229 /* Return 0 when the current instance identifier is invalid. */
231 adv
= hci_find_adv_instance(hdev
, instance
);
237 memcpy(ptr
, adv
->per_adv_data
, adv
->per_adv_data_len
);
238 ad_len
+= adv
->per_adv_data_len
;
239 ptr
+= adv
->per_adv_data_len
;
245 u8
eir_create_adv_data(struct hci_dev
*hdev
, u8 instance
, u8
*ptr
)
247 struct adv_info
*adv
= NULL
;
248 u8 ad_len
= 0, flags
= 0;
251 /* Return 0 when the current instance identifier is invalid. */
253 adv
= hci_find_adv_instance(hdev
, instance
);
258 instance_flags
= hci_adv_instance_flags(hdev
, instance
);
260 /* If instance already has the flags set skip adding it once
263 if (adv
&& eir_get_data(adv
->adv_data
, adv
->adv_data_len
, EIR_FLAGS
,
267 /* The Add Advertising command allows userspace to set both the general
268 * and limited discoverable flags.
270 if (instance_flags
& MGMT_ADV_FLAG_DISCOV
)
271 flags
|= LE_AD_GENERAL
;
273 if (instance_flags
& MGMT_ADV_FLAG_LIMITED_DISCOV
)
274 flags
|= LE_AD_LIMITED
;
276 if (!hci_dev_test_flag(hdev
, HCI_BREDR_ENABLED
))
277 flags
|= LE_AD_NO_BREDR
;
279 if (flags
|| (instance_flags
& MGMT_ADV_FLAG_MANAGED_FLAGS
)) {
280 /* If a discovery flag wasn't provided, simply use the global
284 flags
|= mgmt_get_adv_discov_flags(hdev
);
286 /* If flags would still be empty, then there is no need to
287 * include the "Flags" AD field".
301 memcpy(ptr
, adv
->adv_data
, adv
->adv_data_len
);
302 ad_len
+= adv
->adv_data_len
;
303 ptr
+= adv
->adv_data_len
;
306 if (instance_flags
& MGMT_ADV_FLAG_TX_POWER
) {
309 if (ext_adv_capable(hdev
)) {
311 adv_tx_power
= adv
->tx_power
;
313 adv_tx_power
= hdev
->adv_tx_power
;
315 adv_tx_power
= hdev
->adv_tx_power
;
318 /* Provide Tx Power only if we can provide a valid value for it */
319 if (adv_tx_power
!= HCI_TX_POWER_INVALID
) {
321 ptr
[1] = EIR_TX_POWER
;
322 ptr
[2] = (u8
)adv_tx_power
;
332 static u8
create_default_scan_rsp(struct hci_dev
*hdev
, u8
*ptr
)
336 if (hdev
->appearance
)
337 scan_rsp_len
= eir_append_appearance(hdev
, ptr
, scan_rsp_len
);
339 return eir_append_local_name(hdev
, ptr
, scan_rsp_len
);
342 u8
eir_create_scan_rsp(struct hci_dev
*hdev
, u8 instance
, u8
*ptr
)
344 struct adv_info
*adv
;
348 return create_default_scan_rsp(hdev
, ptr
);
350 adv
= hci_find_adv_instance(hdev
, instance
);
354 if ((adv
->flags
& MGMT_ADV_FLAG_APPEARANCE
) && hdev
->appearance
)
355 scan_rsp_len
= eir_append_appearance(hdev
, ptr
, scan_rsp_len
);
357 memcpy(&ptr
[scan_rsp_len
], adv
->scan_rsp_data
, adv
->scan_rsp_len
);
359 scan_rsp_len
+= adv
->scan_rsp_len
;
361 if (adv
->flags
& MGMT_ADV_FLAG_LOCAL_NAME
)
362 scan_rsp_len
= eir_append_local_name(hdev
, ptr
, scan_rsp_len
);
367 void *eir_get_service_data(u8
*eir
, size_t eir_len
, u16 uuid
, size_t *len
)
369 while ((eir
= eir_get_data(eir
, eir_len
, EIR_SERVICE_DATA
, len
))) {
370 u16 value
= get_unaligned_le16(eir
);