diff options
author | emax <emax@FreeBSD.org> | 2003-10-12 22:04:24 +0000 |
---|---|---|
committer | emax <emax@FreeBSD.org> | 2003-10-12 22:04:24 +0000 |
commit | 41bb0e8fd2568243020852e22a6d176bccfa60cd (patch) | |
tree | 0ae0c2be63f9f9161693789721b96beb9cabcc77 /usr.bin | |
parent | 66feac7937e372f502539e7d443aee80a25abe16 (diff) | |
download | FreeBSD-src-41bb0e8fd2568243020852e22a6d176bccfa60cd.zip FreeBSD-src-41bb0e8fd2568243020852e22a6d176bccfa60cd.tar.gz |
Update Bluetooth code.
Reviewed by: M. Warner Losh <imp@bsdimp.com>; John Hay <jhay@freebsd.org>
Approved by: M. Warner Losh <imp@bsdimp.com> (mentor)
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/Makefile | 3 | ||||
-rw-r--r-- | usr.bin/bluetooth/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/bluetooth/Makefile.inc | 4 | ||||
-rw-r--r-- | usr.bin/bluetooth/bthost/Makefile | 12 | ||||
-rw-r--r-- | usr.bin/bluetooth/bthost/bthost.1 | 111 | ||||
-rw-r--r-- | usr.bin/bluetooth/bthost/bthost.c | 142 | ||||
-rw-r--r-- | usr.bin/bluetooth/btsockstat/Makefile | 17 | ||||
-rw-r--r-- | usr.bin/bluetooth/btsockstat/btsockstat.1 | 8 | ||||
-rw-r--r-- | usr.bin/bluetooth/btsockstat/btsockstat.c | 135 | ||||
-rw-r--r-- | usr.bin/bluetooth/rfcomm_sppd/Makefile | 13 | ||||
-rw-r--r-- | usr.bin/bluetooth/rfcomm_sppd/rfcomm_sdp.c | 266 | ||||
-rw-r--r-- | usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 | 14 | ||||
-rw-r--r-- | usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c | 52 |
13 files changed, 652 insertions, 129 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 1a61881..da67aaa 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -244,7 +244,8 @@ SUBDIR+=usbhidaction \ .if ${MACHINE_ARCH} == "i386" # Things that don't compile on alpha or are aout specific: -SUBDIR+=doscmd \ +SUBDIR+=bluetooth \ + doscmd \ ncplist \ ncplogin \ sasc \ diff --git a/usr.bin/bluetooth/Makefile b/usr.bin/bluetooth/Makefile index be3146e..9ef16cc 100644 --- a/usr.bin/bluetooth/Makefile +++ b/usr.bin/bluetooth/Makefile @@ -1,7 +1,9 @@ # $Id $ # $FreeBSD$ -SUBDIR= btsockstat \ +SUBDIR= \ + bthost \ + btsockstat \ rfcomm_sppd .include <bsd.subdir.mk> diff --git a/usr.bin/bluetooth/Makefile.inc b/usr.bin/bluetooth/Makefile.inc new file mode 100644 index 0000000..c0e05cf --- /dev/null +++ b/usr.bin/bluetooth/Makefile.inc @@ -0,0 +1,4 @@ +# $FreeBSD$ + +.include "${.CURDIR}/../../Makefile.inc" + diff --git a/usr.bin/bluetooth/bthost/Makefile b/usr.bin/bluetooth/bthost/Makefile new file mode 100644 index 0000000..a761bbc --- /dev/null +++ b/usr.bin/bluetooth/bthost/Makefile @@ -0,0 +1,12 @@ +# $Id: Makefile,v 1.4 2003/08/14 20:07:13 max Exp $ +# $FreeBSD$ + +PROG= bthost +MAN= bthost.1 +SRCS= bthost.c +WARNS?= 2 + +DPADD= ${LIBBLUETOOTH} +LDADD= -lbluetooth + +.include <bsd.prog.mk> diff --git a/usr.bin/bluetooth/bthost/bthost.1 b/usr.bin/bluetooth/bthost/bthost.1 new file mode 100644 index 0000000..2fda952 --- /dev/null +++ b/usr.bin/bluetooth/bthost/bthost.1 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: bthost.1,v 1.7 2003/05/21 22:19:00 max Exp $ +.\" $FreeBSD$ +.\" +.Dd May 8, 2003 +.Dt BTHOST 1 +.Os +.Sh NAME +.Nm bthost +.Nd look up Bluetooth host names and Protocol Service Multiplexor values +.Sh SYNOPSIS +.Nm bthost +.Op Fl bhp +.Ar host_or_protocol +.Sh DESCRIPTION +The +.Nm +utility looks for information about Bluetooth hosts and +Protocol Service Multiplexor (PSM) values. +It gets this information from the +.Pa /etc/bluetooth/hosts +and +.Pa /etc/bluetooth/protocols +files. +.Pp +In host mode it simply converts between host names and Bluetooth addresses. +The argument can be either host name or Bluetooth address. +The program first attempts to interpret it as Bluetooth address. +If this fails, it will treat it as host name. +A Bluetooth address consists of six hex bytes sparated by column, +e.g. 01:02:03:04:05:06. +A host name consists of names separated by dots, e.g. my.cell.phone. +.Pp +In protocol mode it simply converts between Protocol Service Multiplexor names +and assigned numbers. +The argument can be either Protocol Service Multiplexor name or assigned number. +The program first attempts to interpret it as assigned number. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl b +Produce brief output. +.It Fl h +Display usage message and exit. +.It Fl p +Activate protocol mode. +.El +.Pp +The +.Nm +utility will print results to the standard output and error messages to the +standard error. +You may see output of different kinds. +Here is an example that shows all of them: +.Pp +.D1 Ic % bthost localhost +.Dl Host localhost has address FF:FF:FF:00:00:00 +.D1 Ic % bthost ff:ff:ff:00:00:00 +.Dl Host FF:FF:FF:00:00:00 has name localhost +.D1 Ic % bthost -b localhost +.Dl FF:FF:FF:00:00:00 +.D1 Ic % bthost -b ff:ff:ff:00:00:00 +.Dl localhost +.D1 Ic % bthost do.not.exists +.Dl do.not.exists: Unknown host +.D1 Ic % bthost 0:0:0:0:0:0 +.Dl 00:00:00:00:00:00: Unknown host +.D1 Ic % bthost -p sdp +.Dl Protocol/Service Multiplexor sdp has number 1 +.D1 Ic % bthost -p 3 +.Dl Protocol/Service Multiplexor rfcomm has number 3 +.D1 Ic % bthost -bp HID-Control +.Dl 17 +.D1 Ic % bthost -p foo +.Dl foo: Unknown Protocol/Service Multiplexor +.Sh FILES +.Bl -tag -width "/etc/bluetooth/hosts" -compact +.It Pa /etc/bluetooth/hosts +.It Pa /etc/bluetooth/protocols +.El +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr bluetooth 3 , +.Xr bluetooth.hosts 5 , +.Xr bluetooth.protocols 5 +.Sh AUTHORS +.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com diff --git a/usr.bin/bluetooth/bthost/bthost.c b/usr.bin/bluetooth/bthost/bthost.c new file mode 100644 index 0000000..2dd5635 --- /dev/null +++ b/usr.bin/bluetooth/bthost/bthost.c @@ -0,0 +1,142 @@ +/* + * bthost.c + * + * Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: bthost.c,v 1.5 2003/05/21 20:30:01 max Exp $ + * $FreeBSD$ + */ + +#include <bluetooth.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +static int hostmode (char const *arg, int brief); +static int protomode (char const *arg, int brief); +static void usage (void); + +int +main(int argc, char **argv) +{ + int opt, brief = 0, proto = 0; + + while ((opt = getopt(argc, argv, "bhp")) != -1) { + switch (opt) { + case 'b': + brief = 1; + break; + + case 'p': + proto = 1; + break; + + case 'h': + default: + usage(); + /* NOT REACHED */ + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) + usage(); + + exit(proto? protomode(*argv, brief) : hostmode(*argv, brief)); +} + +static int +hostmode(char const *arg, int brief) +{ + struct hostent *he = NULL; + bdaddr_t ba; + char bastr[32]; + int reverse; + + if (bt_aton(arg, &ba) == 1) { + reverse = 1; + he = bt_gethostbyaddr((char const *) &ba, sizeof(ba), + AF_BLUETOOTH); + } else { + reverse = 0; + he = bt_gethostbyname(arg); + } + + if (he == NULL) { + herror(reverse? bt_ntoa(&ba, bastr) : arg); + return (1); + } + + if (brief) + printf("%s", reverse? he->h_name : + bt_ntoa((bdaddr_t *)(he->h_addr), bastr)); + else + printf("Host %s has %s %s\n", + reverse? bt_ntoa(&ba, bastr) : arg, + reverse? "name" : "address", + reverse? he->h_name : + bt_ntoa((bdaddr_t *)(he->h_addr), bastr)); + + return (0); +} + +static int +protomode(char const *arg, int brief) +{ + struct protoent *pe = NULL; + int proto; + + if ((proto = atoi(arg)) != 0) + pe = bt_getprotobynumber(proto); + else + pe = bt_getprotobyname(arg); + + if (pe == NULL) { + fprintf(stderr, "%s: Unknown Protocol/Service Multiplexor\n", arg); + return (1); + } + + if (brief) { + if (proto) + printf("%s", pe->p_name); + else + printf("%d", pe->p_proto); + } else { + printf("Protocol/Service Multiplexor %s has number %d\n", + pe->p_name, pe->p_proto); + } + + return (0); +} + +static void +usage(void) +{ + fprintf(stdout, "Usage: bthost [-b -h -p] host_or_protocol\n"); + exit(255); +} + diff --git a/usr.bin/bluetooth/btsockstat/Makefile b/usr.bin/bluetooth/btsockstat/Makefile index 7614881..c2314ba 100644 --- a/usr.bin/bluetooth/btsockstat/Makefile +++ b/usr.bin/bluetooth/btsockstat/Makefile @@ -1,19 +1,14 @@ -# $Id: Makefile,v 1.3 2003/03/24 23:59:49 max Exp $ +# $Id: Makefile,v 1.7 2003/08/14 20:07:14 max Exp $ # $FreeBSD$ PROG= btsockstat +MAN= btsockstat.1 +SRCS= btsockstat.c +WARNS?= 2 BINGRP= kmem BINMODE= 2555 -MAN1= btsockstat.1 - -DESTDIR= /usr/bin/ -MANDIR= ../share/man/man -WARNS?= 2 -CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include/ - -SRCS= btsockstat.c -DPADD= ${LIBKVM} -LDADD= -lkvm +DPADD= ${LIBBLUETOOTH} ${LIBKVM} +LDADD= -lbluetooth -lkvm .include <bsd.prog.mk> diff --git a/usr.bin/bluetooth/btsockstat/btsockstat.1 b/usr.bin/bluetooth/btsockstat/btsockstat.1 index d76799b..f9b6064 100644 --- a/usr.bin/bluetooth/btsockstat/btsockstat.1 +++ b/usr.bin/bluetooth/btsockstat/btsockstat.1 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: btsockstat.1,v 1.4 2003/04/27 19:25:15 max Exp $ +.\" $Id: btsockstat.1,v 1.6 2003/05/21 00:09:45 max Exp $ .\" $FreeBSD$ .\" .Dd August 31, 2002 @@ -33,7 +33,7 @@ .Nd show Bluetooth sockets information .Sh SYNOPSIS .Nm -.Op Fl rh +.Op Fl nrh .Op Fl M Ar core .Op Fl p Ar protocol .Sh DESCRIPTION @@ -57,6 +57,10 @@ Display usage message and exit. Extract values associated with the name list from the specified core instead of the default .Pa /dev/kmem . +.It Fl n +Show Bluetooth addresses as numbers. Normally +.Nm +attempts to resolve Bluetooth addresses, and display them symbolically. .It Fl p Ar protocol Display a list of active sockets (protocol control blocks) for each specified protocol. diff --git a/usr.bin/bluetooth/btsockstat/btsockstat.c b/usr.bin/bluetooth/btsockstat/btsockstat.c index 7911f40..54c1b49 100644 --- a/usr.bin/bluetooth/btsockstat/btsockstat.c +++ b/usr.bin/bluetooth/btsockstat/btsockstat.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: btsockstat.c,v 1.4 2003/03/29 22:28:18 max Exp $ + * $Id: btsockstat.c,v 1.8 2003/05/21 22:40:25 max Exp $ * $FreeBSD$ */ @@ -39,19 +39,16 @@ #include <net/if.h> #include <net/if_var.h> -#include <bitstring.h> +#include <bluetooth.h> #include <err.h> #include <fcntl.h> #include <kvm.h> #include <limits.h> -#include <ng_bluetooth.h> -#include <ng_hci.h> -#include <ng_l2cap.h> -#include <ng_btsocket.h> -#include <ng_btsocket_hci_raw.h> -#include <ng_btsocket_l2cap.h> -#include <ng_btsocket_rfcomm.h> +#include <netgraph/bluetooth/include/ng_bluetooth.h> +#include <netgraph/bluetooth/include/ng_btsocket_hci_raw.h> +#include <netgraph/bluetooth/include/ng_btsocket_l2cap.h> +#include <netgraph/bluetooth/include/ng_btsocket_rfcomm.h> #include <stdio.h> #include <stdlib.h> @@ -65,6 +62,8 @@ static void l2caprtpr (kvm_t *kvmd, u_long addr); static void rfcommpr (kvm_t *kvmd, u_long addr); static void rfcommpr_s (kvm_t *kvmd, u_long addr); +static char * bdaddrpr (bdaddr_p const ba, char *str, int len); + static kvm_t * kopen (char const *memf); static int kread (kvm_t *kvmd, u_long addr, char *buffer, int size); @@ -99,6 +98,8 @@ static struct nlist nl[] = { * Main */ +static int numeric_bdaddr = 0; + int main(int argc, char *argv[]) { @@ -106,8 +107,12 @@ main(int argc, char *argv[]) kvm_t *kvmd = NULL; char *memf = NULL; - while ((opt = getopt(argc, argv, "hM:p:r")) != -1) { + while ((opt = getopt(argc, argv, "hnM:p:r")) != -1) { switch (opt) { + case 'n': + numeric_bdaddr = 1; + break; + case 'M': memf = optarg; break; @@ -265,7 +270,6 @@ l2caprawpr(kvm_t *kvmd, u_long addr) ng_btsocket_l2cap_raw_pcb_t pcb; struct socket so; int first = 1; - char bdaddr[32]; if (addr == 0) return; @@ -293,22 +297,13 @@ l2caprawpr(kvm_t *kvmd, u_long addr) "Local address"); } - if (memcmp(&pcb.src, NG_HCI_BDADDR_ANY, sizeof(pcb.src)) == 0) { - bdaddr[0] = '*'; - bdaddr[1] = 0; - } else - snprintf(bdaddr, sizeof(bdaddr), -"%02x:%02x:%02x:%02x:%02x:%02x", - pcb.src.b[5], pcb.src.b[4], pcb.src.b[3], - pcb.src.b[2], pcb.src.b[1], pcb.src.b[0]); - fprintf(stdout, "%-8.8x %-8.8x %6d %6d %-17.17s\n", (int) pcb.so, (int) this, so.so_rcv.sb_cc, so.so_snd.sb_cc, - bdaddr); + bdaddrpr(&pcb.src, NULL, 0)); } } /* l2caprawpr */ @@ -331,7 +326,7 @@ l2cappr(kvm_t *kvmd, u_long addr) ng_btsocket_l2cap_pcb_t pcb; struct socket so; int first = 1; - char local[32], remote[32]; + char local[24], remote[24]; if (addr == 0) return; @@ -361,31 +356,14 @@ l2cappr(kvm_t *kvmd, u_long addr) "State"); } - if (memcmp(&pcb.src, NG_HCI_BDADDR_ANY, sizeof(pcb.src)) == 0) - snprintf(local, sizeof(local), "*/%d", pcb.psm); - else - snprintf(local, sizeof(local), -"%02x:%02x:%02x:%02x:%02x:%02x/%d", - pcb.src.b[5], pcb.src.b[4], pcb.src.b[3], - pcb.src.b[2], pcb.src.b[1], pcb.src.b[0], - pcb.psm); - - if (memcmp(&pcb.dst, NG_HCI_BDADDR_ANY, sizeof(pcb.dst)) == 0) { - remote[0] = '*'; - remote[1] = 0; - } else - snprintf(remote, sizeof(remote), -"%02x:%02x:%02x:%02x:%02x:%02x", - pcb.dst.b[5], pcb.dst.b[4], pcb.dst.b[3], - pcb.dst.b[2], pcb.dst.b[1], pcb.dst.b[0]); - fprintf(stdout, -"%-8.8x %6d %6d %-23.23s %-17.17s %-5d %s\n", +"%-8.8x %6d %6d %-17.17s/%-5d %-17.17s %-5d %s\n", (int) this, so.so_rcv.sb_cc, so.so_snd.sb_cc, - local, - remote, + bdaddrpr(&pcb.src, local, sizeof(local)), + pcb.psm, + bdaddrpr(&pcb.dst, remote, sizeof(remote)), pcb.cid, (so.so_options & SO_ACCEPTCONN)? "LISTEN" : state2str(pcb.state)); @@ -402,7 +380,6 @@ l2caprtpr(kvm_t *kvmd, u_long addr) ng_btsocket_l2cap_rtentry_p this = NULL, next = NULL; ng_btsocket_l2cap_rtentry_t rt; int first = 1; - char bdaddr[32]; if (addr == 0) return; @@ -426,19 +403,11 @@ l2caprtpr(kvm_t *kvmd, u_long addr) "BD_ADDR"); } - if (memcmp(&rt.src, NG_HCI_BDADDR_ANY, sizeof(rt.src)) == 0) { - bdaddr[0] = '-'; - bdaddr[1] = 0; - } else - snprintf(bdaddr, sizeof(bdaddr), -"%02x:%02x:%02x:%02x:%02x:%02x", rt.src.b[5], rt.src.b[4], rt.src.b[3], - rt.src.b[2], rt.src.b[1], rt.src.b[0]); - fprintf(stdout, "%-8.8x %-8.8x %-17.17s\n", (int) this, (int) rt.hook, - bdaddr); + bdaddrpr(&rt.src, NULL, 0)); } } /* l2caprtpr */ @@ -462,7 +431,7 @@ rfcommpr(kvm_t *kvmd, u_long addr) ng_btsocket_rfcomm_pcb_t pcb; struct socket so; int first = 1; - char local[32], remote[32]; + char local[24], remote[24]; if (addr == 0) return; @@ -493,31 +462,13 @@ rfcommpr(kvm_t *kvmd, u_long addr) "State"); } - if (memcmp(&pcb.src, NG_HCI_BDADDR_ANY, sizeof(pcb.src)) == 0) { - local[0] = '*'; - local[1] = 0; - } else - snprintf(local, sizeof(local), -"%02x:%02x:%02x:%02x:%02x:%02x", - pcb.src.b[5], pcb.src.b[4], pcb.src.b[3], - pcb.src.b[2], pcb.src.b[1], pcb.src.b[0]); - - if (memcmp(&pcb.dst, NG_HCI_BDADDR_ANY, sizeof(pcb.dst)) == 0) { - remote[0] = '*'; - remote[1] = 0; - } else - snprintf(remote, sizeof(remote), -"%02x:%02x:%02x:%02x:%02x:%02x", - pcb.dst.b[5], pcb.dst.b[4], pcb.dst.b[3], - pcb.dst.b[2], pcb.dst.b[1], pcb.dst.b[0]); - fprintf(stdout, "%-8.8x %6d %6d %-17.17s %-17.17s %-4d %-4d %s\n", (int) this, so.so_rcv.sb_cc, so.so_snd.sb_cc, - local, - remote, + bdaddrpr(&pcb.src, local, sizeof(local)), + bdaddrpr(&pcb.dst, remote, sizeof(remote)), pcb.channel, pcb.dlci, (so.so_options & SO_ACCEPTCONN)? @@ -587,6 +538,40 @@ rfcommpr_s(kvm_t *kvmd, u_long addr) } /* rfcommpr_s */ /* + * Return BD_ADDR as string + */ + +static char * +bdaddrpr(bdaddr_p const ba, char *str, int len) +{ + static char buffer[MAXHOSTNAMELEN]; + struct hostent *he = NULL; + + if (str == NULL) { + str = buffer; + len = sizeof(buffer); + } + + if (memcmp(ba, NG_HCI_BDADDR_ANY, sizeof(*ba)) == 0) { + str[0] = '*'; + str[1] = 0; + + return (str); + } + + if (!numeric_bdaddr && + (he = bt_gethostbyaddr((char *)ba, sizeof(*ba), AF_BLUETOOTH)) != NULL) { + strlcpy(str, he->h_name, len); + + return (str); + } + + bt_ntoa(ba, str); + + return (str); +} /* bdaddrpr */ + +/* * Open kvm */ @@ -652,7 +637,7 @@ kread(kvm_t *kvmd, u_long addr, char *buffer, int size) static void usage(void) { - fprintf(stdout, "Usage: btsockstat [-M core ] [-p proto] [-r]\n"); + fprintf(stdout, "Usage: btsockstat [-M core ] [-n] [-p proto] [-r]\n"); exit(255); } /* usage */ diff --git a/usr.bin/bluetooth/rfcomm_sppd/Makefile b/usr.bin/bluetooth/rfcomm_sppd/Makefile index 53d9f31..6e493e8 100644 --- a/usr.bin/bluetooth/rfcomm_sppd/Makefile +++ b/usr.bin/bluetooth/rfcomm_sppd/Makefile @@ -1,15 +1,12 @@ -# $Id: Makefile,v 1.2 2003/04/26 23:55:34 max Exp $ +# $Id: Makefile,v 1.7 2003/09/07 18:15:55 max Exp $ # $FreeBSD$ PROG= rfcomm_sppd -MAN1= rfcomm_sppd.1 - -DESTDIR= /usr/bin/ -MANDIR= ../share/man/man - +MAN= rfcomm_sppd.1 +SRCS= rfcomm_sppd.c rfcomm_sdp.c WARNS?= 2 -CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include/ -SRCS= rfcomm_sppd.c +DPADD= ${LIBBLUETOOTH} ${LIBSDP} +LDADD= -lbluetooth -lsdp .include <bsd.prog.mk> diff --git a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sdp.c b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sdp.c new file mode 100644 index 0000000..ed6b827 --- /dev/null +++ b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sdp.c @@ -0,0 +1,266 @@ +/* + * rfcomm_sdp.c + * + * Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: rfcomm_sdp.c,v 1.1 2003/09/07 18:15:55 max Exp $ + * $FreeBSD$ + */ + +#include <bluetooth.h> +#include <errno.h> +#include <sdp.h> +#include <stdio.h> + +#undef PROTOCOL_DESCRIPTOR_LIST_BUFFER_SIZE +#define PROTOCOL_DESCRIPTOR_LIST_BUFFER_SIZE 256 + +#undef PROTOCOL_DESCRIPTOR_LIST_MINIMAL_SIZE +#define PROTOCOL_DESCRIPTOR_LIST_MINIMAL_SIZE 12 + +static int rfcomm_proto_list_parse (u_int8_t const *start, u_int8_t const *end, + int *channel, int *error); + +/* + * Lookup RFCOMM channel number in the Protocol Descriptor List + */ + +#undef rfcomm_channel_lookup_exit +#define rfcomm_channel_lookup_exit(e) { \ + if (error != NULL) \ + *error = (e); \ + if (ss != NULL) { \ + sdp_close(ss); \ + ss = NULL; \ + } \ + return (((e) == 0)? 0 : -1); \ +} + +int +rfcomm_channel_lookup(bdaddr_t const *local, bdaddr_t const *remote, + int service, int *channel, int *error) +{ + u_int8_t buffer[PROTOCOL_DESCRIPTOR_LIST_BUFFER_SIZE]; + void *ss = NULL; + u_int16_t serv = (u_int16_t) service; + u_int32_t attr = SDP_ATTR_RANGE( + SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST, + SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST); + sdp_attr_t proto = { SDP_ATTR_INVALID,0,sizeof(buffer),buffer }; + u_int32_t type, len; + + if (local == NULL) + local = NG_HCI_BDADDR_ANY; + if (remote == NULL || channel == NULL) + rfcomm_channel_lookup_exit(EINVAL); + + if ((ss = sdp_open(local, remote)) == NULL) + rfcomm_channel_lookup_exit(ENOMEM); + if (sdp_error(ss) != 0) + rfcomm_channel_lookup_exit(sdp_error(ss)); + + if (sdp_search(ss, 1, &serv, 1, &attr, 1, &proto) != 0) + rfcomm_channel_lookup_exit(sdp_error(ss)); + if (proto.flags != SDP_ATTR_OK) + rfcomm_channel_lookup_exit(ENOATTR); + + sdp_close(ss); + ss = NULL; + + /* + * If it is possible for more than one kind of protocol stack to be + * used to gain access to the service, the ProtocolDescriptorList + * takes the form of a data element alternative. We always use the + * first protocol stack. + * + * A minimal Protocol Descriptor List for RFCOMM based service would + * look like + * + * seq8 len8 - 2 bytes + * seq8 len8 - 2 bytes + * uuid16 value16 - 3 bytes L2CAP + * seq8 len8 - 2 bytes + * uuid16 value16 - 3 bytes RFCOMM + * uint8 value8 - 2 bytes RFCOMM param #1 + * ========= + * 14 bytes + * + * Lets not count first [seq8 len8] wrapper, so the minimal size of + * the Protocol Descriptor List (the data we are actually interested + * in) for RFCOMM based service would be 12 bytes. + */ + + if (proto.vlen < PROTOCOL_DESCRIPTOR_LIST_MINIMAL_SIZE) + rfcomm_channel_lookup_exit(EINVAL); + + SDP_GET8(type, proto.value); + + if (type == SDP_DATA_ALT8) { + SDP_GET8(len, proto.value); + } else if (type == SDP_DATA_ALT16) { + SDP_GET16(len, proto.value); + } else if (type == SDP_DATA_ALT32) { + SDP_GET32(len, proto.value); + } else + len = 0; + + if (len > 0) + SDP_GET8(type, proto.value); + + switch (type) { + case SDP_DATA_SEQ8: + SDP_GET8(len, proto.value); + break; + + case SDP_DATA_SEQ16: + SDP_GET16(len, proto.value); + break; + + case SDP_DATA_SEQ32: + SDP_GET32(len, proto.value); + break; + + default: + rfcomm_channel_lookup_exit(ENOATTR); + /* NOT REACHED */ + } + + if (len < PROTOCOL_DESCRIPTOR_LIST_MINIMAL_SIZE) + rfcomm_channel_lookup_exit(EINVAL); + + return (rfcomm_proto_list_parse(proto.value, + buffer + proto.vlen, channel, error)); +} + +/* + * Parse protocol descriptor list + * + * The ProtocolDescriptorList attribute describes one or more protocol + * stacks that may be used to gain access to the service described by + * the service record. If the ProtocolDescriptorList describes a single + * stack, it takes the form of a data element sequence in which each + * element of the sequence is a protocol descriptor. + */ + +#undef rfcomm_proto_list_parse_exit +#define rfcomm_proto_list_parse_exit(e) { \ + if (error != NULL) \ + *error = (e); \ + return (((e) == 0)? 0 : -1); \ +} + +static int +rfcomm_proto_list_parse(u_int8_t const *start, u_int8_t const *end, + int *channel, int *error) +{ + int type, len, value; + + while (start < end) { + + /* + * Parse protocol descriptor + * + * A protocol descriptor identifies a communications protocol + * and provides protocol specific parameters. A protocol + * descriptor is represented as a data element sequence. The + * first data element in the sequence must be the UUID that + * identifies the protocol. Additional data elements optionally + * provide protocol specific information, such as the L2CAP + * protocol/service multiplexer (PSM) and the RFCOMM server + * channel number (CN). + */ + + /* We must have at least one byte (type) */ + if (end - start < 1) + rfcomm_proto_list_parse_exit(EINVAL) + + SDP_GET8(type, start); + switch (type) { + case SDP_DATA_SEQ8: + SDP_GET8(len, start); + break; + + case SDP_DATA_SEQ16: + SDP_GET16(len, start); + break; + + case SDP_DATA_SEQ32: + SDP_GET32(len, start); + break; + + default: + rfcomm_proto_list_parse_exit(ENOATTR) + /* NOT REACHED */ + } + + /* We must have at least 3 bytes (type + UUID16) */ + if (end - start < 3) + rfcomm_proto_list_parse_exit(EINVAL); + + /* Get protocol UUID */ + SDP_GET8(type, start); len -= sizeof(u_int8_t); + switch (type) { + case SDP_DATA_UUID16: + SDP_GET16(value, start); len -= sizeof(u_int16_t); + if (value != SDP_UUID_PROTOCOL_RFCOMM) + goto next_protocol; + break; + + case SDP_DATA_UUID32: /* XXX FIXME can we have 32-bit UUID */ + case SDP_DATA_UUID128: /* XXX FIXME can we have 128-bit UUID */ + default: + rfcomm_proto_list_parse_exit(ENOATTR); + /* NOT REACHED */ + } + + /* + * First protocol specific parameter for RFCOMM procotol must + * be uint8 that represents RFCOMM channel number. So we must + * have at least two bytes. + */ + + if (end - start < 2) + rfcomm_proto_list_parse_exit(EINVAL); + + SDP_GET8(type, start); + if (type != SDP_DATA_UINT8) + rfcomm_proto_list_parse_exit(ENOATTR); + + SDP_GET8(*channel, start); + + rfcomm_proto_list_parse_exit(0); + /* NOT REACHED */ +next_protocol: + start += len; + } + + /* + * If we got here then it means we could not find RFCOMM protocol + * descriptor, but the reply format was actually valid. + */ + + rfcomm_proto_list_parse_exit(ENOATTR); +} + diff --git a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 index a2804b0..8d4a258 100644 --- a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 +++ b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: rfcomm_sppd.1,v 1.1 2003/04/26 23:55:34 max Exp $ +.\" $Id: rfcomm_sppd.1,v 1.3 2003/09/07 18:15:55 max Exp $ .\" $FreeBSD$ .\" .Dd April 26, 2003 @@ -72,8 +72,12 @@ This required option specifies the remote BD_ADDR of the RFCOMM server. .It Fl b Detach from the controlling terminal, i.e., run in background. .It Fl c Ar channel -This required option specifies RFCOMM channel to connect to. -This channel must provide Serial Port service. +This option specifies RFCOMM channel to connect to. +The channel must provide Serial Port service. +If channel was not specified then +.Nm +utility will try to obtain RFCOMM channel via Service Discovery Protocol from +the server. .It Fl h Display usage message and exit. .It Fl t Ar tty @@ -101,9 +105,7 @@ slave pseudo terminals .Sh DIAGNOSTICS .Ex -std .Sh BUGS -The -.Nm -utility is not currently integrated with SDP (Service Discovery Protocol). +Please report if found. .Sh SEE ALSO .Xr ng_btsocket 4 , .Xr pty 4 , diff --git a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c index dbb2032..ee689be 100644 --- a/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c +++ b/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c @@ -25,22 +25,18 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: rfcomm_sppd.c,v 1.2 2003/04/27 19:22:30 max Exp $ + * $Id: rfcomm_sppd.c,v 1.4 2003/09/07 18:15:55 max Exp $ * $FreeBSD$ */ -#include <sys/types.h> -#include <sys/socket.h> #include <sys/stat.h> -#include <bitstring.h> +#include <bluetooth.h> #include <err.h> #include <errno.h> #include <fcntl.h> #include <grp.h> #include <limits.h> -#include <ng_hci.h> -#include <ng_l2cap.h> -#include <ng_btsocket.h> +#include <sdp.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> @@ -54,6 +50,10 @@ #define SPPD_BUFFER_SIZE 1024 #define max(a, b) (((a) > (b))? (a) : (b)) +int rfcomm_channel_lookup (bdaddr_t const *local, + bdaddr_t const *remote, + int service, int *channel, int *error); + static int sppd_ttys_open (char const *tty, int *amaster, int *aslave); static int sppd_read (int fd, char *buffer, int size); static int sppd_write (int fd, char *buffer, int size); @@ -79,21 +79,16 @@ main(int argc, char *argv[]) /* Parse command line options */ while ((n = getopt(argc, argv, "a:bc:t:h")) != -1) { switch (n) { - case 'a': { /* BDADDR */ - int a0, a1, a2, a3, a4, a5; - - if (sscanf(optarg, "%x:%x:%x:%x:%x:%x", - &a5, &a4, &a3, &a2, &a1, &a0) != 6) - usage(); - /* NOT REACHED */ - - addr.b[0] = a0 & 0xff; - addr.b[1] = a1 & 0xff; - addr.b[2] = a2 & 0xff; - addr.b[3] = a3 & 0xff; - addr.b[4] = a4 & 0xff; - addr.b[5] = a5 & 0xff; - } break; + case 'a': /* BDADDR */ + if (!bt_aton(optarg, &addr)) { + struct hostent *he = NULL; + + if ((he = bt_gethostbyname(optarg)) == NULL) + errx(1, "%s: %s", optarg, hstrerror(h_errno)); + + memcpy(&addr, he->h_addr, sizeof(addr)); + } + break; case 'c': /* RFCOMM channel */ channel = atoi(optarg); @@ -115,8 +110,7 @@ main(int argc, char *argv[]) } /* Check if we have everything we need */ - if (channel == 0 || tty == NULL || - memcmp(&addr, NG_HCI_BDADDR_ANY, sizeof(addr)) == 0) + if (tty == NULL || memcmp(&addr, NG_HCI_BDADDR_ANY, sizeof(addr)) == 0) usage(); /* NOT REACHED */ @@ -139,6 +133,14 @@ main(int argc, char *argv[]) if (sigaction(SIGCHLD, &sa, NULL) < 0) err(1, "Could not sigaction(SIGCHLD)"); + /* Check channel, if was not set then obtain it via SDP */ + if (channel == 0) + if (rfcomm_channel_lookup(NULL, &addr, + SDP_SERVICE_CLASS_SERIAL_PORT, &channel, &n) != 0) + errc(1, n, "Could not obtain RFCOMM channel"); + if (channel <= 0 || channel > 30) + errx(1, "Invalid RFCOMM channel number %d", channel); + /* Open TTYs */ if (sppd_ttys_open(tty, &amaster, &aslave) < 0) exit(1); @@ -374,7 +376,7 @@ usage(void) "Where options are:\n" \ "\t-a bdaddr BDADDR to connect to (required)\n" \ "\t-b Run in background\n" \ -"\t-c channel RFCOMM channel to connect to (required)\n" \ +"\t-c channel RFCOMM channel to connect to\n" \ "\t-t tty TTY name\n" \ "\t-h Display this message\n", SPPD_IDENT); |