1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtBluetooth module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef BLUEZ_DATA_P_H
41#define BLUEZ_DATA_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <QtCore/qglobal.h>
55#include <QtCore/qendian.h>
56#include <sys/socket.h>
57#include <QtBluetooth/QBluetoothUuid>
58
59QT_BEGIN_NAMESPACE
60
61#define ATTRIBUTE_CHANNEL_ID 4
62#define SIGNALING_CHANNEL_ID 5
63#define SECURITY_CHANNEL_ID 6
64
65#define BTPROTO_L2CAP 0
66#define BTPROTO_HCI 1
67#define BTPROTO_RFCOMM 3
68
69#define SOL_HCI 0
70#define SOL_L2CAP 6
71#define SOL_RFCOMM 18
72#ifndef SOL_BLUETOOTH
73#define SOL_BLUETOOTH 274
74#endif
75
76#define RFCOMM_LM 0x03
77
78#define RFCOMM_LM_AUTH 0x0002
79#define RFCOMM_LM_ENCRYPT 0x0004
80#define RFCOMM_LM_TRUSTED 0x0008
81#define RFCOMM_LM_SECURE 0x0020
82
83#define L2CAP_LM 0x03
84#define L2CAP_LM_AUTH 0x0002
85#define L2CAP_LM_ENCRYPT 0x0004
86#define L2CAP_LM_TRUSTED 0x0008
87#define L2CAP_LM_SECURE 0x0020
88
89#define BT_SECURITY 4
90struct bt_security {
91 quint8 level;
92 quint8 key_size;
93};
94#define BT_SECURITY_SDP 0
95#define BT_SECURITY_LOW 1
96#define BT_SECURITY_MEDIUM 2
97#define BT_SECURITY_HIGH 3
98
99#define BDADDR_LE_PUBLIC 0x01
100#define BDADDR_LE_RANDOM 0x02
101
102#define SCO_LINK 0x00
103#define ACL_LINK 0x01
104#define ESCO_LINK 0x02
105#define LE_LINK 0x80 // based on hcitool.c -> no fixed constant available
106
107/* Byte order conversions */
108#if __BYTE_ORDER == __LITTLE_ENDIAN
109#define htobs(d) (d)
110#define htobl(d) (d)
111#define htobll(d) (d)
112#define btohs(d) (d)
113#define btohl(d) (d)
114#define btohll(d) (d)
115#elif __BYTE_ORDER == __BIG_ENDIAN
116#define htobs(d) qbswap((quint16)(d))
117#define htobl(d) qbswap((quint32)(d))
118#define htobll(d) qbswap((quint64)(d))
119#define btohs(d) qbswap((quint16)(d))
120#define btohl(d) qbswap((quint32)(d))
121#define btohll(d) qbswap((quint64)(d))
122#else
123#error "Unknown byte order"
124#endif
125
126#define HCIGETCONNLIST _IOR('H', 212, int)
127#define HCIGETDEVINFO _IOR('H', 211, int)
128#define HCIGETDEVLIST _IOR('H', 210, int)
129
130// Bluetooth address
131typedef struct {
132 quint8 b[6];
133} __attribute__((packed)) bdaddr_t;
134
135// L2CP socket
136struct sockaddr_l2 {
137 sa_family_t l2_family;
138 unsigned short l2_psm;
139 bdaddr_t l2_bdaddr;
140 unsigned short l2_cid;
141#if !defined(QT_BLUEZ_NO_BTLE)
142 quint8 l2_bdaddr_type;
143#endif
144};
145
146// RFCOMM socket
147struct sockaddr_rc {
148 sa_family_t rc_family;
149 bdaddr_t rc_bdaddr;
150 quint8 rc_channel;
151};
152
153// Bt Low Energy related
154
155#if __BYTE_ORDER == __LITTLE_ENDIAN
156
157static inline void btoh128(const quint128 *src, quint128 *dst)
158{
159 memcpy(dst, src, sizeof(quint128));
160}
161
162static inline void ntoh128(const quint128 *src, quint128 *dst)
163{
164 int i;
165
166 for (i = 0; i < 16; i++)
167 dst->data[15 - i] = src->data[i];
168}
169
170#elif __BYTE_ORDER == __BIG_ENDIAN
171
172static inline void btoh128(const quint128 *src, quint128 *dst)
173{
174 int i;
175
176 for (i = 0; i < 16; i++)
177 dst->data[15 - i] = src->data[i];
178}
179
180static inline void ntoh128(const quint128 *src, quint128 *dst)
181{
182 memcpy(dst, src, sizeof(quint128));
183}
184#else
185#error "Unknown byte order"
186#endif
187
188template<typename T> inline T getBtData(const void *ptr)
189{
190 return qFromLittleEndian<T>(reinterpret_cast<const uchar *>(ptr));
191}
192
193static inline quint16 bt_get_le16(const void *ptr)
194{
195 return getBtData<quint16>(ptr);
196}
197
198template<typename T> inline void putBtData(T src, void *dst)
199{
200 qToLittleEndian(src, reinterpret_cast<uchar *>(dst));
201}
202template<> inline void putBtData(quint128 src, void *dst)
203{
204 btoh128(&src, reinterpret_cast<quint128 *>(dst));
205}
206
207#define hton128(x, y) ntoh128(x, y)
208
209// HCI related
210
211#define HCI_MAX_DEV 16
212#define HCI_DEV_NONE 0xffff
213
214#define HCI_CHANNEL_CONTROL 0x3
215
216#define HCI_MAX_EVENT_SIZE 260
217
218// HCI sockopts
219#define HCI_FILTER 2
220
221// HCI packet types
222#define HCI_COMMAND_PKT 0x01
223#define HCI_ACL_PKT 0x02
224#define HCI_EVENT_PKT 0x04
225#define HCI_VENDOR_PKT 0xff
226
227#define HCI_FLT_TYPE_BITS 31
228#define HCI_FLT_EVENT_BITS 63
229
230
231struct sockaddr_hci {
232 sa_family_t hci_family;
233 unsigned short hci_dev;
234 unsigned short hci_channel;
235};
236
237struct hci_dev_req {
238 quint16 dev_id;
239 quint32 dev_opt;
240};
241
242struct hci_dev_list_req {
243 quint16 dev_num;
244 struct hci_dev_req dev_req[0];
245};
246
247struct hci_dev_stats {
248 quint32 err_rx;
249 quint32 err_tx;
250 quint32 cmd_tx;
251 quint32 evt_rx;
252 quint32 acl_tx;
253 quint32 acl_rx;
254 quint32 sco_tx;
255 quint32 sco_rx;
256 quint32 byte_rx;
257 quint32 byte_tx;
258};
259
260struct hci_dev_info {
261 quint16 dev_id;
262 char name[8];
263
264 bdaddr_t bdaddr;
265
266 quint32 flags;
267 quint8 type;
268
269 quint8 features[8];
270
271 quint32 pkt_type;
272 quint32 link_policy;
273 quint32 link_mode;
274
275 quint16 acl_mtu;
276 quint16 acl_pkts;
277 quint16 sco_mtu;
278 quint16 sco_pkts;
279
280 struct hci_dev_stats stat;
281};
282
283struct hci_conn_info {
284 quint16 handle;
285 bdaddr_t bdaddr;
286 quint8 type;
287 quint8 out;
288 quint16 state;
289 quint32 link_mode;
290};
291
292struct hci_conn_list_req {
293 quint16 dev_id;
294 quint16 conn_num;
295 struct hci_conn_info conn_info[0];
296};
297
298struct hci_filter {
299 quint32 type_mask;
300 quint32 event_mask[2];
301 quint16 opcode;
302};
303
304static inline void hci_set_bit(int nr, void *addr)
305{
306 *((quint32 *) addr + (nr >> 5)) |= (1 << (nr & 31));
307}
308static inline void hci_clear_bit(int nr, void *addr)
309{
310 *((quint32 *) addr + (nr >> 5)) &= ~(1 << (nr & 31));
311}
312static inline void hci_filter_clear(struct hci_filter *f)
313{
314 memset(f, 0, sizeof(*f));
315}
316static inline void hci_filter_set_ptype(int t, struct hci_filter *f)
317{
318 hci_set_bit((t == HCI_VENDOR_PKT) ? 0 : (t & HCI_FLT_TYPE_BITS), &f->type_mask);
319}
320static inline void hci_filter_clear_ptype(int t, struct hci_filter *f)
321{
322 hci_clear_bit((t == HCI_VENDOR_PKT) ? 0 : (t & HCI_FLT_TYPE_BITS), &f->type_mask);
323}
324static inline void hci_filter_set_event(int e, struct hci_filter *f)
325{
326 hci_set_bit((e & HCI_FLT_EVENT_BITS), &f->event_mask);
327}
328static inline void hci_filter_clear_event(int e, struct hci_filter *f)
329{
330 hci_clear_bit((e & HCI_FLT_EVENT_BITS), &f->event_mask);
331}
332static inline void hci_filter_all_ptypes(struct hci_filter *f)
333{
334 memset((void *) &f->type_mask, 0xff, sizeof(f->type_mask));
335}
336static inline void hci_filter_all_events(struct hci_filter *f)
337{
338 memset((void *) f->event_mask, 0xff, sizeof(f->event_mask));
339}
340
341typedef struct {
342 quint8 evt;
343 quint8 plen;
344} __attribute__ ((packed)) hci_event_hdr;
345#define HCI_EVENT_HDR_SIZE 2
346
347#define EVT_ENCRYPT_CHANGE 0x08
348typedef struct {
349 quint8 status;
350 quint16 handle;
351 quint8 encrypt;
352} __attribute__ ((packed)) evt_encrypt_change;
353#define EVT_ENCRYPT_CHANGE_SIZE 4
354
355#define EVT_CMD_COMPLETE 0x0E
356struct evt_cmd_complete {
357 quint8 ncmd;
358 quint16 opcode;
359} __attribute__ ((packed));
360
361struct AclData {
362 quint16 handle: 12;
363 quint16 pbFlag: 2;
364 quint16 bcFlag: 2;
365 quint16 dataLen;
366};
367
368struct L2CapHeader {
369 quint16 length;
370 quint16 channelId;
371};
372
373struct hci_command_hdr {
374 quint16 opcode; /* OCF & OGF */
375 quint8 plen;
376} __attribute__ ((packed));
377
378enum OpCodeGroupField {
379 OgfLinkControl = 0x8,
380};
381
382enum OpCodeCommandField {
383 OcfLeSetAdvParams = 0x6,
384 OcfLeReadTxPowerLevel = 0x7,
385 OcfLeSetAdvData = 0x8,
386 OcfLeSetScanResponseData = 0x9,
387 OcfLeSetAdvEnable = 0xa,
388 OcfLeClearWhiteList = 0x10,
389 OcfLeAddToWhiteList = 0x11,
390 OcfLeConnectionUpdate = 0x13,
391};
392
393/* Command opcode pack/unpack */
394#define opCodePack(ogf, ocf) (quint16(((ocf) & 0x03ff)|((ogf) << 10)))
395#define ogfFromOpCode(op) ((op) >> 10)
396#define ocfFromOpCode(op) ((op) & 0x03ff)
397
398QT_END_NAMESPACE
399
400#endif // BLUEZ_DATA_P_H
401