xref: /openbmc/linux/net/bluetooth/eir.h (revision fe7498ef)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * BlueZ - Bluetooth protocol stack for Linux
4  *
5  * Copyright (C) 2021 Intel Corporation
6  */
7 
8 void eir_create(struct hci_dev *hdev, u8 *data);
9 
10 u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
11 u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
12 
13 u8 eir_append_local_name(struct hci_dev *hdev, u8 *eir, u8 ad_len);
14 u8 eir_append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len);
15 
16 static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type,
17 				  u8 *data, u8 data_len)
18 {
19 	eir[eir_len++] = sizeof(type) + data_len;
20 	eir[eir_len++] = type;
21 	memcpy(&eir[eir_len], data, data_len);
22 	eir_len += data_len;
23 
24 	return eir_len;
25 }
26 
27 static inline u16 eir_append_le16(u8 *eir, u16 eir_len, u8 type, u16 data)
28 {
29 	eir[eir_len++] = sizeof(type) + sizeof(data);
30 	eir[eir_len++] = type;
31 	put_unaligned_le16(data, &eir[eir_len]);
32 	eir_len += sizeof(data);
33 
34 	return eir_len;
35 }
36 
37 static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type,
38 				 size_t *data_len)
39 {
40 	size_t parsed = 0;
41 
42 	if (eir_len < 2)
43 		return NULL;
44 
45 	while (parsed < eir_len - 1) {
46 		u8 field_len = eir[0];
47 
48 		if (field_len == 0)
49 			break;
50 
51 		parsed += field_len + 1;
52 
53 		if (parsed > eir_len)
54 			break;
55 
56 		if (eir[1] != type) {
57 			eir += field_len + 1;
58 			continue;
59 		}
60 
61 		/* Zero length data */
62 		if (field_len == 1)
63 			return NULL;
64 
65 		if (data_len)
66 			*data_len = field_len - 1;
67 
68 		return &eir[2];
69 	}
70 
71 	return NULL;
72 }
73