Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / unit / test-hfp.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2014  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 #include <sys/socket.h>
25 #include <unistd.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include <glib.h>
31 #include "src/shared/hfp.h"
32 #include "src/shared/tester.h"
33
34 struct context {
35         guint watch_id;
36         int fd_server;
37         int fd_client;
38         struct hfp_gw *hfp;
39         struct hfp_hf *hfp_hf;
40         const struct test_data *data;
41         unsigned int pdu_offset;
42 };
43
44 struct test_pdu {
45         bool valid;
46         const uint8_t *data;
47         size_t size;
48         enum hfp_gw_cmd_type type;
49         bool fragmented;
50 };
51
52 struct test_data {
53         char *test_name;
54         struct test_pdu *pdu_list;
55         hfp_result_func_t result_func;
56         hfp_response_func_t response_func;
57         hfp_hf_result_func_t hf_result_func;
58         GIOFunc test_handler;
59 };
60
61 #define data(args...) ((const unsigned char[]) { args })
62
63 #define raw_pdu(args...)                                        \
64         {                                                       \
65                 .valid = true,                                  \
66                 .data = data(args),                             \
67                 .size = sizeof(data(args)),                     \
68         }
69
70 #define data_end()                                              \
71         {                                                       \
72                 .valid = false,                                 \
73         }
74
75 #define type_pdu(cmd_type, args...)                             \
76         {                                                       \
77                 .valid = true,                                  \
78                 .data = data(args),                             \
79                 .size = sizeof(data(args)),                     \
80                 .type = cmd_type,                               \
81         }
82
83 #define frg_pdu(args...)                                        \
84         {                                                       \
85                 .valid = true,                                  \
86                 .data = data(args),                             \
87                 .size = sizeof(data(args)),                     \
88                 .fragmented = true,                             \
89         }
90
91 #define define_test(name, function, result_function, args...)           \
92         do {                                                            \
93                 const struct test_pdu pdus[] = {                        \
94                         args, { }                                       \
95                 };                                                      \
96                 static struct test_data data;                           \
97                 data.test_name = g_strdup(name);                        \
98                 data.pdu_list = g_memdup(pdus, sizeof(pdus));           \
99                 data.result_func = result_function;                     \
100                 tester_add(name, &data, NULL, function, NULL);          \
101                 data.test_handler = test_handler;                       \
102         } while (0)
103
104 #define define_hf_test(name, function, result_func, response_function,  \
105                                                                 args...)\
106         do {                                                            \
107                 const struct test_pdu pdus[] = {                        \
108                         args, { }                                       \
109                 };                                                      \
110                 static struct test_data data;                           \
111                 data.test_name = g_strdup(name);                        \
112                 data.pdu_list = g_memdup(pdus, sizeof(pdus));           \
113                 data.hf_result_func = result_func;                      \
114                 data.response_func = response_function;                 \
115                 tester_add(name, &data, NULL, function, NULL);          \
116                 data.test_handler = test_hf_handler;                    \
117         } while (0)
118
119 static void test_free(gconstpointer user_data)
120 {
121         const struct test_data *data = user_data;
122
123         g_free(data->test_name);
124         g_free(data->pdu_list);
125 }
126
127 static void destroy_context(struct context *context)
128 {
129         if (context->watch_id)
130                 g_source_remove(context->watch_id);
131
132         test_free(context->data);
133
134         if (context->hfp)
135                 hfp_gw_unref(context->hfp);
136
137         if (context->hfp_hf)
138                 hfp_hf_unref(context->hfp_hf);
139
140         g_free(context);
141 }
142
143 static gboolean context_quit(gpointer user_data)
144 {
145         struct context *context = user_data;
146
147         if (context == NULL)
148                 return FALSE;
149
150         destroy_context(context);
151         tester_test_passed();
152         return FALSE;
153 }
154
155 static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
156                                                         gpointer user_data)
157 {
158         struct context *context = user_data;
159         const struct test_pdu *pdu;
160
161         pdu = &context->data->pdu_list[context->pdu_offset++];
162
163         g_assert(!pdu->valid);
164         context->watch_id = 0;
165
166         context_quit(context);
167
168         return FALSE;
169 }
170
171 static gboolean send_pdu(gpointer user_data)
172 {
173         struct context *context = user_data;
174         const struct test_pdu *pdu;
175         ssize_t len;
176
177         pdu = &context->data->pdu_list[context->pdu_offset++];
178         if (!pdu || !pdu->valid)
179                 return FALSE;
180
181         len = write(context->fd_server, pdu->data, pdu->size);
182         g_assert_cmpint(len, ==, pdu->size);
183
184         pdu = &context->data->pdu_list[context->pdu_offset];
185         if (pdu->fragmented)
186                 g_idle_add(send_pdu, context);
187
188         return FALSE;
189 }
190
191 static gboolean test_hf_handler(GIOChannel *channel, GIOCondition cond,
192                                                         gpointer user_data)
193 {
194         struct context *context = user_data;
195         gchar buf[60];
196         gsize bytes_read;
197         GError *error = NULL;
198
199         if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
200                 goto done;
201
202         /* dummy read */
203         g_io_channel_read_chars(channel, buf, 60, &bytes_read, &error);
204
205         send_pdu(context);
206
207         return TRUE;
208
209 done:
210         context->watch_id = 0;
211
212         context_quit(context);
213
214         return FALSE;
215 }
216
217 static void cmd_handler(const char *command, void *user_data)
218 {
219         struct context *context = user_data;
220         const struct test_pdu *pdu;
221         unsigned int cmd_len = strlen(command);
222
223         pdu = &context->data->pdu_list[context->pdu_offset++];
224
225         g_assert(cmd_len == pdu->size);
226         g_assert(!memcmp(command, pdu->data, cmd_len));
227
228         hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
229 }
230
231 static void prefix_handler(struct hfp_context *result,
232                                 enum hfp_gw_cmd_type type, void *user_data)
233 {
234         struct context *context = user_data;
235         const struct test_pdu *pdu;
236
237         pdu = &context->data->pdu_list[context->pdu_offset++];
238
239         g_assert(type == pdu->type);
240
241         hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
242 }
243
244 static struct context *create_context(gconstpointer data)
245 {
246         struct context *context = g_new0(struct context, 1);
247         GIOChannel *channel;
248         int err, sv[2];
249         const struct test_data *d = data;
250
251         err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
252         g_assert(err == 0);
253
254         channel = g_io_channel_unix_new(sv[1]);
255
256         g_io_channel_set_close_on_unref(channel, TRUE);
257         g_io_channel_set_encoding(channel, NULL, NULL);
258         g_io_channel_set_buffered(channel, FALSE);
259
260         context->watch_id = g_io_add_watch(channel,
261                                 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
262                                 d->test_handler, context);
263
264         g_assert(context->watch_id > 0);
265
266         g_io_channel_unref(channel);
267
268         context->fd_server = sv[1];
269         context->fd_client = sv[0];
270         context->data = data;
271
272         return context;
273 }
274
275 static void test_init(gconstpointer data)
276 {
277         struct context *context = create_context(data);
278
279         context->hfp = hfp_gw_new(context->fd_client);
280
281         g_assert(context->hfp);
282         g_assert(hfp_gw_set_close_on_unref(context->hfp, true));
283
284         hfp_gw_unref(context->hfp);
285         context->hfp = NULL;
286
287         context_quit(context);
288 }
289
290 static void test_command_handler(gconstpointer data)
291 {
292         struct context *context = create_context(data);
293         const struct test_pdu *pdu;
294         ssize_t len;
295         bool ret;
296
297         context->hfp = hfp_gw_new(context->fd_client);
298         g_assert(context->hfp);
299
300         pdu = &context->data->pdu_list[context->pdu_offset++];
301
302         ret = hfp_gw_set_close_on_unref(context->hfp, true);
303         g_assert(ret);
304
305         ret = hfp_gw_set_command_handler(context->hfp, cmd_handler,
306                                                                 context, NULL);
307         g_assert(ret);
308
309         len = write(context->fd_server, pdu->data, pdu->size);
310         g_assert_cmpint(len, ==, pdu->size);
311
312         context_quit(context);
313 }
314
315 static void test_register(gconstpointer data)
316 {
317         struct context *context = create_context(data);
318         const struct test_pdu *pdu;
319         ssize_t len;
320         bool ret;
321
322         context->hfp = hfp_gw_new(context->fd_client);
323         g_assert(context->hfp);
324
325         pdu = &context->data->pdu_list[context->pdu_offset++];
326
327         ret = hfp_gw_set_close_on_unref(context->hfp, true);
328         g_assert(ret);
329
330         if (context->data->result_func) {
331                 ret = hfp_gw_register(context->hfp, context->data->result_func,
332                                         (char *)pdu->data, context, NULL);
333                 g_assert(ret);
334         }
335
336         pdu = &context->data->pdu_list[context->pdu_offset++];
337
338         len = write(context->fd_server, pdu->data, pdu->size);
339         g_assert_cmpint(len, ==, pdu->size);
340
341         context_quit(context);
342 }
343
344 static void test_fragmented(gconstpointer data)
345 {
346         struct context *context = create_context(data);
347         bool ret;
348
349         context->hfp = hfp_gw_new(context->fd_client);
350         g_assert(context->hfp);
351
352         ret = hfp_gw_set_close_on_unref(context->hfp, true);
353         g_assert(ret);
354
355         g_idle_add(send_pdu, context);
356 }
357
358 static void test_send_and_close(gconstpointer data)
359 {
360         struct context *context = create_context(data);
361         bool ret;
362
363         context->hfp = hfp_gw_new(context->fd_client);
364         g_assert(context->hfp);
365
366         ret = hfp_gw_set_close_on_unref(context->hfp, true);
367         g_assert(ret);
368
369         send_pdu(context);
370
371         hfp_gw_unref(context->hfp);
372         context->hfp = NULL;
373
374         context_quit(context);
375 }
376
377 static void check_ustring_1(struct hfp_context *result,
378                                 enum hfp_gw_cmd_type type, void *user_data)
379 {
380         struct context *context = user_data;
381         const struct test_pdu *pdu;
382         unsigned int i = 3, j = 0;
383         char str[10];
384
385         pdu = &context->data->pdu_list[context->pdu_offset++];
386
387         g_assert(type == pdu->type);
388
389         g_assert(hfp_context_get_unquoted_string(result, str, sizeof(str)));
390
391         while (context->data->pdu_list[1].data[i] != '\r') {
392                 g_assert(j < sizeof(str));
393                 g_assert(str[j] == context->data->pdu_list[1].data[i]);
394
395                 i++;
396                 j++;
397         }
398
399         g_assert(str[j] == '\0');
400
401         hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
402 }
403
404 static void check_ustring_2(struct hfp_context *result,
405                                 enum hfp_gw_cmd_type type, void *user_data)
406 {
407         struct context *context = user_data;
408         const struct test_pdu *pdu;
409         char str[10];
410
411         memset(str, 'X', sizeof(str));
412
413         pdu = &context->data->pdu_list[context->pdu_offset++];
414
415         g_assert(type == pdu->type);
416
417         g_assert(!hfp_context_get_unquoted_string(result, str, 3));
418
419         g_assert(str[3] == 'X');
420
421         hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
422 }
423
424 static void check_string_1(struct hfp_context *result,
425                                 enum hfp_gw_cmd_type type, void *user_data)
426 {
427         struct context *context = user_data;
428         const struct test_pdu *pdu;
429         unsigned int i = 4, j = 0;
430         char str[10];
431
432         pdu = &context->data->pdu_list[context->pdu_offset++];
433
434         g_assert(type == pdu->type);
435
436         g_assert(hfp_context_get_string(result, str, sizeof(str)));
437
438         while (context->data->pdu_list[1].data[i] != '\"') {
439                 g_assert(j < sizeof(str));
440                 g_assert(str[j] == context->data->pdu_list[1].data[i]);
441
442                 i++;
443                 j++;
444         }
445
446         g_assert(context->data->pdu_list[1].data[i] == '\"');
447         g_assert(str[j] == '\0');
448
449         hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
450 }
451
452 static void check_string_2(struct hfp_context *result,
453                                 enum hfp_gw_cmd_type type, void *user_data)
454 {
455         struct context *context = user_data;
456         const struct test_pdu *pdu;
457         char str[10];
458
459         memset(str, 'X', sizeof(str));
460
461         pdu = &context->data->pdu_list[context->pdu_offset++];
462
463         g_assert(type == pdu->type);
464
465         g_assert(!hfp_context_get_string(result, str, 3));
466
467         g_assert(str[3] == 'X');
468
469         hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
470 }
471
472 static void check_string_3(struct hfp_context *result,
473                                 enum hfp_gw_cmd_type type, void *user_data)
474 {
475         struct context *context = user_data;
476         const struct test_pdu *pdu;
477
478         pdu = &context->data->pdu_list[context->pdu_offset++];
479
480         g_assert(type == pdu->type);
481
482         hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
483 }
484
485 static void test_hf_init(gconstpointer data)
486 {
487         struct context *context = create_context(data);
488
489         context->hfp_hf = hfp_hf_new(context->fd_client);
490         g_assert(context->hfp_hf);
491         g_assert(hfp_hf_set_close_on_unref(context->hfp_hf, true));
492
493         hfp_hf_unref(context->hfp_hf);
494         context->hfp_hf = NULL;
495
496         context_quit(context);
497 }
498
499 static bool unsolicited_resp = false;
500
501 static void hf_unsolicited_resp_cb(struct hfp_context *context,
502                                                         void *user_data) {
503         unsolicited_resp = true;
504 }
505
506 static void hf_response_with_data(enum hfp_result res,
507                                                         enum hfp_error cme_err,
508                                                         void *user_data)
509 {
510         struct context *context = user_data;
511
512         g_assert(unsolicited_resp);
513         unsolicited_resp = false;
514
515         hfp_hf_disconnect(context->hfp_hf);
516 }
517
518 static void hf_cme_error_response_cb(enum hfp_result res,
519                                                         enum hfp_error cme_err,
520                                                         void *user_data)
521 {
522         struct context *context = user_data;
523
524         g_assert_cmpint(res, ==, HFP_RESULT_CME_ERROR);
525         g_assert_cmpint(cme_err, ==, 30);
526
527         hfp_hf_disconnect(context->hfp_hf);
528 }
529
530 static void hf_response_cb(enum hfp_result res, enum hfp_error cme_err,
531                                                         void *user_data)
532 {
533         struct context *context = user_data;
534
535         hfp_hf_disconnect(context->hfp_hf);
536 }
537
538 static void test_hf_send_command(gconstpointer data)
539 {
540         struct context *context = create_context(data);
541         const struct test_pdu *pdu;
542         bool ret;
543
544         context->hfp_hf = hfp_hf_new(context->fd_client);
545         g_assert(context->hfp_hf);
546
547         ret = hfp_hf_set_close_on_unref(context->hfp_hf, true);
548         g_assert(ret);
549
550         if (context->data->response_func) {
551                 if (context->data->hf_result_func) {
552                         pdu = &context->data->pdu_list[context->pdu_offset++];
553
554                         ret = hfp_hf_register(context->hfp_hf,
555                                                 context->data->hf_result_func,
556                                                 (char *)pdu->data,
557                                                 NULL, NULL);
558                         g_assert(ret);
559                 }
560
561                 pdu = &context->data->pdu_list[context->pdu_offset++];
562
563                 ret = hfp_hf_send_command(context->hfp_hf,
564                                                 context->data->response_func,
565                                                 context, (char *)pdu->data);
566                 g_assert(ret);
567         }
568
569         context_quit(context);
570 }
571 static void hf_chld_result_handler(struct hfp_context *hf_context,
572                                                         void *user_data)
573 {
574         struct context *context = user_data;
575         char str[3];
576
577         g_assert(hf_context);
578         g_assert(hfp_context_get_unquoted_string(hf_context, str,
579                                                         sizeof(str)));
580         g_assert_cmpstr(str, ==, "1");
581         g_assert(hfp_context_get_unquoted_string(hf_context, str,
582                                                         sizeof(str)));
583         g_assert_cmpstr(str, ==, "2x");
584
585         hfp_hf_disconnect(context->hfp_hf);
586 }
587
588 static void hf_chld_skip_field(struct hfp_context *hf_context,
589                                                         void *user_data)
590 {
591         struct context *context = user_data;
592         char str[3];
593
594         g_assert(hf_context);
595
596         hfp_context_skip_field(hf_context);
597
598         g_assert(hfp_context_get_unquoted_string(hf_context, str,
599                                                                 sizeof(str)));
600         g_assert_cmpstr(str, ==, "2x");
601
602         hfp_hf_disconnect(context->hfp_hf);
603 }
604
605 static void hf_clcc_result_handler(struct hfp_context *hf_context,
606                                                         void *user_data)
607 {
608         struct context *context = user_data;
609         char name[10];
610         uint32_t val1, val2;
611
612         g_assert(hf_context);
613         g_assert(hfp_context_open_container(hf_context));
614         g_assert(hfp_context_get_string(hf_context, name, sizeof(name)));
615         g_assert_cmpstr(name, ==, "call");
616         g_assert(hfp_context_open_container(hf_context));
617         g_assert(hfp_context_get_number(hf_context, &val1));
618         g_assert_cmpint(val1, ==, 0);
619         g_assert(hfp_context_get_number(hf_context, &val1));
620         g_assert_cmpint(val1, ==, 1);
621         g_assert(hfp_context_close_container(hf_context));
622         g_assert(hfp_context_close_container(hf_context));
623
624         g_assert(hfp_context_open_container(hf_context));
625         g_assert(hfp_context_get_string(hf_context, name, sizeof(name)));
626         g_assert_cmpstr(name, ==, "callsetup");
627         g_assert(hfp_context_open_container(hf_context));
628         g_assert(hfp_context_get_range(hf_context, &val1, &val2));
629         g_assert_cmpint(val1, ==, 0);
630         g_assert_cmpint(val2, ==, 3);
631         g_assert(hfp_context_close_container(hf_context));
632         g_assert(hfp_context_close_container(hf_context));
633
634         hfp_hf_disconnect(context->hfp_hf);
635 }
636
637 static void hf_result_handler(struct hfp_context *result,
638                                                         void *user_data)
639 {
640         struct context *context = user_data;
641
642         hfp_hf_disconnect(context->hfp_hf);
643 }
644
645 static void test_hf_unsolicited(gconstpointer data)
646 {
647         struct context *context = create_context(data);
648         bool ret;
649
650         context->hfp_hf = hfp_hf_new(context->fd_client);
651         g_assert(context->hfp_hf);
652
653         ret = hfp_hf_set_close_on_unref(context->hfp_hf, true);
654         g_assert(ret);
655
656         if (context->data->hf_result_func) {
657                 const struct test_pdu *pdu;
658
659                 pdu = &context->data->pdu_list[context->pdu_offset++];
660
661                 ret = hfp_hf_register(context->hfp_hf,
662                                                 context->data->hf_result_func,
663                                                 (char *)pdu->data, context,
664                                                 NULL);
665                 g_assert(ret);
666         }
667
668         send_pdu(context);
669 }
670
671 static void test_hf_robustness(gconstpointer data)
672 {
673         struct context *context = create_context(data);
674         bool ret;
675
676         context->hfp_hf = hfp_hf_new(context->fd_client);
677         g_assert(context->hfp_hf);
678
679         ret = hfp_hf_set_close_on_unref(context->hfp_hf, true);
680         g_assert(ret);
681
682         send_pdu(context);
683
684         hfp_hf_unref(context->hfp_hf);
685         context->hfp_hf = NULL;
686
687         context_quit(context);
688 }
689
690 int main(int argc, char *argv[])
691 {
692         tester_init(&argc, &argv);
693
694         define_test("/hfp/test_init", test_init, NULL, data_end());
695         define_test("/hfp/test_cmd_handler_1", test_command_handler, NULL,
696                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\r'),
697                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F'),
698                         data_end());
699         define_test("/hfp/test_cmd_handler_2", test_command_handler, NULL,
700                         raw_pdu('A', 'T', 'D', '1', '2', '3', '4', '\r'),
701                         raw_pdu('A', 'T', 'D', '1', '2', '3', '4'),
702                         data_end());
703         define_test("/hfp/test_register_1", test_register, prefix_handler,
704                         raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
705                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\r'),
706                         type_pdu(HFP_GW_CMD_TYPE_COMMAND, 0),
707                         data_end());
708         define_test("/hfp/test_register_2", test_register, prefix_handler,
709                         raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
710                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '=', '\r'),
711                         type_pdu(HFP_GW_CMD_TYPE_SET, 0),
712                         data_end());
713         define_test("/hfp/test_register_3", test_register, prefix_handler,
714                         raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
715                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '?', '\r'),
716                         type_pdu(HFP_GW_CMD_TYPE_READ, 0),
717                         data_end());
718         define_test("/hfp/test_register_4", test_register, prefix_handler,
719                         raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
720                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '=', '?',
721                                                                         '\r'),
722                         type_pdu(HFP_GW_CMD_TYPE_TEST, 0),
723                         data_end());
724         define_test("/hfp/test_register_5", test_register, prefix_handler,
725                         raw_pdu('D', '\0'),
726                         raw_pdu('A', 'T', 'D', '1', '2', '3', '4', '5', '\r'),
727                         type_pdu(HFP_GW_CMD_TYPE_SET, 0),
728                         data_end());
729         define_test("/hfp/test_fragmented_1", test_fragmented, NULL,
730                         frg_pdu('A'), frg_pdu('T'), frg_pdu('+'), frg_pdu('B'),
731                         frg_pdu('R'), frg_pdu('S'), frg_pdu('F'), frg_pdu('\r'),
732                         data_end());
733         define_test("/hfp/test_ustring_1", test_register, check_ustring_1,
734                         raw_pdu('D', '\0'),
735                         raw_pdu('A', 'T', 'D', '0', '1', '2', '3', '\r'),
736                         type_pdu(HFP_GW_CMD_TYPE_SET, 0),
737                         data_end());
738         define_test("/hfp/test_ustring_2", test_register, check_ustring_2,
739                         raw_pdu('D', '\0'),
740                         raw_pdu('A', 'T', 'D', '0', '1', '2', '3', '\r'),
741                         type_pdu(HFP_GW_CMD_TYPE_SET, 0),
742                         data_end());
743         define_test("/hfp/test_string_1", test_register, check_string_1,
744                         raw_pdu('D', '\0'),
745                         raw_pdu('A', 'T', 'D', '\"', '0', '1', '2', '3', '\"',
746                                                                         '\r'),
747                         type_pdu(HFP_GW_CMD_TYPE_SET, 0),
748                         data_end());
749         define_test("/hfp/test_string_2", test_register, check_string_2,
750                         raw_pdu('D', '\0'),
751                         raw_pdu('A', 'T', 'D', '\"', '0', '1', '2', '3', '\"',
752                                                                         '\r'),
753                         type_pdu(HFP_GW_CMD_TYPE_SET, 0),
754                         data_end());
755         define_test("/hfp/test_corrupted_1", test_register, check_string_3,
756                         raw_pdu('D', '\0'),
757                         raw_pdu('\r', 'A', 'T', 'D', '\"', '0', '1', '2', '3',
758                                                                 '\"', '\r'),
759                         type_pdu(HFP_GW_CMD_TYPE_SET, 0),
760                         data_end());
761         define_test("/hfp/test_empty", test_send_and_close, NULL,
762                         raw_pdu('\r'),
763                         data_end());
764         define_hf_test("/hfp_hf/test_init", test_hf_init, NULL, NULL,
765                         data_end());
766         define_hf_test("/hfp_hf/test_send_command_1", test_hf_send_command,
767                         NULL, hf_response_cb,
768                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\0'),
769                         raw_pdu('\r', '\n', 'O', 'k', '\r', '\n'),
770                         data_end());
771
772         define_hf_test("/hfp_hf/test_send_command_2", test_hf_send_command,
773                         hf_unsolicited_resp_cb,
774                         hf_response_with_data,
775                         raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
776                         raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\0'),
777                         frg_pdu('\r', '\n', '+', 'B', 'R', 'S', 'F', '\r',
778                                                                         '\n'),
779                         frg_pdu('\r', '\n', 'O', 'k', '\r', '\n'),
780                         data_end());
781
782         define_hf_test("/hfp_hf/test_send_command_3", test_hf_send_command,
783                         NULL, hf_cme_error_response_cb,
784                         raw_pdu('A', 'T', '+', 'C', 'H', 'L', 'D', '=',
785                                                                 '1', '\0'),
786                         frg_pdu('\r', '\n', '+', 'C', 'M', 'E', ' ', 'E'),
787                         frg_pdu('R', 'R', 'O', 'R', ':', '3', '0', '\r', '\n'),
788                         data_end());
789
790         define_hf_test("/hfp_hf/test_unsolicited_1", test_hf_unsolicited,
791                         hf_result_handler, NULL,
792                         raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
793                         frg_pdu('\r', '\n', '+', 'C', 'L', 'C'),
794                         frg_pdu('C', '\r', '\n'),
795                         data_end());
796
797         define_hf_test("/hfp_hf/test_unsolicited_2", test_hf_unsolicited,
798                         hf_result_handler, NULL,
799                         raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
800                         frg_pdu('\r', '\n', '+', 'C', 'L', 'C', 'C', ':', '1'),
801                         frg_pdu(',', '3', ',', '0', '\r', '\n'),
802                         data_end());
803
804         define_hf_test("/hfp_hf/test_unsolicited_3", test_hf_unsolicited,
805                         hf_result_handler, NULL,
806                         raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
807                         frg_pdu('\r'), frg_pdu('\n'), frg_pdu('+'),
808                         frg_pdu('C'), frg_pdu('L'), frg_pdu('C'), frg_pdu('C'),
809                         frg_pdu(':'), frg_pdu('1'), frg_pdu(','), frg_pdu('3'),
810                         frg_pdu(','), frg_pdu('0'), frg_pdu('\r'),
811                         frg_pdu('\n'),
812                         data_end());
813
814         define_hf_test("/hfp_hf/test_corrupted_1", test_hf_unsolicited,
815                         hf_result_handler, NULL,
816                         raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
817                         frg_pdu('\r', 'X', '\r', '\n'),
818                         frg_pdu('+', 'C', 'L', 'C', 'C', ':', '1', ',', '3'),
819                         frg_pdu(',', '0', '\r', '\n'),
820                         data_end());
821
822         define_hf_test("/hfp_hf/test_corrupted_2", test_hf_unsolicited,
823                         hf_result_handler, NULL,
824                         raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
825                         raw_pdu('+', 'C', 'L', 'C', 'C', '\r', '\n'),
826                         data_end());
827
828         define_hf_test("/hfp_hf/test_empty", test_hf_robustness, NULL, NULL,
829                         raw_pdu('\r'), data_end());
830
831         define_hf_test("/hfp_hf/test_unknown", test_hf_robustness, NULL, NULL,
832                         raw_pdu('\r', '\n', 'B', 'R', '\r', '\n'),
833                         data_end());
834
835         define_hf_test("/hfp_hf/test_context_parser_1", test_hf_unsolicited,
836                         hf_clcc_result_handler, NULL,
837                         raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
838                         frg_pdu('+', 'C', 'L', 'C', 'C', ':'),
839                         frg_pdu('(', '\"', 'c', 'a', 'l', 'l', '\"'),
840                         frg_pdu('(', '0', ',', '1', ')', ')', ','),
841                         frg_pdu('(', '\"', 'c', 'a', 'l', 'l', 's', 'e', 't'),
842                         frg_pdu('u', 'p', '\"', ',', '(', '0', '-', '3', ')'),
843                         frg_pdu(')', '\r', '\n'),
844                         data_end());
845
846         define_hf_test("/hfp_hf/test_context_parser_2", test_hf_unsolicited,
847                         hf_chld_result_handler, NULL,
848                         raw_pdu('+', 'C', 'H', 'L', 'D', '\0'),
849                         frg_pdu('+', 'C', 'H', 'L', 'D', ':'),
850                         frg_pdu('1', ',', '2', 'x', '\r', '\n'),
851                         data_end());
852
853         define_hf_test("/hfp_hf/test_context_skip_field", test_hf_unsolicited,
854                         hf_chld_skip_field, NULL,
855                         raw_pdu('+', 'C', 'H', 'L', 'D', '\0'),
856                         frg_pdu('+', 'C', 'H', 'L', 'D', ':'),
857                         frg_pdu('1', ',', '2', 'x', '\r', '\n'),
858                         data_end());
859
860         return tester_run();
861 }