rctest.c 17 KB

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