From b5edb3c0a92674b27a95f7968e18bb51150c52f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2002 20:46:47 +0000 Subject: Move testing programs from tools directory into the test directory --- test/l2test.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 530 insertions(+) create mode 100644 test/l2test.c (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c new file mode 100644 index 00000000..b08b2d34 --- /dev/null +++ b/test/l2test.c @@ -0,0 +1,530 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP, + CONNECT, + CRECV, + LSEND +}; + +unsigned char *buf; + +/* Default mtu */ +int imtu = 672; +int omtu = 0; + +/* Default data size */ +long data_size = 672; + +/* Default addr and psm */ +bdaddr_t bdaddr; +unsigned short psm = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; +int socktype = SOCK_SEQPACKET; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_l2 rem_addr, loc_addr; + struct l2cap_options opts; + int s, opt; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + /* Set new options */ + opts.omtu = omtu; + opts.imtu = imtu; + if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.l2_family = AF_BLUETOOTH; + baswap(&rem_addr.l2_bdaddr, strtoba(svr)); + rem_addr.l2_psm = htobs(psm); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", + opts.imtu, opts.omtu, opts.flush_to); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_l2 loc_addr, rem_addr; + struct l2cap_options opts; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + loc_addr.l2_psm = htobs(psm); + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Set new options */ + opts.imtu = imtu; + if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + if (socktype == SOCK_DGRAM) { + handler(s); + return; + } + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + opt = sizeof(opts); + if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + baswap(&ba, &rem_addr.l2_bdaddr); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", + batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO, "Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO,"Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + uint32_t sq; + uint16_t l; + int i,r; + + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + + /* Check sequence */ + sq = btohl(*(uint32_t *)buf); + if (seq != sq) { + syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); + seq = sq; + } + seq++; + + /* Check length */ + l = btohs(*(uint16_t *)(buf+4)); + if (r != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + continue; + } + + /* Verify data */ + for (i=6; i < r; i++) { + if (buf[i] != 0x7f) + syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); + } + + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + } +} + +void send_mode(int s) +{ + uint32_t seq; + int i; + + syslog(LOG_INFO,"Sending ..."); + + for(i=6; i < data_size; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *) buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } +} + +void reconnect_mode(char *svr) +{ + while(1) { + int s = do_connect(svr); + close(s); + } +} + +void connect_mode(char *svr) +{ + int s; + if ((s = do_connect(svr)) < 0) + exit(1); + sleep(99999999); +} + +void multi_connect_mode(char *svr) +{ + while (1) { + int i, s; + for (i=0; i<10; i++) { + if (fork()) continue; + + /* Child */ + s = do_connect(svr); + usleep(500); + close(s); + exit(0); + } + sleep(2); + } +} + +void usage(void) +{ + printf("l2test - L2CAP testing\n" + "Usage:\n"); + printf("\tl2test [options] [bdaddr]\n"); + printf("Modes:\n" + "\t-r listen and receive\n" + "\t-w listen and send\n" + "\t-d listen and dump incomming data\n" + "\t-s connect and send\n" + "\t-u connect and receive\n" + "\t-n connect and be silent\n" + "\t-c connect, disconnect, connect, ...\n" + "\t-m multiple connects\n"); + + printf("Options:\n" + "\t[-b bytes] [-S bdaddr] [-P psm]\n" + "\t[-I imtu] [-O omtu]\n" + "\t[-D] use connectionless channel (datagram)\n" + "\t[-E] request encryption\n" + "\t[-E] request encryption\n" + "\t[-M] become master\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + int opt, mode, s, need_addr; + struct sigaction sa; + + mode = RECV; need_addr = 0; + + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + need_addr = 1; + break; + + case 'w': + mode = LSEND; + break; + + case 'u': + mode = CRECV; + need_addr = 1; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + need_addr = 1; + break; + + case 'n': + mode = CONNECT; + need_addr = 1; + break; + + case 'm': + mode = MULTY; + need_addr = 1; + break; + + case 'b': + data_size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + case 'P': + psm = atoi(optarg); + break; + + case 'I': + imtu = atoi(optarg); + break; + + case 'O': + omtu = atoi(optarg); + break; + + case 'M': + master = 1; + break; + + case 'A': + auth = 1; + break; + + case 'E': + encrypt = 1; + break; + + case 'D': + socktype = SOCK_DGRAM; + break; + + default: + usage(); + exit(1); + } + } + + if (need_addr && !(argc - optind)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case CRECV: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + recv_mode(s); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + send_mode(s); + break; + + case LSEND: + do_listen(send_mode); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multi_connect_mode(argv[optind]); + break; + + case CONNECT: + connect_mode(argv[optind]); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} -- cgit From d774efc2f8cc21d599cacc933ea26e0d63e91365 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 15 Oct 2002 17:44:49 +0000 Subject: Use select in dump mode. --- test/l2test.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index b08b2d34..53e9e768 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -236,8 +237,24 @@ void dump_mode(int s) int len; syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) + while (1) { + fd_set rset; + + FD_ZERO(&rset); + FD_SET(s, &rset); + + if (select(s + 1, &rset, NULL, NULL, NULL) < 0) + return; + + if (!FD_ISSET(s, &rset)) + continue; + + len = read(s, buf, data_size); + if (len <= 0) + return; + syslog(LOG_INFO, "Recevied %d bytes\n", len); + } } void recv_mode(int s) -- cgit From 96209b933e9b3b9c93701e15e4a9590f859cc8c6 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 4 Feb 2003 15:32:21 +0000 Subject: fix typo --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 53e9e768..69960c35 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -376,7 +376,7 @@ void usage(void) printf("Modes:\n" "\t-r listen and receive\n" "\t-w listen and send\n" - "\t-d listen and dump incomming data\n" + "\t-d listen and dump incoming data\n" "\t-s connect and send\n" "\t-u connect and receive\n" "\t-n connect and be silent\n" -- cgit From 17990fc4315e60ba6a3ffd59ea8781f2c1647cfc Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 26 Mar 2003 14:39:19 +0000 Subject: typo --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 69960c35..f7d487d7 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -387,7 +387,7 @@ void usage(void) "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" "\t[-D] use connectionless channel (datagram)\n" - "\t[-E] request encryption\n" + "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); } -- cgit From 33a6d8d6bc6bf30a37a92ef40353e6426beeb59b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 May 2003 07:11:27 +0000 Subject: Add support for sending a number of blocks --- test/l2test.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f7d487d7..c345d06a 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -71,6 +71,9 @@ long data_size = 672; bdaddr_t bdaddr; unsigned short psm = 10; +/* Default number of blocks to send */ +int num_blocks = -1; // Infinite + int master = 0; int auth = 0; int encrypt = 0; @@ -324,7 +327,7 @@ void send_mode(int s) buf[i]=0x7f; seq = 0; - while (1) { + while ((num_blocks == -1) || (num_blocks-- > 0)) { *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); @@ -386,6 +389,7 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" + "\t[-N num] send num blocks (default = infinite)\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" @@ -402,7 +406,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAED")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -477,6 +481,10 @@ int main(int argc ,char *argv[]) socktype = SOCK_DGRAM; break; + case 'N': + num_blocks = atoi(optarg); + break; + default: usage(); exit(1); -- cgit From 79cc4e4e2d74be3f1445203b1fdb844caa1cb009 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 17 May 2003 00:45:58 +0000 Subject: Add SO_LINGER support. --- test/l2test.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index c345d06a..fa8cdf5e 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -78,6 +78,7 @@ int master = 0; int auth = 0; int encrypt = 0; int socktype = SOCK_SEQPACKET; +int linger = 0; float tv2fl(struct timeval tv) { @@ -118,6 +119,16 @@ int do_connect(char *svr) return -1; } + /* Enable SO_LINGER */ + if (linger) { + struct linger l = { .l_onoff = 1, .l_linger = linger }; + if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + strerror(errno), errno); + return -1; + } + } + memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.l2_family = AF_BLUETOOTH; baswap(&rem_addr.l2_bdaddr, strtoba(svr)); @@ -228,6 +239,16 @@ void do_listen( void (*handler)(int sk) ) syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + /* Enable SO_LINGER */ + if (linger) { + struct linger l = { .l_onoff = 1, .l_linger = linger }; + if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + strerror(errno), errno); + exit(1); + } + } + handler(s1); syslog(LOG_INFO, "Disconnect\n"); @@ -390,6 +411,7 @@ void usage(void) "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num blocks (default = infinite)\n" + "\t[-L seconds] enable SO_LINGER\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" @@ -406,7 +428,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAED")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAEDL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -465,6 +487,10 @@ int main(int argc ,char *argv[]) omtu = atoi(optarg); break; + case 'L': + linger = atoi(optarg); + break; + case 'M': master = 1; break; -- cgit From 893ddcab14bb2b5309ba0f181a5a9941a2d28661 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 19 May 2003 21:04:25 +0000 Subject: Call shutdown() before closing the socket and check return value. This is used along with SO_LINGER option to check for errors during cahnel close. Minor cleanups. --- test/l2test.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index fa8cdf5e..a502d7dc 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -71,8 +71,8 @@ long data_size = 672; bdaddr_t bdaddr; unsigned short psm = 10; -/* Default number of blocks to send */ -int num_blocks = -1; // Infinite +/* Default number of frames to send */ +int num_frames = -1; // Infinite int master = 0; int auth = 0; @@ -251,7 +251,7 @@ void do_listen( void (*handler)(int sk) ) handler(s1); - syslog(LOG_INFO, "Disconnect\n"); + syslog(LOG_INFO, "Disconnect. %m\n"); exit(0); } } @@ -342,13 +342,13 @@ void send_mode(int s) uint32_t seq; int i; - syslog(LOG_INFO,"Sending ..."); + syslog(LOG_INFO, "Sending ..."); for(i=6; i < data_size; i++) buf[i]=0x7f; seq = 0; - while ((num_blocks == -1) || (num_blocks-- > 0)) { + while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); @@ -357,6 +357,12 @@ void send_mode(int s) exit(1); } } + + syslog(LOG_INFO, "Closing channel ..."); + if (shutdown(s, SHUT_RDWR) < 0) + syslog(LOG_INFO, "Close failed. %m."); + else + syslog(LOG_INFO, "Done"); } void reconnect_mode(char *svr) @@ -410,7 +416,7 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" - "\t[-N num] send num blocks (default = infinite)\n" + "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" @@ -508,7 +514,7 @@ int main(int argc ,char *argv[]) break; case 'N': - num_blocks = atoi(optarg); + num_frames = atoi(optarg); break; default: -- cgit From f6557046863c041920180d232c8f0a63bb2faf3c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2003 12:05:10 +0000 Subject: Add LM_RELIABLE option --- test/l2test.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 18 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index a502d7dc..608c84ff 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -79,6 +79,7 @@ int auth = 0; int encrypt = 0; int socktype = SOCK_SEQPACKET; int linger = 0; +int reliable = 0; float tv2fl(struct timeval tv) { @@ -91,7 +92,7 @@ int do_connect(char *svr) struct l2cap_options opts; int s, opt; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); return -1; } @@ -99,14 +100,14 @@ int do_connect(char *svr) memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.l2_family = AF_BLUETOOTH; loc_addr.l2_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); } /* Get default options */ opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); return -1; } @@ -114,7 +115,7 @@ int do_connect(char *svr) /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; - if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { + if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); return -1; } @@ -129,18 +130,28 @@ int do_connect(char *svr) } } + /* Set link mode */ + opt = 0; + if (reliable) + opt |= L2CAP_LM_RELIABLE; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } + memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.l2_family = AF_BLUETOOTH; baswap(&rem_addr.l2_bdaddr, strtoba(svr)); rem_addr.l2_psm = htobs(psm); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + if (connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ) { syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); return -1; } opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); close(s); return -1; @@ -159,7 +170,7 @@ void do_listen( void (*handler)(int sk) ) int s, s1, opt; bdaddr_t ba; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -167,13 +178,16 @@ void do_listen( void (*handler)(int sk) ) loc_addr.l2_family = AF_BLUETOOTH; loc_addr.l2_bdaddr = bdaddr; loc_addr.l2_psm = htobs(psm); - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); } /* Set link mode */ opt = 0; + if (reliable) + opt |= L2CAP_LM_RELIABLE; + if (master) opt |= L2CAP_LM_MASTER; @@ -207,7 +221,7 @@ void do_listen( void (*handler)(int sk) ) return; } - if( listen(s, 10) ) { + if (listen(s, 10)) { syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -216,7 +230,7 @@ void do_listen( void (*handler)(int sk) ) while(1) { opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + if ((s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0) { syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); exit(1); } @@ -230,7 +244,7 @@ void do_listen( void (*handler)(int sk) ) close(s); opt = sizeof(opts); - if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); exit(1); } @@ -259,6 +273,7 @@ void do_listen( void (*handler)(int sk) ) void dump_mode(int s) { int len; + int opt, optl; syslog(LOG_INFO, "Receiving ..."); while (1) { @@ -274,8 +289,23 @@ void dump_mode(int s) continue; len = read(s, buf, data_size); - if (len <= 0) + if (len <= 0) { + if (len < 0) { + if (reliable && (errno == ECOMM)) { + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); + optl = sizeof(opt); + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", + strerror(errno), errno); + return; + } + continue; + } else { + syslog(LOG_ERR, "Read error: %s(%d)\n", strerror(errno), errno); + } + } return; + } syslog(LOG_INFO, "Recevied %d bytes\n", len); } @@ -286,6 +316,7 @@ void recv_mode(int s) struct timeval tv_beg,tv_end,tv_diff; long total; uint32_t seq; + int opt, optl; syslog(LOG_INFO,"Receiving ..."); @@ -299,10 +330,22 @@ void recv_mode(int s) int i,r; if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; + if (r < 0) { + if (reliable && (errno == ECOMM)) { + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); + optl = sizeof(opt); + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", + strerror(errno), errno); + return; + } + continue; + } else { + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + } + } + return; } /* Check sequence */ @@ -385,7 +428,7 @@ void multi_connect_mode(char *svr) { while (1) { int i, s; - for (i=0; i<10; i++) { + for (i = 0; i < 10; i++) { if (fork()) continue; /* Child */ @@ -418,6 +461,7 @@ void usage(void) "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" + "\t[-R] reliable mode\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" @@ -434,7 +478,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAEDL:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:RMAEDL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -497,6 +541,10 @@ int main(int argc ,char *argv[]) linger = atoi(optarg); break; + case 'R': + reliable = 1; + break; + case 'M': master = 1; break; -- cgit From 1f882b1b0f5c381c63c34c8558e13068868198b6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2003 21:27:00 +0000 Subject: Add new modes that can dump the incoming data --- test/l2test.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 7 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 608c84ff..d02eb3c0 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -29,12 +29,12 @@ #include #include #include -#include -#include #include #include #include +#include #include +#include #include #include @@ -46,6 +46,8 @@ #include #include +#define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) + /* Test modes */ enum { SEND, @@ -55,7 +57,9 @@ enum { DUMP, CONNECT, CRECV, - LSEND + LSEND, + SENDDUMP, + LSENDDUMP }; unsigned char *buf; @@ -86,6 +90,78 @@ float tv2fl(struct timeval tv) return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } +char *ltoh(unsigned long c, char* s) +{ + int c1; + + c1 = (c >> 28) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 24) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 20) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 16) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 12) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 8) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 4) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = c & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + *s = 0; + return (s); +} + +char *ctoh(char c, char* s) +{ + char c1; + + c1 = (c >> 4) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = c & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + *s = 0; + return (s); +} + +void hexdump(char *s, unsigned long l) +{ + char bfr[80]; + char *pb; + unsigned long i, n = 0; + + if (l == 0) + return; + + while (n < l) { + pb = bfr; + pb = ltoh (n, pb); + *(pb++) = ':'; + *(pb++) = ' '; + for (i = 0; i < 16; i++) { + if (n + i >= l) { + *(pb++) = ' '; + *(pb++) = ' '; + } else + pb = ctoh (*(s + i), pb); + *(pb++) = ' '; + } + *(pb++) = ' '; + for (i = 0; i < 16; i++) { + if (n + i >= l) + break; + else + *(pb++) = (isprint (*(s + i)) ? *(s + i) : '.'); + } + *pb = 0; + n += 16; + s += 16; + puts(bfr); + } +} + int do_connect(char *svr) { struct sockaddr_l2 rem_addr, loc_addr; @@ -163,7 +239,7 @@ int do_connect(char *svr) return s; } -void do_listen( void (*handler)(int sk) ) +void do_listen(void (*handler)(int sk)) { struct sockaddr_l2 loc_addr, rem_addr; struct l2cap_options opts; @@ -308,6 +384,7 @@ void dump_mode(int s) } syslog(LOG_INFO, "Recevied %d bytes\n", len); + hexdump(buf,len); } } @@ -387,8 +464,8 @@ void send_mode(int s) syslog(LOG_INFO, "Sending ..."); - for(i=6; i < data_size; i++) - buf[i]=0x7f; + for(i = 6; i < data_size; i++) + buf[i] = 0x7f; seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { @@ -408,6 +485,31 @@ void send_mode(int s) syslog(LOG_INFO, "Done"); } +void senddump_mode(int s) +{ + uint32_t seq; + int i; + + syslog(LOG_INFO, "Sending ..."); + + for(i = 6; i < data_size; i++) + buf[i] = 0x7f; + + seq = 0; + while ((num_frames == -1) || (num_frames-- > 0)) { + *(uint32_t *) buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } + + dump_mode(s); + +} + void reconnect_mode(char *svr) { while(1) { @@ -450,9 +552,11 @@ void usage(void) "\t-r listen and receive\n" "\t-w listen and send\n" "\t-d listen and dump incoming data\n" + "\t-x listen, then send, then dump incoming data\n" "\t-s connect and send\n" "\t-u connect and receive\n" "\t-n connect and be silent\n" + "\t-y connect, then send, then dump incoming data\n" "\t-c connect, disconnect, connect, ...\n" "\t-m multiple connects\n"); @@ -478,7 +582,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:RMAEDL:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyb:P:I:O:S:N:RMAEDL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -521,6 +625,14 @@ int main(int argc ,char *argv[]) data_size = atoi(optarg); break; + case 'x': + mode = LSENDDUMP; + break; + + case 'y': + mode = SENDDUMP; + break; + case 'S': baswap(&bdaddr, strtoba(optarg)); break; @@ -626,6 +738,18 @@ int main(int argc ,char *argv[]) case CONNECT: connect_mode(argv[optind]); break; + + case SENDDUMP: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + senddump_mode(s); + break; + + case LSENDDUMP: + do_listen(senddump_mode); + break; + } syslog(LOG_INFO, "Exit"); -- cgit From b2d7fd8c8e1c7948169726639675d462bd83e50e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Feb 2004 18:29:02 +0000 Subject: Fix sequence increment --- test/l2test.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index d02eb3c0..4d782532 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -469,8 +469,9 @@ void send_mode(int s) seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { - *(uint32_t *) buf = htobl(seq++); + *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); + seq++; if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); @@ -497,8 +498,9 @@ void senddump_mode(int s) seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { - *(uint32_t *) buf = htobl(seq++); + *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); + seq++; if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); -- cgit From b8707600fd45e0cda31654fc7b2932f29b28d1a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 12:44:32 +0000 Subject: Unify copyright and license information --- test/l2test.c | 55 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 24 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 4d782532..f98e5109 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -1,30 +1,37 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include -- cgit From 52d36be0bf2610739f04786d18df80db23e9cf6b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 17 Nov 2004 08:28:52 +0000 Subject: Add parameter for activating secure mode --- test/l2test.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f98e5109..eedf4b70 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -51,6 +51,8 @@ #include #include +#include +#include #include #define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) @@ -88,6 +90,7 @@ int num_frames = -1; // Infinite int master = 0; int auth = 0; int encrypt = 0; +int secure = 0; int socktype = SOCK_SEQPACKET; int linger = 0; int reliable = 0; @@ -270,15 +273,14 @@ void do_listen(void (*handler)(int sk)) opt = 0; if (reliable) opt |= L2CAP_LM_RELIABLE; - if (master) - opt |= L2CAP_LM_MASTER; - + opt |= L2CAP_LM_MASTER; if (auth) - opt |= L2CAP_LM_AUTH; - + opt |= L2CAP_LM_AUTH; if (encrypt) - opt |= L2CAP_LM_ENCRYPT; + opt |= L2CAP_LM_ENCRYPT; + if (secure) + opt |= L2CAP_LM_SECURE; if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); @@ -570,7 +572,7 @@ void usage(void) "\t-m multiple connects\n"); printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P psm]\n" + "\t[-b bytes] [-i device] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" @@ -578,6 +580,7 @@ void usage(void) "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" + "\t[-S] secure connection\n" "\t[-M] become master\n"); } @@ -590,8 +593,10 @@ int main(int argc ,char *argv[]) struct sigaction sa; mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnxyb:P:I:O:S:N:RMAEDL:")) != EOF) { + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:RMAESL:D")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -642,8 +647,11 @@ int main(int argc ,char *argv[]) mode = SENDDUMP; break; - case 'S': - baswap(&bdaddr, strtoba(optarg)); + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); break; case 'P': @@ -678,6 +686,10 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'S': + secure = 1; + break; + case 'D': socktype = SOCK_DGRAM; break; -- cgit From bbda499067067aefc8e642a2784d247ac0331eae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 25 Dec 2004 17:43:16 +0000 Subject: Add memset() to different places to initialize the structures --- test/l2test.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index eedf4b70..627d37f1 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -192,6 +192,7 @@ int do_connect(char *svr) } /* Get default options */ + memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); @@ -236,6 +237,7 @@ int do_connect(char *svr) return -1; } + memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); -- cgit From 9e6e37723b8d8798ed9ba58734fd3022fdf49dc2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 26 Dec 2004 14:10:24 +0000 Subject: Update for connection information --- test/l2test.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 627d37f1..c36cc3b7 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -176,6 +176,7 @@ int do_connect(char *svr) { struct sockaddr_l2 rem_addr, loc_addr; struct l2cap_options opts; + struct l2cap_conninfo conn; int s, opt; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { @@ -245,8 +246,17 @@ int do_connect(char *svr) return -1; } - syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", - opts.imtu, opts.omtu, opts.flush_to); + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]", + opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); return s; } -- cgit From 3c967ce42aee827ff36622c7b70cbd65ef6dd900 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 10:10:34 +0000 Subject: Fix memory leaks and make more functions static --- test/l2test.c | 112 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 54 insertions(+), 58 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index c36cc3b7..fccea39b 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -71,36 +71,36 @@ enum { LSENDDUMP }; -unsigned char *buf; +static unsigned char *buf; /* Default mtu */ -int imtu = 672; -int omtu = 0; +static int imtu = 672; +static int omtu = 0; /* Default data size */ -long data_size = 672; +static long data_size = 672; /* Default addr and psm */ -bdaddr_t bdaddr; -unsigned short psm = 10; +static bdaddr_t bdaddr; +static unsigned short psm = 10; /* Default number of frames to send */ -int num_frames = -1; // Infinite +static int num_frames = -1; // Infinite -int master = 0; -int auth = 0; -int encrypt = 0; -int secure = 0; -int socktype = SOCK_SEQPACKET; -int linger = 0; -int reliable = 0; +static int master = 0; +static int auth = 0; +static int encrypt = 0; +static int secure = 0; +static int socktype = SOCK_SEQPACKET; +static int linger = 0; +static int reliable = 0; -float tv2fl(struct timeval tv) +static float tv2fl(struct timeval tv) { return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } -char *ltoh(unsigned long c, char* s) +static char *ltoh(unsigned long c, char* s) { int c1; @@ -124,7 +124,7 @@ char *ltoh(unsigned long c, char* s) return (s); } -char *ctoh(char c, char* s) +static char *ctoh(char c, char* s) { char c1; @@ -136,15 +136,15 @@ char *ctoh(char c, char* s) return (s); } -void hexdump(char *s, unsigned long l) +static void hexdump(char *s, unsigned long l) { char bfr[80]; char *pb; unsigned long i, n = 0; - + if (l == 0) return; - + while (n < l) { pb = bfr; pb = ltoh (n, pb); @@ -165,14 +165,14 @@ void hexdump(char *s, unsigned long l) else *(pb++) = (isprint (*(s + i)) ? *(s + i) : '.'); } - *pb = 0; + *pb = 0; n += 16; s += 16; puts(bfr); } } -int do_connect(char *svr) +static int do_connect(char *svr) { struct sockaddr_l2 rem_addr, loc_addr; struct l2cap_options opts; @@ -186,7 +186,7 @@ int do_connect(char *svr) memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; + bacpy(&loc_addr.l2_bdaddr, &bdaddr); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); @@ -232,7 +232,7 @@ int do_connect(char *svr) rem_addr.l2_family = AF_BLUETOOTH; baswap(&rem_addr.l2_bdaddr, strtoba(svr)); rem_addr.l2_psm = htobs(psm); - if (connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ) { + if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0 ) { syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); return -1; @@ -261,12 +261,12 @@ int do_connect(char *svr) return s; } -void do_listen(void (*handler)(int sk)) +static void do_listen(void (*handler)(int sk)) { struct sockaddr_l2 loc_addr, rem_addr; struct l2cap_options opts; - int s, s1, opt; - bdaddr_t ba; + int s, s1, opt; + char ba[18]; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); @@ -274,7 +274,7 @@ void do_listen(void (*handler)(int sk)) } loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; + bacpy(&loc_addr.l2_bdaddr, &bdaddr); loc_addr.l2_psm = htobs(psm); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); @@ -327,7 +327,7 @@ void do_listen(void (*handler)(int sk)) while(1) { opt = sizeof(rem_addr); - if ((s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0) { + if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); exit(1); } @@ -346,9 +346,9 @@ void do_listen(void (*handler)(int sk)) exit(1); } - baswap(&ba, &rem_addr.l2_bdaddr); + ba2str(&rem_addr.l2_bdaddr, ba); syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", - batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + ba, opts.imtu, opts.omtu, opts.flush_to); /* Enable SO_LINGER */ if (linger) { @@ -362,12 +362,12 @@ void do_listen(void (*handler)(int sk)) handler(s1); - syslog(LOG_INFO, "Disconnect. %m\n"); + syslog(LOG_INFO, "Disconnect. %m"); exit(0); } } -void dump_mode(int s) +static void dump_mode(int s) { int len; int opt, optl; @@ -375,7 +375,7 @@ void dump_mode(int s) syslog(LOG_INFO, "Receiving ..."); while (1) { fd_set rset; - + FD_ZERO(&rset); FD_SET(s, &rset); @@ -393,7 +393,7 @@ void dump_mode(int s) optl = sizeof(opt); if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", - strerror(errno), errno); + strerror(errno), errno); return; } continue; @@ -409,7 +409,7 @@ void dump_mode(int s) } } -void recv_mode(int s) +static void recv_mode(int s) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -440,7 +440,7 @@ void recv_mode(int s) continue; } else { syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); } } return; @@ -453,15 +453,15 @@ void recv_mode(int s) seq = sq; } seq++; - + /* Check length */ l = btohs(*(uint16_t *)(buf+4)); if (r != l) { syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); continue; } - - /* Verify data */ + + /* Verify data */ for (i=6; i < r; i++) { if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); @@ -474,11 +474,11 @@ void recv_mode(int s) timersub(&tv_end,&tv_beg,&tv_diff); syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, - tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); } } -void send_mode(int s) +static void send_mode(int s) { uint32_t seq; int i; @@ -493,7 +493,7 @@ void send_mode(int s) *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); seq++; - + if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); exit(1); @@ -507,7 +507,7 @@ void send_mode(int s) syslog(LOG_INFO, "Done"); } -void senddump_mode(int s) +static void senddump_mode(int s) { uint32_t seq; int i; @@ -522,7 +522,7 @@ void senddump_mode(int s) *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); seq++; - + if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); exit(1); @@ -530,10 +530,9 @@ void senddump_mode(int s) } dump_mode(s); - } -void reconnect_mode(char *svr) +static void reconnect_mode(char *svr) { while(1) { int s = do_connect(svr); @@ -541,7 +540,7 @@ void reconnect_mode(char *svr) } } -void connect_mode(char *svr) +static void connect_mode(char *svr) { int s; if ((s = do_connect(svr)) < 0) @@ -549,7 +548,7 @@ void connect_mode(char *svr) sleep(99999999); } -void multi_connect_mode(char *svr) +static void multi_connect_mode(char *svr) { while (1) { int i, s; @@ -566,7 +565,7 @@ void multi_connect_mode(char *svr) } } -void usage(void) +static void usage(void) { printf("l2test - L2CAP testing\n" "Usage:\n"); @@ -585,7 +584,7 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-i device] [-P psm]\n" - "\t[-I imtu] [-O omtu]\n" + "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" "\t[-R] reliable mode\n" @@ -593,12 +592,9 @@ void usage(void) "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" - "\t[-M] become master\n"); + "\t[-M] become master\n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc ,char *argv[]) { int opt, mode, s, need_addr; @@ -613,7 +609,7 @@ int main(int argc ,char *argv[]) case 'r': mode = RECV; break; - + case 's': mode = SEND; need_addr = 1; @@ -733,7 +729,7 @@ int main(int argc ,char *argv[]) openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); - switch( mode ){ + switch (mode) { case RECV: do_listen(recv_mode); break; @@ -782,8 +778,8 @@ int main(int argc ,char *argv[]) case LSENDDUMP: do_listen(senddump_mode); break; - } + syslog(LOG_INFO, "Exit"); closelog(); -- cgit From 14be8b04824df3f5a9bd7b713646a9120e2b2454 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 21:42:38 +0000 Subject: More cleanups --- test/l2test.c | 106 +++++++++++++++++++++++++++------------------------------- 1 file changed, 49 insertions(+), 57 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index fccea39b..e9a7d50d 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,21 +33,13 @@ #endif #include -#include -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include - -#include -#include -#include -#include #include #include @@ -55,7 +47,7 @@ #include #include -#define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) +#define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) /* Test modes */ enum { @@ -121,7 +113,7 @@ static char *ltoh(unsigned long c, char* s) c1 = c & 0x0f; *(s++) = NIBBLE_TO_ASCII (c1); *s = 0; - return (s); + return s; } static char *ctoh(char c, char* s) @@ -133,7 +125,7 @@ static char *ctoh(char c, char* s) c1 = c & 0x0f; *(s++) = NIBBLE_TO_ASCII (c1); *s = 0; - return (s); + return s; } static void hexdump(char *s, unsigned long l) @@ -180,7 +172,7 @@ static int do_connect(char *svr) int s, opt; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); return -1; } @@ -188,7 +180,7 @@ static int do_connect(char *svr) loc_addr.l2_family = AF_BLUETOOTH; bacpy(&loc_addr.l2_bdaddr, &bdaddr); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -196,7 +188,7 @@ static int do_connect(char *svr) memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); return -1; } @@ -204,7 +196,7 @@ static int do_connect(char *svr) opts.omtu = omtu; opts.imtu = imtu; if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); return -1; } @@ -212,7 +204,7 @@ static int do_connect(char *svr) if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { - syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", strerror(errno), errno); return -1; } @@ -221,19 +213,19 @@ static int do_connect(char *svr) /* Set link mode */ opt = 0; if (reliable) - opt |= L2CAP_LM_RELIABLE; + opt |= L2CAP_LM_RELIABLE; if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); exit(1); } memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.l2_family = AF_BLUETOOTH; - baswap(&rem_addr.l2_bdaddr, strtoba(svr)); + str2ba(svr, &rem_addr.l2_bdaddr); rem_addr.l2_psm = htobs(psm); if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0 ) { - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -241,7 +233,7 @@ static int do_connect(char *svr) memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -249,7 +241,7 @@ static int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); if (getsockopt(s, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP connection information. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -269,15 +261,15 @@ static void do_listen(void (*handler)(int sk)) char ba[18]; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); exit(1); } loc_addr.l2_family = AF_BLUETOOTH; bacpy(&loc_addr.l2_bdaddr, &bdaddr); - loc_addr.l2_psm = htobs(psm); + loc_addr.l2_psm = htobs(psm); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -295,21 +287,21 @@ static void do_listen(void (*handler)(int sk)) opt |= L2CAP_LM_SECURE; if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); exit(1); } /* Get default options */ opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); exit(1); } /* Set new options */ opts.imtu = imtu; if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); exit(1); } @@ -319,7 +311,7 @@ static void do_listen(void (*handler)(int sk)) } if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -328,10 +320,10 @@ static void do_listen(void (*handler)(int sk)) while(1) { opt = sizeof(rem_addr); if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); exit(1); } - if( fork() ) { + if (fork()) { /* Parent */ close(s1); continue; @@ -342,7 +334,7 @@ static void do_listen(void (*handler)(int sk)) opt = sizeof(opts); if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); exit(1); } @@ -354,7 +346,7 @@ static void do_listen(void (*handler)(int sk)) if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { - syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", strerror(errno), errno); exit(1); } @@ -362,7 +354,7 @@ static void do_listen(void (*handler)(int sk)) handler(s1); - syslog(LOG_INFO, "Disconnect. %m"); + syslog(LOG_INFO, "Disconnect: %m"); exit(0); } } @@ -378,7 +370,7 @@ static void dump_mode(int s) FD_ZERO(&rset); FD_SET(s, &rset); - + if (select(s + 1, &rset, NULL, NULL, NULL) < 0) return; @@ -392,7 +384,7 @@ static void dump_mode(int s) syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); optl = sizeof(opt); if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", strerror(errno), errno); return; } @@ -420,12 +412,12 @@ static void recv_mode(int s) seq = 0; while (1) { - gettimeofday(&tv_beg,NULL); + gettimeofday(&tv_beg, NULL); total = 0; while (total < data_size) { uint32_t sq; uint16_t l; - int i,r; + int i, r; if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) { @@ -433,8 +425,8 @@ static void recv_mode(int s) syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); optl = sizeof(opt); if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", - strerror(errno), errno); + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", + strerror(errno), errno); return; } continue; @@ -447,7 +439,7 @@ static void recv_mode(int s) } /* Check sequence */ - sq = btohl(*(uint32_t *)buf); + sq = btohl(*(uint32_t *) buf); if (seq != sq) { syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); seq = sq; @@ -455,25 +447,25 @@ static void recv_mode(int s) seq++; /* Check length */ - l = btohs(*(uint16_t *)(buf+4)); + l = btohs(*(uint16_t *) (buf + 4)); if (r != l) { syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); continue; } /* Verify data */ - for (i=6; i < r; i++) { + for (i = 6; i < r; i++) { if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); } total += r; } - gettimeofday(&tv_end,NULL); + gettimeofday(&tv_end, NULL); - timersub(&tv_end,&tv_beg,&tv_diff); + timersub(&tv_end, &tv_beg, &tv_diff); - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s", total, tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); } } @@ -485,24 +477,24 @@ static void send_mode(int s) syslog(LOG_INFO, "Sending ..."); - for(i = 6; i < data_size; i++) + for (i = 6; i < data_size; i++) buf[i] = 0x7f; seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq); - *(uint16_t *)(buf+4) = htobs(data_size); + *(uint16_t *) (buf + 4) = htobs(data_size); seq++; if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } syslog(LOG_INFO, "Closing channel ..."); if (shutdown(s, SHUT_RDWR) < 0) - syslog(LOG_INFO, "Close failed. %m."); + syslog(LOG_INFO, "Close failed: %m"); else syslog(LOG_INFO, "Done"); } @@ -514,17 +506,17 @@ static void senddump_mode(int s) syslog(LOG_INFO, "Sending ..."); - for(i = 6; i < data_size; i++) + for (i = 6; i < data_size; i++) buf[i] = 0x7f; seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq); - *(uint16_t *)(buf+4) = htobs(data_size); + *(uint16_t *) (buf + 4) = htobs(data_size); seq++; if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } -- cgit From 3524d98e35685875e95daee7fa86a9c2178264a4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Jan 2005 19:46:10 +0000 Subject: Only set link mode when needed --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index e9a7d50d..06233d3f 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -286,7 +286,7 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= L2CAP_LM_SECURE; - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + if (opt && setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); exit(1); } -- cgit From a5fcb1982de75e464c1c41a660975c5d8ab4b47b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Jan 2005 18:26:54 +0000 Subject: Adopt data size from the MTU --- test/l2test.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 06233d3f..859ce079 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -70,7 +70,7 @@ static int imtu = 672; static int omtu = 0; /* Default data size */ -static long data_size = 672; +static long data_size = 0; /* Default addr and psm */ static bdaddr_t bdaddr; @@ -709,6 +709,13 @@ int main(int argc ,char *argv[]) exit(1); } + if (!data_size) { + if (imtu > data_size) + data_size = imtu; + if (omtu > data_size) + data_size = omtu; + } + if (!(buf = malloc(data_size))) { perror("Can't allocate data buffer"); exit(1); -- cgit From d198227a6d76b6fb6bff050e6fda9f2e4ffc4544 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Jan 2005 18:33:49 +0000 Subject: Show connection information --- test/l2test.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 859ce079..272f40f6 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -257,6 +257,7 @@ static void do_listen(void (*handler)(int sk)) { struct sockaddr_l2 loc_addr, rem_addr; struct l2cap_options opts; + struct l2cap_conninfo conn; int s, s1, opt; char ba[18]; @@ -332,15 +333,26 @@ static void do_listen(void (*handler)(int sk)) close(s); + memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); + close(s1); + exit(1); + } + + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s1, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); + close(s1); exit(1); } ba2str(&rem_addr.l2_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", - ba, opts.imtu, opts.omtu, opts.flush_to); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]\n", + ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); /* Enable SO_LINGER */ if (linger) { -- cgit From 7715ad4f56e82c9eb4cf75020b1f3039d06ce115 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 18:16:11 +0000 Subject: Cleanup the socket handling --- test/l2test.c | 295 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 177 insertions(+), 118 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 272f40f6..ac831d97 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -76,8 +76,8 @@ static long data_size = 0; static bdaddr_t bdaddr; static unsigned short psm = 10; -/* Default number of frames to send */ -static int num_frames = -1; // Infinite +/* Default number of frames to send (-1 = infinite) */ +static int num_frames = -1; static int master = 0; static int auth = 0; @@ -166,46 +166,58 @@ static void hexdump(char *s, unsigned long l) static int do_connect(char *svr) { - struct sockaddr_l2 rem_addr, loc_addr; + struct sockaddr_l2 addr; struct l2cap_options opts; struct l2cap_conninfo conn; - int s, opt; + socklen_t optlen; + int sk, opt; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); return -1; } - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.l2_family = AF_BLUETOOTH; - bacpy(&loc_addr.l2_bdaddr, &bdaddr); - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } /* Get default options */ memset(&opts, 0, sizeof(opts)); - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); - return -1; + optlen = sizeof(opts); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; - if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); - return -1; + + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + + if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); return -1; } } @@ -215,63 +227,82 @@ static int do_connect(char *svr) if (reliable) opt |= L2CAP_LM_RELIABLE; - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); - exit(1); + if (setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", + strerror(errno), errno); + goto error; } - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.l2_family = AF_BLUETOOTH; - str2ba(svr, &rem_addr.l2_bdaddr); - rem_addr.l2_psm = htobs(psm); - if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0 ) { - syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); - close(s); - return -1; + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + str2ba(svr, &addr.l2_bdaddr); + addr.l2_psm = htobs(psm); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get current options */ memset(&opts, 0, sizeof(opts)); - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); - close(s); - return -1; + optlen = sizeof(opts); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); - close(s); - return -1; + optlen = sizeof(conn); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", + strerror(errno), errno); + goto error; } - syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]", + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d, " + "mode %d, handle %d, class 0x%02x%02x%02x]", opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); - return s; + return sk; + +error: + close(sk); + return -1; } static void do_listen(void (*handler)(int sk)) { - struct sockaddr_l2 loc_addr, rem_addr; + struct sockaddr_l2 addr; struct l2cap_options opts; struct l2cap_conninfo conn; - int s, s1, opt; + socklen_t optlen; + int sk, nsk, opt; char ba[18]; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); exit(1); } - loc_addr.l2_family = AF_BLUETOOTH; - bacpy(&loc_addr.l2_bdaddr, &bdaddr); - loc_addr.l2_psm = htobs(psm); - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, &bdaddr); + addr.l2_psm = htobs(psm); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } /* Set link mode */ @@ -287,138 +318,166 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= L2CAP_LM_SECURE; - if (opt && setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); - exit(1); + if (opt && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", + strerror(errno), errno); + goto error; } /* Get default options */ - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); - exit(1); + memset(&opts, 0, sizeof(opts)); + optlen = sizeof(opts); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } /* Set new options */ opts.imtu = imtu; - if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); - exit(1); + + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } if (socktype == SOCK_DGRAM) { - handler(s); + handler(sk); return; } - if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Listen for connections */ + if (listen(sk, 10)) { + syslog(LOG_ERR, "Can not listen on the socket: %s (%d)", + strerror(errno), errno); + goto error; } - syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); + syslog(LOG_INFO, "Waiting for connection on psm %d ...", psm); while(1) { - opt = sizeof(rem_addr); - if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); - exit(1); + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + nsk = accept(sk, (struct sockaddr *) &addr, &optlen); + if (nsk < 0) { + syslog(LOG_ERR, "Accept failed: %s (%d)", + strerror(errno), errno); + goto error; } if (fork()) { /* Parent */ - close(s1); + close(nsk); continue; } /* Child */ + close(sk); - close(s); - + /* Get current options */ memset(&opts, 0, sizeof(opts)); - opt = sizeof(opts); - if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); - close(s1); - exit(1); + optlen = sizeof(opts); + + if (getsockopt(nsk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", + strerror(errno), errno); + close(nsk); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s1, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); - close(s1); - exit(1); + optlen = sizeof(conn); + + if (getsockopt(nsk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", + strerror(errno), errno); + close(nsk); + goto error; } - ba2str(&rem_addr.l2_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]\n", + ba2str(&addr.l2_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, " + " mode %d, handle %d, class 0x%02x%02x%02x]", ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + + if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", - strerror(errno), errno); - exit(1); + strerror(errno), errno); + close(nsk); + goto error; } } - handler(s1); + handler(nsk); syslog(LOG_INFO, "Disconnect: %m"); exit(0); } + + return; + +error: + close(sk); + exit(1); } -static void dump_mode(int s) +static void dump_mode(int sk) { - int len; - int opt, optl; + socklen_t optlen; + int opt, len; syslog(LOG_INFO, "Receiving ..."); while (1) { fd_set rset; FD_ZERO(&rset); - FD_SET(s, &rset); + FD_SET(sk, &rset); - if (select(s + 1, &rset, NULL, NULL, NULL) < 0) + if (select(sk + 1, &rset, NULL, NULL, NULL) < 0) return; - if (!FD_ISSET(s, &rset)) + if (!FD_ISSET(sk, &rset)) continue; - len = read(s, buf, data_size); + len = read(sk, buf, data_size); if (len <= 0) { if (len < 0) { if (reliable && (errno == ECOMM)) { - syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); - optl = sizeof(opt); - if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing."); + optlen = sizeof(opt); + if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); return; } continue; } else { - syslog(LOG_ERR, "Read error: %s(%d)\n", strerror(errno), errno); + syslog(LOG_ERR, "Read error: %s(%d)", + strerror(errno), errno); } } return; } - syslog(LOG_INFO, "Recevied %d bytes\n", len); + syslog(LOG_INFO, "Recevied %d bytes", len); hexdump(buf,len); } } -static void recv_mode(int s) +static void recv_mode(int sk) { struct timeval tv_beg,tv_end,tv_diff; long total; uint32_t seq; - int opt, optl; + socklen_t optlen; + int opt; syslog(LOG_INFO,"Receiving ..."); @@ -431,19 +490,19 @@ static void recv_mode(int s) uint16_t l; int i, r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { + if ((r = recv(sk, buf, data_size, 0)) <= 0) { if (r < 0) { if (reliable && (errno == ECOMM)) { syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); - optl = sizeof(opt); - if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", + optlen = sizeof(opt); + if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); return; } continue; } else { - syslog(LOG_ERR, "Read failed. %s(%d)", + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); } } @@ -482,7 +541,7 @@ static void recv_mode(int s) } } -static void send_mode(int s) +static void send_mode(int sk) { uint32_t seq; int i; @@ -498,20 +557,20 @@ static void send_mode(int s) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(s, buf, data_size, 0) <= 0) { + if (send(sk, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } syslog(LOG_INFO, "Closing channel ..."); - if (shutdown(s, SHUT_RDWR) < 0) + if (shutdown(sk, SHUT_RDWR) < 0) syslog(LOG_INFO, "Close failed: %m"); else syslog(LOG_INFO, "Done"); } -static void senddump_mode(int s) +static void senddump_mode(int sk) { uint32_t seq; int i; @@ -527,13 +586,13 @@ static void senddump_mode(int s) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(s, buf, data_size, 0) <= 0) { + if (send(sk, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } - dump_mode(s); + dump_mode(sk); } static void reconnect_mode(char *svr) -- cgit From 39654da8de5f5d3f9888cb2d4d576993414642ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 19:59:22 +0000 Subject: More cleanups --- test/l2test.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index ac831d97..82d34efa 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -597,17 +597,19 @@ static void senddump_mode(int sk) static void reconnect_mode(char *svr) { - while(1) { - int s = do_connect(svr); - close(s); + while (1) { + int sk = do_connect(svr); + close(sk); } } static void connect_mode(char *svr) { - int s; - if ((s = do_connect(svr)) < 0) + int sk; + + if ((sk = do_connect(svr)) < 0) exit(1); + sleep(99999999); } -- cgit From 54c95138efbc91165d50ee0e3e1fd906493bf68f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:08:11 +0000 Subject: Typo --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 82d34efa..30d9a2e6 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -399,7 +399,7 @@ static void do_listen(void (*handler)(int sk)) ba2str(&addr.l2_bdaddr, ba); syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, " - " mode %d, handle %d, class 0x%02x%02x%02x]", + "mode %d, handle %d, class 0x%02x%02x%02x]", ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); -- cgit From 917543004017da0f09304844c578b59ca4a1802b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:13:19 +0000 Subject: Another bunch of cleanups --- test/l2test.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 30d9a2e6..70b7b1fa 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -662,10 +662,8 @@ static void usage(void) int main(int argc ,char *argv[]) { - int opt, mode, s, need_addr; struct sigaction sa; - - mode = RECV; need_addr = 0; + int opt, sk, mode = RECV, need_addr = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -807,10 +805,10 @@ int main(int argc ,char *argv[]) break; case CRECV: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - recv_mode(s); + recv_mode(sk); break; case DUMP: @@ -818,10 +816,10 @@ int main(int argc ,char *argv[]) break; case SEND: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - send_mode(s); + send_mode(sk); break; case LSEND: @@ -841,10 +839,10 @@ int main(int argc ,char *argv[]) break; case SENDDUMP: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - senddump_mode(s); + senddump_mode(sk); break; case LSENDDUMP: -- cgit From 5481f007aa304a6f5f4531a243e146f9075dc17f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jan 2005 17:24:40 +0000 Subject: Don't forget to include getopt.h --- test/l2test.c | 1 + 1 file changed, 1 insertion(+) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 70b7b1fa..5857b13d 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include -- cgit From 77f2ea7f02d5981deab6ec22d05570e06d46836e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 14:07:09 +0000 Subject: Support zero length data sizes --- test/l2test.c | 65 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 5857b13d..35e06598 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,7 @@ static int imtu = 672; static int omtu = 0; /* Default data size */ -static long data_size = 0; +static long data_size = -1; /* Default addr and psm */ static bdaddr_t bdaddr; @@ -474,7 +475,8 @@ static void dump_mode(int sk) static void recv_mode(int sk) { - struct timeval tv_beg,tv_end,tv_diff; + struct timeval tv_beg, tv_end, tv_diff; + struct pollfd p; long total; uint32_t seq; socklen_t optlen; @@ -482,6 +484,9 @@ static void recv_mode(int sk) syslog(LOG_INFO,"Receiving ..."); + p.fd = sk; + p.events = POLLIN | POLLERR | POLLHUP; + seq = 0; while (1) { gettimeofday(&tv_beg, NULL); @@ -489,27 +494,35 @@ static void recv_mode(int sk) while (total < data_size) { uint32_t sq; uint16_t l; - int i, r; - - if ((r = recv(sk, buf, data_size, 0)) <= 0) { - if (r < 0) { - if (reliable && (errno == ECOMM)) { - syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); - optlen = sizeof(opt); - if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", - strerror(errno), errno); - return; - } - continue; - } else { - syslog(LOG_ERR, "Read failed: %s (%d)", + int i, len; + + p.revents = 0; + if (poll(&p, 1, -1) <= 0) + return; + + if (p.revents & (POLLERR | POLLHUP)) + return; + + len = recv(sk, buf, data_size, 0); + if (len < 0) { + if (reliable && (errno == ECOMM)) { + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); + optlen = sizeof(opt); + if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); + return; } + continue; + } else { + syslog(LOG_ERR, "Read failed: %s (%d)", + strerror(errno), errno); } - return; } + if (len < 6) + break; + /* Check sequence */ sq = btohl(*(uint32_t *) buf); if (seq != sq) { @@ -520,18 +533,18 @@ static void recv_mode(int sk) /* Check length */ l = btohs(*(uint16_t *) (buf + 4)); - if (r != l) { - syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + if (len != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", len, l); continue; } /* Verify data */ - for (i = 6; i < r; i++) { + for (i = 6; i < len; i++) { if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); } - total += r; + total += len; } gettimeofday(&tv_end, NULL); @@ -545,7 +558,7 @@ static void recv_mode(int sk) static void send_mode(int sk) { uint32_t seq; - int i; + int i, len; syslog(LOG_INFO, "Sending ..."); @@ -558,7 +571,8 @@ static void send_mode(int sk) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(sk, buf, data_size, 0) <= 0) { + len = send(sk, buf, data_size, 0); + if (len < 0 || len != data_size) { syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } @@ -781,7 +795,8 @@ int main(int argc ,char *argv[]) exit(1); } - if (!data_size) { + if (data_size < 0) { + data_size = 48; if (imtu > data_size) data_size = imtu; if (omtu > data_size) -- cgit From 828029f202d7a7116d663ee9b9465b60c1eac030 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 15:21:18 +0000 Subject: Flag to activate flow control mode --- test/l2test.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 35e06598..f3ff2bc4 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -81,6 +81,7 @@ static unsigned short psm = 10; /* Default number of frames to send (-1 = infinite) */ static int num_frames = -1; +static int flowctl = 0; static int master = 0; static int auth = 0; static int encrypt = 0; @@ -206,6 +207,8 @@ static int do_connect(char *svr) /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; + if (flowctl) + opts.mode = 2; if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", @@ -338,6 +341,8 @@ static void do_listen(void (*handler)(int sk)) /* Set new options */ opts.imtu = imtu; + if (flowctl) + opts.mode = 2; if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", @@ -669,6 +674,7 @@ static void usage(void) "\t[-L seconds] enable SO_LINGER\n" "\t[-R] reliable mode\n" "\t[-D] use connectionless channel (datagram)\n" + "\t[-F] enable flow control\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" @@ -682,7 +688,7 @@ int main(int argc ,char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:RMAESL:D")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:L:RDFAESM")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -764,6 +770,10 @@ int main(int argc ,char *argv[]) master = 1; break; + case 'F': + flowctl = 1; + break; + case 'A': auth = 1; break; -- cgit From 72a919e9b1ae03645a63e27dfa6f4190ade6c924 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 19 May 2005 17:06:50 +0000 Subject: Detect hangup in connect mode --- test/l2test.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f3ff2bc4..8d337a9d 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -275,6 +275,9 @@ static int do_connect(char *svr) opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); + if (data_size > opts.omtu) + data_size = opts.omtu; + return sk; error: @@ -625,12 +628,24 @@ static void reconnect_mode(char *svr) static void connect_mode(char *svr) { + struct pollfd p; int sk; if ((sk = do_connect(svr)) < 0) exit(1); - sleep(99999999); + p.fd = sk; + p.events = POLLERR | POLLHUP; + + while (1) { + p.revents = 0; + if (poll(&p, 1, 100)) + break; + } + + syslog(LOG_INFO, "Disconnected"); + + close(sk); } static void multi_connect_mode(char *svr) -- cgit From 1f422e5f2b343d35a8c77ce4be16f74b2819b2bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 21:15:41 +0000 Subject: Fix some GCC 4.0 warnings --- test/l2test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 8d337a9d..f475aa4b 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -131,7 +131,7 @@ static char *ctoh(char c, char* s) return s; } -static void hexdump(char *s, unsigned long l) +static void hexdump(unsigned char *s, unsigned long l) { char bfr[80]; char *pb; @@ -477,7 +477,7 @@ static void dump_mode(int sk) } syslog(LOG_INFO, "Recevied %d bytes", len); - hexdump(buf,len); + hexdump(buf, len); } } -- cgit From 632a9432774ff3a0c6e556e8f32a565b38890767 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 22:36:31 +0000 Subject: Big cleanup of CVS relics --- test/l2test.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f475aa4b..f231587e 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From f2e48c44a7e4c9ee31b8ce2e302186f6047cfeab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:28:56 +0000 Subject: Update copyright information --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f231587e..14d6d0e1 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 6ba87383b2047862686d04db85a4b7e0d1f243ae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Mar 2006 22:06:13 +0000 Subject: Rename connection less option from -D to -G --- test/l2test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 14d6d0e1..8ec92395 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -683,7 +683,7 @@ static void usage(void) "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" "\t[-R] reliable mode\n" - "\t[-D] use connectionless channel (datagram)\n" + "\t[-G] use connectionless channel (datagram)\n" "\t[-F] enable flow control\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" @@ -698,7 +698,7 @@ int main(int argc ,char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:L:RDFAESM")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:L:RGFAESM")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -796,7 +796,7 @@ int main(int argc ,char *argv[]) secure = 1; break; - case 'D': + case 'G': socktype = SOCK_DGRAM; break; -- cgit From b357f1d3900bca5575e88fcfc160945c6088608c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Mar 2006 22:15:09 +0000 Subject: Add options for count and delay --- test/l2test.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 8ec92395..9a23480a 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -76,6 +76,12 @@ static unsigned short psm = 10; /* Default number of frames to send (-1 = infinite) */ static int num_frames = -1; +/* Default number of consecutive frames before the delay */ +static int count = 1; + +/* Default delay after sending count number of frames */ +static unsigned long delay = 0; + static int flowctl = 0; static int master = 0; static int auth = 0; @@ -579,6 +585,9 @@ static void send_mode(int sk) syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } + + if (num_frames && delay && !(seq % count)) + usleep(delay); } syslog(LOG_INFO, "Closing channel ..."); @@ -608,6 +617,9 @@ static void senddump_mode(int sk) syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } + + if (num_frames && delay && !(seq % count)) + usleep(delay); } dump_mode(sk); @@ -682,6 +694,8 @@ static void usage(void) "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" + "\t[-C num] send num frames before delay (default = 1)\n" + "\t[-D seconds] delay after sending num frames (default = 0)\n" "\t[-R] reliable mode\n" "\t[-G] use connectionless channel (datagram)\n" "\t[-F] enable flow control\n" @@ -698,7 +712,7 @@ int main(int argc ,char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:L:RGFAESM")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:L:C:D:RGFAESM")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -772,6 +786,14 @@ int main(int argc ,char *argv[]) linger = atoi(optarg); break; + case 'C': + count = atoi(optarg); + break; + + case 'D': + delay = atoi(optarg) * 1000000; + break; + case 'R': reliable = 1; break; -- cgit From e6673071212596bc54fb5bffff72b0c3a8275071 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Mar 2006 18:05:22 +0000 Subject: Change delay to milliseconds and check count --- test/l2test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 9a23480a..fc966bd3 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -586,7 +586,7 @@ static void send_mode(int sk) exit(1); } - if (num_frames && delay && !(seq % count)) + if (num_frames && delay && count && !(seq % count)) usleep(delay); } @@ -618,7 +618,7 @@ static void senddump_mode(int sk) exit(1); } - if (num_frames && delay && !(seq % count)) + if (num_frames && delay && count && !(seq % count)) usleep(delay); } @@ -695,7 +695,7 @@ static void usage(void) "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" "\t[-C num] send num frames before delay (default = 1)\n" - "\t[-D seconds] delay after sending num frames (default = 0)\n" + "\t[-D milliseconds] delay after sending num frames (default = 0)\n" "\t[-R] reliable mode\n" "\t[-G] use connectionless channel (datagram)\n" "\t[-F] enable flow control\n" @@ -791,7 +791,7 @@ int main(int argc ,char *argv[]) break; case 'D': - delay = atoi(optarg) * 1000000; + delay = atoi(optarg) * 1000; break; case 'R': -- cgit From da1911d8ae3753dc2bb925c48c8ee07c2ba93903 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Jun 2006 11:23:24 +0000 Subject: Allow reading sample data from a file --- test/l2test.c | 73 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 34 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index fc966bd3..5c34b39e 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,8 @@ static int count = 1; /* Default delay after sending count number of frames */ static unsigned long delay = 0; +static char *filename = NULL; + static int flowctl = 0; static int master = 0; static int auth = 0; @@ -564,15 +567,27 @@ static void recv_mode(int sk) } } -static void send_mode(int sk) +static void do_send(int sk) { uint32_t seq; - int i, len; + int i, fd, len; syslog(LOG_INFO, "Sending ..."); - for (i = 6; i < data_size; i++) - buf[i] = 0x7f; + if (filename) { + fd = open(filename, O_RDONLY); + if (fd < 0) { + syslog(LOG_ERR, "Open failed: %s (%d)", + strerror(errno), errno); + exit(1); + } + len = read(fd, buf, data_size); + send(sk, buf, len, 0); + return; + } else { + for (i = 6; i < data_size; i++) + buf[i] = 0x7f; + } seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { @@ -582,13 +597,19 @@ static void send_mode(int sk) len = send(sk, buf, data_size, 0); if (len < 0 || len != data_size) { - syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", + strerror(errno), errno); exit(1); } if (num_frames && delay && count && !(seq % count)) usleep(delay); } +} + +static void send_mode(int sk) +{ + do_send(sk); syslog(LOG_INFO, "Closing channel ..."); if (shutdown(sk, SHUT_RDWR) < 0) @@ -599,28 +620,7 @@ static void send_mode(int sk) static void senddump_mode(int sk) { - uint32_t seq; - int i; - - syslog(LOG_INFO, "Sending ..."); - - for (i = 6; i < data_size; i++) - buf[i] = 0x7f; - - seq = 0; - while ((num_frames == -1) || (num_frames-- > 0)) { - *(uint32_t *) buf = htobl(seq); - *(uint16_t *) (buf + 4) = htobs(data_size); - seq++; - - if (send(sk, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); - exit(1); - } - - if (num_frames && delay && count && !(seq % count)) - usleep(delay); - } + do_send(sk); dump_mode(sk); } @@ -692,8 +692,9 @@ static void usage(void) printf("Options:\n" "\t[-b bytes] [-i device] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" - "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" + "\t[-B filename] use data packets from file\n" + "\t[-N num] send num frames (default = infinite)\n" "\t[-C num] send num frames before delay (default = 1)\n" "\t[-D milliseconds] delay after sending num frames (default = 0)\n" "\t[-R] reliable mode\n" @@ -705,14 +706,14 @@ static void usage(void) "\t[-M] become master\n"); } -int main(int argc ,char *argv[]) +int main(int argc, char *argv[]) { struct sigaction sa; int opt, sk, mode = RECV, need_addr = 0; bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:L:C:D:RGFAESM")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:B:N:L:C:D:RGFAESM")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -786,6 +787,14 @@ int main(int argc ,char *argv[]) linger = atoi(optarg); break; + case 'B': + filename = strdup(optarg); + break; + + case 'N': + num_frames = atoi(optarg); + break; + case 'C': count = atoi(optarg); break; @@ -822,10 +831,6 @@ int main(int argc ,char *argv[]) socktype = SOCK_DGRAM; break; - case 'N': - num_frames = atoi(optarg); - break; - default: usage(); exit(1); -- cgit From 0effff5f4fe0fac9a986bb01dc547a99772d1bfa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 5 Jul 2006 18:53:18 +0000 Subject: Allow connects to multiple remote devices --- test/l2test.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 5c34b39e..f8572067 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -655,20 +655,24 @@ static void connect_mode(char *svr) close(sk); } -static void multi_connect_mode(char *svr) +static void multi_connect_mode(int argc, char *argv[]) { + int i, n, sk; + while (1) { - int i, s; - for (i = 0; i < 10; i++) { - if (fork()) continue; - - /* Child */ - s = do_connect(svr); - usleep(500); - close(s); - exit(0); + for (n = 0; n < argc; n++) { + for (i = 0; i < count; i++) { + if (fork()) + continue; + + /* Child */ + sk = do_connect(argv[n]); + usleep(500); + close(sk); + exit(0); + } } - sleep(2); + sleep(4); } } @@ -894,7 +898,7 @@ int main(int argc, char *argv[]) break; case MULTY: - multi_connect_mode(argv[optind]); + multi_connect_mode(argc - optind, argv + optind); break; case CONNECT: -- cgit From 35e9349ffc53950c4b78fba9537a50cdb6e5fd7a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Aug 2006 10:20:59 +0000 Subject: Change default poll() timeout --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f8572067..f3365c01 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -646,7 +646,7 @@ static void connect_mode(char *svr) while (1) { p.revents = 0; - if (poll(&p, 1, 100)) + if (poll(&p, 1, 500)) break; } -- cgit From 329237dde23a9f692590f0075340ea085f8f3b35 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 24 Sep 2006 11:36:24 +0000 Subject: Add information request command --- test/l2test.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 7 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f3365c01..42d66adf 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -58,7 +58,8 @@ enum { CRECV, LSEND, SENDDUMP, - LSENDDUMP + LSENDDUMP, + INFOREQ }; static unsigned char *buf; @@ -676,6 +677,105 @@ static void multi_connect_mode(int argc, char *argv[]) } } +static void info_request(char *svr) +{ + unsigned char buf[48]; + l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; + l2cap_info_req *req = (l2cap_info_req *) (buf + L2CAP_CMD_HDR_SIZE); + l2cap_info_rsp *rsp = (l2cap_info_rsp *) (buf + L2CAP_CMD_HDR_SIZE); + uint16_t mtu; + uint32_t mask; + struct sockaddr_l2 addr; + int sk, err; + + sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); + if (sk < 0) { + perror("Can't create socket"); + return; + } + + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't bind socket"); + goto failed; + } + + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + str2ba(svr, &addr.l2_bdaddr); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { + perror("Can't connect socket"); + goto failed; + } + + memset(buf, 0, sizeof(buf)); + cmd->code = L2CAP_INFO_REQ; + cmd->ident = 0; + cmd->len = htobs(2); + req->type = htobs(0x0001); + + if (send(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_REQ_SIZE, 0) < 0) { + perror("Can't send info request"); + goto failed; + } + + err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 2, 0); + if (err < 0) { + perror("Can't receive info response"); + goto failed; + } + + switch (btohs(rsp->result)) { + case 0x0000: + mtu = btohs(bt_get_unaligned((uint16_t *) rsp->data)); + printf("Connectionless MTU size is %d\n", mtu); + break; + case 0x0001: + printf("Connectionless MTU is not supported\n"); + break; + } + + memset(buf, 0, sizeof(buf)); + cmd->code = L2CAP_INFO_REQ; + cmd->ident = 0; + cmd->len = htobs(2); + req->type = htobs(0x0002); + + if (send(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_REQ_SIZE, 0) < 0) { + perror("Can't send info request"); + goto failed; + } + + err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + L2CAP_INFO_RSP_SIZE + 4, 0); + if (err < 0) { + perror("Can't receive info response"); + goto failed; + } + + switch (btohs(rsp->result)) { + case 0x0000: + mask = btohl(bt_get_unaligned((uint32_t *) rsp->data)); + printf("Extended feature mask is 0x%04x\n", mask); + if (mask & 0x01) + printf(" Flow control mode\n"); + if (mask & 0x02) + printf(" Retransmission mode\n"); + if (mask & 0x04) + printf(" Bi-directional QoS\n"); + break; + case 0x0001: + printf("Extended feature mask is not supported\n"); + break; + } + +failed: + close(sk); +} + static void usage(void) { printf("l2test - L2CAP testing\n" @@ -691,7 +791,8 @@ static void usage(void) "\t-n connect and be silent\n" "\t-y connect, then send, then dump incoming data\n" "\t-c connect, disconnect, connect, ...\n" - "\t-m multiple connects\n"); + "\t-m multiple connects\n" + "\t-z information request\n"); printf("Options:\n" "\t[-b bytes] [-i device] [-P psm]\n" @@ -717,7 +818,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:B:N:L:C:D:RGFAESM")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyzb:i:P:I:O:B:N:L:C:D:RGFAESM")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -756,10 +857,6 @@ int main(int argc, char *argv[]) need_addr = 1; break; - case 'b': - data_size = atoi(optarg); - break; - case 'x': mode = LSENDDUMP; break; @@ -768,6 +865,15 @@ int main(int argc, char *argv[]) mode = SENDDUMP; break; + case 'z': + mode = INFOREQ; + need_addr = 1; + break; + + case 'b': + data_size = atoi(optarg); + break; + case 'i': if (!strncasecmp(optarg, "hci", 3)) hci_devba(atoi(optarg + 3), &bdaddr); @@ -915,6 +1021,10 @@ int main(int argc, char *argv[]) case LSENDDUMP: do_listen(senddump_mode); break; + + case INFOREQ: + info_request(argv[optind]); + exit(0); } syslog(LOG_INFO, "Exit"); -- cgit From 9ec342ce2d928d2d58777cc7b9d3d0969fc3b208 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 24 Sep 2006 12:43:54 +0000 Subject: Don't use ident 0 for information request --- test/l2test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 42d66adf..f152fb8e 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -714,7 +714,7 @@ static void info_request(char *svr) memset(buf, 0, sizeof(buf)); cmd->code = L2CAP_INFO_REQ; - cmd->ident = 0; + cmd->ident = 42; cmd->len = htobs(2); req->type = htobs(0x0001); @@ -741,7 +741,7 @@ static void info_request(char *svr) memset(buf, 0, sizeof(buf)); cmd->code = L2CAP_INFO_REQ; - cmd->ident = 0; + cmd->ident = 42; cmd->len = htobs(2); req->type = htobs(0x0002); -- cgit From 607695ed109340f4b7a5628420e0a8e8aee34f4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:48:12 +0000 Subject: Update copyright information --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index f152fb8e..c7155e73 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From b4ccc4c8dec3b4421f5f644424103eb0274d446a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Jan 2007 23:56:48 +0000 Subject: Check socket address to get the dynamic PSM and channel values --- test/l2test.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index c7155e73..733c0524 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -370,6 +370,18 @@ static void do_listen(void (*handler)(int sk)) goto error; } + /* Check for socket address */ + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) { + syslog(LOG_ERR, "Can't get socket name: %s (%d)", + strerror(errno), errno); + goto error; + } + + psm = btohs(addr.l2_psm); + syslog(LOG_INFO, "Waiting for connection on psm %d ...", psm); while(1) { -- cgit From 11d24685fbd0b32c19bab01c0644dd9d5ea25315 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 May 2007 11:50:49 +0000 Subject: Set output MTU for listening sockets --- test/l2test.c | 1 + 1 file changed, 1 insertion(+) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 733c0524..59571149 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -348,6 +348,7 @@ static void do_listen(void (*handler)(int sk)) } /* Set new options */ + opts.omtu = omtu; opts.imtu = imtu; if (flowctl) opts.mode = 2; -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 59571149..b8b75d93 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 8e34afe9cc4dada1c34126a9723f76d4a6705707 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Jun 2008 14:09:07 +0000 Subject: Allow setting of RFC mode --- test/l2test.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index b8b75d93..21e17f57 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -86,7 +86,7 @@ static unsigned long delay = 0; static char *filename = NULL; -static int flowctl = 0; +static int rfcmode = 0; static int master = 0; static int auth = 0; static int encrypt = 0; @@ -212,8 +212,8 @@ static int do_connect(char *svr) /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; - if (flowctl) - opts.mode = 2; + if (rfcmode > 0) + opts.mode = rfcmode; if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", @@ -350,8 +350,8 @@ static void do_listen(void (*handler)(int sk)) /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; - if (flowctl) - opts.mode = 2; + if (rfcmode > 0) + opts.mode = rfcmode; if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", @@ -815,9 +815,10 @@ static void usage(void) "\t[-N num] send num frames (default = infinite)\n" "\t[-C num] send num frames before delay (default = 1)\n" "\t[-D milliseconds] delay after sending num frames (default = 0)\n" + "\t[-X mode] select retransmission/flow-control mode\n" "\t[-R] reliable mode\n" "\t[-G] use connectionless channel (datagram)\n" - "\t[-F] enable flow control\n" + "\t[-R] enable retransmission\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" @@ -831,7 +832,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyzb:i:P:I:O:B:N:L:C:D:RGFAESM")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyzb:i:P:I:O:B:N:L:C:D:X:RGAESM")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -926,6 +927,10 @@ int main(int argc, char *argv[]) delay = atoi(optarg) * 1000; break; + case 'X': + rfcmode = atoi(optarg); + break; + case 'R': reliable = 1; break; @@ -934,10 +939,6 @@ int main(int argc, char *argv[]) master = 1; break; - case 'F': - flowctl = 1; - break; - case 'A': auth = 1; break; -- cgit From 30ea633a54cbc0b3352f026d8f3f039eae25d472 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jun 2008 18:21:10 +0000 Subject: Remove invalid line in usage output --- test/l2test.c | 1 - 1 file changed, 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 21e17f57..8338886c 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -818,7 +818,6 @@ static void usage(void) "\t[-X mode] select retransmission/flow-control mode\n" "\t[-R] reliable mode\n" "\t[-G] use connectionless channel (datagram)\n" - "\t[-R] enable retransmission\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" -- cgit From 5b675858211437ea5d42ca49bbfbe15aeece65a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jun 2008 18:45:52 +0000 Subject: Add timestamp option --- test/l2test.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index 8338886c..fffa7fd8 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -94,6 +94,7 @@ static int secure = 0; static int socktype = SOCK_SEQPACKET; static int linger = 0; static int reliable = 0; +static int timestamp = 0; static float tv2fl(struct timeval tv) { @@ -221,6 +222,17 @@ static int do_connect(char *svr) goto error; } + /* Enable SO_TIMESTAMP */ + if (timestamp) { + int t = 1; + + if (setsockopt(sk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { + syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)", + strerror(errno), errno); + goto error; + } + } + /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; @@ -228,7 +240,7 @@ static int do_connect(char *svr) if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", strerror(errno), errno); - return -1; + goto error; } } @@ -431,6 +443,17 @@ static void do_listen(void (*handler)(int sk)) ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); + /* Enable SO_TIMESTAMP */ + if (timestamp) { + int t = 1; + + if (setsockopt(sk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { + syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)", + strerror(errno), errno); + goto error; + } + } + /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; @@ -821,7 +844,8 @@ static void usage(void) "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" - "\t[-M] become master\n"); + "\t[-M] become master\n" + "\t[-T] enable timestamps\n"); } int main(int argc, char *argv[]) @@ -831,7 +855,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyzb:i:P:I:O:B:N:L:C:D:X:RGAESM")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyzb:i:P:I:O:B:N:L:C:D:X:RGAESMT")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -954,6 +978,10 @@ int main(int argc, char *argv[]) socktype = SOCK_DGRAM; break; + case 'T': + timestamp = 1; + break; + default: usage(); exit(1); -- cgit From 9e198552165e2e473a9cb6792a70fe85fecbc987 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jun 2008 18:54:15 +0000 Subject: Use the correct socket descriptor for incoming connections --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index fffa7fd8..acf4a23c 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -447,7 +447,7 @@ static void do_listen(void (*handler)(int sk)) if (timestamp) { int t = 1; - if (setsockopt(sk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { + if (setsockopt(nsk, SOL_SOCKET, SO_TIMESTAMP, &t, sizeof(t)) < 0) { syslog(LOG_ERR, "Can't enable SO_TIMESTAMP: %s (%d)", strerror(errno), errno); goto error; -- cgit From 2199bc76c668f92e14fcaa4bc16fd4674f728bc1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 25 Jun 2008 07:13:46 +0000 Subject: Enable output of timestamps --- test/l2test.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index acf4a23c..a6ff75fa 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -222,6 +223,7 @@ static int do_connect(char *svr) goto error; } +#if 0 /* Enable SO_TIMESTAMP */ if (timestamp) { int t = 1; @@ -232,6 +234,7 @@ static int do_connect(char *svr) goto error; } } +#endif /* Enable SO_LINGER */ if (linger) { @@ -443,6 +446,7 @@ static void do_listen(void (*handler)(int sk)) ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); +#if 0 /* Enable SO_TIMESTAMP */ if (timestamp) { int t = 1; @@ -453,6 +457,7 @@ static void do_listen(void (*handler)(int sk)) goto error; } } +#endif /* Enable SO_LINGER */ if (linger) { @@ -526,12 +531,15 @@ static void recv_mode(int sk) { struct timeval tv_beg, tv_end, tv_diff; struct pollfd p; + char ts[30]; long total; uint32_t seq; socklen_t optlen; int opt; - syslog(LOG_INFO,"Receiving ..."); + syslog(LOG_INFO, "Receiving ..."); + + memset(ts, 0, sizeof(ts)); p.fd = sk; p.events = POLLIN | POLLERR | POLLHUP; @@ -572,6 +580,18 @@ static void recv_mode(int sk) if (len < 6) break; + if (timestamp) { + struct timeval tv; + + if (ioctl(sk, SIOCGSTAMP, &tv) < 0) { + timestamp = 0; + memset(ts, 0, sizeof(ts)); + } else { + sprintf(ts, "[%ld.%ld] ", + tv.tv_sec, tv.tv_usec); + } + } + /* Check sequence */ sq = btohl(*(uint32_t *) buf); if (seq != sq) { @@ -599,7 +619,7 @@ static void recv_mode(int sk) timersub(&tv_end, &tv_beg, &tv_diff); - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s", total, + syslog(LOG_INFO,"%s%ld bytes in %.2f sec, %.2f kB/s", ts, total, tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); } } -- cgit From 06e4d41372a9f005b05cc2f4a09924f18bf6f6d7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 09:38:39 +0000 Subject: Allow link mode settings for outgoing connections --- test/l2test.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test/l2test.c') diff --git a/test/l2test.c b/test/l2test.c index a6ff75fa..bc57d6b6 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -251,6 +251,14 @@ static int do_connect(char *svr) opt = 0; if (reliable) opt |= L2CAP_LM_RELIABLE; + if (master) + opt |= L2CAP_LM_MASTER; + if (auth) + opt |= L2CAP_LM_AUTH; + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + if (secure) + opt |= L2CAP_LM_SECURE; if (setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", -- cgit