1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Copyright (C) 2014 Denis Shienkov <denis.shienkov@gmail.com>
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtBluetooth module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 #ifndef QWINLOWENERGYBLUETOOTH_P_H
42 #define QWINLOWENERGYBLUETOOTH_P_H
43
44 //
45 // W A R N I N G
46 // -------------
47 //
48 // This file is not part of the Qt API. It exists purely as an
49 // implementation detail. This header file may change from version to
50 // version without notice, or even be removed.
51 //
52 // We mean it.
53 //
54
55 #include <QtCore/qlibrary.h>
56
57 #include <qt_windows.h>
58
59 #define WIN32_FROM_HRESULT(hr) \
60 (SUCCEEDED(hr) ? ERROR_SUCCESS : \
61 (HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : (hr)))
62
63 #define BLUETOOTH_GATT_FLAG_NONE 0x00000000
64 #define BLUETOOTH_GATT_FLAG_CONNECTION_ENCRYPTED 0x00000001
65 #define BLUETOOTH_GATT_FLAG_CONNECTION_AUTHENTICATED 0x00000002
66 #define BLUETOOTH_GATT_FLAG_FORCE_READ_FROM_DEVICE 0x00000004
67 #define BLUETOOTH_GATT_FLAG_FORCE_READ_FROM_CACHE 0x00000008
68 #define BLUETOOTH_GATT_FLAG_SIGNED_WRITE 0x00000010
69 #define BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE 0x00000020
70 #define BLUETOOTH_GATT_FLAG_RETURN_ALL 0x00000040
71
72 typedef enum _BTH_LE_GATT_DESCRIPTOR_TYPE {
73 CharacteristicExtendedProperties,
74 CharacteristicUserDescription,
75 ClientCharacteristicConfiguration,
76 ServerCharacteristicConfiguration,
77 CharacteristicFormat,
78 CharacteristicAggregateFormat,
79 CustomDescriptor
80 } BTH_LE_GATT_DESCRIPTOR_TYPE, *PBTH_LE_GATT_DESCRIPTOR_TYPE;
81
82 typedef enum _BTH_LE_GATT_EVENT_TYPE {
83 CharacteristicValueChangedEvent
84 } BTH_LE_GATT_EVENT_TYPE;
85
86 typedef struct _BTH_LE_UUID {
87 BOOLEAN IsShortUuid;
88 union {
89 USHORT ShortUuid;
90 GUID LongUuid;
91 } Value;
92 } BTH_LE_UUID, *PBTH_LE_UUID;
93
94 typedef struct _BTH_LE_GATT_SERVICE {
95 BTH_LE_UUID ServiceUuid;
96 USHORT AttributeHandle;
97 } BTH_LE_GATT_SERVICE, *PBTH_LE_GATT_SERVICE;
98
99 typedef struct _BTH_LE_GATT_CHARACTERISTIC {
100 USHORT ServiceHandle;
101 BTH_LE_UUID CharacteristicUuid;
102 USHORT AttributeHandle;
103 USHORT CharacteristicValueHandle;
104 BOOLEAN IsBroadcastable;
105 BOOLEAN IsReadable;
106 BOOLEAN IsWritable;
107 BOOLEAN IsWritableWithoutResponse;
108 BOOLEAN IsSignedWritable;
109 BOOLEAN IsNotifiable;
110 BOOLEAN IsIndicatable;
111 BOOLEAN HasExtendedProperties;
112 } BTH_LE_GATT_CHARACTERISTIC, *PBTH_LE_GATT_CHARACTERISTIC;
113
114 typedef struct _BTH_LE_GATT_CHARACTERISTIC_VALUE {
115 ULONG DataSize;
116 UCHAR Data[1];
117 } BTH_LE_GATT_CHARACTERISTIC_VALUE, *PBTH_LE_GATT_CHARACTERISTIC_VALUE;
118
119 typedef struct _BTH_LE_GATT_DESCRIPTOR {
120 USHORT ServiceHandle;
121 USHORT CharacteristicHandle;
122 BTH_LE_GATT_DESCRIPTOR_TYPE DescriptorType;
123 BTH_LE_UUID DescriptorUuid;
124 USHORT AttributeHandle;
125 } BTH_LE_GATT_DESCRIPTOR, *PBTH_LE_GATT_DESCRIPTOR;
126
127 typedef struct _BTH_LE_GATT_DESCRIPTOR_VALUE {
128 BTH_LE_GATT_DESCRIPTOR_TYPE DescriptorType;
129 BTH_LE_UUID DescriptorUuid;
130 union {
131 struct {
132 BOOLEAN IsReliableWriteEnabled;
133 BOOLEAN IsAuxiliariesWritable;
134 } CharacteristicExtendedProperties;
135 struct {
136 BOOLEAN IsSubscribeToNotification;
137 BOOLEAN IsSubscribeToIndication;
138 } ClientCharacteristicConfiguration;
139 struct {
140 BOOLEAN IsBroadcast;
141 } ServerCharacteristicConfiguration;
142 struct {
143 UCHAR Format;
144 UCHAR Exponent;
145 BTH_LE_UUID Unit;
146 UCHAR NameSpace;
147 BTH_LE_UUID Description;
148 } CharacteristicFormat;
149 };
150 ULONG DataSize;
151 UCHAR Data[1];
152 } BTH_LE_GATT_DESCRIPTOR_VALUE, *PBTH_LE_GATT_DESCRIPTOR_VALUE;
153
154 typedef struct _BLUETOOTH_GATT_VALUE_CHANGED_EVENT {
155 USHORT ChangedAttributeHandle;
156 size_t CharacteristicValueDataSize;
157 PBTH_LE_GATT_CHARACTERISTIC_VALUE CharacteristicValue;
158 } BLUETOOTH_GATT_VALUE_CHANGED_EVENT, *PBLUETOOTH_GATT_VALUE_CHANGED_EVENT;
159
160 typedef struct _BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION {
161 USHORT NumCharacteristics;
162 BTH_LE_GATT_CHARACTERISTIC Characteristics[1];
163 } BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION, *PBLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION;
164
165 typedef VOID (CALLBACK *PFNBLUETOOTH_GATT_EVENT_CALLBACK)(
166 BTH_LE_GATT_EVENT_TYPE EventType,
167 PVOID EventOutParameter,
168 PVOID Context
169 );
170
171 typedef ULONG64 BTH_LE_GATT_RELIABLE_WRITE_CONTEXT, *PBTH_LE_GATT_RELIABLE_WRITE_CONTEXT;
172
173 #define DEFINEFUNC(ret, func, ...) \
174 typedef ret (WINAPI *fp_##func)(__VA_ARGS__); \
175 static fp_##func func;
176
177 #define RESOLVEFUNC(func) \
178 func = (fp_##func)resolveFunction(library, #func); \
179 if (!func) \
180 return false;
181
DEFINEFUNC(HRESULT,BluetoothGATTGetServices,HANDLE,USHORT,PBTH_LE_GATT_SERVICE,PUSHORT,ULONG)182 DEFINEFUNC(HRESULT, BluetoothGATTGetServices, HANDLE, USHORT, PBTH_LE_GATT_SERVICE, PUSHORT, ULONG)
183 DEFINEFUNC(HRESULT, BluetoothGATTGetIncludedServices, HANDLE, PBTH_LE_GATT_SERVICE, USHORT, PBTH_LE_GATT_SERVICE, PUSHORT, ULONG)
184 DEFINEFUNC(HRESULT, BluetoothGATTGetCharacteristics, HANDLE, PBTH_LE_GATT_SERVICE, USHORT, PBTH_LE_GATT_CHARACTERISTIC, PUSHORT, ULONG)
185 DEFINEFUNC(HRESULT, BluetoothGATTGetDescriptors, HANDLE, PBTH_LE_GATT_CHARACTERISTIC, USHORT, PBTH_LE_GATT_DESCRIPTOR, PUSHORT, ULONG)
186 DEFINEFUNC(HRESULT, BluetoothGATTGetCharacteristicValue, HANDLE, PBTH_LE_GATT_CHARACTERISTIC, ULONG, PBTH_LE_GATT_CHARACTERISTIC_VALUE, PUSHORT, ULONG)
187 DEFINEFUNC(HRESULT, BluetoothGATTGetDescriptorValue, HANDLE, PBTH_LE_GATT_DESCRIPTOR, ULONG, PBTH_LE_GATT_DESCRIPTOR_VALUE, PUSHORT, ULONG)
188 DEFINEFUNC(HRESULT, BluetoothGATTBeginReliableWrite, HANDLE, PBTH_LE_GATT_RELIABLE_WRITE_CONTEXT, ULONG)
189 DEFINEFUNC(HRESULT, BluetoothGATTEndReliableWrite, HANDLE, BTH_LE_GATT_RELIABLE_WRITE_CONTEXT, ULONG)
190 DEFINEFUNC(HRESULT, BluetoothGATTAbortReliableWrite, HANDLE, BTH_LE_GATT_RELIABLE_WRITE_CONTEXT, ULONG)
191 DEFINEFUNC(HRESULT, BluetoothGATTSetCharacteristicValue, HANDLE, PBTH_LE_GATT_CHARACTERISTIC, PBTH_LE_GATT_CHARACTERISTIC_VALUE, BTH_LE_GATT_RELIABLE_WRITE_CONTEXT, ULONG)
192 DEFINEFUNC(HRESULT, BluetoothGATTSetDescriptorValue, HANDLE, PBTH_LE_GATT_DESCRIPTOR, PBTH_LE_GATT_DESCRIPTOR_VALUE, ULONG)
193 DEFINEFUNC(HRESULT, BluetoothGATTRegisterEvent, HANDLE, BTH_LE_GATT_EVENT_TYPE, PVOID, PFNBLUETOOTH_GATT_EVENT_CALLBACK, PVOID, PHANDLE, ULONG)
194 DEFINEFUNC(HRESULT, BluetoothGATTUnregisterEvent, HANDLE, ULONG)
195
196 static inline QFunctionPointer resolveFunction(QLibrary *library, const char *func)
197 {
198 QFunctionPointer symbolFunctionPointer = library->resolve(func);
199 if (!symbolFunctionPointer)
200 qWarning("Cannot resolve '%s' in '%s'.", func, qPrintable(library->fileName()));
201 return symbolFunctionPointer;
202 }
203
resolveFunctions(QLibrary * library)204 static inline bool resolveFunctions(QLibrary *library)
205 {
206 if (!library->isLoaded()) {
207 library->setFileName(QStringLiteral("bluetoothapis"));
208 if (!library->load()) {
209 qWarning("Unable to load '%s' library.", qPrintable(library->fileName()));
210 return false;
211 }
212 }
213
214 RESOLVEFUNC(BluetoothGATTGetServices)
215 RESOLVEFUNC(BluetoothGATTGetIncludedServices)
216 RESOLVEFUNC(BluetoothGATTGetCharacteristics)
217 RESOLVEFUNC(BluetoothGATTGetDescriptors)
218 RESOLVEFUNC(BluetoothGATTGetCharacteristicValue)
219 RESOLVEFUNC(BluetoothGATTGetDescriptorValue)
220 RESOLVEFUNC(BluetoothGATTBeginReliableWrite)
221 RESOLVEFUNC(BluetoothGATTEndReliableWrite)
222 RESOLVEFUNC(BluetoothGATTAbortReliableWrite)
223 RESOLVEFUNC(BluetoothGATTSetCharacteristicValue)
224 RESOLVEFUNC(BluetoothGATTSetDescriptorValue)
225 RESOLVEFUNC(BluetoothGATTRegisterEvent)
226 RESOLVEFUNC(BluetoothGATTUnregisterEvent)
227
228 return true;
229 }
230
231 #endif // QWINLOWENERGYBLUETOOTH_P_H
232