Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
fork
Configure Feed
Select the types of activity you want to include in your feed.
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#include <asm/unaligned.h>
9
10void eir_create(struct hci_dev *hdev, u8 *data);
11
12u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
13u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
14
15u8 eir_append_local_name(struct hci_dev *hdev, u8 *eir, u8 ad_len);
16u8 eir_append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len);
17u8 eir_append_service_data(u8 *eir, u16 eir_len, u16 uuid, u8 *data,
18 u8 data_len);
19
20static inline u16 eir_precalc_len(u8 data_len)
21{
22 return sizeof(u8) * 2 + data_len;
23}
24
25static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type,
26 u8 *data, u8 data_len)
27{
28 eir[eir_len++] = sizeof(type) + data_len;
29 eir[eir_len++] = type;
30 memcpy(&eir[eir_len], data, data_len);
31 eir_len += data_len;
32
33 return eir_len;
34}
35
36static inline u16 eir_append_le16(u8 *eir, u16 eir_len, u8 type, u16 data)
37{
38 eir[eir_len++] = sizeof(type) + sizeof(data);
39 eir[eir_len++] = type;
40 put_unaligned_le16(data, &eir[eir_len]);
41 eir_len += sizeof(data);
42
43 return eir_len;
44}
45
46static inline u16 eir_skb_put_data(struct sk_buff *skb, u8 type, u8 *data, u8 data_len)
47{
48 u8 *eir;
49 u16 eir_len;
50
51 eir_len = eir_precalc_len(data_len);
52 eir = skb_put(skb, eir_len);
53 WARN_ON(sizeof(type) + data_len > U8_MAX);
54 eir[0] = sizeof(type) + data_len;
55 eir[1] = type;
56 memcpy(&eir[2], data, data_len);
57
58 return eir_len;
59}
60
61static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type,
62 size_t *data_len)
63{
64 size_t parsed = 0;
65
66 if (eir_len < 2)
67 return NULL;
68
69 while (parsed < eir_len - 1) {
70 u8 field_len = eir[0];
71
72 if (field_len == 0)
73 break;
74
75 parsed += field_len + 1;
76
77 if (parsed > eir_len)
78 break;
79
80 if (eir[1] != type) {
81 eir += field_len + 1;
82 continue;
83 }
84
85 /* Zero length data */
86 if (field_len == 1)
87 return NULL;
88
89 if (data_len)
90 *data_len = field_len - 1;
91
92 return &eir[2];
93 }
94
95 return NULL;
96}
97
98void *eir_get_service_data(u8 *eir, size_t eir_len, u16 uuid, size_t *len);