3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2015 Intel Corporation. All rights reserved.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <sys/socket.h>
35 #include "lib/bluetooth.h"
38 #include "src/shared/util.h"
39 #include "src/shared/tester.h"
40 #include "src/shared/queue.h"
41 #include "src/shared/att.h"
42 #include "src/shared/gatt-db.h"
44 #include "attrib/gattrib.h"
46 #include "profiles/input/hog-lib.h"
56 struct test_pdu *pdu_list;
65 unsigned int pdu_offset;
66 const struct test_data *data;
69 #define data(args...) ((const unsigned char[]) { args })
71 #define raw_pdu(args...) \
75 .size = sizeof(data(args)),\
83 #define define_test(name, function, args...) \
85 const struct test_pdu pdus[] = { \
88 static struct test_data data; \
89 data.test_name = g_strdup(name); \
90 data.pdu_list = g_memdup(pdus, sizeof(pdus)); \
91 tester_add(name, &data, NULL, function, NULL); \
94 static void test_debug(const char *str, void *user_data)
96 const char *prefix = user_data;
98 tester_debug("%s%s", prefix, str);
101 static gboolean context_quit(gpointer user_data)
103 struct context *context = user_data;
105 if (context->process > 0)
106 g_source_remove(context->process);
108 if (context->source > 0)
109 g_source_remove(context->source);
111 bt_hog_unref(context->hog);
113 g_attrib_unref(context->attrib);
117 tester_test_passed();
122 static gboolean send_pdu(gpointer user_data)
124 struct context *context = user_data;
125 const struct test_pdu *pdu;
128 pdu = &context->data->pdu_list[context->pdu_offset++];
130 len = write(context->fd, pdu->data, pdu->size);
132 util_hexdump('<', pdu->data, len, test_debug, "hog: ");
134 g_assert_cmpint(len, ==, pdu->size);
136 context->process = 0;
138 if (!context->data->pdu_list[context->pdu_offset].valid)
139 context_quit(context);
144 static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
147 struct context *context = user_data;
148 unsigned char buf[512];
149 const struct test_pdu *pdu;
153 pdu = &context->data->pdu_list[context->pdu_offset++];
155 if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
157 g_print("%s: cond %x\n", __func__, cond);
161 fd = g_io_channel_unix_get_fd(channel);
163 len = read(fd, buf, sizeof(buf));
167 util_hexdump('>', buf, len, test_debug, "hog: ");
169 g_assert_cmpint(len, ==, pdu->size);
171 g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
173 context->process = g_idle_add(send_pdu, context);
178 static struct context *create_context(gconstpointer data)
180 struct context *context;
181 GIOChannel *channel, *att_io;
183 char name[] = "bluez-hog";
184 uint16_t vendor = 0x0002;
185 uint16_t product = 0x0001;
186 uint16_t version = 0x0001;
188 context = g_new0(struct context, 1);
189 err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
192 att_io = g_io_channel_unix_new(sv[0]);
194 g_io_channel_set_close_on_unref(att_io, TRUE);
196 context->attrib = g_attrib_new(att_io, 23, false);
197 g_assert(context->attrib);
199 g_io_channel_unref(att_io);
201 fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
204 context->hog = bt_hog_new(fd, name, vendor, product, version, NULL);
205 g_assert(context->hog);
207 channel = g_io_channel_unix_new(sv[1]);
209 g_io_channel_set_close_on_unref(channel, TRUE);
210 g_io_channel_set_encoding(channel, NULL, NULL);
211 g_io_channel_set_buffered(channel, FALSE);
213 context->source = g_io_add_watch(channel,
214 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
215 test_handler, context);
216 g_assert(context->source > 0);
218 g_io_channel_unref(channel);
221 context->data = data;
226 static void test_hog(gconstpointer data)
228 struct context *context = create_context(data);
230 g_assert(bt_hog_attach(context->hog, context->attrib));
233 int main(int argc, char *argv[])
235 tester_init(&argc, &argv);
237 define_test("/TP/HGRF/RH/BV-01-I", test_hog,
238 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
239 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x04, 0x00, 0x12,
240 0x18, 0x05, 0x00, 0x08, 0x00, 0x12, 0x18),
241 raw_pdu(0x10, 0x09, 0x00, 0xff, 0xff, 0x00, 0x28),
242 raw_pdu(0x01, 0x10, 0x09, 0x00, 0x0a),
243 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x03, 0x28),
244 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x02, 0x04, 0x00,
246 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x02, 0x28),
247 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
248 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x02, 0x28),
249 raw_pdu(0x01, 0x08, 0x05, 0x00, 0x0a),
250 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x03, 0x28),
251 raw_pdu(0x09, 0x07, 0x07, 0x00, 0x02, 0x08, 0x00,
253 raw_pdu(0x0a, 0x04, 0x00),
254 raw_pdu(0x0b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
255 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
256 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
258 raw_pdu(0x0a, 0x08, 0x00),
259 raw_pdu(0x0b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
260 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
261 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
263 raw_pdu(0x0c, 0x04, 0x00, 0x16, 0x00),
264 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
265 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
266 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
268 raw_pdu(0x0c, 0x08, 0x00, 0x16, 0x00),
269 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
270 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
271 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
273 raw_pdu(0x0c, 0x04, 0x00, 0x2c, 0x00),
274 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
275 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
276 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13),
277 raw_pdu(0x0c, 0x08, 0x00, 0x2c, 0x00),
278 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
279 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
280 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13));
282 define_test("/TP/HGRF/RH/BV-08-I", test_hog,
283 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
284 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x05, 0x00, 0x12,
285 0x18, 0x06, 0x00, 0x0a, 0x00, 0x12, 0x18),
286 raw_pdu(0x10, 0x0b, 0x00, 0xff, 0xff, 0x00, 0x28),
287 raw_pdu(0x01, 0x10, 0x0b, 0x00, 0x0a),
288 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28),
289 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x0a, 0x04, 0x00,
291 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x02, 0x28),
292 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
293 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x02, 0x28),
294 raw_pdu(0x01, 0x08, 0x06, 0x00, 0x0a),
295 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x03, 0x28),
296 raw_pdu(0x09, 0x07, 0x08, 0x00, 0x0a, 0x09, 0x00,
298 raw_pdu(0x08, 0x04, 0x00, 0x05, 0x00, 0x03, 0x28),
299 raw_pdu(0x01, 0x08, 0x04, 0x00, 0x0a),
300 raw_pdu(0x08, 0x09, 0x00, 0x0a, 0x00, 0x03, 0x28),
301 raw_pdu(0x01, 0x08, 0x09, 0x00, 0x0a),
302 raw_pdu(0x0a, 0x04, 0x00),
303 raw_pdu(0x0b, 0xee, 0xee, 0xff, 0xff),
304 raw_pdu(0x04, 0x05, 0x00, 0x05, 0x00),
305 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x08, 0x29),
306 raw_pdu(0x0a, 0x09, 0x00),
307 raw_pdu(0x0b, 0xff, 0xff, 0xee, 0xee),
308 raw_pdu(0x04, 0x0a, 0x00, 0x0a, 0x00),
309 raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x08, 0x29),
310 raw_pdu(0x0a, 0x05, 0x00),
311 raw_pdu(0x0b, 0x01, 0x03),
312 raw_pdu(0x0a, 0x0a, 0x00),
313 raw_pdu(0x0b, 0x02, 0x03));
315 define_test("/TP/HGRF/RH/BV-09-I", test_hog,
316 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
317 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x04, 0x00, 0x12,
318 0x18, 0x05, 0x00, 0x08, 0x00, 0x12, 0x18),
319 raw_pdu(0x10, 0x09, 0x00, 0xff, 0xff, 0x00, 0x28),
320 raw_pdu(0x01, 0x10, 0x09, 0x00, 0x0a),
321 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x03, 0x28),
322 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x02, 0x04, 0x00,
324 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x02, 0x28),
325 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
326 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x02, 0x28),
327 raw_pdu(0x01, 0x08, 0x05, 0x00, 0x0a),
328 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x03, 0x28),
329 raw_pdu(0x09, 0x07, 0x07, 0x00, 0x02, 0x08, 0x00,
331 raw_pdu(0x0a, 0x04, 0x00),
332 raw_pdu(0x0b, 0x01, 0x11, 0x00, 0x01),
333 raw_pdu(0x0a, 0x08, 0x00),
334 raw_pdu(0x0b, 0x01, 0x11, 0x00, 0x01));
336 define_test("/TP/HGRF/RH/BV-06-I", test_hog,
337 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
338 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x05, 0x00, 0x12,
339 0x18, 0x06, 0x00, 0x0a, 0x00, 0x12, 0x18),
340 raw_pdu(0x10, 0x0b, 0x00, 0xff, 0xff, 0x00, 0x28),
341 raw_pdu(0x01, 0x10, 0x0b, 0x00, 0x0a),
342 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28),
343 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x0a, 0x04, 0x00,
345 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x02, 0x28),
346 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
347 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x02, 0x28),
348 raw_pdu(0x01, 0x08, 0x06, 0x00, 0x0a),
349 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x03, 0x28),
350 raw_pdu(0x09, 0x07, 0x08, 0x00, 0x0a, 0x09, 0x00,
352 raw_pdu(0x08, 0x04, 0x00, 0x05, 0x00, 0x03, 0x28),
353 raw_pdu(0x01, 0x08, 0x05, 0x00, 0x0a),
354 raw_pdu(0x08, 0x09, 0x00, 0x0a, 0x00, 0x03, 0x28),
355 raw_pdu(0x01, 0x08, 0x09, 0x00, 0x0a),
356 raw_pdu(0x0a, 0x04, 0x00),
357 raw_pdu(0x0b, 0xee, 0xee, 0xff, 0xff),
358 raw_pdu(0x04, 0x05, 0x00, 0x05, 0x00),
359 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x08, 0x29),
360 raw_pdu(0x0a, 0x09, 0x00),
361 raw_pdu(0x0b, 0xff, 0xff, 0xee, 0xee),
362 raw_pdu(0x04, 0x0a, 0x00, 0x0a, 0x00),
363 raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x08, 0x29),
364 raw_pdu(0x0a, 0x05, 0x00),
365 raw_pdu(0x0b, 0x01, 0x02),
366 raw_pdu(0x0a, 0x0a, 0x00),
367 raw_pdu(0x0b, 0x02, 0x02));
369 define_test("/TP/HGCF/RH/BV-01-I", test_hog,
370 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
371 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x06, 0x00, 0x12,
372 0x18, 0x07, 0x00, 0x0c, 0x00, 0x12, 0x18),
373 raw_pdu(0x10, 0x0d, 0x00, 0xff, 0xff, 0x00, 0x28),
374 raw_pdu(0x01, 0x10, 0x0d, 0x00, 0x0a),
375 raw_pdu(0x08, 0x01, 0x00, 0x06, 0x00, 0x03, 0x28),
376 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x1a, 0x04, 0x00,
378 raw_pdu(0x08, 0x01, 0x00, 0x06, 0x00, 0x02, 0x28),
379 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
380 raw_pdu(0x08, 0x07, 0x00, 0x0c, 0x00, 0x02, 0x28),
381 raw_pdu(0x01, 0x08, 0x07, 0x00, 0x0a),
382 raw_pdu(0x08, 0x07, 0x00, 0x0c, 0x00, 0x03, 0x28),
383 raw_pdu(0x09, 0x07, 0x09, 0x00, 0x1a, 0x0a, 0x00,
385 raw_pdu(0x08, 0x04, 0x00, 0x06, 0x00, 0x03, 0x28),
386 raw_pdu(0x01, 0x08, 0x04, 0x00, 0x0a),
387 raw_pdu(0x08, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x28),
388 raw_pdu(0x01, 0x08, 0x0a, 0x00, 0x0a),
389 raw_pdu(0x0a, 0x04, 0x00),
390 raw_pdu(0x0b, 0xed, 0x00),
391 raw_pdu(0x04, 0x05, 0x00, 0x06, 0x00),
392 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x02, 0x29,
393 0x06, 0x00, 0x08, 0x29),
394 raw_pdu(0x0a, 0x0a, 0x00),
395 raw_pdu(0x0b, 0xed, 0x00),
396 raw_pdu(0x04, 0x0b, 0x00, 0x0c, 0x00),
397 raw_pdu(0x05, 0x01, 0x0b, 0x00, 0x02, 0x29,
398 0x0c, 0x00, 0x08, 0x29),
399 raw_pdu(0x0a, 0x06, 0x00),
400 raw_pdu(0x0b, 0x01, 0x01),
401 raw_pdu(0x0a, 0x0c, 0x00),
402 raw_pdu(0x0b, 0x02, 0x01),
403 raw_pdu(0x0a, 0x05, 0x00),
404 raw_pdu(0x0b, 0x00, 0x00),
405 raw_pdu(0x0a, 0x0b, 0x00),
406 raw_pdu(0x0b, 0x00, 0x00),
407 raw_pdu(0x12, 0x05, 0x00, 0x01, 0x00),
409 raw_pdu(0x12, 0x0b, 0x00, 0x01, 0x00),
412 define_test("/TP/HGRF/RH/BV-02-I", test_hog,
413 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
414 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x05, 0x00, 0x12,
415 0x18, 0x06, 0x00, 0x0a, 0x00, 0x12, 0x18),
416 raw_pdu(0x10, 0x0b, 0x00, 0xff, 0xff, 0x00, 0x28),
417 raw_pdu(0x01, 0x10, 0x0b, 0x00, 0x0a),
418 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28),
419 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x02, 0x04, 0x00,
421 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x02, 0x28),
422 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
423 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x02, 0x28),
424 raw_pdu(0x01, 0x08, 0x06, 0x00, 0x0a),
425 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x03, 0x28),
426 raw_pdu(0x09, 0x07, 0x08, 0x00, 0x02, 0x09, 0x00,
428 raw_pdu(0x08, 0x04, 0x00, 0x05, 0x00, 0x03, 0x28),
429 raw_pdu(0x01, 0x08, 0x04, 0x00, 0x0a),
430 raw_pdu(0x08, 0x09, 0x00, 0x0a, 0x00, 0x03, 0x28),
431 raw_pdu(0x01, 0x08, 0x09, 0x00, 0x0a),
432 raw_pdu(0x0a, 0x04, 0x00),
433 raw_pdu(0x0b, 0x01, 0x02, 0x03),
434 raw_pdu(0x04, 0x05, 0x00, 0x05, 0x00),
435 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x07, 0x29),
436 raw_pdu(0x0a, 0x09, 0x00),
437 raw_pdu(0x0b, 0x01, 0x02, 0x03),
438 raw_pdu(0x04, 0x0a, 0x00, 0x0a, 0x00),
439 raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x07, 0x29),
440 raw_pdu(0x0a, 0x05, 0x00),
441 raw_pdu(0x0b, 0x19, 0x2a),
442 raw_pdu(0x0a, 0x0a, 0x00),
443 raw_pdu(0x0b, 0x19, 0x2a));