3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2015 Intel Corporation
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
35 #include <sys/ioctl.h>
37 #include <linux/sockios.h>
38 #include <netinet/in.h>
39 #include <linux/if_bridge.h>
43 #include "lib/bluetooth.h"
45 #include "lib/hci_lib.h"
48 #include "src/shared/util.h"
49 #include "btio/btio.h"
51 #include "profiles/network/bnep.h"
58 static GMainLoop *mloop;
59 static GIOChannel *bnep_io;
60 static struct bnep *session;
63 static bool no_close_after_disconn;
64 static int send_frame_timeout;
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";
86 static int set_forward_delay(int sk)
88 unsigned long args[4] = { BRCTL_SET_BRIDGE_FORWARD_DELAY, 0, 0, 0 };
91 memset(&ifr, 0, sizeof(ifr));
92 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
93 ifr.ifr_data = (char *) args;
95 if (ioctl(sk, SIOCDEVPRIVATE, &ifr) < 0) {
96 error("setting forward delay failed: %d (%s)",
97 errno, strerror(errno));
104 static int nap_create_bridge(void)
108 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
112 if (ioctl(sk, SIOCBRADDBR, bridge) < 0) {
113 if (errno != EEXIST) {
119 err = set_forward_delay(sk);
121 printf("failed to set forward delay\n");
122 ioctl(sk, SIOCBRDELBR, bridge);
130 static int cleanup(void)
134 if (mode == MODE_LISTEN)
135 bnep_server_delete(bridge, iface, &dst_addr);
138 g_io_channel_shutdown(bnep_io, TRUE, NULL);
139 g_io_channel_unref(bnep_io);
146 static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
149 printf("%s\n", __func__);
151 if (no_close_after_disconn)
154 /* Cleanup since it's called when disconnected l2cap */
156 printf("cleanup went wrong...\n");
160 g_main_loop_quit(mloop);
164 static ssize_t send_compressed_frame(int sk, uint8_t type)
168 printf("%s\n", __func__);
170 if (send_frame_timeout > 0) {
171 printf("waiting %d seconds before sending msg\n",
173 sleep(send_frame_timeout);
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));
184 /* TODO - set frame payload by user */
185 return send(sk, frame, 15 + sizeof(general_frame_payload), 0);
188 static ssize_t send_general_frame(int sk)
192 printf("%s\n", __func__);
194 if (send_frame_timeout > 0) {
195 printf("waiting %d seconds before sending msg\n",
197 sleep(send_frame_timeout);
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));
208 /* TODO - set frame payload by user */
209 return send(sk, frame, 15 + sizeof(general_frame_payload), 0);
212 static ssize_t send_ctrl_frame(int sk)
215 * Max buff size = type(1byte) + ctrl(1byte) + len(2byte) +
216 * mcast_addr_down(6byte) + mcast_addr_up(6byte)
219 struct bnep_set_filter_req *frame = (void *) buff;
222 printf("%s\n", __func__);
224 if (send_frame_timeout > 0) {
225 printf("waiting %d seconds before sending msg\n",
227 sleep(send_frame_timeout);
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));
241 err = send(sk, frame, sizeof(*frame) +
242 sizeof(ntw_proto_down_range) +
243 sizeof(ntw_proto_up_range), 0);
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));
255 err = send(sk, frame, sizeof(*frame) +
256 sizeof(mcast_addr_down_range) +
257 sizeof(mcast_addr_up_range), 0);
267 static int send_bnep_frame(int sk)
271 switch (bnep_msg_type) {
273 err = send_general_frame(sk);
275 case BNEP_COMPRESSED:
276 err = send_compressed_frame(sk, BNEP_COMPRESSED);
278 case BNEP_COMPRESSED_SRC_ONLY:
279 err = send_compressed_frame(sk,
280 BNEP_COMPRESSED_SRC_ONLY);
282 case BNEP_COMPRESSED_DST_ONLY:
283 err = send_compressed_frame(sk,
284 BNEP_COMPRESSED_DST_ONLY);
287 printf("wrong bnep_msg_type 0x%02x\n", bnep_msg_type);
295 static void handle_bnep_msg_send(int sk)
297 if (send_ctrl_msg_type_set) {
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--);
305 if (send_bnep_msg_type_set) {
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--);
314 static gboolean setup_bnep_cb(GIOChannel *chan, GIOCondition cond,
317 uint8_t packet[BNEP_MTU];
320 printf("%s\n", __func__);
322 if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
323 error("hangup or error or inval on BNEP socket");
327 sk = g_io_channel_unix_get_fd(chan);
329 /* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
330 #ifdef __TIZEN_PATCH__
331 n = recv(sk, packet, sizeof(packet), MSG_PEEK);
333 n = read(sk, packet, sizeof(packet));
336 error("read(): %s(%d)", strerror(errno), errno);
340 err = nap_create_bridge();
342 error("failed to create bridge: %s (%d)", strerror(-err), err);
346 if (bnep_server_add(sk, (err < 0) ? NULL : bridge, iface, &dst_addr,
348 printf("server_connadd failed\n");
353 g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL, bnep_watchdog_cb,
356 handle_bnep_msg_send(sk);
358 g_io_channel_unref(bnep_io);
364 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
366 printf("%s\n", __func__);
369 error("%s", err->message);
373 g_io_add_watch(chan, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
374 setup_bnep_cb, NULL);
377 static void connected_client_cb(char *iface, int err, void *data)
379 int sk = PTR_TO_INT(data);
381 printf("%s\n", __func__);
383 handle_bnep_msg_send(sk);
386 static void disconnected_client_cb(void *data)
388 printf("%s\n", __func__);
390 if (no_close_after_disconn)
393 /* Cleanup since it's called when disconnected l2cap */
395 printf("cleanup went wrong...\n");
399 g_main_loop_quit(mloop);
402 static void connect_client_cb(GIOChannel *chan, GError *err, gpointer user_data)
407 sk = g_io_channel_unix_get_fd(bnep_io);
409 session = bnep_new(sk, local_role, remote_role, bridge);
411 printf("cannot create bnep session\n");
415 perr = bnep_connect(session, connected_client_cb,
416 disconnected_client_cb, INT_TO_PTR(sk), NULL);
418 printf("cannot initiate bnep connection\n");
421 static void confirm_cb(GIOChannel *chan, gpointer data)
426 printf("%s\n", __func__);
428 bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst_addr, BT_IO_OPT_DEST,
429 address, BT_IO_OPT_INVALID);
431 error("%s", err->message);
436 printf("incoming connection from: %s\n", address);
438 bnep_io = g_io_channel_ref(chan);
439 g_io_channel_set_close_on_unref(bnep_io, TRUE);
441 if (!bt_io_accept(bnep_io, connect_cb, NULL, NULL, &err)) {
442 error("bt_io_accept: %s", err->message);
444 g_io_channel_unref(bnep_io);
448 static int bnep_server_listen(void)
452 printf("%s\n", __func__);
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,
462 printf("can't start server listening: err %s\n", gerr->message);
470 static int bnep_client_connect(void)
475 printf("%s\n", __func__);
477 ba2str(&dst_addr, bdastr);
478 printf("connecting %s\n", bdastr);
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,
489 printf("cannot connect: err %s\n", gerr->message);
497 static void exit_handler(int sig)
499 printf("got sig = %d, cleaning up...\n", sig);
502 printf("cleanup failure...\n");
504 printf("cleanup successful - exit\n");
509 static void usage(void)
511 printf("bneptest - BNEP testing ver %s\n", VERSION);
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");
537 "\t-T send message timeout after setup <seconds>\n"
538 "\t-N don't close bneptest after disconnect\n");
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' },
565 int main(int argc, char *argv[])
569 bool is_set_b_name = false, is_set_i_name = false;
573 signal(SIGINT, exit_handler);
575 hci_devba(0, &src_addr);
576 bacpy(&src_addr, BDADDR_ANY);
578 mloop = g_main_loop_new(NULL, FALSE);
580 printf("cannot create main loop\n");
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) {
590 if (!strncmp(optarg, "hci", 3))
591 hci_devba(atoi(optarg + 3), &src_addr);
593 str2ba(optarg, &src_addr);
599 str2ba(optarg, &dst_addr);
603 send_ctrl_msg_type_set = true;
604 ctrl_msg_type = atoi(optarg);
607 send_bnep_msg_type_set = true;
608 bnep_msg_type = atoi(optarg);
611 for (i = 0; i <= 5; i++, optarg += 3)
612 src_hw_addr[i] = strtol(optarg, NULL, 16);
615 for (i = 0; i <= 5; i++, optarg += 3)
616 dst_hw_addr[i] = strtol(optarg, NULL, 16);
619 send_frame_timeout = atoi(optarg);
622 ntw_proto_down_range = htons(atoi(optarg));
625 ntw_proto_up_range = htons(atoi(optarg));
628 for (i = 5; i >= 0; i--, optarg += 3)
629 mcast_addr_down_range[i] =
630 strtol(optarg, NULL, 16);
633 for (i = 5; i >= 0; i--, optarg += 3)
634 mcast_addr_up_range[i] =
635 strtol(optarg, NULL, 16);
638 local_role = atoi(optarg);
641 remote_role = atoi(optarg);
644 strncpy(bridge, optarg, 16);
646 is_set_b_name = true;
649 strncpy(iface, optarg, 14);
650 strcat(iface, "\%d");
652 is_set_i_name = true;
655 no_close_after_disconn = true;
658 ctrl_msg_retransmition_nb = atoi(optarg);
661 bnep_msg_retransmission_nb = atoi(optarg);
670 if (!is_set_b_name || !is_set_i_name) {
671 printf("bridge, interface name must be set!\n");
679 printf("cannot initialize bnep\n");
682 err = bnep_client_connect();
690 printf("cannot initialize bnep\n");
693 err = bnep_server_listen();
699 printf("connect/listen mode not set, exit...\n");
703 g_main_loop_run(mloop);
707 g_main_loop_unref(mloop);