Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / tools / bneptest.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2015 Intel Corporation
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 <stdio.h>
29 #include <signal.h>
30 #include <stdlib.h>
31 #include <getopt.h>
32 #include <stdbool.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <sys/ioctl.h>
36 #include <net/if.h>
37 #include <linux/sockios.h>
38 #include <netinet/in.h>
39 #include <linux/if_bridge.h>
40
41 #include <glib.h>
42
43 #include "lib/bluetooth.h"
44 #include "lib/hci.h"
45 #include "lib/hci_lib.h"
46
47 #include "src/log.h"
48 #include "src/shared/util.h"
49 #include "btio/btio.h"
50 #include "lib/bnep.h"
51 #include "profiles/network/bnep.h"
52
53 enum {
54         MODE_LISTEN,
55         MODE_CONNECT,
56 };
57
58 static GMainLoop *mloop;
59 static GIOChannel *bnep_io;
60 static struct bnep *session;
61
62 static int mode;
63 static bool no_close_after_disconn;
64 static int send_frame_timeout;
65
66 static bdaddr_t src_addr, dst_addr;
67 static char iface[16];
68 static char bridge[16];
69 static bool send_ctrl_msg_type_set = false;
70 static uint8_t ctrl_msg_type = 0x00;
71 static bool send_bnep_msg_type_set = false;
72 static uint8_t bnep_msg_type = 0x00;
73 static int ctrl_msg_retransmition_nb = 0;
74 static int bnep_msg_retransmission_nb = 0;
75 static uint16_t local_role = BNEP_SVC_PANU;
76 static uint16_t remote_role = BNEP_SVC_NAP;
77 static uint16_t ntw_proto_down_range = 0x0000;
78 static uint16_t ntw_proto_up_range = 0xdc05;
79 static uint16_t ntw_proto_type = 0x0000;
80 static uint8_t mcast_addr_down_range[6];
81 static uint8_t mcast_addr_up_range[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
82 static uint8_t src_hw_addr[6];
83 static uint8_t dst_hw_addr[6];
84 static uint8_t general_frame_payload[] = "abcdef0123456789_bnep_test_data";
85
86 static int set_forward_delay(int sk)
87 {
88         unsigned long args[4] = { BRCTL_SET_BRIDGE_FORWARD_DELAY, 0, 0, 0 };
89         struct ifreq ifr;
90
91         memset(&ifr, 0, sizeof(ifr));
92         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
93         ifr.ifr_data = (char *) args;
94
95         if (ioctl(sk, SIOCDEVPRIVATE, &ifr) < 0) {
96                 error("setting forward delay failed: %d (%s)",
97                                                         errno, strerror(errno));
98                 return -1;
99         }
100
101         return 0;
102 }
103
104 static int nap_create_bridge(void)
105 {
106         int sk, err;
107
108         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
109         if (sk < 0)
110                 return -EOPNOTSUPP;
111
112         if (ioctl(sk, SIOCBRADDBR, bridge) < 0) {
113                 if (errno != EEXIST) {
114                         close(sk);
115                         return -EOPNOTSUPP;
116                 }
117         }
118
119         err = set_forward_delay(sk);
120         if (err < 0) {
121                 printf("failed to set forward delay\n");
122                 ioctl(sk, SIOCBRDELBR, bridge);
123         }
124
125         close(sk);
126
127         return err;
128 }
129
130 static int cleanup(void)
131 {
132         bnep_cleanup();
133
134         if (mode == MODE_LISTEN)
135                 bnep_server_delete(bridge, iface, &dst_addr);
136
137         if (bnep_io) {
138                 g_io_channel_shutdown(bnep_io, TRUE, NULL);
139                 g_io_channel_unref(bnep_io);
140                 bnep_io = NULL;
141         }
142
143         return 0;
144 }
145
146 static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
147                                                         gpointer user_data)
148 {
149         printf("%s\n", __func__);
150
151         if (no_close_after_disconn)
152                 return FALSE;
153
154         /* Cleanup since it's called when disconnected l2cap */
155         if (cleanup() < 0) {
156                 printf("cleanup went wrong...\n");
157                 return FALSE;
158         }
159
160         g_main_loop_quit(mloop);
161         return FALSE;
162 }
163
164 static ssize_t send_compressed_frame(int sk, uint8_t type)
165 {
166         uint8_t frame[100];
167
168         printf("%s\n", __func__);
169
170         if (send_frame_timeout > 0) {
171                 printf("waiting %d seconds before sending msg\n",
172                                                         send_frame_timeout);
173                 sleep(send_frame_timeout);
174         }
175
176         frame[0] = type;
177         memcpy(&frame[1], dst_hw_addr, sizeof(dst_hw_addr));
178         memcpy(&frame[7], src_hw_addr, sizeof(src_hw_addr));
179         frame[13] = ntw_proto_type & 0xff;
180         frame[14] = (ntw_proto_type >> 8);
181         memcpy(&frame[15], general_frame_payload,
182                                                 sizeof(general_frame_payload));
183
184         /* TODO - set frame payload by user */
185         return send(sk, frame, 15 + sizeof(general_frame_payload), 0);
186 }
187
188 static ssize_t send_general_frame(int sk)
189 {
190         uint8_t frame[100];
191
192         printf("%s\n", __func__);
193
194         if (send_frame_timeout > 0) {
195                 printf("waiting %d seconds before sending msg\n",
196                                                         send_frame_timeout);
197                 sleep(send_frame_timeout);
198         }
199
200         frame[0] = BNEP_GENERAL;
201         memcpy(&frame[1], dst_hw_addr, sizeof(dst_hw_addr));
202         memcpy(&frame[7], src_hw_addr, sizeof(src_hw_addr));
203         frame[13] = ntw_proto_type & 0xff;
204         frame[14] = (ntw_proto_type >> 8);
205         memcpy(&frame[15], general_frame_payload,
206                                                 sizeof(general_frame_payload));
207
208         /* TODO - set frame payload by user */
209         return send(sk, frame, 15 + sizeof(general_frame_payload), 0);
210 }
211
212 static ssize_t send_ctrl_frame(int sk)
213 {
214         /*
215          * Max buff size = type(1byte) + ctrl(1byte) + len(2byte) +
216          * mcast_addr_down(6byte) + mcast_addr_up(6byte)
217          */
218         uint8_t buff[16];
219         struct bnep_set_filter_req *frame = (void *) buff;
220         int err;
221
222         printf("%s\n", __func__);
223
224         if (send_frame_timeout > 0) {
225                 printf("waiting %d seconds before sending msg\n",
226                                                 send_frame_timeout);
227                 sleep(send_frame_timeout);
228         }
229
230         switch (ctrl_msg_type) {
231         case BNEP_FILTER_NET_TYPE_SET:
232                 frame->type = BNEP_CONTROL;
233                 frame->ctrl = ctrl_msg_type;
234                 frame->len = htons(sizeof(ntw_proto_down_range) +
235                                                 sizeof(ntw_proto_up_range));
236                 memcpy(frame->list, &ntw_proto_down_range,
237                                                 sizeof(ntw_proto_down_range));
238                 memcpy(frame->list + sizeof(ntw_proto_down_range),
239                         &ntw_proto_up_range, sizeof(ntw_proto_up_range));
240
241                 err = send(sk, frame, sizeof(*frame) +
242                                                 sizeof(ntw_proto_down_range) +
243                                                 sizeof(ntw_proto_up_range), 0);
244                 break;
245         case BNEP_FILTER_MULT_ADDR_SET:
246                 frame->type = BNEP_CONTROL;
247                 frame->ctrl = ctrl_msg_type;
248                 frame->len = htons(sizeof(mcast_addr_down_range) +
249                                                 sizeof(mcast_addr_up_range));
250                 memcpy(frame->list, mcast_addr_down_range,
251                                                 sizeof(mcast_addr_down_range));
252                 memcpy(frame->list + sizeof(mcast_addr_down_range),
253                         mcast_addr_up_range, sizeof(mcast_addr_up_range));
254
255                 err = send(sk, frame, sizeof(*frame) +
256                                         sizeof(mcast_addr_down_range) +
257                                         sizeof(mcast_addr_up_range), 0);
258                 break;
259         default:
260                 err = -1;
261                 break;
262         }
263
264         return err;
265 }
266
267 static int send_bnep_frame(int sk)
268 {
269         int err;
270
271         switch (bnep_msg_type) {
272         case BNEP_GENERAL:
273                 err = send_general_frame(sk);
274                 break;
275         case BNEP_COMPRESSED:
276                 err = send_compressed_frame(sk, BNEP_COMPRESSED);
277                 break;
278         case BNEP_COMPRESSED_SRC_ONLY:
279                 err = send_compressed_frame(sk,
280                                         BNEP_COMPRESSED_SRC_ONLY);
281                 break;
282         case BNEP_COMPRESSED_DST_ONLY:
283                 err = send_compressed_frame(sk,
284                                         BNEP_COMPRESSED_DST_ONLY);
285                 break;
286         default:
287                 printf("wrong bnep_msg_type 0x%02x\n", bnep_msg_type);
288                 err = -EINVAL;
289                 break;
290         }
291
292         return err;
293 }
294
295 static void handle_bnep_msg_send(int sk)
296 {
297         if (send_ctrl_msg_type_set) {
298                 do {
299                         if (send_ctrl_frame(sk) < 0)
300                                 printf("sending ctrl frame error: %s (%d)\n",
301                                                         strerror(errno), errno);
302                 } while (ctrl_msg_retransmition_nb--);
303         }
304
305         if (send_bnep_msg_type_set) {
306                 do {
307                         if (send_bnep_frame(sk) < 0)
308                                 printf("sending bnep frame error: %s (%d)\n",
309                                                         strerror(errno), errno);
310                 } while (bnep_msg_retransmission_nb--);
311         }
312 }
313
314 static gboolean setup_bnep_cb(GIOChannel *chan, GIOCondition cond,
315                                                         gpointer user_data)
316 {
317         uint8_t packet[BNEP_MTU];
318         int sk, n, err;
319
320         printf("%s\n", __func__);
321
322         if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
323                 error("hangup or error or inval on BNEP socket");
324                 return FALSE;
325         }
326
327         sk = g_io_channel_unix_get_fd(chan);
328
329         /* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
330 #ifdef  __TIZEN_PATCH__
331         n = recv(sk, packet, sizeof(packet), MSG_PEEK);
332 #else
333         n = read(sk, packet, sizeof(packet));
334 #endif
335         if (n < 0) {
336                 error("read(): %s(%d)", strerror(errno), errno);
337                 return FALSE;
338         }
339
340         err = nap_create_bridge();
341         if (err < 0) {
342                 error("failed to create bridge: %s (%d)", strerror(-err), err);
343                 return FALSE;
344         }
345
346         if (bnep_server_add(sk, (err < 0) ? NULL : bridge, iface, &dst_addr,
347                                                         packet, n) < 0) {
348                 printf("server_connadd failed\n");
349                 cleanup();
350                 return FALSE;
351         }
352
353         g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL, bnep_watchdog_cb,
354                                                                         NULL);
355
356         handle_bnep_msg_send(sk);
357
358         g_io_channel_unref(bnep_io);
359         bnep_io = NULL;
360
361         return FALSE;
362 }
363
364 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
365 {
366         printf("%s\n", __func__);
367
368         if (err) {
369                 error("%s", err->message);
370                 return;
371         }
372
373         g_io_add_watch(chan, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
374                                                         setup_bnep_cb, NULL);
375 }
376
377 static void connected_client_cb(char *iface, int err, void *data)
378 {
379         int sk = PTR_TO_INT(data);
380
381         printf("%s\n", __func__);
382
383         handle_bnep_msg_send(sk);
384 }
385
386 static void disconnected_client_cb(void *data)
387 {
388         printf("%s\n", __func__);
389
390         if (no_close_after_disconn)
391                 return;
392
393         /* Cleanup since it's called when disconnected l2cap */
394         if (cleanup() < 0) {
395                 printf("cleanup went wrong...\n");
396                 return;
397         }
398
399         g_main_loop_quit(mloop);
400 }
401
402 static void connect_client_cb(GIOChannel *chan, GError *err, gpointer user_data)
403 {
404         int perr;
405         int sk;
406
407         sk = g_io_channel_unix_get_fd(bnep_io);
408
409         session = bnep_new(sk, local_role, remote_role, bridge);
410         if (!session) {
411                 printf("cannot create bnep session\n");
412                 return;
413         }
414
415         perr = bnep_connect(session, connected_client_cb,
416                                 disconnected_client_cb, INT_TO_PTR(sk), NULL);
417         if (perr < 0)
418                 printf("cannot initiate bnep connection\n");
419 }
420
421 static void confirm_cb(GIOChannel *chan, gpointer data)
422 {
423         GError *err = NULL;
424         char address[18];
425
426         printf("%s\n", __func__);
427
428         bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst_addr, BT_IO_OPT_DEST,
429                                                 address, BT_IO_OPT_INVALID);
430         if (err) {
431                 error("%s", err->message);
432                 g_error_free(err);
433                 return;
434         }
435
436         printf("incoming connection from: %s\n", address);
437
438         bnep_io = g_io_channel_ref(chan);
439         g_io_channel_set_close_on_unref(bnep_io, TRUE);
440
441         if (!bt_io_accept(bnep_io, connect_cb, NULL, NULL, &err)) {
442                 error("bt_io_accept: %s", err->message);
443                 g_error_free(err);
444                 g_io_channel_unref(bnep_io);
445         }
446 }
447
448 static int bnep_server_listen(void)
449 {
450         GError *gerr = NULL;
451
452         printf("%s\n", __func__);
453
454         bnep_io = bt_io_listen(NULL, confirm_cb, NULL, NULL, &gerr,
455                                         BT_IO_OPT_SOURCE_BDADDR, &src_addr,
456                                         BT_IO_OPT_PSM, BNEP_PSM,
457                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
458                                         BT_IO_OPT_OMTU, BNEP_MTU,
459                                         BT_IO_OPT_IMTU, BNEP_MTU,
460                                         BT_IO_OPT_INVALID);
461         if (!bnep_io) {
462                 printf("can't start server listening: err %s\n", gerr->message);
463                 g_error_free(gerr);
464                 return -1;
465         }
466
467         return 0;
468 }
469
470 static int bnep_client_connect(void)
471 {
472         GError *gerr = NULL;
473         char bdastr[18];
474
475         printf("%s\n", __func__);
476
477         ba2str(&dst_addr, bdastr);
478         printf("connecting %s\n", bdastr);
479
480         bnep_io = bt_io_connect(connect_client_cb, NULL, NULL, &gerr,
481                                         BT_IO_OPT_SOURCE_BDADDR, &src_addr,
482                                         BT_IO_OPT_DEST_BDADDR, &dst_addr,
483                                         BT_IO_OPT_PSM, BNEP_PSM,
484                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
485                                         BT_IO_OPT_OMTU, BNEP_MTU,
486                                         BT_IO_OPT_IMTU, BNEP_MTU,
487                                         BT_IO_OPT_INVALID);
488         if (!bnep_io) {
489                 printf("cannot connect: err %s\n", gerr->message);
490                 g_error_free(gerr);
491                 return -1;
492         }
493
494         return 0;
495 }
496
497 static void exit_handler(int sig)
498 {
499         printf("got sig = %d, cleaning up...\n", sig);
500
501         if (cleanup() < 0)
502                 printf("cleanup failure...\n");
503         else
504                 printf("cleanup successful - exit\n");
505
506         exit(0);
507 }
508
509 static void usage(void)
510 {
511         printf("bneptest - BNEP testing ver %s\n", VERSION);
512         printf("Usage:\n"
513                 "\tbneptest [-i] -b <bridge name> -n <iface name>"
514                                 " <connection mode> [send_ctrl_cmd] [options]\n"
515                 "\t-i hci dev number <hci number>, def. 0\n"
516                 "\t-b bridge name <string>\n"
517                 "\t-n interface name <string>\n");
518         printf("Connect Mode:\n"
519                 "\t-c connect <dst_addr>\n"
520                 "\t-r remote role <16 bit svc value>\n"
521                 "\t-l local role <16 bit svc valu>\n");
522         printf("Listen Mode:\n"
523                 "\t-s start server listening\n");
524         printf("Send control command:\n"
525                 "\t-t send message type <control msg type>, def. 0\n"
526                 "\t-e start network protocol type range <16 bit val>, def. 0\n"
527                 "\t-d end network protocol type range <16 bit val>, def. 1500\n"
528                 "\t-g start multicast addr range <xx:xx:xx:xx:xx:xx>, def. 0\n"
529                 "\t-j end multicast addr range <xx:xx:xx:xx:xx:xx>, def. f\n"
530                 "\t-y number of ctrl frame retransmission <integer>, def. 0\n"
531                 "\t-u number of bnep frame retransmission <integer>, def. 0\n");
532         printf("Send bnep generic frame:\n"
533                 "\t-w send bnep generic frame <bnep generic type>, def. 0\n"
534                 "\t-k set src mac addr <xx:xx:xx:xx:xx:xx>, def. 0\n"
535                 "\t-f set dst mac addr <xx:xx:xx:xx:xx:xx>, def. 0\n");
536         printf("Options:\n"
537                 "\t-T send message timeout after setup <seconds>\n"
538                 "\t-N don't close bneptest after disconnect\n");
539 }
540
541 static struct option main_options[] = {
542         { "device",                     1, 0, 'i' },
543         { "listen",                     0, 0, 's' },
544         { "connect",                    1, 0, 'c' },
545         { "snd_ctrl_msg_type",          1, 0, 't' },
546         { "snd_bnep_msg_type",          1, 0, 'w' },
547         { "src_hw_addr",                1, 0, 'k' },
548         { "dst_hw_addr",                1, 0, 'f' },
549         { "send_timeout",               1, 0, 'T' },
550         { "ntw_proto_down_range",       1, 0, 'd' },
551         { "ntw_proto_up_range",         1, 0, 'e' },
552         { "mcast_addr_down_range",      1, 0, 'g' },
553         { "mcast_addr_up_range",        1, 0, 'j' },
554         { "local_role",                 1, 0, 'l' },
555         { "remote_role",                1, 0, 'r' },
556         { "bridge name",                1, 0, 'b' },
557         { "iface name",                 1, 0, 'n' },
558         { "no_close",                   0, 0, 'N' },
559         { "retrans_ctrl_nb",            0, 0, 'y' },
560         { "retrans_bnep_nb",            0, 0, 'u' },
561         { "help",                       0, 0, 'h' },
562         { 0, 0, 0, 0 }
563 };
564
565 int main(int argc, char *argv[])
566 {
567         int opt, i;
568         int err;
569         bool is_set_b_name = false, is_set_i_name = false;
570
571         DBG("");
572
573         signal(SIGINT, exit_handler);
574
575         hci_devba(0, &src_addr);
576         bacpy(&src_addr, BDADDR_ANY);
577
578         mloop = g_main_loop_new(NULL, FALSE);
579         if (!mloop) {
580                 printf("cannot create main loop\n");
581
582                 exit(1);
583         }
584
585         while ((opt = getopt_long(argc, argv,
586                                 "+i:c:b:n:t:T:d:e:g:j:k:f:w:l:r:y:u:Nsh",
587                                 main_options, NULL)) != EOF) {
588                 switch (opt) {
589                 case 'i':
590                         if (!strncmp(optarg, "hci", 3))
591                                 hci_devba(atoi(optarg + 3), &src_addr);
592                         else
593                                 str2ba(optarg, &src_addr);
594                         break;
595                 case 's':
596                         mode = MODE_LISTEN;
597                         break;
598                 case 'c':
599                         str2ba(optarg, &dst_addr);
600                         mode = MODE_CONNECT;
601                         break;
602                 case 't':
603                         send_ctrl_msg_type_set = true;
604                         ctrl_msg_type = atoi(optarg);
605                         break;
606                 case 'w':
607                         send_bnep_msg_type_set = true;
608                         bnep_msg_type = atoi(optarg);
609                         break;
610                 case 'k':
611                         for (i = 0; i <= 5; i++, optarg += 3)
612                                 src_hw_addr[i] = strtol(optarg, NULL, 16);
613                         break;
614                 case 'f':
615                         for (i = 0; i <= 5; i++, optarg += 3)
616                                 dst_hw_addr[i] = strtol(optarg, NULL, 16);
617                         break;
618                 case 'T':
619                         send_frame_timeout = atoi(optarg);
620                         break;
621                 case 'd':
622                         ntw_proto_down_range = htons(atoi(optarg));
623                         break;
624                 case 'e':
625                         ntw_proto_up_range = htons(atoi(optarg));
626                         break;
627                 case 'g':
628                         for (i = 5; i >= 0; i--, optarg += 3)
629                                 mcast_addr_down_range[i] =
630                                                 strtol(optarg, NULL, 16);
631                         break;
632                 case 'j':
633                         for (i = 5; i >= 0; i--, optarg += 3)
634                                 mcast_addr_up_range[i] =
635                                                 strtol(optarg, NULL, 16);
636                         break;
637                 case 'l':
638                         local_role = atoi(optarg);
639                         break;
640                 case 'r':
641                         remote_role = atoi(optarg);
642                         break;
643                 case 'b':
644                         strncpy(bridge, optarg, 16);
645                         bridge[15] = '\0';
646                         is_set_b_name = true;
647                         break;
648                 case 'n':
649                         strncpy(iface, optarg, 14);
650                         strcat(iface, "\%d");
651                         iface[15] = '\0';
652                         is_set_i_name = true;
653                         break;
654                 case 'N':
655                         no_close_after_disconn = true;
656                         break;
657                 case 'y':
658                         ctrl_msg_retransmition_nb = atoi(optarg);
659                         break;
660                 case 'u':
661                         bnep_msg_retransmission_nb = atoi(optarg);
662                         break;
663                 case 'h':
664                 default:
665                         usage();
666                         exit(0);
667                 }
668         }
669
670         if (!is_set_b_name || !is_set_i_name) {
671                 printf("bridge, interface name must be set!\n");
672                 exit(1);
673         }
674
675         switch (mode) {
676         case MODE_CONNECT:
677                 err = bnep_init();
678                 if (err < 0) {
679                         printf("cannot initialize bnep\n");
680                         exit(1);
681                 }
682                 err = bnep_client_connect();
683                 if (err < 0)
684                         exit(1);
685
686                 break;
687         case MODE_LISTEN:
688                 err = bnep_init();
689                 if (err < 0) {
690                         printf("cannot initialize bnep\n");
691                         exit(1);
692                 }
693                 err = bnep_server_listen();
694                 if (err < 0)
695                         exit(1);
696
697                 break;
698         default:
699                 printf("connect/listen mode not set, exit...\n");
700                 exit(1);
701         }
702
703         g_main_loop_run(mloop);
704
705         printf("Done\n");
706
707         g_main_loop_unref(mloop);
708
709         return 0;
710 }