1c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky/* 2b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * 3b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * BlueZ - Bluetooth protocol stack for Linux 4b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * 5b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * Copyright (C) 2000-2001 Qualcomm Incorporated 6b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> 79184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> 8b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * 9b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * 10b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * This program is free software; you can redistribute it and/or modify 11632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * it under the terms of the GNU General Public License as published by 12632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * the Free Software Foundation; either version 2 of the License, or 13632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * (at your option) any later version. 14b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * 15632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * This program is distributed in the hope that it will be useful, 16632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 17632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * GNU General Public License for more details. 19b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * 20632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * You should have received a copy of the GNU General Public License 21632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * along with this program; if not, write to the Free Software 22632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann * 24c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky */ 25c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 26b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann#ifdef HAVE_CONFIG_H 27b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann#include <config.h> 28b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann#endif 29b8707600fd45e0cda31654fc7b2932f29b28d1a1Marcel Holtmann 30c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <stdio.h> 31c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <errno.h> 321f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann#include <ctype.h> 33da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann#include <fcntl.h> 3414be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann#include <unistd.h> 3514be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann#include <stdlib.h> 365481f007aa304a6f5f4531a243e146f9075dc17fMarcel Holtmann#include <getopt.h> 3714be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann#include <syslog.h> 38c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <signal.h> 391f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann#include <sys/time.h> 4077f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann#include <sys/poll.h> 412199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann#include <sys/ioctl.h> 42c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <sys/socket.h> 43c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4404c8ddd5a5d720e75144755d071e2331c979d1edMax Krasnyansky#include <bluetooth/bluetooth.h> 4552d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann#include <bluetooth/hci.h> 4652d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann#include <bluetooth/hci_lib.h> 4704c8ddd5a5d720e75144755d071e2331c979d1edMax Krasnyansky#include <bluetooth/l2cap.h> 48c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4914be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann#define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) 501f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 51c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky/* Test modes */ 52c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskyenum { 53c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky SEND, 54c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky RECV, 55c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky RECONNECT, 56c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky MULTY, 57c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky DUMP, 5804c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky CONNECT, 5904c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky CRECV, 601f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann LSEND, 611f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann SENDDUMP, 62329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann LSENDDUMP, 63a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan LSENDRECV, 64a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan CSENDRECV, 6522fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann INFOREQ, 6622fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann PAIRING, 67c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky}; 68c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 693c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic unsigned char *buf; 70c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 71c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky/* Default mtu */ 723c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int imtu = 672; 733c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int omtu = 0; 74c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 7533874cd97071383ca45b09a0fcb51b888002b0d9Gustavo F. Padovan/* Default FCS option */ 7633874cd97071383ca45b09a0fcb51b888002b0d9Gustavo F. Padovanstatic int fcs = 0x01; 7733874cd97071383ca45b09a0fcb51b888002b0d9Gustavo F. Padovan 78449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan/* Default Transmission Window */ 79449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovanstatic int txwin_size = 63; 80449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan 81449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan/* Default Max Transmission */ 82449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovanstatic int max_transmit = 3; 83449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan 84c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky/* Default data size */ 8577f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmannstatic long data_size = -1; 8641e30382f9a83f41da700465de274266c60248b4Marcel Holtmannstatic long buffer_size = 2048; 87c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 88c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan/* Default addr and psm and cid */ 893c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic bdaddr_t bdaddr; 90cd09d807d3060f4b269602276504a8380ab1a2c1Gustavo F. Padovanstatic unsigned short psm = 0x1011; 91c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovanstatic unsigned short cid = 0; 92c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 937715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann/* Default number of frames to send (-1 = infinite) */ 947715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmannstatic int num_frames = -1; 9533a6d8d6bc6bf30a37a92ef40353e6426beeb59bMarcel Holtmann 96b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann/* Default number of consecutive frames before the delay */ 97b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmannstatic int count = 1; 98b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann 99b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann/* Default delay after sending count number of frames */ 100b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmannstatic unsigned long delay = 0; 101b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann 102da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmannstatic char *filename = NULL; 103da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann 1048e34afe9cc4dada1c34126a9723f76d4a6705707Marcel Holtmannstatic int rfcmode = 0; 1053c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int master = 0; 1063c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int auth = 0; 1073c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int encrypt = 0; 1083c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int secure = 0; 1093c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int socktype = SOCK_SEQPACKET; 1103c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int linger = 0; 1113c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int reliable = 0; 1125b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmannstatic int timestamp = 0; 1139e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmannstatic int defer_setup = 0; 114c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1153c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic float tv2fl(struct timeval tv) 116c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 117c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); 118c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 119c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1203c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic char *ltoh(unsigned long c, char* s) 1211f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann{ 1221f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann int c1; 1231f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 1241f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 28) & 0x0f; 1251f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1261f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 24) & 0x0f; 1271f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1281f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 20) & 0x0f; 1291f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1301f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 16) & 0x0f; 1311f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1321f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 12) & 0x0f; 1331f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1341f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 8) & 0x0f; 1351f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1361f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 4) & 0x0f; 1371f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1381f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = c & 0x0f; 1391f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1401f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *s = 0; 14114be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann return s; 1421f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann} 1431f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 1443c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic char *ctoh(char c, char* s) 1451f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann{ 1461f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann char c1; 1471f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 1481f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = (c >> 4) & 0x0f; 1491f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1501f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann c1 = c & 0x0f; 1511f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(s++) = NIBBLE_TO_ASCII (c1); 1521f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *s = 0; 15314be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann return s; 1541f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann} 1551f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 1561f422e5f2b343d35a8c77ce4be16f74b2819b2bfMarcel Holtmannstatic void hexdump(unsigned char *s, unsigned long l) 1571f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann{ 1581f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann char bfr[80]; 1591f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann char *pb; 1601f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann unsigned long i, n = 0; 1613c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 1621f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann if (l == 0) 1631f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann return; 1643c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 1651f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann while (n < l) { 1661f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann pb = bfr; 1671f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann pb = ltoh (n, pb); 1681f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(pb++) = ':'; 1691f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(pb++) = ' '; 1701f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann for (i = 0; i < 16; i++) { 1711f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann if (n + i >= l) { 1721f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(pb++) = ' '; 1731f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(pb++) = ' '; 1741f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann } else 1751f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann pb = ctoh (*(s + i), pb); 1761f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(pb++) = ' '; 1771f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann } 1781f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(pb++) = ' '; 1791f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann for (i = 0; i < 16; i++) { 1801f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann if (n + i >= l) 1811f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann break; 1821f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann else 1831f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann *(pb++) = (isprint (*(s + i)) ? *(s + i) : '.'); 1841f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann } 1853c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann *pb = 0; 1861f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann n += 16; 1871f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann s += 16; 1881f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann puts(bfr); 1891f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann } 1901f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann} 1911f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 1923c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic int do_connect(char *svr) 193c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 1947715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann struct sockaddr_l2 addr; 195c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct l2cap_options opts; 1969e6e37723b8d8798ed9ba58734fd3022fdf49dc2Marcel Holtmann struct l2cap_conninfo conn; 1977715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann socklen_t optlen; 1987715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann int sk, opt; 199c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2007715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Create socket */ 2017715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann sk = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP); 2027715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (sk < 0) { 2037715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't create socket: %s (%d)", 2047715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 205c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return -1; 206c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 207c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2087715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Bind to local address */ 2097715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann memset(&addr, 0, sizeof(addr)); 2107715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann addr.l2_family = AF_BLUETOOTH; 2117715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann bacpy(&addr.l2_bdaddr, &bdaddr); 2127715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 2137715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 2147715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't bind socket: %s (%d)", 2157715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 2167715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 217c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 218c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 219c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Get default options */ 220bbda499067067aefc8e642a2784d247ac0331eaeMarcel Holtmann memset(&opts, 0, sizeof(opts)); 2217715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(opts); 2227715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 2237715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { 2247715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", 2257715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 2267715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 227c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 228c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 229c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Set new options */ 230c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky opts.omtu = omtu; 231c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky opts.imtu = imtu; 2325261de27f3d5463febf4d7dfa3a7e417ba0d4df5Gustavo F. Padovan opts.mode = rfcmode; 2337715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 23433874cd97071383ca45b09a0fcb51b888002b0d9Gustavo F. Padovan opts.fcs = fcs; 235449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan opts.txwin_size = txwin_size; 236449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan opts.max_tx = max_transmit; 23733874cd97071383ca45b09a0fcb51b888002b0d9Gustavo F. Padovan 2387715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { 2397715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", 2407715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 2417715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 242c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 243c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2442199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann#if 0 2455b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann /* Enable SO_TIMESTAMP */ 2465b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann if (timestamp) { 2475b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann int t = 1; 2485b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann 2495b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann if (setsockopt(sk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { 2505b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)", 2515b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann strerror(errno), errno); 2525b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann goto error; 2535b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann } 2545b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann } 2552199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann#endif 2565b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann 25779cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky /* Enable SO_LINGER */ 25879cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky if (linger) { 25979cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky struct linger l = { .l_onoff = 1, .l_linger = linger }; 2607715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 2617715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { 26214be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", 2637715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 2645b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann goto error; 26579cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky } 26679cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky } 26779cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky 268f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann /* Set link mode */ 269f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann opt = 0; 270f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann if (reliable) 27114be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann opt |= L2CAP_LM_RELIABLE; 27206e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann if (master) 27306e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann opt |= L2CAP_LM_MASTER; 27406e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann if (auth) 27506e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann opt |= L2CAP_LM_AUTH; 27606e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann if (encrypt) 27706e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann opt |= L2CAP_LM_ENCRYPT; 27806e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann if (secure) 27906e4d41372a9f005b05cc2f4a09924f18bf6f6d7Marcel Holtmann opt |= L2CAP_LM_SECURE; 280f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann 2817715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { 2827715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", 2837715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 2847715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 285f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } 286f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann 2877715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Connect to remote device */ 2887715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann memset(&addr, 0, sizeof(addr)); 2897715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann addr.l2_family = AF_BLUETOOTH; 2907715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann str2ba(svr, &addr.l2_bdaddr); 291c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan if (cid) 292c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan addr.l2_cid = htobs(cid); 293c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan else if (psm) 294c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan addr.l2_psm = htobs(psm); 295c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan else 296c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan goto error; 2977715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 2987715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { 2997715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't connect: %s (%d)", 3007715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 3017715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 302c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 303c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 3047715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Get current options */ 305bbda499067067aefc8e642a2784d247ac0331eaeMarcel Holtmann memset(&opts, 0, sizeof(opts)); 3067715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(opts); 3077715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 3087715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { 3097715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", 3107715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 3117715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 312c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 313c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 3147715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Get connection information */ 3159e6e37723b8d8798ed9ba58734fd3022fdf49dc2Marcel Holtmann memset(&conn, 0, sizeof(conn)); 3167715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(conn); 3177715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 3187715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &optlen) < 0) { 3197715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", 3207715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 3217715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 3229e6e37723b8d8798ed9ba58734fd3022fdf49dc2Marcel Holtmann } 3239e6e37723b8d8798ed9ba58734fd3022fdf49dc2Marcel Holtmann 3247715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d, " 3257715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann "mode %d, handle %d, class 0x%02x%02x%02x]", 3269e6e37723b8d8798ed9ba58734fd3022fdf49dc2Marcel Holtmann opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, 3279e6e37723b8d8798ed9ba58734fd3022fdf49dc2Marcel Holtmann conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); 328c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 32941e30382f9a83f41da700465de274266c60248b4Marcel Holtmann omtu = (opts.omtu > buffer_size) ? buffer_size : opts.omtu; 33041e30382f9a83f41da700465de274266c60248b4Marcel Holtmann imtu = (opts.imtu > buffer_size) ? buffer_size : opts.imtu; 33172a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann 3327715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann return sk; 3337715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 3347715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmannerror: 3357715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann close(sk); 3367715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann return -1; 337c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 338c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 3393c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic void do_listen(void (*handler)(int sk)) 340c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 3417715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann struct sockaddr_l2 addr; 342c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct l2cap_options opts; 343d198227a6d76b6fb6bff050e6fda9f2e4ffc4544Marcel Holtmann struct l2cap_conninfo conn; 3447715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann socklen_t optlen; 3457715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann int sk, nsk, opt; 3463c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann char ba[18]; 347c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 3487715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Create socket */ 3497715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann sk = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP); 3507715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (sk < 0) { 3517715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't create socket: %s (%d)", 3527715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 353c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 354c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 355c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 3567715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Bind to local address */ 3574296b2cda59e00a559caa988c81598605cdfcf0fMarcel Holtmann memset(&addr, 0, sizeof(addr)); 3587715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann addr.l2_family = AF_BLUETOOTH; 3597715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann bacpy(&addr.l2_bdaddr, &bdaddr); 360c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan if (cid) 361c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan addr.l2_cid = htobs(cid); 362c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan else if (psm) 363c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan addr.l2_psm = htobs(psm); 364c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan else 365c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan goto error; 3667715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 3677715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 3687715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't bind socket: %s (%d)", 3697715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 3707715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 371c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 372c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 37370516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky /* Set link mode */ 37470516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky opt = 0; 375f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann if (reliable) 376f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann opt |= L2CAP_LM_RELIABLE; 37770516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky if (master) 37852d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann opt |= L2CAP_LM_MASTER; 37970516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky if (auth) 38052d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann opt |= L2CAP_LM_AUTH; 38170516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky if (encrypt) 38252d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann opt |= L2CAP_LM_ENCRYPT; 38352d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann if (secure) 38452d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann opt |= L2CAP_LM_SECURE; 38570516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky 3867715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (opt && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { 3877715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", 3887715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 3897715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 390c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 391c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 392c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Get default options */ 3937715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann memset(&opts, 0, sizeof(opts)); 3947715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(opts); 3957715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 3967715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { 3977715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", 3987715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 3997715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 400c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 401c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 402c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Set new options */ 40311d24685fbd0b32c19bab01c0644dd9d5ea25315Marcel Holtmann opts.omtu = omtu; 404c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky opts.imtu = imtu; 4058e34afe9cc4dada1c34126a9723f76d4a6705707Marcel Holtmann if (rfcmode > 0) 4068e34afe9cc4dada1c34126a9723f76d4a6705707Marcel Holtmann opts.mode = rfcmode; 4077715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 40833874cd97071383ca45b09a0fcb51b888002b0d9Gustavo F. Padovan opts.fcs = fcs; 409449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan opts.txwin_size = txwin_size; 410449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan opts.max_tx = max_transmit; 41133874cd97071383ca45b09a0fcb51b888002b0d9Gustavo F. Padovan 4127715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { 4137715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", 4147715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 4157715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 416c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 417c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 41870516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky if (socktype == SOCK_DGRAM) { 4197715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann handler(sk); 42070516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky return; 42170516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky } 422c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4239e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann /* Enable deferred setup */ 4249e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann opt = defer_setup; 4259e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann 4269e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (opt && setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP, 4279e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann &opt, sizeof(opt)) < 0) { 4289e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann syslog(LOG_ERR, "Can't enable deferred setup : %s (%d)", 4299e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann strerror(errno), errno); 4309e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann goto error; 4319e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann } 4329e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann 4337715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Listen for connections */ 4347715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (listen(sk, 10)) { 4357715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can not listen on the socket: %s (%d)", 4367715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 4377715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 438c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 439c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 440b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann /* Check for socket address */ 441b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann memset(&addr, 0, sizeof(addr)); 442b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann optlen = sizeof(addr); 443b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann 444b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) { 445b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann syslog(LOG_ERR, "Can't get socket name: %s (%d)", 446b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann strerror(errno), errno); 447b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann goto error; 448b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann } 449b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann 450b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann psm = btohs(addr.l2_psm); 451c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan cid = btohs(addr.l2_cid); 452b4ccc4c8dec3b4421f5f644424103eb0274d446aMarcel Holtmann 4537715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_INFO, "Waiting for connection on psm %d ...", psm); 454c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4559e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann while (1) { 4567715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann memset(&addr, 0, sizeof(addr)); 4577715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(addr); 4587715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 4597715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann nsk = accept(sk, (struct sockaddr *) &addr, &optlen); 4607715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (nsk < 0) { 4617715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Accept failed: %s (%d)", 4627715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 4637715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 464c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 46514be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann if (fork()) { 466c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Parent */ 4677715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann close(nsk); 468c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky continue; 469c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 470c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Child */ 4717715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann close(sk); 472c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4737715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Get current options */ 474d198227a6d76b6fb6bff050e6fda9f2e4ffc4544Marcel Holtmann memset(&opts, 0, sizeof(opts)); 4757715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(opts); 4767715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 4777715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (getsockopt(nsk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { 4787715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", 4797715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 4809e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (!defer_setup) { 4819e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann close(nsk); 4829e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann goto error; 4839e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann } 484d198227a6d76b6fb6bff050e6fda9f2e4ffc4544Marcel Holtmann } 485d198227a6d76b6fb6bff050e6fda9f2e4ffc4544Marcel Holtmann 4867715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann /* Get connection information */ 487d198227a6d76b6fb6bff050e6fda9f2e4ffc4544Marcel Holtmann memset(&conn, 0, sizeof(conn)); 4887715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(conn); 4897715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 4907715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (getsockopt(nsk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &optlen) < 0) { 4917715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", 4927715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 4939e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (!defer_setup) { 4949e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann close(nsk); 4959e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann goto error; 4969e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann } 497c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 498c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4997715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann ba2str(&addr.l2_bdaddr, ba); 5007715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, " 50154c95138efbc91165d50ee0e3e1fd906493bf68fMarcel Holtmann "mode %d, handle %d, class 0x%02x%02x%02x]", 502d198227a6d76b6fb6bff050e6fda9f2e4ffc4544Marcel Holtmann ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, 503d198227a6d76b6fb6bff050e6fda9f2e4ffc4544Marcel Holtmann conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); 504c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 50541e30382f9a83f41da700465de274266c60248b4Marcel Holtmann omtu = (opts.omtu > buffer_size) ? buffer_size : opts.omtu; 50641e30382f9a83f41da700465de274266c60248b4Marcel Holtmann imtu = (opts.imtu > buffer_size) ? buffer_size : opts.imtu; 50741e30382f9a83f41da700465de274266c60248b4Marcel Holtmann 5082199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann#if 0 5095b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann /* Enable SO_TIMESTAMP */ 5105b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann if (timestamp) { 5115b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann int t = 1; 5125b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann 5139e198552165e2e473a9cb6792a70fe85fecbc987Marcel Holtmann if (setsockopt(nsk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { 5145b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)", 5155b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann strerror(errno), errno); 5165b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann goto error; 5175b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann } 5185b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann } 5192199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann#endif 5205b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann 52179cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky /* Enable SO_LINGER */ 52279cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky if (linger) { 52379cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky struct linger l = { .l_onoff = 1, .l_linger = linger }; 5247715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 5257715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { 52614be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", 5277715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 5287715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann close(nsk); 5297715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann goto error; 53079cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky } 53179cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky } 53279cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky 5339e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann /* Handle deferred setup */ 5349e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (defer_setup) { 5359e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann syslog(LOG_INFO, "Waiting for %d seconds", 5369e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann abs(defer_setup) - 1); 5379e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann sleep(abs(defer_setup) - 1); 5389e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann 5399e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (defer_setup < 0) { 5409e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann close(nsk); 5419e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann goto error; 5429e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann } 5439e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann } 5449e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann 5457715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann handler(nsk); 546c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 54714be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann syslog(LOG_INFO, "Disconnect: %m"); 548c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(0); 549c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 5507715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 5517715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann return; 5527715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann 5537715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmannerror: 5547715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann close(sk); 5557715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann exit(1); 556c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 557c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 5587715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmannstatic void dump_mode(int sk) 559c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 5607715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann socklen_t optlen; 5617715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann int opt, len; 562c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 56341e30382f9a83f41da700465de274266c60248b4Marcel Holtmann if (data_size < 0) 56441e30382f9a83f41da700465de274266c60248b4Marcel Holtmann data_size = imtu; 56541e30382f9a83f41da700465de274266c60248b4Marcel Holtmann 5669e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (defer_setup) { 5679e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann len = read(sk, buf, sizeof(buf)); 5689e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (len < 0) 5699e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann syslog(LOG_ERR, "Initial read error: %s (%d)", 5709e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann strerror(errno), errno); 5719e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann else 5729e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann syslog(LOG_INFO, "Initial bytes %d", len); 5739e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann } 5749e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann 57570516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky syslog(LOG_INFO, "Receiving ..."); 576d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky while (1) { 577d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky fd_set rset; 5783c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 579d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky FD_ZERO(&rset); 5807715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann FD_SET(sk, &rset); 58114be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann 5827715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (select(sk + 1, &rset, NULL, NULL, NULL) < 0) 583d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky return; 584d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky 5857715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (!FD_ISSET(sk, &rset)) 586d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky continue; 587d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky 5887715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann len = read(sk, buf, data_size); 589f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann if (len <= 0) { 590f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann if (len < 0) { 591f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann if (reliable && (errno == ECOMM)) { 5927715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing."); 5937715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann optlen = sizeof(opt); 5947715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { 5957715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", 5963c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann strerror(errno), errno); 597f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann return; 598f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } 599f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann continue; 600f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } else { 6017715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_ERR, "Read error: %s(%d)", 6027715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann strerror(errno), errno); 603f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } 604f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } 605d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky return; 606f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } 607d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky 6087715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann syslog(LOG_INFO, "Recevied %d bytes", len); 6091f422e5f2b343d35a8c77ce4be16f74b2819b2bfMarcel Holtmann hexdump(buf, len); 610d774efc2f8cc21d599cacc933ea26e0d63e91365Max Krasnyansky } 611c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 612c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 6137715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmannstatic void recv_mode(int sk) 614c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 61577f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann struct timeval tv_beg, tv_end, tv_diff; 61677f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann struct pollfd p; 6172199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann char ts[30]; 618c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky long total; 619c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky uint32_t seq; 6207715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann socklen_t optlen; 6219e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann int opt, len; 6229e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann 62341e30382f9a83f41da700465de274266c60248b4Marcel Holtmann if (data_size < 0) 62441e30382f9a83f41da700465de274266c60248b4Marcel Holtmann data_size = imtu; 62541e30382f9a83f41da700465de274266c60248b4Marcel Holtmann 6269e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (defer_setup) { 6279e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann len = read(sk, buf, sizeof(buf)); 6289e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann if (len < 0) 6299e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann syslog(LOG_ERR, "Initial read error: %s (%d)", 6309e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann strerror(errno), errno); 6319e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann else 6329e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann syslog(LOG_INFO, "Initial bytes %d", len); 6339e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann } 634c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 6352199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann syslog(LOG_INFO, "Receiving ..."); 6362199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann 6372199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann memset(ts, 0, sizeof(ts)); 638c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 63977f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann p.fd = sk; 64077f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann p.events = POLLIN | POLLERR | POLLHUP; 64177f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann 642c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky seq = 0; 643c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky while (1) { 64414be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann gettimeofday(&tv_beg, NULL); 645c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky total = 0; 646c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky while (total < data_size) { 647c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky uint32_t sq; 648c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky uint16_t l; 6499e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann int i; 65077f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann 65177f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann p.revents = 0; 65277f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann if (poll(&p, 1, -1) <= 0) 65377f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann return; 65477f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann 65577f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann if (p.revents & (POLLERR | POLLHUP)) 65677f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann return; 65777f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann 65877f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann len = recv(sk, buf, data_size, 0); 65977f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann if (len < 0) { 66077f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann if (reliable && (errno == ECOMM)) { 66177f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); 66277f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann optlen = sizeof(opt); 66377f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { 66477f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", 6653c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann strerror(errno), errno); 66677f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann return; 667f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } 66877f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann continue; 66977f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann } else { 67077f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann syslog(LOG_ERR, "Read failed: %s (%d)", 67177f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann strerror(errno), errno); 672f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann } 673c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 674c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 67577f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann if (len < 6) 67677f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann break; 67777f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann 6782199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann if (timestamp) { 6792199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann struct timeval tv; 6802199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann 6812199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann if (ioctl(sk, SIOCGSTAMP, &tv) < 0) { 6822199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann timestamp = 0; 6832199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann memset(ts, 0, sizeof(ts)); 6842199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann } else { 6852199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann sprintf(ts, "[%ld.%ld] ", 6862199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann tv.tv_sec, tv.tv_usec); 6872199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann } 6882199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann } 6892199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann 690c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Check sequence */ 69114be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann sq = btohl(*(uint32_t *) buf); 692c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (seq != sq) { 693c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); 694c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky seq = sq; 695c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 696c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky seq++; 6973c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 698c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Check length */ 69914be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann l = btohs(*(uint16_t *) (buf + 4)); 70077f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann if (len != l) { 70177f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann syslog(LOG_INFO, "size missmatch: %d -> %d", len, l); 702c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky continue; 703c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 7043c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 7053c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann /* Verify data */ 70677f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann for (i = 6; i < len; i++) { 707c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (buf[i] != 0x7f) 708c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); 709c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 710c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 71177f2ea7f02d5981deab6ec22d05570e06d46836eMarcel Holtmann total += len; 712c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 71314be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann gettimeofday(&tv_end, NULL); 714c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 71514be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann timersub(&tv_end, &tv_beg, &tv_diff); 716c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 7172199bc76c668f92e14fcaa4bc16fd4674f728bc1Marcel Holtmann syslog(LOG_INFO,"%s%ld bytes in %.2f sec, %.2f kB/s", ts, total, 7183c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); 719c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 720c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 721c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 722da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmannstatic void do_send(int sk) 723c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 724c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky uint32_t seq; 725f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann int i, fd, len, buflen, size, sent; 726c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 727893ddcab14bb2b5309ba0f181a5a9941a2d28661Max Krasnyansky syslog(LOG_INFO, "Sending ..."); 728c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 72941e30382f9a83f41da700465de274266c60248b4Marcel Holtmann if (data_size < 0) 73041e30382f9a83f41da700465de274266c60248b4Marcel Holtmann data_size = omtu; 73141e30382f9a83f41da700465de274266c60248b4Marcel Holtmann 732da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann if (filename) { 733da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann fd = open(filename, O_RDONLY); 734da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann if (fd < 0) { 735da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann syslog(LOG_ERR, "Open failed: %s (%d)", 736da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann strerror(errno), errno); 737da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann exit(1); 738da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann } 739f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann 740f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann sent = 0; 741f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann size = read(fd, buf, data_size); 742f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann while (size > 0) { 743f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann buflen = (size > omtu) ? omtu : size; 744f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann 745f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann len = send(sk, buf + sent, buflen, 0); 746f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann 747f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann sent += len; 748f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann size -= len; 749f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann } 750da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann return; 751da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann } else { 752da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann for (i = 6; i < data_size; i++) 753da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann buf[i] = 0x7f; 754da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann } 755c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 756c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky seq = 0; 757893ddcab14bb2b5309ba0f181a5a9941a2d28661Max Krasnyansky while ((num_frames == -1) || (num_frames-- > 0)) { 758b2d7fd8c8e1c7948169726639675d462bd83e50eMarcel Holtmann *(uint32_t *) buf = htobl(seq); 75914be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann *(uint16_t *) (buf + 4) = htobs(data_size); 760b2d7fd8c8e1c7948169726639675d462bd83e50eMarcel Holtmann seq++; 7613c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 762f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann sent = 0; 763f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann size = data_size; 764f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann while (size > 0) { 765f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann buflen = (size > omtu) ? omtu : size; 766f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann 767f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann len = send(sk, buf, buflen, 0); 768f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann if (len < 0 || len != buflen) { 769f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann syslog(LOG_ERR, "Send failed: %s (%d)", 770da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann strerror(errno), errno); 771f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann exit(1); 772f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann } 773f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann 774f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann sent += len; 775f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann size -= len; 776c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 777b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann 778e6673071212596bc54fb5bffff72b0c3a8275071Marcel Holtmann if (num_frames && delay && count && !(seq % count)) 779b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann usleep(delay); 780c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 781da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann} 782da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann 783da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmannstatic void send_mode(int sk) 784da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann{ 785da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann do_send(sk); 786893ddcab14bb2b5309ba0f181a5a9941a2d28661Max Krasnyansky 787893ddcab14bb2b5309ba0f181a5a9941a2d28661Max Krasnyansky syslog(LOG_INFO, "Closing channel ..."); 7887715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann if (shutdown(sk, SHUT_RDWR) < 0) 78914be8b04824df3f5a9bd7b713646a9120e2b2454Marcel Holtmann syslog(LOG_INFO, "Close failed: %m"); 790893ddcab14bb2b5309ba0f181a5a9941a2d28661Max Krasnyansky else 791893ddcab14bb2b5309ba0f181a5a9941a2d28661Max Krasnyansky syslog(LOG_INFO, "Done"); 792c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 793c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 7947715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmannstatic void senddump_mode(int sk) 7951f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann{ 796da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann do_send(sk); 7971f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 7987715ad4f56e82c9eb4cf75020b1f3039d06ce115Marcel Holtmann dump_mode(sk); 7991f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann} 8001f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 801a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovanstatic void send_and_recv_mode(int sk) 802a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan{ 803a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan int flags; 804a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 805a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan if ((flags = fcntl(sk, F_GETFL, 0)) < 0) 806a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan flags = 0; 807a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan fcntl(sk, F_SETFL, flags | O_NONBLOCK); 808a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 809a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan /* fork for duplex channel */ 810a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan if (fork()) 811a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan send_mode(sk); 812a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan else 813a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan recv_mode(sk); 814a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan return; 815a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan} 816a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 8173c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic void reconnect_mode(char *svr) 818c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 81939654da8de5f5d3f9888cb2d4d576993414642ecMarcel Holtmann while (1) { 82039654da8de5f5d3f9888cb2d4d576993414642ecMarcel Holtmann int sk = do_connect(svr); 82139654da8de5f5d3f9888cb2d4d576993414642ecMarcel Holtmann close(sk); 822c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 823c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 824c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 8253c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic void connect_mode(char *svr) 826c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 82772a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann struct pollfd p; 82839654da8de5f5d3f9888cb2d4d576993414642ecMarcel Holtmann int sk; 82939654da8de5f5d3f9888cb2d4d576993414642ecMarcel Holtmann 83039654da8de5f5d3f9888cb2d4d576993414642ecMarcel Holtmann if ((sk = do_connect(svr)) < 0) 831c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 83239654da8de5f5d3f9888cb2d4d576993414642ecMarcel Holtmann 83372a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann p.fd = sk; 83472a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann p.events = POLLERR | POLLHUP; 83572a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann 83672a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann while (1) { 83772a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann p.revents = 0; 83835e9349ffc53950c4b78fba9537a50cdb6e5fd7aMarcel Holtmann if (poll(&p, 1, 500)) 83972a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann break; 84072a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann } 84172a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann 84272a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann syslog(LOG_INFO, "Disconnected"); 84372a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann 84472a919e9b1ae03645a63e27dfa6f4190ade6c924Marcel Holtmann close(sk); 845c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 846c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 8470effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmannstatic void multi_connect_mode(int argc, char *argv[]) 848c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 8490effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann int i, n, sk; 8500effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann 85189d41e2e6c81aa5c30f2fa699cc4654eb174627cMax Krasnyansky while (1) { 8520effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann for (n = 0; n < argc; n++) { 8530effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann for (i = 0; i < count; i++) { 8540effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann if (fork()) 8550effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann continue; 8560effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann 8570effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann /* Child */ 8580effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann sk = do_connect(argv[n]); 8590effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann usleep(500); 8600effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann close(sk); 8610effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann exit(0); 8620effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann } 863c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 8640effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann sleep(4); 865c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 866c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 867c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 868329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmannstatic void info_request(char *svr) 869329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann{ 870329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann unsigned char buf[48]; 871329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; 872329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann l2cap_info_req *req = (l2cap_info_req *) (buf + L2CAP_CMD_HDR_SIZE); 873329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann l2cap_info_rsp *rsp = (l2cap_info_rsp *) (buf + L2CAP_CMD_HDR_SIZE); 874329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann uint16_t mtu; 8756f220b305be27d1aea0cdd24b5a615c6b91e9cbfMarcel Holtmann uint32_t channels, mask = 0x0000; 876329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann struct sockaddr_l2 addr; 877329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann int sk, err; 878329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 879329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); 880329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (sk < 0) { 881329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann perror("Can't create socket"); 882329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann return; 883329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 884329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 885329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann memset(&addr, 0, sizeof(addr)); 886329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann addr.l2_family = AF_BLUETOOTH; 887329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann bacpy(&addr.l2_bdaddr, &bdaddr); 888329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 889329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 890329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann perror("Can't bind socket"); 891329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann goto failed; 892329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 893329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 894329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann memset(&addr, 0, sizeof(addr)); 895329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann addr.l2_family = AF_BLUETOOTH; 896329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann str2ba(svr, &addr.l2_bdaddr); 897329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 898329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { 899329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann perror("Can't connect socket"); 900329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann goto failed; 901329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 902329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 903329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann memset(buf, 0, sizeof(buf)); 904329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann cmd->code = L2CAP_INFO_REQ; 90549d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann cmd->ident = 141; 906329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann cmd->len = htobs(2); 907329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann req->type = htobs(0x0001); 908329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 909329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (send(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_REQ_SIZE, 0) < 0) { 910329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann perror("Can't send info request"); 911329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann goto failed; 912329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 913329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 914329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 2, 0); 915329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (err < 0) { 916329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann perror("Can't receive info response"); 917329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann goto failed; 918329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 919329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 920329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann switch (btohs(rsp->result)) { 921329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann case 0x0000: 9226432bf4db31b26943889958263e61c6255f0f15bMarcel Holtmann memcpy(&mtu, rsp->data, sizeof(mtu)); 9236432bf4db31b26943889958263e61c6255f0f15bMarcel Holtmann printf("Connectionless MTU size is %d\n", btohs(mtu)); 924329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann break; 925329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann case 0x0001: 926329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann printf("Connectionless MTU is not supported\n"); 927329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann break; 928329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 929329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 930329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann memset(buf, 0, sizeof(buf)); 931329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann cmd->code = L2CAP_INFO_REQ; 93249d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann cmd->ident = 142; 933329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann cmd->len = htobs(2); 934329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann req->type = htobs(0x0002); 935329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 936329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (send(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_REQ_SIZE, 0) < 0) { 937329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann perror("Can't send info request"); 938329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann goto failed; 939329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 940329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 941329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 4, 0); 942329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (err < 0) { 943329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann perror("Can't receive info response"); 944329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann goto failed; 945329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 946329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 947329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann switch (btohs(rsp->result)) { 948329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann case 0x0000: 9496432bf4db31b26943889958263e61c6255f0f15bMarcel Holtmann memcpy(&mask, rsp->data, sizeof(mask)); 9506432bf4db31b26943889958263e61c6255f0f15bMarcel Holtmann printf("Extended feature mask is 0x%04x\n", btohl(mask)); 951329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (mask & 0x01) 952329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann printf(" Flow control mode\n"); 953329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (mask & 0x02) 954329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann printf(" Retransmission mode\n"); 955329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann if (mask & 0x04) 956329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann printf(" Bi-directional QoS\n"); 9573fb63ab3bf9e6c1d474d3779992feb1f464cef42Gustavo F. Padovan if (mask & 0x08) 9583fb63ab3bf9e6c1d474d3779992feb1f464cef42Gustavo F. Padovan printf(" Enhanced Retransmission mode\n"); 9593fb63ab3bf9e6c1d474d3779992feb1f464cef42Gustavo F. Padovan if (mask & 0x10) 9603fb63ab3bf9e6c1d474d3779992feb1f464cef42Gustavo F. Padovan printf(" Streaming mode\n"); 9613fb63ab3bf9e6c1d474d3779992feb1f464cef42Gustavo F. Padovan if (mask & 0x20) 9623fb63ab3bf9e6c1d474d3779992feb1f464cef42Gustavo F. Padovan printf(" FCS Option\n"); 9639fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann if (mask & 0x40) 9649fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann printf(" Extended Flow Specification\n"); 9659fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann if (mask & 0x80) 9669fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann printf(" Fixed Channels\n"); 9679fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann if (mask & 0x0100) 9689fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann printf(" Extended Window Size\n"); 9699fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann if (mask & 0x0200) 9709fca3da026d6af49ec93b98ec3479b21b58da83dMarcel Holtmann printf(" Unicast Connectionless Data Reception\n"); 971329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann break; 972329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann case 0x0001: 973329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann printf("Extended feature mask is not supported\n"); 974329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann break; 975329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann } 976329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 97749d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann if (!(mask & 0x80)) 97849d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann goto failed; 97949d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann 98049d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann memset(buf, 0, sizeof(buf)); 98149d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann cmd->code = L2CAP_INFO_REQ; 98249d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann cmd->ident = 143; 98349d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann cmd->len = htobs(2); 98449d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann req->type = htobs(0x0003); 98549d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann 98649d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann if (send(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_REQ_SIZE, 0) < 0) { 98749d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann perror("Can't send info request"); 98849d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann goto failed; 98949d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann } 99049d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann 99149d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 8, 0); 99249d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann if (err < 0) { 99349d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann perror("Can't receive info response"); 99449d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann goto failed; 99549d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann } 99649d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann 99749d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann switch (btohs(rsp->result)) { 99849d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann case 0x0000: 9996432bf4db31b26943889958263e61c6255f0f15bMarcel Holtmann memcpy(&channels, rsp->data, sizeof(channels)); 10006432bf4db31b26943889958263e61c6255f0f15bMarcel Holtmann printf("Fixed channels list is 0x%04x\n", btohl(channels)); 1001218672a1b1928266933d3cdabe5a942e34c7cd9cLuiz Augusto von Dentz break; 100249d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann case 0x0001: 100349d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann printf("Fixed channels list is not supported\n"); 100449d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann break; 100549d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann } 100649d0b0513690beec7038ac118ab95988961d7d2dMarcel Holtmann 1007329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmannfailed: 1008329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann close(sk); 1009329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann} 1010329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 101122fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmannstatic void do_pairing(char *svr) 101222fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann{ 101322fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann struct sockaddr_l2 addr; 101422fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann int sk, opt; 101522fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 101622fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); 101722fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann if (sk < 0) { 101822fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann perror("Can't create socket"); 101922fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann return; 102022fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann } 102122fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 102222fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann memset(&addr, 0, sizeof(addr)); 102322fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann addr.l2_family = AF_BLUETOOTH; 102422fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann bacpy(&addr.l2_bdaddr, &bdaddr); 102522fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 102622fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 102722fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann perror("Can't bind socket"); 102822fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann goto failed; 102922fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann } 103022fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 10317b5212174affc3834d32b68b07370810f9592cb1Marcel Holtmann if (secure) 10327b5212174affc3834d32b68b07370810f9592cb1Marcel Holtmann opt = L2CAP_LM_SECURE; 10337b5212174affc3834d32b68b07370810f9592cb1Marcel Holtmann else 10347b5212174affc3834d32b68b07370810f9592cb1Marcel Holtmann opt = L2CAP_LM_ENCRYPT; 103522fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 103622fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann if (setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { 103722fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann perror("Can't set link mode"); 103822fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann goto failed; 103922fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann } 104022fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 104122fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann memset(&addr, 0, sizeof(addr)); 104222fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann addr.l2_family = AF_BLUETOOTH; 104322fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann str2ba(svr, &addr.l2_bdaddr); 104422fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 104522fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { 104622fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann perror("Can't connect socket"); 104722fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann goto failed; 104822fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann } 104922fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 105022fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann printf("Pairing successful\n"); 105122fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 105222fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmannfailed: 105322fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann close(sk); 105422fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann} 105522fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 10563c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmannstatic void usage(void) 1057c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 1058c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky printf("l2test - L2CAP testing\n" 1059c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky "Usage:\n"); 1060aba9dc216df7ddacbaa10d9e25c7aba05ab28afbMax Krasnyansky printf("\tl2test <mode> [options] [bdaddr]\n"); 1061c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky printf("Modes:\n" 106204c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky "\t-r listen and receive\n" 106304c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky "\t-w listen and send\n" 106496209b933e9b3b9c93701e15e4a9590f859cc8c6Stephen Crane "\t-d listen and dump incoming data\n" 10651f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann "\t-x listen, then send, then dump incoming data\n" 1066a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan "\t-t listen, then send and receive at the same time\n" 1067a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan "\t-q connect, then send and receive at the same time\n" 106804c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky "\t-s connect and send\n" 106904c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky "\t-u connect and receive\n" 107004c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky "\t-n connect and be silent\n" 10711f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann "\t-y connect, then send, then dump incoming data\n" 107204c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky "\t-c connect, disconnect, connect, ...\n" 1073329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann "\t-m multiple connects\n" 107422fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann "\t-p trigger dedicated bonding\n" 1075329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann "\t-z information request\n"); 107604c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky 1077aba9dc216df7ddacbaa10d9e25c7aba05ab28afbMax Krasnyansky printf("Options:\n" 1078c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan "\t[-b bytes] [-i device] [-P psm] [-J cid]\n" 10793c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann "\t[-I imtu] [-O omtu]\n" 108079cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky "\t[-L seconds] enable SO_LINGER\n" 108111e2f9bf390d828b45e26a8a1c00f503efc342c4Marcel Holtmann "\t[-W seconds] enable deferred setup\n" 1082da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann "\t[-B filename] use data packets from file\n" 1083da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann "\t[-N num] send num frames (default = infinite)\n" 1084b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann "\t[-C num] send num frames before delay (default = 1)\n" 1085e6673071212596bc54fb5bffff72b0c3a8275071Marcel Holtmann "\t[-D milliseconds] delay after sending num frames (default = 0)\n" 10868e34afe9cc4dada1c34126a9723f76d4a6705707Marcel Holtmann "\t[-X mode] select retransmission/flow-control mode\n" 108711e2f9bf390d828b45e26a8a1c00f503efc342c4Marcel Holtmann "\t[-F fcs] use CRC16 check (default = 1)\n" 1088449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan "\t[-Q num] Max Transmit value (default = 3)\n" 1089449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan "\t[-Z size] Transmission Window size (default = 63)\n" 1090f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann "\t[-R] reliable mode\n" 10916ba87383b2047862686d04db85a4b7e0d1f243aeMarcel Holtmann "\t[-G] use connectionless channel (datagram)\n" 1092c5c6abdf4c2cedfb8ed7977d34222927076698f4Gustavo F. Padovan "\t[-U] use sock stream\n" 109317990fc4315e60ba6a3ffd59ea8781f2c1647cfcStephen Crane "\t[-A] request authentication\n" 1094aba9dc216df7ddacbaa10d9e25c7aba05ab28afbMax Krasnyansky "\t[-E] request encryption\n" 109552d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann "\t[-S] secure connection\n" 10965b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann "\t[-M] become master\n" 10975b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann "\t[-T] enable timestamps\n"); 1098c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 1099c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1100da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmannint main(int argc, char *argv[]) 1101c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 1102c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct sigaction sa; 1103917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann int opt, sk, mode = RECV, need_addr = 0; 110452d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann 110552d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann bacpy(&bdaddr, BDADDR_ANY); 110652d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann 1107c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan while ((opt=getopt(argc,argv,"rdscuwmntqxyzpb:i:P:I:O:J:B:N:L:W:C:D:X:F:Q:Z:RUGAESMT")) != EOF) { 1108c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky switch(opt) { 1109c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'r': 1110c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky mode = RECV; 1111c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 11123c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 1113c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 's': 1114c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky mode = SEND; 111504c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky need_addr = 1; 111604c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky break; 111704c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky 111804c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky case 'w': 111904c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky mode = LSEND; 112004c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky break; 112104c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky 112204c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky case 'u': 112304c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky mode = CRECV; 112404c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky need_addr = 1; 1125c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1126c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1127c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'd': 1128c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky mode = DUMP; 1129c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1130c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1131c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'c': 1132c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky mode = RECONNECT; 113304c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky need_addr = 1; 1134c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1135c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1136c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'n': 1137c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky mode = CONNECT; 113804c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky need_addr = 1; 1139c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1140c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1141c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'm': 1142c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky mode = MULTY; 114304c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky need_addr = 1; 1144c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1145c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1146a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan case 't': 1147a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan mode = LSENDRECV; 1148a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan break; 1149a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 1150a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan case 'q': 1151a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan mode = CSENDRECV; 1152a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan need_addr = 1; 1153a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan break; 1154a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 11551f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann case 'x': 11561f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann mode = LSENDDUMP; 11571f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann break; 11581f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 11591f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann case 'y': 11601f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann mode = SENDDUMP; 11611f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann break; 11621f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 1163329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann case 'z': 1164329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann mode = INFOREQ; 1165329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann need_addr = 1; 1166329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann break; 1167329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 116822fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann case 'p': 116922fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann mode = PAIRING; 117022fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann need_addr = 1; 117122fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann break; 117222fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 1173329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann case 'b': 1174329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann data_size = atoi(optarg); 1175329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann break; 1176329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 117752d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann case 'i': 117852d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann if (!strncasecmp(optarg, "hci", 3)) 117952d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann hci_devba(atoi(optarg + 3), &bdaddr); 118052d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann else 118152d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann str2ba(optarg, &bdaddr); 1182c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1183c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1184c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'P': 1185c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky psm = atoi(optarg); 1186c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1187c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1188c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'I': 1189c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky imtu = atoi(optarg); 1190c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1191c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1192c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'O': 1193c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky omtu = atoi(optarg); 1194c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1195c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 119679cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky case 'L': 119779cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky linger = atoi(optarg); 119879cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky break; 119979cc4e4e2d74be3f1445203b1fdb844caa1cb009Max Krasnyansky 120011e2f9bf390d828b45e26a8a1c00f503efc342c4Marcel Holtmann case 'W': 12019e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann defer_setup = atoi(optarg); 12029e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann break; 12039e7fdeca25a58d1e778a6b706c937628def76d7aMarcel Holtmann 1204da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann case 'B': 1205da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann filename = strdup(optarg); 1206da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann break; 1207da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann 1208da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann case 'N': 1209da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann num_frames = atoi(optarg); 1210da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann break; 1211da1911d8ae3753dc2bb925c48c8ee07c2ba93903Marcel Holtmann 1212b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann case 'C': 1213b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann count = atoi(optarg); 1214b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann break; 1215b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann 1216b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann case 'D': 1217e6673071212596bc54fb5bffff72b0c3a8275071Marcel Holtmann delay = atoi(optarg) * 1000; 1218b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann break; 1219b357f1d3900bca5575e88fcfc160945c6088608cMarcel Holtmann 12208e34afe9cc4dada1c34126a9723f76d4a6705707Marcel Holtmann case 'X': 1221493b4ab0bfe0aa13fbcd8970b3cc1b1d78782d51Marcel Holtmann if (strcasecmp(optarg, "ertm") == 0) 1222493b4ab0bfe0aa13fbcd8970b3cc1b1d78782d51Marcel Holtmann rfcmode = L2CAP_MODE_ERTM; 1223493b4ab0bfe0aa13fbcd8970b3cc1b1d78782d51Marcel Holtmann else 1224493b4ab0bfe0aa13fbcd8970b3cc1b1d78782d51Marcel Holtmann rfcmode = atoi(optarg); 12258e34afe9cc4dada1c34126a9723f76d4a6705707Marcel Holtmann break; 12268e34afe9cc4dada1c34126a9723f76d4a6705707Marcel Holtmann 122711e2f9bf390d828b45e26a8a1c00f503efc342c4Marcel Holtmann case 'F': 122811e2f9bf390d828b45e26a8a1c00f503efc342c4Marcel Holtmann fcs = atoi(optarg); 122911e2f9bf390d828b45e26a8a1c00f503efc342c4Marcel Holtmann break; 123011e2f9bf390d828b45e26a8a1c00f503efc342c4Marcel Holtmann 1231f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann case 'R': 1232f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann reliable = 1; 1233f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann break; 1234f6557046863c041920180d232c8f0a63bb2faf3cMarcel Holtmann 1235c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'M': 1236c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky master = 1; 1237c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1238c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1239c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'A': 1240c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky auth = 1; 1241c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1242c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1243c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 'E': 1244c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky encrypt = 1; 1245c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1246c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 124752d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann case 'S': 124852d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann secure = 1; 124952d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann break; 125052d36be0bf2610739f04786d18df80db23e9cf6bMarcel Holtmann 12516ba87383b2047862686d04db85a4b7e0d1f243aeMarcel Holtmann case 'G': 125270516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky socktype = SOCK_DGRAM; 125370516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky break; 125470516886fef2e6c208d3e48332cc2c6c4b4d964cMax Krasnyansky 1255c5c6abdf4c2cedfb8ed7977d34222927076698f4Gustavo F. Padovan case 'U': 1256c5c6abdf4c2cedfb8ed7977d34222927076698f4Gustavo F. Padovan socktype = SOCK_STREAM; 1257c5c6abdf4c2cedfb8ed7977d34222927076698f4Gustavo F. Padovan break; 1258c5c6abdf4c2cedfb8ed7977d34222927076698f4Gustavo F. Padovan 12595b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann case 'T': 12605b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann timestamp = 1; 12615b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann break; 12625b675858211437ea5d42ca49bbfbe15aeece65a9Marcel Holtmann 1263449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan case 'Q': 1264449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan max_transmit = atoi(optarg); 1265449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan break; 1266449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan 1267449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan case 'Z': 1268449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan txwin_size = atoi(optarg); 1269449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan break; 1270449367e8dab5fadc49f97c72a6837120e889cdc4Gustavo F. Padovan 1271c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan case 'J': 1272c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan cid = atoi(optarg); 1273c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan break; 1274c5eab04d6572dee0885a512bfd4ad7f7a33b57c0Gustavo F. Padovan 1275c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky default: 1276c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky usage(); 1277c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 1278c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 1279c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 1280c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 128104c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky if (need_addr && !(argc - optind)) { 1282c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky usage(); 1283c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 1284c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 1285c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1286f213783e7d4068268187310251fedc546b9f212fMarcel Holtmann if (data_size < 0) 128741e30382f9a83f41da700465de274266c60248b4Marcel Holtmann buffer_size = (omtu > imtu) ? omtu : imtu; 128841e30382f9a83f41da700465de274266c60248b4Marcel Holtmann else 128941e30382f9a83f41da700465de274266c60248b4Marcel Holtmann buffer_size = data_size; 1290a5fcb1982de75e464c1c41a660975c5d8ab4b47bMarcel Holtmann 129141e30382f9a83f41da700465de274266c60248b4Marcel Holtmann if (!(buf = malloc(buffer_size))) { 1292c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky perror("Can't allocate data buffer"); 1293c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 1294c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 1295c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1296c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky memset(&sa, 0, sizeof(sa)); 1297c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sa.sa_handler = SIG_IGN; 1298c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sa.sa_flags = SA_NOCLDSTOP; 1299c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sigaction(SIGCHLD, &sa, NULL); 1300c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1301c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); 1302c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 13033c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann switch (mode) { 1304c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case RECV: 1305c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky do_listen(recv_mode); 1306c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1307c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 130804c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky case CRECV: 1309917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann sk = do_connect(argv[optind]); 1310917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann if (sk < 0) 131104c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky exit(1); 1312917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann recv_mode(sk); 131304c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky break; 131404c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky 1315c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case DUMP: 1316c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky do_listen(dump_mode); 1317c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1318c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1319c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case SEND: 1320917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann sk = do_connect(argv[optind]); 1321917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann if (sk < 0) 132204c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky exit(1); 1323917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann send_mode(sk); 132404c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky break; 132504c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky 132604c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky case LSEND: 132704c60e71e4b19ca904a5ea158a9e28297855350dMax Krasnyansky do_listen(send_mode); 1328c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1329c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1330c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case RECONNECT: 1331c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky reconnect_mode(argv[optind]); 1332c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1333c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1334c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case MULTY: 13350effff5f4fe0fac9a986bb01dc547a99772d1bfaMarcel Holtmann multi_connect_mode(argc - optind, argv + optind); 1336c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 1337c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1338c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case CONNECT: 1339c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky connect_mode(argv[optind]); 1340c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 13411f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 13421f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann case SENDDUMP: 1343917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann sk = do_connect(argv[optind]); 1344917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann if (sk < 0) 13451f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann exit(1); 1346917543004017da0f09304844c578b59ca4a1802bMarcel Holtmann senddump_mode(sk); 13471f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann break; 13481f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann 13491f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann case LSENDDUMP: 13501f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann do_listen(senddump_mode); 13511f882b1b0f5c381c63c34c8558e13068868198b6Marcel Holtmann break; 1352329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann 1353a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan case LSENDRECV: 1354a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan do_listen(send_and_recv_mode); 1355a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan break; 1356a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 1357a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan case CSENDRECV: 1358a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan sk = do_connect(argv[optind]); 1359a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan if (sk < 0) 1360a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan exit(1); 1361a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 1362a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan send_and_recv_mode(sk); 1363a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan break; 1364a43d90eeb9522da483892d60bfc1054c02756fd4Gustavo F. Padovan 1365329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann case INFOREQ: 1366329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann info_request(argv[optind]); 1367329237dde23a9f692590f0075340ea085f8f3b35Marcel Holtmann exit(0); 136822fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann 136922fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann case PAIRING: 137022fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann do_pairing(argv[optind]); 137122fdd674937bb927a00b35b84cca66dda76c6fd5Marcel Holtmann exit(0); 1372c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 13733c967ce42aee827ff36622c7b70cbd65ef6dd900Marcel Holtmann 1374c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "Exit"); 1375c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1376c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky closelog(); 1377c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 1378c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return 0; 1379c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 1380