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/Makefile.am | 5 + test/attest.c | 178 +++++++++++++++++++ test/l2test.c | 530 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/rctest.c | 469 ++++++++++++++++++++++++++++++++++++++++++++++++ test/scotest.c | 358 +++++++++++++++++++++++++++++++++++++ 5 files changed, 1540 insertions(+) create mode 100644 test/Makefile.am create mode 100644 test/attest.c create mode 100644 test/l2test.c create mode 100644 test/rctest.c create mode 100644 test/scotest.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 00000000..dc84f46f --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,5 @@ +# +# $Id$ +# + +noinst_PROGRAMS = l2test scotest rctest attest diff --git a/test/attest.c b/test/attest.c new file mode 100644 index 00000000..078bb886 --- /dev/null +++ b/test/attest.c @@ -0,0 +1,178 @@ +/* + * + * Programm for testing AT commands over Bluetooth RFCOMM + * + * Copyright (C) 2001-2002 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * 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. + * + * 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. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + + +static int at_command(int fd, char *cmd, int to) +{ + fd_set rfds; + struct timeval timeout; + unsigned char buf[1024]; + int sel, len, i, n; + + write(fd, cmd, strlen(cmd)); + + for (i = 0; i < 100; i++) { + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + timeout.tv_sec = 0; + timeout.tv_usec = to; + + if ((sel = select(fd + 1, &rfds, NULL, NULL, &timeout)) > 0) { + + if (FD_ISSET(fd, &rfds)) { + memset(buf, 0, sizeof(buf)); + len = read(fd, buf, sizeof(buf)); + for (n = 0; n < len; n++) + printf("%c", buf[n]); + if (strstr(buf, "\r\nOK") != NULL) + break; + if (strstr(buf, "\r\nERROR") != NULL) + break; + if (strstr(buf, "\r\nCONNECT") != NULL) + break; + } + + } + + } + + return 0; +} + + +static int open_device(char *device) +{ + int fd; + struct termios ti; + + if ((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { + printf("Can't open serial port. %s (%d)\n", strerror(errno), errno); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + /* Switch tty to RAW mode */ + cfmakeraw(&ti); + tcsetattr(fd, TCSANOW, &ti); + + return fd; +} + + +static int open_socket(bdaddr_t *bdaddr, uint8_t channel) +{ + struct sockaddr_rc remote_addr, local_addr; + int s; + + if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { + printf("Can't create socket. %s (%d)\n", strerror(errno), errno); + return -1; + } + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.rc_family = AF_BLUETOOTH; + bacpy(&local_addr.rc_bdaddr, BDADDR_ANY); + if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { + printf("Can't bind socket. %s (%d)\n", strerror(errno), errno); + close(s); + return -1; + } + + memset(&remote_addr, 0, sizeof(remote_addr)); + remote_addr.rc_family = AF_BLUETOOTH; + bacpy(&remote_addr.rc_bdaddr, bdaddr); + remote_addr.rc_channel = channel; + if (connect(s, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) { + printf("Can't connect. %s (%d)\n", strerror(errno), errno); + close(s); + return -1; + } + + return s; +} + + +static void usage(void) +{ + printf("Usage:\n\tattest | [channel]\n"); +} + + +int main(int argc, char *argv[]) +{ + int fd; + + bdaddr_t bdaddr; + uint8_t channel; + + switch (argc) { + case 2: + str2ba(argv[1], &bdaddr); + channel = 1; + break; + case 3: + str2ba(argv[1], &bdaddr); + channel = atoi(argv[2]); + break; + default: + usage(); + exit(-1); + } + + if (bacmp(BDADDR_ANY, &bdaddr)) { + printf("Connecting to %s on channel %d\n", argv[1], channel); + fd = open_socket(&bdaddr, channel); + } else { + printf("Opening device %s\n", argv[1]); + fd = open_device(argv[1]); + } + + if (fd < 0) + exit(-2); + + at_command(fd, "ATZ\r\n", 10000); + at_command(fd, "AT+CPBS=\"ME\"\r\n", 10000); + at_command(fd, "AT+CPBR=1,100\r\n", 100000); + + close(fd); + + return 0; +} 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; +} diff --git a/test/rctest.c b/test/rctest.c new file mode 100644 index 00000000..0584a6a9 --- /dev/null +++ b/test/rctest.c @@ -0,0 +1,469 @@ +/* + RFCOMM test tool + Copyright (C) 2002 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 = 127; + +/* Default addr and channel */ +bdaddr_t bdaddr; +uint8_t channel = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; +int socktype = SOCK_STREAM; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_rc rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_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); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.rc_family = AF_BLUETOOTH; + baswap(&rem_addr.rc_bdaddr, strtoba(svr)); + rem_addr.rc_channel = channel; + 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; + } + + syslog(LOG_INFO, "Connected"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_rc loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_bdaddr = bdaddr; + loc_addr.rc_channel = channel; + 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); + } + +#if 0 + /* 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_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } +#endif + + 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 channel %d ...", channel); + + 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); + + baswap(&ba, &rem_addr.rc_bdaddr); + syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + + 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 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 0 + /* 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]); + } +#endif + 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 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("rctest - RFCOMM testing\n" + "Usage:\n"); + printf("\trctest [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 channel]\n" + "\t[-I imtu] [-O omtu]\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:MAE")) != 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': + channel = 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; + + 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("rctest", 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: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + dump_mode(s); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} diff --git a/test/scotest.c b/test/scotest.c new file mode 100644 index 00000000..dcb1acdf --- /dev/null +++ b/test/scotest.c @@ -0,0 +1,358 @@ +/* + 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 +}; + +unsigned char *buf; + +/* Default data size */ +long data_size = 672; + +bdaddr_t bdaddr; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_sco rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_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); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.sco_family = AF_BLUETOOTH; + baswap(&rem_addr.sco_bdaddr, strtoba(svr)); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + return -1; + } + + syslog(LOG_INFO, "Connected\n"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_sco loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_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); + } + + 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 ..."); + + 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); + + baswap(&ba, &rem_addr.sco_bdaddr); + syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); + + 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) { + int r; + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb",total, + tv2fl(tv_diff) / 60.0, + (float)( total / tv2fl(tv_diff) ) / 1024.0 ); + } +} + +void send_mode(char *svr) +{ + struct sco_options so; + uint32_t seq; + int s, i, opt; + + if ((s = do_connect(svr)) < 0) { + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", + strerror(errno), errno); + exit(1); + } + + opt = sizeof(so); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + syslog(LOG_ERR, "Can't get SCO options. %s(%d)", + strerror(errno), errno); + exit(1); + } + + + syslog(LOG_INFO,"Sending ..."); + + for (i=6; i < so.mtu; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *)buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, so.mtu, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", + strerror(errno), errno); + exit(1); + } + usleep(1); + } +} + +void reconnect_mode(char *svr) +{ + while(1){ + int s; + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + close(s); + + sleep(5); + } +} + +void multy_connect_mode(char *svr) +{ + while(1){ + int i, s; + for(i=0; i<10; i++){ + if( fork() ) continue; + + /* Child */ + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + } + close(s); + exit(0); + } + sleep(19); + } +} + +void usage(void) +{ + printf("scotest - SCO testing\n" + "Usage:\n"); + printf("\tscotest [-b bytes] [bd_addr]\n"); + printf("Modes:\n" + "\t-d dump (server)\n" + "\t-c reconnect (client)\n" + "\t-m multiple connects (client)\n" + "\t-r receive (server)\n" + "\t-s send (client)\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + struct sigaction sa; + int opt, mode = RECV; + + while ((opt=getopt(argc,argv,"rdscmb:")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + break; + + case 'm': + mode = MULTY; + break; + + case 'b': + data_size = atoi(optarg); + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + 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("scotest", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + send_mode(argv[optind]); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multy_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') 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 7490b6c61bfa0b581ff7a15f6482787973cf7e3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 21 Dec 2002 15:40:33 +0000 Subject: Add Headset Test utility --- test/Makefile.am | 4 +- test/hsmicro | 20 ++++ test/hsplay | 22 ++++ test/hstest.c | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 378 insertions(+), 1 deletion(-) create mode 100755 test/hsmicro create mode 100755 test/hsplay create mode 100644 test/hstest.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index dc84f46f..ec6b7779 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,4 +2,6 @@ # $Id$ # -noinst_PROGRAMS = l2test scotest rctest attest +noinst_PROGRAMS = l2test scotest rctest attest hstest + +EXTRA_DIST = hsplay hsmicro diff --git a/test/hsmicro b/test/hsmicro new file mode 100755 index 00000000..8aec68f2 --- /dev/null +++ b/test/hsmicro @@ -0,0 +1,20 @@ +#!/bin/sh + +SOX=`which sox` +HSTEST=`which hstest` + +if [ -z "$HSTEST" ] +then + HSTEST="./hstest" +fi + +if [ -z "$1" ] +then + echo -e "Usage:\n\thsmicro [channel]" + exit +fi + +BDADDR=$1 +CHANNEL=$2 + +$HSTEST record - $BDADDR $CHANNEL | $SOX -t raw -r 8000 -c 1 -s -b - -t ossdsp -r 44100 -c 2 -s -w /dev/dsp polyphase vol 5.0 2> /dev/null diff --git a/test/hsplay b/test/hsplay new file mode 100755 index 00000000..8a676459 --- /dev/null +++ b/test/hsplay @@ -0,0 +1,22 @@ +#!/bin/sh + +MPG123=`which mpg123` +SOX=`which sox` +HSTEST=`which hstest` + +if [ -z "$HSTEST" ] +then + HSTEST="./hstest" +fi + +if [ -z "$1" -o -z "$2" ] +then + echo -e "Usage:\n\thsplay [channel]" + exit +fi + +FILE=$1 +BDADDR=$2 +CHANNEL=$3 + +$MPG123 -q -s "$FILE" | $SOX -t raw -r 44100 -c 2 -s -w - -t raw -r 8000 -c 1 -s -b - | $HSTEST play - $BDADDR $CHANNEL diff --git a/test/hstest.c b/test/hstest.c new file mode 100644 index 00000000..867eb20b --- /dev/null +++ b/test/hstest.c @@ -0,0 +1,333 @@ +/* + * + * Bluetooth Headset Test utility + * + * Copyright (C) 2002 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; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#ifndef OCF_READ_VOICE_SETTING +#define OCF_READ_VOICE_SETTING 0x0025 +typedef struct { + uint8_t status; + uint16_t voice_setting; +} __attribute__ ((packed)) read_voice_setting_rp; +#define READ_VOICE_SETTING_RP_SIZE 3 + +static int hci_read_voice_setting(int dd, uint16_t *vs, int to) +{ + read_voice_setting_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_VOICE_SETTING; + rq.rparam = &rp; + rq.rlen = READ_VOICE_SETTING_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *vs = rp.voice_setting; + return 0; +} +#endif + + +static volatile int terminate = 0; + + +static void sig_term(int sig) { + terminate = 1; +} + + +static int rfcomm_connect(bdaddr_t *src, bdaddr_t *dst, uint8_t channel) +{ + struct sockaddr_rc addr; + int s; + + if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, src); + addr.rc_channel = 0; + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(s); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, dst); + addr.rc_channel = channel; + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ + close(s); + return -1; + } + + return s; +} + + +static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t *mtu) +{ + struct sockaddr_sco addr; + struct sco_conninfo conn; + struct sco_options opts; + int s, size; + + if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, src); + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(s); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, dst); + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ + close(s); + return -1; + } + + size = sizeof(conn); + if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &size) < 0) { + close(s); + return -1; + } + + size = sizeof(opts); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &opts, &size) < 0) { + close(s); + return -1; + } + + if (handle) + *handle = conn.hci_handle; + + if (mtu) + *mtu = opts.mtu; + + return s; +} + + +static void usage(void) +{ + printf("Usage:\n" + "\thstest play [channel]\n" + "\thstest record [channel]\n"); +} + + +#define PLAY 1 +#define RECORD 2 + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + + fd_set rfds; + struct timeval timeout; + unsigned char buf[2048]; + int maxfd, sel, rlen, wlen; + + bdaddr_t local; + bdaddr_t bdaddr; + uint8_t channel; + + char *filename; + mode_t filemode; + int mode = 0; + int dd, rd, sd, fd; + uint16_t sco_handle, sco_mtu, vs; + + + switch (argc) { + case 4: + str2ba(argv[3], &bdaddr); + channel = 6; + break; + case 5: + str2ba(argv[3], &bdaddr); + channel = atoi(argv[4]); + break; + default: + usage(); + exit(-1); + } + + if (strncmp(argv[1], "play", 4) == 0) { + mode = PLAY; + filemode = O_RDONLY; + } else if (strncmp(argv[1], "rec", 3) == 0) { + mode = RECORD; + filemode = O_WRONLY | O_CREAT | O_TRUNC; + } else { + usage(); + exit(-1); + } + + filename = argv[2]; + + + hci_devba(0, &local); + dd = hci_open_dev(0); + hci_read_voice_setting(dd, &vs, 1000); + fprintf(stderr, "Voice setting: 0x%04x\n", vs); + close(dd); + if (vs != 0x0040) { + fprintf(stderr, "The voice setting must be 0x0040\n"); + return -1; + } + + + if (strcmp(filename, "-") == 0) { + switch (mode) { + case PLAY: + fd = 0; + break; + case RECORD: + fd = 1; + break; + default: + return -1; + } + } else { + if ((fd = open(filename, filemode)) < 0) { + perror("Can't open input/output file"); + return -1; + } + } + + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + + if ((rd = rfcomm_connect(&local, &bdaddr, channel)) < 0) { + perror("Can't connect RFCOMM channel"); + return -1; + } + + fprintf(stderr, "RFCOMM channel connected\n"); + + + if ((sd = sco_connect(&local, &bdaddr, &sco_handle, &sco_mtu)) < 0) { + perror("Can't connect SCO audio channel"); + close(rd); + return -1; + } + + fprintf(stderr, "SCO audio channel connected (handle %d, mtu %d)\n", sco_handle, sco_mtu); + + + if (mode == RECORD) + write(rd, "RING\r\n", 6); + + maxfd = (rd > sd) ? rd : sd; + + while (!terminate) { + + FD_ZERO(&rfds); + FD_SET(rd, &rfds); + FD_SET(sd, &rfds); + + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + + if ((sel = select(maxfd + 1, &rfds, NULL, NULL, &timeout)) > 0) { + + if (FD_ISSET(rd, &rfds)) { + memset(buf, 0, sizeof(buf)); + rlen = read(rd, buf, sizeof(buf)); + if (rlen > 0) { + fprintf(stderr, "%s\n", buf); + wlen = write(rd, "OK\r\n", 4); + } + } + + if (FD_ISSET(sd, &rfds)) { + memset(buf, 0, sizeof(buf)); + rlen = read(sd, buf, sizeof(buf)); + if (rlen > 0) + switch (mode) { + case PLAY: + rlen = read(fd, buf, rlen); + wlen = write(sd, buf, rlen); + break; + case RECORD: + wlen = write(fd, buf, rlen); + break; + default: + break; + } + } + + } + + } + + close(sd); + sleep(5); + close(rd); + + close(fd); + + return 0; +} -- 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 +- test/rctest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test') 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" diff --git a/test/rctest.c b/test/rctest.c index 0584a6a9..2afafaa2 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -300,7 +300,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') 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 499f43343f20d5a562ee041d950086df01fb4868 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Mar 2003 09:54:01 +0000 Subject: Remove the voice setting command and fix a big endian problem --- test/hstest.c | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) (limited to 'test') diff --git a/test/hstest.c b/test/hstest.c index 867eb20b..8b47a10a 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -39,42 +39,8 @@ #include -#ifndef OCF_READ_VOICE_SETTING -#define OCF_READ_VOICE_SETTING 0x0025 -typedef struct { - uint8_t status; - uint16_t voice_setting; -} __attribute__ ((packed)) read_voice_setting_rp; -#define READ_VOICE_SETTING_RP_SIZE 3 - -static int hci_read_voice_setting(int dd, uint16_t *vs, int to) -{ - read_voice_setting_rp rp; - struct hci_request rq; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_VOICE_SETTING; - rq.rparam = &rp; - rq.rlen = READ_VOICE_SETTING_RP_SIZE; - - if (hci_send_req(dd, &rq, to) < 0) - return -1; - - if (rp.status) { - errno = EIO; - return -1; - } - - *vs = rp.voice_setting; - return 0; -} -#endif - - static volatile int terminate = 0; - static void sig_term(int sig) { terminate = 1; } @@ -110,7 +76,6 @@ static int rfcomm_connect(bdaddr_t *src, bdaddr_t *dst, uint8_t channel) return s; } - static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t *mtu) { struct sockaddr_sco addr; @@ -167,7 +132,6 @@ static void usage(void) "\thstest record [channel]\n"); } - #define PLAY 1 #define RECORD 2 @@ -222,6 +186,7 @@ int main(int argc, char *argv[]) hci_devba(0, &local); dd = hci_open_dev(0); hci_read_voice_setting(dd, &vs, 1000); + vs = htobs(vs); fprintf(stderr, "Voice setting: 0x%04x\n", vs); close(dd); if (vs != 0x0040) { -- 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') 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') 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') 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 982ff3a573a6c043c48cf64059d92e550ec2d1b6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 19 May 2003 21:05:27 +0000 Subject: Add support for SO_LINGER option. Call shutdown() before closing socket and check return value. This is used with SO_LINGER to check for errors during DCL disconnection. --- test/rctest.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/rctest.c b/test/rctest.c index 2afafaa2..47039555 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -63,6 +63,7 @@ int omtu = 0; /* Default data size */ long data_size = 127; +long num_frames = -1; /* Default addr and channel */ bdaddr_t bdaddr; @@ -72,6 +73,7 @@ int master = 0; int auth = 0; int encrypt = 0; int socktype = SOCK_STREAM; +int linger = 0; float tv2fl(struct timeval tv) { @@ -88,6 +90,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(&loc_addr, 0, sizeof(loc_addr)); loc_addr.rc_family = AF_BLUETOOTH; loc_addr.rc_bdaddr = bdaddr; @@ -173,6 +185,16 @@ void do_listen( void (*handler)(int sk) ) baswap(&ba, &rem_addr.rc_bdaddr); syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + /* 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"); @@ -256,7 +278,7 @@ void send_mode(int s) buf[i]=0x7f; seq = 0; - while (1) { + while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); @@ -265,6 +287,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) @@ -310,6 +338,8 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P channel]\n" "\t[-I imtu] [-O omtu]\n" + "\t[-L seconds] enabled SO_LINGER option\n" + "\t[-N num] number of frames to send\n" "\t[-E] request encryption\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); @@ -325,7 +355,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAEL:N:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -396,6 +426,14 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'L': + linger = atoi(optarg); + break; + + case 'N': + num_frames = atoi(optarg); + break; + default: usage(); exit(1); -- 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') 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') 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 693d345b0cc02c961748aad2074a2ca64934c9f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Oct 2003 15:18:55 +0000 Subject: Let the headset test tools use 16 bit PCM for input and output --- test/hsmicro | 2 +- test/hsplay | 2 +- test/hstest.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/hsmicro b/test/hsmicro index 8aec68f2..c254226b 100755 --- a/test/hsmicro +++ b/test/hsmicro @@ -17,4 +17,4 @@ fi BDADDR=$1 CHANNEL=$2 -$HSTEST record - $BDADDR $CHANNEL | $SOX -t raw -r 8000 -c 1 -s -b - -t ossdsp -r 44100 -c 2 -s -w /dev/dsp polyphase vol 5.0 2> /dev/null +$HSTEST record - $BDADDR $CHANNEL | $SOX -t raw -r 8000 -c 1 -s -w - -t ossdsp -r 44100 -c 2 -s -w /dev/dsp polyphase vol 5.0 2> /dev/null diff --git a/test/hsplay b/test/hsplay index 8a676459..5f53562b 100755 --- a/test/hsplay +++ b/test/hsplay @@ -19,4 +19,4 @@ FILE=$1 BDADDR=$2 CHANNEL=$3 -$MPG123 -q -s "$FILE" | $SOX -t raw -r 44100 -c 2 -s -w - -t raw -r 8000 -c 1 -s -b - | $HSTEST play - $BDADDR $CHANNEL +$MPG123 -q -s "$FILE" | $SOX -t raw -r 44100 -c 2 -s -w - -t raw -r 8000 -c 1 -s -w - | $HSTEST play - $BDADDR $CHANNEL diff --git a/test/hstest.c b/test/hstest.c index 8b47a10a..23bbf089 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -189,8 +189,8 @@ int main(int argc, char *argv[]) vs = htobs(vs); fprintf(stderr, "Voice setting: 0x%04x\n", vs); close(dd); - if (vs != 0x0040) { - fprintf(stderr, "The voice setting must be 0x0040\n"); + if (vs != 0x0060) { + fprintf(stderr, "The voice setting must be 0x0060\n"); return -1; } -- 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 ++++-- test/rctest.c | 3 ++- test/scotest.c | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'test') 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); diff --git a/test/rctest.c b/test/rctest.c index 47039555..3d50ba95 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -279,8 +279,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); diff --git a/test/scotest.c b/test/scotest.c index dcb1acdf..0c8d8da3 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -215,8 +215,9 @@ void send_mode(char *svr) seq = 0; while (1) { - *(uint32_t *)buf = htobl(seq++); + *(uint32_t *)buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); + seq++; if (send(s, buf, so.mtu, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", -- cgit From 1d3715db11f573060cb02a2b7b7c44f06607d337 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:04:35 +0000 Subject: Update BlueZ library configuration --- test/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index ec6b7779..79386603 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,4 +4,8 @@ noinst_PROGRAMS = l2test scotest rctest attest hstest +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + EXTRA_DIST = hsplay hsmicro -- 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/attest.c | 41 ++++++++++++++++++++++------------------- test/hstest.c | 38 +++++++++++++++++++------------------- test/l2test.c | 55 +++++++++++++++++++++++++++++++------------------------ test/rctest.c | 52 ++++++++++++++++++++++++++++++---------------------- test/scotest.c | 54 ++++++++++++++++++++++++++++++------------------------ 5 files changed, 132 insertions(+), 108 deletions(-) (limited to 'test') diff --git a/test/attest.c b/test/attest.c index 078bb886..f4732cb6 100644 --- a/test/attest.c +++ b/test/attest.c @@ -1,26 +1,35 @@ /* * - * Programm for testing AT commands over Bluetooth RFCOMM + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2002 Marcel Holtmann + * Copyright (C) 2001-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 as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * 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. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 @@ -35,8 +44,6 @@ #include #include - - static int at_command(int fd, char *cmd, int to) { fd_set rfds; @@ -76,7 +83,6 @@ static int at_command(int fd, char *cmd, int to) return 0; } - static int open_device(char *device) { int fd; @@ -96,7 +102,6 @@ static int open_device(char *device) return fd; } - static int open_socket(bdaddr_t *bdaddr, uint8_t channel) { struct sockaddr_rc remote_addr, local_addr; @@ -105,7 +110,7 @@ static int open_socket(bdaddr_t *bdaddr, uint8_t channel) if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { printf("Can't create socket. %s (%d)\n", strerror(errno), errno); return -1; - } + } memset(&local_addr, 0, sizeof(local_addr)); local_addr.rc_family = AF_BLUETOOTH; @@ -129,13 +134,11 @@ static int open_socket(bdaddr_t *bdaddr, uint8_t channel) return s; } - static void usage(void) { printf("Usage:\n\tattest | [channel]\n"); } - int main(int argc, char *argv[]) { int fd; diff --git a/test/hstest.c b/test/hstest.c index 23bbf089..1272cd01 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -1,25 +1,35 @@ /* * - * Bluetooth Headset Test utility + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002 Marcel Holtmann + * 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; * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * 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. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 @@ -38,14 +48,12 @@ #include #include - static volatile int terminate = 0; static void sig_term(int sig) { terminate = 1; } - static int rfcomm_connect(bdaddr_t *src, bdaddr_t *dst, uint8_t channel) { struct sockaddr_rc addr; @@ -124,7 +132,6 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t return s; } - static void usage(void) { printf("Usage:\n" @@ -154,7 +161,6 @@ int main(int argc, char *argv[]) int dd, rd, sd, fd; uint16_t sco_handle, sco_mtu, vs; - switch (argc) { case 4: str2ba(argv[3], &bdaddr); @@ -182,7 +188,6 @@ int main(int argc, char *argv[]) filename = argv[2]; - hci_devba(0, &local); dd = hci_open_dev(0); hci_read_voice_setting(dd, &vs, 1000); @@ -194,7 +199,6 @@ int main(int argc, char *argv[]) return -1; } - if (strcmp(filename, "-") == 0) { switch (mode) { case PLAY: @@ -213,7 +217,6 @@ int main(int argc, char *argv[]) } } - memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sig_term; @@ -224,7 +227,6 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - if ((rd = rfcomm_connect(&local, &bdaddr, channel)) < 0) { perror("Can't connect RFCOMM channel"); return -1; @@ -232,7 +234,6 @@ int main(int argc, char *argv[]) fprintf(stderr, "RFCOMM channel connected\n"); - if ((sd = sco_connect(&local, &bdaddr, &sco_handle, &sco_mtu)) < 0) { perror("Can't connect SCO audio channel"); close(rd); @@ -240,7 +241,6 @@ int main(int argc, char *argv[]) } fprintf(stderr, "SCO audio channel connected (handle %d, mtu %d)\n", sco_handle, sco_mtu); - if (mode == RECORD) write(rd, "RING\r\n", 6); 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 diff --git a/test/rctest.c b/test/rctest.c index 3d50ba95..4dcd4f3c 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -1,28 +1,36 @@ -/* - RFCOMM test tool - Copyright (C) 2002 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) 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 diff --git a/test/scotest.c b/test/scotest.c index 0c8d8da3..d245b9c0 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -1,30 +1,36 @@ -/* - 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) 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 7ac6ede99ac309c7e28f3c2993fbc9bbbe28a68b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 May 2004 10:39:50 +0000 Subject: Use LIBS instead of LDFLAGS --- test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 79386603..8c105565 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,7 @@ noinst_PROGRAMS = l2test scotest rctest attest hstest -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ -- cgit From 43f017c9527dd4f64670831114f3c85f5defebbd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:05:27 +0000 Subject: Use AM_CFLAGS instead of INCLUDES --- test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 8c105565..761df0a5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,6 +6,6 @@ noinst_PROGRAMS = l2test scotest rctest attest hstest LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ EXTRA_DIST = hsplay hsmicro -- cgit From 15c1cf1ca0d2fc45dff471d71339db49deecd1cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:20:28 +0000 Subject: Make use of MAINTAINERCLEANFILES --- test/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 761df0a5..5b3f1ff3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -9,3 +9,5 @@ LIBS = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ EXTRA_DIST = hsplay hsmicro + +MAINTAINERCLEANFILES = Makefile.in -- cgit From c37be1ab2480c43fdaec098f75ec5e25a65ceb59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 13:01:42 +0000 Subject: Make more parts optional --- test/Makefile.am | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 5b3f1ff3..5b05c43d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,11 +2,15 @@ # $Id$ # -noinst_PROGRAMS = l2test scotest rctest attest hstest +if TEST +bin_PROGRAMS = l2test rctest -LIBS = @BLUEZ_LIBS@ +noinst_PROGRAMS = scotest attest hstest + +LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ +endif EXTRA_DIST = hsplay hsmicro -- cgit From 67f9a013ade0649d032b9b25e694567a089237d1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 30 Aug 2004 16:04:41 +0000 Subject: Fragment SCO payload that is greater than the SCO MTU --- test/hstest.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/hstest.c b/test/hstest.c index 1272cd01..98428b68 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) fd_set rfds; struct timeval timeout; - unsigned char buf[2048]; + unsigned char buf[2048], *p; int maxfd, sel, rlen, wlen; bdaddr_t local; @@ -274,7 +274,15 @@ int main(int argc, char *argv[]) switch (mode) { case PLAY: rlen = read(fd, buf, rlen); - wlen = write(sd, buf, rlen); + + wlen = 0; + p = buf; + while (rlen > sco_mtu) { + wlen += write(sd, p, sco_mtu); + rlen -= sco_mtu; + p += sco_mtu; + } + wlen += write(sd, p, rlen); break; case RECORD: wlen = write(fd, buf, rlen); -- cgit From e4f0eb0611d76862fecf7053ce55d423409d2ef3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Oct 2004 02:49:27 +0000 Subject: Add support for setting link mode --- test/rctest.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/rctest.c b/test/rctest.c index 4dcd4f3c..5fb5075c 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -150,23 +150,21 @@ void do_listen( void (*handler)(int sk) ) exit(1); } -#if 0 /* Set link mode */ opt = 0; if (master) - opt |= L2CAP_LM_MASTER; + opt |= RFCOMM_LM_MASTER; if (auth) - opt |= L2CAP_LM_AUTH; + opt |= RFCOMM_LM_AUTH; if (encrypt) - opt |= L2CAP_LM_ENCRYPT; + opt |= RFCOMM_LM_ENCRYPT; - if (setsockopt(s, SOL_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { + if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); exit(1); } -#endif if( listen(s, 10) ) { syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); -- cgit From b80620ee96d7ed8c13fdd1331af16856f4e4e135 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Oct 2004 04:01:48 +0000 Subject: Correct typo in help information --- test/rctest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/rctest.c b/test/rctest.c index 5fb5075c..31ecae57 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -347,7 +347,7 @@ void usage(void) "\t[-I imtu] [-O omtu]\n" "\t[-L seconds] enabled SO_LINGER option\n" "\t[-N num] number of frames to send\n" - "\t[-E] request encryption\n" + "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); } -- 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 +++++++++++++++++++++++----------- test/rctest.c | 45 ++++++++++++++++++++++----------------------- 2 files changed, 45 insertions(+), 34 deletions(-) (limited to 'test') 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; diff --git a/test/rctest.c b/test/rctest.c index 31ecae57..6e5fba27 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -49,6 +49,8 @@ #include #include +#include +#include #include /* Test modes */ @@ -65,10 +67,6 @@ enum { unsigned char *buf; -/* Default mtu */ -int imtu = 672; -int omtu = 0; - /* Default data size */ long data_size = 127; long num_frames = -1; @@ -80,6 +78,7 @@ uint8_t channel = 10; int master = 0; int auth = 0; int encrypt = 0; +int secure = 0; int socktype = SOCK_STREAM; int linger = 0; @@ -153,13 +152,13 @@ void do_listen( void (*handler)(int sk) ) /* Set link mode */ opt = 0; if (master) - opt |= RFCOMM_LM_MASTER; - + opt |= RFCOMM_LM_MASTER; if (auth) - opt |= RFCOMM_LM_AUTH; - + opt |= RFCOMM_LM_AUTH; if (encrypt) - opt |= RFCOMM_LM_ENCRYPT; + opt |= RFCOMM_LM_ENCRYPT; + if (secure) + opt |= RFCOMM_LM_SECURE; if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); @@ -343,8 +342,7 @@ void usage(void) "\t-m multiple connects\n"); printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P channel]\n" - "\t[-I imtu] [-O omtu]\n" + "\t[-b bytes] [-i device] [-P channel]\n" "\t[-L seconds] enabled SO_LINGER option\n" "\t[-N num] number of frames to send\n" "\t[-A] request authentication\n" @@ -361,8 +359,10 @@ int main(int argc ,char *argv[]) struct sigaction sa; mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAEL:N:")) != EOF) { + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:N:MAESL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -405,22 +405,17 @@ int main(int argc ,char *argv[]) data_size = atoi(optarg); 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': channel = atoi(optarg); break; - case 'I': - imtu = atoi(optarg); - break; - - case 'O': - omtu = atoi(optarg); - break; - case 'M': master = 1; break; @@ -433,6 +428,10 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'S': + secure = 1; + break; + case 'L': linger = atoi(optarg); 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/hstest.c | 6 ++++++ test/l2test.c | 2 ++ 2 files changed, 8 insertions(+) (limited to 'test') diff --git a/test/hstest.c b/test/hstest.c index 98428b68..f269621c 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -98,6 +98,7 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, src); + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { close(s); return -1; @@ -106,18 +107,23 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, dst); + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ close(s); return -1; } + memset(&conn, 0, sizeof(conn)); size = sizeof(conn); + if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &size) < 0) { close(s); return -1; } + memset(&opts, 0, sizeof(opts)); size = sizeof(opts); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &opts, &size) < 0) { close(s); return -1; 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 +++++++++++-- test/rctest.c | 15 +++++++++++-- test/scotest.c | 66 ++++++++++++++++++++++++++++++++++------------------------ 3 files changed, 64 insertions(+), 31 deletions(-) (limited to 'test') 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; } diff --git a/test/rctest.c b/test/rctest.c index 6e5fba27..2ffb47dd 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -90,7 +90,8 @@ float tv2fl(struct timeval tv) int do_connect(char *svr) { struct sockaddr_rc rem_addr, loc_addr; - int s; + struct rfcomm_conninfo conn; + int s, opt; if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); @@ -125,7 +126,17 @@ int do_connect(char *svr) return -1; } - syslog(LOG_INFO, "Connected"); + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s, SOL_L2CAP, RFCOMM_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get RFCOMM connection information. %s(%d)", strerror(errno), errno); + close(s); + //return -1; + } + + syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", + conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); return s; } diff --git a/test/scotest.c b/test/scotest.c index d245b9c0..0c1ec130 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -60,22 +60,23 @@ enum { DUMP }; -unsigned char *buf; +static unsigned char *buf; /* Default data size */ -long data_size = 672; +static long data_size = 672; -bdaddr_t bdaddr; +static bdaddr_t bdaddr; -float tv2fl(struct timeval tv) +static float tv2fl(struct timeval tv) { return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } -int do_connect(char *svr) +static int do_connect(char *svr) { struct sockaddr_sco rem_addr, loc_addr; - int s; + struct sco_conninfo conn; + int s, opt; if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); @@ -98,43 +99,53 @@ int do_connect(char *svr) return -1; } - syslog(LOG_INFO, "Connected\n"); + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s, SOL_L2CAP, SCO_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get SCO connection information. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", + conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); return s; } -void do_listen( void (*handler)(int sk) ) +static void do_listen(void (*handler)(int sk)) { struct sockaddr_sco loc_addr, rem_addr; int s, s1, opt; bdaddr_t ba; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } loc_addr.sco_family = AF_BLUETOOTH; loc_addr.sco_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); } - if( listen(s, 10) ) { + 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 ..."); - while(1) { + 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); } - if( fork() ) { + if (fork()) { /* Parent */ close(s1); continue; @@ -153,7 +164,7 @@ void do_listen( void (*handler)(int sk) ) } } -void dump_mode(int s) +static void dump_mode(int s) { int len; @@ -162,7 +173,7 @@ void dump_mode(int s) syslog(LOG_INFO, "Recevied %d bytes\n", len); } -void recv_mode(int s) +static void recv_mode(int s) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -194,7 +205,7 @@ void recv_mode(int s) } } -void send_mode(char *svr) +static void send_mode(char *svr) { struct sco_options so; uint32_t seq; @@ -216,7 +227,7 @@ void send_mode(char *svr) syslog(LOG_INFO,"Sending ..."); - for (i=6; i < so.mtu; i++) + for (i = 6; i < so.mtu; i++) buf[i]=0x7f; seq = 0; @@ -234,11 +245,11 @@ void send_mode(char *svr) } } -void reconnect_mode(char *svr) +static void reconnect_mode(char *svr) { - while(1){ + while (1) { int s; - if( (s = do_connect(svr)) < 0 ){ + if ((s = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); exit(1); } @@ -248,15 +259,16 @@ void reconnect_mode(char *svr) } } -void multy_connect_mode(char *svr) +static void multy_connect_mode(char *svr) { - while(1){ + while (1) { int i, s; - for(i=0; i<10; i++){ - if( fork() ) continue; + for (i = 0; i < 10; i++){ + if (fork()) + continue; /* Child */ - if( (s = do_connect(svr)) < 0 ){ + if ((s = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); } close(s); @@ -266,7 +278,7 @@ void multy_connect_mode(char *svr) } } -void usage(void) +static void usage(void) { printf("scotest - SCO testing\n" "Usage:\n"); -- cgit From 95cd931b918a07fcf12e48dce9665f3c90ab4130 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 29 Dec 2004 19:32:16 +0000 Subject: Fix typos --- test/rctest.c | 4 ++-- test/scotest.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/rctest.c b/test/rctest.c index 2ffb47dd..31d2be0f 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -128,7 +128,7 @@ int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); - if (getsockopt(s, SOL_L2CAP, RFCOMM_CONNINFO, &conn, &opt) < 0) { + if (getsockopt(s, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &opt) < 0) { syslog(LOG_ERR, "Can't get RFCOMM connection information. %s(%d)", strerror(errno), errno); close(s); //return -1; @@ -172,7 +172,7 @@ void do_listen( void (*handler)(int sk) ) opt |= RFCOMM_LM_SECURE; if (setsockopt(s, SOL_RFCOMM, RFCOMM_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 RFCOMM link mode. %s(%d)", strerror(errno), errno); exit(1); } diff --git a/test/scotest.c b/test/scotest.c index 0c1ec130..eddd79af 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -101,7 +101,7 @@ static int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); - if (getsockopt(s, SOL_L2CAP, SCO_CONNINFO, &conn, &opt) < 0) { + if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &opt) < 0) { syslog(LOG_ERR, "Can't get SCO connection information. %s(%d)", strerror(errno), errno); close(s); return -1; -- 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 ++++++++++++++++++++++++++++------------------------------ test/rctest.c | 94 ++++++++++++++++++++++++------------------------ 2 files changed, 100 insertions(+), 106 deletions(-) (limited to 'test') 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(); diff --git a/test/rctest.c b/test/rctest.c index 31d2be0f..041e36b3 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -65,35 +65,35 @@ enum { LSEND }; -unsigned char *buf; +static unsigned char *buf; /* Default data size */ -long data_size = 127; -long num_frames = -1; +static long data_size = 127; +static long num_frames = -1; /* Default addr and channel */ -bdaddr_t bdaddr; -uint8_t channel = 10; +static bdaddr_t bdaddr; +static uint8_t channel = 10; -int master = 0; -int auth = 0; -int encrypt = 0; -int secure = 0; -int socktype = SOCK_STREAM; -int linger = 0; +static int master = 0; +static int auth = 0; +static int encrypt = 0; +static int secure = 0; +static int socktype = SOCK_STREAM; +static int linger = 0; -float tv2fl(struct timeval tv) +static float tv2fl(struct timeval tv) { return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } -int do_connect(char *svr) +static int do_connect(char *svr) { struct sockaddr_rc rem_addr, loc_addr; struct rfcomm_conninfo conn; int s, opt; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); return -1; } @@ -110,17 +110,17 @@ int do_connect(char *svr) memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + bacpy(&loc_addr.rc_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); } memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.rc_family = AF_BLUETOOTH; - baswap(&rem_addr.rc_bdaddr, strtoba(svr)); + str2ba(svr, &rem_addr.rc_bdaddr); rem_addr.rc_channel = channel; - 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; @@ -141,21 +141,21 @@ int do_connect(char *svr) return s; } -void do_listen( void (*handler)(int sk) ) +static void do_listen(void (*handler)(int sk)) { struct sockaddr_rc loc_addr, rem_addr; - int s, s1, opt; - bdaddr_t ba; + int s, s1, opt; + char ba[18]; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; + bacpy(&loc_addr.rc_bdaddr, &bdaddr); loc_addr.rc_channel = channel; - 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); } @@ -176,7 +176,7 @@ void do_listen( void (*handler)(int sk) ) exit(1); } - if( listen(s, 10) ) { + if (listen(s, 10)) { syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -185,11 +185,11 @@ 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); } - if( fork() ) { + if (fork()) { /* Parent */ close(s1); continue; @@ -198,8 +198,8 @@ void do_listen( void (*handler)(int sk) ) close(s); - baswap(&ba, &rem_addr.rc_bdaddr); - syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + ba2str(&rem_addr.rc_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s", ba); /* Enable SO_LINGER */ if (linger) { @@ -213,21 +213,21 @@ void do_listen( void (*handler)(int sk) ) handler(s1); - syslog(LOG_INFO, "Disconnect\n"); + syslog(LOG_INFO, "Disconnect"); exit(0); } } -void dump_mode(int s) +static 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); + syslog(LOG_INFO, "Recevied %d bytes", len); } -void recv_mode(int s) +static void recv_mode(int s) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -279,11 +279,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; @@ -312,7 +312,7 @@ void send_mode(int s) syslog(LOG_INFO, "Done"); } -void reconnect_mode(char *svr) +static void reconnect_mode(char *svr) { while(1) { int s = do_connect(svr); @@ -320,11 +320,11 @@ void reconnect_mode(char *svr) } } -void multi_connect_mode(char *svr) +static 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 */ @@ -337,7 +337,7 @@ void multi_connect_mode(char *svr) } } -void usage(void) +static void usage(void) { printf("rctest - RFCOMM testing\n" "Usage:\n"); @@ -354,16 +354,13 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-i device] [-P channel]\n" - "\t[-L seconds] enabled SO_LINGER option\n" - "\t[-N num] number of frames to send\n" + "\t[-L seconds] enabled SO_LINGER option\n" + "\t[-N num] number of frames to send\n" "\t[-A] request authentication\n" "\t[-E] request encryption\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; @@ -374,11 +371,11 @@ int main(int argc ,char *argv[]) bacpy(&bdaddr, BDADDR_ANY); while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:N:MAESL:")) != EOF) { - switch(opt) { + switch (opt) { case 'r': mode = RECV; break; - + case 's': mode = SEND; need_addr = 1; @@ -474,7 +471,7 @@ int main(int argc ,char *argv[]) openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); - switch( mode ){ + switch (mode) { case RECV: do_listen(recv_mode); break; @@ -516,6 +513,7 @@ int main(int argc ,char *argv[]) dump_mode(s); break; } + syslog(LOG_INFO, "Exit"); closelog(); -- cgit From 7477c4f629682f6d1815a8e79250615533bad9ca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 13:46:40 +0000 Subject: Add tool for changing the device address --- test/Makefile.am | 2 +- test/bdaddr.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 test/bdaddr.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 5b05c43d..7bfb74c3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -5,7 +5,7 @@ if TEST bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = scotest attest hstest +noinst_PROGRAMS = scotest attest hstest bdaddr LDADD = @BLUEZ_LIBS@ diff --git a/test/bdaddr.c b/test/bdaddr.c new file mode 100644 index 00000000..d674c3de --- /dev/null +++ b/test/bdaddr.c @@ -0,0 +1,254 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 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 +#include +#include +#include + +#include +#include +#include + +#define OCF_ERICSSON_WRITE_BD_ADDR 0x000d +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) ericsson_write_bd_addr_cp; +#define ERICSSON_WRITE_BD_ADDR_CP_SIZE 6 + +static int ericsson_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + struct hci_request rq; + ericsson_write_bd_addr_cp cp; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ERICSSON_WRITE_BD_ADDR; + rq.cparam = &cp; + rq.clen = ERICSSON_WRITE_BD_ADDR_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + +#if 0 +#define OCF_ERICSSON_STORE_IN_FLASH 0x0022 +typedef struct { + uint8_t user_id; + uint8_t flash_length; + uint8_t flash_data[253]; +} __attribute__ ((packed)) ericsson_store_in_flash_cp; +#define ERICSSON_STORE_IN_FLASH_CP_SIZE 255 + +static int ericsson_store_in_flash(int dd, uint8_t user_id, uint8_t flash_length, uint8_t *flash_data) +{ + struct hci_request rq; + ericsson_store_in_flash_cp cp; + + memset(&cp, 0, sizeof(cp)); + cp.user_id = user_id; + cp.flash_length = flash_length; + if (flash_length > 0) + memcpy(cp.flash_data, flash_data, flash_length); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ERICSSON_STORE_IN_FLASH; + rq.cparam = &cp; + rq.clen = ERICSSON_STORE_IN_FLASH_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} +#endif + +#define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) zeevo_write_bd_addr_cp; +#define ZEEVO_WRITE_BD_ADDR_CP_SIZE 6 + +static int zeevo_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + struct hci_request rq; + zeevo_write_bd_addr_cp cp; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ZEEVO_WRITE_BD_ADDR; + rq.cparam = &cp; + rq.clen = ZEEVO_WRITE_BD_ADDR_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + +static struct { + uint16_t compid; + int (*func)(int dd, bdaddr_t *bdaddr); +} vendor[] = { + { 0, ericsson_write_bd_addr }, + { 18, zeevo_write_bd_addr }, + { 65535, NULL }, +}; + +static void usage(void) +{ + printf("bdaddr - Utility for changing the Bluetooth device address\n\n"); + printf("Usage:\n" + "\tbdaddr [-i ] [new bdaddr]\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0} +}; + +int main(int argc, char *argv[]) +{ + struct hci_dev_info di; + struct hci_version ver; + bdaddr_t bdaddr; + char addr[18]; + int i, dd, opt, dev = 0; + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + di.dev_id = dev; + if (ioctl(dd, HCIGETDEVINFO, (void *) &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + printf("Manufacturer: %s (%d)\n", + bt_compidtostr(ver.manufacturer), ver.manufacturer); + + ba2str(&di.bdaddr, addr); + printf("Device address: %s\n", addr); + + if (argc < 1) { + hci_close_dev(dd); + exit(0); + } + + str2ba(argv[0], &bdaddr); + if (!bacmp(&bdaddr, BDADDR_ANY)) { + hci_close_dev(dd); + exit(0); + } + + for (i = 0; vendor[i].compid != 65535; i++) + if (ver.manufacturer == vendor[i].compid) { + ba2str(&bdaddr, addr); + printf("New BD address: %s\n\n", addr); + + if (vendor[i].func(dd, &bdaddr) < 0) { + fprintf(stderr, "Can't write new address"); + hci_close_dev(dd); + exit(1); + } + + printf("Address changed - Reset device now\n"); + + //ioctl(dd, HCIDEVRESET, dev); + //ioctl(dd, HCIDEVDOWN, dev); + //ioctl(dd, HCIDEVUP, dev); + + hci_close_dev(dd); + exit(0); + } + + hci_close_dev(dd); + + printf("\n"); + fprintf(stderr, "Unsupported manufacturer\n"); + + exit(1); +} -- 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 +++++++++++++++++++++++++++------------------------------- test/rctest.c | 59 ++++++++++++++------------------ 2 files changed, 75 insertions(+), 90 deletions(-) (limited to 'test') 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); } } diff --git a/test/rctest.c b/test/rctest.c index 041e36b3..d3995335 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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 @@ -32,20 +32,13 @@ #endif #include -#include -#include -#include -#include +#include +#include #include +#include #include -#include -#include #include - -#include -#include -#include -#include +#include #include #include @@ -94,7 +87,7 @@ static int do_connect(char *svr) int s, opt; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 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; } @@ -102,7 +95,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; } @@ -112,7 +105,7 @@ static int do_connect(char *svr) loc_addr.rc_family = AF_BLUETOOTH; bacpy(&loc_addr.rc_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); } @@ -121,7 +114,7 @@ static int do_connect(char *svr) str2ba(svr, &rem_addr.rc_bdaddr); rem_addr.rc_channel = channel; 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; } @@ -129,7 +122,7 @@ static int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); if (getsockopt(s, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get RFCOMM connection information. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", strerror(errno), errno); close(s); //return -1; } @@ -148,7 +141,7 @@ static void do_listen(void (*handler)(int sk)) char ba[18]; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 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); } @@ -156,7 +149,7 @@ static void do_listen(void (*handler)(int sk)) bacpy(&loc_addr.rc_bdaddr, &bdaddr); loc_addr.rc_channel = channel; 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); } @@ -172,12 +165,12 @@ static void do_listen(void (*handler)(int sk)) opt |= RFCOMM_LM_SECURE; if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set RFCOMM link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", strerror(errno), errno); exit(1); } 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); } @@ -186,7 +179,7 @@ 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()) { @@ -205,7 +198,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); } @@ -213,7 +206,7 @@ static void do_listen(void (*handler)(int sk)) handler(s1); - syslog(LOG_INFO, "Disconnect"); + syslog(LOG_INFO, "Disconnect: %m"); exit(0); } } @@ -246,13 +239,13 @@ static void recv_mode(int s) if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); return; } #if 0 /* 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; @@ -260,14 +253,14 @@ 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]); } @@ -290,24 +283,24 @@ static 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)) { *(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"); } -- cgit From 0197e2d62cac9323387d52b5711d3c564303d949 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 Jan 2005 20:26:52 +0000 Subject: Whitespace cleanups --- test/scotest.c | 102 ++++++++++++++++++++++++++------------------------------- 1 file changed, 47 insertions(+), 55 deletions(-) (limited to 'test') diff --git a/test/scotest.c b/test/scotest.c index eddd79af..583310a0 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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 @@ -32,20 +32,13 @@ #endif #include -#include -#include -#include -#include +#include +#include #include +#include #include -#include -#include #include - -#include -#include -#include -#include +#include #include #include @@ -78,31 +71,31 @@ static int do_connect(char *svr) struct sco_conninfo conn; int s, opt; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); return -1; } memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_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); + bacpy(&loc_addr.sco_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); } memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.sco_family = AF_BLUETOOTH; - baswap(&rem_addr.sco_bdaddr, strtoba(svr)); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + str2ba(svr, &rem_addr.sco_bdaddr); + if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); return -1; } memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO connection information. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -118,22 +111,22 @@ static void do_listen(void (*handler)(int sk)) { struct sockaddr_sco loc_addr, rem_addr; int s, s1, opt; - bdaddr_t ba; + char ba[18]; if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 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.sco_family = AF_BLUETOOTH; loc_addr.sco_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); } 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); } @@ -141,8 +134,8 @@ 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); + if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { + syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); exit(1); } if (fork()) { @@ -154,12 +147,12 @@ static void do_listen(void (*handler)(int sk)) close(s); - baswap(&ba, &rem_addr.sco_bdaddr); - syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); + ba2str(&rem_addr.sco_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s", ba); handler(s1); - syslog(LOG_INFO, "Disconnect\n"); + syslog(LOG_INFO, "Disconnect"); exit(0); } } @@ -183,25 +176,25 @@ static void recv_mode(int s) seq = 0; while (1) { - gettimeofday(&tv_beg,NULL); + gettimeofday(&tv_beg, NULL); total = 0; while (total < data_size) { int r; if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); return; } 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 %.2fm speed %.2f kb",total, - tv2fl(tv_diff) / 60.0, - (float)( total / tv2fl(tv_diff) ) / 1024.0 ); + syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb", total, + tv2fl(tv_diff) / 60.0, + (float)( total / tv2fl(tv_diff) ) / 1024.0 ); } } @@ -212,33 +205,32 @@ static void send_mode(char *svr) int s, i, opt; if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't connect to the server: %s (%d)", + strerror(errno), errno); exit(1); } opt = sizeof(so); if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO options. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't get SCO options: %s (%d)", + strerror(errno), errno); exit(1); } - syslog(LOG_INFO,"Sending ..."); for (i = 6; i < so.mtu; i++) - buf[i]=0x7f; + buf[i] = 0x7f; seq = 0; while (1) { - *(uint32_t *)buf = htobl(seq); - *(uint16_t *)(buf+4) = htobs(data_size); + *(uint32_t *) buf = htobl(seq); + *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - + if (send(s, buf, so.mtu, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", + strerror(errno), errno); exit(1); } usleep(1); @@ -250,7 +242,8 @@ static void reconnect_mode(char *svr) while (1) { int s; if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't connect to the server: %s (%d)", + strerror(errno), errno); exit(1); } close(s); @@ -269,7 +262,8 @@ static void multy_connect_mode(char *svr) /* Child */ if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't connect to the server: %s (%d)", + strerror(errno), errno); } close(s); exit(0); @@ -291,9 +285,6 @@ static void usage(void) "\t-s send (client)\n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc ,char *argv[]) { struct sigaction sa; @@ -304,7 +295,7 @@ int main(int argc ,char *argv[]) case 'r': mode = RECV; break; - + case 's': mode = SEND; break; @@ -331,7 +322,7 @@ int main(int argc ,char *argv[]) } } - if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + if (!(argc - optind) && (mode != RECV && mode != DUMP)) { usage(); exit(1); } @@ -369,6 +360,7 @@ int main(int argc ,char *argv[]) multy_connect_mode(argv[optind]); break; } + syslog(LOG_INFO, "Exit"); closelog(); -- cgit From 9f859424c471dc8e52a1fa3873ab627966d80316 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Jan 2005 04:11:29 +0000 Subject: Update usage information --- test/rctest.c | 1 + 1 file changed, 1 insertion(+) (limited to 'test') diff --git a/test/rctest.c b/test/rctest.c index d3995335..b7916a34 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -351,6 +351,7 @@ static void usage(void) "\t[-N num] number of frames to send\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" + "\t[-S] secure connection\n" "\t[-M] become master\n"); } -- 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 +- test/rctest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test') 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); } diff --git a/test/rctest.c b/test/rctest.c index b7916a34..8298ab07 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -164,7 +164,7 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= RFCOMM_LM_SECURE; - if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { + if (opt && setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set RFCOMM 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') 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') 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') 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') 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') 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') 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 d23d9a99e234590f4edf5bafcf57b3e99c57c354 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:14:08 +0000 Subject: Cleanup the socket handling --- test/rctest.c | 214 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 133 insertions(+), 81 deletions(-) (limited to 'test') diff --git a/test/rctest.c b/test/rctest.c index 8298ab07..06ccf6ec 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -82,75 +82,99 @@ static float tv2fl(struct timeval tv) static int do_connect(char *svr) { - struct sockaddr_rc rem_addr, loc_addr; + struct sockaddr_rc addr; struct rfcomm_conninfo conn; - int s, opt; + socklen_t optlen; + int sk; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); 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) { + + 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; + strerror(errno), errno); + goto error; } } - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.rc_family = AF_BLUETOOTH; - bacpy(&loc_addr.rc_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.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_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; } - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.rc_family = AF_BLUETOOTH; - str2ba(svr, &rem_addr.rc_bdaddr); - rem_addr.rc_channel = channel; - 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.rc_family = AF_BLUETOOTH; + str2ba(svr, &addr.rc_bdaddr); + addr.rc_channel = channel; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", strerror(errno), errno); - close(s); - //return -1; + optlen = sizeof(conn); + + if (getsockopt(sk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", + strerror(errno), errno); + //goto error; } syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", 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_rc loc_addr, rem_addr; - int s, s1, opt; + struct sockaddr_rc addr; + struct rfcomm_conninfo conn; + socklen_t optlen; + int sk, nsk, opt; char ba[18]; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); exit(1); } - loc_addr.rc_family = AF_BLUETOOTH; - bacpy(&loc_addr.rc_bdaddr, &bdaddr); - loc_addr.rc_channel = channel; - 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.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, &bdaddr); + addr.rc_channel = channel; + + 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 */ @@ -164,63 +188,90 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= RFCOMM_LM_SECURE; - if (opt && setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", strerror(errno), errno); - exit(1); + if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", + strerror(errno), errno); + goto error; } - 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 channel %d ...", channel); 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); + + /* Get connection information */ + memset(&conn, 0, sizeof(conn)); + optlen = sizeof(conn); - close(s); + if (getsockopt(nsk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", + strerror(errno), errno); + //close(nsk); + //goto error; + } - ba2str(&rem_addr.rc_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s", ba); + ba2str(&addr.rc_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s [handle %d, class 0x%02x%02x%02x]", + ba, 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; syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) + while ((len = read(sk, buf, data_size)) > 0) syslog(LOG_INFO, "Recevied %d bytes", len); } -static void recv_mode(int s) +static void recv_mode(int sk) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -237,7 +288,7 @@ static void recv_mode(int s) //uint16_t l; int r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { + if ((r = recv(sk, buf, data_size, 0)) <= 0) { if (r < 0) syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); @@ -271,12 +322,12 @@ static void recv_mode(int s) 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); } } -static void send_mode(int s) +static void send_mode(int sk) { uint32_t seq; int i; @@ -292,14 +343,15 @@ static void send_mode(int s) *(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); + 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"); @@ -308,24 +360,26 @@ static void send_mode(int s) static void reconnect_mode(char *svr) { while(1) { - int s = do_connect(svr); - close(s); + int sk = do_connect(svr); + close(sk); } } static void multi_connect_mode(char *svr) { while (1) { - int i, s; + int i, sk; + for (i = 0; i < 10; i++) { if (fork()) continue; /* Child */ - s = do_connect(svr); + sk = do_connect(svr); usleep(500); - close(s); + close(sk); exit(0); } + sleep(2); } } @@ -357,10 +411,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); @@ -471,10 +523,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: @@ -482,10 +534,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: @@ -501,10 +553,10 @@ int main(int argc ,char *argv[]) break; case CONNECT: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - dump_mode(s); + dump_mode(sk); break; } -- cgit From 96bbfb2039b98046fe72c88dc6f737a66ed65fde Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:26:31 +0000 Subject: Cleanup the socket handling --- test/attest.c | 55 +++++++++-------- test/scotest.c | 183 +++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 150 insertions(+), 88 deletions(-) (limited to 'test') diff --git a/test/attest.c b/test/attest.c index f4732cb6..cd0e93ca 100644 --- a/test/attest.c +++ b/test/attest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2004 Marcel Holtmann + * Copyright (C) 2001-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,11 +33,10 @@ #include #include #include +#include #include #include -#include #include -#include #include #include @@ -85,11 +84,13 @@ static int at_command(int fd, char *cmd, int to) static int open_device(char *device) { - int fd; struct termios ti; + int fd; - if ((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { - printf("Can't open serial port. %s (%d)\n", strerror(errno), errno); + fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (fd < 0) { + fprintf(stderr, "Can't open serial port: %s (%d)\n", + strerror(errno), errno); return -1; } @@ -104,34 +105,40 @@ static int open_device(char *device) static int open_socket(bdaddr_t *bdaddr, uint8_t channel) { - struct sockaddr_rc remote_addr, local_addr; - int s; + struct sockaddr_rc addr; + int sk; - if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { - printf("Can't create socket. %s (%d)\n", strerror(errno), errno); + sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sk < 0) { + fprintf(stderr, "Can't create socket: %s (%d)\n", + strerror(errno), errno); return -1; } - memset(&local_addr, 0, sizeof(local_addr)); - local_addr.rc_family = AF_BLUETOOTH; - bacpy(&local_addr.rc_bdaddr, BDADDR_ANY); - if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { - printf("Can't bind socket. %s (%d)\n", strerror(errno), errno); - close(s); + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, BDADDR_ANY); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't bind socket: %s (%d)\n", + strerror(errno), errno); + close(sk); return -1; } - memset(&remote_addr, 0, sizeof(remote_addr)); - remote_addr.rc_family = AF_BLUETOOTH; - bacpy(&remote_addr.rc_bdaddr, bdaddr); - remote_addr.rc_channel = channel; - if (connect(s, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) { - printf("Can't connect. %s (%d)\n", strerror(errno), errno); - close(s); + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, bdaddr); + addr.rc_channel = channel; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't connect: %s (%d)\n", + strerror(errno), errno); + close(sk); return -1; } - return s; + return sk; } static void usage(void) diff --git a/test/scotest.c b/test/scotest.c index 583310a0..59278460 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -67,106 +67,155 @@ static float tv2fl(struct timeval tv) static int do_connect(char *svr) { - struct sockaddr_sco rem_addr, loc_addr; + struct sockaddr_sco addr; struct sco_conninfo conn; - int s, opt; + socklen_t optlen; + int sk; - if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); + 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.sco_family = AF_BLUETOOTH; - bacpy(&loc_addr.sco_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.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_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; } - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.sco_family = AF_BLUETOOTH; - str2ba(svr, &rem_addr.sco_bdaddr); - if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) { - syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); - return -1; + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + str2ba(svr, &addr.sco_bdaddr); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", strerror(errno), errno); - close(s); - return -1; + optlen = sizeof(conn); + + if (getsockopt(sk, SOL_SCO, SCO_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", + strerror(errno), errno); + goto error; } syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", 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_sco loc_addr, rem_addr; - int s, s1, opt; + struct sockaddr_sco addr; + struct sco_conninfo conn; + socklen_t optlen; + int sk, nsk; char ba[18]; - if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); exit(1); } - loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_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.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_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; } - 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 ..."); 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); + + /* Get connection information */ + memset(&conn, 0, sizeof(conn)); + optlen = sizeof(conn); - close(s); + if (getsockopt(nsk, SOL_SCO, SCO_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", + strerror(errno), errno); + close(nsk); + goto error; + } - ba2str(&rem_addr.sco_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s", ba); + ba2str(&addr.sco_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s [handle %d, class 0x%02x%02x%02x]", + ba, conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); - handler(s1); + handler(nsk); syslog(LOG_INFO, "Disconnect"); exit(0); } + + return; + +error: + close(sk); + exit(1); } -static void dump_mode(int s) +static void dump_mode(int sk) { int len; syslog(LOG_INFO,"Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); + while ((len = read(sk, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes", len); } -static void recv_mode(int s) +static void recv_mode(int sk) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -180,7 +229,7 @@ static void recv_mode(int s) total = 0; while (total < data_size) { int r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { + if ((r = recv(sk, buf, data_size, 0)) <= 0) { if (r < 0) syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); @@ -202,20 +251,20 @@ static void send_mode(char *svr) { struct sco_options so; uint32_t seq; - int s, i, opt; + int sk, i, opt; - if ((s = do_connect(svr)) < 0) { + if ((sk = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); } opt = sizeof(so); - if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + if (getsockopt(sk, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { syslog(LOG_ERR, "Can't get SCO options: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); - } + } syslog(LOG_INFO,"Sending ..."); @@ -228,11 +277,12 @@ static void send_mode(char *svr) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(s, buf, so.mtu, 0) <= 0) { + if (send(sk, buf, so.mtu, 0) <= 0) { syslog(LOG_ERR, "Send failed: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); } + usleep(1); } } @@ -240,13 +290,15 @@ static void send_mode(char *svr) static void reconnect_mode(char *svr) { while (1) { - int s; - if ((s = do_connect(svr)) < 0) { + int sk; + + if ((sk = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); } - close(s); + + close(sk); sleep(5); } @@ -255,19 +307,22 @@ static void reconnect_mode(char *svr) static void multy_connect_mode(char *svr) { while (1) { - int i, s; + int i, sk; + for (i = 0; i < 10; i++){ if (fork()) continue; /* Child */ - if ((s = do_connect(svr)) < 0) { + sk = do_connect(svr); + if (sk < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); } - close(s); + close(sk); exit(0); } + sleep(19); } } -- 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 + test/rctest.c | 1 + test/scotest.c | 1 + 3 files changed, 3 insertions(+) (limited to 'test') 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 diff --git a/test/rctest.c b/test/rctest.c index 06ccf6ec..8c76859f 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/test/scotest.c b/test/scotest.c index 59278460..6447eab4 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -36,6 +36,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') 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') 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 41d566d35dbc0bead25e0aeabb1bccb0d4855dfa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 13:25:21 +0000 Subject: Use hci_devinfo() instead of the ioctl() --- test/bdaddr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index d674c3de..2e2af6c7 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -151,7 +150,7 @@ static void usage(void) static struct option main_options[] = { { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, - { 0, 0, 0, 0} + { 0, 0, 0, 0 } }; int main(int argc, char *argv[]) @@ -192,8 +191,7 @@ int main(int argc, char *argv[]) exit(1); } - di.dev_id = dev; - if (ioctl(dd, HCIGETDEVINFO, (void *) &di) < 0) { + if (hci_devinfo(dev, &di) < 0) { fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); -- cgit From e9ded5ddec57defd792cb0fe7818d34c67dd6414 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 16:54:53 +0000 Subject: Support address changing for CSR chips --- test/bdaddr.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index 2e2af6c7..e1f6921a 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -103,6 +103,53 @@ static int ericsson_store_in_flash(int dd, uint8_t user_id, uint8_t flash_length } #endif +static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + cmd[16] = bdaddr->b[2]; + cmd[17] = 0x00; + cmd[18] = bdaddr->b[0]; + cmd[19] = bdaddr->b[1]; + cmd[20] = bdaddr->b[3]; + cmd[21] = 0x00; + cmd[22] = bdaddr->b[4]; + cmd[23] = bdaddr->b[5]; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} + #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 typedef struct { bdaddr_t bdaddr; @@ -136,6 +183,7 @@ static struct { int (*func)(int dd, bdaddr_t *bdaddr); } vendor[] = { { 0, ericsson_write_bd_addr }, + { 10, csr_write_bd_addr }, { 18, zeevo_write_bd_addr }, { 65535, NULL }, }; @@ -205,10 +253,20 @@ int main(int argc, char *argv[]) exit(1); } + if (!bacmp(&di.bdaddr, BDADDR_ANY)) { + if (hci_read_bd_addr(dd, &bdaddr, 1000) < 0) { + fprintf(stderr, "Can't read address for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + } else + bacpy(&bdaddr, &di.bdaddr); + printf("Manufacturer: %s (%d)\n", bt_compidtostr(ver.manufacturer), ver.manufacturer); - ba2str(&di.bdaddr, addr); + ba2str(&bdaddr, addr); printf("Device address: %s\n", addr); if (argc < 1) { @@ -228,7 +286,7 @@ int main(int argc, char *argv[]) printf("New BD address: %s\n\n", addr); if (vendor[i].func(dd, &bdaddr) < 0) { - fprintf(stderr, "Can't write new address"); + fprintf(stderr, "Can't write new address\n"); hci_close_dev(dd); exit(1); } -- cgit From adbb22a47c9356e0c191a75daec0439e8d941bd1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 21:34:08 +0000 Subject: Use LDADD instead of LIBS --- test/Makefile.am | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 7bfb74c3..bf41fb03 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -7,7 +7,17 @@ bin_PROGRAMS = l2test rctest noinst_PROGRAMS = scotest attest hstest bdaddr -LDADD = @BLUEZ_LIBS@ +l2test_LDADD = @BLUEZ_LIBS@ + +rctest_LDADD = @BLUEZ_LIBS@ + +scotest_LDADD = @BLUEZ_LIBS@ + +attest_LDADD = @BLUEZ_LIBS@ + +hstest_LDADD = @BLUEZ_LIBS@ + +bdaddr_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ endif -- 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') 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/attest.c | 2 +- test/hstest.c | 3 ++- test/l2test.c | 4 ++-- test/scotest.c | 7 ++++--- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/attest.c b/test/attest.c index cd0e93ca..6e7d3808 100644 --- a/test/attest.c +++ b/test/attest.c @@ -47,7 +47,7 @@ static int at_command(int fd, char *cmd, int to) { fd_set rfds; struct timeval timeout; - unsigned char buf[1024]; + char buf[1024]; int sel, len, i, n; write(fd, cmd, strlen(cmd)); diff --git a/test/hstest.c b/test/hstest.c index f269621c..8949be4b 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -89,7 +89,8 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t struct sockaddr_sco addr; struct sco_conninfo conn; struct sco_options opts; - int s, size; + socklen_t size; + int s; if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { return -1; 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); } } diff --git a/test/scotest.c b/test/scotest.c index 6447eab4..22a95fed 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -251,8 +251,9 @@ static void recv_mode(int sk) static void send_mode(char *svr) { struct sco_options so; + socklen_t len; uint32_t seq; - int sk, i, opt; + int i, sk; if ((sk = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", @@ -260,8 +261,8 @@ static void send_mode(char *svr) exit(1); } - opt = sizeof(so); - if (getsockopt(sk, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + len = sizeof(so); + if (getsockopt(sk, SOL_SCO, SCO_OPTIONS, &so, &len) < 0) { syslog(LOG_ERR, "Can't get SCO options: %s (%d)", strerror(errno), errno); exit(1); -- cgit From 0cc4f1817bef34823a547f21911b8b7ceb581a1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Aug 2005 14:00:29 +0000 Subject: Reset the device after changing the address --- test/bdaddr.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index e1f6921a..e34cc961 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -150,6 +151,34 @@ static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr) return 0; } +static int csr_reset_device(int dd) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + return 0; +} + #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 typedef struct { bdaddr_t bdaddr; @@ -180,12 +209,13 @@ static int zeevo_write_bd_addr(int dd, bdaddr_t *bdaddr) static struct { uint16_t compid; - int (*func)(int dd, bdaddr_t *bdaddr); + int (*write_bd_addr)(int dd, bdaddr_t *bdaddr); + int (*reset_device)(int dd); } vendor[] = { - { 0, ericsson_write_bd_addr }, - { 10, csr_write_bd_addr }, - { 18, zeevo_write_bd_addr }, - { 65535, NULL }, + { 0, ericsson_write_bd_addr, NULL }, + { 10, csr_write_bd_addr, csr_reset_device }, + { 18, zeevo_write_bd_addr, NULL }, + { 65535, NULL, NULL }, }; static void usage(void) @@ -285,13 +315,24 @@ int main(int argc, char *argv[]) ba2str(&bdaddr, addr); printf("New BD address: %s\n\n", addr); - if (vendor[i].func(dd, &bdaddr) < 0) { + if (vendor[i].write_bd_addr(dd, &bdaddr) < 0) { fprintf(stderr, "Can't write new address\n"); hci_close_dev(dd); exit(1); } - printf("Address changed - Reset device now\n"); + printf("Address changed - "); + + if (vendor[i].reset_device) { + if (vendor[i].reset_device(dd) < 0) { + printf("Reset device manually\n"); + } else { + ioctl(dd, HCIDEVRESET, dev); + printf("Device reset successully\n"); + } + } else { + printf("Reset device now\n"); + } //ioctl(dd, HCIDEVRESET, dev); //ioctl(dd, HCIDEVDOWN, dev); -- cgit From 033622dcb3935c1d6a7147bfbbf753c1011e6ba0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 6 Sep 2005 21:51:34 +0000 Subject: Make the reset optional --- test/bdaddr.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index e34cc961..5331a8dc 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -222,12 +222,13 @@ static void usage(void) { printf("bdaddr - Utility for changing the Bluetooth device address\n\n"); printf("Usage:\n" - "\tbdaddr [-i ] [new bdaddr]\n"); + "\tbdaddr [-i ] [-r] [new bdaddr]\n"); } static struct option main_options[] = { - { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, + { "reset", 0, 0, 'r' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -237,11 +238,11 @@ int main(int argc, char *argv[]) struct hci_version ver; bdaddr_t bdaddr; char addr[18]; - int i, dd, opt, dev = 0; + int i, dd, opt, dev = 0, reset = 0; bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -251,6 +252,10 @@ int main(int argc, char *argv[]) } break; + case 'r': + reset = 1; + break; + case 'h': default: usage(); @@ -323,7 +328,7 @@ int main(int argc, char *argv[]) printf("Address changed - "); - if (vendor[i].reset_device) { + if (reset && vendor[i].reset_device) { if (vendor[i].reset_device(dd) < 0) { printf("Reset device manually\n"); } else { -- cgit From 0738cf5e684464d157816be73c0b19efb7dd4fc7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 Sep 2005 00:24:52 +0000 Subject: Support volatile changes of the BD_ADDR for CSR chips --- test/bdaddr.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index 5331a8dc..57d9b005 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -41,6 +41,8 @@ #include #include +static int transient = 0; + #define OCF_ERICSSON_WRITE_BD_ADDR 0x000d typedef struct { bdaddr_t bdaddr; @@ -113,6 +115,9 @@ static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr) unsigned char cp[254], rp[254]; struct hci_request rq; + if (transient) + cmd[14] = 0x08; + cmd[16] = bdaddr->b[2]; cmd[17] = 0x00; cmd[18] = bdaddr->b[0]; @@ -160,6 +165,9 @@ static int csr_reset_device(int dd) unsigned char cp[254], rp[254]; struct hci_request rq; + if (transient) + cmd[6] = 0x02; + memset(&cp, 0, sizeof(cp)); cp[0] = 0xc2; memcpy(cp + 1, cmd, sizeof(cmd)); @@ -222,12 +230,13 @@ static void usage(void) { printf("bdaddr - Utility for changing the Bluetooth device address\n\n"); printf("Usage:\n" - "\tbdaddr [-i ] [-r] [new bdaddr]\n"); + "\tbdaddr [-i ] [-r] [-t] [new bdaddr]\n"); } static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, + { "transient", 0, 0, 't' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -242,7 +251,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt_long(argc, argv, "+i:rh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rth", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -256,6 +265,10 @@ int main(int argc, char *argv[]) reset = 1; break; + case 't': + transient = 1; + break; + case 'h': default: usage(); -- cgit From d577091a3632210b7c5d8a07bc7698097f0042a6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Sep 2005 15:19:14 +0000 Subject: Show the OUI and include a manual page for the bdaddr utility --- test/Makefile.am | 8 +++++++- test/bdaddr.8 | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/bdaddr.c | 27 ++++++++++++++++++++++--- 3 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 test/bdaddr.8 (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index bf41fb03..8ee5ed06 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -17,11 +17,17 @@ attest_LDADD = @BLUEZ_LIBS@ hstest_LDADD = @BLUEZ_LIBS@ +bdaddr_SOURCES = bdaddr.c $(top_builddir)/tools/oui.h $(top_builddir)/tools/oui.c + bdaddr_LDADD = @BLUEZ_LIBS@ +noinst_MANS = bdaddr.8 + AM_CFLAGS = @BLUEZ_CFLAGS@ endif -EXTRA_DIST = hsplay hsmicro +INCLUDES = -I$(top_srcdir)/tools + +EXTRA_DIST = hsplay hsmicro bdaddr.8 MAINTAINERCLEANFILES = Makefile.in diff --git a/test/bdaddr.8 b/test/bdaddr.8 new file mode 100644 index 00000000..623a1401 --- /dev/null +++ b/test/bdaddr.8 @@ -0,0 +1,61 @@ +.TH BDADDR 8 "Sep 27 2005" BlueZ "Linux System Administration" +.SH NAME +bdaddr \- Utility for changing the Bluetooth device address +.SH SYNOPSIS +.B bdaddr +.br +.B bdaddr -h +.br +.B bdaddr [-i ] [-r] [-t] [new bdaddr] + +.SH DESCRIPTION +.LP +.B +bdaddr +is used to query or set the local Bluetooth device address (BD_ADDR). If run with no arguments, +.B +bdaddr +prints the chip manufacturer's name, and the current BD_ADDR. If the IEEE OUI index file "oui.txt" is installed on the system, +the BD_ADDR owner will be displayed. If the optional +[new bdaddr] argument is given, the device will be reprogrammed with that address. This can either be permanent or temporary, as specified +by the -t flag. In both cases, the device must be reset before the new address will become active. This can be done +with a 'soft' reset by specifying the -r flag, or a 'hard' reset by removing and replugging the device. +A 'hard' reset will cause the address to revert to the current non-volatile value. +.PP +.B +bdaddr +uses manufacturer specific commands to set the address, and is therefore device specific. For this reason, not all devices are supported, and not all +options are supported on all devices. +Current supported manufacturers are: +.B Ericsson, Cambridge Silicon Radio (CSR) +and +.B Zeevo + +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands. +.TP +.BI -i\ +Specify a particular device to operate on. If not specified, default is the first available device. +.TP +.BI -r +Reset device and make new BD_ADDR active. +.B +CSR +devices only. +.TP +.BI -t +Temporary change. Do not write to non-volatile memory. +.B +CSR +devices only. +.SH FILES +.TP +.I +/usr/share/misc/oui.txt +IEEE Organizationally Unique Identifier master file. Manually update from: http://standards.ieee.org/regauth/oui/oui.txt +.SH AUTHORS +Written by Marcel Holtmann , +man page by Adam Laurie +.PP diff --git a/test/bdaddr.c b/test/bdaddr.c index 57d9b005..92b43de8 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -41,6 +41,8 @@ #include #include +#include "oui.h" + static int transient = 0; #define OCF_ERICSSON_WRITE_BD_ADDR 0x000d @@ -246,7 +248,7 @@ int main(int argc, char *argv[]) struct hci_dev_info di; struct hci_version ver; bdaddr_t bdaddr; - char addr[18]; + char addr[18], oui[9], *comp; int i, dd, opt, dev = 0, reset = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -314,8 +316,17 @@ int main(int argc, char *argv[]) printf("Manufacturer: %s (%d)\n", bt_compidtostr(ver.manufacturer), ver.manufacturer); + ba2oui(&bdaddr, oui); + comp = ouitocomp(oui); + ba2str(&bdaddr, addr); - printf("Device address: %s\n", addr); + printf("Device address: %s", addr); + + if (comp) { + printf(" (%s)\n", comp); + free(comp); + } else + printf("\n"); if (argc < 1) { hci_close_dev(dd); @@ -330,8 +341,18 @@ int main(int argc, char *argv[]) for (i = 0; vendor[i].compid != 65535; i++) if (ver.manufacturer == vendor[i].compid) { + ba2oui(&bdaddr, oui); + comp = ouitocomp(oui); + ba2str(&bdaddr, addr); - printf("New BD address: %s\n\n", addr); + printf("New BD address: %s", addr); + + if (comp) { + printf(" (%s)\n\n", comp); + free(comp); + } else + printf("\n\n"); + if (vendor[i].write_bd_addr(dd, &bdaddr) < 0) { fprintf(stderr, "Can't write new address\n"); -- cgit From 3b01d3c5e0457009c0bdc683d9e8adab29d20fe1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 10 Oct 2005 08:22:59 +0000 Subject: Add address change support for Texas Instruments chips --- test/bdaddr.8 | 31 +++++++++++++++++++------------ test/bdaddr.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/bdaddr.8 b/test/bdaddr.8 index 623a1401..dbc2099e 100644 --- a/test/bdaddr.8 +++ b/test/bdaddr.8 @@ -12,23 +12,28 @@ bdaddr \- Utility for changing the Bluetooth device address .LP .B bdaddr -is used to query or set the local Bluetooth device address (BD_ADDR). If run with no arguments, +is used to query or set the local Bluetooth device address (BD_ADDR). If run +with no arguments, .B bdaddr -prints the chip manufacturer's name, and the current BD_ADDR. If the IEEE OUI index file "oui.txt" is installed on the system, -the BD_ADDR owner will be displayed. If the optional -[new bdaddr] argument is given, the device will be reprogrammed with that address. This can either be permanent or temporary, as specified -by the -t flag. In both cases, the device must be reset before the new address will become active. This can be done -with a 'soft' reset by specifying the -r flag, or a 'hard' reset by removing and replugging the device. -A 'hard' reset will cause the address to revert to the current non-volatile value. +prints the chip manufacturer's name, and the current BD_ADDR. If the IEEE OUI +index file "oui.txt" is installed on the system, the BD_ADDR owner will be +displayed. If the optional [new bdaddr] argument is given, the device will be +reprogrammed with that address. This can either be permanent or temporary, as +specified by the -t flag. In both cases, the device must be reset before the +new address will become active. This can be done with a 'soft' reset by +specifying the -r flag, or a 'hard' reset by removing and replugging the +device. A 'hard' reset will cause the address to revert to the current +non-volatile value. .PP .B bdaddr -uses manufacturer specific commands to set the address, and is therefore device specific. For this reason, not all devices are supported, and not all +uses manufacturer specific commands to set the address, and is therefore +device specific. For this reason, not all devices are supported, and not all options are supported on all devices. Current supported manufacturers are: -.B Ericsson, Cambridge Silicon Radio (CSR) -and +.B Ericsson, Cambridge Silicon Radio (CSR), Texas Instruments (TI) +and .B Zeevo .SH OPTIONS @@ -37,7 +42,8 @@ and Gives a list of possible commands. .TP .BI -i\ -Specify a particular device to operate on. If not specified, default is the first available device. +Specify a particular device to operate on. If not specified, default is the +first available device. .TP .BI -r Reset device and make new BD_ADDR active. @@ -54,7 +60,8 @@ devices only. .TP .I /usr/share/misc/oui.txt -IEEE Organizationally Unique Identifier master file. Manually update from: http://standards.ieee.org/regauth/oui/oui.txt +IEEE Organizationally Unique Identifier master file. +Manually update from: http://standards.ieee.org/regauth/oui/oui.txt .SH AUTHORS Written by Marcel Holtmann , man page by Adam Laurie diff --git a/test/bdaddr.c b/test/bdaddr.c index 92b43de8..ac382e57 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -189,6 +189,34 @@ static int csr_reset_device(int dd) return 0; } +#define OCF_TI_WRITE_BD_ADDR 0x0006 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) ti_write_bd_addr_cp; +#define TI_WRITE_BD_ADDR_CP_SIZE 6 + +static int ti_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + struct hci_request rq; + ti_write_bd_addr_cp cp; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_TI_WRITE_BD_ADDR; + rq.cparam = &cp; + rq.clen = TI_WRITE_BD_ADDR_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 typedef struct { bdaddr_t bdaddr; @@ -224,6 +252,7 @@ static struct { } vendor[] = { { 0, ericsson_write_bd_addr, NULL }, { 10, csr_write_bd_addr, csr_reset_device }, + { 13, ti_write_bd_addr, NULL, }, { 18, zeevo_write_bd_addr, NULL }, { 65535, NULL, NULL }, }; -- 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/Makefile.am | 3 --- test/attest.c | 25 ++++++++++--------------- test/bdaddr.c | 25 ++++++++++--------------- test/hstest.c | 27 +++++++++++---------------- test/l2test.c | 25 ++++++++++--------------- test/rctest.c | 25 ++++++++++--------------- test/scotest.c | 25 ++++++++++--------------- 7 files changed, 61 insertions(+), 94 deletions(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 8ee5ed06..e63e37be 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if TEST bin_PROGRAMS = l2test rctest diff --git a/test/attest.c b/test/attest.c index 6e7d3808..10aec939 100644 --- a/test/attest.c +++ b/test/attest.c @@ -6,24 +6,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 diff --git a/test/bdaddr.c b/test/bdaddr.c index ac382e57..be1419d8 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -6,24 +6,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 diff --git a/test/hstest.c b/test/hstest.c index 8949be4b..bea4d3a4 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 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; + * 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 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 diff --git a/test/rctest.c b/test/rctest.c index 8c76859f..724460c7 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -7,24 +7,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 diff --git a/test/scotest.c b/test/scotest.c index 22a95fed..169f39b7 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -7,24 +7,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 ea6747ecff0ec1a738da67c39cae965caab03c5b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Dec 2005 06:31:42 +0000 Subject: Add HCI emulation tool --- test/Makefile.am | 8 +- test/hciemu.c | 1351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1357 insertions(+), 2 deletions(-) create mode 100644 test/hciemu.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index e63e37be..751fa50c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,8 +1,12 @@ if TEST +sbin_PROGRAMS = hciemu + bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = scotest attest hstest bdaddr +noinst_PROGRAMS = scotest attest hstest bdaddr + +hciemu_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libglib-ectomy.a l2test_LDADD = @BLUEZ_LIBS@ @@ -23,7 +27,7 @@ noinst_MANS = bdaddr.8 AM_CFLAGS = @BLUEZ_CFLAGS@ endif -INCLUDES = -I$(top_srcdir)/tools +INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/tools EXTRA_DIST = hsplay hsmicro bdaddr.8 diff --git a/test/hciemu.c b/test/hciemu.c new file mode 100644 index 00000000..be033c2a --- /dev/null +++ b/test/hciemu.c @@ -0,0 +1,1351 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2002 Maxim Krasnyansky + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * 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. + * + * 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. + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "glib-ectomy.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +static inline uint64_t ntoh64(uint64_t n) +{ + uint64_t h; + uint64_t tmp = ntohl(n & 0x00000000ffffffff); + h = ntohl(n >> 32); + h |= tmp << 32; + return h; +} +#elif __BYTE_ORDER == __BIG_ENDIAN +#define ntoh64(x) (x) +#else +#error "Unknown byte order" +#endif +#define hton64(x) ntoh64(x) + +#define GHCI_DEV "/dev/ghci" + +#define VHCI_DEV "/dev/vhci" +#define VHCI_UDEV "/dev/hci_vhci" + +#define VHCI_MAX_CONN 12 + +#define VHCI_ACL_MTU 192 +#define VHCI_ACL_MAX_PKT 8 + +struct vhci_device { + uint8_t features[8]; + uint8_t name[248]; + uint8_t dev_class[3]; + uint8_t inq_mode; + uint8_t eir_fec; + uint8_t eir_data[240]; + uint16_t acl_cnt; + bdaddr_t bdaddr; + int fd; + int dd; + GIOChannel *scan; +}; + +struct vhci_conn { + bdaddr_t dest; + uint16_t handle; + GIOChannel *chan; +}; + +struct vhci_link_info { + bdaddr_t bdaddr; + uint8_t dev_class[3]; + uint8_t link_type; + uint8_t role; +} __attribute__ ((packed)); + +static struct vhci_device vdev; +static struct vhci_conn *vconn[VHCI_MAX_CONN]; + +struct btsnoop_hdr { + uint8_t id[8]; /* Identification Pattern */ + uint32_t version; /* Version Number = 1 */ + uint32_t type; /* Datalink Type */ +} __attribute__ ((packed)); +#define BTSNOOP_HDR_SIZE (sizeof(struct btsnoop_hdr)) + +struct btsnoop_pkt { + uint32_t size; /* Original Length */ + uint32_t len; /* Included Length */ + uint32_t flags; /* Packet Flags */ + uint32_t drops; /* Cumulative Drops */ + uint64_t ts; /* Timestamp microseconds */ + uint8_t data[0]; /* Packet Data */ +} __attribute__ ((packed)); +#define BTSNOOP_PKT_SIZE (sizeof(struct btsnoop_pkt)) + +static uint8_t btsnoop_id[] = { 0x62, 0x74, 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00 }; + +static GMainLoop *event_loop; + +static volatile sig_atomic_t __io_canceled; + +static inline void io_init(void) +{ + __io_canceled = 0; +} + +static inline void io_cancel(void) +{ + __io_canceled = 1; +} + +static void sig_term(int sig) +{ + io_cancel(); + g_main_quit(event_loop); +} + +static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data); +static gboolean io_conn_ind(GIOChannel *chan, GIOCondition cond, gpointer data); +static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data); + +static inline int read_n(int fd, void *buf, int len) +{ + register int w, t = 0; + + while (!__io_canceled && len > 0) { + if ((w = read(fd, buf, len)) < 0 ){ + if( errno == EINTR || errno == EAGAIN ) + continue; + return -1; + } + if (!w) + return 0; + len -= w; buf += w; t += w; + } + return t; +} + +/* Write exactly len bytes (Signal safe)*/ +static inline int write_n(int fd, void *buf, int len) +{ + register int w, t = 0; + + while (!__io_canceled && len > 0) { + if ((w = write(fd, buf, len)) < 0 ){ + if( errno == EINTR || errno == EAGAIN ) + continue; + return -1; + } + if (!w) + return 0; + len -= w; buf += w; t += w; + } + return t; +} + +static int create_snoop(char *file) +{ + struct btsnoop_hdr hdr; + int fd, len; + + fd = open(file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) + return fd; + + memcpy(hdr.id, btsnoop_id, sizeof(btsnoop_id)); + hdr.version = htonl(1); + hdr.type = htonl(1002); + + len = write(fd, &hdr, BTSNOOP_HDR_SIZE); + if (len < 0) { + close(fd); + return -EIO; + } + + if (len != BTSNOOP_HDR_SIZE) { + close(fd); + return -1; + } + + return fd; +} + +static int write_snoop(int fd, int type, int incoming, unsigned char *buf, int len) +{ + struct btsnoop_pkt pkt; + struct timeval tv; + uint32_t size = len; + uint64_t ts; + + if (fd < 0) + return -1; + + memset(&tv, 0, sizeof(tv)); + gettimeofday(&tv, NULL); + ts = (tv.tv_sec - 946684800ll) * 1000000ll + tv.tv_usec; + + pkt.size = htonl(size); + pkt.len = pkt.size; + pkt.flags = ntohl(incoming & 0x01); + pkt.drops = htonl(0); + pkt.ts = hton64(ts + 0x00E03AB44A676000ll); + + if (type == HCI_COMMAND_PKT || type == HCI_EVENT_PKT) + pkt.flags |= ntohl(0x02); + + write(fd, &pkt, BTSNOOP_PKT_SIZE); + write(fd, buf, size); + + return 0; +} + +static struct vhci_conn *conn_get_by_bdaddr(bdaddr_t *ba) +{ + register int i; + + for (i = 0; i < VHCI_MAX_CONN; i++) + if (!bacmp(&vconn[i]->dest, ba)) + return vconn[i]; + + return NULL; +} + +static void command_status(uint16_t ogf, uint16_t ocf, uint8_t status) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_cmd_status *cs; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CMD_STATUS; + he->plen = EVT_CMD_STATUS_SIZE; + + cs = (void *) ptr; ptr += EVT_CMD_STATUS_SIZE; + + cs->status = status; + cs->ncmd = 1; + cs->opcode = htobs(cmd_opcode_pack(ogf, ocf)); + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s(%d)", + strerror(errno), errno); +} + +static void command_complete(uint16_t ogf, uint16_t ocf, int plen, void *data) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_cmd_complete *cc; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CMD_COMPLETE; + he->plen = EVT_CMD_COMPLETE_SIZE + plen; + + cc = (void *) ptr; ptr += EVT_CMD_COMPLETE_SIZE; + + cc->ncmd = 1; + cc->opcode = htobs(cmd_opcode_pack(ogf, ocf)); + + if (plen) { + memcpy(ptr, data, plen); + ptr += plen; + } + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s(%d)", + strerror(errno), errno); +} + +static void connect_request(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_conn_request *cr; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CONN_REQUEST; + he->plen = EVT_CONN_REQUEST_SIZE; + + cr = (void *) ptr; ptr += EVT_CONN_REQUEST_SIZE; + + bacpy(&cr->bdaddr, &conn->dest); + memset(&cr->dev_class, 0, sizeof(cr->dev_class)); + cr->link_type = ACL_LINK; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); +} + +static void connect_complete(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_conn_complete *cc; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CONN_COMPLETE; + he->plen = EVT_CONN_COMPLETE_SIZE; + + cc = (void *) ptr; ptr += EVT_CONN_COMPLETE_SIZE; + + bacpy(&cc->bdaddr, &conn->dest); + cc->status = 0x00; + cc->handle = htobs(conn->handle); + cc->link_type = ACL_LINK; + cc->encr_mode = 0x00; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); +} + +static void disconn_complete(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_disconn_complete *dc; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_DISCONN_COMPLETE; + he->plen = EVT_DISCONN_COMPLETE_SIZE; + + dc = (void *) ptr; ptr += EVT_DISCONN_COMPLETE_SIZE; + + dc->status = 0x00; + dc->handle = htobs(conn->handle); + dc->reason = 0x00; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); + + vdev.acl_cnt = 0; +} + +static void num_completed_pkts(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_num_comp_pkts *np; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_NUM_COMP_PKTS; + he->plen = EVT_NUM_COMP_PKTS_SIZE; + + np = (void *) ptr; ptr += EVT_NUM_COMP_PKTS_SIZE; + np->num_hndl = 1; + + *((uint16_t *) ptr) = htobs(conn->handle); ptr += 2; + *((uint16_t *) ptr) = htobs(vdev.acl_cnt); ptr += 2; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); +} + +static int scan_enable(uint8_t *data) +{ + struct sockaddr_in sa; + GIOChannel *sk_io; + bdaddr_t ba; + int sk, opt; + + if (!(*data & SCAN_PAGE)) { + if (vdev.scan) { + g_io_channel_close(vdev.scan); + vdev.scan = NULL; + } + return 0; + } + + if (vdev.scan) + return 0; + + if ((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); + return 1; + } + + opt = 1; + setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + baswap(&ba, &vdev.bdaddr); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = *(uint32_t *) &ba; + sa.sin_port = *(uint16_t *) &ba.b[4]; + if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto failed; + } + + if (listen(sk, 10)) { + syslog(LOG_ERR, "Can't listen on socket: %s (%d)", + strerror(errno), errno); + goto failed; + } + + sk_io = g_io_channel_unix_new(sk); + g_io_add_watch(sk_io, G_IO_IN | G_IO_NVAL, io_conn_ind, NULL); + vdev.scan = sk_io; + return 0; + +failed: + close(sk); + return 1; +} + +static void accept_connection(uint8_t *data) +{ + accept_conn_req_cp *cp = (void *) data; + struct vhci_conn *conn; + + if (!(conn = conn_get_by_bdaddr(&cp->bdaddr))) + return; + + connect_complete(conn); + + g_io_add_watch(conn->chan, G_IO_IN | G_IO_NVAL | G_IO_HUP, + io_acl_data, (gpointer) conn); +} + +static void close_connection(struct vhci_conn *conn) +{ + syslog(LOG_INFO, "Closing connection %s handle %d", + batostr(&conn->dest), conn->handle); + + g_io_channel_close(conn->chan); + + vconn[conn->handle - 1] = NULL; + disconn_complete(conn); + free(conn); +} + +static void disconnect(uint8_t *data) +{ + disconnect_cp *cp = (void *) data; + struct vhci_conn *conn; + uint16_t handle; + + handle = btohs(cp->handle); + + if (handle - 1 > VHCI_MAX_CONN) + return; + + if (!(conn = vconn[handle-1])) + return; + + close_connection(conn); +} + +static void create_connection(uint8_t *data) +{ + create_conn_cp *cp = (void *) data; + struct vhci_link_info info; + struct vhci_conn *conn; + struct sockaddr_in sa; + int h, sk, opt; + bdaddr_t ba; + + for (h = 0; h < VHCI_MAX_CONN; h++) + if (!vconn[h]) + goto do_connect; + + syslog(LOG_ERR, "Too many connections"); + return; + +do_connect: + if ((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); + return; + } + + opt = 1; + setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + baswap(&ba, &vdev.bdaddr); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = INADDR_ANY; // *(uint32_t *) &ba; + sa.sin_port = 0; // *(uint16_t *) &ba.b[4]; + if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + close(sk); + return; + } + + baswap(&ba, &cp->bdaddr); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = *(uint32_t *) &ba; + sa.sin_port = *(uint16_t *) &ba.b[4]; + if (connect(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + close(sk); + return; + } + + /* Send info */ + memset(&info, 0, sizeof(info)); + bacpy(&info.bdaddr, &vdev.bdaddr); + info.link_type = ACL_LINK; + info.role = 1; + write_n(sk, (void *) &info, sizeof(info)); + + if (!(conn = malloc(sizeof(*conn)))) { + syslog(LOG_ERR, "Can't alloc new connection: %s (%d)", + strerror(errno), errno); + close(sk); + return; + } + + memcpy((uint8_t *) &ba, (uint8_t *) &sa.sin_addr, 4); + memcpy((uint8_t *) &ba.b[4], (uint8_t *) &sa.sin_port, 2); + baswap(&conn->dest, &ba); + + vconn[h] = conn; + conn->handle = h + 1; + conn->chan = g_io_channel_unix_new(sk); + + connect_complete(conn); + g_io_add_watch(conn->chan, G_IO_IN | G_IO_NVAL | G_IO_HUP, + io_acl_data, (gpointer) conn); + return; +} + +static void inline hci_link_control(uint16_t ocf, int plen, uint8_t *data) +{ + uint8_t status; + + const uint16_t ogf = OGF_LINK_CTL; + + switch (ocf) { + case OCF_CREATE_CONN: + command_status(ogf, ocf, 0x00); + create_connection(data); + break; + + case OCF_ACCEPT_CONN_REQ: + command_status(ogf, ocf, 0x00); + accept_connection(data); + break; + + case OCF_DISCONNECT: + command_status(ogf, ocf, 0x00); + disconnect(data); + break; + + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void inline hci_link_policy(uint16_t ocf, int plen, uint8_t *data) +{ + uint8_t status; + + const uint16_t ogf = OGF_INFO_PARAM; + + switch (ocf) { + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void inline hci_host_control(uint16_t ocf, int plen, uint8_t *data) +{ + read_local_name_rp ln; + read_class_of_dev_rp cd; + read_inquiry_mode_rp im; + read_ext_inquiry_response_rp ir; + uint8_t status; + + const uint16_t ogf = OGF_HOST_CTL; + + switch (ocf) { + case OCF_RESET: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_SET_EVENT_FLT: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_CHANGE_LOCAL_NAME: + status = 0x00; + memcpy(vdev.name, data, sizeof(vdev.name)); + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_LOCAL_NAME: + ln.status = 0x00; + memcpy(ln.name, vdev.name, sizeof(ln.name)); + command_complete(ogf, ocf, sizeof(ln), &ln); + break; + + case OCF_WRITE_CONN_ACCEPT_TIMEOUT: + case OCF_WRITE_PAGE_TIMEOUT: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_WRITE_SCAN_ENABLE: + status = scan_enable(data); + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_WRITE_AUTH_ENABLE: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_WRITE_ENCRYPT_MODE: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_CLASS_OF_DEV: + cd.status = 0x00; + memcpy(cd.dev_class, vdev.dev_class, 3); + command_complete(ogf, ocf, sizeof(cd), &cd); + break; + + case OCF_WRITE_CLASS_OF_DEV: + status = 0x00; + memcpy(vdev.dev_class, data, 3); + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_INQUIRY_MODE: + im.status = 0x00; + im.mode = vdev.inq_mode; + command_complete(ogf, ocf, sizeof(im), &im); + break; + + case OCF_WRITE_INQUIRY_MODE: + status = 0x00; + vdev.inq_mode = data[0]; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_EXT_INQUIRY_RESPONSE: + ir.status = 0x00; + ir.fec = vdev.eir_fec; + memcpy(ir.data, vdev.eir_data, 240); + command_complete(ogf, ocf, sizeof(ir), &ir); + break; + + case OCF_WRITE_EXT_INQUIRY_RESPONSE: + status = 0x00; + vdev.eir_fec = data[0]; + memcpy(vdev.eir_data, data + 1, 240); + command_complete(ogf, ocf, 1, &status); + break; + + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void inline hci_info_param(uint16_t ocf, int plen, uint8_t *data) +{ + read_local_version_rp lv; + read_local_features_rp lf; + read_local_ext_features_rp ef; + read_buffer_size_rp bs; + read_bd_addr_rp ba; + uint8_t status; + + const uint16_t ogf = OGF_INFO_PARAM; + + switch (ocf) { + case OCF_READ_LOCAL_VERSION: + lv.status = 0x00; + lv.hci_ver = 0x03; + lv.hci_rev = htobs(0x0000); + lv.lmp_ver = 0x03; + lv.manufacturer = htobs(29); + lv.lmp_subver = htobs(0x0000); + command_complete(ogf, ocf, sizeof(lv), &lv); + break; + + case OCF_READ_LOCAL_FEATURES: + lf.status = 0x00; + memcpy(lf.features, vdev.features, 8); + command_complete(ogf, ocf, sizeof(lf), &lf); + break; + + case OCF_READ_LOCAL_EXT_FEATURES: + ef.status = 0x00; + if (*data == 0) { + ef.page_num = 0; + ef.max_page_num = 0; + memcpy(ef.features, vdev.features, 8); + } else { + ef.page_num = *data; + ef.max_page_num = 0; + memset(ef.features, 0, 8); + } + command_complete(ogf, ocf, sizeof(ef), &ef); + break; + + case OCF_READ_BUFFER_SIZE: + bs.status = 0x00; + bs.acl_mtu = htobs(VHCI_ACL_MTU); + bs.sco_mtu = 0; + bs.acl_max_pkt = htobs(VHCI_ACL_MAX_PKT); + bs.sco_max_pkt = htobs(0); + command_complete(ogf, ocf, sizeof(bs), &bs); + break; + + case OCF_READ_BD_ADDR: + ba.status = 0x00; + bacpy(&ba.bdaddr, &vdev.bdaddr); + command_complete(ogf, ocf, sizeof(ba), &ba); + break; + + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void hci_command(uint8_t *data) +{ + hci_command_hdr *ch; + uint8_t *ptr = data; + uint16_t ogf, ocf; + + ch = (hci_command_hdr *) ptr; + ptr += HCI_COMMAND_HDR_SIZE; + + ch->opcode = btohs(ch->opcode); + ogf = cmd_opcode_ogf(ch->opcode); + ocf = cmd_opcode_ocf(ch->opcode); + + switch (ogf) { + case OGF_LINK_CTL: + hci_link_control(ocf, ch->plen, ptr); + break; + + case OGF_LINK_POLICY: + hci_link_policy(ocf, ch->plen, ptr); + break; + + case OGF_HOST_CTL: + hci_host_control(ocf, ch->plen, ptr); + break; + + case OGF_INFO_PARAM: + hci_info_param(ocf, ch->plen, ptr); + break; + } +} + +static void hci_acl_data(uint8_t *data) +{ + hci_acl_hdr *ah = (void *) data; + struct vhci_conn *conn; + uint16_t handle; + int fd; + + handle = acl_handle(btohs(ah->handle)); + + if (handle > VHCI_MAX_CONN || !(conn = vconn[handle - 1])) { + syslog(LOG_ERR, "Bad connection handle %d", handle); + return; + } + + fd = g_io_channel_unix_get_fd(conn->chan); + if (write_n(fd, data, btohs(ah->dlen) + HCI_ACL_HDR_SIZE) < 0) { + close_connection(conn); + return; + } + + if (++vdev.acl_cnt > VHCI_ACL_MAX_PKT - 1) { + /* Send num of complete packets event */ + num_completed_pkts(conn); + vdev.acl_cnt = 0; + } +} + +static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + struct vhci_conn *conn = (struct vhci_conn *) data; + unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; + hci_acl_hdr *ah; + uint16_t flags; + int len, fd; + + if (cond & G_IO_NVAL) + return FALSE; + + if (cond & G_IO_HUP) { + close_connection(conn); + return FALSE; + } + + fd = g_io_channel_unix_get_fd(chan); + + ptr = buf + 1; + if (read_n(fd, ptr, HCI_ACL_HDR_SIZE) <= 0) { + close_connection(conn); + return FALSE; + } + + ah = (void *) ptr; + ptr += HCI_ACL_HDR_SIZE; + + len = btohs(ah->dlen); + if (read_n(fd, ptr, len) <= 0) { + close_connection(conn); + return FALSE; + } + + buf[0] = HCI_ACLDATA_PKT; + + flags = acl_flags(btohs(ah->handle)); + ah->handle = htobs(acl_handle_pack(conn->handle, flags)); + len += HCI_ACL_HDR_SIZE + 1; + + write_snoop(vdev.dd, HCI_ACLDATA_PKT, 1, buf, len); + + write(vdev.fd, buf, len); + + return TRUE; +} + +static gboolean io_conn_ind(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + struct vhci_link_info info; + struct vhci_conn *conn; + struct sockaddr_in sa; + socklen_t len; + int sk, nsk, h; + + if (cond & G_IO_NVAL) + return FALSE; + + sk = g_io_channel_unix_get_fd(chan); + + len = sizeof(sa); + if ((nsk = accept(sk, (struct sockaddr *) &sa, &len)) < 0) + return TRUE; + + if (read_n(nsk, &info, sizeof(info)) < 0) { + syslog(LOG_ERR, "Can't read link info"); + return TRUE; + } + + if (!(conn = malloc(sizeof(*conn)))) { + syslog(LOG_ERR, "Can't alloc new connection"); + close(nsk); + return TRUE; + } + + bacpy(&conn->dest, &info.bdaddr); + + for (h = 0; h < VHCI_MAX_CONN; h++) + if (!vconn[h]) + goto accepted; + + syslog(LOG_ERR, "Too many connections"); + free(conn); + close(nsk); + return TRUE; + +accepted: + vconn[h] = conn; + conn->handle = h + 1; + conn->chan = g_io_channel_unix_new(nsk); + connect_request(conn); + + return TRUE; +} + +static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; + int type; + gsize len; + GIOError err; + + ptr = buf; + + if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { + if (err == G_IO_ERROR_AGAIN) + return TRUE; + + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); + g_main_quit(event_loop); + return FALSE; + } + + type = *ptr++; + + write_snoop(vdev.dd, type, 0, buf, len); + + switch (type) { + case HCI_COMMAND_PKT: + hci_command(ptr); + break; + + case HCI_ACLDATA_PKT: + hci_acl_data(ptr); + break; + + default: + syslog(LOG_ERR, "Unknown packet type 0x%2.2x", type); + break; + } + + return TRUE; +} + +static int getbdaddrbyname(char *str, bdaddr_t *ba) +{ + int i, n, len; + + len = strlen(str); + + /* Check address format */ + for (i = 0, n = 0; i < len; i++) + if (str[i] == ':') + n++; + + if (n == 5) { + /* BD address */ + baswap(ba, strtoba(str)); + return 0; + } + + if (n == 1) { + /* IP address + port */ + struct hostent *hent; + bdaddr_t b; + char *ptr; + + ptr = strchr(str, ':'); + *ptr++ = 0; + + if (!(hent = gethostbyname(str))) { + fprintf(stderr, "Can't resolve %s\n", str); + return -2; + } + + memcpy(&b, hent->h_addr, 4); + *(uint16_t *) (&b.b[4]) = htons(atoi(ptr)); + baswap(ba, &b); + + return 0; + } + + fprintf(stderr, "Invalid address format\n"); + + return -1; +} + +static void rewrite_bdaddr(unsigned char *buf, int len, bdaddr_t *bdaddr) +{ + hci_event_hdr *eh; + unsigned char *ptr = buf; + int type; + + if (!bdaddr) + return; + + if (!bacmp(bdaddr, BDADDR_ANY)) + return; + + type = *ptr++; + + switch (type) { + case HCI_EVENT_PKT: + eh = (hci_event_hdr *) ptr; + ptr += HCI_EVENT_HDR_SIZE; + + if (eh->evt == EVT_CMD_COMPLETE) { + evt_cmd_complete *cc = (void *) ptr; + + ptr += EVT_CMD_COMPLETE_SIZE; + + if (cc->opcode == htobs(cmd_opcode_pack(OGF_INFO_PARAM, + OCF_READ_BD_ADDR))) { + bacpy((bdaddr_t *) (ptr + 1), bdaddr); + } + } + break; + } +} + +static int run_proxy(int fd, int dev, bdaddr_t *bdaddr) +{ + unsigned char buf[HCI_MAX_FRAME_SIZE + 1]; + struct hci_dev_info di; + struct hci_filter flt; + struct pollfd p[2]; + int dd, err, len, need_raw; + + dd = hci_open_dev(dev); + if (dd < 0) { + syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", + dev, strerror(errno), errno); + return 1; + } + + if (hci_devinfo(dev, &di) < 0) { + syslog(LOG_ERR, "Can't get device info for hci%d: %s (%d)", + dev, strerror(errno), errno); + hci_close_dev(dd); + return 1; + } + + need_raw = !hci_test_bit(HCI_RAW, &di.flags); + + hci_filter_clear(&flt); + hci_filter_all_ptypes(&flt); + hci_filter_all_events(&flt); + + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + syslog(LOG_ERR, "Can't set filter for hci%d: %s (%d)", + dev, strerror(errno), errno); + hci_close_dev(dd); + return 1; + } + + if (need_raw) { + if (ioctl(dd, HCISETRAW, 1) < 0) { + syslog(LOG_ERR, "Can't set raw mode on hci%d: %s (%d)", + dev, strerror(errno), errno); + hci_close_dev(dd); + return 1; + } + } + + p[0].fd = fd; + p[0].events = POLLIN; + p[1].fd = dd; + p[1].events = POLLIN; + + while (!__io_canceled) { + p[0].revents = 0; + p[1].revents = 0; + err = poll(p, 2, 100); + if (err < 0) + break; + if (!err) + continue; + + if (p[0].revents & POLLIN) { + len = read(fd, buf, sizeof(buf)); + if (len > 0) { + rewrite_bdaddr(buf, len, bdaddr); + write(dd, buf, len); + } + } + + if (p[1].revents & POLLIN) { + len = read(dd, buf, sizeof(buf)); + if (len > 0) { + rewrite_bdaddr(buf, len, bdaddr); + write(fd, buf, len); + } + } + } + + if (need_raw) { + if (ioctl(dd, HCISETRAW, 0) < 0) + syslog(LOG_ERR, "Can't clear raw mode on hci%d: %s (%d)", + dev, strerror(errno), errno); + } + + hci_close_dev(dd); + + syslog(LOG_INFO, "Exit"); + + return 0; +} + +static void usage(void) +{ + printf("hciemu - HCI emulator ver %s\n", VERSION); + printf("Usage: \n"); + printf("\thciemu [-n] local_address\n"); +} + +static struct option main_options[] = { + { "device", 1, 0, 'd' }, + { "bdaddr", 1, 0, 'b' }, + { "snoop", 1, 0, 's' }, + { "nodetach", 0, 0, 'n' }, + { "help", 0, 0, 'h' }, + { 0 } +}; + +int main(int argc, char *argv[], char *env[]) +{ + struct sigaction sa; + GIOChannel *dev_io; + char *device = NULL, *snoop = NULL; + bdaddr_t bdaddr; + int fd, dd, opt, daemon, dofork, dev = -1; + + bacpy(&bdaddr, BDADDR_ANY); + + /* Configure default settings */ + daemon = 1; dofork = 1; + + while ((opt=getopt_long(argc, argv, "d:b:s:nh", main_options, NULL)) != EOF) { + switch(opt) { + case 'd': + device = strdup(optarg); + break; + + case 'b': + str2ba(optarg, &bdaddr); + break; + + case 's': + snoop = strdup(optarg); + break; + + case 'n': + daemon = 0; + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + if (strlen(argv[0]) > 3 && !strncasecmp(argv[0], "hci", 3)) { + dev = hci_devid(argv[0]); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + } else { + if (getbdaddrbyname(argv[0], &vdev.bdaddr) < 0) + exit(1); + } + + if (daemon) { + if (dofork && fork()) + exit(0); + + /* Direct stdin,stdout,stderr to '/dev/null' */ + fd = open("/dev/null", O_RDWR); + dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); + close(fd); + + setsid(); + + chdir("/"); + } + + /* Start logging to syslog and stderr */ + openlog("hciemu", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + syslog(LOG_INFO, "HCI emulation daemon ver %s started", VERSION); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + io_init(); + + if (!device && dev >= 0) + device = strdup(GHCI_DEV); + + /* Open and create virtual HCI device */ + if (device) { + fd = open(device, O_RDWR); + if (fd < 0) { + syslog(LOG_ERR, "Can't open device %s: %s (%d)", + device, strerror(errno), errno); + free(device); + exit(1); + } + free(device); + } else { + fd = open(VHCI_DEV, O_RDWR); + if (fd < 0) { + fd = open(VHCI_UDEV, O_RDWR); + if (fd < 0) { + syslog(LOG_ERR, "Can't open device %s: %s (%d)", + VHCI_DEV, strerror(errno), errno); + exit(1); + } + } + } + + /* Create snoop file */ + if (snoop) { + dd = create_snoop(snoop); + if (dd < 0) + syslog(LOG_ERR, "Can't create snoop file %s: %s (%d)", + snoop, strerror(errno), errno); + free(snoop); + } else + dd = -1; + + /* Create event loop */ + event_loop = g_main_new(FALSE); + + if (dev >= 0) + return run_proxy(fd, dev, &bdaddr); + + /* Device settings */ + vdev.features[0] = 0xff; + vdev.features[1] = 0xff; + vdev.features[2] = 0x8f; + vdev.features[3] = 0xfe; + vdev.features[4] = 0x9b; + vdev.features[5] = 0xf9; + vdev.features[6] = 0x01; + vdev.features[7] = 0x80; + + memset(vdev.name, 0, sizeof(vdev.name)); + strncpy((char *) vdev.name, "BlueZ (Virtual HCI)", sizeof(vdev.name)); + + vdev.dev_class[0] = 0x00; + vdev.dev_class[1] = 0x00; + vdev.dev_class[2] = 0x00; + + vdev.inq_mode = 0x00; + vdev.eir_fec = 0x00; + memset(vdev.eir_data, 0, sizeof(vdev.eir_data)); + + vdev.fd = fd; + vdev.dd = dd; + + dev_io = g_io_channel_unix_new(fd); + g_io_add_watch(dev_io, G_IO_IN, io_hci_data, NULL); + + setpriority(PRIO_PROCESS, 0, -19); + + /* Start event processor */ + g_main_run(event_loop); + + close(fd); + + if (dd >= 0) + close(dd); + + syslog(LOG_INFO, "Exit"); + + return 0; +} -- 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/attest.c | 2 +- test/bdaddr.c | 2 +- test/hciemu.c | 2 +- test/hstest.c | 2 +- test/l2test.c | 2 +- test/rctest.c | 2 +- test/scotest.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/attest.c b/test/attest.c index 10aec939..59ab1d29 100644 --- a/test/attest.c +++ b/test/attest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2005 Marcel Holtmann + * Copyright (C) 2001-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/bdaddr.c b/test/bdaddr.c index be1419d8..ede77049 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hciemu.c b/test/hciemu.c index be033c2a..f6a35044 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2000-2002 Maxim Krasnyansky - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hstest.c b/test/hstest.c index bea4d3a4..cda9101c 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify 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 diff --git a/test/rctest.c b/test/rctest.c index 724460c7..39ec51b7 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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 diff --git a/test/scotest.c b/test/scotest.c index 169f39b7..281e34cb 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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') 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 +++++++++++++++++++++++- test/rctest.c | 21 ++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) (limited to 'test') 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; diff --git a/test/rctest.c b/test/rctest.c index 39ec51b7..ebcc4c07 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -60,6 +60,12 @@ static unsigned char *buf; static long data_size = 127; static long 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; + /* Default addr and channel */ static bdaddr_t bdaddr; static uint8_t channel = 10; @@ -344,6 +350,9 @@ static void send_mode(int sk) strerror(errno), errno); exit(1); } + + if (num_frames && delay && !(seq % count)) + usleep(delay); } syslog(LOG_INFO, "Closing channel ..."); @@ -399,6 +408,8 @@ static void usage(void) "\t[-b bytes] [-i device] [-P channel]\n" "\t[-L seconds] enabled SO_LINGER option\n" "\t[-N num] number of frames to send\n" + "\t[-C num] send num frames before delay (default = 1)\n" + "\t[-D seconds] delay after sending num frames (default = 0)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" @@ -412,7 +423,7 @@ int main(int argc ,char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:N:MAESL:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:N:MAESL:C:D:")) != EOF) { switch (opt) { case 'r': mode = RECV; @@ -490,6 +501,14 @@ int main(int argc ,char *argv[]) num_frames = atoi(optarg); break; + case 'C': + count = atoi(optarg); + break; + + case 'D': + delay = atoi(optarg) * 1000000; + break; + default: usage(); exit(1); -- 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 ++++---- test/rctest.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'test') 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': diff --git a/test/rctest.c b/test/rctest.c index ebcc4c07..1f26c4c7 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -351,7 +351,7 @@ static void send_mode(int sk) exit(1); } - if (num_frames && delay && !(seq % count)) + if (num_frames && delay && count && !(seq % count)) usleep(delay); } @@ -409,7 +409,7 @@ static void usage(void) "\t[-L seconds] enabled SO_LINGER option\n" "\t[-N num] number of frames to send\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[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" @@ -506,7 +506,7 @@ int main(int argc ,char *argv[]) break; case 'D': - delay = atoi(optarg) * 1000000; + delay = atoi(optarg) * 1000; break; default: -- cgit From 8fa8629fa44075dfa41b1bff96a7951dd40cfb0a Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 5 Apr 2006 14:03:53 +0000 Subject: added timeout new function --- test/Makefile.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 751fa50c..32b32b33 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,7 +6,10 @@ bin_PROGRAMS = l2test rctest noinst_PROGRAMS = scotest attest hstest bdaddr -hciemu_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libglib-ectomy.a +hciemu_LDADD = @BLUEZ_LIBS@ \ + $(top_builddir)/common/libglib-ectomy.a \ + $(top_builddir)/common/liblist.a + l2test_LDADD = @BLUEZ_LIBS@ -- cgit From 28af79147ef8ef1d550b25d960eba4e5f3fb6942 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Apr 2006 23:04:53 +0000 Subject: Add support for ST chips --- test/bdaddr.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index ede77049..a48c85b1 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -68,7 +68,6 @@ static int ericsson_write_bd_addr(int dd, bdaddr_t *bdaddr) return 0; } -#if 0 #define OCF_ERICSSON_STORE_IN_FLASH 0x0022 typedef struct { uint8_t user_id; @@ -101,7 +100,6 @@ static int ericsson_store_in_flash(int dd, uint8_t user_id, uint8_t flash_length return 0; } -#endif static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr) { @@ -240,6 +238,23 @@ static int zeevo_write_bd_addr(int dd, bdaddr_t *bdaddr) return 0; } +static int st_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + return ericsson_store_in_flash(dd, 0xfe, 6, (uint8_t *) bdaddr); +} + +static int st_reset_device(int dd) +{ + bdaddr_t bdaddr; + int err; + + err = hci_send_cmd(dd, 0x03, 0x0003, 0, NULL); + if (err < 0) + return err; + + return hci_read_bd_addr(dd, &bdaddr, 10000); +} + static struct { uint16_t compid; int (*write_bd_addr)(int dd, bdaddr_t *bdaddr); @@ -249,6 +264,7 @@ static struct { { 10, csr_write_bd_addr, csr_reset_device }, { 13, ti_write_bd_addr, NULL, }, { 18, zeevo_write_bd_addr, NULL }, + { 48, st_write_bd_addr, st_reset_device }, { 65535, NULL, NULL }, }; -- cgit From 0625c60f29f27381030c00b188d21773f8a057c4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 17 Apr 2006 01:12:27 +0000 Subject: Mention ST based chips --- test/bdaddr.8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/bdaddr.8 b/test/bdaddr.8 index dbc2099e..78d47945 100644 --- a/test/bdaddr.8 +++ b/test/bdaddr.8 @@ -32,9 +32,9 @@ uses manufacturer specific commands to set the address, and is therefore device specific. For this reason, not all devices are supported, and not all options are supported on all devices. Current supported manufacturers are: -.B Ericsson, Cambridge Silicon Radio (CSR), Texas Instruments (TI) +.B Ericsson, Cambridge Silicon Radio (CSR), Texas Instruments (TI), Zeevo and -.B Zeevo +.B ST Microelectronics (ST) .SH OPTIONS .TP -- cgit From 403066f6cd6f4df68f68178acc2db0926370e95c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Apr 2006 14:30:59 +0000 Subject: Cleanup main function declarations --- test/hciemu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/hciemu.c b/test/hciemu.c index f6a35044..d6996a3e 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -1179,7 +1179,7 @@ static struct option main_options[] = { { 0 } }; -int main(int argc, char *argv[], char *env[]) +int main(int argc, char *argv[]) { struct sigaction sa; GIOChannel *dev_io; -- cgit From b96133c91a2abcc6b0a6de80176623f0ee6f600e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Jun 2006 12:09:30 +0000 Subject: Build a generic helper library --- test/Makefile.am | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 32b32b33..065ebdee 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,10 +6,7 @@ bin_PROGRAMS = l2test rctest noinst_PROGRAMS = scotest attest hstest bdaddr -hciemu_LDADD = @BLUEZ_LIBS@ \ - $(top_builddir)/common/libglib-ectomy.a \ - $(top_builddir)/common/liblist.a - +hciemu_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a l2test_LDADD = @BLUEZ_LIBS@ @@ -21,16 +18,16 @@ attest_LDADD = @BLUEZ_LIBS@ hstest_LDADD = @BLUEZ_LIBS@ -bdaddr_SOURCES = bdaddr.c $(top_builddir)/tools/oui.h $(top_builddir)/tools/oui.c +bdaddr_SOURCES = bdaddr.c -bdaddr_LDADD = @BLUEZ_LIBS@ +bdaddr_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a noinst_MANS = bdaddr.8 AM_CFLAGS = @BLUEZ_CFLAGS@ endif -INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/tools +INCLUDES = -I$(top_srcdir)/common EXTRA_DIST = hsplay hsmicro bdaddr.8 -- cgit From 11d3cfa9cb0e5c78f6788443e824a25922a12d30 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Jun 2006 15:13:47 +0000 Subject: Add ST test utility --- test/Makefile.am | 4 +- test/sttest.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 test/sttest.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 065ebdee..d582b639 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,7 @@ sbin_PROGRAMS = hciemu bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = scotest attest hstest bdaddr +noinst_PROGRAMS = scotest attest hstest bdaddr sttest hciemu_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a @@ -22,6 +22,8 @@ bdaddr_SOURCES = bdaddr.c bdaddr_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a +sttest_LDADD = @BLUEZ_LIBS@ + noinst_MANS = bdaddr.8 AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/test/sttest.c b/test/sttest.c new file mode 100644 index 00000000..3a95fb68 --- /dev/null +++ b/test/sttest.c @@ -0,0 +1,141 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2006 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * 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. + * + * 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. + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define OCF_ERICSSON_WRITE_EVENTS 0x0043 +typedef struct { + uint8_t mask; + uint8_t opcode; + uint8_t opcode_ext; +} __attribute__ ((packed)) ericsson_write_events_cp; +#define ERICSSON_WRITE_EVENTS_CP_SIZE 3 + +static int ericsson_write_events(int dd) +{ + struct hci_request rq; + ericsson_write_events_cp cp; + + memset(&cp, 0, sizeof(cp)); + cp.mask = 0x03; + cp.opcode = 0x00; + cp.opcode_ext = 0x00; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ERICSSON_WRITE_EVENTS; + rq.cparam = &cp; + rq.clen = ERICSSON_WRITE_EVENTS_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + +static void usage(void) +{ + printf("sttest - Utility for ST Microelectronics chips\n\n"); + printf("Usage:\n" + "\tsttest [-i ]\n"); +} + +static struct option main_options[] = { + { "device", 1, 0, 'i' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct hci_version ver; + int dd, opt, dev = 0; + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (ver.manufacturer != 48) { + fprintf(stderr, "Can't find supported device hci%d: %s (%d)\n", + dev, strerror(ENOSYS), ENOSYS); + hci_close_dev(dd); + exit(1); + } + + if (ericsson_write_events(dd) < 0) { + fprintf(stderr, "Can't activate events for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + hci_close_dev(dd); + + return 0; +} -- cgit From 0e9c5be0acf66ffaa851b85a4c0525de09b28fcc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Jun 2006 11:03:30 +0000 Subject: Add support for changing Broadcom device addresses --- test/bdaddr.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index a48c85b1..e317c8ad 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -210,6 +210,34 @@ static int ti_write_bd_addr(int dd, bdaddr_t *bdaddr) return 0; } +#define OCF_BCM_WRITE_BD_ADDR 0x0001 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) bcm_write_bd_addr_cp; +#define BCM_WRITE_BD_ADDR_CP_SIZE 6 + +static int bcm_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + struct hci_request rq; + bcm_write_bd_addr_cp cp; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_BCM_WRITE_BD_ADDR; + rq.cparam = &cp; + rq.clen = BCM_WRITE_BD_ADDR_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 typedef struct { bdaddr_t bdaddr; @@ -263,6 +291,7 @@ static struct { { 0, ericsson_write_bd_addr, NULL }, { 10, csr_write_bd_addr, csr_reset_device }, { 13, ti_write_bd_addr, NULL, }, + { 15, bcm_write_bd_addr, NULL, }, { 18, zeevo_write_bd_addr, NULL }, { 48, st_write_bd_addr, st_reset_device }, { 65535, NULL, NULL }, -- 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 +++++++++++++++++++++++++++++++---------------------------- test/rctest.c | 37 +++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 40 deletions(-) (limited to 'test') 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); diff --git a/test/rctest.c b/test/rctest.c index 1f26c4c7..17d7c5d3 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,8 @@ static unsigned long delay = 0; static bdaddr_t bdaddr; static uint8_t channel = 10; +static char *filename = NULL; + static int master = 0; static int auth = 0; static int encrypt = 0; @@ -329,15 +332,27 @@ static void recv_mode(int sk) } } -static void send_mode(int sk) +static void do_send(int sk) { uint32_t seq; - int i; + 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)) { @@ -354,6 +369,11 @@ static void send_mode(int sk) 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) @@ -407,6 +427,7 @@ static void usage(void) printf("Options:\n" "\t[-b bytes] [-i device] [-P channel]\n" "\t[-L seconds] enabled SO_LINGER option\n" + "\t[-B filename] use data packets from file\n" "\t[-N num] number of frames to send\n" "\t[-C num] send num frames before delay (default = 1)\n" "\t[-D milliseconds] delay after sending num frames (default = 0)\n" @@ -416,14 +437,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,"rdscuwmnb:i:P:N:MAESL:C:D:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:B:N:MAESL:C:D:")) != EOF) { switch (opt) { case 'r': mode = RECV; @@ -497,6 +518,10 @@ int main(int argc ,char *argv[]) linger = atoi(optarg); break; + case 'B': + filename = strdup(optarg); + break; + case 'N': num_frames = atoi(optarg); break; -- cgit From c2a3b84e7e6b6e90d5806897ad6c5c088480673a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jun 2006 07:03:50 +0000 Subject: Add support for changing the BD_ADDR of ISSC chips --- test/bdaddr.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index e317c8ad..91ce5791 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -40,6 +40,18 @@ static int transient = 0; +static int generic_reset_device(int dd) +{ + bdaddr_t bdaddr; + int err; + + err = hci_send_cmd(dd, 0x03, 0x0003, 0, NULL); + if (err < 0) + return err; + + return hci_read_bd_addr(dd, &bdaddr, 10000); +} + #define OCF_ERICSSON_WRITE_BD_ADDR 0x000d typedef struct { bdaddr_t bdaddr; @@ -271,18 +283,6 @@ static int st_write_bd_addr(int dd, bdaddr_t *bdaddr) return ericsson_store_in_flash(dd, 0xfe, 6, (uint8_t *) bdaddr); } -static int st_reset_device(int dd) -{ - bdaddr_t bdaddr; - int err; - - err = hci_send_cmd(dd, 0x03, 0x0003, 0, NULL); - if (err < 0) - return err; - - return hci_read_bd_addr(dd, &bdaddr, 10000); -} - static struct { uint16_t compid; int (*write_bd_addr)(int dd, bdaddr_t *bdaddr); @@ -293,7 +293,8 @@ static struct { { 13, ti_write_bd_addr, NULL, }, { 15, bcm_write_bd_addr, NULL, }, { 18, zeevo_write_bd_addr, NULL }, - { 48, st_write_bd_addr, st_reset_device }, + { 48, st_write_bd_addr, generic_reset_device }, + { 57, ericsson_write_bd_addr, generic_reset_device }, { 65535, NULL, NULL }, }; -- cgit From da33b995b67d60a7f05a6ab068e6e6f3a99a6e8c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jun 2006 08:41:48 +0000 Subject: Use generic reset method for Broadcom chips --- test/bdaddr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/bdaddr.c b/test/bdaddr.c index 91ce5791..aa20123d 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -290,8 +290,8 @@ static struct { } vendor[] = { { 0, ericsson_write_bd_addr, NULL }, { 10, csr_write_bd_addr, csr_reset_device }, - { 13, ti_write_bd_addr, NULL, }, - { 15, bcm_write_bd_addr, NULL, }, + { 13, ti_write_bd_addr, NULL }, + { 15, bcm_write_bd_addr, generic_reset_device }, { 18, zeevo_write_bd_addr, NULL }, { 48, st_write_bd_addr, generic_reset_device }, { 57, ericsson_write_bd_addr, generic_reset_device }, -- 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 ++++++++++++++++------------ test/rctest.c | 30 ++++++++++++++++-------------- 2 files changed, 32 insertions(+), 26 deletions(-) (limited to 'test') 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: diff --git a/test/rctest.c b/test/rctest.c index 17d7c5d3..8de23f78 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -390,22 +390,24 @@ static void reconnect_mode(char *svr) } } -static void multi_connect_mode(char *svr) +static void multi_connect_mode(int argc, char *argv[]) { - while (1) { - int i, sk; - - for (i = 0; i < 10; i++) { - if (fork()) continue; + int i, n, sk; - /* Child */ - sk = do_connect(svr); - usleep(500); - close(sk); - exit(0); + while (1) { + 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); } } @@ -589,7 +591,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 b102348e988e4abc5d579ce13c067ce2c885aaf7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jul 2006 13:32:44 +0000 Subject: Fix declared with attribute warn_unused_result errors --- test/attest.c | 2 +- test/hciemu.c | 37 ++++++++++++++----------------------- test/hstest.c | 4 ++-- 3 files changed, 17 insertions(+), 26 deletions(-) (limited to 'test') diff --git a/test/attest.c b/test/attest.c index 59ab1d29..98fdf5e7 100644 --- a/test/attest.c +++ b/test/attest.c @@ -45,7 +45,7 @@ static int at_command(int fd, char *cmd, int to) char buf[1024]; int sel, len, i, n; - write(fd, cmd, strlen(cmd)); + len = write(fd, cmd, strlen(cmd)); for (i = 0; i < 100; i++) { diff --git a/test/hciemu.c b/test/hciemu.c index d6996a3e..213ca78c 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -219,6 +219,7 @@ static int write_snoop(int fd, int type, int incoming, unsigned char *buf, int l struct timeval tv; uint32_t size = len; uint64_t ts; + int err; if (fd < 0) return -1; @@ -236,8 +237,8 @@ static int write_snoop(int fd, int type, int incoming, unsigned char *buf, int l if (type == HCI_COMMAND_PKT || type == HCI_EVENT_PKT) pkt.flags |= ntohl(0x02); - write(fd, &pkt, BTSNOOP_PKT_SIZE); - write(fd, buf, size); + err = write(fd, &pkt, BTSNOOP_PKT_SIZE); + err = write(fd, buf, size); return 0; } @@ -872,7 +873,7 @@ static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data) unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; hci_acl_hdr *ah; uint16_t flags; - int len, fd; + int fd, err, len; if (cond & G_IO_NVAL) return FALSE; @@ -907,7 +908,7 @@ static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data) write_snoop(vdev.dd, HCI_ACLDATA_PKT, 1, buf, len); - write(vdev.fd, buf, len); + err = write(vdev.fd, buf, len); return TRUE; } @@ -1137,7 +1138,7 @@ static int run_proxy(int fd, int dev, bdaddr_t *bdaddr) len = read(fd, buf, sizeof(buf)); if (len > 0) { rewrite_bdaddr(buf, len, bdaddr); - write(dd, buf, len); + err = write(dd, buf, len); } } @@ -1145,7 +1146,7 @@ static int run_proxy(int fd, int dev, bdaddr_t *bdaddr) len = read(dd, buf, sizeof(buf)); if (len > 0) { rewrite_bdaddr(buf, len, bdaddr); - write(fd, buf, len); + err = write(fd, buf, len); } } } @@ -1185,13 +1186,10 @@ int main(int argc, char *argv[]) GIOChannel *dev_io; char *device = NULL, *snoop = NULL; bdaddr_t bdaddr; - int fd, dd, opt, daemon, dofork, dev = -1; + int fd, dd, opt, detach = 1, dev = -1; bacpy(&bdaddr, BDADDR_ANY); - /* Configure default settings */ - daemon = 1; dofork = 1; - while ((opt=getopt_long(argc, argv, "d:b:s:nh", main_options, NULL)) != EOF) { switch(opt) { case 'd': @@ -1207,7 +1205,7 @@ int main(int argc, char *argv[]) break; case 'n': - daemon = 0; + detach = 0; break; case 'h': @@ -1237,18 +1235,11 @@ int main(int argc, char *argv[]) exit(1); } - if (daemon) { - if (dofork && fork()) - exit(0); - - /* Direct stdin,stdout,stderr to '/dev/null' */ - fd = open("/dev/null", O_RDWR); - dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); - close(fd); - - setsid(); - - chdir("/"); + if (detach) { + if (daemon(0, 0)) { + perror("Can't start daemon"); + exit(1); + } } /* Start logging to syslog and stderr */ diff --git a/test/hstest.c b/test/hstest.c index cda9101c..d94ade20 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -159,7 +159,7 @@ int main(int argc, char *argv[]) char *filename; mode_t filemode; - int mode = 0; + int err, mode = 0; int dd, rd, sd, fd; uint16_t sco_handle, sco_mtu, vs; @@ -245,7 +245,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "SCO audio channel connected (handle %d, mtu %d)\n", sco_handle, sco_mtu); if (mode == RECORD) - write(rd, "RING\r\n", 6); + err = write(rd, "RING\r\n", 6); maxfd = (rd > sd) ? rd : sd; -- 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/hciemu.c | 2 +- test/l2test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/hciemu.c b/test/hciemu.c index 213ca78c..37e80318 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -1128,7 +1128,7 @@ static int run_proxy(int fd, int dev, bdaddr_t *bdaddr) while (!__io_canceled) { p[0].revents = 0; p[1].revents = 0; - err = poll(p, 2, 100); + err = poll(p, 2, 500); if (err < 0) break; if (!err) 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 2f1fece0402ce32292bc17dae43e3becbd19683f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 26 Aug 2006 17:26:18 +0000 Subject: Fix hciemu GIOChannel usage --- test/hciemu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/hciemu.c b/test/hciemu.c index 37e80318..2631868d 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -503,6 +503,7 @@ static void close_connection(struct vhci_conn *conn) batostr(&conn->dest), conn->handle); g_io_channel_close(conn->chan); + g_io_channel_unref(conn->chan); vconn[conn->handle - 1] = NULL; disconn_complete(conn); @@ -875,8 +876,10 @@ static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data) uint16_t flags; int fd, err, len; - if (cond & G_IO_NVAL) + if (cond & G_IO_NVAL) { + g_io_channel_unref(chan); return FALSE; + } if (cond & G_IO_HUP) { close_connection(conn); @@ -975,6 +978,7 @@ static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data) return TRUE; syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); + g_io_channel_unref(chan); g_main_quit(event_loop); return FALSE; } -- cgit From 87268f7c7c0804afb5865d9ead1cae2473090ff3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 29 Aug 2006 22:08:09 +0000 Subject: Add sdptest utility --- test/Makefile.am | 4 +- test/sdptest.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 test/sdptest.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index d582b639..ad596f50 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,7 @@ sbin_PROGRAMS = hciemu bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = scotest attest hstest bdaddr sttest +noinst_PROGRAMS = sdptest scotest attest hstest bdaddr sttest hciemu_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a @@ -12,6 +12,8 @@ l2test_LDADD = @BLUEZ_LIBS@ rctest_LDADD = @BLUEZ_LIBS@ +sdptest_LDADD = @BLUEZ_LIBS@ + scotest_LDADD = @BLUEZ_LIBS@ attest_LDADD = @BLUEZ_LIBS@ diff --git a/test/sdptest.c b/test/sdptest.c new file mode 100644 index 00000000..f0184cc1 --- /dev/null +++ b/test/sdptest.c @@ -0,0 +1,142 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2006 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * 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. + * + * 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. + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static volatile sig_atomic_t __io_finished = 0; + +static void callback(uint8_t type, uint16_t status, + uint8_t *rsp, size_t size, void *udata) +{ + int i; + + for (i = 0; i < size; i++) { + printf("%02x ", rsp[i]); + if ((i + 1) % 8 == 0) + printf(" "); + if ((i + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); + + __io_finished = 1; +} + +static void cmd_search(bdaddr_t *src, bdaddr_t *dst) +{ + sdp_session_t *session; + sdp_list_t *search, *attrids; + uint32_t range = 0x0000ffff; + uuid_t uuid; + + session = sdp_connect(src, dst, 0); + if (!session) { + perror("Can't connect to SDP service"); + exit(1); + } + + sdp_set_notify(session, callback, NULL); + + sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); + + search = sdp_list_append(NULL, &uuid); + + attrids = sdp_list_append(NULL, &range); + + sdp_service_search_attr_async(session, search, + SDP_ATTR_REQ_RANGE, attrids); + + sdp_list_free(search, NULL); + + while (!__io_finished) + sdp_process(session); + + sdp_close(session); +} + +static void usage(void) +{ + printf("sdptest - Utility for SDP testing\n\n"); + printf("Usage:\n" + "\tsdptest [-i ] \n"); +} + +static struct option main_options[] = { + { "device", 1, 0, 'i' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + bdaddr_t src, dst; + int opt; + + bacpy(&src, BDADDR_ANY); + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &src); + else + str2ba(optarg, &dst); + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + str2ba(argv[0], &dst); + + cmd_search(&src, &dst); + + return 0; +} -- cgit From 75dc7cdf39d34c98244c7b98340a1541c421ed68 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Aug 2006 22:37:55 +0000 Subject: Call sdp_service_search_async() as first test case --- test/sdptest.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/sdptest.c b/test/sdptest.c index f0184cc1..a1a8abd0 100644 --- a/test/sdptest.c +++ b/test/sdptest.c @@ -78,8 +78,12 @@ static void cmd_search(bdaddr_t *src, bdaddr_t *dst) attrids = sdp_list_append(NULL, &range); - sdp_service_search_attr_async(session, search, - SDP_ATTR_REQ_RANGE, attrids); + //sdp_service_search_attr_async(session, search, + // SDP_ATTR_REQ_RANGE, attrids); + + sdp_service_search_async(session, search, 0xffff); + + sdp_list_free(attrids, NULL); sdp_list_free(search, NULL); -- cgit From 117091aff7a9416b9fe58214b8a9118cd88a9fb3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Sep 2006 10:54:36 +0000 Subject: More compatible usage of test --- test/hsplay | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/hsplay b/test/hsplay index 5f53562b..8cecbffa 100755 --- a/test/hsplay +++ b/test/hsplay @@ -9,7 +9,7 @@ then HSTEST="./hstest" fi -if [ -z "$1" -o -z "$2" ] +if [ -z "$1" ] || [ -z "$2" ] then echo -e "Usage:\n\thsplay [channel]" exit -- 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') 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') 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 41e91c49a5d682c375d3af21057b01fa43c29bea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 28 Sep 2006 15:23:24 +0000 Subject: Add apitest utility --- test/Makefile.am | 2 +- test/apitest | 432 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 433 insertions(+), 1 deletion(-) create mode 100755 test/apitest (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index ad596f50..dde68ed0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -33,6 +33,6 @@ endif INCLUDES = -I$(top_srcdir)/common -EXTRA_DIST = hsplay hsmicro bdaddr.8 +EXTRA_DIST = apitest hsplay hsmicro bdaddr.8 MAINTAINERCLEANFILES = Makefile.in diff --git a/test/apitest b/test/apitest new file mode 100755 index 00000000..83988896 --- /dev/null +++ b/test/apitest @@ -0,0 +1,432 @@ +#!/usr/bin/env python + +import dbus +import dbus.decorators +import dbus.glib +import gobject +import sys +import getopt +from signal import * + +mgr_cmds = [ "InterfaceVersion", "ListAdapters", "DefaultAdapter" ] +mgr_signals = [ "AdapterAdded", "AdapterRemoved" ] + +dev_cmds = [ "GetAddress", + "GetVersion", + "GetRevision", + "GetManufacturer", + "GetCompany", + "GetMode", + "SetMode", + "GetDiscoverableTimeout", + "SetDiscoverableTimeout", + "IsConnectable", + "IsDiscoverable", + "IsConnected", + "ListConnections", + "GetMajorClass", + "ListAvailableMinorClasses", + "GetMinorClass", + "SetMinorClass", + "GetServiceClasses", + "GetName", + "SetName", + "GetRemoteVersion", + "GetRemoteRevision", + "GetRemoteManufacturer", + "GetRemoteCompany", + "GetRemoteMajorClass", + "GetRemoteMinorClass", + "GetRemoteServiceClasses", + "GetRemoteClass", + "GetRemoteName", + "GetRemoteAlias", + "SetRemoteAlias", + "ClearRemoteAlias", + "LastSeen", + "LastUsed", + "DisconnectRemoteDevice", + "CreateBonding", + "CancelBondingProcess", + "RemoveBonding", + "HasBonding", + "ListBondings", + "GetPinCodeLength", + "GetEncryptionKeySize", + "DiscoverDevices", + "DiscoverDevicesWithoutNameResolving", + "CancelDiscovery" ] +dev_signals = [ "ModeChanged", + "NameChanged", + "MinorClassChanged", + "DiscoveryStarted", + "DiscoveryCompleted", + "RemoteDeviceFound", + "RemoteNameUpdated", + "RemoteNameFailed", + "RemoteAliasChanged" + "RemoteAliasCleared", + "RemoteDeviceConnected", + "RemoteDeviceDisconnected", + "BondingCreated", + "BondingRemoved" ] + +dev_signals_filter = [ "/org/bluez/hci0", "/org/bluez/hci1", + "/org/bluez/hci2", "/org/bluez/hci3", + "/org/bluez/hci4", "/org/bluez/hci5", + "/org/bluez/hci6", "/org/bluez/hci7" ] + +class Tester: + exit_events = [] + dev_path = None + need_dev = False + listen = False + at_interrupt = None + + def __init__(self, argv): + self.name = argv[0] + + self.parse_args(argv[1:]) + + try: + self.dbus_setup() + except dbus.DBusException, e: + print 'Failed to do D-Bus setup: %s' % e + sys.exit(1) + + def parse_args(self, argv): + try: + opts, args = getopt.getopt(argv, "hli:") + except getopt.GetoptError: + self.usage() + sys.exit(1) + + for o, a in opts: + if o == "-h": + self.usage() + sys.exit() + elif o == "-l": + self.listen = True + elif o == "-i": + if a[0] == '/': + self.dev_path = a + else: + self.dev_path = '/org/bluez/%s' % a + + if not (args or self.listen): + self.usage() + sys.exit(1) + + if args: + self.cmd = args[0] + self.cmd_args = args[1:] + + def dbus_dev_setup(self): + if not self.dev_path: + try: + self.dbus_mgr_setup() + self.dev_path = self.manager.DefaultAdapter() + except dbus.DBusException, e: + print 'Failed to get default device: %s' % e + sys.exit(1) + try: + obj = self.bus.get_object('org.bluez', self.dev_path) + self.device = dbus.Interface(obj, 'org.bluez.Adapter') + except dbus.DBusException, e: + print 'Failed to setup device path: %s' % e + sys.exit(1) + + def dbus_dev_sig_setup(self): + try: + for signal in dev_signals: + for path in dev_signals_filter: + self.bus.add_signal_receiver(self.dev_signal_handler, + signal, 'org.bluez.Adapter', + 'org.bluez', path) + except dbus.DBusException, e: + print 'Failed to setup signal handler for device path: %s' % e + sys.exit(1) + + def dbus_mgr_sig_setup(self): + try: + for signal in mgr_signals: + self.bus.add_signal_receiver(self.mgr_signal_handler, + signal,'org.bluez.Manager', + 'org.bluez', '/org/bluez') + except dbus.DBusException, e: + print 'Failed to setup signal handler for manager path: %s' % e + sys.exit(1) + + def dbus_mgr_setup(self): + self.manager_obj = self.bus.get_object('org.bluez', '/org/bluez') + self.manager = dbus.Interface(self.manager_obj, 'org.bluez.Manager') + + def dbus_setup(self): + self.bus = dbus.SystemBus() + + def usage(self): + print 'Usage: %s [-i ] [-l] [-h] [arg1..]' % self.name + print ' -i Specify device (e.g. "hci0" or "/org/bluez/hci0")' + print ' -l Listen for events (no command required)' + print ' -h Show this help' + print 'Manager commands:' + for cmd in mgr_cmds: + print '\t%s' % cmd + print 'Adapter commands:' + for cmd in dev_cmds: + print '\t%s' % cmd + + @dbus.decorators.explicitly_pass_message + def dev_signal_handler(*args, **keywords): + dbus_message = keywords["dbus_message"] + print '%s - %s: ' % (dbus_message.get_member(), dbus_message.get_path()), + for arg in args[1:]: + print '%s ' % arg, + print + + @dbus.decorators.explicitly_pass_message + def mgr_signal_handler(*args, **keywords): + dbus_message = keywords["dbus_message"] + print '%s: ' % dbus_message.get_member() + for arg in args[1:]: + print '%s ' % arg, + print + + def signal_cb(self, sig, frame): + print 'Caught signal, exiting' + if self.at_interrupt: + self.at_interrupt() + self.main_loop.quit() + + def call_mgr_dbus_func(self): + if self.cmd == 'InterfaceVersion': + try: + print self.manager.InterfaceVersion() + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + if self.cmd == 'ListAdapters': + try: + devices = self.manager.ListAdapters() + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + for device in devices: + print device + elif self.cmd == 'DefaultAdapter': + try: + print self.manager.DefaultAdapter() + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + + def call_dev_dbus_func(self): + try: + if self.cmd == 'GetAddress': + print self.device.GetAddress() + elif self.cmd == 'GetManufacturer': + print self.device.GetManufacturer() + elif self.cmd == 'GetVersion': + print self.device.GetVersion() + elif self.cmd == 'GetRevision': + print self.device.GetRevision() + elif self.cmd == 'GetCompany': + print self.device.GetCompany() + elif self.cmd == 'GetMode': + print self.device.GetMode() + elif self.cmd == 'SetMode': + if len(self.cmd_args) == 1: + self.device.SetMode(self.cmd_args[0]) + else: + print 'Usage: %s -i SetMode scan_mode' % self.name + elif self.cmd == 'GetDiscoverableTimeout': + print '%u' % (self.device.GetDiscoverableTimeout()) + elif self.cmd == 'SetDiscoverableTimeout': + if len(self.cmd_args) == 1: + self.device.SetDiscoverableTimeout(dbus.UInt32(self.cmd_args[0])) + else: + print 'Usage: %s -i SetDiscoverableTimeout timeout' % self.name + elif self.cmd == 'IsConnectable': + print self.device.IsConnectable() + elif self.cmd == 'IsDiscoverable': + print self.device.IsDiscoverable() + elif self.cmd == 'IsConnected': + if len(self.cmd_args) == 1: + print self.device.IsConnected(self.cmd_args[0]) + else: + print 'Usage: %s -i IsConnected address' % self.name + elif self.cmd == 'ListConnections': + print self.device.ListConnections() + elif self.cmd == 'GetMajorClass': + print self.device.GetMajorClass() + elif self.cmd == 'ListAvailableMinorClasses': + print self.device.ListAvailableMinorClasses() + elif self.cmd == 'GetMinorClass': + print self.device.GetMinorClass() + elif self.cmd == 'SetMinorClass': + if len(self.cmd_args) == 1: + self.device.SetMinorClass(self.cmd_args[0]) + else: + print 'Usage: %s -i SetMinorClass minor' % self.name + elif self.cmd == 'GetServiceClasses': + classes = self.device.GetServiceClasses() + for clas in classes: + print clas, + elif self.cmd == 'GetName': + print self.device.GetName() + elif self.cmd == 'SetName': + if len(self.cmd_args) == 1: + self.device.SetName(self.cmd_args[0]) + else: + print 'Usage: %s -i SetName newname' % self.name + elif self.cmd == 'GetRemoteName': + if len(self.cmd_args) == 1: + print self.device.GetRemoteName(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteName address' % self.name + elif self.cmd == 'GetRemoteVersion': + if len(self.cmd_args) == 1: + print self.device.GetRemoteVersion(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteVersion address' % self.name + elif self.cmd == 'GetRemoteRevision': + if len(self.cmd_args) == 1: + print self.device.GetRemoteRevision(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteRevision address' % self.name + elif self.cmd == 'GetRemoteManufacturer': + if len(self.cmd_args) == 1: + print self.device.GetRemoteManufacturer(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteManufacturer address' % self.name + elif self.cmd == 'GetRemoteCompany': + if len(self.cmd_args) == 1: + print self.device.GetRemoteCompany(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteCompany address' % self.name + elif self.cmd == 'GetRemoteAlias': + if len(self.cmd_args) == 1: + print self.device.GetRemoteAlias(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteAlias address' % self.name + elif self.cmd == 'GetRemoteMajorClass': + if len(self.cmd_args) == 1: + print self.device.GetRemoteMajorClass(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteMajorClass address' % self.name + elif self.cmd == 'GetRemoteMinorClass': + if len(self.cmd_args) == 1: + print self.device.GetRemoteMinorClass(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteMinorClass address' % self.name + elif self.cmd == 'GetRemoteServiceClasses': + if len(self.cmd_args) == 1: + print self.device.GetRemoteServiceClasses(self.cmd_args[0]) + else: + print 'Usage: %s -i GetRemoteServiceClasses address' % self.name + elif self.cmd == 'SetRemoteAlias': + if len(self.cmd_args) == 2: + self.device.SetRemoteAlias(self.cmd_args[0], self.cmd_args[1]) + else: + print 'Usage: %s -i SetRemoteAlias address alias' % self.name + elif self.cmd == 'ClearRemoteAlias': + if len(self.cmd_args) == 1: + print self.device.ClearRemoteAlias(self.cmd_args[0]) + else: + print 'Usage: %s -i ClearRemoteAlias address' % self.name + elif self.cmd == 'LastSeen': + if len(self.cmd_args) == 1: + print self.device.LastSeen(self.cmd_args[0]) + else: + print 'Usage: %s -i LastSeen address' % self.name + elif self.cmd == 'LastUsed': + if len(self.cmd_args) == 1: + print self.device.LastUsed(self.cmd_args[0]) + else: + print 'Usage: %s -i LastUsed address' % self.name + elif self.cmd == 'DisconnectRemoteDevice': + if len(self.cmd_args) == 1: + print self.device.LastUsed(self.cmd_args[0]) + else: + print 'Usage: %s -i DisconnectRemoteDevice address' % self.name + elif self.cmd == 'CreateBonding': + if len(self.cmd_args) == 1: + print self.device.CreateBonding(self.cmd_args[0]) + else: + print 'Usage: %s -i CreateBonding address' % self.name + elif self.cmd == 'RemoveBonding': + if len(self.cmd_args) == 1: + print self.device.RemoveBonding(self.cmd_args[0]) + else: + print 'Usage: %s -i RemoveBonding address' % self.name + elif self.cmd == 'CancelBondingProcess': + if len(self.cmd_args) == 1: + print self.device.CancelBondingProcess(self.cmd_args[0]) + else: + print 'Usage: %s -i CancelBondingProcess address' % self.name + elif self.cmd == 'HasBonding': + if len(self.cmd_args) == 1: + print self.device.HasBonding(self.cmd_args[0]) + else: + print 'Usage: %s -i HasBonding address' % self.name + elif self.cmd == 'ListBondings': + bondings = self.device.ListBondings() + for bond in bondings: + print bond, + elif self.cmd == 'GetPinCodeLength': + if len(self.cmd_args) == 1: + print self.device.GetPinCodeLength(self.cmd_args[0]) + else: + print 'Usage: %s -i GetPinCodeLength address' % self.name + elif self.cmd == 'GetEncryptionKeySize': + if len(self.cmd_args) == 1: + print self.device.GetEncryptionKeySize(self.cmd_args[0]) + else: + print 'Usage: %s -i GetEncryptionKeySize address' % self.name + elif self.cmd == 'DiscoverDevices': + print self.device.DiscoverDevices() + elif self.cmd == 'DiscoverDevicesWithoutNameResolving': + print self.device.DiscoverDevicesWithoutNameResolving() + else: + # FIXME: remove at future version + print 'Script Error: Method %s not found. Maybe a mispelled word.' % (self.cmd_args) + except dbus.DBusException, e: + print '%s failed: %s' % (self.cmd, e) + sys.exit(1) + + def run(self): + # Manager methods + if self.listen: + self.dbus_mgr_sig_setup() + self.dbus_dev_sig_setup() + print 'Listening for events...' + elif self.cmd in mgr_cmds: + try: + self.dbus_mgr_setup() + except dbus.DBusException, e: + print 'Failed to setup manager interface: %s' % e + sys.exit(1) + self.call_mgr_dbus_func() + elif self.cmd in dev_cmds: + try: + self.dbus_dev_setup() + except dbus.DBusException, e: + print 'Failed to setup device interface: %s' % e + sys.exit(1) + self.call_dev_dbus_func() + else: + print 'Unknown command: %s' % self.cmd + self.usage() + sys.exit(1) + + if self.listen: + signal(SIGINT, self.signal_cb) + signal(SIGTERM, self.signal_cb) + self.main_loop = gobject.MainLoop() + self.main_loop.run() + +if __name__ == '__main__': + gobject.threads_init() + dbus.glib.init_threads() + + tester = Tester(sys.argv) + tester.run() -- cgit From b31cef173e499db68ebdeb56708d300b8a1942d5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Sep 2006 18:45:25 +0000 Subject: Add simple D-Bus preload script for Python --- test/Makefile.am | 2 +- test/dbusdef.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test/dbusdef.py (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index dde68ed0..7b1f0713 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -33,6 +33,6 @@ endif INCLUDES = -I$(top_srcdir)/common -EXTRA_DIST = apitest hsplay hsmicro bdaddr.8 +EXTRA_DIST = apitest hsplay hsmicro bdaddr.8 dbusdef.py MAINTAINERCLEANFILES = Makefile.in diff --git a/test/dbusdef.py b/test/dbusdef.py new file mode 100644 index 00000000..29cf7ffc --- /dev/null +++ b/test/dbusdef.py @@ -0,0 +1,7 @@ +import dbus + +bus = dbus.SystemBus() + +manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager') + +adapter = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Adapter') -- cgit From d78dcb8b79e0db5dddab5f98cd825c69f0bf9938 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Sep 2006 19:11:48 +0000 Subject: Add experimental objects --- test/dbusdef.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test') diff --git a/test/dbusdef.py b/test/dbusdef.py index 29cf7ffc..150c5b66 100644 --- a/test/dbusdef.py +++ b/test/dbusdef.py @@ -5,3 +5,9 @@ bus = dbus.SystemBus() manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager') adapter = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Adapter') + +test = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Test') + +rfcomm = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.RFCOMM') + +sdp = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.SDP') -- cgit From 8f0584a2042946f1bbe41b48a57c3a824ffd443b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 19 Oct 2006 12:48:59 +0000 Subject: Allow listening for events even when a command is sent --- test/apitest | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/apitest b/test/apitest index 83988896..6d16e7ac 100755 --- a/test/apitest +++ b/test/apitest @@ -399,7 +399,8 @@ class Tester: self.dbus_mgr_sig_setup() self.dbus_dev_sig_setup() print 'Listening for events...' - elif self.cmd in mgr_cmds: + + if self.cmd in mgr_cmds: try: self.dbus_mgr_setup() except dbus.DBusException, e: @@ -413,7 +414,7 @@ class Tester: print 'Failed to setup device interface: %s' % e sys.exit(1) self.call_dev_dbus_func() - else: + elif not self.listen: print 'Unknown command: %s' % self.cmd self.usage() sys.exit(1) -- cgit From b467488a2ed54badfff71b4aa892ded051670aa3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 29 Oct 2006 16:50:26 +0000 Subject: Add service objects --- test/dbusdef.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'test') diff --git a/test/dbusdef.py b/test/dbusdef.py index 150c5b66..f039cd4b 100644 --- a/test/dbusdef.py +++ b/test/dbusdef.py @@ -11,3 +11,18 @@ test = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'or rfcomm = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.RFCOMM') sdp = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.SDP') + +echo = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/echo'), 'org.bluez.Service') + +network = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/network'), 'org.bluez.Service') + +input = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/input'), 'org.bluez.Service') + +audio = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/audio'), 'org.bluez.Service') + +def connect_echo() : + return dbus.Interface(bus.get_object(echo.GetConnectionName(), '/org/bluez/echo'), 'org.freedesktop.DBus.Introspectable') + +def connect_holtmann() : + holtmann = dbus.Interface(bus.get_object('org.bluez', '/org/holtmann'), 'org.bluez.Service') + return dbus.Interface(bus.get_object(holtmann.GetConnectionName(), '/org/holtmann'), 'org.freedesktop.DBus.Introspectable') -- cgit From 326cf15e58c699fb2fb62181fcdd47339ec60c15 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 10 Nov 2006 17:20:25 +0000 Subject: Support for ListRemoteDevices and ListRecentRemoteDevices --- test/apitest | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/apitest b/test/apitest index 6d16e7ac..1c955136 100755 --- a/test/apitest +++ b/test/apitest @@ -55,7 +55,9 @@ dev_cmds = [ "GetAddress", "GetEncryptionKeySize", "DiscoverDevices", "DiscoverDevicesWithoutNameResolving", - "CancelDiscovery" ] + "CancelDiscovery", + "ListRemoteDevices", + "ListRecentRemoteDevices" ] dev_signals = [ "ModeChanged", "NameChanged", "MinorClassChanged", @@ -386,6 +388,17 @@ class Tester: print self.device.DiscoverDevices() elif self.cmd == 'DiscoverDevicesWithoutNameResolving': print self.device.DiscoverDevicesWithoutNameResolving() + elif self.cmd == 'ListRemoteDevices': + devices = self.device.ListRemoteDevices() + for device in devices: + print device, + elif self.cmd == 'ListRecentRemoteDevices': + if len(self.cmd_args) == 1: + devices = self.device.ListRecentRemoteDevices(self.cmd_args[0]) + for device in devices: + print device, + else: + print 'Usage: %s -i ListRecentRemoteDevices date' % self.name else: # FIXME: remove at future version print 'Script Error: Method %s not found. Maybe a mispelled word.' % (self.cmd_args) -- cgit From 6033ee0c9966238f3732e945841d85ddb5162cc2 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 3 Jan 2007 12:14:01 +0000 Subject: Add disconnection delay and RemoteDeviceDisconnectRequested signal for the DisconnectRemoteDevice method --- test/apitest | 1 + 1 file changed, 1 insertion(+) (limited to 'test') diff --git a/test/apitest b/test/apitest index 1c955136..601cf8df 100755 --- a/test/apitest +++ b/test/apitest @@ -69,6 +69,7 @@ dev_signals = [ "ModeChanged", "RemoteAliasChanged" "RemoteAliasCleared", "RemoteDeviceConnected", + "RemoteDeviceDisconnectRequested", "RemoteDeviceDisconnected", "BondingCreated", "BondingRemoved" ] -- cgit From 0d68e70bb86132a935e1521f3bf430f404f91afe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 12 Jan 2007 00:49:27 +0000 Subject: Allow compilation against GLib --- test/Makefile.am | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 7b1f0713..93ad39b9 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,12 @@ +if GLIB +glib_cflags = @GLIB_CFLAGS@ +glib_ldadd = @GLIB_LIBS@ +else +glib_cflags = +glib_ldadd = +endif + if TEST sbin_PROGRAMS = hciemu @@ -6,7 +14,7 @@ bin_PROGRAMS = l2test rctest noinst_PROGRAMS = sdptest scotest attest hstest bdaddr sttest -hciemu_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a +hciemu_LDADD = $(glib_ldadd) @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a l2test_LDADD = @BLUEZ_LIBS@ @@ -28,7 +36,7 @@ sttest_LDADD = @BLUEZ_LIBS@ noinst_MANS = bdaddr.8 -AM_CFLAGS = @BLUEZ_CFLAGS@ +AM_CFLAGS = @BLUEZ_CFLAGS@ $(glib_cflags) endif INCLUDES = -I$(top_srcdir)/common -- 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/attest.c | 2 +- test/bdaddr.c | 2 +- test/hciemu.c | 2 +- test/hstest.c | 2 +- test/l2test.c | 2 +- test/rctest.c | 2 +- test/scotest.c | 2 +- test/sdptest.c | 2 +- test/sttest.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/attest.c b/test/attest.c index 98fdf5e7..23c99aeb 100644 --- a/test/attest.c +++ b/test/attest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2006 Marcel Holtmann + * Copyright (C) 2001-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/bdaddr.c b/test/bdaddr.c index aa20123d..0d2d7e83 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hciemu.c b/test/hciemu.c index 2631868d..a974a0c1 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2000-2002 Maxim Krasnyansky - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hstest.c b/test/hstest.c index d94ade20..2a6ae593 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify 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 diff --git a/test/rctest.c b/test/rctest.c index 8de23f78..ff3b50e8 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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 diff --git a/test/scotest.c b/test/scotest.c index 281e34cb..22da3497 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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 diff --git a/test/sdptest.c b/test/sdptest.c index a1a8abd0..89b30dd3 100644 --- a/test/sdptest.c +++ b/test/sdptest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2005-2006 Marcel Holtmann + * Copyright (C) 2005-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/sttest.c b/test/sttest.c index 3a95fb68..8ee44638 100644 --- a/test/sttest.c +++ b/test/sttest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2005-2006 Marcel Holtmann + * Copyright (C) 2005-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 331c95a5f378b5c6483d98fd4eceafa38c6fb57a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 14 Jan 2007 22:43:52 +0000 Subject: Works also with a Philips chip --- test/sttest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/sttest.c b/test/sttest.c index 8ee44638..8f714489 100644 --- a/test/sttest.c +++ b/test/sttest.c @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) exit(1); } - if (ver.manufacturer != 48) { + if (ver.manufacturer != 37 && ver.manufacturer != 48) { fprintf(stderr, "Can't find supported device hci%d: %s (%d)\n", dev, strerror(ENOSYS), ENOSYS); hci_close_dev(dd); -- cgit From 8f94be819dc3173ff0f023bf5a3d41a527a612ed Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 15 Jan 2007 20:05:22 +0000 Subject: Add LMP test utility --- test/Makefile.am | 4 +- test/lmptest.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/sttest.c | 141 -------------------------------------------- 3 files changed, 177 insertions(+), 143 deletions(-) create mode 100644 test/lmptest.c delete mode 100644 test/sttest.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 93ad39b9..18989ba5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -12,7 +12,7 @@ sbin_PROGRAMS = hciemu bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = sdptest scotest attest hstest bdaddr sttest +noinst_PROGRAMS = sdptest scotest attest hstest bdaddr lmptest hciemu_LDADD = $(glib_ldadd) @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a @@ -32,7 +32,7 @@ bdaddr_SOURCES = bdaddr.c bdaddr_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a -sttest_LDADD = @BLUEZ_LIBS@ +lmptest_LDADD = @BLUEZ_LIBS@ noinst_MANS = bdaddr.8 diff --git a/test/lmptest.c b/test/lmptest.c new file mode 100644 index 00000000..39a906a2 --- /dev/null +++ b/test/lmptest.c @@ -0,0 +1,175 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * 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. + * + * 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. + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if 0 +#define OCF_ERICSSON_SEND_LMP 0x0021 +typedef struct { + uint16_t handle; + uint8_t length; + uint8_t data[17]; +} __attribute__ ((packed)) ericsson_send_lmp_cp; +#define ERICSSON_SEND_LMP_CP_SIZE 20 + +static int ericsson_send_lmp(int dd, uint16_t handle, uint8_t length, uint8_t *data) +{ + struct hci_request rq; + ericsson_send_lmp_cp cp; + + memset(&cp, 0, sizeof(cp)); + cp.handle = htobs(handle); + cp.length = length; + memcpy(cp.data, data, length); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ERICSSON_SEND_LMP; + rq.cparam = &cp; + rq.clen = ERICSSON_SEND_LMP_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} +#endif + +#define OCF_ERICSSON_WRITE_EVENTS 0x0043 +typedef struct { + uint8_t mask; + uint8_t opcode; + uint8_t opcode_ext; +} __attribute__ ((packed)) ericsson_write_events_cp; +#define ERICSSON_WRITE_EVENTS_CP_SIZE 3 + +static int ericsson_write_events(int dd, uint8_t mask) +{ + struct hci_request rq; + ericsson_write_events_cp cp; + + memset(&cp, 0, sizeof(cp)); + cp.mask = mask; + cp.opcode = 0x00; + cp.opcode_ext = 0x00; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ERICSSON_WRITE_EVENTS; + rq.cparam = &cp; + rq.clen = ERICSSON_WRITE_EVENTS_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + +static void usage(void) +{ + printf("lmptest - Utility for testing special LMP functions\n\n"); + printf("Usage:\n" + "\tlmptest [-i ]\n"); +} + +static struct option main_options[] = { + { "device", 1, 0, 'i' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct hci_version ver; + int dd, opt, dev = 0; + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (ver.manufacturer != 37 && ver.manufacturer != 48) { + fprintf(stderr, "Can't find supported device hci%d: %s (%d)\n", + dev, strerror(ENOSYS), ENOSYS); + hci_close_dev(dd); + exit(1); + } + + if (ericsson_write_events(dd, 0x03) < 0) { + fprintf(stderr, "Can't activate events for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + hci_close_dev(dd); + + return 0; +} diff --git a/test/sttest.c b/test/sttest.c deleted file mode 100644 index 8f714489..00000000 --- a/test/sttest.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2005-2007 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * 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. - * - * 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. - * - * 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 - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define OCF_ERICSSON_WRITE_EVENTS 0x0043 -typedef struct { - uint8_t mask; - uint8_t opcode; - uint8_t opcode_ext; -} __attribute__ ((packed)) ericsson_write_events_cp; -#define ERICSSON_WRITE_EVENTS_CP_SIZE 3 - -static int ericsson_write_events(int dd) -{ - struct hci_request rq; - ericsson_write_events_cp cp; - - memset(&cp, 0, sizeof(cp)); - cp.mask = 0x03; - cp.opcode = 0x00; - cp.opcode_ext = 0x00; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_ERICSSON_WRITE_EVENTS; - rq.cparam = &cp; - rq.clen = ERICSSON_WRITE_EVENTS_CP_SIZE; - rq.rparam = NULL; - rq.rlen = 0; - - if (hci_send_req(dd, &rq, 1000) < 0) - return -1; - - return 0; -} - -static void usage(void) -{ - printf("sttest - Utility for ST Microelectronics chips\n\n"); - printf("Usage:\n" - "\tsttest [-i ]\n"); -} - -static struct option main_options[] = { - { "device", 1, 0, 'i' }, - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - struct hci_version ver; - int dd, opt, dev = 0; - - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { - switch (opt) { - case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } - break; - - case 'h': - default: - usage(); - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - dd = hci_open_dev(dev); - if (dd < 0) { - fprintf(stderr, "Can't open device hci%d: %s (%d)\n", - dev, strerror(errno), errno); - exit(1); - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - fprintf(stderr, "Can't read version for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (ver.manufacturer != 37 && ver.manufacturer != 48) { - fprintf(stderr, "Can't find supported device hci%d: %s (%d)\n", - dev, strerror(ENOSYS), ENOSYS); - hci_close_dev(dd); - exit(1); - } - - if (ericsson_write_events(dd) < 0) { - fprintf(stderr, "Can't activate events for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - hci_close_dev(dd); - - return 0; -} -- cgit From 2666321aed1ad39b9dd3f25879d0993e9f51ed17 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 16 Jan 2007 11:18:21 +0000 Subject: Adapt to the service interface changes --- test/dbusdef.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/dbusdef.py b/test/dbusdef.py index f039cd4b..c48f8479 100644 --- a/test/dbusdef.py +++ b/test/dbusdef.py @@ -2,6 +2,7 @@ import dbus bus = dbus.SystemBus() + manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager') adapter = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Adapter') @@ -10,19 +11,22 @@ test = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'or rfcomm = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.RFCOMM') -sdp = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.SDP') -echo = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/echo'), 'org.bluez.Service') +def create_service(identifier): + try: + path = manager.FindService(identifier) + except: + path = "" + + if (path != ""): + return dbus.Interface(bus.get_object('org.bluez', path), 'org.bluez.Service') -network = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/network'), 'org.bluez.Service') +transfer = create_service("transfer") -input = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/input'), 'org.bluez.Service') +network = create_service("network") -audio = dbus.Interface(bus.get_object('org.bluez', '/org/bluez/audio'), 'org.bluez.Service') +input = create_service("input") -def connect_echo() : - return dbus.Interface(bus.get_object(echo.GetConnectionName(), '/org/bluez/echo'), 'org.freedesktop.DBus.Introspectable') +audio = create_service("audio") -def connect_holtmann() : - holtmann = dbus.Interface(bus.get_object('org.bluez', '/org/holtmann'), 'org.bluez.Service') - return dbus.Interface(bus.get_object(holtmann.GetConnectionName(), '/org/holtmann'), 'org.freedesktop.DBus.Introspectable') +headset = create_service("headset") -- cgit From f24e25355de0241f9a1c9117e0a3a3be35026611 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Jan 2007 15:53:19 +0000 Subject: Update pre-created objects --- test/dbusdef.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test') diff --git a/test/dbusdef.py b/test/dbusdef.py index c48f8479..b0ab1b89 100644 --- a/test/dbusdef.py +++ b/test/dbusdef.py @@ -3,8 +3,14 @@ import dbus bus = dbus.SystemBus() +dummy = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.freedesktop.DBus.Introspectable') + +#print dummy.Introspect() + manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager') +database = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Database') + adapter = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Adapter') test = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Test') @@ -21,6 +27,8 @@ def create_service(identifier): if (path != ""): return dbus.Interface(bus.get_object('org.bluez', path), 'org.bluez.Service') +echo = create_service("echo") + transfer = create_service("transfer") network = create_service("network") -- cgit From 8cc5595d9091b484b9a4abe314c0f3ec055e0581 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 20 Jan 2007 05:26:15 +0000 Subject: Make it possible to support an embedded GLib --- test/Makefile.am | 13 +++---------- test/hciemu.c | 10 +++++----- 2 files changed, 8 insertions(+), 15 deletions(-) (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index 18989ba5..c2a456d5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,12 +1,4 @@ -if GLIB -glib_cflags = @GLIB_CFLAGS@ -glib_ldadd = @GLIB_LIBS@ -else -glib_cflags = -glib_ldadd = -endif - if TEST sbin_PROGRAMS = hciemu @@ -14,7 +6,8 @@ bin_PROGRAMS = l2test rctest noinst_PROGRAMS = sdptest scotest attest hstest bdaddr lmptest -hciemu_LDADD = $(glib_ldadd) @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a +hciemu_LDADD = $(top_builddir)/common/libhelper.a \ + @GLIB_LIBS@ @BLUEZ_LIBS@ l2test_LDADD = @BLUEZ_LIBS@ @@ -36,7 +29,7 @@ lmptest_LDADD = @BLUEZ_LIBS@ noinst_MANS = bdaddr.8 -AM_CFLAGS = @BLUEZ_CFLAGS@ $(glib_cflags) +AM_CFLAGS = @BLUEZ_CFLAGS@ @GLIB_CFLAGS@ endif INCLUDES = -I$(top_srcdir)/common diff --git a/test/hciemu.c b/test/hciemu.c index a974a0c1..79f642a4 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -50,7 +50,7 @@ #include -#include "glib-ectomy.h" +#include #if __BYTE_ORDER == __LITTLE_ENDIAN static inline uint64_t ntoh64(uint64_t n) @@ -144,7 +144,7 @@ static inline void io_cancel(void) static void sig_term(int sig) { io_cancel(); - g_main_quit(event_loop); + g_main_loop_quit(event_loop); } static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data); @@ -979,7 +979,7 @@ static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data) syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); g_io_channel_unref(chan); - g_main_quit(event_loop); + g_main_loop_quit(event_loop); return FALSE; } @@ -1298,7 +1298,7 @@ int main(int argc, char *argv[]) dd = -1; /* Create event loop */ - event_loop = g_main_new(FALSE); + event_loop = g_main_loop_new(NULL, FALSE); if (dev >= 0) return run_proxy(fd, dev, &bdaddr); @@ -1333,7 +1333,7 @@ int main(int argc, char *argv[]) setpriority(PRIO_PROCESS, 0, -19); /* Start event processor */ - g_main_run(event_loop); + g_main_loop_run(event_loop); close(fd); -- cgit From 1c36a2a3227e07660d678b6844cf393aac005119 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Jan 2007 01:51:04 +0000 Subject: Add function for connection the transfer manager --- test/dbusdef.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'test') diff --git a/test/dbusdef.py b/test/dbusdef.py index b0ab1b89..62203993 100644 --- a/test/dbusdef.py +++ b/test/dbusdef.py @@ -38,3 +38,13 @@ input = create_service("input") audio = create_service("audio") headset = create_service("headset") + + +def connect_transfer(): + try: + conn = manager.ActivateService("transfer") + except: + conn = "" + + if (conn != ""): + return dbus.Interface(bus.get_object(conn, "/org/bluez/transfer"), 'org.bluez.transfer.Manager') -- 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 ++++++++++++ test/rctest.c | 14 +++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'test') 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) { diff --git a/test/rctest.c b/test/rctest.c index ff3b50e8..80117d23 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -206,7 +206,19 @@ static void do_listen(void (*handler)(int sk)) goto error; } - syslog(LOG_INFO,"Waiting for connection on channel %d ...", channel); + /* 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; + } + + channel = addr.rc_channel; + + syslog(LOG_INFO, "Waiting for connection on channel %d ...", channel); while(1) { memset(&addr, 0, sizeof(addr)); -- cgit From 03ebdf91be3d0652e27c2813ee37b43bb29f9411 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Jan 2007 17:12:12 +0000 Subject: Add a connect only mode --- test/scotest.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/scotest.c b/test/scotest.c index 22da3497..f80d63bd 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -46,7 +46,8 @@ enum { RECV, RECONNECT, MULTY, - DUMP + DUMP, + CONNECT }; static unsigned char *buf; @@ -334,15 +335,16 @@ static void usage(void) "\t-c reconnect (client)\n" "\t-m multiple connects (client)\n" "\t-r receive (server)\n" - "\t-s send (client)\n"); + "\t-s connect and send (client)\n" + "\t-n connect and be silent (client)\n"); } int main(int argc ,char *argv[]) { struct sigaction sa; - int opt, mode = RECV; + int opt, sk, mode = RECV; - while ((opt=getopt(argc,argv,"rdscmb:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscmnb:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -364,6 +366,10 @@ int main(int argc ,char *argv[]) mode = MULTY; break; + case 'n': + mode = CONNECT; + break; + case 'b': data_size = atoi(optarg); break; @@ -411,6 +417,13 @@ int main(int argc ,char *argv[]) case MULTY: multy_connect_mode(argv[optind]); break; + + case CONNECT: + sk = do_connect(argv[optind]); + if (sk < 0) + exit(1); + dump_mode(sk); + break; } syslog(LOG_INFO, "Exit"); -- cgit From f89882a84a048cd676798e4a047a73fb202e246d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Apr 2007 20:48:42 +0000 Subject: Update test setup --- test/dbusdef.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/dbusdef.py b/test/dbusdef.py index 62203993..97a0eb4d 100644 --- a/test/dbusdef.py +++ b/test/dbusdef.py @@ -7,15 +7,24 @@ dummy = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.freedeskt #print dummy.Introspect() + manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager') database = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Database') -adapter = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Adapter') -test = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Test') +try: + adapter = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Adapter') + + test = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.Test') + + rfcomm = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.RFCOMM') +except: + adapter = "" + + test = "" -rfcomm = dbus.Interface(bus.get_object('org.bluez', manager.DefaultAdapter()), 'org.bluez.RFCOMM') + rfcomm = "" def create_service(identifier): @@ -40,11 +49,11 @@ audio = create_service("audio") headset = create_service("headset") -def connect_transfer(): +def connect_headset(): try: - conn = manager.ActivateService("transfer") + conn = manager.ActivateService("headset") except: conn = "" if (conn != ""): - return dbus.Interface(bus.get_object(conn, "/org/bluez/transfer"), 'org.bluez.transfer.Manager') + return dbus.Interface(bus.get_object(conn, "/org/bluez/audio"), 'org.bluez.audio.Manager') -- cgit From 232610dea7be7fc8ca6a6bd22a02eca4a072b9c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 5 Apr 2007 20:10:01 +0000 Subject: Use generic service connect function --- test/dbusdef.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/dbusdef.py b/test/dbusdef.py index 97a0eb4d..ca6debf4 100644 --- a/test/dbusdef.py +++ b/test/dbusdef.py @@ -49,11 +49,11 @@ audio = create_service("audio") headset = create_service("headset") -def connect_headset(): +def connect_service(identifier): try: - conn = manager.ActivateService("headset") + conn = manager.ActivateService(identifier) except: conn = "" if (conn != ""): - return dbus.Interface(bus.get_object(conn, "/org/bluez/audio"), 'org.bluez.audio.Manager') + return dbus.Interface(bus.get_object(conn, "/org/bluez/" + identifier), 'org.bluez.' + identifier + '.Manager') -- 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') 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 3e4bc988db4efbc53148d75fbfca3b5e8b1fed8f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Jun 2007 22:31:54 +0000 Subject: Comment out @dbus.decorators.explicitly_pass_message statement --- test/apitest | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/apitest b/test/apitest index 601cf8df..7ce3f098 100755 --- a/test/apitest +++ b/test/apitest @@ -179,7 +179,7 @@ class Tester: for cmd in dev_cmds: print '\t%s' % cmd - @dbus.decorators.explicitly_pass_message + #@dbus.decorators.explicitly_pass_message def dev_signal_handler(*args, **keywords): dbus_message = keywords["dbus_message"] print '%s - %s: ' % (dbus_message.get_member(), dbus_message.get_path()), @@ -187,7 +187,7 @@ class Tester: print '%s ' % arg, print - @dbus.decorators.explicitly_pass_message + #@dbus.decorators.explicitly_pass_message def mgr_signal_handler(*args, **keywords): dbus_message = keywords["dbus_message"] print '%s: ' % dbus_message.get_member() -- cgit From 7d8dc82e027404d688639c0aea2909c131f221f4 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Sat, 23 Jun 2007 13:56:20 +0000 Subject: apitest: fixed signal handler --- test/apitest | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/apitest b/test/apitest index 7ce3f098..ccb40bbe 100755 --- a/test/apitest +++ b/test/apitest @@ -145,7 +145,8 @@ class Tester: for path in dev_signals_filter: self.bus.add_signal_receiver(self.dev_signal_handler, signal, 'org.bluez.Adapter', - 'org.bluez', path) + 'org.bluez', path, + message_keyword='dbus_message') except dbus.DBusException, e: print 'Failed to setup signal handler for device path: %s' % e sys.exit(1) @@ -414,7 +415,7 @@ class Tester: self.dbus_dev_sig_setup() print 'Listening for events...' - if self.cmd in mgr_cmds: + elif self.cmd in mgr_cmds: try: self.dbus_mgr_setup() except dbus.DBusException, e: -- 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/attest.c | 2 +- test/bdaddr.c | 2 +- test/hciemu.c | 2 +- test/hstest.c | 2 +- test/l2test.c | 2 +- test/lmptest.c | 2 +- test/rctest.c | 2 +- test/scotest.c | 2 +- test/sdptest.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/attest.c b/test/attest.c index 23c99aeb..531c2157 100644 --- a/test/attest.c +++ b/test/attest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2007 Marcel Holtmann + * Copyright (C) 2001-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/bdaddr.c b/test/bdaddr.c index 0d2d7e83..7c0df31d 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hciemu.c b/test/hciemu.c index 79f642a4..bebcd9c8 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2000-2002 Maxim Krasnyansky - * Copyright (C) 2003-2007 Marcel Holtmann + * Copyright (C) 2003-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hstest.c b/test/hstest.c index 2a6ae593..158bf204 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify 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 diff --git a/test/lmptest.c b/test/lmptest.c index 39a906a2..276ca071 100644 --- a/test/lmptest.c +++ b/test/lmptest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2005-2007 Marcel Holtmann + * Copyright (C) 2005-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/rctest.c b/test/rctest.c index 80117d23..1ee4827b 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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 diff --git a/test/scotest.c b/test/scotest.c index f80d63bd..4c5a310c 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * 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 diff --git a/test/sdptest.c b/test/sdptest.c index 89b30dd3..d2213bfa 100644 --- a/test/sdptest.c +++ b/test/sdptest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2005-2007 Marcel Holtmann + * Copyright (C) 2005-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 5a14261153a166511b651572ca76708ad3d8ea52 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 Mar 2008 14:07:54 +0000 Subject: Allow event listening and commands at the same time --- test/apitest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/apitest b/test/apitest index ccb40bbe..b1c3f103 100755 --- a/test/apitest +++ b/test/apitest @@ -415,7 +415,7 @@ class Tester: self.dbus_dev_sig_setup() print 'Listening for events...' - elif self.cmd in mgr_cmds: + if self.cmd in mgr_cmds: try: self.dbus_mgr_setup() except dbus.DBusException, e: -- cgit From e0a54a416a5abc3bab139e5db6391c1926855ff6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jun 2008 12:44:58 +0000 Subject: Move passkey-agent and auth-agent sample code to test directory --- test/Makefile.am | 9 +- test/auth-agent.c | 351 ++++++++++++++++++++++++++++++++++++++++ test/passkey-agent.c | 441 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 799 insertions(+), 2 deletions(-) create mode 100644 test/auth-agent.c create mode 100644 test/passkey-agent.c (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am index c2a456d5..16b80e7d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,8 @@ sbin_PROGRAMS = hciemu bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = sdptest scotest attest hstest bdaddr lmptest +noinst_PROGRAMS = sdptest scotest attest hstest bdaddr lmptest \ + passkey-agent auth-agent hciemu_LDADD = $(top_builddir)/common/libhelper.a \ @GLIB_LIBS@ @BLUEZ_LIBS@ @@ -27,9 +28,13 @@ bdaddr_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a lmptest_LDADD = @BLUEZ_LIBS@ +passkey_agent_LDADD = @DBUS_LIBS@ + +auth_agent_LDADD = @DBUS_LIBS@ + noinst_MANS = bdaddr.8 -AM_CFLAGS = @BLUEZ_CFLAGS@ @GLIB_CFLAGS@ +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ endif INCLUDES = -I$(top_srcdir)/common diff --git a/test/auth-agent.c b/test/auth-agent.c new file mode 100644 index 00000000..2686c3ee --- /dev/null +++ b/test/auth-agent.c @@ -0,0 +1,351 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2008 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * 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. + * + * 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. + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define INTERFACE "org.bluez.Security" + +static volatile sig_atomic_t __io_canceled = 0; +static volatile sig_atomic_t __io_terminated = 0; + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static DBusHandlerResult agent_filter(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *name, *old, *new; + + if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, + DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for NameOwnerChanged signal"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!strcmp(name, "org.bluez") && *new == '\0') { + fprintf(stderr, "Authorization service has been terminated\n"); + __io_terminated = 1; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult authorize_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + const char *adapter, *address, *service, *string; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &adapter, DBUS_TYPE_STRING, &address, + DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &string, + DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for passkey Confirm method"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + printf("Authorization request for device %s\n", address); + + reply = dbus_message_new_method_return(msg); + if (!reply) { + fprintf(stderr, "Can't create reply message\n"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_connection_flush(conn); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult cancel_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + const char *adapter, *address, *service, *string; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &adapter, DBUS_TYPE_STRING, &address, + DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &string, + DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for passkey Confirm method"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + printf("Request canceled for device %s\n", address); + + reply = dbus_message_new_method_return(msg); + if (!reply) { + fprintf(stderr, "Can't create reply message\n"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_connection_flush(conn); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult release_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for Release method"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!__io_canceled) + fprintf(stderr, "Authorization agent has been released\n"); + + __io_terminated = 1; + + reply = dbus_message_new_method_return(msg); + if (!reply) { + fprintf(stderr, "Can't create reply message\n"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_connection_flush(conn); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult auth_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + if (dbus_message_is_method_call(msg, "org.bluez.AuthorizationAgent", "Authorize")) + return authorize_message(conn, msg, data); + + if (dbus_message_is_method_call(msg, "org.bluez.AuthorizationAgent", "Cancel")) + return cancel_message(conn, msg, data); + + if (dbus_message_is_method_call(msg, "org.bluez.AuthorizationAgent", "Release")) + return release_message(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static const DBusObjectPathVTable auth_table = { + .message_function = auth_message, +}; + +static int register_auth(DBusConnection *conn, const char *auth_path) +{ + DBusMessage *msg, *reply; + DBusError err; + + if (!dbus_connection_register_object_path(conn, auth_path, + &auth_table, NULL)) { + fprintf(stderr, "Can't register object path for agent\n"); + return -1; + } + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + INTERFACE, "RegisterDefaultAuthorizationAgent"); + if (!msg) { + fprintf(stderr, "Can't allocate new method call\n"); + return -1; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &auth_path, + DBUS_TYPE_INVALID); + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + + dbus_message_unref(msg); + + if (!reply) { + fprintf(stderr, "Can't register authorization agent\n"); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "%s\n", err.message); + dbus_error_free(&err); + } + return -1; + } + + dbus_message_unref(reply); + + dbus_connection_flush(conn); + + return 0; +} + +static int unregister_auth(DBusConnection *conn, const char *auth_path) +{ + DBusMessage *msg, *reply; + DBusError err; + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + INTERFACE, "UnregisterDefaultAuthorizationAgent"); + if (!msg) { + fprintf(stderr, "Can't allocate new method call\n"); + dbus_connection_unref(conn); + exit(1); + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &auth_path, + DBUS_TYPE_INVALID); + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + + dbus_message_unref(msg); + + if (!reply) { + fprintf(stderr, "Can't unregister authorization agent\n"); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "%s\n", err.message); + dbus_error_free(&err); + } + return -1; + } + + dbus_message_unref(reply); + + dbus_connection_flush(conn); + + dbus_connection_unregister_object_path(conn, auth_path); + + return 0; +} + +static void usage(void) +{ + printf("Bluetooth authorization agent ver %s\n\n", VERSION); + + printf("Usage:\n" + "\tauth-agent [--path auth-path]\n" + "\n"); +} + +static struct option main_options[] = { + { "path", 1, 0, 'p' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + DBusConnection *conn; + char match_string[128], default_path[128], *auth_path = NULL; + int opt; + + snprintf(default_path, sizeof(default_path), + "/org/bluez/auth_agent_%d", getpid()); + + while ((opt = getopt_long(argc, argv, "+p:h", main_options, NULL)) != EOF) { + switch(opt) { + case 'p': + if (optarg[0] != '/') { + fprintf(stderr, "Invalid path\n"); + exit(1); + } + auth_path = strdup(optarg); + break; + case 'h': + usage(); + exit(0); + default: + exit(1); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (!auth_path) + auth_path = strdup(default_path); + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + fprintf(stderr, "Can't get on system bus"); + exit(1); + } + + if (register_auth(conn, auth_path) < 0) { + dbus_connection_unref(conn); + exit(1); + } + + if (!dbus_connection_add_filter(conn, agent_filter, NULL, NULL)) + fprintf(stderr, "Can't add signal filter"); + + snprintf(match_string, sizeof(match_string), + "interface=%s,member=NameOwnerChanged,arg0=%s", + DBUS_INTERFACE_DBUS, "org.bluez"); + + dbus_bus_add_match(conn, match_string, NULL); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + while (!__io_canceled && !__io_terminated) { + if (dbus_connection_read_write_dispatch(conn, 500) != TRUE) + break; + } + + if (!__io_terminated) + unregister_auth(conn, auth_path); + + dbus_connection_unref(conn); + + return 0; +} diff --git a/test/passkey-agent.c b/test/passkey-agent.c new file mode 100644 index 00000000..c4dec584 --- /dev/null +++ b/test/passkey-agent.c @@ -0,0 +1,441 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2008 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * 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. + * + * 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. + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define INTERFACE "org.bluez.Security" + +static char *passkey = NULL; +static char *address = NULL; + +static volatile sig_atomic_t __io_canceled = 0; +static volatile sig_atomic_t __io_terminated = 0; + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static DBusHandlerResult agent_filter(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *name, *old, *new; + + if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old, + DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for NameOwnerChanged signal"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!strcmp(name, "org.bluez") && *new == '\0') { + fprintf(stderr, "Passkey service has been terminated\n"); + __io_terminated = 1; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult request_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + const char *path, *address; + dbus_bool_t numeric; + + if (!passkey) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &address, + DBUS_TYPE_BOOLEAN, &numeric, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for passkey Request method"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) { + fprintf(stderr, "Can't create reply message\n"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + printf("Passkey request for device %s\n", address); + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &passkey, + DBUS_TYPE_INVALID); + + dbus_connection_send(conn, reply, NULL); + + dbus_connection_flush(conn); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult confirm_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + const char *path, *address, *value; + + if (!passkey) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &address, + DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for passkey Confirm method"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + printf("Confirm request for device %s\n", address); + + reply = dbus_message_new_method_return(msg); + if (!reply) { + fprintf(stderr, "Can't create reply message\n"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_connection_flush(conn); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult cancel_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + const char *path, *address; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &address, + DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for passkey Confirm method"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + printf("Request canceled for device %s\n", address); + + reply = dbus_message_new_method_return(msg); + if (!reply) { + fprintf(stderr, "Can't create reply message\n"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_connection_flush(conn); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult release_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID)) { + fprintf(stderr, "Invalid arguments for passkey Release method"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!__io_canceled) + fprintf(stderr, "Passkey service has been released\n"); + + __io_terminated = 1; + + reply = dbus_message_new_method_return(msg); + if (!reply) { + fprintf(stderr, "Can't create reply message\n"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_connection_flush(conn); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult agent_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + if (dbus_message_is_method_call(msg, "org.bluez.PasskeyAgent", "Request")) + return request_message(conn, msg, data); + + if (dbus_message_is_method_call(msg, "org.bluez.PasskeyAgent", "Confirm")) + return confirm_message(conn, msg, data); + + if (dbus_message_is_method_call(msg, "org.bluez.PasskeyAgent", "Cancel")) + return cancel_message(conn, msg, data); + + if (dbus_message_is_method_call(msg, "org.bluez.PasskeyAgent", "Release")) + return release_message(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static const DBusObjectPathVTable agent_table = { + .message_function = agent_message, +}; + +static int register_agent(DBusConnection *conn, const char *agent_path, + const char *remote_address, int use_default) +{ + DBusMessage *msg, *reply; + DBusError err; + const char *path, *method, *address = remote_address; + + if (!dbus_connection_register_object_path(conn, agent_path, + &agent_table, NULL)) { + fprintf(stderr, "Can't register object path for agent\n"); + return -1; + } + + if (use_default) { + path = "/org/bluez"; + method = "RegisterDefaultPasskeyAgent"; + } else { + path = "/org/bluez/hci0"; + method = "RegisterPasskeyAgent"; + } + + msg = dbus_message_new_method_call("org.bluez", path, INTERFACE, method); + if (!msg) { + fprintf(stderr, "Can't allocate new method call\n"); + return -1; + } + + if (use_default) + dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path, + DBUS_TYPE_INVALID); + else + dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path, + DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID); + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + + dbus_message_unref(msg); + + if (!reply) { + fprintf(stderr, "Can't register passkey agent\n"); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "%s\n", err.message); + dbus_error_free(&err); + } + return -1; + } + + dbus_message_unref(reply); + + dbus_connection_flush(conn); + + return 0; +} + +static int unregister_agent(DBusConnection *conn, const char *agent_path, + const char *remote_address, int use_default) +{ + DBusMessage *msg, *reply; + DBusError err; + const char *path, *method, *address = remote_address; + + if (use_default) { + path = "/org/bluez"; + method = "UnregisterDefaultPasskeyAgent"; + } else { + path = "/org/bluez/hci0"; + method = "UnregisterPasskeyAgent"; + } + + msg = dbus_message_new_method_call("org.bluez", path, INTERFACE, method); + if (!msg) { + fprintf(stderr, "Can't allocate new method call\n"); + dbus_connection_unref(conn); + exit(1); + } + + if (use_default) + dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path, + DBUS_TYPE_INVALID); + else + dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path, + DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID); + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + + dbus_message_unref(msg); + + if (!reply) { + fprintf(stderr, "Can't unregister passkey agent\n"); + if (dbus_error_is_set(&err)) { + fprintf(stderr, "%s\n", err.message); + dbus_error_free(&err); + } + return -1; + } + + dbus_message_unref(reply); + + dbus_connection_flush(conn); + + dbus_connection_unregister_object_path(conn, agent_path); + + return 0; +} + +static void usage(void) +{ + printf("Bluetooth passkey agent ver %s\n\n", VERSION); + + printf("Usage:\n" + "\tpasskey-agent [--default] [--path agent-path] [address]\n" + "\n"); +} + +static struct option main_options[] = { + { "default", 0, 0, 'd' }, + { "path", 1, 0, 'p' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + DBusConnection *conn; + char match_string[128], default_path[128], *agent_path = NULL; + int opt, use_default = 0; + + snprintf(default_path, sizeof(default_path), + "/org/bluez/passkey_agent_%d", getpid()); + + while ((opt = getopt_long(argc, argv, "+dp:h", main_options, NULL)) != EOF) { + switch(opt) { + case 'd': + use_default = 1; + break; + case 'p': + if (optarg[0] != '/') { + fprintf(stderr, "Invalid path\n"); + exit(1); + } + agent_path = strdup(optarg); + break; + case 'h': + usage(); + exit(0); + default: + exit(1); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + passkey = strdup(argv[0]); + address = (argc > 1) ? strdup(argv[1]) : NULL; + + if (!use_default && !address) { + usage(); + exit(1); + } + + if (!agent_path) + agent_path = strdup(default_path); + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + fprintf(stderr, "Can't get on system bus"); + exit(1); + } + + if (register_agent(conn, agent_path, address, use_default) < 0) { + dbus_connection_unref(conn); + exit(1); + } + + if (!dbus_connection_add_filter(conn, agent_filter, NULL, NULL)) + fprintf(stderr, "Can't add signal filter"); + + snprintf(match_string, sizeof(match_string), + "interface=%s,member=NameOwnerChanged,arg0=%s", + DBUS_INTERFACE_DBUS, "org.bluez"); + + dbus_bus_add_match(conn, match_string, NULL); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + while (!__io_canceled && !__io_terminated) { + if (dbus_connection_read_write_dispatch(conn, 500) != TRUE) + break; + } + + if (!__io_terminated) + unregister_agent(conn, agent_path, address, use_default); + + if (passkey) + free(passkey); + + dbus_connection_unref(conn); + + return 0; +} -- cgit From 5ac0d04df13361d3151c7a77593fa36b371b51cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jun 2008 15:31:41 +0000 Subject: Remove the confirm method from the sample passkey agent --- test/passkey-agent.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'test') diff --git a/test/passkey-agent.c b/test/passkey-agent.c index c4dec584..4a612662 100644 --- a/test/passkey-agent.c +++ b/test/passkey-agent.c @@ -108,39 +108,6 @@ static DBusHandlerResult request_message(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult confirm_message(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - DBusMessage *reply; - const char *path, *address, *value; - - if (!passkey) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID)) { - fprintf(stderr, "Invalid arguments for passkey Confirm method"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - printf("Confirm request for device %s\n", address); - - reply = dbus_message_new_method_return(msg); - if (!reply) { - fprintf(stderr, "Can't create reply message\n"); - return DBUS_HANDLER_RESULT_NEED_MEMORY; - } - - dbus_connection_send(conn, reply, NULL); - - dbus_connection_flush(conn); - - dbus_message_unref(reply); - - return DBUS_HANDLER_RESULT_HANDLED; -} - static DBusHandlerResult cancel_message(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -207,9 +174,6 @@ static DBusHandlerResult agent_message(DBusConnection *conn, if (dbus_message_is_method_call(msg, "org.bluez.PasskeyAgent", "Request")) return request_message(conn, msg, data); - if (dbus_message_is_method_call(msg, "org.bluez.PasskeyAgent", "Confirm")) - return confirm_message(conn, msg, data); - if (dbus_message_is_method_call(msg, "org.bluez.PasskeyAgent", "Cancel")) return cancel_message(conn, msg, data); -- 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') 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') 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 +++++++++++++++++++++++++++++++--- test/rctest.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 5 deletions(-) (limited to 'test') 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); diff --git a/test/rctest.c b/test/rctest.c index 1ee4827b..2e366c72 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -79,6 +79,7 @@ static int encrypt = 0; static int secure = 0; static int socktype = SOCK_STREAM; static int linger = 0; +static int timestamp = 0; static float tv2fl(struct timeval tv) { @@ -100,6 +101,17 @@ static int do_connect(char *svr) return -1; } + /* 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 }; @@ -254,6 +266,17 @@ static void do_listen(void (*handler)(int sk)) ba, 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 }; @@ -448,7 +471,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[]) @@ -458,7 +482,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:B:N:MAESL:C:D:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:B:N:MAESL:C:D:T")) != EOF) { switch (opt) { case 'r': mode = RECV; @@ -548,6 +572,10 @@ int main(int argc, char *argv[]) delay = atoi(optarg) * 1000; 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 +- test/rctest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test') 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; diff --git a/test/rctest.c b/test/rctest.c index 2e366c72..2c69b5b2 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -270,7 +270,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 ++++++++++++++++++++++-- test/rctest.c | 27 ++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 5 deletions(-) (limited to 'test') 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); } } diff --git a/test/rctest.c b/test/rctest.c index 2c69b5b2..612855f3 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -101,6 +102,7 @@ static int do_connect(char *svr) return -1; } +#if 0 /* Enable SO_TIMESTAMP */ if (timestamp) { int t = 1; @@ -111,6 +113,7 @@ static int do_connect(char *svr) goto error; } } +#endif /* Enable SO_LINGER */ if (linger) { @@ -266,6 +269,7 @@ static void do_listen(void (*handler)(int sk)) ba, 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; @@ -276,6 +280,7 @@ static void do_listen(void (*handler)(int sk)) goto error; } } +#endif /* Enable SO_LINGER */ if (linger) { @@ -313,11 +318,14 @@ 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; + char ts[30]; long total; uint32_t seq; - syslog(LOG_INFO,"Receiving ..."); + syslog(LOG_INFO, "Receiving ..."); + + memset(ts, 0, sizeof(ts)); seq = 0; while (1) { @@ -334,6 +342,19 @@ static void recv_mode(int sk) strerror(errno), errno); return; } + + 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); + } + } + #if 0 /* Check sequence */ sq = btohl(*(uint32_t *) buf); @@ -362,7 +383,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 81ef88706fcf1a8d1671506d6734bdab0dbd7c6f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:16:28 +0000 Subject: Quick hack to allow reject of PIN code requests --- test/passkey-agent.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'test') diff --git a/test/passkey-agent.c b/test/passkey-agent.c index 4a612662..8ac91d27 100644 --- a/test/passkey-agent.c +++ b/test/passkey-agent.c @@ -40,6 +40,8 @@ static char *passkey = NULL; static char *address = NULL; +static int do_reject = 0; + static volatile sig_atomic_t __io_canceled = 0; static volatile sig_atomic_t __io_terminated = 0; @@ -88,6 +90,12 @@ static DBusHandlerResult request_message(DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } + if (do_reject) { + reply = dbus_message_new_error(msg, + "org.bluez.Error.Rejected", ""); + goto send; + } + reply = dbus_message_new_method_return(msg); if (!reply) { fprintf(stderr, "Can't create reply message\n"); @@ -99,6 +107,7 @@ static DBusHandlerResult request_message(DBusConnection *conn, dbus_message_append_args(reply, DBUS_TYPE_STRING, &passkey, DBUS_TYPE_INVALID); +send: dbus_connection_send(conn, reply, NULL); dbus_connection_flush(conn); @@ -307,6 +316,7 @@ static void usage(void) static struct option main_options[] = { { "default", 0, 0, 'd' }, + { "reject", 0, 0, 'r' }, { "path", 1, 0, 'p' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } @@ -327,6 +337,9 @@ int main(int argc, char *argv[]) case 'd': use_default = 1; break; + case 'r': + do_reject = 1; + break; case 'p': if (optarg[0] != '/') { fprintf(stderr, "Invalid path\n"); -- 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 ++++++++ test/rctest.c | 33 ++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 11 deletions(-) (limited to 'test') 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)", diff --git a/test/rctest.c b/test/rctest.c index 612855f3..2da87f71 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -92,7 +92,7 @@ static int do_connect(char *svr) struct sockaddr_rc addr; struct rfcomm_conninfo conn; socklen_t optlen; - int sk; + int sk, opt; /* Create socket */ sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM); @@ -102,6 +102,17 @@ static int do_connect(char *svr) return -1; } + /* Bind to local address */ + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_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; + } + #if 0 /* Enable SO_TIMESTAMP */ if (timestamp) { @@ -126,16 +137,16 @@ static int do_connect(char *svr) } } - /* Bind to local address */ - memset(&addr, 0, sizeof(addr)); - addr.rc_family = AF_BLUETOOTH; - bacpy(&addr.rc_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; - } + /* Set link mode */ + opt = 0; + if (master) + opt |= RFCOMM_LM_MASTER; + if (auth) + opt |= RFCOMM_LM_AUTH; + if (encrypt) + opt |= RFCOMM_LM_ENCRYPT; + if (secure) + opt |= RFCOMM_LM_SECURE; /* Connect to remote device */ memset(&addr, 0, sizeof(addr)); -- cgit From 93f86d24ccd3e1a589a2762e1a424cf7cc70e740 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 03:00:37 +0000 Subject: Make sure to actually set the link mode option --- test/rctest.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test') diff --git a/test/rctest.c b/test/rctest.c index 2da87f71..08620d4e 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -148,6 +148,12 @@ static int do_connect(char *svr) if (secure) opt |= RFCOMM_LM_SECURE; + if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", + strerror(errno), errno); + goto error; + } + /* Connect to remote device */ memset(&addr, 0, sizeof(addr)); addr.rc_family = AF_BLUETOOTH; -- cgit