1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk (at) qualcomm.com> 6 * Copyright (C) 2002-2010 Marcel Holtmann <marcel (at) holtmann.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #ifdef HAVE_CONFIG_H 26 #include <config.h> 27 #endif 28 29 #include <stdio.h> 30 #include <errno.h> 31 #include <ctype.h> 32 #include <fcntl.h> 33 #include <unistd.h> 34 #include <stdlib.h> 35 #include <getopt.h> 36 #include <syslog.h> 37 #include <signal.h> 38 #include <sys/time.h> 39 #include <sys/ioctl.h> 40 #include <sys/socket.h> 41 42 #include <bluetooth/bluetooth.h> 43 #include <bluetooth/hci.h> 44 #include <bluetooth/hci_lib.h> 45 #include <bluetooth/rfcomm.h> 46 #include <bluetooth/sdp.h> 47 #include <bluetooth/sdp_lib.h> 48 49 /* Test modes */ 50 enum { 51 SEND, 52 RECV, 53 RECONNECT, 54 MULTY, 55 DUMP, 56 CONNECT, 57 CRECV, 58 LSEND 59 }; 60 61 static unsigned char *buf; 62 63 /* Default data size */ 64 static long data_size = 127; 65 static long num_frames = -1; 66 67 /* Default number of consecutive frames before the delay */ 68 static int count = 1; 69 70 /* Default delay after sending count number of frames */ 71 static unsigned long delay = 0; 72 73 /* Default addr and channel */ 74 static bdaddr_t bdaddr; 75 static uint16_t uuid = 0x0000; 76 static uint8_t channel = 10; 77 78 static char *filename = NULL; 79 80 static int master = 0; 81 static int auth = 0; 82 static int encrypt = 0; 83 static int secure = 0; 84 static int socktype = SOCK_STREAM; 85 static int linger = 0; 86 static int timestamp = 0; 87 static int defer_setup = 0; 88 89 static float tv2fl(struct timeval tv) 90 { 91 return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); 92 } 93 94 static uint8_t get_channel(const char *svr, uint16_t uuid) 95 { 96 sdp_session_t *sdp; 97 sdp_list_t *srch, *attrs, *rsp; 98 uuid_t svclass; 99 uint16_t attr; 100 bdaddr_t dst; 101 uint8_t channel = 0; 102 int err; 103 104 str2ba(svr, &dst); 105 106 sdp = sdp_connect(&bdaddr, &dst, SDP_RETRY_IF_BUSY); 107 if (!sdp) 108 return 0; 109 110 sdp_uuid16_create(&svclass, uuid); 111 srch = sdp_list_append(NULL, &svclass); 112 113 attr = SDP_ATTR_PROTO_DESC_LIST; 114 attrs = sdp_list_append(NULL, &attr); 115 116 err = sdp_service_search_attr_req(sdp, srch, 117 SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); 118 if (err) 119 goto done; 120 121 for (; rsp; rsp = rsp->next) { 122 sdp_record_t *rec = (sdp_record_t *) rsp->data; 123 sdp_list_t *protos; 124 125 if (!sdp_get_access_protos(rec, &protos)) { 126 channel = sdp_get_proto_port(protos, RFCOMM_UUID); 127 if (channel > 0) 128 break; 129 } 130 } 131 132 done: 133 sdp_close(sdp); 134 135 return channel; 136 } 137 138 static int do_connect(const char *svr) 139 { 140 struct sockaddr_rc addr; 141 struct rfcomm_conninfo conn; 142 socklen_t optlen; 143 int sk, opt; 144 145 if (uuid != 0x0000) 146 channel = get_channel(svr, uuid); 147 148 if (channel == 0) { 149 syslog(LOG_ERR, "Can't get channel number"); 150 return -1; 151 } 152 153 /* Create socket */ 154 sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM); 155 if (sk < 0) { 156 syslog(LOG_ERR, "Can't create socket: %s (%d)", 157 strerror(errno), errno); 158 return -1; 159 } 160 161 /* Bind to local address */ 162 memset(&addr, 0, sizeof(addr)); 163 addr.rc_family = AF_BLUETOOTH; 164 bacpy(&addr.rc_bdaddr, &bdaddr); 165 166 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 167 syslog(LOG_ERR, "Can't bind socket: %s (%d)", 168 strerror(errno), errno); 169 goto error; 170 } 171 172 #if 0 173 /* Enable SO_TIMESTAMP */ 174 if (timestamp) { 175 int t = 1; 176 177 if (setsockopt(sk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { 178 syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)", 179 strerror(errno), errno); 180 goto error; 181 } 182 } 183 #endif 184 185 /* Enable SO_LINGER */ 186 if (linger) { 187 struct linger l = { .l_onoff = 1, .l_linger = linger }; 188 189 if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { 190 syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", 191 strerror(errno), errno); 192 goto error; 193 } 194 } 195 196 /* Set link mode */ 197 opt = 0; 198 if (master) 199 opt |= RFCOMM_LM_MASTER; 200 if (auth) 201 opt |= RFCOMM_LM_AUTH; 202 if (encrypt) 203 opt |= RFCOMM_LM_ENCRYPT; 204 if (secure) 205 opt |= RFCOMM_LM_SECURE; 206 207 if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { 208 syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", 209 strerror(errno), errno); 210 goto error; 211 } 212 213 /* Connect to remote device */ 214 memset(&addr, 0, sizeof(addr)); 215 addr.rc_family = AF_BLUETOOTH; 216 str2ba(svr, &addr.rc_bdaddr); 217 addr.rc_channel = channel; 218 219 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 220 syslog(LOG_ERR, "Can't connect: %s (%d)", 221 strerror(errno), errno); 222 goto error; 223 } 224 225 /* Get connection information */ 226 memset(&conn, 0, sizeof(conn)); 227 optlen = sizeof(conn); 228 229 if (getsockopt(sk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) { 230 syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", 231 strerror(errno), errno); 232 //goto error; 233 } 234 235 syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", 236 conn.hci_handle, 237 conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); 238 239 return sk; 240 241 error: 242 close(sk); 243 return -1; 244 } 245 246 static void do_listen(void (*handler)(int sk)) 247 { 248 struct sockaddr_rc addr; 249 struct rfcomm_conninfo conn; 250 socklen_t optlen; 251 int sk, nsk, opt; 252 char ba[18]; 253 254 /* Create socket */ 255 sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM); 256 if (sk < 0) { 257 syslog(LOG_ERR, "Can't create socket: %s (%d)", 258 strerror(errno), errno); 259 exit(1); 260 } 261 262 /* Bind to local address */ 263 memset(&addr, 0, sizeof(addr)); 264 addr.rc_family = AF_BLUETOOTH; 265 bacpy(&addr.rc_bdaddr, &bdaddr); 266 addr.rc_channel = channel; 267 268 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 269 syslog(LOG_ERR, "Can't bind socket: %s (%d)", 270 strerror(errno), errno); 271 goto error; 272 } 273 274 /* Set link mode */ 275 opt = 0; 276 if (master) 277 opt |= RFCOMM_LM_MASTER; 278 if (auth) 279 opt |= RFCOMM_LM_AUTH; 280 if (encrypt) 281 opt |= RFCOMM_LM_ENCRYPT; 282 if (secure) 283 opt |= RFCOMM_LM_SECURE; 284 285 if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { 286 syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", 287 strerror(errno), errno); 288 goto error; 289 } 290 291 /* Enable deferred setup */ 292 opt = defer_setup; 293 294 if (opt && setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP, 295 &opt, sizeof(opt)) < 0) { 296 syslog(LOG_ERR, "Can't enable deferred setup : %s (%d)", 297 strerror(errno), errno); 298 goto error; 299 } 300 301 /* Listen for connections */ 302 if (listen(sk, 10)) { 303 syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", 304 strerror(errno), errno); 305 goto error; 306 } 307 308 /* Check for socket address */ 309 memset(&addr, 0, sizeof(addr)); 310 optlen = sizeof(addr); 311 312 if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) { 313 syslog(LOG_ERR, "Can't get socket name: %s (%d)", 314 strerror(errno), errno); 315 goto error; 316 } 317 318 channel = addr.rc_channel; 319 320 syslog(LOG_INFO, "Waiting for connection on channel %d ...", channel); 321 322 while (1) { 323 memset(&addr, 0, sizeof(addr)); 324 optlen = sizeof(addr); 325 326 nsk = accept(sk, (struct sockaddr *) &addr, &optlen); 327 if (nsk < 0) { 328 syslog(LOG_ERR,"Accept failed: %s (%d)", 329 strerror(errno), errno); 330 goto error; 331 } 332 if (fork()) { 333 /* Parent */ 334 close(nsk); 335 continue; 336 } 337 /* Child */ 338 close(sk); 339 340 /* Get connection information */ 341 memset(&conn, 0, sizeof(conn)); 342 optlen = sizeof(conn); 343 344 if (getsockopt(nsk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) { 345 syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", 346 strerror(errno), errno); 347 //close(nsk); 348 //goto error; 349 } 350 351 ba2str(&addr.rc_bdaddr, ba); 352 syslog(LOG_INFO, "Connect from %s [handle %d, class 0x%02x%02x%02x]", 353 ba, conn.hci_handle, 354 conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); 355 356 #if 0 357 /* Enable SO_TIMESTAMP */ 358 if (timestamp) { 359 int t = 1; 360 361 if (setsockopt(nsk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { 362 syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)", 363 strerror(errno), errno); 364 goto error; 365 } 366 } 367 #endif 368 369 /* Enable SO_LINGER */ 370 if (linger) { 371 struct linger l = { .l_onoff = 1, .l_linger = linger }; 372 373 if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { 374 syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", 375 strerror(errno), errno); 376 close(nsk); 377 goto error; 378 } 379 } 380 381 /* Handle deferred setup */ 382 if (defer_setup) { 383 syslog(LOG_INFO, "Waiting for %d seconds", 384 abs(defer_setup) - 1); 385 sleep(abs(defer_setup) - 1); 386 387 if (defer_setup < 0) { 388 close(nsk); 389 goto error; 390 } 391 } 392 393 handler(nsk); 394 395 syslog(LOG_INFO, "Disconnect: %m"); 396 exit(0); 397 } 398 399 return; 400 401 error: 402 close(sk); 403 exit(1); 404 } 405 406 static void dump_mode(int sk) 407 { 408 int len; 409 410 syslog(LOG_INFO, "Receiving ..."); 411 while ((len = read(sk, buf, data_size)) > 0) 412 syslog(LOG_INFO, "Recevied %d bytes", len); 413 } 414 415 static void recv_mode(int sk) 416 { 417 struct timeval tv_beg, tv_end, tv_diff; 418 char ts[30]; 419 long total; 420 421 syslog(LOG_INFO, "Receiving ..."); 422 423 memset(ts, 0, sizeof(ts)); 424 425 while (1) { 426 gettimeofday(&tv_beg,NULL); 427 total = 0; 428 while (total < data_size) { 429 //uint32_t sq; 430 //uint16_t l; 431 int r; 432 433 if ((r = recv(sk, buf, data_size, 0)) < 0) { 434 if (r < 0) 435 syslog(LOG_ERR, "Read failed: %s (%d)", 436 strerror(errno), errno); 437 return; 438 } 439 440 if (timestamp) { 441 struct timeval tv; 442 443 if (ioctl(sk, SIOCGSTAMP, &tv) < 0) { 444 timestamp = 0; 445 memset(ts, 0, sizeof(ts)); 446 } else { 447 sprintf(ts, "[%ld.%ld] ", 448 tv.tv_sec, tv.tv_usec); 449 } 450 } 451 452 #if 0 453 /* Check sequence */ 454 sq = btohl(*(uint32_t *) buf); 455 if (seq != sq) { 456 syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); 457 seq = sq; 458 } 459 seq++; 460 461 /* Check length */ 462 l = btohs(*(uint16_t *) (buf + 4)); 463 if (r != l) { 464 syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); 465 continue; 466 } 467 468 /* Verify data */ 469 for (i = 6; i < r; i++) { 470 if (buf[i] != 0x7f) 471 syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); 472 } 473 #endif 474 total += r; 475 } 476 gettimeofday(&tv_end,NULL); 477 478 timersub(&tv_end,&tv_beg,&tv_diff); 479 480 syslog(LOG_INFO,"%s%ld bytes in %.2f sec, %.2f kB/s", ts, total, 481 tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); 482 } 483 } 484 485 static void do_send(int sk) 486 { 487 uint32_t seq; 488 int i, fd, len; 489 490 syslog(LOG_INFO,"Sending ..."); 491 492 if (filename) { 493 fd = open(filename, O_RDONLY); 494 if (fd < 0) { 495 syslog(LOG_ERR, "Open failed: %s (%d)", 496 strerror(errno), errno); 497 exit(1); 498 } 499 len = read(fd, buf, data_size); 500 send(sk, buf, len, 0); 501 return; 502 } else { 503 for (i = 6; i < data_size; i++) 504 buf[i] = 0x7f; 505 } 506 507 seq = 0; 508 while ((num_frames == -1) || (num_frames-- > 0)) { 509 *(uint32_t *) buf = htobl(seq); 510 *(uint16_t *) (buf + 4) = htobs(data_size); 511 seq++; 512 513 if (send(sk, buf, data_size, 0) <= 0) { 514 syslog(LOG_ERR, "Send failed: %s (%d)", 515 strerror(errno), errno); 516 exit(1); 517 } 518 519 if (num_frames && delay && count && !(seq % count)) 520 usleep(delay); 521 } 522 } 523 524 static void send_mode(int sk) 525 { 526 do_send(sk); 527 528 syslog(LOG_INFO, "Closing channel ..."); 529 if (shutdown(sk, SHUT_RDWR) < 0) 530 syslog(LOG_INFO, "Close failed: %m"); 531 else 532 syslog(LOG_INFO, "Done"); 533 } 534 535 static void reconnect_mode(char *svr) 536 { 537 while(1) { 538 int sk = do_connect(svr); 539 close(sk); 540 } 541 } 542 543 static void multi_connect_mode(int argc, char *argv[]) 544 { 545 int i, n, sk; 546 547 while (1) { 548 for (n = 0; n < argc; n++) { 549 for (i = 0; i < count; i++) { 550 if (fork()) 551 continue; 552 553 /* Child */ 554 sk = do_connect(argv[n]); 555 usleep(500); 556 close(sk); 557 exit(0); 558 } 559 } 560 sleep(4); 561 } 562 } 563 564 static void usage(void) 565 { 566 printf("rctest - RFCOMM testing\n" 567 "Usage:\n"); 568 printf("\trctest <mode> [options] [bdaddr]\n"); 569 printf("Modes:\n" 570 "\t-r listen and receive\n" 571 "\t-w listen and send\n" 572 "\t-d listen and dump incoming data\n" 573 "\t-s connect and send\n" 574 "\t-u connect and receive\n" 575 "\t-n connect and be silent\n" 576 "\t-c connect, disconnect, connect, ...\n" 577 "\t-m multiple connects\n"); 578 579 printf("Options:\n" 580 "\t[-b bytes] [-i device] [-P channel] [-U uuid]\n" 581 "\t[-L seconds] enabled SO_LINGER option\n" 582 "\t[-W seconds] enable deferred setup\n" 583 "\t[-B filename] use data packets from file\n" 584 "\t[-N num] number of frames to send\n" 585 "\t[-C num] send num frames before delay (default = 1)\n" 586 "\t[-D milliseconds] delay after sending num frames (default = 0)\n" 587 "\t[-A] request authentication\n" 588 "\t[-E] request encryption\n" 589 "\t[-S] secure connection\n" 590 "\t[-M] become master\n" 591 "\t[-T] enable timestamps\n"); 592 } 593 594 int main(int argc, char *argv[]) 595 { 596 struct sigaction sa; 597 int opt, sk, mode = RECV, need_addr = 0; 598 599 bacpy(&bdaddr, BDADDR_ANY); 600 601 while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:U:B:N:MAESL:W:C:D:T")) != EOF) { 602 switch (opt) { 603 case 'r': 604 mode = RECV; 605 break; 606 607 case 's': 608 mode = SEND; 609 need_addr = 1; 610 break; 611 612 case 'w': 613 mode = LSEND; 614 break; 615 616 case 'u': 617 mode = CRECV; 618 need_addr = 1; 619 break; 620 621 case 'd': 622 mode = DUMP; 623 break; 624 625 case 'c': 626 mode = RECONNECT; 627 need_addr = 1; 628 break; 629 630 case 'n': 631 mode = CONNECT; 632 need_addr = 1; 633 break; 634 635 case 'm': 636 mode = MULTY; 637 need_addr = 1; 638 break; 639 640 case 'b': 641 data_size = atoi(optarg); 642 break; 643 644 case 'i': 645 if (!strncasecmp(optarg, "hci", 3)) 646 hci_devba(atoi(optarg + 3), &bdaddr); 647 else 648 str2ba(optarg, &bdaddr); 649 break; 650 651 case 'P': 652 channel = atoi(optarg); 653 break; 654 655 case 'U': 656 if (!strcasecmp(optarg, "spp")) 657 uuid = SERIAL_PORT_SVCLASS_ID; 658 else if (!strncasecmp(optarg, "0x", 2)) 659 uuid = strtoul(optarg + 2, NULL, 16); 660 else 661 uuid = atoi(optarg); 662 break; 663 664 case 'M': 665 master = 1; 666 break; 667 668 case 'A': 669 auth = 1; 670 break; 671 672 case 'E': 673 encrypt = 1; 674 break; 675 676 case 'S': 677 secure = 1; 678 break; 679 680 case 'L': 681 linger = atoi(optarg); 682 break; 683 684 case 'W': 685 defer_setup = atoi(optarg); 686 break; 687 688 case 'B': 689 filename = strdup(optarg); 690 break; 691 692 case 'N': 693 num_frames = atoi(optarg); 694 break; 695 696 case 'C': 697 count = atoi(optarg); 698 break; 699 700 case 'D': 701 delay = atoi(optarg) * 1000; 702 break; 703 704 case 'T': 705 timestamp = 1; 706 break; 707 708 default: 709 usage(); 710 exit(1); 711 } 712 } 713 714 if (need_addr && !(argc - optind)) { 715 usage(); 716 exit(1); 717 } 718 719 if (!(buf = malloc(data_size))) { 720 perror("Can't allocate data buffer"); 721 exit(1); 722 } 723 724 memset(&sa, 0, sizeof(sa)); 725 sa.sa_handler = SIG_IGN; 726 sa.sa_flags = SA_NOCLDSTOP; 727 sigaction(SIGCHLD, &sa, NULL); 728 729 openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); 730 731 switch (mode) { 732 case RECV: 733 do_listen(recv_mode); 734 break; 735 736 case CRECV: 737 sk = do_connect(argv[optind]); 738 if (sk < 0) 739 exit(1); 740 recv_mode(sk); 741 break; 742 743 case DUMP: 744 do_listen(dump_mode); 745 break; 746 747 case SEND: 748 sk = do_connect(argv[optind]); 749 if (sk < 0) 750 exit(1); 751 send_mode(sk); 752 break; 753 754 case LSEND: 755 do_listen(send_mode); 756 break; 757 758 case RECONNECT: 759 reconnect_mode(argv[optind]); 760 break; 761 762 case MULTY: 763 multi_connect_mode(argc - optind, argv + optind); 764 break; 765 766 case CONNECT: 767 sk = do_connect(argv[optind]); 768 if (sk < 0) 769 exit(1); 770 dump_mode(sk); 771 break; 772 } 773 774 syslog(LOG_INFO, "Exit"); 775 776 closelog(); 777 778 return 0; 779 } 780