tizen 2.4 release
[framework/connectivity/bluez.git] / unit / test-hog.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2015  Intel Corporation. All rights reserved.
6  *
7  *
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.
12  *
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.
17  *
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
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/socket.h>
31 #include <fcntl.h>
32
33 #include <glib.h>
34
35 #include "src/shared/util.h"
36 #include "src/shared/tester.h"
37
38 #include "attrib/gattrib.h"
39
40 #include "android/hog.h"
41
42 struct test_pdu {
43         bool valid;
44         const uint8_t *data;
45         size_t size;
46 };
47
48 struct test_data {
49         char *test_name;
50         struct test_pdu *pdu_list;
51 };
52
53 struct context {
54         GAttrib *attrib;
55         struct bt_hog *hog;
56         guint source;
57         guint process;
58         int fd;
59         unsigned int pdu_offset;
60         const struct test_data *data;
61 };
62
63 #define data(args...) ((const unsigned char[]) { args })
64
65 #define raw_pdu(args...)    \
66 {      \
67         .valid = true,          \
68         .data = data(args), \
69         .size = sizeof(data(args)),\
70 }
71
72 #define false_pdu()     \
73 {                                               \
74                 .valid = false, \
75 }
76
77 #define define_test(name, function, args...)      \
78         do {    \
79                 const struct test_pdu pdus[] = {                        \
80                         args, { }                                       \
81                 };              \
82                 static struct test_data data;      \
83                 data.test_name = g_strdup(name);   \
84                 data.pdu_list = g_memdup(pdus, sizeof(pdus));           \
85                 tester_add(name, &data, NULL, function, NULL);     \
86         } while (0)
87
88 static void test_debug(const char *str, void *user_data)
89 {
90         const char *prefix = user_data;
91
92         tester_debug("%s%s", prefix, str);
93 }
94
95 static gboolean context_quit(gpointer user_data)
96 {
97         struct context *context = user_data;
98
99         if (context->process > 0)
100                 g_source_remove(context->process);
101
102         if (context->source > 0)
103                 g_source_remove(context->source);
104
105         bt_hog_unref(context->hog);
106
107         g_attrib_unref(context->attrib);
108
109         g_free(context);
110
111         tester_test_passed();
112
113         return FALSE;
114 }
115
116 static gboolean send_pdu(gpointer user_data)
117 {
118         struct context *context = user_data;
119         const struct test_pdu *pdu;
120         ssize_t len;
121
122         pdu = &context->data->pdu_list[context->pdu_offset++];
123
124         len = write(context->fd, pdu->data, pdu->size);
125
126         util_hexdump('<', pdu->data, len, test_debug, "hog: ");
127
128         g_assert_cmpint(len, ==, pdu->size);
129
130         context->process = 0;
131
132         if (!context->data->pdu_list[context->pdu_offset].valid)
133                 context_quit(context);
134
135         return FALSE;
136 }
137
138 static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
139                                                         gpointer user_data)
140 {
141         struct context *context = user_data;
142         unsigned char buf[512];
143         const struct test_pdu *pdu;
144         ssize_t len;
145         int fd;
146
147         pdu = &context->data->pdu_list[context->pdu_offset++];
148
149         if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
150                 context->source = 0;
151                 g_print("%s: cond %x\n", __func__, cond);
152                 return FALSE;
153         }
154
155         fd = g_io_channel_unix_get_fd(channel);
156
157         len = read(fd, buf, sizeof(buf));
158
159         g_assert(len > 0);
160
161         util_hexdump('>', buf, len, test_debug, "hog: ");
162
163         g_assert_cmpint(len, ==, pdu->size);
164
165         g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
166
167         context->process = g_idle_add(send_pdu, context);
168
169         return TRUE;
170 }
171
172 static struct context *create_context(gconstpointer data)
173 {
174         struct context *context;
175         GIOChannel *channel, *att_io;
176         int err, sv[2], fd;
177         char name[] = "bluez-hog";
178         uint16_t vendor = 0x0002;
179         uint16_t product = 0x0001;
180         uint16_t version = 0x0001;
181
182         context = g_new0(struct context, 1);
183         err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
184         g_assert(err == 0);
185
186         att_io = g_io_channel_unix_new(sv[0]);
187
188         g_io_channel_set_close_on_unref(att_io, TRUE);
189
190         context->attrib = g_attrib_new(att_io, 23);
191         g_assert(context->attrib);
192
193         g_io_channel_unref(att_io);
194
195         fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
196         g_assert(fd > 0);
197
198         context->hog = bt_hog_new(fd, name, vendor, product, version, NULL);
199         g_assert(context->hog);
200
201         channel = g_io_channel_unix_new(sv[1]);
202
203         g_io_channel_set_close_on_unref(channel, TRUE);
204         g_io_channel_set_encoding(channel, NULL, NULL);
205         g_io_channel_set_buffered(channel, FALSE);
206
207         context->source = g_io_add_watch(channel,
208                                 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
209                                 test_handler, context);
210         g_assert(context->source > 0);
211
212         g_io_channel_unref(channel);
213
214         context->fd = sv[1];
215         context->data = data;
216
217         return context;
218 }
219
220 static void test_hog(gconstpointer data)
221 {
222         struct context *context = create_context(data);
223
224         g_assert(bt_hog_attach(context->hog, context->attrib));
225 }
226
227 int main(int argc, char *argv[])
228 {
229         tester_init(&argc, &argv);
230
231         define_test("/TP/HGRF/RH/BV-01-I", test_hog,
232                 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
233                 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x04, 0x00, 0x12,
234                         0x18, 0x05, 0x00, 0x08, 0x00, 0x12, 0x18),
235                 raw_pdu(0x10, 0x09, 0x00, 0xff, 0xff, 0x00, 0x28),
236                 raw_pdu(0x01, 0x10, 0x09, 0x00, 0x0a),
237                 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x03, 0x28),
238                 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x02, 0x04, 0x00,
239                         0x4b, 0x2a),
240                 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x02, 0x28),
241                 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
242                 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x02, 0x28),
243                 raw_pdu(0x01, 0x08, 0x05, 0x00, 0x0a),
244                 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x03, 0x28),
245                 raw_pdu(0x09, 0x07, 0x07, 0x00, 0x02, 0x08, 0x00,
246                         0x4b, 0x2a),
247                 raw_pdu(0x0a, 0x04, 0x00),
248                 raw_pdu(0x0b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
249                         0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
250                         0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
251                         0x15, 0x16),
252                 raw_pdu(0x0a, 0x08, 0x00),
253                 raw_pdu(0x0b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
254                         0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
255                         0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
256                         0x15, 0x16),
257                 raw_pdu(0x0c, 0x04, 0x00, 0x16, 0x00),
258                 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
259                         0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
260                         0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
261                         0x15, 0x16),
262                 raw_pdu(0x0c, 0x08, 0x00, 0x16, 0x00),
263                 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
264                         0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
265                         0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
266                         0x15, 0x16),
267                 raw_pdu(0x0c, 0x04, 0x00, 0x2c, 0x00),
268                 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
269                         0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
270                         0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13),
271                 raw_pdu(0x0c, 0x08, 0x00, 0x2c, 0x00),
272                 raw_pdu(0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
273                         0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
274                         0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13));
275
276         define_test("/TP/HGRF/RH/BV-08-I", test_hog,
277                 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
278                 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x05, 0x00, 0x12,
279                         0x18, 0x06, 0x00, 0x0a, 0x00, 0x12, 0x18),
280                 raw_pdu(0x10, 0x0b, 0x00, 0xff, 0xff, 0x00, 0x28),
281                 raw_pdu(0x01, 0x10, 0x0b, 0x00, 0x0a),
282                 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28),
283                 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x0a, 0x04, 0x00,
284                         0x4d, 0x2a),
285                 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x02, 0x28),
286                 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
287                 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x02, 0x28),
288                 raw_pdu(0x01, 0x08, 0x06, 0x00, 0x0a),
289                 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x03, 0x28),
290                 raw_pdu(0x09, 0x07, 0x08, 0x00, 0x0a, 0x09, 0x00,
291                         0x4d, 0x2a),
292                 raw_pdu(0x08, 0x04, 0x00, 0x05, 0x00, 0x03, 0x28),
293                 raw_pdu(0x01, 0x08, 0x04, 0x00, 0x0a),
294                 raw_pdu(0x08, 0x09, 0x00, 0x0a, 0x00, 0x03, 0x28),
295                 raw_pdu(0x01, 0x08, 0x09, 0x00, 0x0a),
296                 raw_pdu(0x0a, 0x04, 0x00),
297                 raw_pdu(0x0b, 0xee, 0xee, 0xff, 0xff),
298                 raw_pdu(0x04, 0x05, 0x00, 0x05, 0x00),
299                 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x08, 0x29),
300                 raw_pdu(0x0a, 0x09, 0x00),
301                 raw_pdu(0x0b, 0xff, 0xff, 0xee, 0xee),
302                 raw_pdu(0x04, 0x0a, 0x00, 0x0a, 0x00),
303                 raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x08, 0x29),
304                 raw_pdu(0x0a, 0x05, 0x00),
305                 raw_pdu(0x0b, 0x01, 0x03),
306                 raw_pdu(0x0a, 0x0a, 0x00),
307                 raw_pdu(0x0b, 0x02, 0x03));
308
309         define_test("/TP/HGRF/RH/BV-09-I", test_hog,
310                 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
311                 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x04, 0x00, 0x12,
312                         0x18, 0x05, 0x00, 0x08, 0x00, 0x12, 0x18),
313                 raw_pdu(0x10, 0x09, 0x00, 0xff, 0xff, 0x00, 0x28),
314                 raw_pdu(0x01, 0x10, 0x09, 0x00, 0x0a),
315                 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x03, 0x28),
316                 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x02, 0x04, 0x00,
317                         0x4a, 0x2a),
318                 raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x02, 0x28),
319                 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
320                 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x02, 0x28),
321                 raw_pdu(0x01, 0x08, 0x05, 0x00, 0x0a),
322                 raw_pdu(0x08, 0x05, 0x00, 0x08, 0x00, 0x03, 0x28),
323                 raw_pdu(0x09, 0x07, 0x07, 0x00, 0x02, 0x08, 0x00,
324                         0x4a, 0x2a),
325                 raw_pdu(0x0a, 0x04, 0x00),
326                 raw_pdu(0x0b, 0x01, 0x11, 0x00, 0x01),
327                 raw_pdu(0x0a, 0x08, 0x00),
328                 raw_pdu(0x0b, 0x01, 0x11, 0x00, 0x01));
329
330         define_test("/TP/HGRF/RH/BV-06-I", test_hog,
331                 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
332                 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x05, 0x00, 0x12,
333                         0x18, 0x06, 0x00, 0x0a, 0x00, 0x12, 0x18),
334                 raw_pdu(0x10, 0x0b, 0x00, 0xff, 0xff, 0x00, 0x28),
335                 raw_pdu(0x01, 0x10, 0x0b, 0x00, 0x0a),
336                 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28),
337                 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x0a, 0x04, 0x00,
338                         0x4d, 0x2a),
339                 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x02, 0x28),
340                 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
341                 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x02, 0x28),
342                 raw_pdu(0x01, 0x08, 0x06, 0x00, 0x0a),
343                 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x03, 0x28),
344                 raw_pdu(0x09, 0x07, 0x08, 0x00, 0x0a, 0x09, 0x00,
345                         0x4d, 0x2a),
346                 raw_pdu(0x08, 0x04, 0x00, 0x05, 0x00, 0x03, 0x28),
347                 raw_pdu(0x01, 0x08, 0x05, 0x00, 0x0a),
348                 raw_pdu(0x08, 0x09, 0x00, 0x0a, 0x00, 0x03, 0x28),
349                 raw_pdu(0x01, 0x08, 0x09, 0x00, 0x0a),
350                 raw_pdu(0x0a, 0x04, 0x00),
351                 raw_pdu(0x0b, 0xee, 0xee, 0xff, 0xff),
352                 raw_pdu(0x04, 0x05, 0x00, 0x05, 0x00),
353                 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x08, 0x29),
354                 raw_pdu(0x0a, 0x09, 0x00),
355                 raw_pdu(0x0b, 0xff, 0xff, 0xee, 0xee),
356                 raw_pdu(0x04, 0x0a, 0x00, 0x0a, 0x00),
357                 raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x08, 0x29),
358                 raw_pdu(0x0a, 0x05, 0x00),
359                 raw_pdu(0x0b, 0x01, 0x02),
360                 raw_pdu(0x0a, 0x0a, 0x00),
361                 raw_pdu(0x0b, 0x02, 0x02));
362
363         define_test("/TP/HGCF/RH/BV-01-I", test_hog,
364                 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
365                 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x06, 0x00, 0x12,
366                         0x18, 0x07, 0x00, 0x0c, 0x00, 0x12, 0x18),
367                 raw_pdu(0x10, 0x0d, 0x00, 0xff, 0xff, 0x00, 0x28),
368                 raw_pdu(0x01, 0x10, 0x0d, 0x00, 0x0a),
369                 raw_pdu(0x08, 0x01, 0x00, 0x06, 0x00, 0x03, 0x28),
370                 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x1a, 0x04, 0x00,
371                         0x4d, 0x2a),
372                 raw_pdu(0x08, 0x01, 0x00, 0x06, 0x00, 0x02, 0x28),
373                 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
374                 raw_pdu(0x08, 0x07, 0x00, 0x0c, 0x00, 0x02, 0x28),
375                 raw_pdu(0x01, 0x08, 0x07, 0x00, 0x0a),
376                 raw_pdu(0x08, 0x07, 0x00, 0x0c, 0x00, 0x03, 0x28),
377                 raw_pdu(0x09, 0x07, 0x09, 0x00, 0x1a, 0x0a, 0x00,
378                         0x4d, 0x2a),
379                 raw_pdu(0x08, 0x04, 0x00, 0x06, 0x00, 0x03, 0x28),
380                 raw_pdu(0x01, 0x08, 0x04, 0x00, 0x0a),
381                 raw_pdu(0x08, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x28),
382                 raw_pdu(0x01, 0x08, 0x0a, 0x00, 0x0a),
383                 raw_pdu(0x0a, 0x04, 0x00),
384                 raw_pdu(0x0b, 0xed, 0x00),
385                 raw_pdu(0x04, 0x05, 0x00, 0x06, 0x00),
386                 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x02, 0x29,
387                         0x06, 0x00, 0x08, 0x29),
388                 raw_pdu(0x0a, 0x0a, 0x00),
389                 raw_pdu(0x0b, 0xed, 0x00),
390                 raw_pdu(0x04, 0x0b, 0x00, 0x0c, 0x00),
391                 raw_pdu(0x05, 0x01, 0x0b, 0x00, 0x02, 0x29,
392                         0x0c, 0x00, 0x08, 0x29),
393                 raw_pdu(0x0a, 0x06, 0x00),
394                 raw_pdu(0x0b, 0x01, 0x01),
395                 raw_pdu(0x0a, 0x0c, 0x00),
396                 raw_pdu(0x0b, 0x02, 0x01),
397                 raw_pdu(0x0a, 0x05, 0x00),
398                 raw_pdu(0x0b, 0x00, 0x00),
399                 raw_pdu(0x0a, 0x0b, 0x00),
400                 raw_pdu(0x0b, 0x00, 0x00),
401                 raw_pdu(0x12, 0x05, 0x00, 0x01, 0x00),
402                 raw_pdu(0x13),
403                 raw_pdu(0x12, 0x0b, 0x00, 0x01, 0x00),
404                 raw_pdu(0x13));
405
406         define_test("/TP/HGRF/RH/BV-02-I", test_hog,
407                 raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),
408                 raw_pdu(0x11, 0x06, 0x01, 0x00, 0x05, 0x00, 0x12,
409                         0x18, 0x06, 0x00, 0x0a, 0x00, 0x12, 0x18),
410                 raw_pdu(0x10, 0x0b, 0x00, 0xff, 0xff, 0x00, 0x28),
411                 raw_pdu(0x01, 0x10, 0x0b, 0x00, 0x0a),
412                 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28),
413                 raw_pdu(0x09, 0x07, 0x03, 0x00, 0x02, 0x04, 0x00,
414                         0x4b, 0x2a),
415                 raw_pdu(0x08, 0x01, 0x00, 0x05, 0x00, 0x02, 0x28),
416                 raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),
417                 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x02, 0x28),
418                 raw_pdu(0x01, 0x08, 0x06, 0x00, 0x0a),
419                 raw_pdu(0x08, 0x06, 0x00, 0x0a, 0x00, 0x03, 0x28),
420                 raw_pdu(0x09, 0x07, 0x08, 0x00, 0x02, 0x09, 0x00,
421                         0x4b, 0x2a),
422                 raw_pdu(0x08, 0x04, 0x00, 0x05, 0x00, 0x03, 0x28),
423                 raw_pdu(0x01, 0x08, 0x04, 0x00, 0x0a),
424                 raw_pdu(0x08, 0x09, 0x00, 0x0a, 0x00, 0x03, 0x28),
425                 raw_pdu(0x01, 0x08, 0x09, 0x00, 0x0a),
426                 raw_pdu(0x0a, 0x04, 0x00),
427                 raw_pdu(0x0b, 0x01, 0x02, 0x03),
428                 raw_pdu(0x04, 0x05, 0x00, 0x05, 0x00),
429                 raw_pdu(0x05, 0x01, 0x05, 0x00, 0x07, 0x29),
430                 raw_pdu(0x0a, 0x09, 0x00),
431                 raw_pdu(0x0b, 0x01, 0x02, 0x03),
432                 raw_pdu(0x04, 0x0a, 0x00, 0x0a, 0x00),
433                 raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x07, 0x29),
434                 raw_pdu(0x0a, 0x05, 0x00),
435                 raw_pdu(0x0b, 0x19, 0x2a),
436                 raw_pdu(0x0a, 0x0a, 0x00),
437                 raw_pdu(0x0b, 0x19, 0x2a));
438
439         return tester_run();
440 }