summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bluetooth
diff options
context:
space:
mode:
authoremax <emax@FreeBSD.org>2003-10-12 22:04:24 +0000
committeremax <emax@FreeBSD.org>2003-10-12 22:04:24 +0000
commit41bb0e8fd2568243020852e22a6d176bccfa60cd (patch)
tree0ae0c2be63f9f9161693789721b96beb9cabcc77 /usr.sbin/bluetooth
parent66feac7937e372f502539e7d443aee80a25abe16 (diff)
downloadFreeBSD-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.sbin/bluetooth')
-rw-r--r--usr.sbin/bluetooth/Makefile22
-rw-r--r--usr.sbin/bluetooth/Makefile.inc4
-rw-r--r--usr.sbin/bluetooth/bcmfw/Makefile20
-rw-r--r--usr.sbin/bluetooth/bcmfw/bcmfw.813
-rw-r--r--usr.sbin/bluetooth/bt3cfw/Makefile9
-rw-r--r--usr.sbin/bluetooth/bt3cfw/bt3cfw.82
-rw-r--r--usr.sbin/bluetooth/bt3cfw/bt3cfw.c4
-rw-r--r--usr.sbin/bluetooth/hccontrol/Makefile12
-rw-r--r--usr.sbin/bluetooth/hccontrol/hccontrol.813
-rw-r--r--usr.sbin/bluetooth/hccontrol/hccontrol.c18
-rw-r--r--usr.sbin/bluetooth/hccontrol/hccontrol.h3
-rw-r--r--usr.sbin/bluetooth/hccontrol/host_controller_baseband.c244
-rw-r--r--usr.sbin/bluetooth/hccontrol/info.c10
-rw-r--r--usr.sbin/bluetooth/hccontrol/link_control.c58
-rw-r--r--usr.sbin/bluetooth/hccontrol/link_policy.c29
-rw-r--r--usr.sbin/bluetooth/hccontrol/node.c28
-rw-r--r--usr.sbin/bluetooth/hccontrol/send_recv.c4
-rw-r--r--usr.sbin/bluetooth/hccontrol/status.c4
-rw-r--r--usr.sbin/bluetooth/hccontrol/util.c32
-rw-r--r--usr.sbin/bluetooth/hcsecd/Makefile13
-rw-r--r--usr.sbin/bluetooth/hcsecd/hcsecd.862
-rw-r--r--usr.sbin/bluetooth/hcsecd/hcsecd.c150
-rw-r--r--usr.sbin/bluetooth/hcsecd/hcsecd.conf.5129
-rw-r--r--usr.sbin/bluetooth/hcsecd/hcsecd.h12
-rw-r--r--usr.sbin/bluetooth/hcsecd/parser.y145
-rw-r--r--usr.sbin/bluetooth/hcseriald/Makefile11
-rw-r--r--usr.sbin/bluetooth/hcseriald/hcseriald.82
-rw-r--r--usr.sbin/bluetooth/hcseriald/hcseriald.c4
-rw-r--r--usr.sbin/bluetooth/l2control/Makefile12
-rw-r--r--usr.sbin/bluetooth/l2control/l2cap.c50
-rw-r--r--usr.sbin/bluetooth/l2control/l2control.89
-rw-r--r--usr.sbin/bluetooth/l2control/l2control.c47
-rw-r--r--usr.sbin/bluetooth/l2ping/Makefile10
-rw-r--r--usr.sbin/bluetooth/l2ping/l2ping.82
-rw-r--r--usr.sbin/bluetooth/l2ping/l2ping.c78
-rw-r--r--usr.sbin/bluetooth/rfcomm_pppd/Makefile15
-rw-r--r--usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.829
-rw-r--r--usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c80
-rw-r--r--usr.sbin/bluetooth/sdpcontrol/Makefile12
-rw-r--r--usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8100
-rw-r--r--usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c197
-rw-r--r--usr.sbin/bluetooth/sdpcontrol/sdpcontrol.h49
-rw-r--r--usr.sbin/bluetooth/sdpcontrol/search.c707
43 files changed, 1991 insertions, 463 deletions
diff --git a/usr.sbin/bluetooth/Makefile b/usr.sbin/bluetooth/Makefile
index 32e1806..916a1aea 100644
--- a/usr.sbin/bluetooth/Makefile
+++ b/usr.sbin/bluetooth/Makefile
@@ -1,14 +1,16 @@
-# $Id: Makefile,v 1.3 2003/04/01 02:06:47 max Exp $
+# $Id: Makefile,v 1.5 2003/09/08 02:28:35 max Exp $
# $FreeBSD$
-SUBDIR= \
- bt3cfw \
- bcmfw \
- hccontrol \
- hcsecd \
- hcseriald \
- l2control \
- l2ping \
- rfcomm_pppd
+SUBDIR= \
+ bcmfw \
+ bt3cfw \
+ hccontrol \
+ hcsecd \
+ hcseriald \
+ l2control \
+ l2ping \
+ rfcomm_pppd \
+ sdpcontrol
+
.include <bsd.subdir.mk>
diff --git a/usr.sbin/bluetooth/Makefile.inc b/usr.sbin/bluetooth/Makefile.inc
new file mode 100644
index 0000000..c0e05cf
--- /dev/null
+++ b/usr.sbin/bluetooth/Makefile.inc
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+.include "${.CURDIR}/../../Makefile.inc"
+
diff --git a/usr.sbin/bluetooth/bcmfw/Makefile b/usr.sbin/bluetooth/bcmfw/Makefile
index fc2abca..e601a76 100644
--- a/usr.sbin/bluetooth/bcmfw/Makefile
+++ b/usr.sbin/bluetooth/bcmfw/Makefile
@@ -1,23 +1,9 @@
-# $Id: Makefile,v 1.2 2003/04/27 00:44:54 max Exp $
+# $Id: Makefile,v 1.6 2003/08/14 20:05:58 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
PROG= bcmfw
-MAN8= bcmfw.8
-WARNS?= 2
-CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
+MAN= bcmfw.8
SRCS= bcmfw.c
+WARNS?= 2
-#FILESDIR= ../local/etc/
-#FILES+= BCM2033-FW.bin BCM2033-MD.hex
-#CLEANFILES+= BCM2033-FW.bin BCM2033-MD.hex
-#
-#BCM2033-FW.bin: BCM2033-FW.bin.uue
-# uudecode BCM2033-FW.bin.uue
-#
-#BCM2033-MD.hex: BCM2033-MD.hex.uue
-# uudecode BCM2033-MD.hex.uue
-#
.include <bsd.prog.mk>
-#.include <bsd.files.mk>
diff --git a/usr.sbin/bluetooth/bcmfw/bcmfw.8 b/usr.sbin/bluetooth/bcmfw/bcmfw.8
index b961167..d5b984b 100644
--- a/usr.sbin/bluetooth/bcmfw/bcmfw.8
+++ b/usr.sbin/bluetooth/bcmfw/bcmfw.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: bcmfw.8,v 1.4 2003/04/28 17:10:56 max Exp $
+.\" $Id: bcmfw.8,v 1.7 2003/05/21 00:33:40 max Exp $
.\" $FreeBSD$
.\"
.Dd March 31, 2003
@@ -51,6 +51,17 @@ The vendor ID should be 0x0a5c
.Pq Dv USB_VENDOR_BROADCOM
and the product ID should be 0x2033.
.Pp
+Due to copyright issues I will no longer provide mini-driver and firmware
+files for the device. These files can be obtained from the Linux BlueZ BlueFW
+package.
+.Pp
+Visit http://bluez.sourceforge.net/download/download.html for details.
+.Pp
+I am using the following files:
+.Pp
+.Dl "MD5 (BCM2033-MD.hex) = 5580317158d07fc4ace90af04f8e1c73"
+.Dl "MD5 (BCM2033-FW.bin) = a3a0edfcb85029f4a5d0b1c9649b127d"
+.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl f Ar firmware_file_name
diff --git a/usr.sbin/bluetooth/bt3cfw/Makefile b/usr.sbin/bluetooth/bt3cfw/Makefile
index 6310c0a..daa0f65 100644
--- a/usr.sbin/bluetooth/bt3cfw/Makefile
+++ b/usr.sbin/bluetooth/bt3cfw/Makefile
@@ -1,13 +1,10 @@
-# $Id: Makefile,v 1.2 2003/03/15 03:06:53 max Exp $
+# $Id: Makefile,v 1.5 2003/08/14 20:06:00 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
PROG= bt3cfw
-MAN8= bt3cfw.8
-WARNS?= 2
-CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
+MAN= bt3cfw.8
SRCS= bt3cfw.c
+WARNS?= 2
DPADD= ${LIBNETGRAPH}
LDADD= -lnetgraph
diff --git a/usr.sbin/bluetooth/bt3cfw/bt3cfw.8 b/usr.sbin/bluetooth/bt3cfw/bt3cfw.8
index 83a3fcb..74aa6d7 100644
--- a/usr.sbin/bluetooth/bt3cfw/bt3cfw.8
+++ b/usr.sbin/bluetooth/bt3cfw/bt3cfw.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: bt3cfw.8,v 1.3 2003/04/27 19:45:22 max Exp $
+.\" $Id: bt3cfw.8,v 1.4 2003/05/21 00:34:51 max Exp $
.\" $FreeBSD$
.\"
.Dd November 11, 2002
diff --git a/usr.sbin/bluetooth/bt3cfw/bt3cfw.c b/usr.sbin/bluetooth/bt3cfw/bt3cfw.c
index d0a32a8..02b40ed 100644
--- a/usr.sbin/bluetooth/bt3cfw/bt3cfw.c
+++ b/usr.sbin/bluetooth/bt3cfw/bt3cfw.c
@@ -25,20 +25,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bt3cfw.c,v 1.1 2002/11/24 20:22:37 max Exp $
+ * $Id: bt3cfw.c,v 1.2 2003/05/21 22:40:29 max Exp $
* $FreeBSD$
*/
#include <sys/types.h>
#include <errno.h>
#include <netgraph.h>
+#include <netgraph/bluetooth/include/ng_bt3c.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
-#include "ng_bt3c.h"
#define BT3CFW_IDENT "bt3cfw"
#define BT3CFW_MAX_FIRMWARE_SIZE 0xffff
diff --git a/usr.sbin/bluetooth/hccontrol/Makefile b/usr.sbin/bluetooth/hccontrol/Makefile
index 5b68cd8..592247e 100644
--- a/usr.sbin/bluetooth/hccontrol/Makefile
+++ b/usr.sbin/bluetooth/hccontrol/Makefile
@@ -1,14 +1,14 @@
-# $Id: Makefile,v 1.2 2003/03/15 03:07:39 max Exp $
+# $Id: Makefile,v 1.7 2003/08/14 20:06:17 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
PROG= hccontrol
-MAN8= hccontrol.8
-WARNS?= 2
-CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
+MAN= hccontrol.8
SRCS= send_recv.c link_policy.c link_control.c \
host_controller_baseband.c info.c status.c node.c hccontrol.c \
util.c
+WARNS?= 2
+
+DPADD= ${LIBBLUETOOTH}
+LDADD= -lbluetooth
.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.8 b/usr.sbin/bluetooth/hccontrol/hccontrol.8
index e55635c..559b5f6 100644
--- a/usr.sbin/bluetooth/hccontrol/hccontrol.8
+++ b/usr.sbin/bluetooth/hccontrol/hccontrol.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: hccontrol.8,v 1.3 2003/04/27 19:45:23 max Exp $
+.\" $Id: hccontrol.8,v 1.6 2003/08/06 21:26:38 max Exp $
.\" $FreeBSD$
.\"
.Dd June 14, 2002
@@ -33,7 +33,7 @@
.Nd HCI configuration utility
.Sh SYNOPSIS
.Nm
-.Op Fl h
+.Op Fl hN
.Fl n Ar HCI_node_name
.Ar command
.Op Ar parameters ...
@@ -53,6 +53,11 @@ The options are as follows:
.Bl -tag -width indent
.It Fl h
Display usage message and exit.
+.It Fl N
+Show Bluetooth addresses as numbers.
+Normally
+.Nm
+attempts to resolve Bluetooth addresses, and display them symbolically.
.It Fl n Ar HCI_node_name
Connect to the specified HCI Netgraph node.
.It Ar command
@@ -118,6 +123,10 @@ are:
.It Cm Write_SCO_Flow_Control_Enable
.It Cm Read_Link_Supervision_Timeout
.It Cm Write_Link_Supervision_Timeout
+.It Cm Read_Page_Scan_Period_Mode
+.It Cm Write_Page_Scan_Period_Mode
+.It Cm Read_Page_Scan_Mode
+.It Cm Write_Page_Scan_Mode
.It Cm Read_Local_Version_Information
.It Cm Read_Local_Supported_Features
.It Cm Read_Buffer_Size
diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.c b/usr.sbin/bluetooth/hccontrol/hccontrol.c
index fafbf7b..0bf5583 100644
--- a/usr.sbin/bluetooth/hccontrol/hccontrol.c
+++ b/usr.sbin/bluetooth/hccontrol/hccontrol.c
@@ -25,20 +25,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: hccontrol.c,v 1.2 2003/04/27 19:45:24 max Exp $
+ * $Id: hccontrol.c,v 1.5 2003/09/05 00:38:24 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <bluetooth.h>
#include <sys/sysctl.h>
#include <assert.h>
-#include <bitstring.h>
#include <err.h>
#include <errno.h>
-#include <ng_hci.h>
-#include <ng_l2cap.h>
-#include <ng_btsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -54,6 +49,7 @@ static void usage (void);
/* Globals */
int verbose = 0;
int timeout;
+int numeric_bdaddr = 0;
/* Main */
int
@@ -63,12 +59,16 @@ main(int argc, char *argv[])
int n;
/* Process command line arguments */
- while ((n = getopt(argc, argv, "n:vh")) != -1) {
+ while ((n = getopt(argc, argv, "n:Nvh")) != -1) {
switch (n) {
case 'n':
node = optarg;
break;
+ case 'N':
+ numeric_bdaddr = 1;
+ break;
+
case 'v':
verbose = 1;
break;
@@ -254,7 +254,7 @@ find_hci_command(char const *command, struct hci_command *category)
return (NULL);
} /* find_hci_command */
-/* Try to find command in specified category */
+/* Print commands in specified category */
static void
print_hci_command(struct hci_command *category)
{
diff --git a/usr.sbin/bluetooth/hccontrol/hccontrol.h b/usr.sbin/bluetooth/hccontrol/hccontrol.h
index d578fea..001ca71 100644
--- a/usr.sbin/bluetooth/hccontrol/hccontrol.h
+++ b/usr.sbin/bluetooth/hccontrol/hccontrol.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: hccontrol.h,v 1.1 2002/11/24 20:22:38 max Exp $
+ * $Id: hccontrol.h,v 1.2 2003/05/19 17:29:29 max Exp $
* $FreeBSD$
*/
@@ -70,6 +70,7 @@ char const * const hci_features2str (u_int8_t *, char *, int);
char const * const hci_cc2str (int);
char const * const hci_con_state2str (int);
char const * const hci_status2str (int);
+char const * const hci_bdaddr2str (bdaddr_t const *);
#endif /* _HCCONTROL_H_ */
diff --git a/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c b/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
index 5854b00..fd4d60e 100644
--- a/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
+++ b/usr.sbin/bluetooth/hccontrol/host_controller_baseband.c
@@ -25,14 +25,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: host_controller_baseband.c,v 1.1 2002/11/24 20:22:38 max Exp $
+ * $Id: host_controller_baseband.c,v 1.4 2003/08/18 19:19:53 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/endian.h>
+#include <bluetooth.h>
#include <errno.h>
-#include <ng_hci.h>
#include <stdio.h>
#include <string.h>
#include "hccontrol.h"
@@ -189,7 +187,7 @@ hci_read_stored_link_key(int s, int argc, char **argv)
} ep;
} __attribute__ ((packed)) event;
- int n,a0,a1,a2,a3,a4,a5;
+ int n, n1;
/* Send command */
memset(&cmd, 0, sizeof(cmd));
@@ -201,16 +199,14 @@ hci_read_stored_link_key(int s, int argc, char **argv)
switch (argc) {
case 1:
/* parse BD_ADDR */
- if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &a5, &a4, &a3, &a2,
- &a1, &a0) != 6)
- return (USAGE);
+ if (!bt_aton(argv[0], &cmd.cp.bdaddr)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(argv[0])) == NULL)
+ return (USAGE);
- cmd.cp.bdaddr.b[0] = (a0 & 0xff);
- cmd.cp.bdaddr.b[1] = (a1 & 0xff);
- cmd.cp.bdaddr.b[2] = (a2 & 0xff);
- cmd.cp.bdaddr.b[3] = (a3 & 0xff);
- cmd.cp.bdaddr.b[4] = (a4 & 0xff);
- cmd.cp.bdaddr.b[5] = (a5 & 0xff);
+ memcpy(&cmd.cp.bdaddr, he->h_addr, sizeof(cmd.cp.bdaddr));
+ }
break;
default:
@@ -269,13 +265,11 @@ again:
k = (struct _key *)(event.ep.b + sizeof(event.ep.key));
for (n = 0; n < event.ep.key.num_keys; n++) {
- fprintf(stdout, "\t%d: %02x:%02x:%02x:%02x:%02x:%02x ",
- n + 1,
- k->bdaddr.b[5], k->bdaddr.b[4], k->bdaddr.b[3],
- k->bdaddr.b[2], k->bdaddr.b[1], k->bdaddr.b[0]);
+ fprintf(stdout, "\t%d: %s ",
+ n + 1, hci_bdaddr2str(&k->bdaddr));
- for (a0 = 0; a0 < sizeof(k->key); a0++)
- fprintf(stdout, "%02x", k->key[a0]);
+ for (n1 = 0; n1 < sizeof(k->key); n1++)
+ fprintf(stdout, "%02x", k->key[n1]);
fprintf(stdout, "\n");
k ++;
@@ -302,7 +296,7 @@ hci_write_stored_link_key(int s, int argc, char **argv)
u_int8_t key[NG_HCI_KEY_SIZE];
} cp;
ng_hci_write_stored_link_key_rp rp;
- int32_t n, a0, a1, a2, a3, a4, a5;
+ int32_t n;
memset(&cp, 0, sizeof(cp));
@@ -311,16 +305,14 @@ hci_write_stored_link_key(int s, int argc, char **argv)
cp.p.num_keys_write = 1;
/* parse BD_ADDR */
- if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x",
- &a5, &a4, &a3, &a2, &a1, &a0) != 6)
- return (USAGE);
+ if (!bt_aton(argv[0], &cp.bdaddr)) {
+ struct hostent *he = NULL;
- cp.bdaddr.b[0] = (a0 & 0xff);
- cp.bdaddr.b[1] = (a1 & 0xff);
- cp.bdaddr.b[2] = (a2 & 0xff);
- cp.bdaddr.b[3] = (a3 & 0xff);
- cp.bdaddr.b[4] = (a4 & 0xff);
- cp.bdaddr.b[5] = (a5 & 0xff);
+ if ((he = bt_gethostbyname(argv[0])) == NULL)
+ return (USAGE);
+
+ memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
+ }
/* parse key */
if (hci_hexstring2array(argv[1], cp.key, sizeof(cp.key)) < 0)
@@ -357,23 +349,21 @@ hci_delete_stored_link_key(int s, int argc, char **argv)
{
ng_hci_delete_stored_link_key_cp cp;
ng_hci_delete_stored_link_key_rp rp;
- int32_t n, a0, a1, a2, a3, a4, a5;
+ int32_t n;
memset(&cp, 0, sizeof(cp));
switch (argc) {
case 1:
/* parse BD_ADDR */
- if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x",
- &a5, &a4, &a3, &a2, &a1, &a0) != 6)
- return (USAGE);
+ if (!bt_aton(argv[0], &cp.bdaddr)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(argv[0])) == NULL)
+ return (USAGE);
- cp.bdaddr.b[0] = (a0 & 0xff);
- cp.bdaddr.b[1] = (a1 & 0xff);
- cp.bdaddr.b[2] = (a2 & 0xff);
- cp.bdaddr.b[3] = (a3 & 0xff);
- cp.bdaddr.b[4] = (a4 & 0xff);
- cp.bdaddr.b[5] = (a5 & 0xff);
+ memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
+ }
break;
default:
@@ -1372,6 +1362,131 @@ hci_write_link_supervision_timeout(int s, int argc, char **argv)
return (OK);
} /* hci_write_link_supervision_timeout */
+/* Send Read_Page_Scan_Period_Mode command to the unit */
+static int
+hci_read_page_scan_period_mode(int s, int argc, char **argv)
+{
+ ng_hci_read_page_scan_period_rp rp;
+ int n;
+
+ n = sizeof(rp);
+ if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
+ NG_HCI_OCF_READ_PAGE_SCAN_PERIOD),
+ (char *) &rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ fprintf(stdout, "Page scan period mode: %#02x\n",
+ rp.page_scan_period_mode);
+
+ return (OK);
+} /* hci_read_page_scan_period_mode */
+
+/* Send Write_Page_Scan_Period_Mode command to the unit */
+static int
+hci_write_page_scan_period_mode(int s, int argc, char **argv)
+{
+ ng_hci_write_page_scan_period_cp cp;
+ ng_hci_write_page_scan_period_rp rp;
+ int n;
+
+ /* parse command arguments */
+ switch (argc) {
+ case 1:
+ if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 2)
+ return (USAGE);
+
+ cp.page_scan_period_mode = (n & 0xff);
+ break;
+
+ default:
+ return (USAGE);
+ }
+
+ /* send command */
+ n = sizeof(rp);
+ if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
+ NG_HCI_OCF_WRITE_PAGE_SCAN_PERIOD),
+ (char const *) &cp, sizeof(cp),
+ (char *) &rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ return (OK);
+} /* hci_write_page_scan_period_mode */
+
+/* Send Read_Page_Scan_Mode command to the unit */
+static int
+hci_read_page_scan_mode(int s, int argc, char **argv)
+{
+ ng_hci_read_page_scan_rp rp;
+ int n;
+
+ n = sizeof(rp);
+ if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
+ NG_HCI_OCF_READ_PAGE_SCAN),
+ (char *) &rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ fprintf(stdout, "Page scan mode: %#02x\n", rp.page_scan_mode);
+
+ return (OK);
+} /* hci_read_page_scan_mode */
+
+/* Send Write_Page_Scan_Mode command to the unit */
+static int
+hci_write_page_scan_mode(int s, int argc, char **argv)
+{
+ ng_hci_write_page_scan_cp cp;
+ ng_hci_write_page_scan_rp rp;
+ int n;
+
+ /* parse command arguments */
+ switch (argc) {
+ case 1:
+ if (sscanf(argv[0], "%d", &n) != 1 || n < 0 || n > 3)
+ return (USAGE);
+
+ cp.page_scan_mode = (n & 0xff);
+ break;
+
+ default:
+ return (USAGE);
+ }
+
+ /* send command */
+ n = sizeof(rp);
+ if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND,
+ NG_HCI_OCF_WRITE_PAGE_SCAN),
+ (char const *) &cp, sizeof(cp),
+ (char *) &rp, &n) == ERROR)
+ return (ERROR);
+
+ if (rp.status != 0x00) {
+ fprintf(stdout, "Status: %s [%#02x]\n",
+ hci_status2str(rp.status), rp.status);
+ return (FAILED);
+ }
+
+ return (OK);
+} /* hci_write_page_scan_mode */
+
struct hci_command host_controller_baseband_commands[] = {
{
"reset",
@@ -1708,6 +1823,55 @@ struct hci_command host_controller_baseband_commands[] = {
"\t<timeout> - dddd; timeout measured in number of baseband slots\n",
&hci_write_link_supervision_timeout
},
+{
+"read_page_scan_period_mode",
+"\nThis command is used to read the mandatory Page_Scan_Period_Mode of the\n" \
+"local Bluetooth device. Every time an inquiry response message is sent, the\n"\
+"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
+"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
+"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
+"following page scans.",
+&hci_read_page_scan_period_mode
+},
+{
+"write_page_scan_period_mode <page_scan_period_mode>",
+"\nThis command is used to write the mandatory Page_Scan_Period_Mode of the\n" \
+"local Bluetooth device. Every time an inquiry response message is sent, the\n"\
+"Bluetooth device will start a timer (T_mandatory_pscan), the value of which\n"\
+"is dependent on the Page_Scan_Period_Mode. As long as this timer has not\n" \
+"expired, the Bluetooth device will use the Page_Scan_Period_Mode for all\n" \
+"following page scans.\n\n" \
+"\t<page_scan_period_mode> - dd; page scan period mode:\n" \
+"\t0x00 - P0 (Default)\n" \
+"\t0x01 - P1\n" \
+"\t0x02 - P2",
+&hci_write_page_scan_period_mode
+},
+{
+"read_page_scan_mode",
+"\nThis command is used to read the default page scan mode of the local\n" \
+"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
+"that is used for the default page scan. Currently one mandatory page scan\n"\
+"mode and three optional page scan modes are defined. Following an inquiry\n" \
+"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
+"mandatory page scan mode must be applied.",
+&hci_read_page_scan_mode
+},
+{
+"write_page_scan_mode <page_scan_mode>",
+"\nThis command is used to write the default page scan mode of the local\n" \
+"Bluetooth device. The Page_Scan_Mode parameter indicates the page scan mode\n"\
+"that is used for the default page scan. Currently, one mandatory page scan\n"\
+"mode and three optional page scan modes are defined. Following an inquiry\n"\
+"response, if the Baseband timer T_mandatory_pscan has not expired, the\n" \
+"mandatory page scan mode must be applied.\n\n" \
+"\t<page_scan_mode> - dd; page scan mode:\n" \
+"\t0x00 - Mandatory Page Scan Mode (Default)\n" \
+"\t0x01 - Optional Page Scan Mode I\n" \
+"\t0x02 - Optional Page Scan Mode II\n" \
+"\t0x03 - Optional Page Scan Mode III",
+&hci_write_page_scan_mode
+},
{ NULL, }
};
diff --git a/usr.sbin/bluetooth/hccontrol/info.c b/usr.sbin/bluetooth/hccontrol/info.c
index 1a8649f..12b685b 100644
--- a/usr.sbin/bluetooth/hccontrol/info.c
+++ b/usr.sbin/bluetooth/hccontrol/info.c
@@ -25,14 +25,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: info.c,v 1.1 2002/11/24 20:22:38 max Exp $
+ * $Id: info.c,v 1.3 2003/08/18 19:19:54 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/endian.h>
+#include <bluetooth.h>
#include <errno.h>
-#include <ng_hci.h>
#include <stdio.h>
#include <string.h>
#include "hccontrol.h"
@@ -173,9 +171,7 @@ hci_read_bd_addr(int s, int argc, char **argv)
return (FAILED);
}
- fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- rp.bdaddr.b[5], rp.bdaddr.b[4], rp.bdaddr.b[3],
- rp.bdaddr.b[2], rp.bdaddr.b[1], rp.bdaddr.b[0]);
+ fprintf(stdout, "BD_ADDR: %s\n", bt_ntoa(&rp.bdaddr, NULL));
return (OK);
} /* hci_read_bd_addr */
diff --git a/usr.sbin/bluetooth/hccontrol/link_control.c b/usr.sbin/bluetooth/hccontrol/link_control.c
index 2f3b4b2..0b8ec84 100644
--- a/usr.sbin/bluetooth/hccontrol/link_control.c
+++ b/usr.sbin/bluetooth/hccontrol/link_control.c
@@ -25,14 +25,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: link_control.c,v 1.2 2003/03/15 03:07:39 max Exp $
+ * $Id: link_control.c,v 1.4 2003/08/18 19:19:54 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/endian.h>
+#include <bluetooth.h>
#include <errno.h>
-#include <ng_hci.h>
#include <stdio.h>
#include <string.h>
#include "hccontrol.h"
@@ -158,9 +156,7 @@ hci_inquiry_response(int n, u_int8_t **b)
} *ir = (struct inquiry_response *)(*b);
fprintf(stdout, "Inquiry result #%d\n", n);
- fprintf(stdout, "\tBD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- ir->bdaddr.b[5], ir->bdaddr.b[4], ir->bdaddr.b[3],
- ir->bdaddr.b[2], ir->bdaddr.b[1], ir->bdaddr.b[0]);
+ fprintf(stdout, "\tBD_ADDR: %s\n", hci_bdaddr2str(&ir->bdaddr));
fprintf(stdout, "\tPage Scan Rep. Mode: %#02x\n",
ir->page_scan_rep_mode);
fprintf(stdout, "\tPage Scan Period Mode: %#02x\n",
@@ -179,7 +175,7 @@ hci_inquiry_response(int n, u_int8_t **b)
static int
hci_create_connection(int s, int argc, char **argv)
{
- int n0, n1, n2, n3, n4, n5;
+ int n0;
char b[512];
ng_hci_create_con_cp cp;
ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t *) b;
@@ -241,16 +237,14 @@ hci_create_connection(int s, int argc, char **argv)
case 1:
/* BD_ADDR */
- if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x",
- &n5, &n4, &n3, &n2, &n1, &n0) != 6)
- return (USAGE);
+ if (!bt_aton(argv[0], &cp.bdaddr)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(argv[0])) == NULL)
+ return (USAGE);
- cp.bdaddr.b[0] = (n0 & 0xff);
- cp.bdaddr.b[1] = (n1 & 0xff);
- cp.bdaddr.b[2] = (n2 & 0xff);
- cp.bdaddr.b[3] = (n3 & 0xff);
- cp.bdaddr.b[4] = (n4 & 0xff);
- cp.bdaddr.b[5] = (n5 & 0xff);
+ memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
+ }
break;
default:
@@ -286,9 +280,7 @@ again:
return (FAILED);
}
- fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- ep->bdaddr.b[5], ep->bdaddr.b[4], ep->bdaddr.b[3],
- ep->bdaddr.b[2], ep->bdaddr.b[1], ep->bdaddr.b[0]);
+ fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
fprintf(stdout, "Connection handle: %d\n",
le16toh(ep->con_handle));
fprintf(stdout, "Encryption mode: %s [%d]\n",
@@ -443,9 +435,7 @@ again:
return (FAILED);
}
- fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- ep->bdaddr.b[5], ep->bdaddr.b[4], ep->bdaddr.b[3],
- ep->bdaddr.b[2], ep->bdaddr.b[1], ep->bdaddr.b[0]);
+ fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
fprintf(stdout, "Connection handle: %d\n",
le16toh(ep->con_handle));
fprintf(stdout, "Encryption mode: %s [%d]\n",
@@ -531,7 +521,7 @@ again:
static int
hci_remote_name_request(int s, int argc, char **argv)
{
- int n0, n1, n2, n3, n4, n5;
+ int n0;
char b[512];
ng_hci_remote_name_req_cp cp;
ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t *) b;
@@ -566,16 +556,14 @@ hci_remote_name_request(int s, int argc, char **argv)
case 1:
/* BD_ADDR */
- if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x",
- &n5, &n4, &n3, &n2, &n1, &n0) != 6)
- return (USAGE);
+ if (!bt_aton(argv[0], &cp.bdaddr)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(argv[0])) == NULL)
+ return (USAGE);
- cp.bdaddr.b[0] = (n0 & 0xff);
- cp.bdaddr.b[1] = (n1 & 0xff);
- cp.bdaddr.b[2] = (n2 & 0xff);
- cp.bdaddr.b[3] = (n3 & 0xff);
- cp.bdaddr.b[4] = (n4 & 0xff);
- cp.bdaddr.b[5] = (n5 & 0xff);
+ memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
+ }
break;
default:
@@ -612,9 +600,7 @@ again:
return (FAILED);
}
- fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- ep->bdaddr.b[5], ep->bdaddr.b[4], ep->bdaddr.b[3],
- ep->bdaddr.b[2], ep->bdaddr.b[1], ep->bdaddr.b[0]);
+ fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
fprintf(stdout, "Name: %s\n", ep->name);
} else
goto again;
diff --git a/usr.sbin/bluetooth/hccontrol/link_policy.c b/usr.sbin/bluetooth/hccontrol/link_policy.c
index 0a40f56..387d601 100644
--- a/usr.sbin/bluetooth/hccontrol/link_policy.c
+++ b/usr.sbin/bluetooth/hccontrol/link_policy.c
@@ -25,15 +25,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: link_policy.c,v 1.1 2002/11/24 20:22:38 max Exp $
+ * $Id: link_policy.c,v 1.3 2003/08/18 19:19:54 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/endian.h>
+#include <bluetooth.h>
#include <errno.h>
-#include <ng_hci.h>
#include <stdio.h>
+#include <string.h>
#include "hccontrol.h"
/* Send Role Discovery to the unit */
@@ -84,7 +83,7 @@ hci_role_discovery(int s, int argc, char **argv)
static int
hci_switch_role(int s, int argc, char **argv)
{
- int n0, n1, n2, n3, n4, n5;
+ int n0;
char b[512];
ng_hci_switch_role_cp cp;
ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t *) b;
@@ -93,16 +92,14 @@ hci_switch_role(int s, int argc, char **argv)
switch (argc) {
case 2:
/* bdaddr */
- if (sscanf(argv[0], "%x:%x:%x:%x:%x:%x",
- &n5, &n4, &n3, &n2, &n1, &n0) != 6)
- return (USAGE);
+ if (!bt_aton(argv[0], &cp.bdaddr)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(argv[0])) == NULL)
+ return (USAGE);
- cp.bdaddr.b[0] = n0 & 0xff;
- cp.bdaddr.b[1] = n1 & 0xff;
- cp.bdaddr.b[2] = n2 & 0xff;
- cp.bdaddr.b[3] = n3 & 0xff;
- cp.bdaddr.b[4] = n4 & 0xff;
- cp.bdaddr.b[5] = n5 & 0xff;
+ memcpy(&cp.bdaddr, he->h_addr, sizeof(cp.bdaddr));
+ }
/* role */
if (sscanf(argv[1], "%d", &n0) != 1)
@@ -144,9 +141,7 @@ again:
return (FAILED);
}
- fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- ep->bdaddr.b[5], ep->bdaddr.b[4], ep->bdaddr.b[3],
- ep->bdaddr.b[2], ep->bdaddr.b[1], ep->bdaddr.b[0]);
+ fprintf(stdout, "BD_ADDR: %s\n", hci_bdaddr2str(&ep->bdaddr));
fprintf(stdout, "Role: %s [%#x]\n",
(ep->role == NG_HCI_ROLE_MASTER)? "Master" : "Slave",
ep->role);
diff --git a/usr.sbin/bluetooth/hccontrol/node.c b/usr.sbin/bluetooth/hccontrol/node.c
index 4771027..863d516 100644
--- a/usr.sbin/bluetooth/hccontrol/node.c
+++ b/usr.sbin/bluetooth/hccontrol/node.c
@@ -25,18 +25,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: node.c,v 1.4 2003/03/23 21:28:17 max Exp $
+ * $Id: node.c,v 1.6 2003/07/22 21:14:02 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/ioctl.h>
-#include <bitstring.h>
+#include <bluetooth.h>
#include <errno.h>
-#include <ng_hci.h>
-#include <ng_l2cap.h>
-#include <ng_btsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -142,9 +137,7 @@ hci_read_node_bd_addr(int s, int argc, char **argv)
if (ioctl(s, SIOC_HCI_RAW_NODE_GET_BDADDR, &r, sizeof(r)) < 0)
return (ERROR);
- fprintf(stdout, "BD_ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- r.bdaddr.b[5], r.bdaddr.b[4], r.bdaddr.b[3],
- r.bdaddr.b[2], r.bdaddr.b[1], r.bdaddr.b[0]);
+ fprintf(stdout, "BD_ADDR: %s\n", bt_ntoa(&r.bdaddr, NULL));
return (OK);
} /* hci_read_node_bd_addr */
@@ -243,14 +236,12 @@ hci_read_neighbor_cache(int s, int argc, char **argv)
for (n = 0; n < r.num_entries; n++) {
fprintf(stdout,
-"%02x:%02x:%02x:%02x:%02x:%02x " \
+"%-17.17s " \
"%02x %02x %02x %02x %02x %02x %02x %02x " \
"%#12x " \
"%#9x " \
"%#9x\n",
- r.entries[n].bdaddr.b[5], r.entries[n].bdaddr.b[4],
- r.entries[n].bdaddr.b[3], r.entries[n].bdaddr.b[2],
- r.entries[n].bdaddr.b[1], r.entries[n].bdaddr.b[0],
+ hci_bdaddr2str(&r.entries[n].bdaddr),
r.entries[n].features[0], r.entries[n].features[1],
r.entries[n].features[2], r.entries[n].features[3],
r.entries[n].features[4], r.entries[n].features[5],
@@ -297,7 +288,7 @@ hci_read_connection_list(int s, int argc, char **argv)
for (n = 0; n < r.num_connections; n++) {
fprintf(stdout,
-"%02x:%02x:%02x:%02x:%02x:%02x " \
+"%-17.17s " \
"%6d " \
"%4.4s " \
"%4d " \
@@ -306,12 +297,7 @@ hci_read_connection_list(int s, int argc, char **argv)
"%7d " \
"%5d " \
"%s\n",
- r.connections[n].bdaddr.b[5],
- r.connections[n].bdaddr.b[4],
- r.connections[n].bdaddr.b[3],
- r.connections[n].bdaddr.b[2],
- r.connections[n].bdaddr.b[1],
- r.connections[n].bdaddr.b[0],
+ hci_bdaddr2str(&r.connections[n].bdaddr),
r.connections[n].con_handle,
(r.connections[n].link_type == NG_HCI_LINK_ACL)?
"ACL" : "SCO",
diff --git a/usr.sbin/bluetooth/hccontrol/send_recv.c b/usr.sbin/bluetooth/hccontrol/send_recv.c
index 43a2e2a..fc9c549 100644
--- a/usr.sbin/bluetooth/hccontrol/send_recv.c
+++ b/usr.sbin/bluetooth/hccontrol/send_recv.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: send_recv.c,v 1.1 2002/11/24 20:22:38 max Exp $
+ * $Id: send_recv.c,v 1.2 2003/05/21 22:40:30 max Exp $
* $FreeBSD$
*/
@@ -35,7 +35,7 @@
#include <sys/endian.h>
#include <assert.h>
#include <errno.h>
-#include <ng_hci.h>
+#include <netgraph/bluetooth/include/ng_hci.h>
#include <string.h>
#include <unistd.h>
#include "hccontrol.h"
diff --git a/usr.sbin/bluetooth/hccontrol/status.c b/usr.sbin/bluetooth/hccontrol/status.c
index fdbf61f..86dd8c9 100644
--- a/usr.sbin/bluetooth/hccontrol/status.c
+++ b/usr.sbin/bluetooth/hccontrol/status.c
@@ -25,14 +25,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: status.c,v 1.1 2002/11/24 20:22:38 max Exp $
+ * $Id: status.c,v 1.2 2003/05/21 22:40:30 max Exp $
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/endian.h>
#include <errno.h>
-#include <ng_hci.h>
+#include <netgraph/bluetooth/include/ng_hci.h>
#include <stdio.h>
#include "hccontrol.h"
diff --git a/usr.sbin/bluetooth/hccontrol/util.c b/usr.sbin/bluetooth/hccontrol/util.c
index 7abe4d4..53b110a 100644
--- a/usr.sbin/bluetooth/hccontrol/util.c
+++ b/usr.sbin/bluetooth/hccontrol/util.c
@@ -25,11 +25,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: util.c,v 1.1 2002/11/24 20:22:38 max Exp $
+ * $Id: util.c,v 1.2 2003/05/19 17:29:29 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
+#include <bluetooth.h>
+#include <stdio.h>
#include <string.h>
#define SIZE(x) (sizeof((x))/sizeof((x)[0]))
@@ -348,3 +350,29 @@ hci_status2str(int status)
return (status >= SIZE(t)? "Unknown error" : t[status]);
} /* hci_status2str */
+char const * const
+hci_bdaddr2str(bdaddr_t const *ba)
+{
+ extern int numeric_bdaddr;
+ static char buffer[MAXHOSTNAMELEN];
+ struct hostent *he = NULL;
+
+ if (memcmp(ba, NG_HCI_BDADDR_ANY, sizeof(*ba)) == 0) {
+ buffer[0] = '*';
+ buffer[1] = 0;
+
+ return (buffer);
+ }
+
+ if (!numeric_bdaddr &&
+ (he = bt_gethostbyaddr((char *)ba, sizeof(*ba), AF_BLUETOOTH)) != NULL) {
+ strlcpy(buffer, he->h_name, sizeof(buffer));
+
+ return (buffer);
+ }
+
+ bt_ntoa(ba, buffer);
+
+ return (buffer);
+} /* hci_bdaddr2str */
+
diff --git a/usr.sbin/bluetooth/hcsecd/Makefile b/usr.sbin/bluetooth/hcsecd/Makefile
index b39ac22..d9a106f 100644
--- a/usr.sbin/bluetooth/hcsecd/Makefile
+++ b/usr.sbin/bluetooth/hcsecd/Makefile
@@ -1,12 +1,13 @@
-# $Id: Makefile,v 1.2 2003/03/15 03:07:42 max Exp $
+# $Id: Makefile,v 1.8 2003/08/14 20:06:20 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
PROG= hcsecd
-MAN8= hcsecd.8
-WARNS?= 1
-CFLAGS+= -g -I${.CURDIR} -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
+MAN= hcsecd.8 hcsecd.conf.5
SRCS= hcsecd.c lexer.l parser.y
+WARNS?= 1
+CFLAGS+= -I${.CURDIR}
+
+DPADD= ${LIBBLUETOOTH}
+LDADD= -lbluetooth
.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.8 b/usr.sbin/bluetooth/hcsecd/hcsecd.8
index 71ffcb8..1a3bb09 100644
--- a/usr.sbin/bluetooth/hcsecd/hcsecd.8
+++ b/usr.sbin/bluetooth/hcsecd/hcsecd.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: hcsecd.8,v 1.3 2003/04/27 19:45:32 max Exp $
+.\" $Id: hcsecd.8,v 1.8 2003/09/08 18:54:20 max Exp $
.\" $FreeBSD$
.\"
.Dd November 16, 2002
@@ -38,22 +38,28 @@
.Sh DESCRIPTION
The
.Nm
-daemon controls link keys and PIN code for Bluetooth devices.
+daemon controls link keys and PIN codes for Bluetooth devices.
It opens raw HCI socket and listens for the
-.Dv Link_Key_Request
-and
+.Dv Link_Key_Request ,
.Dv PIN_Code_Request
+and
+.Dv Link_Key_Notification
HCI events.
-Once appropriate HCI event has been received, the daemon will
+.Pp
+Once
+.Dv Link_Key_Request
+or
+.Dv PIN_Code_Request
+HCI event is received, the daemon will
scan configuration file for matching entry.
-The remove device BD_ADDR is used as a key.
+The remote device BD_ADDR is used as a key.
If no matching entry was found, the default entry will be used.
-If no default entry was found then it is assumed that no link key and no PIN code
-exist.
+If no default entry was found then it is assumed that no link key and no
+PIN code exists.
For any given entry, link key takes precedence over PIN code.
If link key was not specified, it means device must generate link key from
PIN code.
-If entry was found and has the link key (or PIN code) then the
+If entry was found and the link key (or PIN code) exists then the
.Dv Link_Key_Request_Reply
(or
.Dv PIN_Code_Request_Reply )
@@ -66,12 +72,28 @@ command will be sent back to the device.
.Pp
The
.Nm
-daemon currently does not handle HCI
+daemon also handles HCI
.Dv Link_Key_Notification
-event and does not cache link keys created from the PIN codes.
-It means that the link key only exists while connection is opened.
-After the connection has been terminated, the user will have to enter PIN code
-again.
+event and caches link keys created from the PIN codes in the memory.
+To preserve link keys between restarts the
+.Nm
+daemon dumps link keys for all entries in the
+.Pa /var/db/hcsecd.keys
+link keys file.
+If exists, the link keys file gets processed by
+.Nm
+daemon after it processes its main configuration file.
+The link keys file gets written every time
+.Nm
+daemon is gracefully shutdown.
+It is possible to force
+.Nm
+daemon to re-read its main configuration file and dump link keys file by sending
+.Dv HUP
+signal to the
+.Nm
+process.
+User is not expected to modify link keys file by hand.
.Pp
The command line options are as follows:
.Bl -tag -width indent
@@ -80,7 +102,7 @@ Do not detach from the controlling terminal.
.It Fl f Ar configfile
Specify name of the configuration file.
The default is
-.Pa /usr/local/etc/hcsecd.conf .
+.Pa /etc/bluetooth/hcsecd.conf .
.It Fl h
Display usage message and exit.
.El
@@ -91,15 +113,15 @@ Everything is based on remote device BD_ADDR.
Also might implement interface for external helpers to obtain link keys and
PIN codes.
.Sh FILES
-.Bl -tag -width ".Pa /usr/local/etc/hcsecd.conf" -compact
-.It Pa /usr/local/etc/hcsecd.conf
-.It Pa /var/run/hcsecd.pid
+.Bl -tag -width ".Pa /etc/bluetooth/hcsecd.conf" -compact
+.It Pa /etc/bluetooth/hcsecd.conf
+.It Pa /var/db/hcsecd.pid
+.It Pa /var/run/hcsecd.keys
.El
.Sh SEE ALSO
-.Xr netgraph 3 ,
-.Xr netgraph 4 ,
.Xr ng_btsocket 4 ,
.Xr ng_hci 4 ,
+.Xr hcsecd.conf 5 ,
.Xr hccontrol 8 ,
.Xr hcseriald 8
.Sh AUTHORS
diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.c b/usr.sbin/bluetooth/hcsecd/hcsecd.c
index 0f72eb7..ac7eacb 100644
--- a/usr.sbin/bluetooth/hcsecd/hcsecd.c
+++ b/usr.sbin/bluetooth/hcsecd/hcsecd.c
@@ -25,20 +25,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: hcsecd.c,v 1.3 2003/04/27 19:45:32 max Exp $
+ * $Id: hcsecd.c,v 1.6 2003/08/18 19:19:55 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/endian.h>
-#include <sys/socket.h>
#include <sys/queue.h>
-#include <bitstring.h>
+#include <bluetooth.h>
#include <err.h>
#include <errno.h>
-#include <ng_hci.h>
-#include <ng_l2cap.h>
-#include <ng_btsocket.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
@@ -48,10 +42,6 @@
#include <unistd.h>
#include "hcsecd.h"
-#define HCSECD_BUFFER_SIZE 512
-#define HCSECD_IDENT "hcsecd"
-#define HCSECD_PIDFILE "/var/run/" HCSECD_IDENT ".pid"
-
static int done = 0;
static int process_pin_code_request_event
@@ -62,6 +52,10 @@ static int send_pin_code_reply
(int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr, char const *pin);
static int send_link_key_reply
(int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr, u_int8_t *key);
+static int process_link_key_notification_event
+ (int sock, struct sockaddr_hci *addr, ng_hci_link_key_notification_ep *ep);
+static void sighup
+ (int s);
static void sigint
(int s);
static void usage
@@ -115,7 +109,7 @@ main(int argc, char *argv[])
err(1, "Could not sigaction(SIGINT)");
memset(&sa, 0, sizeof(sa));
- sa.sa_handler = read_config_file;
+ sa.sa_handler = sighup;
if (sigaction(SIGHUP, &sa, NULL) < 0)
err(1, "Could not sigaction(SIGHUP)");
@@ -127,6 +121,7 @@ main(int argc, char *argv[])
memset(&filter, 0, sizeof(filter));
bit_set(filter.event_mask, NG_HCI_EVENT_PIN_CODE_REQ - 1);
bit_set(filter.event_mask, NG_HCI_EVENT_LINK_KEY_REQ - 1);
+ bit_set(filter.event_mask, NG_HCI_EVENT_LINK_KEY_NOTIFICATION - 1);
if (setsockopt(sock, SOL_HCI_RAW, SO_HCI_RAW_FILTER,
(void * const) &filter, sizeof(filter)) < 0)
@@ -138,7 +133,8 @@ main(int argc, char *argv[])
openlog(HCSECD_IDENT, LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_DAEMON);
- read_config_file(0);
+ read_config_file();
+ read_keys_file();
if (detach) {
FILE *pid = NULL;
@@ -184,6 +180,11 @@ main(int argc, char *argv[])
(bdaddr_p)(event + 1));
break;
+ case NG_HCI_EVENT_LINK_KEY_NOTIFICATION:
+ process_link_key_notification_event(sock, &addr,
+ (ng_hci_link_key_notification_ep *)(event + 1));
+ break;
+
default:
syslog(LOG_ERR, "Received unexpected HCI event, " \
"event=%#x", event->event);
@@ -196,6 +197,7 @@ main(int argc, char *argv[])
syslog(LOG_ERR, "Could not remove PID file %s. %s (%d)",
HCSECD_PIDFILE, strerror(errno), errno);
+ dump_keys_file();
clean_config();
closelog();
close(sock);
@@ -211,27 +213,21 @@ process_pin_code_request_event(int sock, struct sockaddr_hci *addr,
link_key_p key = NULL;
syslog(LOG_DEBUG, "Got PIN_Code_Request event from '%s', " \
- "remote bdaddr %x:%x:%x:%x:%x:%x", addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ "remote bdaddr %s", addr->hci_node,
+ bt_ntoa(bdaddr, NULL));
if ((key = get_key(bdaddr, 0)) != NULL) {
syslog(LOG_DEBUG, "Found matching entry, " \
- "remote bdaddr %x:%x:%x:%x:%x:%x, name '%s', " \
- "PIN code %s",
- key->bdaddr.b[5], key->bdaddr.b[4],
- key->bdaddr.b[3], key->bdaddr.b[2],
- key->bdaddr.b[1], key->bdaddr.b[0],
+ "remote bdaddr %s, name '%s', PIN code %s",
+ bt_ntoa(&key->bdaddr, NULL),
(key->name != NULL)? key->name : "No name",
(key->pin != NULL)? "exists" : "doesn't exist");
return (send_pin_code_reply(sock, addr, bdaddr, key->pin));
}
- syslog(LOG_DEBUG, "Could not PIN code for remote bdaddr " \
- "%x:%x:%x:%x:%x:%x",
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ syslog(LOG_DEBUG, "Could not PIN code for remote bdaddr %s",
+ bt_ntoa(bdaddr, NULL));
return (send_pin_code_reply(sock, addr, bdaddr, NULL));
}
@@ -244,27 +240,21 @@ process_link_key_request_event(int sock, struct sockaddr_hci *addr,
link_key_p key = NULL;
syslog(LOG_DEBUG, "Got Link_Key_Request event from '%s', " \
- "remote bdaddr %x:%x:%x:%x:%x:%x", addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ "remote bdaddr %s", addr->hci_node,
+ bt_ntoa(bdaddr, NULL));
if ((key = get_key(bdaddr, 0)) != NULL) {
syslog(LOG_DEBUG, "Found matching entry, " \
- "remote bdaddr %x:%x:%x:%x:%x:%x, name '%s', " \
- "link key %s",
- key->bdaddr.b[5], key->bdaddr.b[4],
- key->bdaddr.b[3], key->bdaddr.b[2],
- key->bdaddr.b[1], key->bdaddr.b[0],
+ "remote bdaddr %s, name '%s', link key %s",
+ bt_ntoa(&key->bdaddr, NULL),
(key->name != NULL)? key->name : "No name",
(key->key != NULL)? "exists" : "doesn't exist");
return (send_link_key_reply(sock, addr, bdaddr, key->key));
}
- syslog(LOG_DEBUG, "Could not find link key for remote bdaddr " \
- "%x:%x:%x:%x:%x:%x",
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ syslog(LOG_DEBUG, "Could not find link key for remote bdaddr %s",
+ bt_ntoa(bdaddr, NULL));
return (send_link_key_reply(sock, addr, bdaddr, NULL));
}
@@ -295,10 +285,8 @@ send_pin_code_reply(int sock, struct sockaddr_hci *addr,
cp->pin_size = strlen(cp->pin);
syslog(LOG_DEBUG, "Sending PIN_Code_Reply to '%s' " \
- "for remote bdaddr %x:%x:%x:%x:%x:%x",
- addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ "for remote bdaddr %s",
+ addr->hci_node, bt_ntoa(bdaddr, NULL));
} else {
ng_hci_pin_code_neg_rep_cp *cp = NULL;
@@ -310,10 +298,8 @@ send_pin_code_reply(int sock, struct sockaddr_hci *addr,
memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr));
syslog(LOG_DEBUG, "Sending PIN_Code_Negative_Reply to '%s' " \
- "for remote bdaddr %x:%x:%x:%x:%x:%x",
- addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ "for remote bdaddr %s",
+ addr->hci_node, bt_ntoa(bdaddr, NULL));
}
again:
@@ -323,10 +309,8 @@ again:
goto again;
syslog(LOG_ERR, "Could not send PIN code reply to '%s' " \
- "for remote bdaddr %x:%x:%x:%x:%x:%x. %s (%d)",
- addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0],
+ "for remote bdaddr %s. %s (%d)",
+ addr->hci_node, bt_ntoa(bdaddr, NULL),
strerror(errno), errno);
return (-1);
}
@@ -359,10 +343,8 @@ send_link_key_reply(int sock, struct sockaddr_hci *addr,
memcpy(&cp->key, key, sizeof(cp->key));
syslog(LOG_DEBUG, "Sending Link_Key_Reply to '%s' " \
- "for remote bdaddr %x:%x:%x:%x:%x:%x",
- addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ "for remote bdaddr %s",
+ addr->hci_node, bt_ntoa(bdaddr, NULL));
} else {
ng_hci_link_key_neg_rep_cp *cp = NULL;
@@ -374,10 +356,8 @@ send_link_key_reply(int sock, struct sockaddr_hci *addr,
memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr));
syslog(LOG_DEBUG, "Sending Link_Key_Negative_Reply to '%s' " \
- "for remote bdaddr %x:%x:%x:%x:%x:%x",
- addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
+ "for remote bdaddr %s",
+ addr->hci_node, bt_ntoa(bdaddr, NULL));
}
again:
@@ -387,10 +367,8 @@ again:
goto again;
syslog(LOG_ERR, "Could not send link key reply to '%s' " \
- "for remote bdaddr %x:%x:%x:%x:%x:%x. %s (%d)",
- addr->hci_node,
- bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
- bdaddr->b[2], bdaddr->b[1], bdaddr->b[0],
+ "for remote bdaddr %s. %s (%d)",
+ addr->hci_node, bt_ntoa(bdaddr, NULL),
strerror(errno), errno);
return (-1);
}
@@ -398,7 +376,53 @@ again:
return (0);
}
-/* Signal handler */
+/* Process Link_Key_Notification event */
+static int
+process_link_key_notification_event(int sock, struct sockaddr_hci *addr,
+ ng_hci_link_key_notification_ep *ep)
+{
+ link_key_p key = NULL;
+
+ syslog(LOG_DEBUG, "Got Link_Key_Notification event from '%s', " \
+ "remote bdaddr %s", addr->hci_node,
+ bt_ntoa(&ep->bdaddr, NULL));
+
+ if ((key = get_key(&ep->bdaddr, 1)) == NULL) {
+ syslog(LOG_ERR, "Could not find entry for remote bdaddr %s",
+ bt_ntoa(&ep->bdaddr, NULL));
+ return (-1);
+ }
+
+ syslog(LOG_DEBUG, "Updating link key for the entry, " \
+ "remote bdaddr %s, name '%s', link key %s",
+ bt_ntoa(&key->bdaddr, NULL),
+ (key->name != NULL)? key->name : "No name",
+ (key->key != NULL)? "exists" : "doesn't exist");
+
+ if (key->key == NULL) {
+ key->key = (u_int8_t *) malloc(NG_HCI_KEY_SIZE);
+ if (key->key == NULL) {
+ syslog(LOG_ERR, "Could not allocate link key");
+ exit(1);
+ }
+ }
+
+ memcpy(key->key, &ep->key, NG_HCI_KEY_SIZE);
+
+ return (0);
+}
+
+/* Signal handlers */
+static void
+sighup(int s)
+{
+ syslog(LOG_DEBUG, "Got SIGHUP (%d)", s);
+
+ dump_keys_file();
+ read_config_file();
+ read_keys_file();
+}
+
static void
sigint(int s)
{
diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.conf.5 b/usr.sbin/bluetooth/hcsecd/hcsecd.conf.5
new file mode 100644
index 0000000..d27025f
--- /dev/null
+++ b/usr.sbin/bluetooth/hcsecd/hcsecd.conf.5
@@ -0,0 +1,129 @@
+.\" Copyright (c) 2001-2002 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: hcsecd.conf.5,v 1.1 2003/05/26 22:49:23 max Exp $
+.\" $FreeBSD$
+.\"
+.Dd May 26, 2003
+.Dt HCSECD.CONF 5
+.Os
+.Sh NAME
+.Nm hcsecd.conf
+.Nd
+.Xr hcsecd 8
+configuration file
+.Sh DESCRIPTION
+The
+.Nm
+file is the configuration file for the
+.Xr hcsecd 8
+Bluetooth link keys/PIN codes management daemon.
+.Pp
+The
+.Nm
+file is a free-form ASCII text file.
+It is parsed by the recursive-descent parser built into
+.Xr hcsecd 8 .
+The file may contain extra tabs and newlines for formatting purposes.
+Keywords in the file are case-sensitive.
+Comments may be placed anywhere within the file (except within quotes).
+Comments begin with the
+.Dq #
+character and end at the end of the line.
+.Sh FILE FORMAT
+The
+.Nm
+file consists of a list of
+.Cm device
+entries.
+Each
+.Cm device
+entry defines a link key or PIN code for a remote Bluetooth device.
+Each remote Bluetooth device is identified by its unique BD_ADDR.
+.Pp
+The
+.Cm device
+entry
+.Pp
+.Cm device
+{
+.Cm option Ar argument ;
+.Oo
+.Cm option Ar argument ;
+.Oc
+}
+.Pp
+The following section describes all supported options and arguments
+.Bl -tag -width indent
+.It Cm bdaddr Ar BD_ADDR
+Specify remote device BD_ADDR for the entry.
+.It Cm name Ar device_name
+Specify user friendly name for the entry.
+Name is a string in a straight double quotes.
+.It Cm key Ar link_key
+Specify link key for the entry.
+Link key is hexadecimal string upto 32 characters in length starting with
+.Dq 0x .
+.It Cm key nokey
+Specify no link key for the entry.
+.It Cm pin Ar PIN_code
+Specify PIN code for the entry.
+PIN code is a string upto 16 characters in length in a straight double quotes.
+.It Cm pin nopin
+Specify no PIN code for the entry.
+.El
+.Sh EXAMPLES
+A sample
+.Nm
+file
+.Bd -literal
+# Default entry is applied if no better match found
+# It MUST have 00:00:00:00:00:00 as bdaddr
+device {
+ bdaddr 00:00:00:00:00:00;
+ name "Default entry";
+ key nokey;
+ pin nopin;
+}
+
+# Ericsson T68 phone
+device {
+ bdaddr 00:80:37:5e:4d:d4;
+ name "Ericsson T68 phone";
+ key nokey;
+ pin "0000"; # PIN code
+}
+
+# Dummy device
+device {
+ bdaddr 00:11:22:33:44:55;
+ name "Dummy";
+ key 0x00112233445566778899aabbccddeeff; # 16 bytes key
+ pin nopin;
+}
+.Ed
+.Sh SEE ALSO
+.Xr hcsecd 8
+.Sh AUTHORS
+.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com
diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.h b/usr.sbin/bluetooth/hcsecd/hcsecd.h
index 65820ed..4f53e99 100644
--- a/usr.sbin/bluetooth/hcsecd/hcsecd.h
+++ b/usr.sbin/bluetooth/hcsecd/hcsecd.h
@@ -25,13 +25,18 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: hcsecd.h,v 1.1 2002/11/24 20:22:39 max Exp $
+ * $Id: hcsecd.h,v 1.3 2003/09/08 18:54:21 max Exp $
* $FreeBSD$
*/
#ifndef _HCSECD_H_
#define _HCSECD_H_ 1
+#define HCSECD_BUFFER_SIZE 512
+#define HCSECD_IDENT "hcsecd"
+#define HCSECD_PIDFILE "/var/run/" HCSECD_IDENT ".pid"
+#define HCSECD_KEYSFILE "/var/db/" HCSECD_IDENT ".keys"
+
struct link_key
{
bdaddr_t bdaddr; /* remote device BDADDR */
@@ -49,9 +54,12 @@ extern char *config_file;
void dump_config (void);
#endif
-void read_config_file(int s);
+void read_config_file(void);
void clean_config (void);
link_key_p get_key (bdaddr_p bdaddr, int exact_match);
+int read_keys_file (void);
+int dump_keys_file (void);
+
#endif /* ndef _HCSECD_H_ */
diff --git a/usr.sbin/bluetooth/hcsecd/parser.y b/usr.sbin/bluetooth/hcsecd/parser.y
index 750c068..d2e3696 100644
--- a/usr.sbin/bluetooth/hcsecd/parser.y
+++ b/usr.sbin/bluetooth/hcsecd/parser.y
@@ -26,14 +26,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: parser.y,v 1.1 2002/11/24 20:22:39 max Exp $
+ * $Id: parser.y,v 1.5 2003/06/07 21:22:30 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/fcntl.h>
#include <sys/queue.h>
+#include <bluetooth.h>
#include <errno.h>
-#include <ng_hci.h>
+#include <limits.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
@@ -49,7 +50,7 @@ static int hexa2int8(char *a);
extern int yylineno;
static LIST_HEAD(, link_key) link_keys;
- char *config_file = "/usr/local/etc/hcsecd.conf";
+ char *config_file = "/etc/bluetooth/hcsecd.conf";
static link_key_p key = NULL;
%}
@@ -82,13 +83,8 @@ line: T_DEVICE
{
if (get_key(&key->bdaddr, 1) != NULL) {
syslog(LOG_ERR, "Ignoring duplicated entry " \
- "for bdaddr %x:%x:%x:%x:%x:%x",
- key->bdaddr.b[5],
- key->bdaddr.b[4],
- key->bdaddr.b[3],
- key->bdaddr.b[2],
- key->bdaddr.b[1],
- key->bdaddr.b[0]);
+ "for bdaddr %s",
+ bt_ntoa(&key->bdaddr, NULL));
free_key(key);
} else
LIST_INSERT_HEAD(&link_keys, key, next);
@@ -109,21 +105,11 @@ option: bdaddr
bdaddr: T_BDADDR T_BDADDRSTRING
{
- int a0, a1, a2, a3, a4, a5;
-
- if (sscanf($2, "%x:%x:%x:%x:%x:%x",
- &a5, &a4, &a3, &a2, &a1, &a0) != 6) {
+ if (!bt_aton($2, &key->bdaddr)) {
syslog(LOG_ERR, "Cound not parse BDADDR " \
"'%s'", $2);
exit(1);
}
-
- key->bdaddr.b[0] = (a0 & 0xff);
- key->bdaddr.b[1] = (a1 & 0xff);
- key->bdaddr.b[2] = (a2 & 0xff);
- key->bdaddr.b[3] = (a3 & 0xff);
- key->bdaddr.b[4] = (a4 & 0xff);
- key->bdaddr.b[5] = (a5 & 0xff);
}
;
@@ -205,7 +191,7 @@ yyerror(char const *message)
/* Re-read config file */
void
-read_config_file(int s)
+read_config_file(void)
{
extern FILE *yyin;
@@ -286,18 +272,125 @@ dump_config(void)
syslog(LOG_DEBUG,
"device %s " \
-"bdaddr %x:%x:%x:%x:%x:%x " \
+"bdaddr %s " \
"pin %s " \
"key %s",
(key->name != NULL)? key->name : "noname",
- key->bdaddr.b[5], key->bdaddr.b[4], key->bdaddr.b[3],
- key->bdaddr.b[2], key->bdaddr.b[1], key->bdaddr.b[0],
+ bt_ntoa(&key->bdaddr, NULL),
(key->pin != NULL)? key->pin : "nopin",
(key->key != NULL)? buffer : "nokey");
}
}
#endif
+/* Read keys file */
+int
+read_keys_file(void)
+{
+ FILE *f = NULL;
+ link_key_t *key = NULL;
+ char buf[HCSECD_BUFFER_SIZE], *p = NULL, *cp = NULL;
+ bdaddr_t bdaddr;
+ int i, len;
+
+ if ((f = fopen(HCSECD_KEYSFILE, "r")) == NULL) {
+ if (errno == ENOENT)
+ return (0);
+
+ syslog(LOG_ERR, "Could not open keys file %s. %s (%d)\n",
+ HCSECD_KEYSFILE, strerror(errno), errno);
+
+ return (-1);
+ }
+
+ while ((p = fgets(buf, sizeof(buf), f)) != NULL) {
+ if (*p == '#')
+ continue;
+ if ((cp = strpbrk(p, " ")) == NULL)
+ continue;
+
+ *cp++ = '\0';
+
+ if (!bt_aton(p, &bdaddr))
+ continue;
+
+ if ((key = get_key(&bdaddr, 1)) == NULL)
+ continue;
+
+ if (key->key == NULL) {
+ key->key = (u_int8_t *) malloc(NG_HCI_KEY_SIZE);
+ if (key->key == NULL) {
+ syslog(LOG_ERR, "Could not allocate link key");
+ exit(1);
+ }
+ }
+
+ memset(key->key, 0, NG_HCI_KEY_SIZE);
+
+ len = strlen(cp) / 2;
+ if (len > NG_HCI_KEY_SIZE)
+ len = NG_HCI_KEY_SIZE;
+
+ for (i = 0; i < len; i ++)
+ key->key[i] = hexa2int8(cp + 2*i);
+
+ syslog(LOG_DEBUG, "Restored link key for the entry, " \
+ "remote bdaddr %s, name '%s'",
+ bt_ntoa(&key->bdaddr, NULL),
+ (key->name != NULL)? key->name : "No name");
+ }
+
+ fclose(f);
+
+ return (0);
+}
+
+/* Dump keys file */
+int
+dump_keys_file(void)
+{
+ link_key_p key = NULL;
+ char tmp[PATH_MAX], buf[HCSECD_BUFFER_SIZE];
+ int f;
+
+ snprintf(tmp, sizeof(tmp), "%s.tmp", HCSECD_KEYSFILE);
+ if ((f = open(tmp, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600)) < 0) {
+ syslog(LOG_ERR, "Could not create temp keys file %s. %s (%d)\n",
+ tmp, strerror(errno), errno);
+ return (-1);
+ }
+
+ LIST_FOREACH(key, &link_keys, next) {
+ if (key->key == NULL)
+ continue;
+
+ snprintf(buf, sizeof(buf),
+"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ bt_ntoa(&key->bdaddr, NULL),
+ key->key[0], key->key[1], key->key[2], key->key[3],
+ key->key[4], key->key[5], key->key[6], key->key[7],
+ key->key[8], key->key[9], key->key[10], key->key[11],
+ key->key[12], key->key[13], key->key[14], key->key[15]);
+
+ if (write(f, buf, strlen(buf)) < 0) {
+ syslog(LOG_ERR, "Could not write temp keys file. " \
+ "%s (%d)\n", strerror(errno), errno);
+ break;
+ }
+ }
+
+ close(f);
+
+ if (rename(tmp, HCSECD_KEYSFILE) < 0) {
+ syslog(LOG_ERR, "Could not rename(%s, %s). %s (%d)\n",
+ tmp, HCSECD_KEYSFILE, strerror(errno), errno);
+ unlink(tmp);
+ return (-1);
+ }
+
+ return (0);
+}
+
/* Free key entry */
static void
free_key(link_key_p key)
diff --git a/usr.sbin/bluetooth/hcseriald/Makefile b/usr.sbin/bluetooth/hcseriald/Makefile
index 4d6b629..f21331b 100644
--- a/usr.sbin/bluetooth/hcseriald/Makefile
+++ b/usr.sbin/bluetooth/hcseriald/Makefile
@@ -1,15 +1,10 @@
-# $Id: Makefile,v 1.2 2003/03/15 03:07:45 max Exp $
+# $Id: Makefile,v 1.5 2003/08/14 20:06:21 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
-
PROG= hcseriald
-MAN8= hcseriald.8
-
-WARNS?= 2
-CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
+MAN= hcseriald.8
SRCS= hcseriald.c
+WARNS?= 2
DPADD= ${LIBNETGRAPH}
LDADD= -lnetgraph
diff --git a/usr.sbin/bluetooth/hcseriald/hcseriald.8 b/usr.sbin/bluetooth/hcseriald/hcseriald.8
index 25b89b3..2bf9c54 100644
--- a/usr.sbin/bluetooth/hcseriald/hcseriald.8
+++ b/usr.sbin/bluetooth/hcseriald/hcseriald.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: hcseriald.8,v 1.2 2003/04/27 19:45:33 max Exp $
+.\" $Id: hcseriald.8,v 1.3 2003/05/21 00:47:26 max Exp $
.\" $FreeBSD$
.\"
.Dd June 14, 2002
diff --git a/usr.sbin/bluetooth/hcseriald/hcseriald.c b/usr.sbin/bluetooth/hcseriald/hcseriald.c
index a4e7f54..35429ad 100644
--- a/usr.sbin/bluetooth/hcseriald/hcseriald.c
+++ b/usr.sbin/bluetooth/hcseriald/hcseriald.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: hcseriald.c,v 1.2 2003/04/27 19:45:33 max Exp $
+ * $Id: hcseriald.c,v 1.3 2003/05/21 22:40:32 max Exp $
* $FreeBSD$
*/
@@ -34,7 +34,7 @@
#include <netgraph/ng_message.h>
#include <netgraph.h>
-#include <ng_h4.h>
+#include <netgraph/bluetooth/include/ng_h4.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/usr.sbin/bluetooth/l2control/Makefile b/usr.sbin/bluetooth/l2control/Makefile
index f6fb501..847ff4b 100644
--- a/usr.sbin/bluetooth/l2control/Makefile
+++ b/usr.sbin/bluetooth/l2control/Makefile
@@ -1,12 +1,12 @@
-# $Id: Makefile,v 1.2 2003/03/15 03:07:47 max Exp $
+# $Id: Makefile,v 1.7 2003/08/14 20:06:22 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
PROG= l2control
-MAN8= l2control.8
-WARNS?= 2
-CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
+MAN= l2control.8
SRCS= l2cap.c l2control.c
+WARNS?= 2
+
+DPADD= ${LIBBLUETOOTH}
+LDADD= -lbluetooth
.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/l2control/l2cap.c b/usr.sbin/bluetooth/l2control/l2cap.c
index ca4111d..c23106c 100644
--- a/usr.sbin/bluetooth/l2control/l2cap.c
+++ b/usr.sbin/bluetooth/l2control/l2cap.c
@@ -25,17 +25,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: l2cap.c,v 1.4 2003/04/26 23:11:25 max Exp $
+ * $Id: l2cap.c,v 1.5 2003/05/16 19:52:37 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
#include <sys/ioctl.h>
-#include <bitstring.h>
+#include <bluetooth.h>
#include <errno.h>
-#include <ng_hci.h>
-#include <ng_l2cap.h>
-#include <ng_btsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -43,6 +39,33 @@
#define SIZE(x) (sizeof((x))/sizeof((x)[0]))
+/* Print BDADDR */
+static char *
+bdaddrpr(bdaddr_t const *ba)
+{
+ extern int numeric_bdaddr;
+ static char str[24];
+ struct hostent *he = NULL;
+
+ 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, sizeof(str));
+
+ return (str);
+ }
+
+ bt_ntoa(ba, str);
+
+ return (str);
+} /* bdaddrpr */
+
/* Send read_node_flags command to the node */
static int
l2cap_read_node_flags(int s, int argc, char **argv)
@@ -134,17 +157,12 @@ l2cap_read_connection_list(int s, int argc, char **argv)
"Remote BD_ADDR Handle Flags Pending State\n");
for (n = 0; n < r.num_connections; n++) {
fprintf(stdout,
- "%02x:%02x:%02x:%02x:%02x:%02x " \
+ "%-17.17s " \
"%6d " \
"%c%c%c%c%c " \
"%7d " \
"%s\n",
- r.connections[n].remote.b[5],
- r.connections[n].remote.b[4],
- r.connections[n].remote.b[3],
- r.connections[n].remote.b[2],
- r.connections[n].remote.b[1],
- r.connections[n].remote.b[0],
+ bdaddrpr(&r.connections[n].remote),
r.connections[n].con_handle,
((r.connections[n].flags & NG_L2CAP_CON_OUTGOING)? 'O' : 'I'),
((r.connections[n].flags & NG_L2CAP_CON_LP_TIMO)? 'L' : ' '),
@@ -197,13 +215,11 @@ l2cap_read_channel_list(int s, int argc, char **argv)
"Remote BD_ADDR SCID/ DCID PSM IMTU/ OMTU State\n");
for (n = 0; n < r.num_channels; n++) {
fprintf(stdout,
- "%02x:%02x:%02x:%02x:%02x:%02x " \
+ "%-17.17s " \
"%5d/%5d %5d " \
"%5d/%5d " \
"%s\n",
- r.channels[n].remote.b[5], r.channels[n].remote.b[4],
- r.channels[n].remote.b[3], r.channels[n].remote.b[2],
- r.channels[n].remote.b[1], r.channels[n].remote.b[0],
+ bdaddrpr(&r.channels[n].remote),
r.channels[n].scid, r.channels[n].dcid,
r.channels[n].psm, r.channels[n].imtu,
r.channels[n].omtu,
diff --git a/usr.sbin/bluetooth/l2control/l2control.8 b/usr.sbin/bluetooth/l2control/l2control.8
index dcd05fe..e98f301 100644
--- a/usr.sbin/bluetooth/l2control/l2control.8
+++ b/usr.sbin/bluetooth/l2control/l2control.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: l2control.8,v 1.3 2003/04/27 19:45:34 max Exp $
+.\" $Id: l2control.8,v 1.5 2003/05/21 00:53:00 max Exp $
.\" $FreeBSD$
.\"
.Dd June 14, 2002
@@ -33,7 +33,7 @@
.Nd L2CAP configuration utility
.Sh SYNOPSIS
.Nm
-.Op Fl h
+.Op Fl hn
.Fl a Ar BD_ADDR
.Ar command
.Op Ar parameters ...
@@ -55,6 +55,11 @@ Example:
.Fl a Li 00:01:02:03:04:05 .
.It Fl h
Display usage message and exit.
+.It Fl n
+Show Bluetooth addresses as numbers.
+Normally
+.Nm
+attempts to resolve Bluetooth addresses, and display them symbolically.
.It Ar command
One of the supported commands (see below).
Special command
diff --git a/usr.sbin/bluetooth/l2control/l2control.c b/usr.sbin/bluetooth/l2control/l2control.c
index a259657..585021c 100644
--- a/usr.sbin/bluetooth/l2control/l2control.c
+++ b/usr.sbin/bluetooth/l2control/l2control.c
@@ -25,19 +25,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: l2control.c,v 1.3 2003/04/27 19:45:34 max Exp $
+ * $Id: l2control.c,v 1.6 2003/09/05 00:38:25 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <bitstring.h>
#include <assert.h>
+#include <bluetooth.h>
#include <err.h>
#include <errno.h>
-#include <ng_hci.h>
-#include <ng_l2cap.h>
-#include <ng_btsocket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -52,6 +47,9 @@ static void print_l2cap_command (struct l2cap_command *);
static void usage (void);
/* Main */
+
+int numeric_bdaddr = 0;
+
int
main(int argc, char *argv[])
{
@@ -61,24 +59,22 @@ main(int argc, char *argv[])
memset(&bdaddr, 0, sizeof(bdaddr));
/* Process command line arguments */
- while ((n = getopt(argc, argv, "a:h")) != -1) {
+ while ((n = getopt(argc, argv, "a:nh")) != -1) {
switch (n) {
- case 'a': {
- int a0, a1, a2, a3, a4, a5;
+ case 'a':
+ if (!bt_aton(optarg, &bdaddr)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(optarg)) == NULL)
+ errx(1, "%s: %s", optarg, hstrerror(h_errno));
- if (sscanf(optarg, "%x:%x:%x:%x:%x:%x",
- &a5, &a4, &a3, &a2, &a1, &a0) != 6) {
- usage();
- break;
+ memcpy(&bdaddr, he->h_addr, sizeof(bdaddr));
}
+ break;
- bdaddr.b[0] = (a0 & 0xff);
- bdaddr.b[1] = (a1 & 0xff);
- bdaddr.b[2] = (a2 & 0xff);
- bdaddr.b[3] = (a3 & 0xff);
- bdaddr.b[4] = (a4 & 0xff);
- bdaddr.b[5] = (a5 & 0xff);
- } break;
+ case 'n':
+ numeric_bdaddr = 1;
+ break;
case 'h':
default:
@@ -144,10 +140,7 @@ do_l2cap_command(bdaddr_p bdaddr, int argc, char **argv)
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
err(2,
-"Could not bind socket, bdaddr=%x:%x:%x:%x:%x:%x",
- sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4],
- sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2],
- sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]);
+"Could not bind socket, bdaddr=%s", bt_ntoa(&sa.l2cap_bdaddr, NULL));
e = 0x0ffff;
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &e, sizeof(e)) < 0)
@@ -200,7 +193,7 @@ find_l2cap_command(char const *command, struct l2cap_command *category)
return (NULL);
} /* find_l2cap_command */
-/* Try to find command in specified category */
+/* Print commands in specified category */
static void
print_l2cap_command(struct l2cap_command *category)
{
@@ -214,7 +207,7 @@ print_l2cap_command(struct l2cap_command *category)
static void
usage(void)
{
- fprintf(stdout, "Usage: l2control -a BD_ADDR [-h] cmd [p1] [..]]\n");
+ fprintf(stdout, "Usage: l2control -a BD_ADDR [-n] [-h] cmd [p1] [..]]\n");
exit(255);
} /* usage */
diff --git a/usr.sbin/bluetooth/l2ping/Makefile b/usr.sbin/bluetooth/l2ping/Makefile
index d99143b..e62d2af 100644
--- a/usr.sbin/bluetooth/l2ping/Makefile
+++ b/usr.sbin/bluetooth/l2ping/Makefile
@@ -1,12 +1,12 @@
-# $Id: Makefile,v 1.2 2003/03/15 03:07:49 max Exp $
+# $Id: Makefile,v 1.6 2003/08/14 20:06:24 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
PROG= l2ping
-MAN8= l2ping.8
+MAN= l2ping.8
SRCS= l2ping.c
WARNS?= 2
-CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
+
+DPADD= ${LIBBLUETOOTH}
+LDADD= -lbluetooth
.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/l2ping/l2ping.8 b/usr.sbin/bluetooth/l2ping/l2ping.8
index 8ecd11e..13e2dfc 100644
--- a/usr.sbin/bluetooth/l2ping/l2ping.8
+++ b/usr.sbin/bluetooth/l2ping/l2ping.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: l2ping.8,v 1.2 2003/04/27 19:45:35 max Exp $
+.\" $Id: l2ping.8,v 1.3 2003/05/21 01:00:19 max Exp $
.\" $FreeBSD$
.\"
.Dd June 14, 2002
diff --git a/usr.sbin/bluetooth/l2ping/l2ping.c b/usr.sbin/bluetooth/l2ping/l2ping.c
index 5f3bc28..b7ef2a5 100644
--- a/usr.sbin/bluetooth/l2ping/l2ping.c
+++ b/usr.sbin/bluetooth/l2ping/l2ping.c
@@ -25,27 +25,22 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: l2ping.c,v 1.3 2003/04/27 19:45:36 max Exp $
+ * $Id: l2ping.c,v 1.5 2003/05/16 19:54:40 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
#include <sys/ioctl.h>
-#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <assert.h>
-#include <bitstring.h>
+#include <bluetooth.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <ng_hci.h>
-#include <ng_l2cap.h>
-#include <ng_btsocket.h>
static void usage (void);
static void tv_sub (struct timeval *, struct timeval const *);
@@ -64,11 +59,12 @@ static char const pattern[] = "1234567890-";
int
main(int argc, char *argv[])
{
- bdaddr_t src, dst;
- struct sockaddr_l2cap sa;
- struct ng_btsocket_l2cap_raw_ping r;
- int n, s, count, wait, flood, fail;
- struct timeval a, b;
+ bdaddr_t src, dst;
+ struct hostent *he = NULL;
+ struct sockaddr_l2cap sa;
+ struct ng_btsocket_l2cap_raw_ping r;
+ int n, s, count, wait, flood, fail;
+ struct timeval a, b;
/* Set defaults */
memcpy(&src, NG_HCI_BDADDR_ANY, sizeof(src));
@@ -90,31 +86,22 @@ main(int argc, char *argv[])
while ((n = getopt(argc, argv, "a:c:fi:n:s:S:h")) != -1) {
switch (n) {
case 'a':
- case 'S': {
- int a0, a1, a2, a3, a4, a5;
+ if (!bt_aton(optarg, &dst)) {
+ if ((he = bt_gethostbyname(optarg)) == NULL)
+ errx(1, "%s: %s", optarg, hstrerror(h_errno));
- if (sscanf(optarg, "%x:%x:%x:%x:%x:%x",
- &a5, &a4, &a3, &a2, &a1, &a0) != 6)
- usage();
+ memcpy(&dst, he->h_addr, sizeof(dst));
+ }
+ break;
- if (n == 'a') {
- /* destination bdaddr */
- dst.b[0] = (a0 & 0xff);
- dst.b[1] = (a1 & 0xff);
- dst.b[2] = (a2 & 0xff);
- dst.b[3] = (a3 & 0xff);
- dst.b[4] = (a4 & 0xff);
- dst.b[5] = (a5 & 0xff);
- } else {
- /* source bdaddr */
- src.b[0] = (a0 & 0xff);
- src.b[1] = (a1 & 0xff);
- src.b[2] = (a2 & 0xff);
- src.b[3] = (a3 & 0xff);
- src.b[4] = (a4 & 0xff);
- src.b[5] = (a5 & 0xff);
+ case 'S':
+ if (!bt_aton(optarg, &src)) {
+ if ((he = bt_gethostbyname(optarg)) == NULL)
+ errx(1, "%s: %s", optarg, hstrerror(h_errno));
+
+ memcpy(&src, he->h_addr, sizeof(src));
}
- } break;
+ break;
case 'c':
count = atoi(optarg);
@@ -162,10 +149,7 @@ main(int argc, char *argv[])
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
err(3,
-"Could not bind socket, src bdaddr=%x:%x:%x:%x:%x:%x",
- sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4],
- sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2],
- sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]);
+"Could not bind socket, src bdaddr=%s", bt_ntoa(&sa.l2cap_bdaddr, NULL));
memset(&sa, 0, sizeof(sa));
sa.l2cap_len = sizeof(sa);
@@ -174,10 +158,7 @@ main(int argc, char *argv[])
if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
err(4,
-"Could not connect socket, dst bdaddr=%x:%x:%x:%x:%x:%x",
- sa.l2cap_bdaddr.b[5], sa.l2cap_bdaddr.b[4],
- sa.l2cap_bdaddr.b[3], sa.l2cap_bdaddr.b[2],
- sa.l2cap_bdaddr.b[1], sa.l2cap_bdaddr.b[0]);
+"Could not connect socket, dst bdaddr=%s", bt_ntoa(&sa.l2cap_bdaddr, NULL));
/* Fill pattern */
for (n = 0; n < r.echo_size; ) {
@@ -198,10 +179,8 @@ main(int argc, char *argv[])
r.result = errno;
fail = 1;
/*
- warn("Could not ping, dst bdaddr=%x:%x:%x:%x:%x:%x",
- r.echo_dst.b[5], r.echo_dst.b[4],
- r.echo_dst.b[3], r.echo_dst.b[2],
- r.echo_dst.b[1], r.echo_dst.b[0]);
+ warn("Could not ping, dst bdaddr=%s",
+ bt_ntoa(&r.echo_dst, NULL));
*/
}
@@ -211,10 +190,9 @@ main(int argc, char *argv[])
tv_sub(&b, &a);
fprintf(stdout,
-"%d bytes from %x:%x:%x:%x:%x:%x seq_no=%d time=%.3f ms result=%#x %s\n",
- r.echo_size,
- dst.b[5], dst.b[4], dst.b[3],
- dst.b[2], dst.b[1], dst.b[0],
+"%d bytes from %s seq_no=%d time=%.3f ms result=%#x %s\n",
+ r.echo_size,
+ bt_ntoa(&dst, NULL),
ntohl(*((int *)(r.echo_data))),
tv2msec(&b), r.result,
((fail == 0)? "" : strerror(errno)));
diff --git a/usr.sbin/bluetooth/rfcomm_pppd/Makefile b/usr.sbin/bluetooth/rfcomm_pppd/Makefile
index 0269123..adac64e 100644
--- a/usr.sbin/bluetooth/rfcomm_pppd/Makefile
+++ b/usr.sbin/bluetooth/rfcomm_pppd/Makefile
@@ -1,13 +1,14 @@
-# $Id: Makefile,v 1.2 2003/03/15 03:07:50 max Exp $
+# $Id: Makefile,v 1.7 2003/09/07 18:32:11 max Exp $
# $FreeBSD$
-DESTDIR= /usr/sbin/
-MANDIR= ../share/man/man
+.PATH: ${.CURDIR}/../../../usr.bin/bluetooth/rfcomm_sppd
+
PROG= rfcomm_pppd
-MAN8= rfcomm_pppd.8
+MAN= rfcomm_pppd.8
+SRCS= rfcomm_pppd.c rfcomm_sdp.c
WARNS?= 2
-CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include
-SRCS= rfcomm_pppd.c
-.include <bsd.prog.mk>
+DPADD= ${LIBBLUETOOTH} ${LIBSDP}
+LDADD= -lbluetooth -lsdp
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.8 b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.8
index d6af46d..591a5ce 100644
--- a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.8
+++ b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: rfcomm_pppd.8,v 1.5 2003/04/27 19:45:37 max Exp $
+.\" $Id: rfcomm_pppd.8,v 1.7 2003/09/07 18:32:11 max Exp $
.\" $FreeBSD$
.\"
.Dd February 4, 2003
@@ -54,7 +54,7 @@ It can operate in two modes: client and server.
.Pp
In the client mode,
.Nm
-opens an RFCOMM connection to the specified server's
+opens a RFCOMM connection to the specified server's
.Ar BD_ADRR
and
.Ar channel .
@@ -75,7 +75,7 @@ and connect to the Internet.
.Pp
In the server mode,
.Nm
-opens an RFCOMM socket and listens for incomming connections from remote clients.
+opens a RFCOMM socket and listens for incomming connections from remote clients.
Once the new incomming connection is accepted,
.Nm
forks and executes
@@ -92,7 +92,7 @@ the standard serial port thus providing network connectivity to remote clients.
The options are as follows:
.Bl -tag -width indent
.It Fl a Ar BD_ADDR
-In the client mode, this required option specifies the remote BD_ADDR of the
+In the client mode this required option specifies the remote BD_ADDR of the
RFCOMM server.
In the server mode, this option can be used to specify the local
BD_ADDR to listen on.
@@ -100,21 +100,32 @@ By default, server will listen on
.Dv ANY
address.
.It Fl C Ar channel
-In both client and server modes, this required option specifies RFCOMM channel
+In both client and server modes this required option specifies RFCOMM channel
to connect to or listen on.
+In the server mode RFCOMM channel should be number between 1 and 30.
+In the client mode RFCOMM channel could be either number between 1 and 30 or
+service name. Supported service names are:
+.Cm DUN
+for DialUp Networking service and
+.Cm LAN
+for LAN Access Using PPP service.
+If service name was specified instead of numeric RFCOMM channel then
+.Nm
+utility will try to obtain RFCOMM channel for the service via Service
+Discovery Protocol.
.It Fl c
-Act as an RFCOMM client.
+Act as a RFCOMM client.
This is the default mode.
.It Fl d
Do not detach from the controlling terminal, i.e., run in foreground.
.It Fl h
Display usage message and exit.
.It Fl l Ar label
-In both client and server modes, this required option specifies which
+In both client and server modes this required option specifies which
.Xr ppp 8
label will be used.
.It Fl s
-Act as an RFCOMM server.
+Act as a RFCOMM server.
.El
.Sh PPP CONFIGURATION
.Ss Important Notes on PPP Configuration
@@ -265,7 +276,7 @@ label.
The
.Nm
utility
-is not currently integrated with the SDP (Service Discovery Protocol).
+does not register services with local SDP (Service Discovery Protocol) daemon.
.Sh SEE ALSO
.Xr rfcomm_sppd 1 ,
.Xr ng_btsocket 4 ,
diff --git a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c
index 160988e..ec9f4ca4 100644
--- a/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c
+++ b/usr.sbin/bluetooth/rfcomm_pppd/rfcomm_pppd.c
@@ -25,18 +25,16 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: rfcomm_pppd.c,v 1.3 2003/04/26 23:59:49 max Exp $
+ * $Id: rfcomm_pppd.c,v 1.5 2003/09/07 18:32:11 max Exp $
* $FreeBSD$
*/
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <bitstring.h>
+#include <bluetooth.h>
+#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.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>
@@ -47,6 +45,10 @@
#define RFCOMM_PPPD "rfcomm_pppd"
+int rfcomm_channel_lookup (bdaddr_t const *local,
+ bdaddr_t const *remote,
+ int service, int *channel, int *error);
+
static void exec_ppp (int s, char *label);
static void sighandler (int s);
static void usage (void);
@@ -58,41 +60,49 @@ int
main(int argc, char *argv[])
{
struct sockaddr_rfcomm sock_addr;
- char *label = NULL;
+ char *label = NULL, *ep = NULL;
bdaddr_t addr;
- int s, channel, detach, server;
+ int s, channel, detach, server, service;
pid_t pid;
memcpy(&addr, NG_HCI_BDADDR_ANY, sizeof(addr));
channel = 0;
detach = 1;
server = 0;
+ service = 0;
/* Parse command line arguments */
while ((s = getopt(argc, argv, "a:cC:dhl:s")) != -1) {
switch (s) {
- 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': /* client */
server = 0;
break;
case 'C': /* RFCOMM channel */
- channel = atoi(optarg);
+ channel = strtoul(optarg, &ep, 10);
+ if (*ep != 0) {
+ channel = 0;
+ switch (tolower(optarg[0])) {
+ case 'd': /* DialUp Networking */
+ service = SDP_SERVICE_CLASS_DIALUP_NETWORKING;
+ break;
+
+ case 'l': /* LAN Access Using PPP */
+ service = SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP;
+ break;
+ }
+ }
break;
case 'd': /* do not detach */
@@ -115,10 +125,22 @@ main(int argc, char *argv[])
}
/* Check if we got everything we wanted */
- if ((channel <= 0 || channel > 30) || label == NULL ||
- (!server && memcmp(&addr, NG_HCI_BDADDR_ANY, sizeof(addr)) == 0))
- usage();
- /* NOT REACHED */
+ if (label == NULL)
+ errx(1, "Must specify PPP label");
+
+ if (!server) {
+ if (memcmp(&addr, NG_HCI_BDADDR_ANY, sizeof(addr)) == 0)
+ errx(1, "Must specify server BD_ADDR");
+
+ /* Check channel, if was not set then obtain it via SDP */
+ if (channel == 0 && service != 0)
+ if (rfcomm_channel_lookup(NULL, &addr, service,
+ &channel, &s) != 0)
+ errc(1, s, "Could not obtain RFCOMM channel");
+ }
+
+ if (channel <= 0 || channel > 30)
+ errx(1, "Invalid RFCOMM channel number %d", channel);
openlog(RFCOMM_PPPD, LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_USER);
diff --git a/usr.sbin/bluetooth/sdpcontrol/Makefile b/usr.sbin/bluetooth/sdpcontrol/Makefile
new file mode 100644
index 0000000..c0ec8d4
--- /dev/null
+++ b/usr.sbin/bluetooth/sdpcontrol/Makefile
@@ -0,0 +1,12 @@
+# $Id: Makefile,v 1.1 2003/09/08 02:27:27 max Exp $
+# $FreeBSD$
+
+PROG= sdpcontrol
+MAN= sdpcontrol.8
+SRCS= sdpcontrol.c search.c
+WARNS?= 2
+
+DPADD= ${LIBBLUETOOTH} ${LIBSDP}
+LDADD= -lbluetooth -lsdp
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8 b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8
new file mode 100644
index 0000000..a7f1f6b
--- /dev/null
+++ b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.8
@@ -0,0 +1,100 @@
+.\" 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: sdpcontrol.8,v 1.1 2003/09/08 02:27:27 max Exp $
+.\" $FreeBSD$
+.\"
+.Dd September 7, 2003
+.Dt SDPCONTROL 8
+.Os
+.Sh NAME
+.Nm spdcontrol
+.Nd SDP configuration utility
+.Sh SYNOPSIS
+.Nm
+.Op Fl h
+.Fl a Ar BD_ADDR
+.Ar command
+.Op Ar parameters ...
+.Sh DESCRIPTION
+The
+.Nm
+utility connects to the remote device with the specified BD_ADDR and attempts
+to send query via Service Discovery Protocol (SDP).
+The
+.Nm
+utility will use Service Search Attribute Request and will print results to
+the standard output and error messages to the standard error.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl a Ar BD_ADDR
+Connect to the remote device with the specified BD_ADDR.
+Example:
+.Fl a Li 00:01:02:03:04:05 .
+.It Fl h
+Display usage message and exit.
+.It Ar command
+One of the supported commands (see below).
+Special command
+.Cm help
+can be used to obtain the list of all supported commands.
+To get more information about specific command use
+.Cm help Ar command .
+.It Ar parameters
+One or more optional space separated command parameters.
+.El
+.Sh COMMANDS
+The currently supported node commands in
+.Nm
+are:
+.Pp
+.Bl -tag -offset indent -compact
+.It Cm Browse
+.It Cm Search
+.El
+.Sh CAVEAT
+Currently, the
+.Nm
+utility only implements client side functionality.
+.Pp
+The
+.Nm
+utility only request the following attributes from the remote SDP server:
+.Bl -enum -offset indent -compact
+.It
+Service Record Handle
+.It
+Service Class ID List
+.It
+Protocol Descriptor List
+.It
+Bluetooth Profile Descriptor List
+.El
+.Sh DIAGNOSTICS
+.Ex -std
+.Sh SEE ALSO
+.Xr sdp 3
+.Sh AUTHORS
+.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com
diff --git a/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c
new file mode 100644
index 0000000..b5a1a4d
--- /dev/null
+++ b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c
@@ -0,0 +1,197 @@
+/*
+ * sdpcontrol.c
+ *
+ * Copyright (c) 2001-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: sdpcontrol.c,v 1.1 2003/09/08 02:27:27 max Exp $
+ * $FreeBSD$
+ */
+
+#include <assert.h>
+#include <bluetooth.h>
+#include <err.h>
+#include <errno.h>
+#include <sdp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "sdpcontrol.h"
+
+/* Prototypes */
+static int do_sdp_command (bdaddr_p, int, char **);
+static struct sdp_command * find_sdp_command (char const *,
+ struct sdp_command *);
+static void print_sdp_command (struct sdp_command *);
+static void usage (void);
+
+/* Main */
+int
+main(int argc, char *argv[])
+{
+ int n;
+ bdaddr_t bdaddr;
+
+ memset(&bdaddr, 0, sizeof(bdaddr));
+
+ /* Process command line arguments */
+ while ((n = getopt(argc, argv, "a:h")) != -1) {
+ switch (n) {
+ case 'a':
+ if (!bt_aton(optarg, &bdaddr)) {
+ struct hostent *he = NULL;
+
+ if ((he = bt_gethostbyname(optarg)) == NULL)
+ errx(1, "%s: %s", optarg, hstrerror(h_errno));
+
+ memcpy(&bdaddr, he->h_addr, sizeof(bdaddr));
+ }
+ break;
+
+ case 'h':
+ default:
+ usage();
+ /* NOT REACHED */
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (*argv == NULL)
+ usage();
+
+ return (do_sdp_command(&bdaddr, argc, argv));
+}
+
+/* Execute commands */
+static int
+do_sdp_command(bdaddr_p bdaddr, int argc, char **argv)
+{
+ char *cmd = argv[0];
+ struct sdp_command *c = NULL;
+ void *xs = NULL;
+ int e, help;
+
+ help = 0;
+ if (strcasecmp(cmd, "help") == 0) {
+ argc --;
+ argv ++;
+
+ if (argc <= 0) {
+ fprintf(stdout, "Supported commands:\n");
+ print_sdp_command(sdp_commands);
+ fprintf(stdout, "\nFor more information use " \
+ "'help command'\n");
+
+ return (OK);
+ }
+
+ help = 1;
+ cmd = argv[0];
+ }
+
+ c = find_sdp_command(cmd, sdp_commands);
+ if (c == NULL) {
+ fprintf(stdout, "Unknown command: \"%s\"\n", cmd);
+ return (ERROR);
+ }
+
+ if (!help) {
+ if (memcmp(bdaddr, NG_HCI_BDADDR_ANY, sizeof(*bdaddr)) == 0)
+ usage();
+
+ if ((xs = sdp_open(NG_HCI_BDADDR_ANY, bdaddr)) == NULL)
+ errx(1, "Could not create SDP session object");
+
+ if (sdp_error(xs) == 0)
+ e = (c->handler)(xs, -- argc, ++ argv);
+ else
+ e = ERROR;
+ } else
+ e = USAGE;
+
+ switch (e) {
+ case OK:
+ case FAILED:
+ break;
+
+ case ERROR:
+ fprintf(stdout, "Could not execute command \"%s\". %s\n",
+ cmd, strerror(sdp_error(xs)));
+ break;
+
+ case USAGE:
+ fprintf(stdout, "Usage: %s\n%s\n", c->command, c->description);
+ break;
+
+ default: assert(0); break;
+ }
+
+ sdp_close(xs);
+
+ return (e);
+} /* do_sdp_command */
+
+/* Try to find command in specified category */
+static struct sdp_command *
+find_sdp_command(char const *command, struct sdp_command *category)
+{
+ struct sdp_command *c = NULL;
+
+ for (c = category; c->command != NULL; c++) {
+ char *c_end = strchr(c->command, ' ');
+
+ if (c_end != NULL) {
+ int len = c_end - c->command;
+
+ if (strncasecmp(command, c->command, len) == 0)
+ return (c);
+ } else if (strcasecmp(command, c->command) == 0)
+ return (c);
+ }
+
+ return (NULL);
+} /* find_sdp_command */
+
+/* Print commands in specified category */
+static void
+print_sdp_command(struct sdp_command *category)
+{
+ struct sdp_command *c = NULL;
+
+ for (c = category; c->command != NULL; c++)
+ fprintf(stdout, "\t%s\n", c->command);
+} /* print_sdp_command */
+
+/* Usage */
+static void
+usage(void)
+{
+ fprintf(stdout, "Usage: sdpcontrol -a BD_ADDR [-h] " \
+ "cmd [p1] [..]]\n");
+ exit(255);
+} /* usage */
+
diff --git a/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.h b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.h
new file mode 100644
index 0000000..4a1ee76f
--- /dev/null
+++ b/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.h
@@ -0,0 +1,49 @@
+/*
+ * sdpcontrol.h
+ *
+ * Copyright (c) 2001-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: sdpcontrol.h,v 1.1 2003/09/08 02:27:27 max Exp $
+ * $FreeBSD$
+ */
+
+#ifndef __SDPCONTROL_H__
+#define __SDPCONTROL_H__
+
+#define OK 0 /* everything was OK */
+#define ERROR 1 /* could not execute command */
+#define FAILED 2 /* error was reported */
+#define USAGE 3 /* invalid parameters */
+
+struct sdp_command {
+ char const *command;
+ char const *description;
+ int (*handler)(void *, int, char **);
+};
+
+extern struct sdp_command sdp_commands[];
+
+#endif /* __SDPCONTROL_H__ */
+
diff --git a/usr.sbin/bluetooth/sdpcontrol/search.c b/usr.sbin/bluetooth/sdpcontrol/search.c
new file mode 100644
index 0000000..7180952
--- /dev/null
+++ b/usr.sbin/bluetooth/sdpcontrol/search.c
@@ -0,0 +1,707 @@
+/*
+ * search.c
+ *
+ * Copyright (c) 2001-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: search.c,v 1.2 2003/09/08 17:35:15 max Exp $
+ * $FreeBSD$
+ */
+
+#include <bluetooth.h>
+#include <ctype.h>
+#include <sdp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "sdpcontrol.h"
+
+/* List of the attributes we are looking for */
+static u_int32_t attrs[] =
+{
+ SDP_ATTR_RANGE( SDP_ATTR_SERVICE_RECORD_HANDLE,
+ SDP_ATTR_SERVICE_RECORD_HANDLE),
+ SDP_ATTR_RANGE( SDP_ATTR_SERVICE_CLASS_ID_LIST,
+ SDP_ATTR_SERVICE_CLASS_ID_LIST),
+ SDP_ATTR_RANGE( SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
+ SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST),
+ SDP_ATTR_RANGE( SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST,
+ SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST)
+};
+#define attrs_len (sizeof(attrs)/sizeof(attrs[0]))
+
+/* Buffer for the attributes */
+#define NRECS 25 /* request this much records from the SDP server */
+#define BSIZE 256 /* one attribute buffer size */
+static u_int8_t buffer[NRECS * attrs_len][BSIZE];
+
+/* SDP attributes */
+static sdp_attr_t values[NRECS * attrs_len];
+#define values_len (sizeof(values)/sizeof(values[0]))
+
+/*
+ * Print Service Class ID List
+ *
+ * The ServiceClassIDList attribute consists of a data element sequence in
+ * which each data element is a UUID representing the service classes that
+ * a given service record conforms to. The UUIDs are listed in order from
+ * the most specific class to the most general class. The ServiceClassIDList
+ * must contain at least one service class UUID.
+ */
+
+static void
+print_service_class_id_list(u_int8_t const *start, u_int8_t const *end)
+{
+ u_int32_t type, len, value;
+
+ if (end - start < 2) {
+ fprintf(stderr, "Invalid Service Class ID List. " \
+ "Too short, len=%d\n", end - start);
+ return;
+ }
+
+ 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:
+ fprintf(stderr, "Invalid Service Class ID List. " \
+ "Not a sequence, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+
+ while (start < end) {
+ SDP_GET8(type, start);
+ switch (type) {
+ case SDP_DATA_UUID16:
+ SDP_GET16(value, start);
+ fprintf(stdout, "\t%s (%#4.4x)\n",
+ sdp_uuid2desc(value), value);
+ break;
+
+ case SDP_DATA_UUID32:
+ SDP_GET32(value, start);
+ fprintf(stdout, "\t%#8.8x\n", value);
+ break;
+
+ case SDP_DATA_UUID128: {
+ int128_t uuid;
+
+ SDP_GET128(&uuid, start);
+ fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n",
+ *(u_int32_t *)&uuid.b[0],
+ *(u_int16_t *)&uuid.b[4],
+ *(u_int16_t *)&uuid.b[6],
+ *(u_int16_t *)&uuid.b[8],
+ *(u_int16_t *)&uuid.b[10],
+ *(u_int32_t *)&uuid.b[12]);
+ } break;
+
+ default:
+ fprintf(stderr, "Invalid Service Class ID List. " \
+ "Not a UUID, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+ }
+} /* print_service_class_id_list */
+
+/*
+ * Print Protocol Descriptor List
+ *
+ * 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. Each protocol descriptor is, in turn, a data element
+ * sequence whose first element is a UUID identifying the protocol and whose
+ * successive elements are protocol-specific parameters. The protocol
+ * descriptors are listed in order from the lowest layer protocol to the
+ * highest layer protocol used to gain access to the service. 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 where each member is a data element sequence as described above.
+ */
+
+static void
+print_protocol_descriptor(u_int8_t const *start, u_int8_t const *end)
+{
+ union {
+ uint8_t uint8;
+ uint16_t uint16;
+ uint32_t uint32;
+ uint64_t uint64;
+ int128_t int128;
+ } value;
+ u_int32_t type, len, param;
+
+ /* Get Protocol UUID */
+ SDP_GET8(type, start);
+ switch (type) {
+ case SDP_DATA_UUID16:
+ SDP_GET16(value.uint16, start);
+ fprintf(stdout, "\t%s (%#4.4x)\n", sdp_uuid2desc(value.uint16),
+ value.uint16);
+ break;
+
+ case SDP_DATA_UUID32:
+ SDP_GET32(value.uint32, start);
+ fprintf(stdout, "\t%#8.8x\n", value.uint32);
+ break;
+
+ case SDP_DATA_UUID128:
+ SDP_GET128(&value.int128, start);
+ fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n",
+ *(u_int32_t *)&value.int128.b[0],
+ *(u_int16_t *)&value.int128.b[4],
+ *(u_int16_t *)&value.int128.b[6],
+ *(u_int16_t *)&value.int128.b[8],
+ *(u_int16_t *)&value.int128.b[10],
+ *(u_int32_t *)&value.int128.b[12]);
+ break;
+
+ default:
+ fprintf(stderr, "Invalid Protocol Descriptor. " \
+ "Not a UUID, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+
+ /* Protocol specific parameters */
+ for (param = 1; start < end; param ++) {
+ fprintf(stdout, "\t\tProtocol specific parameter #%d: ", param);
+
+ SDP_GET8(type, start);
+ switch (type) {
+ case SDP_DATA_NIL:
+ fprintf(stdout, "nil\n");
+ break;
+
+ case SDP_DATA_UINT8:
+ case SDP_DATA_INT8:
+ case SDP_DATA_BOOL:
+ SDP_GET8(value.uint8, start);
+ fprintf(stdout, "u/int8/bool %u\n", value.uint8);
+ break;
+
+ case SDP_DATA_UINT16:
+ case SDP_DATA_INT16:
+ case SDP_DATA_UUID16:
+ SDP_GET16(value.uint16, start);
+ fprintf(stdout, "u/int/uuid16 %u\n", value.uint16);
+ break;
+
+ case SDP_DATA_UINT32:
+ case SDP_DATA_INT32:
+ case SDP_DATA_UUID32:
+ SDP_GET32(value.uint32, start);
+ fprintf(stdout, "u/int/uuid32 %u\n", value.uint32);
+ break;
+
+ case SDP_DATA_UINT64:
+ case SDP_DATA_INT64:
+ SDP_GET64(value.uint64, start);
+ fprintf(stdout, "u/int64 %llu\n", value.uint64);
+ break;
+
+ case SDP_DATA_UINT128:
+ case SDP_DATA_INT128:
+ case SDP_DATA_UUID128:
+ SDP_GET128(&value.int128, start);
+ fprintf(stdout, "u/int/uuid128 %#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x\n",
+ *(u_int32_t *)&value.int128.b[0],
+ *(u_int16_t *)&value.int128.b[4],
+ *(u_int16_t *)&value.int128.b[6],
+ *(u_int16_t *)&value.int128.b[8],
+ *(u_int16_t *)&value.int128.b[10],
+ *(u_int32_t *)&value.int128.b[12]);
+ break;
+
+ case SDP_DATA_STR8:
+ case SDP_DATA_URL8:
+ SDP_GET8(len, start);
+ fprintf(stdout, "%*.*s\n", len, len, (char *) start);
+ start += len;
+ break;
+
+ case SDP_DATA_STR16:
+ case SDP_DATA_URL16:
+ SDP_GET16(len, start);
+ fprintf(stdout, "%*.*s\n", len, len, (char *) start);
+ start += len;
+ break;
+
+ case SDP_DATA_STR32:
+ case SDP_DATA_URL32:
+ SDP_GET32(len, start);
+ fprintf(stdout, "%*.*s\n", len, len, (char *) start);
+ start += len;
+ break;
+
+ case SDP_DATA_SEQ8:
+ case SDP_DATA_ALT8:
+ SDP_GET8(len, start);
+ for (; len > 0; start ++, len --)
+ fprintf(stdout, "%#2.2x ", *start);
+ fprintf(stdout, "\n");
+ break;
+
+ case SDP_DATA_SEQ16:
+ case SDP_DATA_ALT16:
+ SDP_GET16(len, start);
+ for (; len > 0; start ++, len --)
+ fprintf(stdout, "%#2.2x ", *start);
+ fprintf(stdout, "\n");
+ break;
+
+ case SDP_DATA_SEQ32:
+ case SDP_DATA_ALT32:
+ SDP_GET32(len, start);
+ for (; len > 0; start ++, len --)
+ fprintf(stdout, "%#2.2x ", *start);
+ fprintf(stdout, "\n");
+ break;
+
+ default:
+ fprintf(stderr, "Invalid Protocol Descriptor. " \
+ "Unknown data type: %#02x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+ }
+} /* print_protocol_descriptor */
+
+static void
+print_protocol_descriptor_list(u_int8_t const *start, u_int8_t const *end)
+{
+ u_int32_t type, len;
+
+ if (end - start < 2) {
+ fprintf(stderr, "Invalid Protocol Descriptor List. " \
+ "Too short, len=%d\n", end - start);
+ return;
+ }
+
+ 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:
+ fprintf(stderr, "Invalid Protocol Descriptor List. " \
+ "Not a sequence, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+
+ while (start < end) {
+ 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:
+ fprintf(stderr, "Invalid Protocol Descriptor List. " \
+ "Not a sequence, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+
+ print_protocol_descriptor(start, start + len);
+ start += len;
+ }
+} /* print_protocol_descriptor_list */
+
+/*
+ * Print Bluetooth Profile Descriptor List
+ *
+ * The BluetoothProfileDescriptorList attribute consists of a data element
+ * sequence in which each element is a profile descriptor that contains
+ * information about a Bluetooth profile to which the service represented by
+ * this service record conforms. Each profile descriptor is a data element
+ * sequence whose first element is the UUID assigned to the profile and whose
+ * second element is a 16-bit profile version number. Each version of a profile
+ * is assigned a 16-bit unsigned integer profile version number, which consists
+ * of two 8-bit fields. The higher-order 8 bits contain the major version
+ * number field and the lower-order 8 bits contain the minor version number
+ * field.
+ */
+
+static void
+print_bluetooth_profile_descriptor_list(u_int8_t const *start, u_int8_t const *end)
+{
+ u_int32_t type, len, value;
+
+ if (end - start < 2) {
+ fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \
+ "Too short, len=%d\n", end - start);
+ return;
+ }
+
+ 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:
+ fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \
+ "Not a sequence, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+
+ while (start < end) {
+ 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:
+ fprintf(stderr, "Invalid Bluetooth Profile " \
+ "Descriptor List. " \
+ "Not a sequence, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+
+ /* Get UUID */
+ SDP_GET8(type, start);
+ switch (type) {
+ case SDP_DATA_UUID16:
+ SDP_GET16(value, start);
+ fprintf(stdout, "\t%s (%#4.4x) ",
+ sdp_uuid2desc(value), value);
+ break;
+
+ case SDP_DATA_UUID32:
+ SDP_GET32(value, start);
+ fprintf(stdout, "\t%#8.8x ", value);
+ break;
+
+ case SDP_DATA_UUID128: {
+ int128_t uuid;
+
+ SDP_GET128(&uuid, start);
+ fprintf(stdout, "\t%#8.8x-%4.4x-%4.4x-%4.4x-%4.4x%8.8x ",
+ *(u_int32_t *)&uuid.b[0],
+ *(u_int16_t *)&uuid.b[4],
+ *(u_int16_t *)&uuid.b[6],
+ *(u_int16_t *)&uuid.b[8],
+ *(u_int16_t *)&uuid.b[10],
+ *(u_int32_t *)&uuid.b[12]);
+ } break;
+
+ default:
+ fprintf(stderr, "Invalid Bluetooth Profile " \
+ "Descriptor List. " \
+ "Not a UUID, type=%#x\n", type);
+ return;
+ /* NOT REACHED */
+ }
+
+ /* Get version */
+ SDP_GET8(type, start);
+ if (type != SDP_DATA_UINT16) {
+ fprintf(stderr, "Invalid Bluetooth Profile " \
+ "Descriptor List. " \
+ "Invalid version type=%#x\n", type);
+ return;
+ }
+
+ SDP_GET16(value, start);
+ fprintf(stdout, "ver. %d.%d\n",
+ (value >> 8) & 0xff, value & 0xff);
+ }
+} /* print_bluetooth_profile_descriptor_list */
+
+/* Perform SDP search command */
+static int
+do_sdp_search(void *xs, int argc, char **argv)
+{
+ char *ep = NULL;
+ int32_t n, type, value;
+ u_int16_t service;
+
+ /* Parse command line arguments */
+ switch (argc) {
+ case 1:
+ n = strtoul(argv[0], &ep, 16);
+ if (*ep != 0) {
+ switch (tolower(argv[0][0])) {
+ case 'c': /* CIP/CTP */
+ switch (tolower(argv[0][1])) {
+ case 'i':
+ service = SDP_SERVICE_CLASS_COMMON_ISDN_ACCESS;
+ break;
+
+ case 't':
+ service = SDP_SERVICE_CLASS_CORDLESS_TELEPHONY;
+ break;
+
+ default:
+ return (USAGE);
+ /* NOT REACHED */
+ }
+ break;
+
+ case 'd': /* DialUp Networking */
+ service = SDP_SERVICE_CLASS_DIALUP_NETWORKING;
+ break;
+
+ case 'f': /* Fax/OBEX File Transfer */
+ switch (tolower(argv[0][1])) {
+ case 'a':
+ service = SDP_SERVICE_CLASS_FAX;
+ break;
+
+ case 't':
+ service = SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER;
+ break;
+
+ default:
+ return (USAGE);
+ /* NOT REACHED */
+ }
+ break;
+
+ case 'g': /* GN */
+ service = SDP_SERVICE_CLASS_GN;
+ break;
+
+ case 'h': /* Headset/HID */
+ switch (tolower(argv[0][1])) {
+ case 'i':
+ service = SDP_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE;
+ break;
+
+ case 's':
+ service = SDP_SERVICE_CLASS_HEADSET;
+ break;
+
+ default:
+ return (USAGE);
+ /* NOT REACHED */
+ }
+ break;
+
+ case 'l': /* LAN Access Using PPP */
+ service = SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP;
+ break;
+
+ case 'n': /* NAP */
+ service = SDP_SERVICE_CLASS_NAP;
+ break;
+
+ case 'o': /* OBEX Object Push */
+ service = SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH;
+ break;
+
+ case 's': /* Serial Port */
+ service = SDP_SERVICE_CLASS_SERIAL_PORT;
+ break;
+
+ default:
+ return (USAGE);
+ /* NOT REACHED */
+ }
+ } else
+ service = (u_int16_t) n;
+ break;
+
+ default:
+ return (USAGE);
+ }
+
+ if (service < SDP_SERVICE_CLASS_SERVICE_DISCOVERY_SERVER)
+ return (USAGE);
+
+ /* Initialize attribute values array */
+ for (n = 0; n < values_len; n ++) {
+ values[n].flags = SDP_ATTR_INVALID;
+ values[n].attr = 0;
+ values[n].vlen = BSIZE;
+ values[n].value = buffer[n];
+ }
+
+ /* Do SDP Service Search Attribute Request */
+ n = sdp_search(xs, 1, &service, attrs_len, attrs, values_len, values);
+ if (n != 0)
+ return (ERROR);
+
+ /* Print attributes values */
+ for (n = 0; n < values_len; n ++) {
+ if (values[n].flags != SDP_ATTR_OK)
+ break;
+
+ switch (values[n].attr) {
+ case SDP_ATTR_SERVICE_RECORD_HANDLE:
+ fprintf(stdout, "\n");
+ if (values[n].vlen == 5) {
+ SDP_GET8(type, values[n].value);
+ if (type == SDP_DATA_UINT32) {
+ SDP_GET32(value, values[n].value);
+ fprintf(stdout, "Record Handle: " \
+ "%#8.8x\n", value);
+ } else
+ fprintf(stderr, "Invalid type=%#x " \
+ "Record Handle " \
+ "attribute!\n", type);
+ } else
+ fprintf(stderr, "Invalid size=%d for Record " \
+ "Handle attribute\n",
+ values[n].vlen);
+ break;
+
+ case SDP_ATTR_SERVICE_CLASS_ID_LIST:
+ fprintf(stdout, "Service Class ID List:\n");
+ print_service_class_id_list(values[n].value,
+ values[n].value + values[n].vlen);
+ break;
+
+ case SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST:
+ fprintf(stdout, "Protocol Descriptor List:\n");
+ print_protocol_descriptor_list(values[n].value,
+ values[n].value + values[n].vlen);
+ break;
+
+ case SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST:
+ fprintf(stdout, "Bluetooth Profile Descriptor List:\n");
+ print_bluetooth_profile_descriptor_list(values[n].value,
+ values[n].value + values[n].vlen);
+ break;
+
+ default:
+ fprintf(stderr, "Unexpected attribute ID=%#4.4x\n",
+ values[n].attr);
+ break;
+ }
+ }
+
+ return (OK);
+} /* do_sdp_search */
+
+/* Perform SDP browse command */
+static int
+do_sdp_browse(void *xs, int argc, char **argv)
+{
+#undef _STR
+#undef STR
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
+ static char const * const av[] = {
+ STR(SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP),
+ NULL
+ };
+
+ switch (argc) {
+ case 0:
+ argc = 1;
+ argv = (char **) av;
+ /* FALL THROUGH */
+ case 1:
+ return (do_sdp_search(xs, argc, argv));
+ }
+
+ return (USAGE);
+} /* do_sdp_browse */
+
+/* List of SDP commands */
+struct sdp_command sdp_commands[] = {
+{
+"Browse [<Group>]",
+"Browse for services. The <Group> parameter is a 16-bit UUID of the group\n" \
+"to browse. If omitted <Group> is set to Public Browse Group.\n\n" \
+"\t<Group> - xxxx; 16-bit UUID of the group to browse\n",
+do_sdp_browse
+},
+{
+"Search <Service>",
+"Search for the <Service>. The <Service> parameter is a 16-bit UUID of the\n" \
+"service to search for. For some services it is possible to use service name\n"\
+"instead of service UUID\n\n" \
+"\t<Service> - xxxx; 16-bit UUID of the service to search for\n\n" \
+"\tKnown service names\n" \
+"\t===================\n" \
+"\tCIP - Common ISDN Access\n" \
+"\tCTP - Cordless Telephony\n" \
+"\tDUN - DialUp Networking\n" \
+"\tFAX - Fax\n" \
+"\tFTRN - OBEX File Transfer\n" \
+"\tGN - GN\n" \
+"\tHID - Human Interface Device\n" \
+"\tHSET - Headset\n" \
+"\tLAN - LAN Access Using PPP\n" \
+"\tNAP - Network Access Point\n" \
+"\tOPUSH - OBEX Object Push\n" \
+"\tSP - Serial Port\n",
+do_sdp_search
+},
+{ NULL, NULL, NULL }
+};
+
OpenPOWER on IntegriCloud