1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 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:GPL-EXCEPT$ |
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 General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <QtTest/QtTest> |
30 | #include <QUuid> |
31 | |
32 | #include <QDebug> |
33 | |
34 | #include <qbluetoothuuid.h> |
35 | |
36 | #if defined(Q_OS_UNIX) |
37 | # include <arpa/inet.h> |
38 | # include <netinet/in.h> |
39 | #endif |
40 | |
41 | QT_USE_NAMESPACE |
42 | |
43 | Q_DECLARE_METATYPE(quint128) |
44 | |
45 | class tst_QBluetoothUuid : public QObject |
46 | { |
47 | Q_OBJECT |
48 | |
49 | public: |
50 | tst_QBluetoothUuid(); |
51 | ~tst_QBluetoothUuid(); |
52 | |
53 | private slots: |
54 | void initTestCase(); |
55 | |
56 | void tst_construction(); |
57 | void tst_assignment(); |
58 | void tst_conversion_data(); |
59 | void tst_conversion(); |
60 | void tst_comparison_data(); |
61 | void tst_comparison(); |
62 | void tst_quint128ToUuid(); |
63 | }; |
64 | |
65 | tst_QBluetoothUuid::tst_QBluetoothUuid() |
66 | { |
67 | qRegisterMetaType<quint128>(); |
68 | } |
69 | |
70 | tst_QBluetoothUuid::~tst_QBluetoothUuid() |
71 | { |
72 | } |
73 | |
74 | void tst_QBluetoothUuid::initTestCase() |
75 | { |
76 | } |
77 | |
78 | void tst_QBluetoothUuid::tst_construction() |
79 | { |
80 | { |
81 | QBluetoothUuid nullUuid; |
82 | |
83 | QVERIFY(nullUuid.isNull()); |
84 | } |
85 | |
86 | { |
87 | QBluetoothUuid uuid(QBluetoothUuid::PublicBrowseGroup); |
88 | |
89 | QVERIFY(!uuid.isNull()); |
90 | |
91 | bool ok; |
92 | quint16 uuid16; |
93 | |
94 | uuid16 = uuid.toUInt16(ok: &ok); |
95 | |
96 | QVERIFY(ok); |
97 | QCOMPARE(uuid16, static_cast<quint16>(QBluetoothUuid::PublicBrowseGroup)); |
98 | } |
99 | |
100 | { |
101 | QBluetoothUuid uuid(QBluetoothUuid::PublicBrowseGroup); |
102 | |
103 | QBluetoothUuid copy(uuid); |
104 | |
105 | QCOMPARE(uuid.toUInt16(), copy.toUInt16()); |
106 | } |
107 | |
108 | { |
109 | QBluetoothUuid uuid(QBluetoothUuid::L2cap); |
110 | |
111 | QVERIFY(!uuid.isNull()); |
112 | |
113 | bool ok; |
114 | quint16 uuid16; |
115 | |
116 | uuid16 = uuid.toUInt16(ok: &ok); |
117 | |
118 | QVERIFY(ok); |
119 | QCOMPARE(uuid16, static_cast<quint16>(QBluetoothUuid::L2cap)); |
120 | } |
121 | |
122 | { |
123 | QUuid uuid(0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee); |
124 | QBluetoothUuid btUuid(uuid); |
125 | QVERIFY(!btUuid.isNull()); |
126 | |
127 | QString uuidString(btUuid.toString()); |
128 | QVERIFY(!uuidString.isEmpty()); |
129 | QCOMPARE(uuidString, QString("{67c8770b-44f1-410a-ab9a-f9b5446f13ee}" )); |
130 | } |
131 | |
132 | { |
133 | QBluetoothUuid btUuid(QString("67c8770b-44f1-410a-ab9a-f9b5446f13ee" )); |
134 | QVERIFY(!btUuid.isNull()); |
135 | |
136 | QString uuidString(btUuid.toString()); |
137 | QVERIFY(!uuidString.isEmpty()); |
138 | QCOMPARE(uuidString, QString("{67c8770b-44f1-410a-ab9a-f9b5446f13ee}" )); |
139 | } |
140 | |
141 | { |
142 | QBluetoothUuid btUuid(QString("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" )); |
143 | QVERIFY(btUuid.isNull()); |
144 | } |
145 | } |
146 | |
147 | void tst_QBluetoothUuid::tst_assignment() |
148 | { |
149 | QBluetoothUuid uuid(QBluetoothUuid::PublicBrowseGroup); |
150 | |
151 | { |
152 | QBluetoothUuid copy = uuid; |
153 | |
154 | QCOMPARE(uuid.toUInt16(), copy.toUInt16()); |
155 | } |
156 | |
157 | { |
158 | QBluetoothUuid copy1; |
159 | QBluetoothUuid copy2; |
160 | |
161 | QVERIFY(copy1.isNull()); |
162 | QVERIFY(copy2.isNull()); |
163 | |
164 | copy1 = copy2 = uuid; |
165 | |
166 | QVERIFY(!copy1.isNull()); |
167 | QVERIFY(!copy2.isNull()); |
168 | |
169 | QCOMPARE(uuid.toUInt16(), copy1.toUInt16()); |
170 | QCOMPARE(uuid.toUInt16(), copy2.toUInt16()); |
171 | } |
172 | } |
173 | |
174 | #define BASEUUID "-0000-1000-8000-00805F9B34FB" |
175 | |
176 | #define UUID128_32(x, a, b, c, d) \ |
177 | quint128 x = { \ |
178 | { \ |
179 | a, b, c, d, \ |
180 | 0x00, 0x00, \ |
181 | 0x10, 0x00, \ |
182 | 0x80, 0x00, \ |
183 | 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB \ |
184 | } \ |
185 | } |
186 | |
187 | #define UUID128_16(x, a, b) UUID128_32(x, 0, 0, a, b) |
188 | |
189 | #define NEWROW16(text, a, b, s) \ |
190 | do { \ |
191 | UUID128_16(uuid128, a, b); \ |
192 | quint32 uuid32 = a << 8 | b; \ |
193 | quint16 uuid16 = a << 8 | b; \ |
194 | QTest::newRow(text) << true << uuid16 << true << uuid32 << true << uuid128 \ |
195 | << (QLatin1Char('{') + QLatin1String(s) + QLatin1Char('}')); \ |
196 | } while (0) |
197 | |
198 | #define NEWROW32(text, a, b, c, d, s) \ |
199 | do { \ |
200 | UUID128_32(uuid128, a, b, c, d); \ |
201 | quint32 uuid32 = a << 24 | b << 16 | c << 8 | d; \ |
202 | quint16 uuid16; \ |
203 | bool constructUuid16 = (a == 0) && (b == 0); \ |
204 | if (constructUuid16) \ |
205 | uuid16 = c << 8 | d; \ |
206 | else \ |
207 | uuid16 = 0; \ |
208 | QTest::newRow(text) << constructUuid16 << uuid16 << true << uuid32 << true << uuid128 \ |
209 | << (QLatin1Char('{') + QLatin1String(s) + QLatin1Char('}')); \ |
210 | } while (0) |
211 | |
212 | void tst_QBluetoothUuid::tst_conversion_data() |
213 | { |
214 | QTest::addColumn<bool>(name: "constructUuid16" ); |
215 | QTest::addColumn<quint16>(name: "uuid16" ); |
216 | QTest::addColumn<bool>(name: "constructUuid32" ); |
217 | QTest::addColumn<quint32>(name: "uuid32" ); |
218 | QTest::addColumn<bool>(name: "constructUuid128" ); |
219 | QTest::addColumn<quint128>(name: "uuid128" ); |
220 | QTest::addColumn<QString>(name: "uuidS" ); |
221 | |
222 | NEWROW32("base uuid" , 0x00, 0x00, 0x00, 0x00, "00000000" BASEUUID); |
223 | NEWROW16("0x0001" , 0x00, 0x01, "00000001" BASEUUID); |
224 | NEWROW16("0xffff" , 0xff, 0xff, "0000FFFF" BASEUUID); |
225 | NEWROW32("0x00010000" , 0x00, 0x01, 0x00, 0x00, "00010000" BASEUUID); |
226 | NEWROW32("0x0001ffff" , 0x00, 0x01, 0xff, 0xff, "0001FFFF" BASEUUID); |
227 | NEWROW32("0xffff0000" , 0xff, 0xff, 0x00, 0x00, "FFFF0000" BASEUUID); |
228 | NEWROW32("0xffffffff" , 0xff, 0xff, 0xff, 0xff, "FFFFFFFF" BASEUUID); |
229 | |
230 | { |
231 | quint128 uuid128 = { |
232 | .data: { |
233 | 0x00, 0x11, 0x22, 0x33, |
234 | 0x44, 0x55, |
235 | 0x66, 0x77, |
236 | 0x88, 0x99, |
237 | 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff |
238 | } |
239 | }; |
240 | |
241 | QTest::newRow(dataTag: "00112233-4455-6677-8899-AABBCCDDEEFF" ) |
242 | << false << quint16(0) << false << quint32(0) << true << uuid128 |
243 | << QStringLiteral("{00112233-4455-6677-8899-AABBCCDDEEFF}" ); |
244 | } |
245 | } |
246 | |
247 | void tst_QBluetoothUuid::tst_conversion() |
248 | { |
249 | QFETCH(bool, constructUuid16); |
250 | QFETCH(quint16, uuid16); |
251 | QFETCH(bool, constructUuid32); |
252 | QFETCH(quint32, uuid32); |
253 | QFETCH(bool, constructUuid128); |
254 | QFETCH(quint128, uuid128); |
255 | QFETCH(QString, uuidS); |
256 | |
257 | int minimumSize = 16; |
258 | if (constructUuid16) |
259 | minimumSize = 2; |
260 | else if (constructUuid32) |
261 | minimumSize = 4; |
262 | |
263 | if (constructUuid16) { |
264 | QBluetoothUuid uuid(uuid16); |
265 | |
266 | bool ok; |
267 | |
268 | QCOMPARE(uuid.toUInt16(&ok), uuid16); |
269 | QVERIFY(ok); |
270 | |
271 | QCOMPARE(uuid.toUInt32(&ok), uuid32); |
272 | QVERIFY(ok); |
273 | |
274 | QVERIFY(memcmp(uuid.toUInt128().data, uuid128.data, 16) == 0); |
275 | |
276 | QCOMPARE(uuid.toString().toUpper(), uuidS.toUpper()); |
277 | |
278 | QCOMPARE(uuid.minimumSize(), minimumSize); |
279 | } |
280 | |
281 | if (constructUuid32) { |
282 | QBluetoothUuid uuid(uuid32); |
283 | |
284 | bool ok; |
285 | |
286 | quint16 tmp = uuid.toUInt16(ok: &ok); |
287 | QCOMPARE(ok, constructUuid16); |
288 | if (ok) { |
289 | QCOMPARE(tmp, uuid16); |
290 | } |
291 | |
292 | QCOMPARE(uuid.toUInt32(&ok), uuid32); |
293 | QVERIFY(ok); |
294 | |
295 | QVERIFY(memcmp(uuid.toUInt128().data, uuid128.data, 16) == 0); |
296 | |
297 | QCOMPARE(uuid.toString().toUpper(), uuidS.toUpper()); |
298 | |
299 | QCOMPARE(uuid.minimumSize(), minimumSize); |
300 | } |
301 | |
302 | if (constructUuid128) { |
303 | QBluetoothUuid uuid(uuid128); |
304 | |
305 | bool ok; |
306 | |
307 | quint16 tmpUuid16 = uuid.toUInt16(ok: &ok); |
308 | QCOMPARE(ok, constructUuid16); |
309 | if (ok) |
310 | QCOMPARE(tmpUuid16, uuid16); |
311 | |
312 | quint32 tmpUuid32 = uuid.toUInt32(ok: &ok); |
313 | QCOMPARE(ok, constructUuid32); |
314 | if (ok) |
315 | QCOMPARE(tmpUuid32, uuid32); |
316 | |
317 | QVERIFY(memcmp(uuid.toUInt128().data, uuid128.data, 16) == 0); |
318 | |
319 | QCOMPARE(uuid.toString().toUpper(), uuidS.toUpper()); |
320 | |
321 | QCOMPARE(uuid.minimumSize(), minimumSize); |
322 | } |
323 | } |
324 | |
325 | void tst_QBluetoothUuid::tst_comparison_data() |
326 | { |
327 | tst_conversion_data(); |
328 | } |
329 | |
330 | void tst_QBluetoothUuid::tst_comparison() |
331 | { |
332 | QFETCH(bool, constructUuid16); |
333 | QFETCH(quint16, uuid16); |
334 | QFETCH(bool, constructUuid32); |
335 | QFETCH(quint32, uuid32); |
336 | QFETCH(bool, constructUuid128); |
337 | QFETCH(quint128, uuid128); |
338 | |
339 | QVERIFY(QBluetoothUuid() == QBluetoothUuid()); |
340 | |
341 | if (constructUuid16) { |
342 | QBluetoothUuid quuid16(uuid16); |
343 | QBluetoothUuid quuid32(uuid32); |
344 | QBluetoothUuid quuid128(uuid128); |
345 | |
346 | QVERIFY(quuid16.toUInt16() == uuid16); |
347 | QVERIFY(quuid16.toUInt32() == uuid32); |
348 | |
349 | QVERIFY(quuid16 == quuid32); |
350 | QVERIFY(quuid16 == quuid128); |
351 | |
352 | QVERIFY(quuid32 == quuid16); |
353 | QVERIFY(quuid128 == quuid16); |
354 | } |
355 | |
356 | if (constructUuid32) { |
357 | QBluetoothUuid quuid32(uuid32); |
358 | QBluetoothUuid quuid128(uuid128); |
359 | |
360 | QVERIFY(quuid32.toUInt32() == uuid32); |
361 | QVERIFY(quuid32 == quuid128); |
362 | |
363 | QVERIFY(quuid128 == quuid32); |
364 | } |
365 | |
366 | if (constructUuid128) { |
367 | QBluetoothUuid quuid128(uuid128); |
368 | |
369 | for (int var = 0; var < 16; ++var) { |
370 | QVERIFY(quuid128.toUInt128().data[var] == uuid128.data[var]); |
371 | } |
372 | } |
373 | } |
374 | |
375 | void tst_QBluetoothUuid::tst_quint128ToUuid() |
376 | { |
377 | QBluetoothUuid temp(QString("{67C8770B-44F1-410A-AB9A-F9B5446F13EE}" )); |
378 | quint128 array = temp.toUInt128(); |
379 | QBluetoothUuid u(array); |
380 | QVERIFY(temp == u); |
381 | |
382 | QBENCHMARK { |
383 | QBluetoothUuid u(array); |
384 | } |
385 | } |
386 | QTEST_MAIN(tst_QBluetoothUuid) |
387 | |
388 | #include "tst_qbluetoothuuid.moc" |
389 | |